summaryrefslogtreecommitdiffstats
path: root/rpc/xdr/src/nlm4.x
blob: d738b27770dc308a688f4210ef554acf1c90037b (plain)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
  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<MAXNAMELEN>;
	netobj fh;
	netobj oh;
	u_int32_t svid;
	u_int64_t l_offset;
	u_int64_t l_len;
};

struct nlm4_share {
	string caller_name<MAXNAMELEN>;
	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;
};

/*
 * 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 */
};
9ca4b872a48667e09019991dea00b'>api/src/gfapi.aliases105
-rw-r--r--api/src/gfapi.map118
-rw-r--r--api/src/glfs-fops.c8231
-rw-r--r--api/src/glfs-handleops.c3847
-rw-r--r--api/src/glfs-handles.h396
-rw-r--r--api/src/glfs-internal.h870
-rw-r--r--api/src/glfs-master.c250
-rw-r--r--api/src/glfs-mem-types.h31
-rw-r--r--api/src/glfs-mgmt.c1657
-rw-r--r--api/src/glfs-resolve.c1842
-rw-r--r--api/src/glfs.c2338
-rw-r--r--api/src/glfs.h1247
-rwxr-xr-xautogen.sh6
-rwxr-xr-xbuild-aux/checkpatch.pl (renamed from extras/checkpatch.pl)26
-rwxr-xr-xbuild-aux/config.guess.dist14
-rwxr-xr-xbuild-aux/config.sub.dist14
-rwxr-xr-xbuild-aux/pkg-version20
-rwxr-xr-xbuild-aux/xdrgen104
-rw-r--r--cli/src/Makefile.am19
-rw-r--r--cli/src/cli-cmd-global.c229
-rw-r--r--cli/src/cli-cmd-misc.c121
-rw-r--r--cli/src/cli-cmd-parser.c9149
-rw-r--r--cli/src/cli-cmd-peer.c444
-rw-r--r--cli/src/cli-cmd-snapshot.c203
-rw-r--r--cli/src/cli-cmd-system.c979
-rw-r--r--cli/src/cli-cmd-volume.c4946
-rw-r--r--cli/src/cli-cmd.c553
-rw-r--r--cli/src/cli-cmd.h155
-rw-r--r--cli/src/cli-mem-types.h21
-rw-r--r--cli/src/cli-quotad-client.c219
-rw-r--r--cli/src/cli-quotad-client.h20
-rw-r--r--cli/src/cli-rl.c506
-rw-r--r--cli/src/cli-rpc-ops.c18265
-rw-r--r--cli/src/cli-xml-output.c9368
-rw-r--r--cli/src/cli.c1257
-rw-r--r--cli/src/cli.h558
-rw-r--r--cli/src/input.c105
-rw-r--r--cli/src/registry.c495
-rw-r--r--configure.ac1223
-rw-r--r--contrib/argp-standalone/Makefile.am38
-rw-r--r--contrib/argp-standalone/acinclude.m41084
-rw-r--r--contrib/argp-standalone/argp-ba.c26
-rw-r--r--contrib/argp-standalone/argp-eexst.c36
-rw-r--r--contrib/argp-standalone/argp-fmtstream.c477
-rw-r--r--contrib/argp-standalone/argp-fmtstream.h327
-rw-r--r--contrib/argp-standalone/argp-help.c1849
-rw-r--r--contrib/argp-standalone/argp-namefrob.h96
-rw-r--r--contrib/argp-standalone/argp-parse.c1305
-rw-r--r--contrib/argp-standalone/argp-pv.c25
-rw-r--r--contrib/argp-standalone/argp-pvh.c32
-rw-r--r--contrib/argp-standalone/argp.h602
-rwxr-xr-xcontrib/argp-standalone/autogen.sh6
-rw-r--r--contrib/argp-standalone/configure.ac105
-rw-r--r--contrib/argp-standalone/mempcpy.c21
-rw-r--r--contrib/argp-standalone/strcasecmp.c29
-rw-r--r--contrib/argp-standalone/strchrnul.c23
-rw-r--r--contrib/argp-standalone/strndup.c34
-rw-r--r--contrib/argp-standalone/vsnprintf.c839
-rw-r--r--contrib/fuse-include/fuse-mount.h4
-rw-r--r--contrib/fuse-include/fuse_kernel.h47
-rw-r--r--contrib/fuse-lib/misc.c3
-rw-r--r--contrib/fuse-lib/mount-common.c10
-rw-r--r--contrib/fuse-lib/mount-gluster-compat.h48
-rw-r--r--contrib/fuse-lib/mount.c174
-rw-r--r--contrib/fuse-util/fusermount.c6
-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/macfuse/mount_darwin.c11
-rw-r--r--contrib/mount/mntent.c266
-rw-r--r--contrib/qemu/block.c4604
-rw-r--r--contrib/qemu/block/qcow.c914
-rw-r--r--contrib/qemu/block/qcow2-cache.c323
-rw-r--r--contrib/qemu/block/qcow2-cluster.c1478
-rw-r--r--contrib/qemu/block/qcow2-refcount.c1374
-rw-r--r--contrib/qemu/block/qcow2-snapshot.c660
-rw-r--r--contrib/qemu/block/qcow2.c1825
-rw-r--r--contrib/qemu/block/qcow2.h437
-rw-r--r--contrib/qemu/block/qed-check.c248
-rw-r--r--contrib/qemu/block/qed-cluster.c165
-rw-r--r--contrib/qemu/block/qed-gencb.c32
-rw-r--r--contrib/qemu/block/qed-l2-cache.c187
-rw-r--r--contrib/qemu/block/qed-table.c296
-rw-r--r--contrib/qemu/block/qed.c1596
-rw-r--r--contrib/qemu/block/qed.h344
-rw-r--r--contrib/qemu/block/snapshot.c157
-rw-r--r--contrib/qemu/config-host.h72
-rw-r--r--contrib/qemu/coroutine-ucontext.c225
-rw-r--r--contrib/qemu/include/block/aio.h247
-rw-r--r--contrib/qemu/include/block/block.h443
-rw-r--r--contrib/qemu/include/block/block_int.h421
-rw-r--r--contrib/qemu/include/block/blockjob.h278
-rw-r--r--contrib/qemu/include/block/coroutine.h218
-rw-r--r--contrib/qemu/include/block/coroutine_int.h53
-rw-r--r--contrib/qemu/include/block/snapshot.h53
-rw-r--r--contrib/qemu/include/config.h2
-rw-r--r--contrib/qemu/include/exec/cpu-common.h124
-rw-r--r--contrib/qemu/include/exec/hwaddr.h20
-rw-r--r--contrib/qemu/include/exec/poison.h63
-rw-r--r--contrib/qemu/include/fpu/softfloat.h641
-rw-r--r--contrib/qemu/include/glib-compat.h27
-rw-r--r--contrib/qemu/include/migration/migration.h157
-rw-r--r--contrib/qemu/include/migration/qemu-file.h266
-rw-r--r--contrib/qemu/include/migration/vmstate.h740
-rw-r--r--contrib/qemu/include/monitor/monitor.h104
-rw-r--r--contrib/qemu/include/monitor/readline.h55
-rw-r--r--contrib/qemu/include/qapi/error.h85
-rw-r--r--contrib/qemu/include/qapi/qmp/json-lexer.h51
-rw-r--r--contrib/qemu/include/qapi/qmp/json-parser.h24
-rw-r--r--contrib/qemu/include/qapi/qmp/json-streamer.h40
-rw-r--r--contrib/qemu/include/qapi/qmp/qbool.h29
-rw-r--r--contrib/qemu/include/qapi/qmp/qdict.h69
-rw-r--r--contrib/qemu/include/qapi/qmp/qerror.h249
-rw-r--r--contrib/qemu/include/qapi/qmp/qfloat.h29
-rw-r--r--contrib/qemu/include/qapi/qmp/qint.h28
-rw-r--r--contrib/qemu/include/qapi/qmp/qjson.h29
-rw-r--r--contrib/qemu/include/qapi/qmp/qlist.h63
-rw-r--r--contrib/qemu/include/qapi/qmp/qobject.h112
-rw-r--r--contrib/qemu/include/qapi/qmp/qstring.h36
-rw-r--r--contrib/qemu/include/qapi/qmp/types.h25
-rw-r--r--contrib/qemu/include/qemu-common.h478
-rw-r--r--contrib/qemu/include/qemu/aes.h45
-rw-r--r--contrib/qemu/include/qemu/atomic.h202
-rw-r--r--contrib/qemu/include/qemu/bitmap.h222
-rw-r--r--contrib/qemu/include/qemu/bitops.h276
-rw-r--r--contrib/qemu/include/qemu/bswap.h487
-rw-r--r--contrib/qemu/include/qemu/compiler.h55
-rw-r--r--contrib/qemu/include/qemu/error-report.h46
-rw-r--r--contrib/qemu/include/qemu/event_notifier.h46
-rw-r--r--contrib/qemu/include/qemu/hbitmap.h209
-rw-r--r--contrib/qemu/include/qemu/host-utils.h322
-rw-r--r--contrib/qemu/include/qemu/iov.h115
-rw-r--r--contrib/qemu/include/qemu/main-loop.h311
-rw-r--r--contrib/qemu/include/qemu/module.h40
-rw-r--r--contrib/qemu/include/qemu/notify.h72
-rw-r--r--contrib/qemu/include/qemu/option.h157
-rw-r--r--contrib/qemu/include/qemu/option_int.h54
-rw-r--r--contrib/qemu/include/qemu/osdep.h218
-rw-r--r--contrib/qemu/include/qemu/queue.h414
-rw-r--r--contrib/qemu/include/qemu/sockets.h83
-rw-r--r--contrib/qemu/include/qemu/thread-posix.h28
-rw-r--r--contrib/qemu/include/qemu/thread.h56
-rw-r--r--contrib/qemu/include/qemu/timer.h305
-rw-r--r--contrib/qemu/include/qemu/typedefs.h69
-rw-r--r--contrib/qemu/include/sysemu/os-posix.h52
-rw-r--r--contrib/qemu/include/sysemu/sysemu.h200
-rw-r--r--contrib/qemu/include/trace.h6
-rw-r--r--contrib/qemu/nop-symbols.c12
-rw-r--r--contrib/qemu/qapi-types.h2746
-rw-r--r--contrib/qemu/qemu-coroutine-lock.c178
-rw-r--r--contrib/qemu/qemu-coroutine-sleep.c39
-rw-r--r--contrib/qemu/qemu-coroutine.c135
-rw-r--r--contrib/qemu/qmp-commands.h204
-rw-r--r--contrib/qemu/qobject/json-lexer.c373
-rw-r--r--contrib/qemu/qobject/json-parser.c724
-rw-r--r--contrib/qemu/qobject/json-streamer.c122
-rw-r--r--contrib/qemu/qobject/qbool.c68
-rw-r--r--contrib/qemu/qobject/qdict.c478
-rw-r--r--contrib/qemu/qobject/qerror.c156
-rw-r--r--contrib/qemu/qobject/qfloat.c68
-rw-r--r--contrib/qemu/qobject/qint.c67
-rw-r--r--contrib/qemu/qobject/qjson.c282
-rw-r--r--contrib/qemu/qobject/qlist.c170
-rw-r--r--contrib/qemu/qobject/qstring.c149
-rw-r--r--contrib/qemu/trace/generated-tracers.h3759
-rw-r--r--contrib/qemu/util/aes.c1314
-rw-r--r--contrib/qemu/util/bitmap.c256
-rw-r--r--contrib/qemu/util/bitops.c158
-rw-r--r--contrib/qemu/util/cutils.c532
-rw-r--r--contrib/qemu/util/error.c120
-rw-r--r--contrib/qemu/util/hbitmap.c404
-rw-r--r--contrib/qemu/util/hexdump.c37
-rw-r--r--contrib/qemu/util/iov.c426
-rw-r--r--contrib/qemu/util/module.c81
-rw-r--r--contrib/qemu/util/oslib-posix.c248
-rw-r--r--contrib/qemu/util/qemu-error.c225
-rw-r--r--contrib/qemu/util/qemu-option.c1126
-rw-r--r--contrib/qemu/util/qemu-thread-posix.c327
-rw-r--r--contrib/qemu/util/unicode.c100
-rw-r--r--contrib/stdlib/gf_mkostemp.c107
-rw-r--r--contrib/sunrpc/xdr_sizeof.c204
-rw-r--r--contrib/timer-wheel/find_last_bit.c117
-rw-r--r--contrib/timer-wheel/timer-wheel.c29
-rw-r--r--contrib/timer-wheel/timer-wheel.h4
-rw-r--r--contrib/umountd/Makefile.am3
-rw-r--r--contrib/umountd/umountd.c18
-rw-r--r--contrib/userspace-rcu/static-wfcqueue.h685
-rw-r--r--contrib/userspace-rcu/static-wfstack.h455
-rw-r--r--contrib/userspace-rcu/wfcqueue.h216
-rw-r--r--contrib/userspace-rcu/wfstack.h178
-rw-r--r--contrib/uuid/clear.c43
-rw-r--r--contrib/uuid/compare.c55
-rw-r--r--contrib/uuid/copy.c45
-rw-r--r--contrib/uuid/gen_uuid.c686
-rw-r--r--contrib/uuid/gen_uuid_nt.c92
-rw-r--r--contrib/uuid/isnull.c48
-rw-r--r--contrib/uuid/pack.c69
-rw-r--r--contrib/uuid/parse.c79
-rw-r--r--contrib/uuid/tst_uuid.c180
-rw-r--r--contrib/uuid/unpack.c63
-rw-r--r--contrib/uuid/unparse.c76
-rw-r--r--contrib/uuid/uuid.h104
-rw-r--r--contrib/uuid/uuidP.h63
-rw-r--r--contrib/uuid/uuid_time.c171
-rw-r--r--contrib/uuid/uuid_types.h.in50
-rw-r--r--contrib/uuid/uuidd.h54
-rw-r--r--contrib/xxhash/xxhash.c1029
-rw-r--r--contrib/xxhash/xxhash.h328
-rw-r--r--contrib/xxhash/xxhsum.c1301
-rw-r--r--doc/Makefile.am5
-rw-r--r--doc/README.md12
-rw-r--r--doc/debugging/analyzing-regression-cores.md54
-rw-r--r--doc/debugging/coredump-analysis.md31
-rw-r--r--doc/debugging/gfid-to-path.md45
-rw-r--r--doc/debugging/mem-alloc-list.md19
-rw-r--r--doc/debugging/split-brain.md75
-rw-r--r--doc/debugging/statedump.md87
-rw-r--r--doc/developer-guide/Language-Bindings.md45
-rw-r--r--doc/developer-guide/README.md81
-rw-r--r--doc/developer-guide/Using-Gluster-Test-Framework.md271
-rw-r--r--doc/developer-guide/afr-locks-evolution.md (renamed from doc/developer-guide/afr/afr-locks-evolution.md)6
-rw-r--r--doc/developer-guide/afr-self-heal-daemon.md (renamed from doc/developer-guide/afr/self-heal-daemon.md)10
-rw-r--r--doc/developer-guide/afr.md (renamed from doc/developer-guide/afr/afr.md)0
-rw-r--r--doc/developer-guide/bd-xlator.md469
-rw-r--r--doc/developer-guide/brickmux-thread-reduction.md64
-rw-r--r--doc/developer-guide/coding-standard.md445
-rw-r--r--doc/developer-guide/commit-guidelines.md136
-rw-r--r--doc/developer-guide/daemon-management-framework.md9
-rw-r--r--doc/developer-guide/datastructure-inode.md (renamed from doc/developer-guide/data-structures/inode.md)61
-rw-r--r--doc/developer-guide/datastructure-iobuf.md (renamed from doc/developer-guide/data-structures/iobuf.md)36
-rw-r--r--doc/developer-guide/datastructure-mem-pool.md (renamed from doc/developer-guide/data-structures/mem-pool.md)8
-rw-r--r--doc/developer-guide/dirops-transactions-in-dht.md273
-rw-r--r--doc/developer-guide/ec-implementation.md588
-rw-r--r--doc/developer-guide/fuse-interrupt.md211
-rw-r--r--doc/developer-guide/gfapi-symbol-versions.md (renamed from doc/developer-guide/gfapi-symbol-versions/gfapi-symbol-versions.md)2
-rw-r--r--doc/developer-guide/identifying-resource-leaks.md200
-rw-r--r--doc/developer-guide/logging-guidelines.md2
-rw-r--r--doc/developer-guide/network_compression.md20
-rw-r--r--doc/developer-guide/options-to-contribute.md212
-rw-r--r--doc/developer-guide/rpc-for-glusterfs.new-versions.md32
-rw-r--r--doc/developer-guide/syncop.md72
-rw-r--r--doc/developer-guide/thread-naming.md104
-rw-r--r--doc/developer-guide/translator-development.md8
-rw-r--r--doc/developer-guide/writing-a-cloudsync-plugin.md164
-rw-r--r--doc/developer-guide/xlator-classification.md221
-rw-r--r--doc/features/ctime.md68
-rw-r--r--doc/features/ganesha-ha.md43
-rw-r--r--doc/gluster.8140
-rw-r--r--doc/glusterd.83
-rw-r--r--doc/glusterfs.825
-rw-r--r--doc/glusterfsd.810
-rw-r--r--doc/mount.glusterfs.855
-rw-r--r--events/Makefile.am8
-rw-r--r--events/eventskeygen.py243
-rw-r--r--events/src/Makefile.am41
-rw-r--r--events/src/__init__.py10
-rw-r--r--events/src/eventsapiconf.py.in59
-rw-r--r--events/src/eventsconfig.json5
-rw-r--r--events/src/gf_event.py60
-rw-r--r--events/src/glustereventsd.py159
-rw-r--r--events/src/handlers.py40
-rw-r--r--events/src/peer_eventsapi.py669
-rw-r--r--events/src/utils.py445
-rw-r--r--events/tools/Makefile.am6
-rw-r--r--events/tools/eventsdash.py75
-rw-r--r--extras/LinuxRPM/Makefile.am10
-rw-r--r--extras/Makefile.am70
-rw-r--r--extras/backend-cleanup.sh2
-rw-r--r--extras/benchmarking/glfs-bm.c509
-rw-r--r--extras/benchmarking/rdd.c1001
-rwxr-xr-xextras/clang-checker.sh301
-rw-r--r--extras/cliutils/Makefile.am4
-rw-r--r--extras/cliutils/README.md233
-rw-r--r--extras/cliutils/__init__.py31
-rw-r--r--extras/cliutils/cliutils.py237
-rwxr-xr-xextras/collect-system-stats.sh52
-rw-r--r--extras/command-completion/gluster.bash40
-rwxr-xr-xextras/control-cpu-load.sh116
-rwxr-xr-xextras/control-mem.sh128
-rw-r--r--extras/create_new_xlator/README.md24
-rwxr-xr-xextras/create_new_xlator/generate_xlator.py208
-rw-r--r--extras/create_new_xlator/new-xlator.c.tmpl151
-rw-r--r--extras/devel-tools/devel-vagrant/Vagrantfile165
-rw-r--r--extras/devel-tools/devel-vagrant/ansible/roles/cluster/tasks/main.yml5
-rw-r--r--extras/devel-tools/devel-vagrant/ansible/roles/compile-gluster/tasks/main.yml29
-rw-r--r--extras/devel-tools/devel-vagrant/ansible/roles/install-pkgs/tasks/main.yml72
-rw-r--r--extras/devel-tools/devel-vagrant/ansible/roles/iptables/tasks/main.yml3
-rw-r--r--extras/devel-tools/devel-vagrant/ansible/roles/prepare-brick/tasks/main.yml30
-rw-r--r--extras/devel-tools/devel-vagrant/ansible/roles/selinux/tasks/main.yml3
-rw-r--r--extras/devel-tools/devel-vagrant/ansible/roles/service/tasks/main.yml21
-rw-r--r--extras/devel-tools/devel-vagrant/ansible/setup.yml23
-rw-r--r--extras/devel-tools/devel-vagrant/bootstrap.sh3
-rwxr-xr-xextras/devel-tools/devel-vagrant/up.sh4
-rw-r--r--extras/devel-tools/gdb_macros84
-rwxr-xr-xextras/devel-tools/print-backtrace.sh115
-rwxr-xr-xextras/devel-tools/strace-brick.sh55
-rw-r--r--extras/distributed-testing/README28
-rw-r--r--extras/distributed-testing/distributed-test-build-env20
-rwxr-xr-xextras/distributed-testing/distributed-test-build.sh27
-rw-r--r--extras/distributed-testing/distributed-test-env48
-rwxr-xr-xextras/distributed-testing/distributed-test-runner.py859
-rwxr-xr-xextras/distributed-testing/distributed-test.sh95
-rw-r--r--extras/ec-heal-script/README.md69
-rwxr-xr-xextras/ec-heal-script/correct_pending_heals.sh415
-rwxr-xr-xextras/ec-heal-script/gfid_needing_heal_parallel.sh278
-rwxr-xr-xextras/failed-tests.py180
-rw-r--r--extras/firewalld/Makefile.am2
-rw-r--r--extras/firewalld/glusterfs.xml1
-rw-r--r--extras/ganesha/config/ganesha-ha.conf.sample7
-rw-r--r--extras/ganesha/ocf/Makefile.am1
-rw-r--r--extras/ganesha/ocf/ganesha_grace175
-rw-r--r--extras/ganesha/ocf/ganesha_mon153
-rw-r--r--extras/ganesha/ocf/ganesha_nfsd98
-rw-r--r--extras/ganesha/scripts/Makefile.am6
-rwxr-xr-xextras/ganesha/scripts/create-export-ganesha.sh79
-rwxr-xr-xextras/ganesha/scripts/dbus-send.sh98
-rw-r--r--extras/ganesha/scripts/ganesha-ha.sh840
-rwxr-xr-xextras/ganesha/scripts/generate-epoch.py48
-rw-r--r--extras/geo-rep/Makefile.am11
-rw-r--r--extras/geo-rep/gsync-sync-gfid.c168
-rw-r--r--extras/geo-rep/schedule_georep.py.in492
-rwxr-xr-xextras/gfid-to-dirname.sh46
-rwxr-xr-xextras/git-branch-diff.py285
-rw-r--r--extras/glusterd.vol.in9
-rw-r--r--extras/glusterfs-georep-logrotate24
-rwxr-xr-xextras/glusterfs-georep-upgrade.py77
-rw-r--r--extras/glusterfs-logrotate44
-rw-r--r--extras/glusterfs-mode.el225
-rwxr-xr-x[-rw-r--r--]extras/gnfs-loganalyse.py5
-rw-r--r--extras/group-db-workload12
-rw-r--r--extras/group-distributed-virt10
-rw-r--r--extras/group-gluster-block27
-rw-r--r--extras/group-metadata-cache6
-rw-r--r--extras/group-nl-cache5
-rw-r--r--extras/group-samba11
-rw-r--r--extras/group-virt.example32
-rw-r--r--extras/hook-scripts/Makefile.am2
-rwxr-xr-xextras/hook-scripts/S40ufo-stop.py2
-rwxr-xr-xextras/hook-scripts/S56glusterd-geo-rep-create-post.sh38
-rw-r--r--extras/hook-scripts/add-brick/post/Makefile.am7
-rwxr-xr-xextras/hook-scripts/add-brick/post/S10selinux-label-brick.sh100
-rwxr-xr-xextras/hook-scripts/add-brick/post/S13create-subdir-mounts.sh86
-rwxr-xr-xextras/hook-scripts/add-brick/post/disabled-quota-root-xattr-heal.sh184
-rw-r--r--extras/hook-scripts/add-brick/pre/Makefile.am5
-rwxr-xr-xextras/hook-scripts/add-brick/pre/S28Quota-enable-root-xattr-heal.sh15
-rw-r--r--extras/hook-scripts/create/Makefile.am1
-rw-r--r--extras/hook-scripts/create/post/Makefile.am8
-rwxr-xr-xextras/hook-scripts/create/post/S10selinux-label-brick.sh65
-rw-r--r--extras/hook-scripts/delete/Makefile.am1
-rw-r--r--extras/hook-scripts/delete/pre/Makefile.am8
-rwxr-xr-xextras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh73
-rw-r--r--extras/hook-scripts/reset/post/Makefile.am2
-rwxr-xr-xextras/hook-scripts/reset/post/S31ganesha-reset.sh47
-rw-r--r--extras/hook-scripts/set/post/Makefile.am5
-rwxr-xr-xextras/hook-scripts/set/post/S30samba-set.sh50
-rwxr-xr-xextras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh31
-rw-r--r--extras/hook-scripts/start/post/Makefile.am5
-rwxr-xr-xextras/hook-scripts/start/post/S29CTDBsetup.sh63
-rwxr-xr-xextras/hook-scripts/start/post/S30samba-start.sh70
-rwxr-xr-xextras/hook-scripts/start/post/S31ganesha-start.sh90
-rw-r--r--extras/hook-scripts/stop/pre/Makefile.am5
-rwxr-xr-xextras/hook-scripts/stop/pre/S29CTDB-teardown.sh47
-rwxr-xr-xextras/hook-scripts/stop/pre/S30samba-stop.sh46
-rwxr-xr-xextras/identify-hangs.sh53
-rw-r--r--extras/init.d/Makefile.am16
-rwxr-xr-xextras/init.d/glusterd-Redhat.in1
-rw-r--r--extras/init.d/glustereventsd-Debian.in91
-rw-r--r--extras/init.d/glustereventsd-FreeBSD.in19
-rw-r--r--extras/init.d/glustereventsd-Redhat.in129
-rwxr-xr-xextras/init.d/rhel5-load-fuse.modules7
-rwxr-xr-xextras/mount-shared-storage.sh39
-rwxr-xr-xextras/ocf/volume.in42
-rwxr-xr-xextras/profiler/glusterfs-profiler4
-rwxr-xr-xextras/prot_filter.py144
-rw-r--r--extras/python/Makefile.am7
-rw-r--r--extras/python/__init__.py (renamed from xlators/features/glupy/src/__init__.py.in)0
-rwxr-xr-xextras/quota/contri-add.sh (renamed from extras/contri-add.sh)0
-rwxr-xr-xextras/quota/log_accounting.sh26
-rwxr-xr-xextras/quota/quota_fsck.py377
-rwxr-xr-xextras/quota/xattr_analysis.py73
-rwxr-xr-xextras/rebalance.py106
-rw-r--r--extras/run-gluster.tmpfiles.in2
-rw-r--r--extras/snap_scheduler/Makefile.am6
-rw-r--r--extras/snap_scheduler/conf.py.in11
-rwxr-xr-xextras/snap_scheduler/gcron.py38
-rwxr-xr-xextras/snap_scheduler/snap_scheduler.py307
-rwxr-xr-xextras/statedumpparse.rb208
-rwxr-xr-xextras/stop-all-gluster-processes.sh202
-rw-r--r--extras/stripe-merge.c689
-rw-r--r--extras/systemd/Makefile.am22
-rw-r--r--extras/systemd/gluster-ta-volume.service.in13
-rw-r--r--extras/systemd/glusterd.service.in16
-rw-r--r--extras/systemd/glustereventsd.service.in16
-rw-r--r--extras/systemd/glusterfssharedstorage.service.in13
-rw-r--r--extras/test/ld-preload-test/ld-preload-lib.c598
-rw-r--r--extras/test/ld-preload-test/ld-preload-test.c505
-rw-r--r--extras/test/open-fd-tests.c85
-rw-r--r--extras/test/test-ffop.c1640
-rwxr-xr-xextras/thin-arbiter/setup-thin-arbiter.sh184
-rw-r--r--extras/thin-arbiter/thin-arbiter.vol57
-rw-r--r--extras/volfilter.py45
-rw-r--r--extras/who-wrote-glusterfs/gitdm.aliases8
-rw-r--r--extras/who-wrote-glusterfs/gitdm.domain-map15
-rw-r--r--geo-replication/Makefile.am5
-rw-r--r--geo-replication/gsyncd.conf.in349
-rw-r--r--geo-replication/setup.py6
-rw-r--r--geo-replication/src/Makefile.am32
-rw-r--r--geo-replication/src/gsyncd.c634
-rwxr-xr-xgeo-replication/src/gverify.sh90
-rw-r--r--geo-replication/src/peer_georep-sshkey.py.in116
-rwxr-xr-xgeo-replication/src/peer_gsec_create.in10
-rw-r--r--geo-replication/src/peer_mountbroker.in28
-rw-r--r--geo-replication/src/peer_mountbroker.py.in401
-rw-r--r--geo-replication/src/procdiggy.c190
-rw-r--r--geo-replication/src/procdiggy.h9
-rwxr-xr-xgeo-replication/src/set_geo_rep_pem_keys.sh1
-rw-r--r--geo-replication/syncdaemon/Makefile.am10
-rw-r--r--geo-replication/syncdaemon/README.md1
-rw-r--r--geo-replication/syncdaemon/__codecheck.py3
-rw-r--r--geo-replication/syncdaemon/argsupgrade.py359
-rw-r--r--geo-replication/syncdaemon/changelogagent.py81
-rw-r--r--geo-replication/syncdaemon/conf.py.in17
-rw-r--r--geo-replication/syncdaemon/configinterface.py.in360
-rw-r--r--geo-replication/syncdaemon/gsyncd.py947
-rw-r--r--geo-replication/syncdaemon/gsyncdconfig.py485
-rw-r--r--geo-replication/syncdaemon/gsyncdstatus.py110
-rw-r--r--geo-replication/syncdaemon/libcxattr.py52
-rw-r--r--geo-replication/syncdaemon/libgfchangelog.py253
-rw-r--r--geo-replication/syncdaemon/logutils.py77
-rw-r--r--geo-replication/syncdaemon/master.py1097
-rw-r--r--geo-replication/syncdaemon/monitor.py484
-rw-r--r--geo-replication/syncdaemon/py2py3.py184
-rw-r--r--geo-replication/syncdaemon/rconf.py (renamed from geo-replication/syncdaemon/gconf.py)18
-rw-r--r--geo-replication/syncdaemon/repce.py36
-rw-r--r--geo-replication/syncdaemon/resource.py2013
-rw-r--r--geo-replication/syncdaemon/subcmds.py335
-rw-r--r--geo-replication/syncdaemon/syncdutils.py874
-rw-r--r--geo-replication/tests/__init__.py1
-rw-r--r--geo-replication/tests/unit/__init__.py1
-rwxr-xr-x[-rw-r--r--]geo-replication/tests/unit/test_gsyncdstatus.py12
-rw-r--r--geo-replication/tests/unit/test_syncdutils.py1
-rw-r--r--glusterfs-api.pc.in2
-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.in1912
-rw-r--r--glusterfsd/src/Makefile.am27
-rw-r--r--glusterfsd/src/gf_attach.c241
-rw-r--r--glusterfsd/src/glusterfsd-mem-types.h16
-rw-r--r--glusterfsd/src/glusterfsd-messages.h166
-rw-r--r--glusterfsd/src/glusterfsd-mgmt.c4559
-rw-r--r--glusterfsd/src/glusterfsd.c4008
-rw-r--r--glusterfsd/src/glusterfsd.h197
-rw-r--r--heal/src/Makefile.am13
-rw-r--r--heal/src/glfs-heal.c2289
-rw-r--r--libgfchangelog.pc.in2
-rw-r--r--libgfdb.pc.in12
-rw-r--r--libglusterd/Makefile.am (renamed from xlators/features/changetimerecorder/Makefile.am)0
-rw-r--r--libglusterd/src/Makefile.am31
-rw-r--r--libglusterd/src/gd-common-utils.c78
-rw-r--r--libglusterd/src/gd-common-utils.h28
-rw-r--r--libglusterd/src/libglusterd.sym2
-rw-r--r--libglusterfs/Makefile.am2
-rw-r--r--libglusterfs/src/Makefile.am111
-rw-r--r--libglusterfs/src/async.c720
-rw-r--r--libglusterfs/src/byte-order.h301
-rw-r--r--libglusterfs/src/call-stub.c3280
-rw-r--r--libglusterfs/src/call-stub.h750
-rw-r--r--libglusterfs/src/changelog.h101
-rw-r--r--libglusterfs/src/checksum.c18
-rw-r--r--libglusterfs/src/circ-buff.c298
-rw-r--r--libglusterfs/src/circ-buff.h64
-rw-r--r--libglusterfs/src/client_t.c1329
-rw-r--r--libglusterfs/src/client_t.h150
-rw-r--r--libglusterfs/src/cluster-syncop.c1577
-rw-r--r--libglusterfs/src/cluster-syncop.h156
-rw-r--r--libglusterfs/src/common-utils.c7055
-rw-r--r--libglusterfs/src/common-utils.h767
-rw-r--r--libglusterfs/src/compat-errno.c1728
-rw-r--r--libglusterfs/src/compat-errno.h226
-rw-r--r--libglusterfs/src/compat.c909
-rw-r--r--libglusterfs/src/compat.h480
-rw-r--r--libglusterfs/src/ctr-messages.h501
-rw-r--r--libglusterfs/src/ctx.c98
-rw-r--r--libglusterfs/src/daemon.c69
-rw-r--r--libglusterfs/src/default-args.c1651
-rw-r--r--libglusterfs/src/defaults-tmpl.c247
-rw-r--r--libglusterfs/src/defaults.c3167
-rw-r--r--libglusterfs/src/defaults.h1413
-rw-r--r--libglusterfs/src/dict.c4495
-rw-r--r--libglusterfs/src/dict.h265
-rw-r--r--libglusterfs/src/event-epoll.c1557
-rw-r--r--libglusterfs/src/event-history.c85
-rw-r--r--libglusterfs/src/event-history.h39
-rw-r--r--libglusterfs/src/event-poll.c749
-rw-r--r--libglusterfs/src/event.c363
-rw-r--r--libglusterfs/src/event.h96
-rw-r--r--libglusterfs/src/events.c136
-rw-r--r--libglusterfs/src/fd-lk.c668
-rw-r--r--libglusterfs/src/fd-lk.h70
-rw-r--r--libglusterfs/src/fd.c1761
-rw-r--r--libglusterfs/src/fd.h190
-rwxr-xr-xlibglusterfs/src/gen-defaults.py81
-rwxr-xr-xlibglusterfs/src/generator.py777
-rw-r--r--libglusterfs/src/gf-dirent.c386
-rw-r--r--libglusterfs/src/gf-dirent.h67
-rw-r--r--libglusterfs/src/gfdb/Makefile.am33
-rw-r--r--libglusterfs/src/gfdb/gfdb_data_store.c731
-rw-r--r--libglusterfs/src/gfdb/gfdb_data_store.h271
-rw-r--r--libglusterfs/src/gfdb/gfdb_data_store_types.h754
-rw-r--r--libglusterfs/src/gfdb/gfdb_sqlite3.c1143
-rw-r--r--libglusterfs/src/gfdb/gfdb_sqlite3.h286
-rw-r--r--libglusterfs/src/gfdb/gfdb_sqlite3_helper.c1217
-rw-r--r--libglusterfs/src/gfdb/gfdb_sqlite3_helper.h59
-rw-r--r--libglusterfs/src/gidcache.c311
-rw-r--r--libglusterfs/src/glfs-message-id.h164
-rw-r--r--libglusterfs/src/globals.c540
-rw-r--r--libglusterfs/src/globals.h91
-rw-r--r--libglusterfs/src/glusterfs-acl.h165
-rw-r--r--libglusterfs/src/glusterfs.h665
-rw-r--r--libglusterfs/src/glusterfs/async.h209
-rw-r--r--libglusterfs/src/glusterfs/atomic.h459
-rw-r--r--libglusterfs/src/glusterfs/byte-order.h279
-rw-r--r--libglusterfs/src/glusterfs/call-stub.h622
-rw-r--r--libglusterfs/src/glusterfs/checksum.h (renamed from libglusterfs/src/checksum.h)6
-rw-r--r--libglusterfs/src/glusterfs/circ-buff.h61
-rw-r--r--libglusterfs/src/glusterfs/client_t.h147
-rw-r--r--libglusterfs/src/glusterfs/cluster-syncop.h227
-rw-r--r--libglusterfs/src/glusterfs/common-utils.h1256
-rw-r--r--libglusterfs/src/glusterfs/compat-errno.h238
-rw-r--r--libglusterfs/src/glusterfs/compat-uuid.h (renamed from libglusterfs/src/compat-uuid.h)41
-rw-r--r--libglusterfs/src/glusterfs/compat.h544
-rw-r--r--libglusterfs/src/glusterfs/daemon.h (renamed from libglusterfs/src/daemon.h)6
-rw-r--r--libglusterfs/src/glusterfs/default-args.h455
-rw-r--r--libglusterfs/src/glusterfs/defaults.h1275
-rw-r--r--libglusterfs/src/glusterfs/dict.h420
-rw-r--r--libglusterfs/src/glusterfs/event-history.h40
-rw-r--r--libglusterfs/src/glusterfs/events.h34
-rw-r--r--libglusterfs/src/glusterfs/fd-lk.h59
-rw-r--r--libglusterfs/src/glusterfs/fd.h169
-rw-r--r--libglusterfs/src/glusterfs/gf-dirent.h71
-rw-r--r--libglusterfs/src/glusterfs/gf-event.h140
-rw-r--r--libglusterfs/src/glusterfs/gidcache.h (renamed from libglusterfs/src/gidcache.h)45
-rw-r--r--libglusterfs/src/glusterfs/glfs-message-id.h102
-rw-r--r--libglusterfs/src/glusterfs/globals.h188
-rw-r--r--libglusterfs/src/glusterfs/glusterfs-acl.h162
-rw-r--r--libglusterfs/src/glusterfs/glusterfs-fops.h241
-rw-r--r--libglusterfs/src/glusterfs/glusterfs.h838
-rw-r--r--libglusterfs/src/glusterfs/graph-utils.h (renamed from libglusterfs/src/graph-utils.h)12
-rw-r--r--libglusterfs/src/glusterfs/hashfn.h (renamed from libglusterfs/src/hashfn.h)7
-rw-r--r--libglusterfs/src/glusterfs/iatt.h489
-rw-r--r--libglusterfs/src/glusterfs/inode.h306
-rw-r--r--libglusterfs/src/glusterfs/iobuf.h194
-rw-r--r--libglusterfs/src/glusterfs/latency.h33
-rw-r--r--libglusterfs/src/glusterfs/libglusterfs-messages.h245
-rw-r--r--libglusterfs/src/glusterfs/list.h273
-rw-r--r--libglusterfs/src/glusterfs/lkowner.h93
-rw-r--r--libglusterfs/src/glusterfs/locking.h84
-rw-r--r--libglusterfs/src/glusterfs/logging.h383
-rw-r--r--libglusterfs/src/glusterfs/lvm-defaults.h (renamed from libglusterfs/src/lvm-defaults.h)0
-rw-r--r--libglusterfs/src/glusterfs/mem-pool.h336
-rw-r--r--libglusterfs/src/glusterfs/mem-types.h139
-rw-r--r--libglusterfs/src/glusterfs/monitoring.h21
-rw-r--r--libglusterfs/src/glusterfs/options.h327
-rw-r--r--libglusterfs/src/glusterfs/parse-utils.h (renamed from libglusterfs/src/parse-utils.h)20
-rw-r--r--libglusterfs/src/glusterfs/quota-common-utils.h68
-rw-r--r--libglusterfs/src/glusterfs/rbthash.h75
-rw-r--r--libglusterfs/src/glusterfs/refcount.h (renamed from libglusterfs/src/refcount.h)38
-rw-r--r--libglusterfs/src/glusterfs/revision.h1
-rw-r--r--libglusterfs/src/glusterfs/rot-buffs.h125
-rw-r--r--libglusterfs/src/glusterfs/run.h (renamed from libglusterfs/src/run.h)57
-rw-r--r--libglusterfs/src/glusterfs/stack.h555
-rw-r--r--libglusterfs/src/glusterfs/statedump.h132
-rw-r--r--libglusterfs/src/glusterfs/store.h112
-rw-r--r--libglusterfs/src/glusterfs/strfd.h (renamed from libglusterfs/src/strfd.h)22
-rw-r--r--libglusterfs/src/glusterfs/syncop-utils.h54
-rw-r--r--libglusterfs/src/glusterfs/syncop.h718
-rw-r--r--libglusterfs/src/glusterfs/syscall.h278
-rw-r--r--libglusterfs/src/glusterfs/template-component-messages.h28
-rw-r--r--libglusterfs/src/glusterfs/throttle-tbf.h74
-rw-r--r--libglusterfs/src/glusterfs/timer.h56
-rw-r--r--libglusterfs/src/glusterfs/timespec.h (renamed from libglusterfs/src/timespec.h)15
-rw-r--r--libglusterfs/src/glusterfs/trie.h52
-rw-r--r--libglusterfs/src/glusterfs/upcall-utils.h110
-rw-r--r--libglusterfs/src/glusterfs/xlator.h1106
-rw-r--r--libglusterfs/src/graph-print.c214
-rw-r--r--libglusterfs/src/graph.c2161
-rw-r--r--libglusterfs/src/graph.l40
-rw-r--r--libglusterfs/src/graph.y30
-rw-r--r--libglusterfs/src/hashfn.c264
-rw-r--r--libglusterfs/src/iatt.h327
-rw-r--r--libglusterfs/src/inode.c3697
-rw-r--r--libglusterfs/src/inode.h279
-rw-r--r--libglusterfs/src/iobuf.c1712
-rw-r--r--libglusterfs/src/iobuf.h172
-rw-r--r--libglusterfs/src/latency.c202
-rw-r--r--libglusterfs/src/latency.h28
-rw-r--r--libglusterfs/src/libglusterfs-messages.h1756
-rw-r--r--libglusterfs/src/libglusterfs.sym1193
-rw-r--r--libglusterfs/src/list.h287
-rw-r--r--libglusterfs/src/lkowner.h97
-rw-r--r--libglusterfs/src/locking.c27
-rw-r--r--libglusterfs/src/locking.h44
-rw-r--r--libglusterfs/src/logging.c3801
-rw-r--r--libglusterfs/src/logging.h326
-rw-r--r--libglusterfs/src/mem-pool.c1256
-rw-r--r--libglusterfs/src/mem-pool.h241
-rw-r--r--libglusterfs/src/mem-types.h160
-rw-r--r--libglusterfs/src/monitoring.c282
-rw-r--r--libglusterfs/src/options.c1928
-rw-r--r--libglusterfs/src/options.h264
-rw-r--r--libglusterfs/src/parse-utils.c145
-rw-r--r--libglusterfs/src/quota-common-utils.c343
-rw-r--r--libglusterfs/src/quota-common-utils.h65
-rw-r--r--libglusterfs/src/rbthash.c676
-rw-r--r--libglusterfs/src/rbthash.h77
-rw-r--r--libglusterfs/src/refcount.c146
-rw-r--r--libglusterfs/src/revision.h1
-rw-r--r--libglusterfs/src/rot-buffs.c627
-rw-r--r--libglusterfs/src/rot-buffs.h121
-rw-r--r--libglusterfs/src/run.c785
-rw-r--r--libglusterfs/src/stack.c706
-rw-r--r--libglusterfs/src/stack.h485
-rw-r--r--libglusterfs/src/statedump.c1500
-rw-r--r--libglusterfs/src/statedump.h106
-rw-r--r--libglusterfs/src/store.c1157
-rw-r--r--libglusterfs/src/store.h109
-rw-r--r--libglusterfs/src/strfd.c109
-rw-r--r--libglusterfs/src/syncop-utils.c813
-rw-r--r--libglusterfs/src/syncop-utils.h39
-rw-r--r--libglusterfs/src/syncop.c4606
-rw-r--r--libglusterfs/src/syncop.h514
-rw-r--r--libglusterfs/src/syscall.c812
-rw-r--r--libglusterfs/src/syscall.h193
-rw-r--r--libglusterfs/src/throttle-tbf.c290
-rw-r--r--libglusterfs/src/timer.c401
-rw-r--r--libglusterfs/src/timer.h58
-rw-r--r--libglusterfs/src/timespec.c127
-rw-r--r--libglusterfs/src/trie.c489
-rw-r--r--libglusterfs/src/trie.h46
-rw-r--r--libglusterfs/src/tw.c25
-rw-r--r--libglusterfs/src/unittest/global_mock.c7
-rw-r--r--libglusterfs/src/unittest/log_mock.c34
-rw-r--r--libglusterfs/src/unittest/mem_pool_unittest.c64
-rw-r--r--libglusterfs/src/unittest/unittest.h16
-rw-r--r--libglusterfs/src/upcall-utils.h38
-rw-r--r--libglusterfs/src/xlator.c1969
-rw-r--r--libglusterfs/src/xlator.h991
-rwxr-xr-xrfc.sh279
-rw-r--r--rpc/rpc-lib/src/Makefile.am16
-rw-r--r--rpc/rpc-lib/src/auth-glusterfs.c529
-rw-r--r--rpc/rpc-lib/src/auth-null.c39
-rw-r--r--rpc/rpc-lib/src/auth-unix.c78
-rw-r--r--rpc/rpc-lib/src/autoscale-threads.c22
-rw-r--r--rpc/rpc-lib/src/libgfrpc.sym68
-rw-r--r--rpc/rpc-lib/src/mgmt-pmap.c147
-rw-r--r--rpc/rpc-lib/src/protocol-common.h539
-rw-r--r--rpc/rpc-lib/src/rpc-clnt-ping.c549
-rw-r--r--rpc/rpc-lib/src/rpc-clnt-ping.h6
-rw-r--r--rpc/rpc-lib/src/rpc-clnt.c3157
-rw-r--r--rpc/rpc-lib/src/rpc-clnt.h284
-rw-r--r--rpc/rpc-lib/src/rpc-drc.c1105
-rw-r--r--rpc/rpc-lib/src/rpc-drc.h100
-rw-r--r--rpc/rpc-lib/src/rpc-lib-messages.h80
-rw-r--r--rpc/rpc-lib/src/rpc-transport.c1021
-rw-r--r--rpc/rpc-lib/src/rpc-transport.h326
-rw-r--r--rpc/rpc-lib/src/rpcsvc-auth.c828
-rw-r--r--rpc/rpc-lib/src/rpcsvc-common.h147
-rw-r--r--rpc/rpc-lib/src/rpcsvc.c4581
-rw-r--r--rpc/rpc-lib/src/rpcsvc.h813
-rw-r--r--rpc/rpc-lib/src/xdr-common.h42
-rw-r--r--rpc/rpc-lib/src/xdr-rpc.c265
-rw-r--r--rpc/rpc-lib/src/xdr-rpc.h86
-rw-r--r--rpc/rpc-lib/src/xdr-rpcclnt.c125
-rw-r--r--rpc/rpc-lib/src/xdr-rpcclnt.h23
-rw-r--r--rpc/rpc-transport/Makefile.am2
-rw-r--r--rpc/rpc-transport/rdma/Makefile.am1
-rw-r--r--rpc/rpc-transport/rdma/src/Makefile.am22
-rw-r--r--rpc/rpc-transport/rdma/src/name.c721
-rw-r--r--rpc/rpc-transport/rdma/src/name.h36
-rw-r--r--rpc/rpc-transport/rdma/src/rdma.c5024
-rw-r--r--rpc/rpc-transport/rdma/src/rdma.h389
-rw-r--r--rpc/rpc-transport/rdma/src/rpc-trans-rdma-messages.h212
-rw-r--r--rpc/rpc-transport/socket/src/Makefile.am11
-rw-r--r--rpc/rpc-transport/socket/src/name.c1174
-rw-r--r--rpc/rpc-transport/socket/src/name.h22
-rw-r--r--rpc/rpc-transport/socket/src/socket-mem-types.h8
-rw-r--r--rpc/rpc-transport/socket/src/socket.c7369
-rw-r--r--rpc/rpc-transport/socket/src/socket.h349
-rw-r--r--rpc/xdr/src/.gitignore2
-rw-r--r--rpc/xdr/src/Makefile.am139
-rw-r--r--rpc/xdr/src/acl3-xdr.x17
-rw-r--r--rpc/xdr/src/changelog-xdr.x23
-rw-r--r--rpc/xdr/src/cli1-xdr.x53
-rw-r--r--rpc/xdr/src/glusterd1-xdr.x31
-rw-r--r--rpc/xdr/src/glusterfs3-xdr.x216
-rw-r--r--rpc/xdr/src/glusterfs3.h1117
-rw-r--r--rpc/xdr/src/glusterfs4-xdr.x797
-rw-r--r--rpc/xdr/src/libgfxdr.sym350
-rw-r--r--rpc/xdr/src/mount3udp.x7
-rw-r--r--rpc/xdr/src/msg-nfs3.c442
-rw-r--r--rpc/xdr/src/msg-nfs3.h134
-rw-r--r--rpc/xdr/src/nlm4-xdr.x19
-rw-r--r--rpc/xdr/src/nsm-xdr.x19
-rw-r--r--rpc/xdr/src/portmap-xdr.x26
-rw-r--r--rpc/xdr/src/rpc-common-xdr.x20
-rw-r--r--rpc/xdr/src/rpc-pragmas.h28
-rw-r--r--rpc/xdr/src/xdr-generic.c129
-rw-r--r--rpc/xdr/src/xdr-generic.h33
-rw-r--r--rpc/xdr/src/xdr-nfs3.c2576
-rw-r--r--rpc/xdr/src/xdr-nfs3.h1431
-rwxr-xr-xrun-tests-in-vagrant.sh311
-rwxr-xr-xrun-tests.sh566
-rw-r--r--site.h.in44
l---------submit-for-review.sh1
-rw-r--r--tests/00-geo-rep/00-georep-verify-non-root-setup.t294
-rw-r--r--tests/00-geo-rep/00-georep-verify-setup.t110
-rw-r--r--tests/00-geo-rep/01-georep-glusterd-tests.t213
-rw-r--r--tests/00-geo-rep/bug-1600145.t109
-rw-r--r--tests/00-geo-rep/bug-1708603.t63
-rw-r--r--tests/00-geo-rep/georep-basic-dr-rsync-arbiter.t234
-rw-r--r--tests/00-geo-rep/georep-basic-dr-rsync.t258
-rw-r--r--tests/00-geo-rep/georep-basic-dr-tarssh-arbiter.t227
-rw-r--r--tests/00-geo-rep/georep-basic-dr-tarssh.t227
-rw-r--r--tests/00-geo-rep/georep-basic-rsync-ec.t224
-rw-r--r--tests/00-geo-rep/georep-basic-tarssh-ec.t223
-rw-r--r--tests/00-geo-rep/georep-config-upgrade.t132
-rw-r--r--tests/00-geo-rep/georep-stderr-hang.t128
-rw-r--r--tests/00-geo-rep/georep-upgrade.t79
-rw-r--r--tests/00-geo-rep/gsyncd.conf.old47
-rw-r--r--tests/000-flaky/basic_afr_split-brain-favorite-child-policy.t203
-rw-r--r--tests/000-flaky/basic_changelog_changelog-snapshot.t60
-rw-r--r--tests/000-flaky/basic_distribute_rebal-all-nodes-migrate.t142
-rw-r--r--tests/000-flaky/basic_ec_ec-quorum-count-partial-failure.t50
-rw-r--r--[-rwxr-xr-x]tests/000-flaky/basic_mount-nfs-auth.t (renamed from tests/basic/mount-nfs-auth.t)70
-rw-r--r--tests/000-flaky/bugs_core_multiplex-limit-issue-151.t56
-rw-r--r--[-rwxr-xr-x]tests/000-flaky/bugs_distribute_bug-1117851.t (renamed from tests/bugs/distribute/bug-1117851.t)6
-rw-r--r--tests/000-flaky/bugs_distribute_bug-1122443.t (renamed from tests/bugs/distribute/bug-1122443.t)17
-rw-r--r--tests/000-flaky/bugs_glusterd_bug-857330/common.rc (renamed from tests/bugs/glusterd/bug-857330/common.rc)2
-rwxr-xr-xtests/000-flaky/bugs_glusterd_bug-857330/normal.t (renamed from tests/bugs/glusterd/bug-857330/normal.t)18
-rwxr-xr-xtests/000-flaky/bugs_glusterd_bug-857330/xml.t (renamed from tests/bugs/glusterd/bug-857330/xml.t)20
-rw-r--r--tests/000-flaky/bugs_glusterd_quorum-value-check.t37
-rw-r--r--tests/000-flaky/bugs_nfs_bug-1116503.t (renamed from tests/bugs/nfs/bug-1116503.t)8
-rw-r--r--tests/000-flaky/features_lock-migration_lkmigration-set-option.t34
-rw-r--r--tests/afr.rc37
-rwxr-xr-xtests/basic/0symbol-check.t46
-rw-r--r--tests/basic/afr/add-brick-self-heal.t74
-rw-r--r--tests/basic/afr/afr-anon-inode-no-quorum.t63
-rw-r--r--tests/basic/afr/afr-anon-inode.t114
-rw-r--r--tests/basic/afr/afr-no-fsync.t20
-rw-r--r--tests/basic/afr/afr-read-hash-mode.t56
-rw-r--r--tests/basic/afr/afr-seek.t55
-rw-r--r--tests/basic/afr/afr-up.t28
-rw-r--r--tests/basic/afr/arbiter-add-brick.t86
-rw-r--r--tests/basic/afr/arbiter-cli.t30
-rw-r--r--tests/basic/afr/arbiter-mount.t48
-rw-r--r--tests/basic/afr/arbiter-remove-brick.t36
-rw-r--r--tests/basic/afr/arbiter-statfs.t12
-rw-r--r--tests/basic/afr/arbiter.t34
-rwxr-xr-x[-rw-r--r--]tests/basic/afr/client-side-heal.t39
-rw-r--r--tests/basic/afr/data-self-heal.t2
-rw-r--r--tests/basic/afr/durability-off.t46
-rw-r--r--tests/basic/afr/entry-self-heal-anon-dir-off.t459
-rw-r--r--tests/basic/afr/entry-self-heal.t76
-rw-r--r--tests/basic/afr/gfid-heal.t33
-rw-r--r--tests/basic/afr/gfid-mismatch-resolution-with-cli.t168
-rw-r--r--tests/basic/afr/gfid-mismatch-resolution-with-fav-child-policy.t229
-rw-r--r--tests/basic/afr/gfid-mismatch.t4
-rw-r--r--tests/basic/afr/gfid-self-heal.t18
-rw-r--r--tests/basic/afr/granular-esh/add-brick.t80
-rw-r--r--tests/basic/afr/granular-esh/cli.t114
-rw-r--r--tests/basic/afr/granular-esh/conservative-merge.t138
-rw-r--r--tests/basic/afr/granular-esh/granular-esh.t168
-rw-r--r--tests/basic/afr/granular-esh/granular-indices-but-non-granular-heal.t76
-rw-r--r--tests/basic/afr/granular-esh/replace-brick.t76
-rw-r--r--tests/basic/afr/halo.t61
-rw-r--r--tests/basic/afr/heal-info.t36
-rw-r--r--tests/basic/afr/heal-quota.t35
-rw-r--r--tests/basic/afr/inodelk.t87
-rw-r--r--tests/basic/afr/lk-quorum.t257
-rw-r--r--tests/basic/afr/metadata-self-heal.t2
-rw-r--r--tests/basic/afr/name-self-heal.t112
-rw-r--r--tests/basic/afr/quorum.t27
-rw-r--r--tests/basic/afr/rename-data-loss.t72
-rw-r--r--tests/basic/afr/replace-brick-self-heal.t4
-rw-r--r--tests/basic/afr/resolve.t4
-rw-r--r--tests/basic/afr/root-squash-self-heal.t6
-rw-r--r--tests/basic/afr/self-heal.t2
-rw-r--r--tests/basic/afr/self-heald.t19
-rw-r--r--tests/basic/afr/sparse-file-self-heal.t33
-rw-r--r--tests/basic/afr/split-brain-favorite-child-policy-client-side-healing.t124
-rw-r--r--tests/basic/afr/split-brain-heal-info.t4
-rw-r--r--tests/basic/afr/split-brain-healing-ctime.t252
-rw-r--r--tests/basic/afr/split-brain-healing.t90
-rw-r--r--tests/basic/afr/split-brain-open.t38
-rw-r--r--tests/basic/afr/split-brain-resolution.t20
-rw-r--r--tests/basic/afr/ta-check-locks.t68
-rw-r--r--tests/basic/afr/ta-read.t64
-rw-r--r--tests/basic/afr/ta-shd.t49
-rw-r--r--tests/basic/afr/ta-write-on-bad-brick.t51
-rw-r--r--tests/basic/afr/ta.t54
-rw-r--r--tests/basic/afr/tarissue.t39
-rw-r--r--tests/basic/all_squash.t74
-rwxr-xr-xtests/basic/bd.t142
-rw-r--r--tests/basic/changelog/changelog-api.t37
-rw-r--r--tests/basic/changelog/changelog-history.t91
-rw-r--r--tests/basic/changelog/changelog-rename.t44
-rw-r--r--tests/basic/changelog/history-api.t42
-rw-r--r--tests/basic/cloudsync-sanity.t29
-rw-r--r--tests/basic/ctime/ctime-ec-heal.t70
-rw-r--r--tests/basic/ctime/ctime-ec-rebalance.t43
-rw-r--r--tests/basic/ctime/ctime-glfs-init.c68
-rw-r--r--tests/basic/ctime/ctime-glfs-init.t23
-rw-r--r--tests/basic/ctime/ctime-heal-symlinks.t65
-rw-r--r--tests/basic/ctime/ctime-mdata-legacy-files.t83
-rw-r--r--tests/basic/ctime/ctime-noatime.t49
-rw-r--r--tests/basic/ctime/ctime-readdir.c29
-rw-r--r--tests/basic/ctime/ctime-readdir.t50
-rw-r--r--tests/basic/ctime/ctime-rep-heal.t70
-rw-r--r--tests/basic/ctime/ctime-rep-rebalance.t41
-rw-r--r--tests/basic/ctime/ctime-utimesat.t28
-rw-r--r--tests/basic/distribute/brick-down.t83
-rw-r--r--tests/basic/distribute/bug-1265677-use-readdirp.t38
-rw-r--r--tests/basic/distribute/debug-xattrs.t54
-rw-r--r--tests/basic/distribute/dir-heal.t145
-rw-r--r--tests/basic/distribute/file-create.t120
-rw-r--r--tests/basic/distribute/file-rename.t1021
-rw-r--r--tests/basic/distribute/force-migration.t50
-rw-r--r--tests/basic/distribute/lookup.t54
-rw-r--r--tests/basic/distribute/non-root-unlink-stale-linkto.t51
-rw-r--r--tests/basic/distribute/spare_file_rebalance.t51
-rw-r--r--tests/basic/distribute/throttle-rebal.t14
-rw-r--r--tests/basic/ec/ec-12-4.t14
-rw-r--r--tests/basic/ec/ec-1468261.t95
-rw-r--r--tests/basic/ec/ec-5-1.t14
-rw-r--r--tests/basic/ec/ec-7-3.t14
-rw-r--r--tests/basic/ec/ec-anonymous-fd.t42
-rw-r--r--tests/basic/ec/ec-background-heals.t13
-rw-r--r--tests/basic/ec/ec-badfd.c124
-rwxr-xr-xtests/basic/ec/ec-badfd.t26
-rw-r--r--tests/basic/ec/ec-common2
-rw-r--r--tests/basic/ec/ec-cpu-extensions.t62
-rwxr-xr-xtests/basic/ec/ec-data-heal.t75
-rw-r--r--tests/basic/ec/ec-dirty-flags.t23
-rw-r--r--tests/basic/ec/ec-discard.t205
-rw-r--r--tests/basic/ec/ec-fallocate.t72
-rw-r--r--tests/basic/ec/ec-fast-fgetxattr.c129
-rwxr-xr-xtests/basic/ec/ec-fast-fgetxattr.t40
-rw-r--r--tests/basic/ec/ec-fix-openfd.t111
-rw-r--r--tests/basic/ec/ec-new-entry.t70
-rw-r--r--tests/basic/ec/ec-notify.t22
-rw-r--r--tests/basic/ec/ec-optimistic-changelog.t153
-rw-r--r--tests/basic/ec/ec-quorum-count.t167
-rw-r--r--tests/basic/ec/ec-read-mask.t114
-rw-r--r--tests/basic/ec/ec-read-policy.t52
-rw-r--r--tests/basic/ec/ec-rebalance.t61
-rw-r--r--tests/basic/ec/ec-reset-brick.t50
-rw-r--r--tests/basic/ec/ec-root-heal.t5
-rw-r--r--tests/basic/ec/ec-seek.t58
-rw-r--r--tests/basic/ec/ec-stripe.t227
-rw-r--r--tests/basic/ec/ec-up.t28
-rw-r--r--tests/basic/ec/ec.t14
-rw-r--r--tests/basic/ec/gfapi-ec-open-truncate.c171
-rw-r--r--tests/basic/ec/gfapi-ec-open-truncate.t48
-rw-r--r--tests/basic/ec/heal-info.t74
-rw-r--r--tests/basic/ec/lock-contention.t62
-rwxr-xr-xtests/basic/ec/nfs.t3
-rwxr-xr-xtests/basic/ec/quota.t3
-rw-r--r--tests/basic/ec/self-heal-read-write-fail.t69
-rw-r--r--tests/basic/ec/self-heal.t27
-rw-r--r--tests/basic/exports_parsing.t15
-rw-r--r--tests/basic/fencing/afr-lock-heal-advanced.c227
-rw-r--r--tests/basic/fencing/afr-lock-heal-advanced.t115
-rw-r--r--tests/basic/fencing/afr-lock-heal-basic.c182
-rw-r--r--tests/basic/fencing/afr-lock-heal-basic.t102
-rw-r--r--tests/basic/fencing/fence-basic.c229
-rwxr-xr-xtests/basic/fencing/fence-basic.t31
-rw-r--r--tests/basic/fencing/fencing-crash-conistency.t62
-rw-r--r--tests/basic/fencing/test-fence-option.t37
-rwxr-xr-xtests/basic/file-snapshot.t62
-rw-r--r--tests/basic/fop-sampling.t61
-rw-r--r--tests/basic/fops-sanity.c1812
-rw-r--r--tests/basic/fuse/Makefile12
-rw-r--r--tests/basic/fuse/active-io-graph-switch.t65
-rw-r--r--tests/basic/fuse/seek.c82
-rwxr-xr-xtests/basic/geo-replication/marker-xattrs.t46
-rw-r--r--tests/basic/gfapi/Makefile (renamed from tests/basic/gfapi/Makefile.am)13
-rwxr-xr-xtests/basic/gfapi/anonymous_fd.t (renamed from tests/basic/gfapi/anonymous_fd.sh)2
-rw-r--r--tests/basic/gfapi/anonymous_fd_read_write.c175
-rw-r--r--tests/basic/gfapi/bug-1241104.c93
-rwxr-xr-xtests/basic/gfapi/bug-1241104.t30
-rw-r--r--tests/basic/gfapi/bug-1507896.c49
-rw-r--r--tests/basic/gfapi/bug-1507896.t33
-rw-r--r--tests/basic/gfapi/bug1283983.c122
-rwxr-xr-xtests/basic/gfapi/bug1283983.sh33
-rw-r--r--tests/basic/gfapi/bug1291259.c181
-rwxr-xr-xtests/basic/gfapi/bug1291259.t32
-rw-r--r--tests/basic/gfapi/bug1613098.c96
-rwxr-xr-xtests/basic/gfapi/bug1613098.t22
-rw-r--r--tests/basic/gfapi/gfapi-async-calls-test.c494
-rw-r--r--tests/basic/gfapi/gfapi-async-calls-test.t26
-rw-r--r--tests/basic/gfapi/gfapi-copy-file-range.t82
-rw-r--r--tests/basic/gfapi/gfapi-dup.c84
-rwxr-xr-xtests/basic/gfapi/gfapi-dup.t27
-rw-r--r--tests/basic/gfapi/gfapi-graph-switch-open-fd.t44
-rw-r--r--tests/basic/gfapi/gfapi-keep-writing.c129
-rw-r--r--tests/basic/gfapi/gfapi-load-volfile.c65
-rw-r--r--tests/basic/gfapi/gfapi-load-volfile.t28
-rw-r--r--tests/basic/gfapi/gfapi-ssl-load-volfile-test.c127
-rwxr-xr-xtests/basic/gfapi/gfapi-ssl-load-volfile-test.t76
-rw-r--r--tests/basic/gfapi/gfapi-ssl-test.c124
-rwxr-xr-xtests/basic/gfapi/gfapi-ssl-test.t61
-rw-r--r--tests/basic/gfapi/gfapi-statx-basic.c184
-rwxr-xr-xtests/basic/gfapi/gfapi-statx-basic.t30
-rw-r--r--tests/basic/gfapi/gfapi-trunc.c89
-rw-r--r--tests/basic/gfapi/gfapi-trunc.t22
-rw-r--r--tests/basic/gfapi/glfd-lkowner.c214
-rwxr-xr-xtests/basic/gfapi/glfd-lkowner.t27
-rw-r--r--tests/basic/gfapi/glfs-copy-file-range.c180
-rw-r--r--tests/basic/gfapi/glfs_h_creat_open.c118
-rwxr-xr-xtests/basic/gfapi/glfs_h_creat_open.t27
-rw-r--r--tests/basic/gfapi/glfs_sysrq.c60
-rwxr-xr-xtests/basic/gfapi/glfs_sysrq.t39
-rw-r--r--tests/basic/gfapi/glfs_xreaddirplus_r.c242
-rwxr-xr-xtests/basic/gfapi/glfs_xreaddirplus_r.t28
-rw-r--r--tests/basic/gfapi/glfsxmp-coverage.c1900
-rw-r--r--tests/basic/gfapi/glfsxmp.t30
-rw-r--r--tests/basic/gfapi/libgfapi-fini-hang.c98
-rwxr-xr-xtests/basic/gfapi/libgfapi-fini-hang.t (renamed from tests/basic/gfapi/libgfapi-fini-hang.sh)14
-rw-r--r--tests/basic/gfapi/mandatory-lock-optimal.c532
-rw-r--r--tests/basic/gfapi/mandatory-lock-optimal.t38
-rw-r--r--tests/basic/gfapi/protocol-client-ssl.vol.in15
-rw-r--r--tests/basic/gfapi/protocol-client.vol.in14
-rw-r--r--tests/basic/gfapi/seek.c99
-rw-r--r--tests/basic/gfapi/sink.t13
-rw-r--r--tests/basic/gfapi/sink.vol24
-rw-r--r--tests/basic/gfapi/upcall-cache-invalidate.c346
-rwxr-xr-xtests/basic/gfapi/upcall-cache-invalidate.t (renamed from tests/basic/gfapi/upcall-cache-invalidate.sh)13
-rw-r--r--tests/basic/gfapi/upcall-register-api.c286
-rwxr-xr-xtests/basic/gfapi/upcall-register-api.t30
-rwxr-xr-xtests/basic/gfproxy.t71
-rw-r--r--tests/basic/global-threading.t104
-rw-r--r--tests/basic/glusterd-restart-shd-mux.t96
-rw-r--r--tests/basic/glusterd/arbiter-volume-probe.t25
-rw-r--r--tests/basic/glusterd/check-cloudsync-ancestry.t48
-rw-r--r--tests/basic/glusterd/disperse-create.t20
-rw-r--r--tests/basic/glusterd/heald.t55
-rw-r--r--tests/basic/glusterd/thin-arbiter-volume-probe.t25
-rw-r--r--tests/basic/glusterd/thin-arbiter-volume.t45
-rw-r--r--tests/basic/glusterd/volfile_server_switch.t46
-rw-r--r--tests/basic/glusterd/volume-brick-count.t61
-rw-r--r--tests/basic/glusterfsd-args.t5
-rw-r--r--tests/basic/graph-cleanup-brick-down-shd-mux.t64
-rw-r--r--tests/basic/hardlink-limit.t44
-rw-r--r--tests/basic/inode-leak.t31
-rw-r--r--tests/basic/inode-quota-enforcing.t (renamed from tests/bugs/quota/inode-quota.t)81
-rw-r--r--tests/basic/ios-dump.t43
-rw-r--r--tests/basic/jbr/jbr-volgen.t39
-rwxr-xr-xtests/basic/jbr/jbr.t38
-rw-r--r--tests/basic/logchecks-messages.h86
-rw-r--r--tests/basic/logchecks.c356
-rw-r--r--tests/basic/md-cache/bug-1317785.t34
-rwxr-xr-xtests/basic/md-cache/bug-1418249.t20
-rwxr-xr-xtests/basic/meta.t2
-rw-r--r--tests/basic/metadisp/fsyncdir.c29
-rw-r--r--tests/basic/metadisp/ftruncate.c34
-rw-r--r--tests/basic/metadisp/fxattr.c107
-rw-r--r--tests/basic/metadisp/gfs-fsetxattr.c141
-rw-r--r--tests/basic/metadisp/metadisp.t316
-rw-r--r--tests/basic/metadisp/metadisp.vol14
-rw-r--r--tests/basic/mount-options.disabled3
-rwxr-xr-xtests/basic/mount.t9
-rw-r--r--tests/basic/mpx-compat.t53
-rw-r--r--tests/basic/multiple-volume-shd-mux.t46
-rw-r--r--tests/basic/multiplex.t78
-rw-r--r--tests/basic/namespace.t131
-rw-r--r--tests/basic/netgroup_parsing.t12
-rwxr-xr-xtests/basic/nl-cache.t98
-rw-r--r--tests/basic/nufa.t7
-rwxr-xr-xtests/basic/op_errnos.t4
-rw-r--r--tests/basic/open-behind/open-behind.t183
-rw-r--r--tests/basic/open-behind/tester-fd.c99
-rw-r--r--tests/basic/open-behind/tester.c444
-rw-r--r--tests/basic/open-behind/tester.h145
-rw-r--r--tests/basic/open-fd-snap-delete.t74
-rw-r--r--tests/basic/peer-parsing.t52
-rwxr-xr-xtests/basic/playground/template-xlator-sanity.t43
-rw-r--r--tests/basic/posix/shared-statfs.t58
-rw-r--r--tests/basic/posix/zero-fill-enospace.c67
-rw-r--r--tests/basic/posix/zero-fill-enospace.t35
-rw-r--r--tests/basic/pump.t45
-rw-r--r--tests/basic/quick-read-with-upcall.t72
-rwxr-xr-xtests/basic/quota-ancestry-building.t2
-rwxr-xr-xtests/basic/quota-anon-fd-nfs.t15
-rwxr-xr-xtests/basic/quota-nfs.t5
-rw-r--r--tests/basic/quota-rename.t (renamed from tests/bugs/quota/bug-1240991.t)10
-rw-r--r--tests/basic/quota.c108
-rwxr-xr-xtests/basic/quota.t71
-rwxr-xr-xtests/basic/quota_aux_mount.t53
-rwxr-xr-xtests/basic/rpc-coverage.sh21
-rwxr-xr-x[-rw-r--r--]tests/basic/rpc-coverage.t4
-rwxr-xr-xtests/basic/rpm.t145
-rw-r--r--tests/basic/sdfs-sanity.t28
-rw-r--r--tests/basic/seek.c182
-rw-r--r--tests/basic/shd-mux-afr.t70
-rw-r--r--tests/basic/shd-mux-ec.t75
-rw-r--r--tests/basic/stats-dump.t55
-rwxr-xr-xtests/basic/symbol-check.sh114
-rwxr-xr-xtests/basic/tier/bug-1214222-directories_miising_after_attach_tier.t71
-rwxr-xr-xtests/basic/tier/tier.t225
-rwxr-xr-xtests/basic/tier/tier_lookup_heal.t73
-rwxr-xr-xtests/basic/trace.t55
-rw-r--r--tests/basic/uss.t81
-rw-r--r--tests/basic/volfile-sanity.t29
-rw-r--r--tests/basic/volume-scale-shd-mux.t116
-rw-r--r--tests/basic/volume-snap-scheduler.t49
-rwxr-xr-xtests/basic/volume-snapshot-clone.t15
-rwxr-xr-xtests/basic/volume-snapshot-xml.t72
-rwxr-xr-xtests/basic/volume-snapshot.t20
-rw-r--r--tests/basic/volume-status.t44
-rw-r--r--[-rwxr-xr-x]tests/basic/volume.t48
-rw-r--r--tests/basic/xlator-pass-through-sanity.t22
-rw-r--r--tests/bitrot/br-signer-threads-config-1797869.t73
-rw-r--r--tests/bitrot/br-state-check.t2
-rw-r--r--tests/bitrot/br-stub.c304
-rw-r--r--tests/bitrot/br-stub.t9
-rw-r--r--tests/bitrot/bug-1207627-bitrot-scrub-status.t52
-rw-r--r--tests/bitrot/bug-1221914.t3
-rw-r--r--tests/bitrot/bug-1244613.t10
-rw-r--r--tests/bitrot/bug-1294786.t95
-rw-r--r--tests/bitrot/bug-1373520.t71
-rw-r--r--tests/bitrot/bug-1700078.t87
-rw-r--r--tests/bugs/access-control/bug-1051896.c147
-rw-r--r--tests/bugs/access-control/bug-1387241.c18
-rw-r--r--tests/bugs/access-control/bug-1387241.t36
-rw-r--r--tests/bugs/access-control/bug-958691.t3
-rw-r--r--tests/bugs/bitrot/bug-1227996.t1
-rw-r--r--tests/bugs/bitrot/bug-1245981.t4
-rw-r--r--tests/bugs/bitrot/bug-1288490.t48
-rwxr-xr-xtests/bugs/bug-1064147.t72
-rw-r--r--tests/bugs/bug-1110262.t22
-rw-r--r--tests/bugs/bug-1138841.t25
-rwxr-xr-xtests/bugs/bug-1258069.t2
-rw-r--r--tests/bugs/bug-1368312.t86
-rw-r--r--tests/bugs/bug-1371806.t81
-rw-r--r--tests/bugs/bug-1371806_1.t48
-rw-r--r--tests/bugs/bug-1371806_2.t52
-rw-r--r--tests/bugs/bug-1371806_3.t63
-rw-r--r--tests/bugs/bug-1371806_acl.t96
-rw-r--r--tests/bugs/bug-1584517.t70
-rw-r--r--tests/bugs/bug-1620580.t67
-rw-r--r--tests/bugs/bug-1694920.t63
-rw-r--r--tests/bugs/bug-1702299.t67
-rw-r--r--tests/bugs/changelog/bug-1211327.t8
-rw-r--r--tests/bugs/changelog/bug-1321955.t60
-rw-r--r--tests/bugs/cli/bug-1022905.t1
-rw-r--r--tests/bugs/cli/bug-1030580.t5
-rw-r--r--tests/bugs/cli/bug-1047416.t5
-rw-r--r--tests/bugs/cli/bug-1113476.t11
-rw-r--r--tests/bugs/cli/bug-1169302.c79
-rwxr-xr-xtests/bugs/cli/bug-1169302.t55
-rwxr-xr-xtests/bugs/cli/bug-1320388.t44
-rw-r--r--tests/bugs/cli/bug-1353156-get-state-cli-validations.t147
-rw-r--r--tests/bugs/cli/bug-1378842-volume-get-all.t23
-rwxr-xr-xtests/bugs/cli/bug-770655.t168
-rwxr-xr-xtests/bugs/cli/bug-822830.t2
-rw-r--r--tests/bugs/cli/bug-961307.t2
-rw-r--r--tests/bugs/cli/bug-983317-volume-get.t45
-rw-r--r--tests/bugs/cli/bug-983317.t25
-rw-r--r--tests/bugs/core/brick-mux-fd-cleanup.t78
-rwxr-xr-xtests/bugs/core/bug-1168803-snapd-option-validation-fix.t2
-rwxr-xr-xtests/bugs/core/bug-1402841.t-mt-dir-scan-race.t42
-rw-r--r--tests/bugs/core/bug-1421721-mpx-toggle.t25
-rw-r--r--tests/bugs/core/bug-1432542-mpx-restart-crash.t116
-rw-r--r--tests/bugs/core/bug-1650403.t113
-rw-r--r--tests/bugs/core/bug-1699025-brick-mux-detach-brick-fd-issue.t33
-rw-r--r--tests/bugs/core/bug-834465.c85
-rwxr-xr-xtests/bugs/core/bug-834465.t13
-rwxr-xr-xtests/bugs/core/bug-908146.t12
-rwxr-xr-xtests/bugs/core/bug-927616.t3
-rwxr-xr-xtests/bugs/core/io-stats-1322825.t67
-rwxr-xr-xtests/bugs/core/log-bug-1362520.t43
-rwxr-xr-xtests/bugs/ctime/issue-832.t32
-rw-r--r--tests/bugs/disperse/bug-1161886.c53
-rwxr-xr-xtests/bugs/distribute/bug-1063230.t29
-rwxr-xr-xtests/bugs/distribute/bug-1066798.t2
-rwxr-xr-xtests/bugs/distribute/bug-1088231.t14
-rw-r--r--tests/bugs/distribute/bug-1099890.t1
-rwxr-xr-xtests/bugs/distribute/bug-1125824.t3
-rwxr-xr-xtests/bugs/distribute/bug-1161156.t4
-rwxr-xr-xtests/bugs/distribute/bug-1161311.t45
-rw-r--r--tests/bugs/distribute/bug-1190734.t4
-rw-r--r--tests/bugs/distribute/bug-1193636.c102
-rw-r--r--tests/bugs/distribute/bug-1193636.t4
-rw-r--r--tests/bugs/distribute/bug-1247563.t5
-rw-r--r--tests/bugs/distribute/bug-1368012.t51
-rw-r--r--tests/bugs/distribute/bug-1389697.t42
-rw-r--r--tests/bugs/distribute/bug-1543279.t67
-rw-r--r--tests/bugs/distribute/bug-1600379.t54
-rw-r--r--tests/bugs/distribute/bug-1667804.t63
-rwxr-xr-xtests/bugs/distribute/bug-1786679.t69
-rwxr-xr-xtests/bugs/distribute/bug-853258.t6
-rw-r--r--tests/bugs/distribute/bug-860663.c48
-rw-r--r--tests/bugs/distribute/bug-860663.t16
-rw-r--r--tests/bugs/distribute/bug-862967.t8
-rwxr-xr-xtests/bugs/distribute/bug-915554.t2
-rwxr-xr-xtests/bugs/distribute/issue-1327.t33
-rwxr-xr-xtests/bugs/distribute/overlap.py32
-rw-r--r--tests/bugs/ec/bug-1161621.t (renamed from tests/bugs/disperse/bug-1161621.t)5
-rw-r--r--tests/bugs/ec/bug-1161886.c53
-rw-r--r--tests/bugs/ec/bug-1161886.t (renamed from tests/bugs/disperse/bug-1161886.t)2
-rw-r--r--tests/bugs/ec/bug-1179050.t23
-rw-r--r--tests/bugs/ec/bug-1187474.t (renamed from tests/bugs/disperse/bug-1187474.t)3
-rw-r--r--tests/bugs/ec/bug-1188145.t (renamed from tests/bugs/disperse/bug-1188145.t)0
-rw-r--r--tests/bugs/ec/bug-1227869.t (renamed from tests/bugs/disperse/bug-1227869.t)0
-rw-r--r--tests/bugs/ec/bug-1236065.t (renamed from tests/bugs/disperse/bug-1236065.t)14
-rw-r--r--tests/bugs/ec/bug-1251446.t (renamed from tests/bugs/disperse/bug-1251446.t)4
-rwxr-xr-xtests/bugs/ec/bug-1304988.t42
-rw-r--r--tests/bugs/ec/bug-1547662.t41
-rw-r--r--tests/bugs/ec/bug-1699866-check-reopen-fd.t34
-rw-r--r--tests/bugs/ec/bug-1708156-honor-inodelk-contention-notify-on-partial-locks.t54
-rwxr-xr-xtests/bugs/error-gen/bug-767095.t2
-rw-r--r--tests/bugs/fuse/bug-1126048.c44
-rw-r--r--tests/bugs/fuse/bug-1283103.t59
-rw-r--r--tests/bugs/fuse/bug-1309462.t50
-rw-r--r--tests/bugs/fuse/bug-1336818.t52
-rwxr-xr-xtests/bugs/fuse/bug-858215.t11
-rwxr-xr-xtests/bugs/fuse/bug-924726.t2
-rw-r--r--tests/bugs/fuse/bug-985074.t5
-rwxr-xr-xtests/bugs/fuse/many-groups-for-acl.t14
-rwxr-xr-xtests/bugs/fuse/setup.sh20
-rwxr-xr-xtests/bugs/fuse/teardown.sh (renamed from tests/bugs/glusterd/bug-000000.t)4
-rw-r--r--tests/bugs/geo-replication/bug-1111490.t1
-rw-r--r--tests/bugs/geo-replication/bug-1296496.t44
-rwxr-xr-xtests/bugs/geo-replication/bug-877293.t4
-rw-r--r--tests/bugs/gfapi/bug-1032894.t (renamed from tests/bugs/libgfapi/bug-1032894.t)0
-rw-r--r--tests/bugs/gfapi/bug-1093594.c510
-rwxr-xr-xtests/bugs/gfapi/bug-1093594.t22
-rwxr-xr-xtests/bugs/gfapi/bug-1319374-THIS-crash.t27
-rw-r--r--tests/bugs/gfapi/bug-1319374.c131
-rw-r--r--tests/bugs/gfapi/bug-1447266/1460514.c150
-rw-r--r--tests/bugs/gfapi/bug-1447266/1460514.t26
-rw-r--r--tests/bugs/gfapi/bug-1447266/bug-1447266.c107
-rw-r--r--tests/bugs/gfapi/bug-1447266/bug-1447266.t60
-rw-r--r--tests/bugs/gfapi/bug-1630804/gfapi-bz1630804.c112
-rw-r--r--tests/bugs/gfapi/bug-1630804/gfapi-bz1630804.t25
-rw-r--r--tests/bugs/gfapi/glfs_vol_set_IO_ERR.c163
-rwxr-xr-xtests/bugs/gfapi/glfs_vol_set_IO_ERR.t (renamed from tests/bugs/gfapi/bug-1093594.sh)6
-rwxr-xr-xtests/bugs/glusterd/859927/repl.t13
-rw-r--r--tests/bugs/glusterd/add-brick-and-validate-replicated-volume-options.t110
-rw-r--r--tests/bugs/glusterd/brick-mux-validation-in-cluster.t108
-rw-r--r--tests/bugs/glusterd/brick-mux-validation.t104
-rw-r--r--tests/bugs/glusterd/brick-mux.t81
-rw-r--r--tests/bugs/glusterd/brick-order-check-add-brick.t61
-rwxr-xr-xtests/bugs/glusterd/bug-1002556.t25
-rw-r--r--tests/bugs/glusterd/bug-1004744.t46
-rw-r--r--tests/bugs/glusterd/bug-1027171.t53
-rw-r--r--tests/bugs/glusterd/bug-1040408.t31
-rw-r--r--tests/bugs/glusterd/bug-1046308.t19
-rw-r--r--tests/bugs/glusterd/bug-1047955.t23
-rwxr-xr-xtests/bugs/glusterd/bug-1070734.t3
-rw-r--r--tests/bugs/glusterd/bug-1075087.t33
-rw-r--r--[-rwxr-xr-x]tests/bugs/glusterd/bug-1085330-and-bug-916549.t (renamed from tests/bugs/glusterd/bug-1085330.t)17
-rwxr-xr-xtests/bugs/glusterd/bug-1089668.t27
-rw-r--r--tests/bugs/glusterd/bug-1092841.t24
-rw-r--r--tests/bugs/glusterd/bug-1094119-remove-replace-brick-support-from-glusterd.t30
-rwxr-xr-xtests/bugs/glusterd/bug-1095097.t19
-rw-r--r--tests/bugs/glusterd/bug-1102656.t20
-rw-r--r--tests/bugs/glusterd/bug-1104642.t47
-rw-r--r--tests/bugs/glusterd/bug-1109741-auth-mgmt-handshake.t50
-rw-r--r--tests/bugs/glusterd/bug-1120647.t18
-rw-r--r--tests/bugs/glusterd/bug-1121584-brick-existing-validation-for-remove-brick-status-stop.t34
-rw-r--r--tests/bugs/glusterd/bug-1163108-min-free-disk-option-validation.t37
-rwxr-xr-xtests/bugs/glusterd/bug-1173414-mgmt-v3-remote-lock-failure.t34
-rw-r--r--tests/bugs/glusterd/bug-1177132-quorum-validation.t64
-rw-r--r--tests/bugs/glusterd/bug-1179175-uss-option-validation.t37
-rw-r--r--tests/bugs/glusterd/bug-1199451-op-version-retrieving-fix.t22
-rw-r--r--tests/bugs/glusterd/bug-1209329_daemon-svcs-on-reset-volume.t69
-rw-r--r--tests/bugs/glusterd/bug-1213295-snapd-svc-uninitialized.t26
-rwxr-xr-xtests/bugs/glusterd/bug-1223213-peerid-fix.t32
-rw-r--r--tests/bugs/glusterd/bug-1231437-rebalance-test-in-cluster.t31
-rw-r--r--tests/bugs/glusterd/bug-1238135-lazy-daemon-initialization-on-demand.t16
-rw-r--r--tests/bugs/glusterd/bug-1238706-daemons-stop-on-peer-cleanup.t5
-rw-r--r--tests/bugs/glusterd/bug-1242543-replace-brick.t25
-rw-r--r--tests/bugs/glusterd/bug-1260185-donot-allow-detach-commit-unnecessarily.t41
-rw-r--r--tests/bugs/glusterd/bug-1482906-peer-file-blank-line.t29
-rw-r--r--tests/bugs/glusterd/bug-1595320.t93
-rw-r--r--tests/bugs/glusterd/bug-1696046.t113
-rw-r--r--tests/bugs/glusterd/bug-1699339.t73
-rw-r--r--tests/bugs/glusterd/bug-1720566.t50
-rwxr-xr-xtests/bugs/glusterd/bug-765230-remove-quota-related-option-after-disabling-quota.t63
-rwxr-xr-xtests/bugs/glusterd/bug-782095.t48
-rw-r--r--tests/bugs/glusterd/bug-824753-file-locker.c46
-rwxr-xr-xtests/bugs/glusterd/bug-824753.t45
-rw-r--r--tests/bugs/glusterd/bug-839595.t31
-rwxr-xr-xtests/bugs/glusterd/bug-859927.t70
-rwxr-xr-xtests/bugs/glusterd/bug-862834.t46
-rw-r--r--tests/bugs/glusterd/bug-878004.t29
-rw-r--r--tests/bugs/glusterd/bug-888752.t24
-rwxr-xr-xtests/bugs/glusterd/bug-889630.t56
-rw-r--r--tests/bugs/glusterd/bug-905307.t36
-rw-r--r--tests/bugs/glusterd/bug-913487.t14
-rwxr-xr-xtests/bugs/glusterd/bug-913555.t50
-rwxr-xr-xtests/bugs/glusterd/bug-916549.t19
-rwxr-xr-xtests/bugs/glusterd/bug-948686.t46
-rw-r--r--tests/bugs/glusterd/bug-949930.t2
-rwxr-xr-xtests/bugs/glusterd/bug-955588.t27
-rw-r--r--tests/bugs/glusterd/bug-958790.t21
-rw-r--r--tests/bugs/glusterd/bug-961669.t48
-rwxr-xr-xtests/bugs/glusterd/bug-963541.t33
-rwxr-xr-xtests/bugs/glusterd/bug-964059.t30
-rw-r--r--tests/bugs/glusterd/check_elastic_server.t63
-rw-r--r--tests/bugs/glusterd/daemon-log-level-option.t93
-rw-r--r--tests/bugs/glusterd/df-results-post-replace-brick-operations.t61
-rw-r--r--tests/bugs/glusterd/mgmt-handshake-and-volume-sync-post-glusterd-restart.t71
-rw-r--r--tests/bugs/glusterd/optimized-basic-testcases-in-cluster.t115
-rw-r--r--tests/bugs/glusterd/optimized-basic-testcases.t305
-rw-r--r--tests/bugs/glusterd/quorum-validation.t122
-rw-r--r--tests/bugs/glusterd/rebalance-in-cluster.t (renamed from tests/bugs/glusterd/bug-1245142-rebalance_test.t)24
-rw-r--r--tests/bugs/glusterd/rebalance-operations-in-single-node.t131
-rw-r--r--tests/bugs/glusterd/remove-brick-in-cluster.t (renamed from tests/bugs/glusterd/bug-1230121-replica_subvol_count_correct_cal.t)30
-rw-r--r--tests/bugs/glusterd/remove-brick-testcases.t119
-rw-r--r--tests/bugs/glusterd/remove-brick-validation.t (renamed from tests/bugs/glusterd/bug-1245045-remove-brick-validation.t)34
-rw-r--r--tests/bugs/glusterd/removing-multiple-bricks-in-single-remove-brick-command.t (renamed from tests/bugs/glusterd/bug-974007.t)40
-rw-r--r--tests/bugs/glusterd/replace-brick-operations.t48
-rw-r--r--tests/bugs/glusterd/reset-brick-and-daemons-follow-quorum.t63
-rw-r--r--tests/bugs/glusterd/serialize-shd-manager-glusterd-restart.t54
-rw-r--r--tests/bugs/glusterd/snapshot-operations.t50
-rw-r--r--tests/bugs/glusterd/sync-post-glusterd-restart.t54
-rw-r--r--tests/bugs/glusterd/validating-options-for-replicated-volume.t142
-rw-r--r--tests/bugs/glusterd/validating-server-quorum.t125
-rwxr-xr-xtests/bugs/glusterfs-server/bug-852147.t6
-rwxr-xr-xtests/bugs/glusterfs-server/bug-861542.t2
-rwxr-xr-xtests/bugs/glusterfs-server/bug-864222.t3
-rw-r--r--tests/bugs/glusterfs-server/bug-873549.t2
-rwxr-xr-xtests/bugs/glusterfs-server/bug-877992.t8
-rwxr-xr-xtests/bugs/glusterfs-server/bug-887145.t17
-rwxr-xr-xtests/bugs/glusterfs-server/bug-904300.t3
-rw-r--r--tests/bugs/glusterfs-server/bug-905864.c99
-rwxr-xr-xtests/bugs/glusterfs-server/bug-912297.t2
-rw-r--r--tests/bugs/glusterfs/bug-1482528.t100
-rwxr-xr-xtests/bugs/glusterfs/bug-844688.t45
-rw-r--r--tests/bugs/glusterfs/bug-848251.t1
-rw-r--r--tests/bugs/glusterfs/bug-856455.t3
-rw-r--r--tests/bugs/glusterfs/bug-867253.t7
-rwxr-xr-xtests/bugs/glusterfs/bug-872923.t3
-rw-r--r--tests/bugs/glusterfs/bug-873962-spb.t1
-rwxr-xr-xtests/bugs/glusterfs/bug-879490.t2
-rwxr-xr-xtests/bugs/glusterfs/bug-879494.t2
-rw-r--r--tests/bugs/glusterfs/bug-893338.t2
-rwxr-xr-xtests/bugs/glusterfs/bug-893378.t4
-rwxr-xr-xtests/bugs/glusterfs/bug-896431.t37
-rwxr-xr-xtests/bugs/glusterfs/bug-902610.t7
-rw-r--r--tests/bugs/glusterfs/bug-906646.t10
-rw-r--r--tests/bugs/glusterfs/getlk_owner.c96
-rw-r--r--tests/bugs/heal-symlinks.t65
-rw-r--r--tests/bugs/index/bug-1559004-EMLINK-handling.t91
-rw-r--r--tests/bugs/io-cache/bug-858242.c119
-rw-r--r--tests/bugs/io-cache/bug-read-hang.c125
-rwxr-xr-xtests/bugs/io-cache/bug-read-hang.t34
-rwxr-xr-xtests/bugs/io-stats/bug-1598548.t41
-rwxr-xr-xtests/bugs/logging/bug-823081.t8
-rwxr-xr-xtests/bugs/md-cache/afr-stale-read.t44
-rwxr-xr-xtests/bugs/md-cache/bug-1211863.t69
-rwxr-xr-xtests/bugs/md-cache/bug-1211863_unlink.t49
-rw-r--r--tests/bugs/md-cache/bug-1476324.t27
-rwxr-xr-xtests/bugs/md-cache/bug-1632503.t24
-rw-r--r--tests/bugs/md-cache/bug-1726205.t22
-rwxr-xr-xtests/bugs/md-cache/setxattr-prepoststat.t38
-rwxr-xr-xtests/bugs/nfs/bug-1053579.t3
-rw-r--r--tests/bugs/nfs/bug-1143880-fix-gNFSd-auth-crash.t4
-rw-r--r--tests/bugs/nfs/bug-1157223-symlink-mounting.t4
-rw-r--r--tests/bugs/nfs/bug-1161092-nfs-acls.t3
-rwxr-xr-xtests/bugs/nfs/bug-1166862.t3
-rw-r--r--tests/bugs/nfs/bug-1210338.c27
-rw-r--r--tests/bugs/nfs/bug-1210338.t3
-rwxr-xr-xtests/bugs/nfs/bug-1302948.t13
-rwxr-xr-xtests/bugs/nfs/bug-847622.t3
-rwxr-xr-xtests/bugs/nfs/bug-877885.t3
-rwxr-xr-xtests/bugs/nfs/bug-904065.t11
-rwxr-xr-xtests/bugs/nfs/bug-915280.t3
-rwxr-xr-xtests/bugs/nfs/bug-974972.t4
-rw-r--r--tests/bugs/nfs/showmount-many-clients.t43
-rwxr-xr-xtests/bugs/nfs/socket-as-fifo.py4
-rw-r--r--tests/bugs/nfs/socket-as-fifo.t5
-rw-r--r--tests/bugs/nfs/subdir-trailing-slash.t32
-rwxr-xr-xtests/bugs/nfs/zero-atime.t33
-rwxr-xr-xtests/bugs/nl-cache/bug-1451588.t25
-rwxr-xr-xtests/bugs/posix/bug-1040275-brick-uid-reset-on-volume-restart.t14
-rw-r--r--tests/bugs/posix/bug-1175711.c37
-rwxr-xr-xtests/bugs/posix/bug-1175711.t30
-rw-r--r--tests/bugs/posix/bug-1360679.t36
-rwxr-xr-xtests/bugs/posix/bug-1619720.t58
-rw-r--r--tests/bugs/posix/bug-1651445.t54
-rwxr-xr-xtests/bugs/posix/bug-990028.t3
-rw-r--r--tests/bugs/posix/bug-gfid-path.t70
-rw-r--r--tests/bugs/posix/disallow-gfid-volumeid-fremovexattr.c104
-rwxr-xr-xtests/bugs/posix/disallow-gfid-volumeid-fremovexattr.t21
-rw-r--r--tests/bugs/posix/disallow-gfid-volumeid-removexattr.t26
-rw-r--r--tests/bugs/protocol/bug-1321578.t82
-rw-r--r--tests/bugs/protocol/bug-1390914.t36
-rw-r--r--tests/bugs/protocol/bug-1433815-auth-allow.t40
-rwxr-xr-xtests/bugs/protocol/bug-762989.t2
-rw-r--r--tests/bugs/protocol/bug-808400-fcntl.c191
-rw-r--r--tests/bugs/protocol/bug-808400-flock.c124
-rwxr-xr-xtests/bugs/protocol/bug-808400-stripe.t32
-rwxr-xr-xtests/bugs/quick-read/bug-846240.t5
-rwxr-xr-xtests/bugs/quick-read/bz1523599/bz1523599.t32
-rw-r--r--tests/bugs/quick-read/bz1523599/test_bz1523599.c198
-rw-r--r--tests/bugs/quota/afr-quota-xattr-mdata-heal.t3
-rw-r--r--tests/bugs/quota/bug-1023974.t45
-rw-r--r--tests/bugs/quota/bug-1035576.t7
-rw-r--r--tests/bugs/quota/bug-1038598.t5
-rwxr-xr-xtests/bugs/quota/bug-1040423.t70
-rwxr-xr-xtests/bugs/quota/bug-1049323.t51
-rw-r--r--tests/bugs/quota/bug-1087198.t10
-rw-r--r--tests/bugs/quota/bug-1100050.t27
-rwxr-xr-xtests/bugs/quota/bug-1104692.t7
-rw-r--r--tests/bugs/quota/bug-1153964.t8
-rw-r--r--tests/bugs/quota/bug-1178130.t6
-rw-r--r--tests/bugs/quota/bug-1202244-support-inode-quota.t43
-rw-r--r--tests/bugs/quota/bug-1213364-disable-deem-statfs-when-quota-disable.t24
-rw-r--r--tests/bugs/quota/bug-1235182.t10
-rw-r--r--tests/bugs/quota/bug-1243798.t46
-rw-r--r--tests/bugs/quota/bug-1260545.t53
-rw-r--r--[-rwxr-xr-x]tests/bugs/quota/bug-1287996.t (renamed from tests/bugs/glusterd/bug-1022055.t)15
-rw-r--r--tests/bugs/quota/bug-1292020.t28
-rw-r--r--tests/bugs/quota/bug-1293601.t33
-rwxr-xr-xtests/bugs/rdma/bug-765473.t35
-rw-r--r--tests/bugs/readdir-ahead/bug-1390050.c72
-rw-r--r--tests/bugs/readdir-ahead/bug-1390050.t29
-rwxr-xr-xtests/bugs/readdir-ahead/bug-1436090.t44
-rwxr-xr-xtests/bugs/readdir-ahead/bug-1439640.t31
-rwxr-xr-xtests/bugs/readdir-ahead/bug-1446516.t21
-rwxr-xr-xtests/bugs/readdir-ahead/bug-1512437.t23
-rw-r--r--tests/bugs/readdir-ahead/bug-1670253-consistent-metadata.t23
-rwxr-xr-xtests/bugs/replicate/bug-1015990-rep.t21
-rwxr-xr-xtests/bugs/replicate/bug-1046624.t3
-rw-r--r--tests/bugs/replicate/bug-1058797.t3
-rw-r--r--tests/bugs/replicate/bug-1101647.t4
-rw-r--r--tests/bugs/replicate/bug-1130892.t16
-rw-r--r--tests/bugs/replicate/bug-1134691-afr-lookup-metadata-heal.t8
-rw-r--r--tests/bugs/replicate/bug-1180545.t35
-rw-r--r--tests/bugs/replicate/bug-1190069-afr-stale-index-entries.t10
-rw-r--r--tests/bugs/replicate/bug-1221481-allow-fops-on-dir-split-brain.t15
-rw-r--r--tests/bugs/replicate/bug-1238398-split-brain-resolution.t3
-rw-r--r--tests/bugs/replicate/bug-1250170-fsync.c78
-rw-r--r--tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t54
-rw-r--r--tests/bugs/replicate/bug-1292379.t58
-rw-r--r--tests/bugs/replicate/bug-1297695.t43
-rw-r--r--tests/bugs/replicate/bug-1305031-block-reads-on-metadata-sbrain.t40
-rw-r--r--tests/bugs/replicate/bug-1325792.t25
-rw-r--r--tests/bugs/replicate/bug-1335652.t29
-rw-r--r--tests/bugs/replicate/bug-1340623-mkdir-fails-remove-brick-started.t46
-rw-r--r--tests/bugs/replicate/bug-1341650.t63
-rw-r--r--tests/bugs/replicate/bug-1363721.t118
-rw-r--r--tests/bugs/replicate/bug-1365455.t54
-rw-r--r--tests/bugs/replicate/bug-1386188-sbrain-fav-child.t82
-rw-r--r--tests/bugs/replicate/bug-1402730.t47
-rw-r--r--tests/bugs/replicate/bug-1408712.t101
-rw-r--r--tests/bugs/replicate/bug-1417522-block-split-brain-resolution.t69
-rw-r--r--tests/bugs/replicate/bug-1433571-undo-pending-only-on-up-bricks.t79
-rw-r--r--tests/bugs/replicate/bug-1438255-do-not-mark-self-accusing-xattrs.t46
-rw-r--r--tests/bugs/replicate/bug-1448804-check-quorum-type-values.t47
-rw-r--r--tests/bugs/replicate/bug-1473026.t31
-rw-r--r--tests/bugs/replicate/bug-1477169-entry-selfheal-rename.t52
-rw-r--r--tests/bugs/replicate/bug-1480525.t18
-rw-r--r--tests/bugs/replicate/bug-1493415-gfid-heal.t78
-rw-r--r--tests/bugs/replicate/bug-1498570-client-iot-graph-check.t48
-rwxr-xr-xtests/bugs/replicate/bug-1539358-split-brain-detection.t89
-rw-r--r--tests/bugs/replicate/bug-1561129-enospc.t24
-rw-r--r--tests/bugs/replicate/bug-1586020-mark-dirty-for-entry-txn-on-quorum-failure.t72
-rw-r--r--tests/bugs/replicate/bug-1591193-assign-gfid-and-heal.t128
-rw-r--r--tests/bugs/replicate/bug-1626994-info-split-brain.t62
-rw-r--r--tests/bugs/replicate/bug-1637249-gfid-heal.t149
-rw-r--r--tests/bugs/replicate/bug-1637802-arbiter-stale-data-heal-lock.t45
-rw-r--r--tests/bugs/replicate/bug-1655050-dir-sbrain-size-policy.t55
-rwxr-xr-xtests/bugs/replicate/bug-1655052-sbrain-policy-same-size.t55
-rw-r--r--tests/bugs/replicate/bug-1655854-support-dist-to-rep3-arb-conversion.t95
-rw-r--r--tests/bugs/replicate/bug-1657783-do-not-update-read-subvol-on-rename-link.t40
-rw-r--r--tests/bugs/replicate/bug-1686568-send-truncate-on-arbiter-from-shd.t38
-rwxr-xr-xtests/bugs/replicate/bug-1696599-io-hang.t47
-rw-r--r--tests/bugs/replicate/bug-1717819-metadata-split-brain-detection.t136
-rw-r--r--tests/bugs/replicate/bug-1722507-type-mismatch-error-handling.t116
-rw-r--r--tests/bugs/replicate/bug-1728770-pass-xattrs.t52
-rw-r--r--tests/bugs/replicate/bug-1734370-entry-heal-restore-time.t102
-rw-r--r--tests/bugs/replicate/bug-1744548-heal-timeout.t47
-rw-r--r--tests/bugs/replicate/bug-1749322-entry-heal-not-happening.t89
-rw-r--r--tests/bugs/replicate/bug-1756938-replica-3-sbrain-cli.t111
-rw-r--r--tests/bugs/replicate/bug-1761531-metadata-heal-restore-time.t74
-rw-r--r--tests/bugs/replicate/bug-1801624-entry-heal.t58
-rwxr-xr-xtests/bugs/replicate/bug-802417.t17
-rw-r--r--tests/bugs/replicate/bug-821056.t4
-rwxr-xr-xtests/bugs/replicate/bug-830665.t7
-rwxr-xr-xtests/bugs/replicate/bug-853680.t53
-rw-r--r--tests/bugs/replicate/bug-880898.t7
-rw-r--r--tests/bugs/replicate/bug-913051.t13
-rwxr-xr-x[-rw-r--r--]tests/bugs/replicate/bug-921231.t4
-rw-r--r--tests/bugs/replicate/bug-966018.t35
-rw-r--r--tests/bugs/replicate/bug-976800.t2
-rwxr-xr-xtests/bugs/replicate/bug-977797.t65
-rwxr-xr-xtests/bugs/replicate/bug-979365.t2
-rw-r--r--tests/bugs/replicate/issue-1254-prioritize-enospc.t80
-rw-r--r--tests/bugs/replicate/mdata-heal-no-xattrs.t59
-rw-r--r--tests/bugs/replicate/ta-inode-refresh-read.t40
-rwxr-xr-xtests/bugs/rpc/bug-1043886.t3
-rwxr-xr-xtests/bugs/rpc/bug-847624.t4
-rwxr-xr-xtests/bugs/rpc/bug-921072.t18
-rwxr-xr-xtests/bugs/rpc/bug-954057.t10
-rw-r--r--tests/bugs/shard/bug-1245547.t4
-rw-r--r--tests/bugs/shard/bug-1248887.t1
-rw-r--r--tests/bugs/shard/bug-1251824.t18
-rw-r--r--tests/bugs/shard/bug-1256580.t3
-rw-r--r--tests/bugs/shard/bug-1258334.t3
-rw-r--r--tests/bugs/shard/bug-1259651.t3
-rw-r--r--tests/bugs/shard/bug-1260637.t3
-rw-r--r--tests/bugs/shard/bug-1261773.t14
-rw-r--r--tests/bugs/shard/bug-1272986.t35
-rw-r--r--tests/bugs/shard/bug-1342298.t23
-rw-r--r--tests/bugs/shard/bug-1468483.t58
-rw-r--r--tests/bugs/shard/bug-1488546.t25
-rw-r--r--tests/bugs/shard/bug-1568521-EEXIST.t91
-rw-r--r--tests/bugs/shard/bug-1568521.t53
-rw-r--r--tests/bugs/shard/bug-1605056-2.t34
-rw-r--r--tests/bugs/shard/bug-1605056.t63
-rw-r--r--tests/bugs/shard/bug-1669077.t29
-rw-r--r--tests/bugs/shard/bug-1696136-lru-limit-equals-deletion-rate.t34
-rw-r--r--tests/bugs/shard/bug-1696136.c122
-rw-r--r--tests/bugs/shard/bug-1696136.t33
-rw-r--r--tests/bugs/shard/bug-1705884.t32
-rw-r--r--tests/bugs/shard/bug-1738419.t29
-rw-r--r--tests/bugs/shard/bug-shard-discard.c70
-rw-r--r--tests/bugs/shard/bug-shard-discard.t65
-rw-r--r--tests/bugs/shard/bug-shard-zerofill.c60
-rw-r--r--tests/bugs/shard/bug-shard-zerofill.t46
-rw-r--r--tests/bugs/shard/configure-lru-limit.t52
-rw-r--r--tests/bugs/shard/issue-1243.t43
-rw-r--r--tests/bugs/shard/issue-1281.t34
-rw-r--r--tests/bugs/shard/issue-1425.t45
-rw-r--r--tests/bugs/shard/parallel-truncate-read.t48
-rw-r--r--tests/bugs/shard/shard-append-test.c183
-rw-r--r--tests/bugs/shard/shard-append-test.t32
-rw-r--r--tests/bugs/shard/shard-fallocate.c113
-rw-r--r--tests/bugs/shard/shard-inode-refcount-test.t30
-rw-r--r--tests/bugs/shard/unlinks-and-renames.t333
-rw-r--r--tests/bugs/shard/zero-flag.t76
-rw-r--r--tests/bugs/snapshot/bug-1109889.t4
-rwxr-xr-x[-rw-r--r--]tests/bugs/snapshot/bug-1111041.t (renamed from tests/bugs/glusterd/bug-1111041.t)12
-rw-r--r--tests/bugs/snapshot/bug-1140162-file-snapshot-features-encrypt-opts-validation.t33
-rw-r--r--tests/bugs/snapshot/bug-1155042-dont-display-deactivated-snapshots.t6
-rw-r--r--tests/bugs/snapshot/bug-1164613.t35
-rwxr-xr-xtests/bugs/snapshot/bug-1166197.t3
-rw-r--r--tests/bugs/snapshot/bug-1167580-set-proper-uid-and-gid-during-nfs-access.t5
-rw-r--r--tests/bugs/snapshot/bug-1202436-calculate-quota-cksum-during-snap-restore.t1
-rw-r--r--tests/bugs/snapshot/bug-1227646.t1
-rw-r--r--tests/bugs/snapshot/bug-1260848.t28
-rwxr-xr-xtests/bugs/snapshot/bug-1275616.t50
-rw-r--r--tests/bugs/snapshot/bug-1279327.t29
-rw-r--r--tests/bugs/snapshot/bug-1316437.t29
-rw-r--r--tests/bugs/snapshot/bug-1322772-real-path-fix-for-snapshot.t56
-rwxr-xr-xtests/bugs/snapshot/bug-1399598-uss-with-ssl.t108
-rw-r--r--tests/bugs/snapshot/bug-1482023-snpashot-issue-with-other-processes-accessing-mounted-path.t133
-rw-r--r--tests/bugs/snapshot/bug-1512451-snapshot-creation-failed-after-brick-reset.t39
-rw-r--r--tests/bugs/snapshot/bug-1597662.t58
-rw-r--r--tests/bugs/snapshot/bug-1618004-fix-memory-corruption-in-snap-import.t48
-rw-r--r--tests/bugs/stripe/bug-1002207.t2
-rw-r--r--tests/bugs/stripe/bug-1111454.t2
-rw-r--r--tests/bugs/tier/bug-1205545-CTR-and-trash-integration.t71
-rwxr-xr-xtests/bugs/trace/bug-797171.t4
-rwxr-xr-xtests/bugs/transport/bug-873367.t2
-rw-r--r--tests/bugs/unclassified/bug-1357397.t35
-rw-r--r--tests/bugs/unclassified/bug-874498.t4
-rwxr-xr-xtests/bugs/upcall/bug-1369430.t43
-rwxr-xr-xtests/bugs/upcall/bug-1394131.t29
-rwxr-xr-xtests/bugs/upcall/bug-1422776.t30
-rwxr-xr-xtests/bugs/upcall/bug-1458127.t36
-rwxr-xr-xtests/bugs/upcall/bug-upcall-stat.t39
-rw-r--r--tests/bugs/write-behind/bug-1058663.c158
-rw-r--r--tests/bugs/write-behind/bug-1279730.c149
-rwxr-xr-xtests/bugs/write-behind/bug-1279730.t37
-rw-r--r--tests/bugs/write-behind/issue-884.c267
-rwxr-xr-xtests/bugs/write-behind/issue-884.t40
-rw-r--r--tests/cleanup.sh4
-rw-r--r--tests/cluster.rc84
-rw-r--r--tests/configfiles/exports-v61
-rw-r--r--tests/configfiles/netgroups1
-rw-r--r--tests/dht.rc63
-rw-r--r--tests/ec.rc18
-rwxr-xr-xtests/encryption/crypt.t87
-rw-r--r--tests/encryption/frag.c328
-rw-r--r--tests/env.rc.in24
-rw-r--r--tests/experimental/.gitignore7
-rw-r--r--tests/fdl.rc12
-rwxr-xr-xtests/features/delay-gen.t52
-rw-r--r--tests/features/fdl-overflow.t72
-rw-r--r--tests/features/fdl.t44
-rw-r--r--tests/features/flock_interrupt.t32
-rw-r--r--tests/features/fuse-lru-limit.t43
-rw-r--r--tests/features/glfs-lease-recall.c372
-rw-r--r--tests/features/glfs-lease.c717
-rwxr-xr-xtests/features/glfs-lease.t31
-rwxr-xr-xtests/features/glupy.t31
-rw-r--r--tests/features/interrupt.t71
-rwxr-xr-xtests/features/ipc.t3
-rwxr-xr-xtests/features/ipctest.py24
-rw-r--r--tests/features/lock_revocation.t54
-rw-r--r--tests/features/mandatory-lock-forced.c143
-rw-r--r--tests/features/mandatory-lock-forced.t80
-rwxr-xr-xtests/features/nuke.t41
-rw-r--r--tests/features/open_and_sleep.c27
-rw-r--r--tests/features/recon.t59
-rwxr-xr-xtests/features/ssl-authz.t26
-rw-r--r--tests/features/ssl-ciphers.t94
-rw-r--r--tests/features/subdir-mount.t121
-rwxr-xr-xtests/features/trash.t96
-rwxr-xr-xtests/features/unhashed-auto.t2
-rwxr-xr-xtests/features/worm.t117
-rw-r--r--tests/features/worm_sh.t75
-rw-r--r--tests/geo-rep.rc513
-rw-r--r--tests/geo-rep/georep-basic-dr-rsync.t125
-rw-r--r--tests/geo-rep/georep-basic-dr-tarssh.t127
-rw-r--r--tests/gfid2path/block-mount-access.t51
-rw-r--r--tests/gfid2path/get-gfid-to-path.t72
-rw-r--r--tests/gfid2path/gfid2path_fuse.t166
-rw-r--r--tests/gfid2path/gfid2path_nfs.t152
-rw-r--r--tests/glusterfind/glusterfind-basic.t84
-rw-r--r--tests/include.rc334
-rw-r--r--tests/line-coverage/afr-heal-info.t43
-rwxr-xr-xtests/line-coverage/arbiter-coverage.t32
-rw-r--r--tests/line-coverage/cli-peer-and-volume-operations.t135
-rw-r--r--tests/line-coverage/cli-volume-top-profile-coverage.t62
-rwxr-xr-xtests/line-coverage/errorgen-coverage.t42
-rw-r--r--tests/line-coverage/log-and-brick-ops-negative-case.t82
-rwxr-xr-xtests/line-coverage/meta-max-coverage.t33
-rw-r--r--tests/line-coverage/namespace-linecoverage.t39
-rwxr-xr-xtests/line-coverage/old-protocol.t37
-rwxr-xr-xtests/line-coverage/quiesce-coverage.t44
-rw-r--r--tests/line-coverage/shard-coverage.t33
-rw-r--r--tests/line-coverage/some-features-in-libglusterfs.t67
-rw-r--r--tests/line-coverage/volfile-with-all-graph-syntax.t73
-rwxr-xr-xtests/performance/open-behind.t13
-rw-r--r--tests/snapshot.rc34
-rw-r--r--tests/ssl.rc35
-rw-r--r--tests/thin-arbiter.rc613
-rw-r--r--tests/traps.rc22
-rw-r--r--tests/utils/arequal-checksum.c878
-rw-r--r--tests/utils/changelog/changelog.h125
-rw-r--r--tests/utils/changelog/get-history.c71
-rw-r--r--tests/utils/changelog/test-changelog-api.c98
-rw-r--r--tests/utils/changelog/test-history-api.c111
-rw-r--r--tests/utils/changelogparser.py236
-rwxr-xr-xtests/utils/create-files.py20
-rw-r--r--tests/utils/get-mdata-xattr.c152
-rwxr-xr-xtests/utils/getfattr.py22
-rwxr-xr-xtests/utils/gfid-access.py70
-rw-r--r--tests/utils/libcxattr.py29
-rwxr-xr-xtests/utils/pidof.py12
-rw-r--r--tests/utils/py2py3.py186
-rwxr-xr-xtests/utils/setfattr.py3
-rw-r--r--tests/vagrant/vagrant-template-centos6/Vagrantfile55
-rw-r--r--tests/vagrant/vagrant-template-centos6/roles/daemon-services/tasks/main.yml3
-rw-r--r--tests/vagrant/vagrant-template-centos6/roles/fix-localhost/tasks/main.yml6
-rw-r--r--tests/vagrant/vagrant-template-centos6/roles/install-pkgs/tasks/main.yml92
-rw-r--r--tests/vagrant/vagrant-template-centos6/roles/iptables/tasks/main.yml3
-rw-r--r--tests/vagrant/vagrant-template-centos6/roles/mock-user/tasks/main.yml3
-rw-r--r--tests/vagrant/vagrant-template-centos6/roles/prepare-brick/tasks/main.yml6
-rw-r--r--tests/vagrant/vagrant-template-centos6/roles/remove-gluster-pkgs/tasks/main.yml4
-rw-r--r--tests/vagrant/vagrant-template-centos6/setup.yml15
-rw-r--r--tests/vagrant/vagrant-template-fedora/Vagrantfile56
-rw-r--r--tests/vagrant/vagrant-template-fedora/roles/daemon-services/tasks/main.yml3
-rw-r--r--tests/vagrant/vagrant-template-fedora/roles/fix-localhost/tasks/main.yml6
-rw-r--r--tests/vagrant/vagrant-template-fedora/roles/install-pkgs/tasks/main.yml85
-rw-r--r--tests/vagrant/vagrant-template-fedora/roles/iptables/tasks/main.yml3
-rw-r--r--tests/vagrant/vagrant-template-fedora/roles/mock-user/tasks/main.yml3
-rw-r--r--tests/vagrant/vagrant-template-fedora/roles/prepare-brick/tasks/main.yml6
-rw-r--r--tests/vagrant/vagrant-template-fedora/roles/remove-gluster-pkgs/tasks/main.yml4
-rw-r--r--tests/vagrant/vagrant-template-fedora/roles/selinux/tasks/main.yml3
-rw-r--r--tests/vagrant/vagrant-template-fedora/setup.yml16
-rw-r--r--tests/volume.rc430
-rw-r--r--tools/Makefile.am2
-rw-r--r--tools/gfind_missing_files/Makefile.am10
-rw-r--r--tools/gfind_missing_files/gcrawler.c787
-rw-r--r--tools/gfind_missing_files/gfid_to_path.py2
-rw-r--r--tools/gfind_missing_files/gfid_to_path.sh5
-rw-r--r--tools/gfind_missing_files/gfind_missing_files.sh14
-rw-r--r--tools/glusterfind/Makefile.am20
-rwxr-xr-xtools/glusterfind/S57glusterfind-delete-post.py15
-rw-r--r--tools/glusterfind/glusterfind.in3
-rw-r--r--tools/glusterfind/src/Makefile.am6
-rw-r--r--tools/glusterfind/src/__init__.py2
-rw-r--r--tools/glusterfind/src/brickfind.py42
-rw-r--r--tools/glusterfind/src/changelog.py144
-rw-r--r--tools/glusterfind/src/changelogdata.py65
-rw-r--r--tools/glusterfind/src/conf.py9
-rw-r--r--tools/glusterfind/src/gfind_py2py3.py88
-rw-r--r--tools/glusterfind/src/libgfchangelog.py43
-rw-r--r--tools/glusterfind/src/main.py558
-rw-r--r--tools/glusterfind/src/nodeagent.py18
-rw-r--r--tools/glusterfind/src/utils.py58
-rw-r--r--tools/setgfid2path/Makefile.am5
-rw-r--r--tools/setgfid2path/gluster-setgfid2path.854
-rw-r--r--tools/setgfid2path/src/Makefile.am16
-rw-r--r--tools/setgfid2path/src/main.c130
-rw-r--r--xlators/Makefile.am13
-rw-r--r--xlators/cluster/Makefile.am2
-rw-r--r--xlators/cluster/afr/src/Makefile.am13
-rw-r--r--xlators/cluster/afr/src/afr-common.c10432
-rw-r--r--xlators/cluster/afr/src/afr-dir-read.c509
-rw-r--r--xlators/cluster/afr/src/afr-dir-read.h21
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.c2151
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.h33
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.c2792
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.h32
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.c3566
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.h78
-rw-r--r--xlators/cluster/afr/src/afr-lk-common.c2141
-rw-r--r--xlators/cluster/afr/src/afr-mem-types.h54
-rw-r--r--xlators/cluster/afr/src/afr-messages.h468
-rw-r--r--xlators/cluster/afr/src/afr-open.c528
-rw-r--r--xlators/cluster/afr/src/afr-read-txn.c590
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c3557
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-data.c1405
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-entry.c1871
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-metadata.c817
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-name.c1092
-rw-r--r--xlators/cluster/afr/src/afr-self-heal.h441
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.c2376
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.h82
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c4035
-rw-r--r--xlators/cluster/afr/src/afr-transaction.h63
-rw-r--r--xlators/cluster/afr/src/afr.c1870
-rw-r--r--xlators/cluster/afr/src/afr.h1887
-rw-r--r--xlators/cluster/afr/src/pump.c2470
-rw-r--r--xlators/cluster/afr/src/pump.h81
-rw-r--r--xlators/cluster/dht/src/Makefile.am26
-rw-r--r--xlators/cluster/dht/src/dht-common.c16089
-rw-r--r--xlators/cluster/dht/src/dht-common.h2007
-rw-r--r--xlators/cluster/dht/src/dht-diskusage.c804
-rw-r--r--xlators/cluster/dht/src/dht-hashfn.c139
-rw-r--r--xlators/cluster/dht/src/dht-helper.c3335
-rw-r--r--xlators/cluster/dht/src/dht-inode-read.c2167
-rw-r--r--xlators/cluster/dht/src/dht-inode-write.c1990
-rw-r--r--xlators/cluster/dht/src/dht-layout.c1282
-rw-r--r--xlators/cluster/dht/src/dht-linkfile.c522
-rw-r--r--xlators/cluster/dht/src/dht-lock.c1392
-rw-r--r--xlators/cluster/dht/src/dht-lock.h91
-rw-r--r--xlators/cluster/dht/src/dht-mem-types.h44
-rw-r--r--xlators/cluster/dht/src/dht-messages.h1340
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c6723
-rw-r--r--xlators/cluster/dht/src/dht-rename.c2833
-rw-r--r--xlators/cluster/dht/src/dht-selfheal.c4082
-rw-r--r--xlators/cluster/dht/src/dht-shared.c1720
-rw-r--r--xlators/cluster/dht/src/dht.c160
-rw-r--r--xlators/cluster/dht/src/nufa.c1100
-rw-r--r--xlators/cluster/dht/src/switch.c1479
-rw-r--r--xlators/cluster/dht/src/tier.c1399
-rw-r--r--xlators/cluster/dht/src/tier.h73
-rw-r--r--xlators/cluster/dht/src/unittest/dht_layout_mock.c39
-rw-r--r--xlators/cluster/dht/src/unittest/dht_layout_unittest.c26
-rw-r--r--xlators/cluster/ec/src/Makefile.am38
-rw-r--r--xlators/cluster/ec/src/ec-code-avx.c109
-rw-r--r--xlators/cluster/ec/src/ec-code-avx.h (renamed from xlators/cluster/dht/src/dht-helper.h)15
-rw-r--r--xlators/cluster/ec/src/ec-code-c.c11679
-rw-r--r--xlators/cluster/ec/src/ec-code-c.h27
-rw-r--r--xlators/cluster/ec/src/ec-code-intel.c594
-rw-r--r--xlators/cluster/ec/src/ec-code-intel.h191
-rw-r--r--xlators/cluster/ec/src/ec-code-sse.c101
-rw-r--r--xlators/cluster/ec/src/ec-code-sse.h (renamed from libglusterfs/src/gfdb/gfdb_mem-types.h)16
-rw-r--r--xlators/cluster/ec/src/ec-code-x64.c144
-rw-r--r--xlators/cluster/ec/src/ec-code-x64.h18
-rw-r--r--xlators/cluster/ec/src/ec-code.c1060
-rw-r--r--xlators/cluster/ec/src/ec-code.h44
-rw-r--r--xlators/cluster/ec/src/ec-combine.c760
-rw-r--r--xlators/cluster/ec/src/ec-combine.h38
-rw-r--r--xlators/cluster/ec/src/ec-common.c2148
-rw-r--r--xlators/cluster/ec/src/ec-common.h286
-rw-r--r--xlators/cluster/ec/src/ec-data.c223
-rw-r--r--xlators/cluster/ec/src/ec-data.h322
-rw-r--r--xlators/cluster/ec/src/ec-dir-read.c398
-rw-r--r--xlators/cluster/ec/src/ec-dir-write.c703
-rw-r--r--xlators/cluster/ec/src/ec-fops.h416
-rw-r--r--xlators/cluster/ec/src/ec-galois.c183
-rw-r--r--xlators/cluster/ec/src/ec-galois.h32
-rw-r--r--xlators/cluster/ec/src/ec-generic.c944
-rw-r--r--xlators/cluster/ec/src/ec-gf.c11635
-rw-r--r--xlators/cluster/ec/src/ec-gf8.c5882
-rw-r--r--xlators/cluster/ec/src/ec-gf8.h (renamed from xlators/cluster/ec/src/ec-gf.h)11
-rw-r--r--xlators/cluster/ec/src/ec-heal.c4687
-rw-r--r--xlators/cluster/ec/src/ec-heald.c981
-rw-r--r--xlators/cluster/ec/src/ec-heald.h41
-rw-r--r--xlators/cluster/ec/src/ec-helpers.c482
-rw-r--r--xlators/cluster/ec/src/ec-helpers.h223
-rw-r--r--xlators/cluster/ec/src/ec-inode-read.c1268
-rw-r--r--xlators/cluster/ec/src/ec-inode-write.c2030
-rw-r--r--xlators/cluster/ec/src/ec-locks.c701
-rw-r--r--xlators/cluster/ec/src/ec-mem-types.h11
-rw-r--r--xlators/cluster/ec/src/ec-messages.h557
-rw-r--r--xlators/cluster/ec/src/ec-method.c488
-rw-r--r--xlators/cluster/ec/src/ec-method.h34
-rw-r--r--xlators/cluster/ec/src/ec-types.h690
-rw-r--r--xlators/cluster/ec/src/ec.c1937
-rw-r--r--xlators/cluster/ec/src/ec.h67
-rw-r--r--xlators/cluster/ha/src/Makefile.am16
-rw-r--r--xlators/cluster/ha/src/ha-helpers.c194
-rw-r--r--xlators/cluster/ha/src/ha-mem-types.h26
-rw-r--r--xlators/cluster/ha/src/ha.c4008
-rw-r--r--xlators/cluster/ha/src/ha.h53
-rw-r--r--xlators/cluster/map/src/Makefile.am16
-rw-r--r--xlators/cluster/map/src/map-helper.c343
-rw-r--r--xlators/cluster/map/src/map-mem-types.h24
-rw-r--r--xlators/cluster/map/src/map.c2561
-rw-r--r--xlators/cluster/map/src/map.h67
-rw-r--r--xlators/cluster/stripe/src/Makefile.am19
-rw-r--r--xlators/cluster/stripe/src/stripe-helpers.c677
-rw-r--r--xlators/cluster/stripe/src/stripe-mem-types.h31
-rw-r--r--xlators/cluster/stripe/src/stripe.c5763
-rw-r--r--xlators/cluster/stripe/src/stripe.h281
-rw-r--r--xlators/debug/Makefile.am2
-rw-r--r--xlators/debug/delay-gen/Makefile.am (renamed from xlators/features/ganesha/Makefile.am)0
-rw-r--r--xlators/debug/delay-gen/src/Makefile.am11
-rw-r--r--xlators/debug/delay-gen/src/delay-gen-mem-types.h21
-rw-r--r--xlators/debug/delay-gen/src/delay-gen-messages.h26
-rw-r--r--xlators/debug/delay-gen/src/delay-gen.c697
-rw-r--r--xlators/debug/delay-gen/src/delay-gen.h27
-rw-r--r--xlators/debug/error-gen/src/Makefile.am5
-rw-r--r--xlators/debug/error-gen/src/error-gen-mem-types.h6
-rw-r--r--xlators/debug/error-gen/src/error-gen.c2992
-rw-r--r--xlators/debug/error-gen/src/error-gen.h26
-rw-r--r--xlators/debug/io-stats/src/Makefile.am7
-rw-r--r--xlators/debug/io-stats/src/io-stats-mem-types.h17
-rw-r--r--xlators/debug/io-stats/src/io-stats.c6157
-rw-r--r--xlators/debug/sink/Makefile.am (renamed from xlators/features/qemu-block/Makefile.am)1
-rw-r--r--xlators/debug/sink/src/Makefile.am14
-rw-r--r--xlators/debug/sink/src/sink.c94
-rw-r--r--xlators/debug/trace/src/Makefile.am5
-rw-r--r--xlators/debug/trace/src/trace-mem-types.h7
-rw-r--r--xlators/debug/trace/src/trace.c5413
-rw-r--r--xlators/debug/trace/src/trace.h65
-rw-r--r--xlators/encryption/Makefile.am3
-rw-r--r--xlators/encryption/crypt/src/Makefile.am24
-rw-r--r--xlators/encryption/crypt/src/atom.c957
-rw-r--r--xlators/encryption/crypt/src/crypt-common.h141
-rw-r--r--xlators/encryption/crypt/src/crypt-mem-types.h45
-rw-r--r--xlators/encryption/crypt/src/crypt.c4526
-rw-r--r--xlators/encryption/crypt/src/crypt.h900
-rw-r--r--xlators/encryption/crypt/src/data.c764
-rw-r--r--xlators/encryption/crypt/src/keys.c297
-rw-r--r--xlators/encryption/crypt/src/metadata.c614
-rw-r--r--xlators/encryption/crypt/src/metadata.h74
-rw-r--r--xlators/encryption/rot-13/src/rot-13.c196
-rw-r--r--xlators/features/Makefile.am15
-rw-r--r--xlators/features/arbiter/src/Makefile.am8
-rw-r--r--xlators/features/arbiter/src/arbiter-mem-types.h7
-rw-r--r--xlators/features/arbiter/src/arbiter.c503
-rw-r--r--xlators/features/arbiter/src/arbiter.h6
-rw-r--r--xlators/features/barrier/src/Makefile.am5
-rw-r--r--xlators/features/barrier/src/barrier-mem-types.h6
-rw-r--r--xlators/features/barrier/src/barrier.c1076
-rw-r--r--xlators/features/barrier/src/barrier.h129
-rw-r--r--xlators/features/bit-rot/src/bitd/Makefile.am19
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-bitd-messages.h479
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-scrub-status.c78
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-scrub-status.h50
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-scrub.c2706
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-scrub.h36
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-ssm.c137
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-ssm.h28
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-tbf.c306
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot-tbf.h70
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot.c3218
-rw-r--r--xlators/features/bit-rot/src/bitd/bit-rot.h341
-rw-r--r--xlators/features/bit-rot/src/stub/Makefile.am12
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-common.h181
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-object-version.h12
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub-helpers.c796
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub-mem-types.h38
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h273
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub.c4726
-rw-r--r--xlators/features/bit-rot/src/stub/bit-rot-stub.h661
-rw-r--r--xlators/features/changelog/lib/examples/c/get-changes-multi.c80
-rw-r--r--xlators/features/changelog/lib/examples/c/get-changes.c102
-rw-r--r--xlators/features/changelog/lib/examples/c/get-history.c148
-rwxr-xr-x[-rw-r--r--]xlators/features/changelog/lib/examples/python/changes.py13
-rw-r--r--xlators/features/changelog/lib/examples/python/libgfchangelog.py3
-rw-r--r--xlators/features/changelog/lib/src/Makefile.am34
-rw-r--r--xlators/features/changelog/lib/src/changelog-lib-messages.h327
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-api.c319
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-helpers.c252
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-helpers.h244
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-journal-handler.c1641
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-journal.h94
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-reborp.c583
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-rpc.c93
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog-rpc.h10
-rw-r--r--xlators/features/changelog/lib/src/gf-changelog.c881
-rw-r--r--xlators/features/changelog/lib/src/gf-history-changelog.c1492
-rw-r--r--xlators/features/changelog/src/Makefile.am27
-rw-r--r--xlators/features/changelog/src/changelog-barrier.c141
-rw-r--r--xlators/features/changelog/src/changelog-encoders.c298
-rw-r--r--xlators/features/changelog/src/changelog-encoders.h42
-rw-r--r--xlators/features/changelog/src/changelog-ev-handle.c576
-rw-r--r--xlators/features/changelog/src/changelog-ev-handle.h110
-rw-r--r--xlators/features/changelog/src/changelog-helpers.c2881
-rw-r--r--xlators/features/changelog/src/changelog-helpers.h892
-rw-r--r--xlators/features/changelog/src/changelog-mem-types.h33
-rw-r--r--xlators/features/changelog/src/changelog-messages.h590
-rw-r--r--xlators/features/changelog/src/changelog-misc.h164
-rw-r--r--xlators/features/changelog/src/changelog-rpc-common.c516
-rw-r--r--xlators/features/changelog/src/changelog-rpc-common.h59
-rw-r--r--xlators/features/changelog/src/changelog-rpc.c588
-rw-r--r--xlators/features/changelog/src/changelog-rpc.h10
-rw-r--r--xlators/features/changelog/src/changelog-rt.c63
-rw-r--r--xlators/features/changelog/src/changelog-rt.h14
-rw-r--r--xlators/features/changelog/src/changelog.c4558
-rw-r--r--xlators/features/changetimerecorder/src/Makefile.am23
-rw-r--r--xlators/features/changetimerecorder/src/changetimerecorder.c1723
-rw-r--r--xlators/features/changetimerecorder/src/changetimerecorder.h21
-rw-r--r--xlators/features/changetimerecorder/src/ctr-helper.c300
-rw-r--r--xlators/features/changetimerecorder/src/ctr-helper.h731
-rw-r--r--xlators/features/changetimerecorder/src/ctr-xlator-ctx.c409
-rw-r--r--xlators/features/changetimerecorder/src/ctr-xlator-ctx.h90
-rw-r--r--xlators/features/changetimerecorder/src/ctr_mem_types.h24
-rw-r--r--xlators/features/cloudsync/Makefile.am (renamed from xlators/storage/bd/Makefile.am)0
-rw-r--r--xlators/features/cloudsync/src/Makefile.am46
-rw-r--r--xlators/features/cloudsync/src/cloudsync-autogen-fops-tmpl.c30
-rw-r--r--xlators/features/cloudsync/src/cloudsync-autogen-fops-tmpl.h (renamed from libglusterfs/src/tw.h)19
-rw-r--r--xlators/features/cloudsync/src/cloudsync-common.c60
-rw-r--r--xlators/features/cloudsync/src/cloudsync-common.h134
-rwxr-xr-xxlators/features/cloudsync/src/cloudsync-fops-c.py324
-rwxr-xr-xxlators/features/cloudsync/src/cloudsync-fops-h.py31
-rw-r--r--xlators/features/cloudsync/src/cloudsync-mem-types.h22
-rw-r--r--xlators/features/cloudsync/src/cloudsync-messages.h16
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/Makefile.am (renamed from xlators/cluster/map/Makefile.am)2
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/Makefile.am11
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/Makefile.am (renamed from xlators/cluster/stripe/Makefile.am)2
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/Makefile.am12
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3-mem-types.h19
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3.c584
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3.h50
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/libcloudsyncs3.sym1
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/Makefile.am (renamed from xlators/encryption/rot-13/Makefile.am)2
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/Makefile.am12
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/archivestore.h203
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/cvlt-messages.h30
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcloudsynccvlt.sym1
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcvlt-mem-types.h19
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcvlt.c842
-rw-r--r--xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/libcvlt.h84
-rw-r--r--xlators/features/cloudsync/src/cloudsync.c2076
-rw-r--r--xlators/features/cloudsync/src/cloudsync.h123
-rw-r--r--xlators/features/compress/src/Makefile.am8
-rw-r--r--xlators/features/compress/src/cdc-helper.c761
-rw-r--r--xlators/features/compress/src/cdc-mem-types.h10
-rw-r--r--xlators/features/compress/src/cdc.c578
-rw-r--r--xlators/features/compress/src/cdc.h76
-rw-r--r--xlators/features/filter/Makefile.am3
-rw-r--r--xlators/features/filter/src/Makefile.am16
-rw-r--r--xlators/features/filter/src/filter.c1729
-rw-r--r--xlators/features/ganesha/src/Makefile.am18
-rw-r--r--xlators/features/ganesha/src/ganesha.c90
-rw-r--r--xlators/features/ganesha/src/ganesha.h18
-rw-r--r--xlators/features/gfid-access/src/Makefile.am5
-rw-r--r--xlators/features/gfid-access/src/gfid-access-mem-types.h9
-rw-r--r--xlators/features/gfid-access/src/gfid-access.c2198
-rw-r--r--xlators/features/gfid-access/src/gfid-access.h132
-rw-r--r--xlators/features/glupy/Makefile.am3
-rw-r--r--xlators/features/glupy/doc/README.md44
-rw-r--r--xlators/features/glupy/doc/TESTING9
-rw-r--r--xlators/features/glupy/doc/test.vol10
-rw-r--r--xlators/features/glupy/examples/Makefile.am5
-rw-r--r--xlators/features/glupy/examples/debug-trace.py775
-rw-r--r--xlators/features/glupy/examples/helloworld.py19
-rw-r--r--xlators/features/glupy/examples/negative.py91
-rw-r--r--xlators/features/glupy/src/Makefile.am24
-rw-r--r--xlators/features/glupy/src/glupy.c2496
-rw-r--r--xlators/features/glupy/src/glupy.h56
-rw-r--r--xlators/features/glupy/src/glupy/Makefile.am5
-rw-r--r--xlators/features/glupy/src/glupy/__init__.py852
-rw-r--r--xlators/features/glupy/src/setup.py.in24
-rw-r--r--xlators/features/index/src/Makefile.am10
-rw-r--r--xlators/features/index/src/index-mem-types.h15
-rw-r--r--xlators/features/index/src/index-messages.h33
-rw-r--r--xlators/features/index/src/index.c3420
-rw-r--r--xlators/features/index/src/index.h89
-rw-r--r--xlators/features/leases/Makefile.am (renamed from xlators/encryption/crypt/Makefile.am)2
-rw-r--r--xlators/features/leases/src/Makefile.am20
-rw-r--r--xlators/features/leases/src/leases-internal.c1412
-rw-r--r--xlators/features/leases/src/leases-mem-types.h27
-rw-r--r--xlators/features/leases/src/leases-messages.h33
-rw-r--r--xlators/features/leases/src/leases.c1168
-rw-r--r--xlators/features/leases/src/leases.h259
-rw-r--r--xlators/features/locks/src/Makefile.am14
-rw-r--r--xlators/features/locks/src/clear.c684
-rw-r--r--xlators/features/locks/src/clear.h66
-rw-r--r--xlators/features/locks/src/common.c1948
-rw-r--r--xlators/features/locks/src/common.h258
-rw-r--r--xlators/features/locks/src/entrylk.c1489
-rw-r--r--xlators/features/locks/src/inodelk.c1580
-rw-r--r--xlators/features/locks/src/locks-mem-types.h23
-rw-r--r--xlators/features/locks/src/locks.h327
-rw-r--r--xlators/features/locks/src/pl-messages.h29
-rw-r--r--xlators/features/locks/src/posix.c6351
-rw-r--r--xlators/features/locks/src/reservelk.c580
-rw-r--r--xlators/features/locks/tests/unit-test.c101
-rw-r--r--xlators/features/mac-compat/Makefile.am3
-rw-r--r--xlators/features/mac-compat/src/Makefile.am15
-rw-r--r--xlators/features/mac-compat/src/mac-compat.c344
-rw-r--r--xlators/features/mac-compat/src/mac-compat.h41
-rw-r--r--xlators/features/marker/src/Makefile.am13
-rw-r--r--xlators/features/marker/src/marker-common.c74
-rw-r--r--xlators/features/marker/src/marker-common.h7
-rw-r--r--xlators/features/marker/src/marker-mem-types.h23
-rw-r--r--xlators/features/marker/src/marker-quota-helper.c606
-rw-r--r--xlators/features/marker/src/marker-quota-helper.h81
-rw-r--r--xlators/features/marker/src/marker-quota.c5622
-rw-r--r--xlators/features/marker/src/marker-quota.h201
-rw-r--r--xlators/features/marker/src/marker.c4578
-rw-r--r--xlators/features/marker/src/marker.h225
-rw-r--r--xlators/features/metadisp/Makefile.am3
-rw-r--r--xlators/features/metadisp/src/Makefile.am38
-rw-r--r--xlators/features/metadisp/src/backend.c45
-rw-r--r--xlators/features/metadisp/src/fops-tmpl.c10
-rw-r--r--xlators/features/metadisp/src/gen-fops.py160
-rw-r--r--xlators/features/metadisp/src/metadisp-create.c101
-rw-r--r--xlators/features/metadisp/src/metadisp-fops.h51
-rw-r--r--xlators/features/metadisp/src/metadisp-fsync.c54
-rw-r--r--xlators/features/metadisp/src/metadisp-lookup.c90
-rw-r--r--xlators/features/metadisp/src/metadisp-open.c70
-rw-r--r--xlators/features/metadisp/src/metadisp-readdir.c65
-rw-r--r--xlators/features/metadisp/src/metadisp-setattr.c90
-rw-r--r--xlators/features/metadisp/src/metadisp-stat.c124
-rw-r--r--xlators/features/metadisp/src/metadisp-unlink.c160
-rw-r--r--xlators/features/metadisp/src/metadisp.c46
-rw-r--r--xlators/features/metadisp/src/metadisp.h45
-rw-r--r--xlators/features/namespace/Makefile.am3
-rw-r--r--xlators/features/namespace/src/Makefile.am17
-rw-r--r--xlators/features/namespace/src/namespace.c1344
-rw-r--r--xlators/features/namespace/src/namespace.h23
-rw-r--r--xlators/features/path-convertor/Makefile.am3
-rw-r--r--xlators/features/path-convertor/src/Makefile.am15
-rw-r--r--xlators/features/path-convertor/src/path-mem-types.h22
-rw-r--r--xlators/features/path-convertor/src/path.c1223
-rw-r--r--xlators/features/protect/Makefile.am3
-rw-r--r--xlators/features/protect/src/Makefile.am21
-rw-r--r--xlators/features/protect/src/prot_client.c213
-rw-r--r--xlators/features/protect/src/prot_dht.c163
-rw-r--r--xlators/features/protect/src/prot_server.c46
-rw-r--r--xlators/features/qemu-block/src/Makefile.am156
-rw-r--r--xlators/features/qemu-block/src/bdrv-xlator.c386
-rw-r--r--xlators/features/qemu-block/src/bh-syncop.c43
-rw-r--r--xlators/features/qemu-block/src/clock-timer.c55
-rw-r--r--xlators/features/qemu-block/src/coroutine-synctask.c111
-rw-r--r--xlators/features/qemu-block/src/monitor-logging.c45
-rw-r--r--xlators/features/qemu-block/src/qb-coroutines.c662
-rw-r--r--xlators/features/qemu-block/src/qb-coroutines.h30
-rw-r--r--xlators/features/qemu-block/src/qemu-block-memory-types.h25
-rw-r--r--xlators/features/qemu-block/src/qemu-block.c1134
-rw-r--r--xlators/features/qemu-block/src/qemu-block.h109
-rw-r--r--xlators/features/quiesce/src/Makefile.am7
-rw-r--r--xlators/features/quiesce/src/quiesce-mem-types.h7
-rw-r--r--xlators/features/quiesce/src/quiesce-messages.h28
-rw-r--r--xlators/features/quiesce/src/quiesce.c3365
-rw-r--r--xlators/features/quiesce/src/quiesce.h68
-rw-r--r--xlators/features/quota/src/Makefile.am22
-rw-r--r--xlators/features/quota/src/quota-enforcer-client.c724
-rw-r--r--xlators/features/quota/src/quota-mem-types.h28
-rw-r--r--xlators/features/quota/src/quota-messages.h252
-rw-r--r--xlators/features/quota/src/quota.c8236
-rw-r--r--xlators/features/quota/src/quota.h419
-rw-r--r--xlators/features/quota/src/quotad-aggregator.c757
-rw-r--r--xlators/features/quota/src/quotad-aggregator.h29
-rw-r--r--xlators/features/quota/src/quotad-helpers.c116
-rw-r--r--xlators/features/quota/src/quotad-helpers.h4
-rw-r--r--xlators/features/quota/src/quotad.c315
-rw-r--r--xlators/features/read-only/src/Makefile.am11
-rw-r--r--xlators/features/read-only/src/read-only-common.c545
-rw-r--r--xlators/features/read-only/src/read-only-common.h112
-rw-r--r--xlators/features/read-only/src/read-only-mem-types.h6
-rw-r--r--xlators/features/read-only/src/read-only.c176
-rw-r--r--xlators/features/read-only/src/read-only.h22
-rw-r--r--xlators/features/read-only/src/worm-helper.c395
-rw-r--r--xlators/features/read-only/src/worm-helper.h44
-rw-r--r--xlators/features/read-only/src/worm.c746
-rw-r--r--xlators/features/sdfs/Makefile.am3
-rw-r--r--xlators/features/sdfs/src/Makefile.am19
-rw-r--r--xlators/features/sdfs/src/sdfs-messages.h (renamed from libglusterfs/src/template-component-messages.h)41
-rw-r--r--xlators/features/sdfs/src/sdfs.c1479
-rw-r--r--xlators/features/sdfs/src/sdfs.h49
-rw-r--r--xlators/features/selinux/Makefile.am3
-rw-r--r--xlators/features/selinux/src/Makefile.am20
-rw-r--r--xlators/features/selinux/src/selinux-mem-types.h (renamed from xlators/features/filter/src/filter-mem-types.h)15
-rw-r--r--xlators/features/selinux/src/selinux-messages.h30
-rw-r--r--xlators/features/selinux/src/selinux.c323
-rw-r--r--xlators/features/selinux/src/selinux.h24
-rw-r--r--xlators/features/shard/src/Makefile.am7
-rw-r--r--xlators/features/shard/src/shard-mem-types.h15
-rw-r--r--xlators/features/shard/src/shard-messages.h39
-rw-r--r--xlators/features/shard/src/shard.c9572
-rw-r--r--xlators/features/shard/src/shard.h508
-rw-r--r--xlators/features/snapview-client/src/Makefile.am7
-rw-r--r--xlators/features/snapview-client/src/snapview-client-mem-types.h12
-rw-r--r--xlators/features/snapview-client/src/snapview-client-messages.h71
-rw-r--r--xlators/features/snapview-client/src/snapview-client.c4065
-rw-r--r--xlators/features/snapview-client/src/snapview-client.h176
-rw-r--r--xlators/features/snapview-server/src/Makefile.am25
-rw-r--r--xlators/features/snapview-server/src/snapview-server-helpers.c900
-rw-r--r--xlators/features/snapview-server/src/snapview-server-mem-types.h15
-rw-r--r--xlators/features/snapview-server/src/snapview-server-messages.h54
-rw-r--r--xlators/features/snapview-server/src/snapview-server-mgmt.c840
-rw-r--r--xlators/features/snapview-server/src/snapview-server.c4135
-rw-r--r--xlators/features/snapview-server/src/snapview-server.h294
-rw-r--r--xlators/features/thin-arbiter/Makefile.am3
-rw-r--r--xlators/features/thin-arbiter/src/Makefile.am22
-rw-r--r--xlators/features/thin-arbiter/src/thin-arbiter-mem-types.h19
-rw-r--r--xlators/features/thin-arbiter/src/thin-arbiter-messages.h28
-rw-r--r--xlators/features/thin-arbiter/src/thin-arbiter.c661
-rw-r--r--xlators/features/thin-arbiter/src/thin-arbiter.h59
-rw-r--r--xlators/features/trash/src/Makefile.am7
-rw-r--r--xlators/features/trash/src/trash-mem-types.h13
-rw-r--r--xlators/features/trash/src/trash.c4291
-rw-r--r--xlators/features/trash/src/trash.h100
-rw-r--r--xlators/features/upcall/src/Makefile.am12
-rw-r--r--xlators/features/upcall/src/upcall-cache-invalidation.h38
-rw-r--r--xlators/features/upcall/src/upcall-internal.c1026
-rw-r--r--xlators/features/upcall/src/upcall-mem-types.h13
-rw-r--r--xlators/features/upcall/src/upcall-messages.h54
-rw-r--r--xlators/features/upcall/src/upcall.c3079
-rw-r--r--xlators/features/upcall/src/upcall.h201
-rw-r--r--xlators/features/utime/Makefile.am3
-rw-r--r--xlators/features/utime/src/Makefile.am41
-rw-r--r--xlators/features/utime/src/utime-autogen-fops-tmpl.c28
-rw-r--r--xlators/features/utime/src/utime-autogen-fops-tmpl.h22
-rwxr-xr-xxlators/features/utime/src/utime-gen-fops-c.py147
-rwxr-xr-xxlators/features/utime/src/utime-gen-fops-h.py35
-rw-r--r--xlators/features/utime/src/utime-helpers.c110
-rw-r--r--xlators/features/utime/src/utime-helpers.h25
-rw-r--r--xlators/features/utime/src/utime-mem-types.h21
-rw-r--r--xlators/features/utime/src/utime-messages.h29
-rw-r--r--xlators/features/utime/src/utime.c392
-rw-r--r--xlators/features/utime/src/utime.h23
-rw-r--r--xlators/lib/src/libxlator.c796
-rw-r--r--xlators/lib/src/libxlator.h116
-rw-r--r--xlators/meta/Makefile.am2
-rw-r--r--xlators/meta/src/Makefile.am5
-rw-r--r--xlators/meta/src/active-link.c25
-rw-r--r--xlators/meta/src/cmdline-file.c32
-rw-r--r--xlators/meta/src/frames-file.c164
-rw-r--r--xlators/meta/src/graph-dir.c129
-rw-r--r--xlators/meta/src/graphs-dir.c87
-rw-r--r--xlators/meta/src/history-file.c33
-rw-r--r--xlators/meta/src/logfile-link.c25
-rw-r--r--xlators/meta/src/logging-dir.c42
-rw-r--r--xlators/meta/src/loglevel-file.c40
-rw-r--r--xlators/meta/src/mallinfo-file.c25
-rw-r--r--xlators/meta/src/measure-file.c37
-rw-r--r--xlators/meta/src/meminfo-file.c33
-rw-r--r--xlators/meta/src/meta-defaults.c775
-rw-r--r--xlators/meta/src/meta-helpers.c445
-rw-r--r--xlators/meta/src/meta-hooks.h6
-rw-r--r--xlators/meta/src/meta-mem-types.h17
-rw-r--r--xlators/meta/src/meta.c293
-rw-r--r--xlators/meta/src/meta.h181
-rw-r--r--xlators/meta/src/name-file.c34
-rw-r--r--xlators/meta/src/option-file.c36
-rw-r--r--xlators/meta/src/options-dir.c62
-rw-r--r--xlators/meta/src/private-file.c33
-rw-r--r--xlators/meta/src/process_uuid-file.c28
-rw-r--r--xlators/meta/src/profile-file.c33
-rw-r--r--xlators/meta/src/root-dir.c105
-rw-r--r--xlators/meta/src/subvolume-link.c67
-rw-r--r--xlators/meta/src/subvolumes-dir.c65
-rw-r--r--xlators/meta/src/top-link.c31
-rw-r--r--xlators/meta/src/type-file.c34
-rw-r--r--xlators/meta/src/version-file.c29
-rw-r--r--xlators/meta/src/view-dir.c27
-rw-r--r--xlators/meta/src/volfile-file.c71
-rw-r--r--xlators/meta/src/xlator-dir.c130
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am62
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-bitd-svc.c287
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-bitd-svc.h16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-bitrot.c1235
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-brick-ops.c4704
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-conn-helper.c4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-conn-helper.h2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-conn-mgmt.c223
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-conn-mgmt.h38
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-errno.h33
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-ganesha.c1432
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-geo-rep.c10859
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-geo-rep.h38
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-gfproxyd-svc-helper.c235
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-gfproxyd-svc-helper.h51
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-gfproxyd-svc.c478
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-gfproxyd-svc.h47
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c10093
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c4035
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-hooks.c983
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-hooks.h80
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-locks.c1258
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-locks.h38
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-log-ops.c454
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mem-types.h101
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-messages.h5032
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt-handler.c1759
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.c4721
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mgmt.h86
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mountbroker.c1187
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mountbroker.h35
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-nfs-svc.c313
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-nfs-svc.h17
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c13204
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.h327
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-peer-utils.c1559
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-peer-utils.h67
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-pmap.c876
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-pmap.h58
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-proc-mgmt.c181
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-proc-mgmt.h34
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quota.c3447
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quota.h (renamed from xlators/features/ganesha/src/ganesha-mem-types.h)16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quotad-svc.c323
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quotad-svc.h10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rcu.h8
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rebalance.c2065
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-replace-brick.c1488
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-reset-brick.c376
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c4085
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-scrub-svc.c284
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-scrub-svc.h22
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-server-quorum.c692
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-server-quorum.h28
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.c153
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-shd-svc-helper.h42
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-shd-svc.c920
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-shd-svc.h25
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c2481
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.h253
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapd-svc-helper.c66
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapd-svc-helper.h16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapd-svc.c738
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapd-svc.h20
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot-utils.c6766
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h152
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c17204
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-statedump.c367
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-statedump.h4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c8014
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h255
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-svc-helper.c1111
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-svc-helper.h50
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c646
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-svc-mgmt.h100
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c3286
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.h102
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-tierd-svc-helper.c207
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c21107
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h820
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c9847
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.h342
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c5159
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c4927
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c3599
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h1755
-rw-r--r--xlators/mount/fuse/src/Makefile.am9
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c10323
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h796
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c1048
-rw-r--r--xlators/mount/fuse/src/fuse-mem-types.h25
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c1012
-rwxr-xr-xxlators/mount/fuse/utils/mount.glusterfs.in224
-rwxr-xr-xxlators/mount/fuse/utils/mount_glusterfs.in36
-rw-r--r--xlators/nfs/server/src/Makefile.am21
-rw-r--r--xlators/nfs/server/src/acl3.c1585
-rw-r--r--xlators/nfs/server/src/acl3.h18
-rw-r--r--xlators/nfs/server/src/auth-cache.c535
-rw-r--r--xlators/nfs/server/src/auth-cache.h26
-rw-r--r--xlators/nfs/server/src/exports.c1632
-rw-r--r--xlators/nfs/server/src/exports.h69
-rw-r--r--xlators/nfs/server/src/mount3-auth.c682
-rw-r--r--xlators/nfs/server/src/mount3-auth.h28
-rw-r--r--xlators/nfs/server/src/mount3.c6350
-rw-r--r--xlators/nfs/server/src/mount3.h209
-rw-r--r--xlators/nfs/server/src/mount3udp_svc.c344
-rw-r--r--xlators/nfs/server/src/netgroups.c1012
-rw-r--r--xlators/nfs/server/src/netgroups.h31
-rw-r--r--xlators/nfs/server/src/nfs-common.c652
-rw-r--r--xlators/nfs/server/src/nfs-common.h51
-rw-r--r--xlators/nfs/server/src/nfs-fops.c2365
-rw-r--r--xlators/nfs/server/src/nfs-fops.h305
-rw-r--r--xlators/nfs/server/src/nfs-generics.c336
-rw-r--r--xlators/nfs/server/src/nfs-generics.h146
-rw-r--r--xlators/nfs/server/src/nfs-inodes.c768
-rw-r--r--xlators/nfs/server/src/nfs-inodes.h60
-rw-r--r--xlators/nfs/server/src/nfs-mem-types.h70
-rw-r--r--xlators/nfs/server/src/nfs-messages.h1743
-rw-r--r--xlators/nfs/server/src/nfs.c3406
-rw-r--r--xlators/nfs/server/src/nfs.h172
-rw-r--r--xlators/nfs/server/src/nfs3-fh.c216
-rw-r--r--xlators/nfs/server/src/nfs3-fh.h105
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.c5047
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.h280
-rw-r--r--xlators/nfs/server/src/nfs3.c9193
-rw-r--r--xlators/nfs/server/src/nfs3.h382
-rw-r--r--xlators/nfs/server/src/nfsserver.sym12
-rw-r--r--xlators/nfs/server/src/nlm4.c4332
-rw-r--r--xlators/nfs/server/src/nlm4.h126
-rw-r--r--xlators/nfs/server/src/nlmcbk_svc.c176
-rw-r--r--xlators/performance/Makefile.am3
-rw-r--r--xlators/performance/io-cache/src/Makefile.am3
-rw-r--r--xlators/performance/io-cache/src/io-cache-messages.h170
-rw-r--r--xlators/performance/io-cache/src/io-cache.c3099
-rw-r--r--xlators/performance/io-cache/src/io-cache.h400
-rw-r--r--xlators/performance/io-cache/src/ioc-inode.c292
-rw-r--r--xlators/performance/io-cache/src/ioc-mem-types.h24
-rw-r--r--xlators/performance/io-cache/src/page.c1456
-rw-r--r--xlators/performance/io-threads/src/Makefile.am5
-rw-r--r--xlators/performance/io-threads/src/io-threads-messages.h108
-rw-r--r--xlators/performance/io-threads/src/io-threads.c1968
-rw-r--r--xlators/performance/io-threads/src/io-threads.h115
-rw-r--r--xlators/performance/io-threads/src/iot-mem-types.h9
-rw-r--r--xlators/performance/md-cache/src/Makefile.am3
-rw-r--r--xlators/performance/md-cache/src/md-cache-mem-types.h13
-rw-r--r--xlators/performance/md-cache/src/md-cache-messages.h57
-rw-r--r--xlators/performance/md-cache/src/md-cache.c4705
-rw-r--r--xlators/performance/nl-cache/Makefile.am3
-rw-r--r--xlators/performance/nl-cache/src/Makefile.am12
-rw-r--r--xlators/performance/nl-cache/src/nl-cache-helper.c1201
-rw-r--r--xlators/performance/nl-cache/src/nl-cache-mem-types.h27
-rw-r--r--xlators/performance/nl-cache/src/nl-cache-messages.h29
-rw-r--r--xlators/performance/nl-cache/src/nl-cache.c840
-rw-r--r--xlators/performance/nl-cache/src/nl-cache.h175
-rw-r--r--xlators/performance/open-behind/src/Makefile.am5
-rw-r--r--xlators/performance/open-behind/src/open-behind-mem-types.h9
-rw-r--r--xlators/performance/open-behind/src/open-behind-messages.h77
-rw-r--r--xlators/performance/open-behind/src/open-behind.c1622
-rw-r--r--xlators/performance/quick-read/src/Makefile.am5
-rw-r--r--xlators/performance/quick-read/src/quick-read-mem-types.h16
-rw-r--r--xlators/performance/quick-read/src/quick-read-messages.h121
-rw-r--r--xlators/performance/quick-read/src/quick-read.c2140
-rw-r--r--xlators/performance/quick-read/src/quick-read.h83
-rw-r--r--xlators/performance/read-ahead/src/Makefile.am5
-rw-r--r--xlators/performance/read-ahead/src/page.c847
-rw-r--r--xlators/performance/read-ahead/src/read-ahead-mem-types.h17
-rw-r--r--xlators/performance/read-ahead/src/read-ahead-messages.h104
-rw-r--r--xlators/performance/read-ahead/src/read-ahead.c1839
-rw-r--r--xlators/performance/read-ahead/src/read-ahead.h178
-rw-r--r--xlators/performance/readdir-ahead/src/Makefile.am9
-rw-r--r--xlators/performance/readdir-ahead/src/readdir-ahead-mem-types.h12
-rw-r--r--xlators/performance/readdir-ahead/src/readdir-ahead-messages.h97
-rw-r--r--xlators/performance/readdir-ahead/src/readdir-ahead.c1581
-rw-r--r--xlators/performance/readdir-ahead/src/readdir-ahead.h94
-rw-r--r--xlators/performance/symlink-cache/Makefile.am3
-rw-r--r--xlators/performance/symlink-cache/src/Makefile.am15
-rw-r--r--xlators/performance/symlink-cache/src/symlink-cache-messages.h93
-rw-r--r--xlators/performance/symlink-cache/src/symlink-cache.c402
-rw-r--r--xlators/performance/write-behind/src/Makefile.am5
-rw-r--r--xlators/performance/write-behind/src/write-behind-mem-types.h16
-rw-r--r--xlators/performance/write-behind/src/write-behind-messages.h114
-rw-r--r--xlators/performance/write-behind/src/write-behind.c4205
-rw-r--r--xlators/playground/rot-13/Makefile.am (renamed from xlators/cluster/ha/Makefile.am)0
-rw-r--r--xlators/playground/rot-13/src/Makefile.am (renamed from xlators/encryption/rot-13/src/Makefile.am)5
-rw-r--r--xlators/playground/rot-13/src/rot-13.c166
-rw-r--r--xlators/playground/rot-13/src/rot-13.h (renamed from xlators/encryption/rot-13/src/rot-13.h)4
-rw-r--r--xlators/playground/template/src/Makefile.am7
-rw-r--r--xlators/playground/template/src/template.c182
-rw-r--r--xlators/playground/template/src/template.h36
-rw-r--r--xlators/protocol/auth/addr/src/Makefile.am6
-rw-r--r--xlators/protocol/auth/addr/src/addr.c470
-rw-r--r--xlators/protocol/auth/login/src/Makefile.am5
-rw-r--r--xlators/protocol/auth/login/src/login.c318
-rw-r--r--xlators/protocol/client/src/Makefile.am13
-rw-r--r--xlators/protocol/client/src/client-callback.c328
-rw-r--r--xlators/protocol/client/src/client-common.c3589
-rw-r--r--xlators/protocol/client/src/client-common.h630
-rw-r--r--xlators/protocol/client/src/client-handshake.c2641
-rw-r--r--xlators/protocol/client/src/client-helpers.c1029
-rw-r--r--xlators/protocol/client/src/client-lk.c755
-rw-r--r--xlators/protocol/client/src/client-mem-types.h17
-rw-r--r--xlators/protocol/client/src/client-messages.h776
-rw-r--r--xlators/protocol/client/src/client-rpc-fops.c10479
-rw-r--r--xlators/protocol/client/src/client-rpc-fops_v2.c6177
-rw-r--r--xlators/protocol/client/src/client.c4321
-rw-r--r--xlators/protocol/client/src/client.h571
-rw-r--r--xlators/protocol/server/src/Makefile.am22
-rw-r--r--xlators/protocol/server/src/authenticate.c327
-rw-r--r--xlators/protocol/server/src/authenticate.h34
-rw-r--r--xlators/protocol/server/src/server-common.c842
-rw-r--r--xlators/protocol/server/src/server-common.h199
-rw-r--r--xlators/protocol/server/src/server-handshake.c1434
-rw-r--r--xlators/protocol/server/src/server-helpers.c2156
-rw-r--r--xlators/protocol/server/src/server-helpers.h94
-rw-r--r--xlators/protocol/server/src/server-mem-types.h23
-rw-r--r--xlators/protocol/server/src/server-messages.h977
-rw-r--r--xlators/protocol/server/src/server-resolve.c960
-rw-r--r--xlators/protocol/server/src/server-rpc-fops.c9182
-rw-r--r--xlators/protocol/server/src/server-rpc-fops_v2.c6031
-rw-r--r--xlators/protocol/server/src/server.c2797
-rw-r--r--xlators/protocol/server/src/server.h274
-rw-r--r--xlators/storage/Makefile.am4
-rw-r--r--xlators/storage/bd/src/Makefile.am20
-rw-r--r--xlators/storage/bd/src/bd-aio.c523
-rw-r--r--xlators/storage/bd/src/bd-aio.h36
-rw-r--r--xlators/storage/bd/src/bd-helper.c1019
-rw-r--r--xlators/storage/bd/src/bd-mem-types.h27
-rw-r--r--xlators/storage/bd/src/bd.c2448
-rw-r--r--xlators/storage/bd/src/bd.h168
-rw-r--r--xlators/storage/posix/src/Makefile.am20
-rw-r--r--xlators/storage/posix/src/posix-aio.c954
-rw-r--r--xlators/storage/posix/src/posix-aio.h22
-rw-r--r--xlators/storage/posix/src/posix-common.c1524
-rw-r--r--xlators/storage/posix/src/posix-entry-ops.c2496
-rw-r--r--xlators/storage/posix/src/posix-gfid-path.c243
-rw-r--r--xlators/storage/posix/src/posix-gfid-path.h28
-rw-r--r--xlators/storage/posix/src/posix-handle.c1564
-rw-r--r--xlators/storage/posix/src/posix-handle.h427
-rw-r--r--xlators/storage/posix/src/posix-helpers.c4825
-rw-r--r--xlators/storage/posix/src/posix-inode-fd-ops.c6004
-rw-r--r--xlators/storage/posix/src/posix-inode-handle.h118
-rw-r--r--xlators/storage/posix/src/posix-mem-types.h20
-rw-r--r--xlators/storage/posix/src/posix-messages.h951
-rw-r--r--xlators/storage/posix/src/posix-metadata-disk.h31
-rw-r--r--xlators/storage/posix/src/posix-metadata.c916
-rw-r--r--xlators/storage/posix/src/posix-metadata.h71
-rw-r--r--xlators/storage/posix/src/posix.c6754
-rw-r--r--xlators/storage/posix/src/posix.h734
-rw-r--r--xlators/system/posix-acl/src/Makefile.am8
-rw-r--r--xlators/system/posix-acl/src/posix-acl-mem-types.h13
-rw-r--r--xlators/system/posix-acl/src/posix-acl-messages.h28
-rw-r--r--xlators/system/posix-acl/src/posix-acl-xattr.c229
-rw-r--r--xlators/system/posix-acl/src/posix-acl-xattr.h17
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c3309
-rw-r--r--xlators/system/posix-acl/src/posix-acl.h33
-rw-r--r--xlators/xlator.sym1
2367 files changed, 565653 insertions, 490503 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 00000000000..84c2efe3fad
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,107 @@
+---
+Language: Cpp
+# BasedOnStyle: Chromium
+AccessModifierOffset: -1
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: All
+AlwaysBreakAfterReturnType: All
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: true
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Linux
+BreakBeforeInheritanceComma: false
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IncludeCategories:
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ - Regex: '^<.*'
+ Priority: 2
+ - Regex: '.*'
+ Priority: 3
+IncludeIsMainRegex: '([-_](test|unittest))?$'
+IndentCaseLabels: true
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakAssignment: 200
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Right
+ReflowComments: true
+SortIncludes: false
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Auto
+TabWidth: 8
+UseTab: Never
+...
diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE
new file mode 100644
index 00000000000..386ed2d8dd5
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE
@@ -0,0 +1,30 @@
+<!-- Please use this template while reporting an issue, providing as much information as possible. Failure to do so may result in a delayed response. Thank you! -->
+
+**Description of problem:**
+
+
+**The exact command to reproduce the issue**:
+
+
+**The full output of the command that failed**:
+<details>
+
+
+
+</details>
+
+**Expected results:**
+
+
+**Additional info:**
+
+
+**- The output of the `gluster volume info` command**:
+<details>
+
+
+
+</details>
+
+**- The operating system / glusterfs version**:
+
diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE
diff --git a/.github/RELEASE_TRACKER_TEMPLATE b/.github/RELEASE_TRACKER_TEMPLATE
new file mode 100644
index 00000000000..502bbd5556c
--- /dev/null
+++ b/.github/RELEASE_TRACKER_TEMPLATE
@@ -0,0 +1,12 @@
+<!-- Please use this template while creating a tracker issue -->
+
+**Description of problem:**
+A tracker issue to track the issues that will be fixed as a part of this release
+
+
+**Major or minor release**:
+
+
+**Release version**:
+
+
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 00000000000..460e327c6ea
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,25 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 210
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 15
+# Issues with these labels will never be considered stale
+exemptLabels:
+ - pinned
+ - security
+# Label to use when marking an issue as stale
+staleLabel: wontfix
+
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ Thank you for your contributions.
+
+ Noticed that this issue is not having any activity in last ~6 months! We
+ are marking this issue as stale because it has not had recent activity.
+
+ It will be closed in 2 weeks if no one responds with a comment here.
+
+
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: >
+ Closing this issue as there was no update since my last update on issue.
+ If this is an issue which is still valid, feel free to open it.
diff --git a/.gitignore b/.gitignore
index a3975d594d1..fc5ba586f8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,13 +4,16 @@ build
config.*
configure
cscope.*
+tags
depcomp
+INSTALL
install-sh
ltmain.sh
Makefile
Makefile.in
missing
stamp-h1
+stamp-h2
test-driver
*compile
*.gcda
@@ -26,10 +29,12 @@ test-driver
*.patch
.libs
.deps
+.dirstamp
# Softlinks to test and log
log
*.vol
+.clang-format
# cmocka unit tests
*.log
@@ -37,15 +42,16 @@ log
*_unittest
# Generated files
+site.h
*.py[co]
api/examples/__init__.py
api/examples/setup.py
api/src/gfapi.map
cli/src/gluster
-contrib/argp-standalone/libargp.a
contrib/fuse-util/fusermount-glusterfs
-contrib/uuid/uuid_types.h
extras/geo-rep/gsync-sync-gfid
+extras/geo-rep/schedule_georep.py
+extras/snap_scheduler/conf.py
extras/init.d/glusterd-Debian
extras/init.d/glusterd-FreeBSD
extras/init.d/glusterd-Redhat
@@ -55,14 +61,19 @@ extras/ocf/glusterd
extras/ocf/volume
extras/run-gluster.tmpfiles
extras/systemd/glusterd.service
+extras/systemd/gluster-ta-volume.service
+extras/systemd/glusterfssharedstorage.service
extras/who-wrote-glusterfs/gitdm
geo-replication/.tox
+geo-replication/gsyncd.conf
geo-replication/src/gsyncd
geo-replication/src/peer_gsec_create
geo-replication/src/peer_mountbroker
+geo-replication/src/peer_mountbroker.py
geo-replication/src/set_geo_rep_pem_keys.sh
+geo-replication/src/peer_georep-sshkey.py
geo-replication/syncdaemon.egg-info
-geo-replication/syncdaemon/configinterface.py
+geo-replication/syncdaemon/conf.py
geo-replication/tests/unit/.coverage
geo-replication/tests/unit/cover
geo-replication/tests/unit/coverage.xml
@@ -73,14 +84,20 @@ glusterfs.spec
glusterfsd/src/glusterd
glusterfsd/src/glusterfs
glusterfsd/src/glusterfsd
+glusterfsd/src/gf_attach
heal/src/glfsheal
libgfchangelog.pc
-libgfdb.pc
libglusterfs/src/graph.lex.c
libglusterfs/src/y.tab.c
libglusterfs/src/y.tab.h
+libglusterfs/src/defaults.c
+libglusterfs/src/cli1-xdr.h
+libglusterfs/src/protocol-common.h
libtool
+# copied XDR for cyclic libglusterfs <-> rpc-header dependency
run-tests.sh
+!tests/basic/fuse/Makefile
+!tests/basic/gfapi/Makefile
tests/env.rc
tests/utils/arequal-checksum
xlators/features/glupy/src/__init__.py
@@ -91,3 +108,18 @@ extras/peer_add_secret_pub
tools/gfind_missing_files/gcrawler
tools/glusterfind/glusterfind
tools/glusterfind/src/tool.conf
+# Eventing
+events/src/eventsapiconf.py
+extras/systemd/glustereventsd.service
+events/src/eventtypes.py
+libglusterfs/src/eventtypes.h
+extras/init.d/glustereventsd-Debian
+extras/init.d/glustereventsd-FreeBSD
+extras/init.d/glustereventsd-Redhat
+tools/setgfid2path/src/gluster-setgfid2path
+xlators/features/cloudsync/src/cloudsync-autogen-fops.c
+xlators/features/cloudsync/src/cloudsync-autogen-fops.h
+xlators/features/utime/src/utime-autogen-fops.c
+xlators/features/utime/src/utime-autogen-fops.h
+tests/basic/metadisp/ftruncate
+xlators/features/metadisp/src/fops.c
diff --git a/.mailmap b/.mailmap
index d4a13b40065..141a1667ffa 100644
--- a/.mailmap
+++ b/.mailmap
@@ -10,15 +10,20 @@ Amar Tumballi <amarts@redhat.com> <amar@gluster.com> <amar@del.gluster.com>
Anand Avati <avati@redhat.com> <avati@gluster.com> <avati@dev.gluster.com> <avati@amp.gluster.com> <avati@blackhole.gluster.com>
Anush Shetty <ashetty@redhat.com> <anush@gluster.com>
Csaba Henk <csaba@redhat.com> <csaba@gluster.com> <csaba@lowlife.hu> <csaba@zresearch.com>
+Günther Deschner <gd@redhat.com> <gd@samba.org>
Harshavardhana <fharshav@redhat.com> <harsha@gluster.com> <harsha@zresearch.com> <harsha@dev.gluster.com> <harsha@harshavardhana.net>
+Ji-Hyeon Gim <potatogim@gluesys.com> <potatogim@potatogim.net>
Justin Clift <justin@gluster.org> <jclift@redhat.com>
-Kaleb S. KEITHLEY <kkeithle@redhat.com> <kkeithle@f16node1.kkeithle.usersys.redhat.com>
+Kaleb S. KEITHLEY <kkeithle@redhat.com> <kkeithle@f16node1.kkeithle.usersys.redhat.com> <kkeithle@linux.keithley.org>
Kaushal M <kaushal@redhat.com> <kaushal@gluster.com>
Kaushik BV <kbudiger@redhat.com> <kaushikbv@gluster.com>
Krishna Srinivas <ksriniva@redhat.com> <krishna@gluster.com> <krishna@zresearch.com> <krishna@guest-laptop>
Krishnan Parthasarathi <kparthas@redhat.com> <kp@gluster.com>
Louis Zuckerman <louiszuckerman@gmail.com> <me@louiszuckerman.com>
M S Vishwanath Bhat <vbhat@redhat.com> <msvbhat@gmail.com> <vishwanath@gluster.com>
+Michael Adam <madam@redhat.com> <obnox@samba.org>
+Oleksandr Natalenko <oleksandr@natalenko.name> <o.natalenko@lanet.ua>
+Patrick Uiterwijk <puiterwijk@fedoraproject.org> <patrick@puiterwijk.org>
Pavan Sondur <pavan@gluster.com> <pavan@dev.gluster.com>
Pete Zaitcev <zaitcev@kotori.zaitcev.us> <zaitcev@yahoo.com>
Pranith Kumar K <pkarampu@redhat.com> <pranithk@gluster.com>
@@ -27,9 +32,12 @@ Raghavendra Bhat <raghavendra@redhat.com> <raghavendrabhat@gluster.com>
Raghavendra G <rgowdapp@redhat.com> <raghavendra@gluster.com> <raghavendra@zresearch.com>
Rahul C S <rahulcs@redhat.com> <rahulcssjce@gmail.com>
Rajesh Amaravathi <rajesh@redhat.com> <rajesh@gluster.com> <rajesh.amaravathi@gmail.com>
+Ravishankar N <ravishankar@redhat.com> <root@ravi2.(none)>
+Sakshi Bansal <sabansal@redhat.com> <sabansal@localhost.localdomain>
Shehjar Tikoo <shehjart@gluster.com> <shehjart@zresearch.com>
Venky Shankar <vshankar@redhat.com> <venky@gluster.com>
Vijay Bellur <vbellur@redhat.com> <vijay@gluster.com> <vijay@dev.gluster.com>
Vijaykumar Koppad <vkoppad@redhat.com> <vijaykumar.koppad@gmail.com>
+Vijaikumar Mallikarjuna <vmallika@redhat.com>
Vikas Gorur <vikas@gluster.com> <vikas@zresearch.com>
shishir gowda <sgowda@redhat.com> <shishirng@gluster.com>
diff --git a/.testignore b/.testignore
new file mode 100644
index 00000000000..fe8f838bf2b
--- /dev/null
+++ b/.testignore
@@ -0,0 +1,64 @@
+.github/ISSUE_TEMPLATE
+.github/PULL_REQUEST_TEMPLATE
+.github/stale.yml
+.gitignore
+.mailmap
+.testignore
+.clang-format
+rfc.sh
+submit-for-review.sh
+AUTHORS
+CONTRIBUTING.md
+COPYING-GPLV2
+COPYING-LGPLV3
+ChangeLog
+INSTALL
+MAINTAINERS
+NEWS
+README.md
+THANKS
+COMMITMENT
+api/examples/README
+api/examples/getvolfile.py
+api/src/README.Symbol_Versions
+build-aux/checkpatch.pl
+contrib/fuse-lib/COPYING.LIB
+contrib/fuse-util/COPYING
+contrib/macfuse/COPYING.txt
+doc/*
+extras/FreeBSD/README.FreeBSD
+extras/Solaris/README.solaris
+extras/Ubuntu/README.Ubuntu
+extras/benchmarking/README
+extras/cliutils/README.md
+extras/command-completion/README
+extras/create_new_xlator/README.md
+extras/glusterfs.vim
+extras/glusterfs-logrotate
+extras/glusterfs-georep-logrotate
+extras/init.d/glusterd-Debian.in
+extras/init.d/glusterd-FreeBSD.in
+extras/init.d/glusterd-Redhat.in
+extras/init.d/glusterd-SuSE.in
+extras/init.d/glusterd.plist.in
+extras/init.d/glustereventsd-Debian.in
+extras/init.d/glustereventsd-FreeBSD.in
+extras/init.d/glustereventsd-Redhat.in
+extras/init.d/rhel5-load-fuse.modules
+extras/logger.conf.example
+extras/snap_scheduler/README.md
+extras/test/ld-preload-test/README
+extras/who-wrote-glusterfs/*
+extras/distributed-testing/*
+geo-replication/syncdaemon/README.md
+geo-replication/test-requirements.txt
+rpc/xdr/src/.gitignore
+tests/README.md
+xlators/experimental/README.md
+xlators/experimental/dht2/README.md
+xlators/experimental/dht2/TODO.md
+xlators/experimental/posix2/README.md
+xlators/experimental/posix2/TODO.md
+xlators/features/glupy/doc/README.md
+xlators/features/glupy/doc/TESTING
+xlators/features/glupy/doc/test.vol
diff --git a/COMMITMENT b/COMMITMENT
new file mode 100644
index 00000000000..16b75efcf29
--- /dev/null
+++ b/COMMITMENT
@@ -0,0 +1,46 @@
+Common Cure Rights Commitment
+Version 1.0
+
+Before filing or continuing to prosecute any legal proceeding or claim
+(other than a Defensive Action) arising from termination of a Covered
+License, we commit to extend to the person or entity ('you') accused
+of violating the Covered License the following provisions regarding
+cure and reinstatement, taken from GPL version 3. As used here, the
+term 'this License' refers to the specific Covered License being
+enforced.
+
+ 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.
+
+We intend this Commitment to be irrevocable, and binding and
+enforceable against us and assignees of or successors to our
+copyrights.
+
+Definitions
+
+'Covered License' means the GNU General Public License, version 2
+(GPLv2), the GNU Lesser General Public License, version 2.1
+(LGPLv2.1), or the GNU Library General Public License, version 2
+(LGPLv2), all as published by the Free Software Foundation.
+
+'Defensive Action' means a legal proceeding or claim that We bring
+against you in response to a prior proceeding or claim initiated by
+you or your affiliate.
+
+'We' means each contributor to this repository as of the date of
+inclusion of this file, including subsidiaries of a corporate
+contributor.
+
+This work is available under a Creative Commons Attribution-ShareAlike
+4.0 International license (https://creativecommons.org/licenses/by-sa/4.0/).
diff --git a/CONTRIBUTING b/CONTRIBUTING
deleted file mode 100644
index 7bccd88d7e5..00000000000
--- a/CONTRIBUTING
+++ /dev/null
@@ -1,25 +0,0 @@
- 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.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000000..65fc3497104
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,114 @@
+# GlusterFS project Contribution guidelines
+
+## Development Workflow
+
+We follow most of the details as per the [document here](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests). If you are not aware of the github workflow, it is recommended to go through them before continuing here.
+
+
+#### Get the Repository setup
+
+0. Fork Repository
+ - Fork [GlusterFS repository](https://github.com/gluster/glusterfs/fork).
+
+1. Clone Repository
+ - Clone the glusterfs repo freshly from github using below steps.
+
+```
+ git clone git@github.com:${username}/glusterfs.git
+ cd glusterfs/
+ git remote add upstream git@github.com:gluster/glusterfs.git
+```
+
+About two tasks are one time for the life time. You can continue to use the same repository for all the work in future.
+
+#### Development & Other flows
+
+0. Issue:
+ - Make sure there is an issue filed for the task you are working on.
+ - If it is not filed, open the issue with all the description.
+ - If it is a bug fix, add label "Type:Bug".
+ - If it is an RFC, provide all the documentation, and request for "DocApproved", and "SpecApproved" label.
+
+1. Code:
+ - Start coding
+ - Build and test locally
+ - Make sure clang-format is installed and is run on the patch.
+
+2. Keep up-to-date
+ - GlusterFS is a large project with many developers, so there would be one or the other patch everyday.
+ - It is critical for developer to be up-to-date with `devel` repo to be Conflict-Free when PR is opened.
+ - Git provides many options to keep up-to-date, below is one of them
+```
+ git fetch upstream
+ git rebase upstream/devel
+```
+ - It is recommended you keep pushing to your repo every day, so you don't loose any work.
+ - It can be done by `./rfc.sh` (or `git push origin HEAD:issueNNN`)
+
+2. Commit Message / PR description:
+ - The name of the branch on your personal fork can start with issueNNNN, followed by anything of your choice.
+ - PRs continue to have the title of format "component: \<title\>", like it is practiced now.
+ - When you open a PR, having a reference Issue for the commit is mandatory in GlusterFS.
+ - Commit message can have, either `Fixes: #NNNN` or `Updates: #NNNN` in a separate line in the commit message.
+ - Here, NNNN is the Issue ID in glusterfs repository.
+ - Each commit needs the author to have the "Signed-off-by: Name \<email\>" line.
+ - Can do this by `-s` option for `git commit`.
+ - If the PR is not ready for review, apply the label `work-in-progress`.
+ - Check the availability of "Draft PR" is present for you, if yes, use that instead.
+
+3. Tests:
+ - All the required smoke tests would be auto-triggered.
+ - Developers get a chance to retrigger the smoke tests using **"/recheck smoke"** as comment.
+ - The "regression" tests would be triggered by a comment **"/run regression"** from developers in the [@gluster-maintainers](https://github.com/orgs/gluster/teams/gluster-maintainers) group.
+ - Ask for help as comment in PR if you have any questions about the process!
+
+4. Review Process:
+ - `+2` : is equivalent to "Approve" from the people in the maintainer's group.
+ - `+1` : can be given by a maintainer/reviewer by explicitly stating that in the comment.
+ - `-1` : provide details on required changes and pick "Request Changes" while submitting your review.
+ - `-2` : done by adding the `DO-NOT-MERGE` label.
+
+ - Any further discussions can happen as comments in the PR.
+
+5. Making changes:
+ - There are 2 approaches to submit changes done after addressing review comments.
+ - Commit changes as a new commit on top of the original commits in the branch, and push the changes to same branch (issueNNNN)
+ - Commit changes into the same commit with `--amend` option, and do a push to the same branch with `--force` option.
+
+6. Merging:
+ - GlusterFS project follows 'Squash and Merge' method
+ - This is mainly to preserve the historic Gerrit method of one patch in `git log` for one URL link.
+ - This also makes every merge a complete patch, which has passed all tests.
+ - The merging of the patch is expected to be done by the maintainers.
+ - It can be done when all the tests (smoke and regression) pass.
+ - When the PR has 'Approved' flag from corresponding maintainer.
+ - If you feel there is delay, feel free to add a comment, discuss the same in Slack channel, or send email.
+
+## By contributing to this project, the contributor would need to agree to below.
+
+### 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.
+
diff --git a/INSTALL b/INSTALL
index 9709727c358..a56390e54fb 100644
--- a/INSTALL
+++ b/INSTALL
@@ -19,7 +19,6 @@ Installation Instructions
georeplication : yes
Linux-AIO : yes
Enable Debug : no
- systemtap : no
Block Device xlator : yes
glupy : yes
Use syslog : yes
@@ -45,4 +44,4 @@ Installation completed :-)
Make sure your version is the latest from the release, and the one you
just installed :-)
-For more information on GlusterFS installation refer# http://gluster.org/community/documentation/index.php/Building_GlusterFS
+For more information on GlusterFS installation refer# http://docs.gluster.org/en/latest/Developer-guide/Building-GlusterFS/
diff --git a/MAINTAINERS b/MAINTAINERS
index 057fb62f062..953e8755fd9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11,7 +11,7 @@ consult gluster-devel@gluster.org and not any specific individual privately.
Descriptions of section entries:
- M: Mail patches to: FullName <address@domain>
+ M: Main contact that knows and takes care of this area
L: Mailing list that is relevant to this area
W: Web-page with status/info
Q: Patchwork web based patch tracking system site
@@ -46,253 +46,409 @@ Descriptions of section entries:
matches patches or files that contain one or more of the words
printk, pr_info or pr_err
One regex pattern per line. Multiple K: lines acceptable.
+ P: Peer for a component
General Project Architects
--------------------------
-M: Anand Avati <avati@redhat.com>
-M: Jeff Darcy <jdarcy@redhat.com>
-M: Kaleb S. Keithley <kkeithle@redhat.com>
-M: Vijay Bellur <vbellur@redhat.com>
-
+M: Amar Tumballi <amarts@gmail.com>
+M: Xavier Hernandez <xhernandez@redhat.com>
+P: Pranith Karampuri <pranith.karampuri@phonepe.com>
+P: Atin Mukherjee <amukherj@redhat.com>
xlators:
--------
+Access Control List (ACL)
+M: Raghavendra Talur <rtalur@redhat.com>
+P: Jiffin Tony Thottan <jthottan@redhat.com>
+S: Maintained
+F: xlators/system/posix-acl/
+
+Arbiter
+M: Ravishankar N <ravishankar@redhat.com>
+P: Pranith Karampuri <pranith.karampuri@phonepe.com>
+S: Maintained
+F: xlators/features/arbiter/
+
Automatic File Replication (AFR)
-M: Pranith Karampuri <pkarampu@redhat.com>
+M: Pranith Karampuri <pranith.karampuri@phonepe.com>
+M: Ravishankar N <ravishankar@redhat.com>
+P: Karthik US <ksubrahm@redhat.com>
S: Maintained
F: xlators/cluster/afr/
-Block Device
-S: Orphan
-F: xlators/storage/bd/
+Barrier
+M: Raghavendra Bhat <rabhat@redhat.com>
+P: Atin Mukherjee <amukherj@redhat.com>
+S: Maintained
+F: xlators/features/barrier
BitRot
-M: Venky Shankar <vshankar@redhat.com>
-M: Raghavendra Bhat (a.k.a. "Johnny") <rabhat@redhat.com>
+M: Kotresh HR <khiremat@redhat.com>
+P: Raghavendra Bhat <rabhat@redhat.com>
S: Maintained
F: xlators/features/bit-rot/
Changelog
-M: Venky Shankar <vshankar@redhat.com>
+M: Aravinda V K <avishwan@redhat.com>
+P: Kotresh HR <khiremat@redhat.com>
S: Maintained
F: xlators/features/changelog/
-Changetimerecorder
-M: Dan Lambright <dlambrig@redhat.com>
-S: Maintained
-F: xlators/features/changetimerecorder/
-
Distributed Hashing Table (DHT)
-M: Raghavendra Gowdappa <rgowdapp@redhat.com>
-M: Shyamsundar Ranganathan <srangana@redhat.com>
+P: Susant Palai <spalai@redhat.com>
S: Maintained
F: xlators/cluster/dht/
Erasure Coding
-M: Pranith Karampuri <pkarampu@redhat.com>
-M: Xavier Hernandez <xhernandez@datalab.es>
+M: Pranith Karampuri <pranith.karampuri@phonepe.com>
+M: Xavier Hernandez <xhernandez@redhat.com>
+P: Ashish Pandey <aspandey@redhat.com>
S: Maintained
F: xlators/cluster/ec/
+Error-gen
+M: Raghavendra Talur <rtalur@redhat.com>
+S: Maintained
+F: xlators/debug/error-gen/
+
FUSE Bridge
-M: Anand Avati <avati@redhat.com>
-M: Niels de Vos <ndevos@redhat.com>
-M: Raghavendra Bhat <rabhat@redhat.com>
+M: Csaba Henk <chenk@redhat.com>
+P: Niels de Vos <ndevos@redhat.com>
S: Maintained
F: xlators/mount/
Index
-M: Pranith Karampuri <pkarampu@redhat.com>
+M: Pranith Karampuri <pranith.karampuri@phonepe.com>
+P: Ravishankar N <ravishankar@redhat.com>
S: Maintained
F: xlators/features/index/
+IO Cache
+P: Mohammed Rafi KC <rafi.kavungal@iternity.com>
+S: Maintained
+F: xlators/performance/io-cache/
+
+IO Statistics
+M: Krutika Dhananjay <kdhananj@redhat.com>
+M: Shyam Ranganathan <srangana@redhat.com>
+S: Maintained
+F: xlators/debug/io-stats/
+
IO threads
-M: Pranith Karampuri <pkarampu@redhat.com>
+M: Pranith Karampuri <pranith.karampuri@phonepe.com>
+P: Ravishankar N <ravishankar@redhat.com>
S: Maintained
F: xlators/performance/io-threads/
+Leases
+M: Poornima G <pgurusid@redhat.com>
+P: Niels de Vos <ndevos@redhat.com>
+P: Soumya Koduri <skoduri@redhat.com>
+S: Maintained
+F: xlators/features/leases/
+
Locks
-M: Pranith Karampuri <pkarampu@redhat.com>
+M: Krutika Dhananjay <kdhananj@redhat.com>
+P: Xavier Hernandez <xhernandez@redhat.com>
S: Maintained
F: xlators/features/locks/
Marker
-M: Raghavendra Gowdappa <rgowdapp@redhat.com>
+M: Kotresh HR <khiremat@redhat.com>
S: Maintained
F: xlators/features/marker/
-NFS
-M: Niels de Vos <ndevos@redhat.com>
+Meta
+M: Mohammed Rafi KC <rafi.kavungal@iternity.com>
+S: Maintained
+F: xlators/features/meta/
+
+Metadata-cache
+M: Poornima G <pgurusid@redhat.com>
+P: Soumya Koduri <skoduri@redhat.com>
S: Maintained
+F: xlators/performance/md-cache/
+
+Negative-lookup Cache
+M: Poornima G <pgurusid@redhat.com>
+P: Pranith Karampuri <pranith.karampuri@phonepe.com>
+S: Maintained
+F: xlators/performance/nl-cache/
+
+gNFS
+M: Jiffin Tony Thottan <jthottan@redhat.com>
+P: Xie Changlong <xiechanglong@cmss.chinamobile.com>
+P: Amar Tumballi <amarts@gmail.com>
+S: Odd Fixes
F: xlators/nfs/server/
-Performance
-M: Raghavendra Gowdappa <rgowdapp@redhat.com>
+Open-behind
S: Maintained
-F: xlators/performance/
+F: xlators/performance/open-behind/
Posix:
-M: Pranith Karampuri <pkarampu@redhat.com>
M: Raghavendra Bhat <raghavendra@redhat.com>
+P: Kotresh HR <khiremat@redhat.com>
+P: Krutika Dhananjay <kdhananj@redhat.com>
S: Maintained
F: xlators/storage/posix/
+Quick-read
+S: Maintained
+F: xlators/performance/quick-read/
+
Quota
-M: Krishnan Parthasarathi <kparthas@redhat.com>
-M: Raghavendra Gowdappa <rgowdapp@redhat.com>
+M: Shyamsundar Ranganathan <srangana@redhat.com>
+P: Hari Gowtham <hgowtham@redhat.com>
S: Maintained
F: xlators/features/quota/
-Tiering
-M: Dan Lambright <dlambrig@redhat.com>
-M: Joseph Fernandes <josferna@redhat.com>
+Read-ahead
+P: Csaba Henk <chenk@redhat.com>
+S: Maintained
+F: xlators/performance/read-ahead/
+
+Readdir-ahead
S: Maintained
-F: xlators/cluster/dht/src/tier.c
-F: xlators/features/changetimerecorder
-F: libglusterfs/src/gfdb
-W: http://www.gluster.org/community/documentation/index.php/Features/data-classification
+F: xlators/performance/readdir-ahead/
+
+Sharding
+M: Krutika Dhananjay <kdhananj@redhat.com>
+P: Xavier Hernandez <xhernandez@redhat.com>
+S: Maintained
+F: xlators/features/shard/
+
+Trash
+M: Anoop C S <anoopcs@redhat.com>
+M: Jiffin Tony Thottan <jthottan@redhat.com>
+S: Maintained
+F: xlators/features/trash/
Upcall
-M: Niels de Vos <ndevos@redhat.com>
+M: Poornima G <pgurusid@redhat.com>
+M: Soumya Koduri <skoduri@redhat.com>
+P: Niels de Vos <ndevos@redhat.com>
S: Maintained
F: xlators/features/upcall/
+Write-behind
+P: Csaba Henk <chenk@redhat.com>
+S: Maintained
+F: xlators/performance/write-behind/
+
+Write Once Read Many
+P: Karthik US <ksubrahm@redhat.com>
+S: Maintained
+F: xlators/features/read-only/
+
+Cloudsync
+M: Susant Kumar Palai <spalai@redhat.com>
+S: Maintained
+F: xlators/features/cloudsync/
+
Other bits of code:
-------------------
Doc
M: Humble Chirammal <hchiramm@redhat.com>
M: Raghavendra Talur <rtalur@redhat.com>
-M: Prashanth Pai <ppai@redhat.com>
-M: Shravan Chandrashekar <shravantc99@gmail.com>
S: Maintained
F: doc/
Geo Replication
-M: Venky Shankar <vshankar@redhat.com>
+M: Aravinda V K <avishwan@redhat.com>
+M: Kotresh HR <khiremat@redhat.com>
+M: Sunny Kumar <sunkumar@redhat.com>
S: Maintained
F: geo-replication/
-
-Glupy
-M: Justin Clift <justin@gluster.org>
+Glusterfind
+M: Aravinda VK <avishwan@redhat.com>
S: Maintained
-F: xlators/features/glupy/
+F: tools/glusterfind/
libgfapi
-M: Anand Avati <avati@redhat.com>
M: Niels de Vos <ndevos@redhat.com>
-M: Shyamsundar Ranganathan <srangana@redhat.com>
+P: Poornima G <pgurusid@redhat.com>
+P: Shyamsundar Ranganathan <srangana@redhat.com>
+P: Soumya Koduri <skoduri@redhat.com>
S: Maintained
F: api/
-libgfdb
-M: Dan Lambright <dlambrig@redhat.com>
-S: Maintained
-F: libglusterfs/src/gfdb/
-
libglusterfs
-M: Niels de Vos <ndevos@redhat.com>
-M: Pranith Karampuri <pkarampu@redhat.com>
+M: Amar Tumballi <amarts@gmail.com>
+M: Xavier Hernandez <xhernandez@redhat.com>
+M: Jeff Darcy <jeff@pl.atyp.us>
+P: Kaleb Keithley <kkeithle@redhat.com>
+P: Niels de Vos <ndevos@redhat.com>
+P: Pranith Karampuri <pranith.karampuri@phonepe.com>
+P: Shyamsundar Ranganathan <srangana@redhat.com>
S: Maintained
F: libglusterfs/
-Management Daemon
-M: Krishnan Parthasarathi <kparthas@redhat.com>
-M: Kaushal Madappa <kmadapp@redhat.com>
+xxhash
+M: Aravinda VK <avishwan@redhat.com>
+M: Kotresh HR <khiremat@redhat.com>
+P: Yaniv Kaul <ykaul@redhat.com>
+S: Maintained
+F: contrib/xxhash/
+T: https://github.com/Cyan4973/xxHash.git
+
+Management Daemon - glusterd
M: Atin Mukherjee <amukherj@redhat.com>
+M: Mohit Agrawal <moagrawa@redhat.com>
+M: Sanju Rakonde <srakonde@redhat.com>
S: Maintained
F: cli/
-F: xlators/mgmt/
+F: xlators/mgmt/glusterd/
+
+Protocol
+M: Niels de Vos <ndevos@redhat.com>
+P: Mohammed Rafi KC <rafi.kavungal@iternity.com>
+S: Maintained
+F: xlators/protocol/
Remote Procedure Call subsystem
-M: Raghavendra Gowdappa <rgowdapp@redhat.com>
-M: Anand Avati <avati@redhat.com>
+P: Mohit Agrawal <moagrawa@redhat.com>
S: Maintained
-F: rpc/
+F: rpc/rpc-lib/
+F: rpc/xdr/
Snapshot
-M: Rajesh Joesh <rjoseph@redhat.com>
+M: Raghavendra Bhat <raghavendra@redhat.com>
+P: Mohammed Rafi KC <rafi.kavungal@iternity.com>
+P: Sunny Kumar <sunkumar@redhat.com>
S: Maintained
F: xlators/mgmt/glusterd/src/glusterd-snap*
F: extras/snap-scheduler.py
-Distribution Specific:
-----------------------
-Build:
-M: Kaleb Keithley <kkeithle@redhat.com>
-M: Niels de Vos <ndevos@redhat.com>
+Socket subsystem
+P: Krutika Dhananjay <kdhananj@redhat.com>
+P: Milind Changire <mchangir@redhat.com>
+P: Mohammed Rafi KC <rafi.kavungal@iternity.com>
+P: Mohit Agrawal <moagrawa@redhat.com>
S: Maintained
+F: rpc/rpc-transport/socket/
-Debian Packaging
-M: Patrick Matthäi <pmatthaei@debian.org>
-M: Louis Zuckerman <me@louiszuckerman.com>
+Testing - .t framework
+M: Raghavendra Talur <rtalur@redhat.com>
S: Maintained
-W: http://packages.qa.debian.org/g/glusterfs.html
+F: tests/
-Fedora Packaging
-M: glusterfs-owner@fedoraproject.org
-M: Humble Chirammal <hchiramm@redhat.com>
-M: Kaleb Keithley <kkeithle@redhat.com>
-M: Lalatendu Mohanty <lmohanty@redhat.com>
+Utilities
+M: Aravinda VK <avishwan@redhat.com>
+P: Niels de Vos <ndevos@redhat.com>
+P: Raghavendra Talur <rtalur@redhat.com>
+P: Sachidanda Urs <surs@redhat.com>
+S: Maintained
+F: extras/
+
+Events APIs
+M: Aravinda VK <avishwan@redhat.com>
+S: Maintained
+F: events/
+F: libglusterfs/src/events*
+F: libglusterfs/src/eventtypes*
+F: extras/systemd/glustereventsd*
+
+Distribution Specific:
+----------------------
+Build:
M: Niels de Vos <ndevos@redhat.com>
+M: Hari Gowtham <hgowtham@redhat.com>
+P: Anoop C S <anoopcs@redhat.com>
+P: Raghavendra Talur <rtalur@redhat.com>
+P: Rinku Kothiya <rkothiya@redhat.com>
S: Maintained
-W: https://apps.fedoraproject.org/packages/glusterfs
-T: http://pkgs.fedoraproject.org/git/glusterfs.git
-FreeBSD port
-M: Harshavardhana <harsha@harshavardhana.net>
+Debian packages on download.gluster.org
+M: packaging@gluster.org
+M: Kaleb Keithley <kkeithle@redhat.com>
+P: Sheetal Pamecha <spamecha@redhat.com>
+P: Shwetha Acharya <sacharya@redhat.com>
S: Maintained
+W: http://download.gluster.org/pub/gluster/glusterfs/LATEST/Debian/Debian.README
+T: https://github.com/gluster/glusterfs-debian.git
-MacOS X port
-M: Dennis Schafroth <dennis@schafroth.com>
-M: Harshavardhana <harsha@harshavardhana.net>
+OpenSuSE
+M: packaging@gluster.org
+M: Kaleb Keithley <kkeithle@redhat.com>
+P: Sheetal Pamecha <spamecha@redhat.com>
+P: Shwetha Acharya <sacharya@redhat.com>
S: Maintained
+W: https://build.opensuse.org/repositories/home:glusterfs
+W: https://download.gluster.org/pub/gluster/glusterfs/LATEST/SuSE/SuSE.README
+T: https://github.com/gluster/glusterfs-suse.git
-NetBSD port
-M: Emmanuel Dreyfus <manu@netbsd.org>
+Packages for the CentOS Storage SIG
+M: centos-devel@centos.org
+M: Niels de Vos <ndevos@redhat.com>
+P: Kaleb Keithley <kkeithle@redhat.com>
S: Maintained
-W: http://pkgsrc.se/filesystems/glusterfs
+W: https://wiki.centos.org/SpecialInterestGroup/Storage/Gluster
+T: https://github.com/CentOS-Storage-SIG/glusterfs.git
-Ubuntu Packaging
-M: Louis Zuckerman <me@louiszuckerman.com>
+Ubuntu PPA
+M: packaging@gluster.org
+M: Kaleb Keithley <kkeithle@redhat.com>
+P: Sheetal Pamecha <spamecha@redhat.com>
+P: Shwetha Acharya <sacharya@redhat.com>
S: Maintained
+W: https://launchpad.net/~gluster
W: http://download.gluster.org/pub/gluster/glusterfs/LATEST/Ubuntu/Ubuntu.README
-
+T: https://github.com/gluster/glusterfs-debian.git
Related projects
----------------
-Gluster Openstack Swift
-M: Luis Pabon <lpabon@redhat.com>
+Gluster Block
+M: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+M: Xiubo Li <xiubli@redhat.com>
S: Maintained
-T: https://github.com/gluster/gluster-swift.git
+T: https://github.com/gluster/gluster-block.git
-GlusterFS Hadoop HCFS plugin
-M: Jay Vyas <jvyas@redhat.com>
+GlusterFS core-utils
+M: Anoop C S <anoopcs@redhat.com>
S: Maintained
-T: https://github.com/gluster/glusterfs-hadoop.git
+T: https://github.com/gluster/glusterfs-coreutils.git
NFS-Ganesha FSAL plugin
-M: Anand Subramanian <ansubram@redhat.com>
+M: Jiffin Tony Thottan <jthottan@redhat.com>
+M: Kaleb Keithley <kkeithle@redhat.com>
+M: Soumya Koduri <skoduri@redhat.com>
S: Maintained
T: git://github.com/nfs-ganesha/nfs-ganesha.git
F: src/nfs-ganesha~/src/FSAL/FSAL_GLUSTER/
QEMU integration
-M: Bharata B Rao <bharata@linux.vnet.ibm.com>
+M: Niels de Vos <ndevos@redhat.com>
+M: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
S: Maintained
T: git://git.qemu.org/qemu.git
F: block/gluster.c
Samba VFS plugin
+M: Anoop C S <anoopcs@redhat.com>
M: Raghavendra Talur <rtalur@redhat.com>
-M: Jose Rivera <jrivera@redhat.com>
-M: Ira Cooper <icooper@redhat.com>
+M: Michael Adam <madam@redhat.com>
+M: Poornima G <pgurusid@redhat.com>
S: Maintained
T: git://git.samba.org/samba.git
F: source3/modules/vfs_glusterfs.c
+Storhaug
+M: Jose A. Rivera <jarrpa@redhat.com>
+P: Kaleb Keithley <kkeithle@redhat.com>
+S: Maintained
+T: https://github.com/linux-ha-storage/storhaug.git
+
+Testing - Glusto-Tests
+M: Jonathan Holloway <jholloway@redhat.com>
+M: Vijay Bhaskar Reddy Avuthu <vavuthu@redhat.com>
+M: Akarsha Rai <akrai@redhat.com>
+S: Maintained
+T: https://github.com/gluster/glusto-tests.git
+
Wireshark dissectors
M: Niels de Vos <ndevos@redhat.com>
S: Maintained
@@ -300,14 +456,55 @@ W: https://forge.gluster.org/wireshark
T: http://code.wireshark.org/git/wireshark
F: epan/dissectors/packet-gluster*
+Infrastructure
+--------------
+
+Platform
+M: Michael Scherer <misc@redhat.com>
+P: Shyamsundar Ranganathan <srangana@redhat.com>
+P: Amar Tumballi <amarts@gmail.com>
+
+Continuous Integration
+M: Michael Scherer <misc@redhat.com>
+M: Deepshikha Khandelwal <dkhandel@redhat.com>
+P: Niels de Vos <ndevos@redhat.com>
+
Special Thanks
--------------
GlusterFS would not be possible without the contributions of:
-M: Amar Tumballi <amarts@gmail.com>
-M: Chris Hertel <chertel@redhat.com>
+
+M: Vijay Bellur <vbellur@redhat.com>
+M: Jeff Darcy <jeff@pl.atyp.us>
+M: Shreyas Siravara <sshreyas@fb.com>
+M: Kaushal M <kaushal@redhat.com>
+M: Nigel Babu
+M: Prashanth Pai
+P: Sanoj Unnikrishnan
+P: Milind Changire <mchangir@redhat.com>
+P: Sunil Kumar Acharya <sheggodu@redhat.com>
+M: Samikshan Bairagya <samikshan@gmail.com>
+M: Chris Hertel
M: M. Mohan Kumar <mohan@in.ibm.com>
M: Shishir Gowda <gowda.shishir@gmail.com>
M: Brian Foster <bfoster@redhat.com>
-M: Csaba Henk <chenk@redhat.com>
+M: Anand Avati <avati@cs.stanford.edu>
+M: Dennis Schafroth <dennis@schafroth.com>
+M: Harshavardhana <harsha@harshavardhana.net>
+M: Krishnan Parthasarathi
+M: Justin Clift <justin@gluster.org>
+M: Venky Shankar <vshankar@redhat.com>
+M: Shravan Chandrashekar <shravantc99@gmail.com>
+M: Joseph Fernandes
+M: Vijaikumar Mallikarjuna
+M: Anand Subramanian
+M: Bharata B Rao <bharata@linux.vnet.ibm.com>
+M: Rajesh Joseph
+M: Dan Lambright
+M: Jay Vyas
+M: Luis Pabon
+M: Ira Cooper
+M: Shwetha Panduranga
+M: Nithya Balachandran
+M: Raghavendra Gowdappa
diff --git a/Makefile.am b/Makefile.am
index 5bfe07c4abf..98ea5c1038d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,58 +1,52 @@
+SOURCES = site.h
+
EXTRA_DIST = autogen.sh \
- COPYING-GPLV2 COPYING-LGPLV3 \
+ COPYING-GPLV2 COPYING-LGPLV3 COMMITMENT \
INSTALL README.md AUTHORS THANKS NEWS \
- glusterfs.spec glusterfs-api.pc.in libgfchangelog.pc.in libgfdb.pc.in \
+ glusterfs.spec glusterfs-api.pc.in libgfchangelog.pc.in \
run-tests.sh \
build-aux/pkg-version \
- build-aux/xdrgen \
- contrib/argp-standalone \
- contrib/umountd \
- contrib/uuid \
+ contrib/umountd \
$(shell find $(top_srcdir)/tests -type f -print)
-SUBDIRS = $(ARGP_STANDALONE_DIR) libglusterfs rpc api xlators glusterfsd \
- $(FUSERMOUNT_SUBDIR) doc extras cli heal @SYNCDAEMON_SUBDIR@ \
- @UMOUNTD_SUBDIR@ tools
+
+SUBDIRS = $(ARGP_STANDALONE_DIR) libglusterfs rpc libglusterd api \
+ glusterfsd xlators $(FUSERMOUNT_SUBDIR) doc extras cli heal \
+ @SYNCDAEMON_SUBDIR@ @UMOUNTD_SUBDIR@ tools events
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = glusterfs-api.pc libgfchangelog.pc
-if USE_GFDB
-pkgconfig_DATA += libgfdb.pc
-endif
-CLEANFILES =
-CONFIG_CLEAN_FILES = $(CONTRIB_BUILDDIR)/uuid/uuid_types.h
+CLEANFILES = glusterfs-api.pc libgfchangelog.pc contrib/umountd/Makefile
+
+clean-local:
+ find . -name '*.o' -o -name '*.lo' -o -name '.Po' | xargs rm -f
gitclean: distclean
find . -name Makefile.in -exec rm -f {} \;
- find . -name Makefile \( ! -path "$(top_srcdir)/extras/FreeBSD/*" \
- ! -path "$(top_srcdir)/extras/command-completion/*" \
- ! -path "$(top_srcdir)/extras/test/*" \) -exec rm -f {} \;
find . -name mount.glusterfs -exec rm -f {} \;
+ find . -name .deps -o -name .libs | xargs rm -rf
rm -fr autom4te.cache
rm -f missing aclocal.m4 config.h.in config.guess config.sub ltmain.sh install-sh configure depcomp
- -rm -fr $(CONTRIBDIR)/argp-standalone/autom4te.cache
- -rm -f $(CONTRIBDIR)/argp-standalone/aclocal.m4
- -rm -f $(CONTRIBDIR)/argp-standalone/config.h.in
- -rm -f $(CONTRIBDIR)/argp-standalone/configure
- -rm -f $(CONTRIBDIR)/argp-standalone/config.status
- -rm -f $(CONTRIBDIR)/argp-standalone/config.log
- -rm -f $(CONTRIBDIR)/argp-standalone/depcomp
- -rm -fr $(CONTRIBDIR)/argp-standalone/.deps
- -rm -f $(CONTRIBDIR)/argp-standalone/install-sh
- -rm -f $(CONTRIBDIR)/argp-standalone/missing
+# dist-hook gets executed with 'make dist', this is the only target getting
+# executed, a dist-hook in other Makefile.am files seem to get ignored.
dist-hook: gen-VERSION gen-ChangeLog
- -rm -fr $(distdir)/contrib/argp-standalone/autom4te.cache
- -rm -fr $(distdir)/contrib/argp-standalone/.deps
-rm -fr $(distdir)/contrib/umountd/.deps
- -rm -fr $(distdir)/config.{guess,sub}
+ -rm -f $(distdir)/events/src/eventtypes.py
+ -rm -f $(distdir)/tests/env.rc
+ -cp -f $(top_srcdir)/build-aux/config.sub.dist $(distdir)/config.sub
+ -cp -f $(top_srcdir)/build-aux/config.guess.dist $(distdir)/config.guess
+
+.PHONY: gen-VERSION gen-ChangeLog clang-check
-.PHONY: gen-VERSION gen-ChangeLog
+clang-check:
+ @$(top_srcdir)/extras/clang-checker.sh
gen-ChangeLog:
(cd $(srcdir) && git diff && echo ===== git log ==== && git log) > $(distdir)/ChangeLog
+.PHONY : gen-VERSION
gen-VERSION:
if test -d $(top_srcdir)/.git; then \
cd $(top_srcdir); \
diff --git a/README.md b/README.md
index 0e2c2b7d2b4..9d68e033782 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,46 @@
-For information about contributing to GlusterFS, please follow the below link :
-[Contributing to GlusterFS community](http://www.gluster.org/community/documentation/index.php/Main_Page#Contributing_to_the_Gluster_Community)
+# Gluster
+ Gluster is a software defined distributed storage that can scale to several
+ petabytes. It provides interfaces for object, block and file storage.
-*GlusterFS does not follow the [GitHub: Fork & pull](https://help.github.com/articles/using-pull-requests/) workflow but use [Gerrit](http://review.gluster.org) for code review.*
+## Development
+ The development workflow is documented in [Contributors guide](CONTRIBUTING.md)
-The development guidelines are detailed in [Development Workflow.](http://www.gluster.org/community/documentation/index.php/Simplified_dev_workflow)
+## Documentation
+ The Gluster documentation can be found at [Gluster Docs](http://docs.gluster.org).
-The GlusterFS documentation can be found at [Documentation](http://gluster.readthedocs.org/en/latest)
+## Deployment
+ Quick instructions to build and install can be found in [INSTALL](INSTALL) file.
-For more info, please visit http://www.gluster.org/.
+## Testing
+
+ GlusterFS source contains some functional tests under `tests/` directory. All
+ these tests are run against every patch submitted for review. If you want your
+ patch to be tested, please add a `.t` test file as part of your patch submission.
+ You can also submit a patch to only add a `.t` file for the test case you are
+ aware of.
+
+ To run these tests, on your test-machine, just run `./run-tests.sh`. Don't run
+ this on a machine where you have 'production' glusterfs is running, as it would
+ blindly kill all gluster processes in each runs.
+
+ If you are sending a patch, and want to validate one or few specific tests, then
+ run a single test by running the below command.
+
+```
+ bash# /bin/bash ${path_to_gluster}/tests/basic/rpc-coverage.t
+```
+
+ You can also use `prove` tool if available in your machine, as follows.
+
+```
+ bash# prove -vmfe '/bin/bash' ${path_to_gluster}/tests/basic/rpc-coverage.t
+```
+
+
+## Maintainers
+ The list of Gluster maintainers is available in [MAINTAINERS](MAINTAINERS) file.
+
+## License
+ Gluster is dual licensed under [GPLV2](COPYING-GPLV2) and [LGPLV3+](COPYING-LGPLV3).
+
+ Please visit the [Gluster Home Page](http://www.gluster.org/) to find out more about Gluster.
diff --git a/api/examples/getvolfile.py b/api/examples/getvolfile.py
index 184586c632d..3b2c8ab5a15 100755
--- a/api/examples/getvolfile.py
+++ b/api/examples/getvolfile.py
@@ -1,43 +1,45 @@
-#!/usr/bin/python
+#!/usr/bin/python3
+from __future__ import print_function
import ctypes
import ctypes.util
-api = ctypes.CDLL(ctypes.util.find_library("gfapi"))
+api = ctypes.CDLL("libgfapi.so")
api.glfs_get_volfile.argtypes = [ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_ulong]
-api.glfs_get_volfile.restype = ctypes.c_long;
+api.glfs_get_volfile.restype = ctypes.c_long
-def get_volfile (host, volume):
- # This is set to a large value to exercise the "buffer not big enough"
- # path. More realistically, you'd just start with a huge buffer.
- BUF_LEN = 0
- fs = api.glfs_new(volume)
- #api.glfs_set_logging(fs,"/dev/stderr",7)
- api.glfs_set_volfile_server(fs,"tcp",host,24007)
- api.glfs_init(fs)
- vbuf = ctypes.create_string_buffer(BUF_LEN)
- vlen = api.glfs_get_volfile(fs,vbuf,BUF_LEN)
- if vlen < 0:
- vlen = BUF_LEN - vlen
- vbuf = ctypes.create_string_buffer(vlen)
- vlen = api.glfs_get_volfile(fs,vbuf,vlen)
- api.glfs_fini(fs)
- if vlen <= 0:
- return vlen
- return vbuf.value[:vlen]
+
+def get_volfile(host, volume):
+ # This is set to a large value to exercise the "buffer not big enough"
+ # path. More realistically, you'd just start with a huge buffer.
+ BUF_LEN = 0
+ fs = api.glfs_new(volume)
+ # api.glfs_set_logging(fs,"/dev/stderr",7)
+ api.glfs_set_volfile_server(fs, "tcp", host, 24007)
+ api.glfs_init(fs)
+ vbuf = ctypes.create_string_buffer(BUF_LEN)
+ vlen = api.glfs_get_volfile(fs, vbuf, BUF_LEN)
+ if vlen < 0:
+ vlen = BUF_LEN - vlen
+ vbuf = ctypes.create_string_buffer(vlen)
+ vlen = api.glfs_get_volfile(fs, vbuf, vlen)
+ api.glfs_fini(fs)
+ if vlen <= 0:
+ return vlen
+ return vbuf.value[:vlen]
if __name__ == "__main__":
- import sys
+ import sys
- try:
- res = apply(get_volfile,sys.argv[1:3])
- except:
- print "fetching volfile failed (volume not started?)"
+ try:
+ res = get_volfile(*sys.argv[1:3])
+ except:
+ print("fetching volfile failed (volume not started?)")
- try:
- for line in res.split('\n'):
- print line
- except:
- print "bad return value %s" % res
+ try:
+ for line in res.split('\n'):
+ print(line)
+ except:
+ print("bad return value %s" % res)
diff --git a/api/examples/glfsxmp.c b/api/examples/glfsxmp.c
index 7ff3f0eb7ee..a55616ef739 100644
--- a/api/examples/glfsxmp.c
+++ b/api/examples/glfsxmp.c
@@ -1,1598 +1,1811 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
-#include "api/glfs.h"
-#include "api/glfs-handles.h"
+#include <glusterfs/api/glfs.h>
+#include <glusterfs/api/glfs-handles.h>
#include <string.h>
#include <time.h>
+#define TEST_STR_LEN 2048
int
-test_dirops (glfs_t *fs)
+test_dirops(glfs_t *fs)
{
- glfs_fd_t *fd = NULL;
- char buf[512];
- struct dirent *entry = NULL;
-
- fd = glfs_opendir (fs, "/");
- if (!fd) {
- fprintf (stderr, "/: %s\n", strerror (errno));
- return -1;
- }
-
- fprintf (stderr, "Entries:\n");
- while (glfs_readdir_r (fd, (struct dirent *)buf, &entry), entry) {
- fprintf (stderr, "%s: %lu\n", entry->d_name, glfs_telldir (fd));
- }
-
- glfs_closedir (fd);
- return 0;
+ glfs_fd_t *fd = NULL;
+ char buf[512];
+ struct dirent *entry = NULL;
+
+ fd = glfs_opendir(fs, "/");
+ if (!fd) {
+ fprintf(stderr, "/: %s\n", strerror(errno));
+ return -1;
+ }
+
+ fprintf(stderr, "Entries:\n");
+ while (glfs_readdir_r(fd, (struct dirent *)buf, &entry), entry) {
+ fprintf(stderr, "%s: %lu\n", entry->d_name, glfs_telldir(fd));
+ }
+
+ glfs_closedir(fd);
+ return 0;
}
-
int
-test_xattr (glfs_t *fs)
+test_xattr(glfs_t *fs)
{
- char *filename = "/filename2";
- char buf[512];
- char *ptr;
- int ret;
-
- ret = glfs_setxattr (fs, filename, "user.testkey", "testval", 8, 0);
- fprintf (stderr, "setxattr(%s): %d (%s)\n", filename, ret,
- strerror (errno));
-
- ret = glfs_setxattr (fs, filename, "user.testkey2", "testval", 8, 0);
- fprintf (stderr, "setxattr(%s): %d (%s)\n", filename, ret,
- strerror (errno));
-
- ret = glfs_listxattr (fs, filename, buf, 512);
- fprintf (stderr, "listxattr(%s): %d (%s)\n", filename, ret,
- strerror (errno));
- if (ret < 0)
- return -1;
-
- for (ptr = buf; ptr < buf + ret; ptr++) {
- printf ("key=%s\n", ptr);
- ptr += strlen (ptr);
- }
-
- return 0;
+ char *filename = "/filename2";
+ char *linkfile = "/linkfile";
+ glfs_fd_t *fd = NULL;
+ char buf[512];
+ char *ptr;
+ int ret;
+
+ ret = glfs_setxattr(fs, filename, "user.testkey", "testval", 8, 0);
+ fprintf(stderr, "setxattr(%s): %d (%s)\n", filename, ret, strerror(errno));
+
+ ret = glfs_setxattr(fs, filename, "user.testkey2", "testval", 8, 0);
+ fprintf(stderr, "setxattr(%s): %d (%s)\n", filename, ret, strerror(errno));
+
+ ret = glfs_getxattr(fs, filename, "user.testkey", buf, 512);
+ fprintf(stderr, "getxattr(%s): %d (%s)\n", filename, ret, strerror(errno));
+ if (ret < 0)
+ return -1;
+
+ ret = glfs_listxattr(fs, filename, buf, 512);
+ fprintf(stderr, "listxattr(%s): %d (%s)\n", filename, ret, strerror(errno));
+ if (ret < 0)
+ return -1;
+
+ ret = glfs_symlink(fs, "filename", linkfile);
+ fprintf(stderr, "symlink(%s %s): %s\n", filename, linkfile,
+ strerror(errno));
+ if (ret < 0)
+ return -1;
+
+ ret = glfs_readlink(fs, linkfile, buf, 512);
+ fprintf(stderr, "readlink(%s) : %d (%s)\n", filename, ret, strerror(errno));
+ if (ret < 0)
+ return -1;
+
+ ret = glfs_lsetxattr(fs, filename, "user.testkey3", "testval", 8, 0);
+ fprintf(stderr, "lsetxattr(%s) : %d (%s)\n", linkfile, ret,
+ strerror(errno));
+ if (ret < 0)
+ return -1;
+
+ ret = glfs_llistxattr(fs, linkfile, buf, 512);
+ fprintf(stderr, "llistxattr(%s): %d (%s)\n", filename, ret,
+ strerror(errno));
+ if (ret < 0)
+ return -1;
+
+ ret = glfs_lgetxattr(fs, filename, "user.testkey3", buf, 512);
+ fprintf(stderr, "lgetxattr(%s): %d (%s)\n", linkfile, ret, strerror(errno));
+ if (ret < 0)
+ return -1;
+
+ for (ptr = buf; ptr < buf + ret; ptr++) {
+ printf("key=%s\n", ptr);
+ ptr += strlen(ptr);
+ }
+
+ ret = glfs_removexattr(fs, filename, "user.testkey2");
+ fprintf(stderr, "removexattr(%s): %d (%s)\n", filename, ret,
+ strerror(errno));
+
+ fd = glfs_open(fs, filename, O_RDWR);
+ fprintf(stderr, "open(%s): (%p) %s\n", filename, fd, strerror(errno));
+
+ ret = glfs_fsetxattr(fd, "user.testkey2", "testval", 8, 0);
+ fprintf(stderr, "fsetxattr(%s): %d (%s)\n", filename, ret, strerror(errno));
+
+ ret = glfs_fgetxattr(fd, "user.testkey2", buf, 512);
+ fprintf(stderr, "fgetxattr(%s): %d (%s)\n", filename, ret, strerror(errno));
+
+ ret = glfs_flistxattr(fd, buf, 512);
+ fprintf(stderr, "flistxattr(%s): %d (%s)\n", filename, ret,
+ strerror(errno));
+ if (ret < 0)
+ return -1;
+
+ for (ptr = buf; ptr < buf + ret; ptr++) {
+ printf("key=%s\n", ptr);
+ ptr += strlen(ptr);
+ }
+
+ ret = glfs_fremovexattr(fd, "user.testkey2");
+ fprintf(stderr, "fremovexattr(%s): %d (%s)\n", filename, ret,
+ strerror(errno));
+
+ glfs_close(fd);
+
+ return 0;
}
-
int
-test_chdir (glfs_t *fs)
+test_chdir(glfs_t *fs)
{
- int ret = -1;
- char *topdir = "/topdir";
- char *linkdir = "/linkdir";
- char *subdir = "./subdir";
- char *respath = NULL;
- char pathbuf[4096];
-
- ret = glfs_mkdir (fs, topdir, 0755);
- if (ret) {
- fprintf (stderr, "mkdir(%s): %s\n", topdir, strerror (errno));
- return -1;
- }
-
- respath = glfs_getcwd (fs, pathbuf, 4096);
- fprintf (stdout, "getcwd() = %s\n", respath);
-
- ret = glfs_symlink (fs, topdir, linkdir);
- if (ret) {
- fprintf (stderr, "symlink(%s, %s): %s\n", topdir, linkdir, strerror (errno));
- return -1;
- }
-
- ret = glfs_chdir (fs, linkdir);
- if (ret) {
- fprintf (stderr, "chdir(%s): %s\n", linkdir, strerror (errno));
- return -1;
- }
-
- respath = glfs_getcwd (fs, pathbuf, 4096);
- fprintf (stdout, "getcwd() = %s\n", respath);
-
- respath = glfs_realpath (fs, subdir, pathbuf);
- if (respath) {
- fprintf (stderr, "realpath(%s) worked unexpectedly: %s\n", subdir, respath);
- return -1;
- }
-
- ret = glfs_mkdir (fs, subdir, 0755);
- if (ret) {
- fprintf (stderr, "mkdir(%s): %s\n", subdir, strerror (errno));
- return -1;
- }
-
- respath = glfs_realpath (fs, subdir, pathbuf);
- if (!respath) {
- fprintf (stderr, "realpath(%s): %s\n", subdir, strerror (errno));
- } else {
- fprintf (stdout, "realpath(%s) = %s\n", subdir, respath);
- }
-
- ret = glfs_chdir (fs, subdir);
- if (ret) {
- fprintf (stderr, "chdir(%s): %s\n", subdir, strerror (errno));
- return -1;
- }
-
- respath = glfs_getcwd (fs, pathbuf, 4096);
- fprintf (stdout, "getcwd() = %s\n", respath);
-
- respath = glfs_realpath (fs, "/linkdir/subdir", pathbuf);
- if (!respath) {
- fprintf (stderr, "realpath(/linkdir/subdir): %s\n", strerror (errno));
- } else {
- fprintf (stdout, "realpath(/linkdir/subdir) = %s\n", respath);
- }
-
- return 0;
+ int ret = -1;
+ char *dir = "/dir";
+ char *topdir = "/topdir";
+ char *linkdir = "/linkdir";
+ char *linkdir2 = "/linkdir2";
+ char *subdir = "./subdir";
+ char *respath = NULL;
+ char pathbuf[4096];
+
+ ret = glfs_mkdir(fs, topdir, 0755);
+ fprintf(stderr, "mkdir(%s): %s\n", topdir, strerror(errno));
+ if (ret)
+ return -1;
+
+ ret = glfs_mkdir(fs, dir, 0755);
+ fprintf(stderr, "mkdir(%s): %s\n", dir, strerror(errno));
+ if (ret)
+ return -1;
+
+ respath = glfs_getcwd(fs, pathbuf, 4096);
+ fprintf(stdout, "getcwd() = %s\n", respath);
+
+ ret = glfs_symlink(fs, "topdir", linkdir);
+ if (ret) {
+ fprintf(stderr, "symlink(%s, %s): %s\n", topdir, linkdir,
+ strerror(errno));
+ return -1;
+ }
+
+ ret = glfs_chdir(fs, linkdir);
+ if (ret) {
+ fprintf(stderr, "chdir(%s): %s\n", linkdir, strerror(errno));
+ return -1;
+ }
+
+ respath = glfs_getcwd(fs, pathbuf, 4096);
+ fprintf(stdout, "getcwd() = %s\n", respath);
+
+ respath = glfs_realpath(fs, subdir, pathbuf);
+ if (respath) {
+ fprintf(stderr, "realpath(%s) worked unexpectedly: %s\n", subdir,
+ respath);
+ return -1;
+ }
+
+ ret = glfs_mkdir(fs, subdir, 0755);
+ if (ret) {
+ fprintf(stderr, "mkdir(%s): %s\n", subdir, strerror(errno));
+ return -1;
+ }
+
+ respath = glfs_realpath(fs, subdir, pathbuf);
+ if (!respath) {
+ fprintf(stderr, "realpath(%s): %s\n", subdir, strerror(errno));
+ } else {
+ fprintf(stdout, "realpath(%s) = %s\n", subdir, respath);
+ }
+
+ ret = glfs_chdir(fs, subdir);
+ if (ret) {
+ fprintf(stderr, "chdir(%s): %s\n", subdir, strerror(errno));
+ return -1;
+ }
+
+ respath = glfs_getcwd(fs, pathbuf, 4096);
+ fprintf(stdout, "getcwd() = %s\n", respath);
+
+ respath = glfs_realpath(fs, "/linkdir/subdir", pathbuf);
+ if (!respath) {
+ fprintf(stderr, "realpath(/linkdir/subdir): %s\n", strerror(errno));
+ } else {
+ fprintf(stdout, "realpath(/linkdir/subdir) = %s\n", respath);
+ }
+
+ return 0;
}
#ifdef DEBUG
static void
-peek_stat (struct stat *sb)
+peek_stat(struct stat *sb)
{
- printf ("Dumping stat information:\n");
- printf ("File type: ");
-
- switch (sb->st_mode & S_IFMT) {
- case S_IFBLK: printf ("block device\n"); break;
- case S_IFCHR: printf ("character device\n"); break;
- case S_IFDIR: printf ("directory\n"); break;
- case S_IFIFO: printf ("FIFO/pipe\n"); break;
- case S_IFLNK: printf ("symlink\n"); break;
- case S_IFREG: printf ("regular file\n"); break;
- case S_IFSOCK: printf ("socket\n"); break;
- default: printf ("unknown?\n"); break;
- }
-
- printf ("I-node number: %ld\n", (long) sb->st_ino);
-
- printf ("Mode: %lo (octal)\n",
- (unsigned long) sb->st_mode);
-
- printf ("Link count: %ld\n", (long) sb->st_nlink);
- printf ("Ownership: UID=%ld GID=%ld\n",
- (long) sb->st_uid, (long) sb->st_gid);
-
- printf ("Preferred I/O block size: %ld bytes\n",
- (long) sb->st_blksize);
- printf ("File size: %lld bytes\n",
- (long long) sb->st_size);
- printf ("Blocks allocated: %lld\n",
- (long long) sb->st_blocks);
-
- printf ("Last status change: %s", ctime(&sb->st_ctime));
- printf ("Last file access: %s", ctime(&sb->st_atime));
- printf ("Last file modification: %s", ctime(&sb->st_mtime));
-
- return;
+ printf("Dumping stat information:\n");
+ printf("File type: ");
+
+ switch (sb->st_mode & S_IFMT) {
+ case S_IFBLK:
+ printf("block device\n");
+ break;
+ case S_IFCHR:
+ printf("character device\n");
+ break;
+ case S_IFDIR:
+ printf("directory\n");
+ break;
+ case S_IFIFO:
+ printf("FIFO/pipe\n");
+ break;
+ case S_IFLNK:
+ printf("symlink\n");
+ break;
+ case S_IFREG:
+ printf("regular file\n");
+ break;
+ case S_IFSOCK:
+ printf("socket\n");
+ break;
+ default:
+ printf("unknown?\n");
+ break;
+ }
+
+ printf("I-node number: %ld\n", (long)sb->st_ino);
+
+ printf("Mode: %lo (octal)\n",
+ (unsigned long)sb->st_mode);
+
+ printf("Link count: %ld\n", (long)sb->st_nlink);
+ printf("Ownership: UID=%ld GID=%ld\n", (long)sb->st_uid,
+ (long)sb->st_gid);
+
+ printf("Preferred I/O block size: %ld bytes\n", (long)sb->st_blksize);
+ printf("File size: %lld bytes\n", (long long)sb->st_size);
+ printf("Blocks allocated: %lld\n", (long long)sb->st_blocks);
+
+ printf("Last status change: %s", ctime(&sb->st_ctime));
+ printf("Last file access: %s", ctime(&sb->st_atime));
+ printf("Last file modification: %s", ctime(&sb->st_mtime));
+
+ return;
}
static void
-peek_handle (unsigned char *glid)
+peek_handle(unsigned char *glid)
{
- int i;
+ int i;
- for (i = 0; i < GFAPI_HANDLE_LENGTH; i++)
- {
- printf (":%02x:", glid[i]);
- }
- printf ("\n");
+ for (i = 0; i < GFAPI_HANDLE_LENGTH; i++) {
+ printf(":%02x:", glid[i]);
+ }
+ printf("\n");
}
-#else /* DEBUG */
+#else /* DEBUG */
static void
-peek_stat (struct stat *sb)
+peek_stat(struct stat *sb)
{
- return;
+ return;
}
static void
-peek_handle (unsigned char *id)
+peek_handle(unsigned char *id)
{
- return;
+ return;
}
#endif /* DEBUG */
-glfs_t *fs = NULL;
-char *full_parent_name = "/testdir", *parent_name = "testdir";
+glfs_t *fs = NULL;
+char *full_parent_name = "/testdir", *parent_name = "testdir";
void
-test_h_unlink (void)
+test_h_unlink(void)
{
- char *my_dir = "unlinkdir";
- char *my_file = "file.txt";
- char *my_subdir = "dir1";
- struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL,
- *subdir = NULL, *subleaf = NULL;
- struct stat sb;
- int ret;
-
- printf ("glfs_h_unlink tests: In Progress\n");
-
- /* Prepare tests */
- parent = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, NULL, strerror (errno));
- printf ("glfs_h_lookupat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- dir = glfs_h_mkdir (fs, parent, my_dir, 0644, &sb);
- if (dir == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- my_dir, parent, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- leaf = glfs_h_creat (fs, dir, my_file, O_CREAT, 0644, &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
- my_file, dir, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- subdir = glfs_h_mkdir (fs, dir, my_subdir, 0644, &sb);
- if (subdir == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- my_subdir, dir, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- subleaf = glfs_h_creat (fs, subdir, my_file, O_CREAT, 0644, &sb);
- if (subleaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
- my_file, subdir, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- /* unlink non empty directory */
- ret = glfs_h_unlink (fs, dir, my_subdir);
- if ((ret && errno != ENOTEMPTY) || (ret == 0)) {
- fprintf (stderr, "glfs_h_unlink: error unlinking %s: it is non empty: %s\n",
- my_subdir, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- /* unlink regular file */
- ret = glfs_h_unlink (fs, subdir, my_file);
- if (ret) {
- fprintf (stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n",
- my_file, subdir, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- /* unlink directory */
- ret = glfs_h_unlink (fs, dir, my_subdir);
- if (ret) {
- fprintf (stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n",
- my_subdir, dir, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- /* unlink regular file */
- ret = glfs_h_unlink (fs, dir, my_file);
- if (ret) {
- fprintf (stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n",
- my_file, dir, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- /* unlink non-existent regular file */
- ret = glfs_h_unlink (fs, dir, my_file);
- if ((ret && errno != ENOENT) || (ret == 0)) {
- fprintf (stderr, "glfs_h_unlink: error unlinking non-existent %s: invalid errno ,%d, %s\n",
- my_file, ret, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- /* unlink non-existent directory */
- ret = glfs_h_unlink (fs, dir, my_subdir);
- if ((ret && errno != ENOENT) || (ret == 0)) {
- fprintf (stderr, "glfs_h_unlink: error unlinking non-existent %s: invalid errno ,%d, %s\n",
- my_subdir, ret, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- /* unlink directory */
- ret = glfs_h_unlink (fs, parent, my_dir);
- if (ret) {
- fprintf (stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n",
- my_dir, dir, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
-
- printf ("glfs_h_unlink tests: PASSED\n");
+ char *my_dir = "unlinkdir";
+ char *my_file = "file.txt";
+ char *my_subdir = "dir1";
+ struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL,
+ *subdir = NULL, *subleaf = NULL;
+ struct stat sb;
+ int ret;
+
+ printf("glfs_h_unlink tests: In Progress\n");
+
+ /* Prepare tests */
+ parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (parent == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, NULL, strerror(errno));
+ printf("glfs_h_lookupat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ dir = glfs_h_mkdir(fs, parent, my_dir, 0755, &sb);
+ if (dir == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ my_dir, parent, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ leaf = glfs_h_creat(fs, dir, my_file, O_CREAT, 0644, &sb);
+ if (leaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
+ my_file, dir, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ subdir = glfs_h_mkdir(fs, dir, my_subdir, 0755, &sb);
+ if (subdir == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ my_subdir, dir, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ subleaf = glfs_h_creat(fs, subdir, my_file, O_CREAT, 0644, &sb);
+ if (subleaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
+ my_file, subdir, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ /* unlink non empty directory */
+ ret = glfs_h_unlink(fs, dir, my_subdir);
+ if ((ret && errno != ENOTEMPTY) || (ret == 0)) {
+ fprintf(stderr,
+ "glfs_h_unlink: error unlinking %s: it is non empty: %s\n",
+ my_subdir, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ /* unlink regular file */
+ ret = glfs_h_unlink(fs, subdir, my_file);
+ if (ret) {
+ fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n",
+ my_file, subdir, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ /* unlink directory */
+ ret = glfs_h_unlink(fs, dir, my_subdir);
+ if (ret) {
+ fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n",
+ my_subdir, dir, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ /* unlink regular file */
+ ret = glfs_h_unlink(fs, dir, my_file);
+ if (ret) {
+ fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n",
+ my_file, dir, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ /* unlink non-existent regular file */
+ ret = glfs_h_unlink(fs, dir, my_file);
+ if ((ret && errno != ENOENT) || (ret == 0)) {
+ fprintf(stderr,
+ "glfs_h_unlink: error unlinking non-existent %s: invalid errno "
+ ",%d, %s\n",
+ my_file, ret, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ /* unlink non-existent directory */
+ ret = glfs_h_unlink(fs, dir, my_subdir);
+ if ((ret && errno != ENOENT) || (ret == 0)) {
+ fprintf(stderr,
+ "glfs_h_unlink: error unlinking non-existent %s: invalid "
+ "errno ,%d, %s\n",
+ my_subdir, ret, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ /* unlink directory */
+ ret = glfs_h_unlink(fs, parent, my_dir);
+ if (ret) {
+ fprintf(stderr, "glfs_h_unlink: error unlinking %s: from (%p),%s\n",
+ my_dir, dir, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+
+ printf("glfs_h_unlink tests: PASSED\n");
out:
- if (dir)
- glfs_h_close (dir);
- if (leaf)
- glfs_h_close (leaf);
- if (subdir)
- glfs_h_close (subdir);
- if (subleaf)
- glfs_h_close (subleaf);
- if (parent)
- glfs_h_close (parent);
-
- return;
+ if (dir)
+ glfs_h_close(dir);
+ if (leaf)
+ glfs_h_close(leaf);
+ if (subdir)
+ glfs_h_close(subdir);
+ if (subleaf)
+ glfs_h_close(subleaf);
+ if (parent)
+ glfs_h_close(parent);
+
+ return;
}
void
-test_h_getsetattrs (void)
+test_h_getsetattrs(void)
{
- char *my_dir = "attrdir";
- char *my_file = "attrfile.txt";
- struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL;
- struct stat sb, retsb;
- int ret, valid;
- struct timespec timestamp;
-
- printf("glfs_h_getattrs and setattrs tests: In Progress\n");
-
- /* Prepare tests */
- parent = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, NULL, strerror (errno));
- printf ("glfs_h_lookupat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- dir = glfs_h_mkdir (fs, parent, my_dir, 0644, &sb);
- if (dir == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- my_dir, parent, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- leaf = glfs_h_creat (fs, dir, my_file, O_CREAT, 0644, &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
- my_file, dir, strerror (errno));
- printf ("glfs_h_unlink tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- ret = glfs_h_getattrs (fs, dir, &retsb);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_getattrs: error %s: from (%p),%s\n",
- my_dir, dir, strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
- }
- peek_stat (&retsb);
- /* TODO: Compare stat information */
-
- retsb.st_mode = 00666;
- retsb.st_uid = 1000;
- retsb.st_gid = 1001;
- ret = clock_gettime (CLOCK_REALTIME, &timestamp);
- if(ret != 0) {
- fprintf (stderr, "clock_gettime: error %s\n", strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
- }
- retsb.st_atim = timestamp;
- retsb.st_mtim = timestamp;
- valid = GFAPI_SET_ATTR_MODE | GFAPI_SET_ATTR_UID | GFAPI_SET_ATTR_GID |
- GFAPI_SET_ATTR_ATIME | GFAPI_SET_ATTR_MTIME;
- peek_stat (&retsb);
-
- ret = glfs_h_setattrs (fs, dir, &retsb, valid);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_setattrs: error %s: from (%p),%s\n",
- my_dir, dir, strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
- }
-
- memset(&retsb, 0, sizeof (struct stat));
- ret = glfs_h_stat (fs, dir, &retsb);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_stat: error %s: from (%p),%s\n",
- my_dir, dir, strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
- }
- peek_stat (&retsb);
-
- printf ("glfs_h_getattrs and setattrs tests: PASSED\n");
+ char *my_dir = "attrdir";
+ char *my_file = "attrfile.txt";
+ struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL;
+ struct stat sb, retsb;
+ int ret, valid;
+ struct timespec timestamp;
+
+ printf("glfs_h_getattrs and setattrs tests: In Progress\n");
+
+ /* Prepare tests */
+ parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (parent == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, NULL, strerror(errno));
+ printf("glfs_h_lookupat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ dir = glfs_h_mkdir(fs, parent, my_dir, 0755, &sb);
+ if (dir == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ my_dir, parent, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ leaf = glfs_h_creat(fs, dir, my_file, O_CREAT, 0644, &sb);
+ if (leaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
+ my_file, dir, strerror(errno));
+ printf("glfs_h_unlink tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ ret = glfs_h_getattrs(fs, dir, &retsb);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_getattrs: error %s: from (%p),%s\n", my_dir,
+ dir, strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&retsb);
+ /* TODO: Compare stat information */
+
+ retsb.st_mode = 00666;
+ retsb.st_uid = 1000;
+ retsb.st_gid = 1001;
+ ret = clock_gettime(CLOCK_REALTIME, &timestamp);
+ if (ret != 0) {
+ fprintf(stderr, "clock_gettime: error %s\n", strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+ retsb.st_atim = timestamp;
+ retsb.st_mtim = timestamp;
+ valid = GFAPI_SET_ATTR_MODE | GFAPI_SET_ATTR_UID | GFAPI_SET_ATTR_GID |
+ GFAPI_SET_ATTR_ATIME | GFAPI_SET_ATTR_MTIME;
+ peek_stat(&retsb);
+
+ ret = glfs_h_setattrs(fs, dir, &retsb, valid);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_setattrs: error %s: from (%p),%s\n", my_dir,
+ dir, strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+
+ memset(&retsb, 0, sizeof(struct stat));
+ ret = glfs_h_stat(fs, dir, &retsb);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_stat: error %s: from (%p),%s\n", my_dir, dir,
+ strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&retsb);
+
+ printf("glfs_h_getattrs and setattrs tests: PASSED\n");
out:
- if (parent)
- glfs_h_close (parent);
- if (leaf)
- glfs_h_close (leaf);
- if (dir)
- glfs_h_close (dir);
-
- return;
+ if (parent)
+ glfs_h_close(parent);
+ if (leaf)
+ glfs_h_close(leaf);
+ if (dir)
+ glfs_h_close(dir);
+
+ return;
}
void
-test_h_truncate (void)
+test_h_truncate(void)
{
- char *my_dir = "truncatedir";
- char *my_file = "file.txt";
- struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL;
- struct stat sb;
- glfs_fd_t *fd = NULL;
- char buf[32];
- off_t offset = 0;
- int ret = 0;
-
- printf("glfs_h_truncate tests: In Progress\n");
-
- /* Prepare tests */
- root = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (root == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, NULL, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- parent = glfs_h_mkdir (fs, root, my_dir, 0644, &sb);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- my_dir, root, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- leaf = glfs_h_creat (fs, parent, my_file, O_CREAT, 0644, &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
- my_file, parent, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- fd = glfs_h_open (fs, leaf, O_RDWR);
- if (fd == NULL) {
- fprintf (stderr, "glfs_h_open: error on open of %s: %s\n",
- my_file, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
-
- memcpy (buf, "abcdefghijklmnopqrstuvwxyz012345", 32);
- ret = glfs_write (fd, buf, 32, 0);
-
- /* run tests */
- /* truncate lower */
- offset = 30;
- ret = glfs_h_truncate (fs, leaf, offset);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n",
- my_file, parent, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
- ret = glfs_h_getattrs (fs, leaf, &sb);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_getattrs: error for %s (%p),%s\n",
- my_file, leaf, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
- if (sb.st_size != offset) {
- fprintf (stderr, "glfs_h_truncate: post size mismatch\n");
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
-
- /* truncate higher */
- offset = 32;
- ret = glfs_h_truncate (fs, leaf, offset);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n",
- my_file, parent, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
- ret = glfs_h_getattrs (fs, leaf, &sb);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_getattrs: error for %s (%p),%s\n",
- my_file, leaf, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
- if (sb.st_size != offset) {
- fprintf (stderr, "glfs_h_truncate: post size mismatch\n");
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
-
- /* truncate equal */
- offset = 30;
- ret = glfs_h_truncate (fs, leaf, offset);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n",
- my_file, parent, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
- ret = glfs_h_getattrs (fs, leaf, &sb);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_getattrs: error for %s (%p),%s\n",
- my_file, leaf, strerror (errno));
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
- if (sb.st_size != offset) {
- fprintf (stderr, "glfs_h_truncate: post size mismatch\n");
- printf ("glfs_h_truncate tests: FAILED\n");
- goto out;
- }
-
- printf ("glfs_h_truncate tests: PASSED\n");
+ char *my_dir = "truncatedir";
+ char *my_file = "file.txt";
+ struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL;
+ struct stat sb;
+ glfs_fd_t *fd = NULL;
+ char buf[32];
+ off_t offset = 0;
+ int ret = 0;
+
+ printf("glfs_h_truncate tests: In Progress\n");
+
+ /* Prepare tests */
+ root = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (root == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, NULL, strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ parent = glfs_h_mkdir(fs, root, my_dir, 0755, &sb);
+ if (parent == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ my_dir, root, strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ leaf = glfs_h_creat(fs, parent, my_file, O_CREAT, 0644, &sb);
+ if (leaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
+ my_file, parent, strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ fd = glfs_h_open(fs, leaf, O_RDWR);
+ if (fd == NULL) {
+ fprintf(stderr, "glfs_h_open: error on open of %s: %s\n", my_file,
+ strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+
+ memcpy(buf, "abcdefghijklmnopqrstuvwxyz012345", 32);
+ ret = glfs_write(fd, buf, 32, 0);
+
+ /* run tests */
+ /* truncate lower */
+ offset = 30;
+ ret = glfs_h_truncate(fs, leaf, offset);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n",
+ my_file, parent, strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+ ret = glfs_h_getattrs(fs, leaf, &sb);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_getattrs: error for %s (%p),%s\n", my_file,
+ leaf, strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+ if (sb.st_size != offset) {
+ fprintf(stderr, "glfs_h_truncate: post size mismatch\n");
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+
+ /* truncate higher */
+ offset = 32;
+ ret = glfs_h_truncate(fs, leaf, offset);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n",
+ my_file, parent, strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+ ret = glfs_h_getattrs(fs, leaf, &sb);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_getattrs: error for %s (%p),%s\n", my_file,
+ leaf, strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+ if (sb.st_size != offset) {
+ fprintf(stderr, "glfs_h_truncate: post size mismatch\n");
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+
+ /* truncate equal */
+ offset = 30;
+ ret = glfs_h_truncate(fs, leaf, offset);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_truncate: error creating %s: from (%p),%s\n",
+ my_file, parent, strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+ ret = glfs_h_getattrs(fs, leaf, &sb);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_getattrs: error for %s (%p),%s\n", my_file,
+ leaf, strerror(errno));
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+ if (sb.st_size != offset) {
+ fprintf(stderr, "glfs_h_truncate: post size mismatch\n");
+ printf("glfs_h_truncate tests: FAILED\n");
+ goto out;
+ }
+
+ printf("glfs_h_truncate tests: PASSED\n");
out:
- if (fd)
- glfs_close (fd);
- if (root)
- glfs_h_close (root);
- if (parent)
- glfs_h_close (parent);
- if (leaf)
- glfs_h_close (leaf);
-
- return;
+ if (fd)
+ glfs_close(fd);
+ if (root)
+ glfs_h_close(root);
+ if (parent)
+ glfs_h_close(parent);
+ if (leaf)
+ glfs_h_close(leaf);
+
+ return;
}
void
-test_h_links (void)
+test_h_links(void)
{
- char *my_dir = "linkdir";
- char *my_file = "file.txt";
- char *my_symlnk = "slnk.txt";
- char *my_lnk = "lnk.txt";
- char *linksrc_dir = "dir1";
- char *linktgt_dir = "dir2";
- struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL,
- *dirsrc = NULL, *dirtgt = NULL, *dleaf = NULL;
- struct glfs_object *ln1 = NULL;
- struct stat sb;
- int ret;
- char *buf = NULL;
-
- printf("glfs_h_link(s) tests: In Progress\n");
-
- /* Prepare tests */
- root = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (root == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, NULL, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- parent = glfs_h_mkdir (fs, root, my_dir, 0644, &sb);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- my_dir, root, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- leaf = glfs_h_creat (fs, parent, my_file, O_CREAT, 0644, &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
- my_file, parent, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- dirsrc = glfs_h_mkdir (fs, parent, linksrc_dir, 0644, &sb);
- if (dirsrc == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- linksrc_dir, parent, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- dirtgt = glfs_h_mkdir (fs, parent, linktgt_dir, 0644, &sb);
- if (dirtgt == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- linktgt_dir, parent, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- dleaf = glfs_h_creat (fs, dirsrc, my_file, O_CREAT, 0644, &sb);
- if (dleaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
- my_file, dirsrc, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- /* run tests */
- /* sym link: /testdir/linkdir/file.txt to ./slnk.txt */
- ln1 = glfs_h_symlink (fs, parent, my_symlnk, "./file.txt", &sb);
- if (ln1 == NULL) {
- fprintf (stderr, "glfs_h_symlink: error creating %s: from (%p),%s\n",
- my_symlnk, parent, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- buf = calloc (1024, sizeof(char));
- if (buf == NULL) {
- fprintf (stderr, "Error allocating memory\n");
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
-
- ret = glfs_h_readlink (fs, ln1, buf, 1024);
- if (ret <= 0) {
- fprintf (stderr, "glfs_h_readlink: error reading %s: from (%p),%s\n",
- my_symlnk, ln1, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- if (!(strncmp (buf, my_symlnk, strlen (my_symlnk)))) {
- fprintf (stderr, "glfs_h_readlink: error mismatch in link name: actual %s: retrieved %s\n",
- my_symlnk, buf);
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
-
- /* link: /testdir/linkdir/file.txt to ./lnk.txt */
- ret = glfs_h_link (fs, leaf, parent, my_lnk);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_link: error creating %s: from (%p),%s\n",
- my_lnk, parent, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- /* TODO: Should write content to a file and read from the link */
-
- /* link: /testdir/linkdir/dir1/file.txt to ../dir2/slnk.txt */
- ret = glfs_h_link (fs, dleaf, dirtgt, my_lnk);
- if (ret != 0) {
- fprintf (stderr, "glfs_h_link: error creating %s: from (%p),%s\n",
- my_lnk, dirtgt, strerror (errno));
- printf ("glfs_h_link(s) tests: FAILED\n");
- goto out;
- }
- /* TODO: Should write content to a file and read from the link */
-
- printf ("glfs_h_link(s) tests: PASSED\n");
+ char *my_dir = "linkdir";
+ char *my_file = "file.txt";
+ char *my_symlnk = "slnk.txt";
+ char *my_lnk = "lnk.txt";
+ char *linksrc_dir = "dir1";
+ char *linktgt_dir = "dir2";
+ struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL,
+ *dirsrc = NULL, *dirtgt = NULL, *dleaf = NULL;
+ struct glfs_object *ln1 = NULL;
+ struct stat sb;
+ int ret;
+ char *buf = NULL;
+
+ printf("glfs_h_link(s) tests: In Progress\n");
+
+ /* Prepare tests */
+ root = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (root == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, NULL, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ parent = glfs_h_mkdir(fs, root, my_dir, 0755, &sb);
+ if (parent == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ my_dir, root, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ leaf = glfs_h_creat(fs, parent, my_file, O_CREAT, 0644, &sb);
+ if (leaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
+ my_file, parent, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ dirsrc = glfs_h_mkdir(fs, parent, linksrc_dir, 0755, &sb);
+ if (dirsrc == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ linksrc_dir, parent, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ dirtgt = glfs_h_mkdir(fs, parent, linktgt_dir, 0755, &sb);
+ if (dirtgt == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ linktgt_dir, parent, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ dleaf = glfs_h_creat(fs, dirsrc, my_file, O_CREAT, 0644, &sb);
+ if (dleaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
+ my_file, dirsrc, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ /* run tests */
+ /* sym link: /testdir/linkdir/file.txt to ./slnk.txt */
+ ln1 = glfs_h_symlink(fs, parent, my_symlnk, "./file.txt", &sb);
+ if (ln1 == NULL) {
+ fprintf(stderr, "glfs_h_symlink: error creating %s: from (%p),%s\n",
+ my_symlnk, parent, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ buf = calloc(1024, sizeof(char));
+ if (buf == NULL) {
+ fprintf(stderr, "Error allocating memory\n");
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+
+ ret = glfs_h_readlink(fs, ln1, buf, 1024);
+ if (ret <= 0) {
+ fprintf(stderr, "glfs_h_readlink: error reading %s: from (%p),%s\n",
+ my_symlnk, ln1, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ if (!(strncmp(buf, my_symlnk, strlen(my_symlnk)))) {
+ fprintf(stderr,
+ "glfs_h_readlink: error mismatch in link name: actual %s: "
+ "retrieved %s\n",
+ my_symlnk, buf);
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+
+ /* link: /testdir/linkdir/file.txt to ./lnk.txt */
+ ret = glfs_h_link(fs, leaf, parent, my_lnk);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_link: error creating %s: from (%p),%s\n",
+ my_lnk, parent, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ /* TODO: Should write content to a file and read from the link */
+
+ /* link: /testdir/linkdir/dir1/file.txt to ../dir2/slnk.txt */
+ ret = glfs_h_link(fs, dleaf, dirtgt, my_lnk);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_link: error creating %s: from (%p),%s\n",
+ my_lnk, dirtgt, strerror(errno));
+ printf("glfs_h_link(s) tests: FAILED\n");
+ goto out;
+ }
+ /* TODO: Should write content to a file and read from the link */
+
+ printf("glfs_h_link(s) tests: PASSED\n");
out:
- if (root)
- glfs_h_close (root);
- if (parent)
- glfs_h_close (parent);
- if (leaf)
- glfs_h_close (leaf);
- if (dirsrc)
- glfs_h_close (dirsrc);
- if (dirtgt)
- glfs_h_close (dirtgt);
- if (dleaf)
- glfs_h_close (dleaf);
- if (ln1)
- glfs_h_close (ln1);
- if (buf)
- free (buf);
-
- return;
+ if (root)
+ glfs_h_close(root);
+ if (parent)
+ glfs_h_close(parent);
+ if (leaf)
+ glfs_h_close(leaf);
+ if (dirsrc)
+ glfs_h_close(dirsrc);
+ if (dirtgt)
+ glfs_h_close(dirtgt);
+ if (dleaf)
+ glfs_h_close(dleaf);
+ if (ln1)
+ glfs_h_close(ln1);
+ if (buf)
+ free(buf);
+
+ return;
}
void
-test_h_rename (void)
+test_h_rename(void)
{
- char *my_dir = "renamedir";
- char *my_file = "file.txt";
- char *src_dir = "dir1";
- char *tgt_dir = "dir2";
- struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL,
- *dirsrc = NULL, *dirtgt = NULL, *dleaf = NULL;
- struct stat sb;
- int ret;
-
- printf("glfs_h_rename tests: In Progress\n");
-
- /* Prepare tests */
- root = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (root == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, NULL, strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- parent = glfs_h_mkdir (fs, root, my_dir, 0644, &sb);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- my_dir, root, strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- leaf = glfs_h_creat (fs, parent, my_file, O_CREAT, 0644, &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
- my_file, parent, strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- dirsrc = glfs_h_mkdir (fs, parent, src_dir, 0644, &sb);
- if (dirsrc == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- src_dir, parent, strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- dirtgt = glfs_h_mkdir (fs, parent, tgt_dir, 0644, &sb);
- if (dirtgt == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- tgt_dir, parent, strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- dleaf = glfs_h_creat (fs, dirsrc, my_file, O_CREAT, 0644, &sb);
- if (dleaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
- my_file, dirsrc, strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- /* run tests */
- /* Rename file.txt -> file1.txt */
- ret = glfs_h_rename (fs, parent, "file.txt", parent, "file1.txt");
- if (ret != 0) {
- fprintf (stderr, "glfs_h_rename: error renaming %s to %s (%s)\n",
- "file.txt", "file1.txt", strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
-
- /* rename dir1/file.txt -> file.txt */
- ret = glfs_h_rename (fs, dirsrc, "file.txt", parent, "file.txt");
- if (ret != 0) {
- fprintf (stderr, "glfs_h_rename: error renaming %s/%s to %s (%s)\n",
- src_dir, "file.txt", "file.txt", strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
-
- /* rename file1.txt -> file.txt (exists) */
- ret = glfs_h_rename (fs, parent, "file1.txt", parent, "file.txt");
- if (ret != 0) {
- fprintf (stderr, "glfs_h_rename: error renaming %s to %s (%s)\n",
- "file.txt", "file.txt", strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
-
- /* rename dir1 -> dir3 */
- ret = glfs_h_rename (fs, parent, "dir1", parent, "dir3");
- if (ret != 0) {
- fprintf (stderr, "glfs_h_rename: error renaming %s to %s (%s)\n",
- "dir1", "dir3", strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
-
- /* rename dir2 ->dir3 (exists) */
- ret = glfs_h_rename (fs, parent, "dir2", parent, "dir3");
- if (ret != 0) {
- fprintf (stderr, "glfs_h_rename: error renaming %s to %s (%s)\n",
- "dir2", "dir3", strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
-
- /* rename file.txt -> dir3 (fail) */
- ret = glfs_h_rename (fs, parent, "file.txt", parent, "dir3");
- if (ret == 0) {
- fprintf (stderr, "glfs_h_rename: NO error renaming %s to %s (%s)\n",
- "file.txt", "dir3", strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
-
- /* rename dir3 -> file.txt (fail) */
- ret = glfs_h_rename (fs, parent, "dir3", parent, "file.txt");
- if (ret == 0) {
- fprintf (stderr, "glfs_h_rename: NO error renaming %s to %s (%s)\n",
- "dir3", "file.txt", strerror (errno));
- printf ("glfs_h_rename tests: FAILED\n");
- goto out;
- }
-
- printf ("glfs_h_rename tests: PASSED\n");
+ char *my_dir = "renamedir";
+ char *my_file = "file.txt";
+ char *src_dir = "dir1";
+ char *tgt_dir = "dir2";
+ struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL,
+ *dirsrc = NULL, *dirtgt = NULL, *dleaf = NULL;
+ struct stat sb;
+ int ret;
+
+ printf("glfs_h_rename tests: In Progress\n");
+
+ /* Prepare tests */
+ root = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (root == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, NULL, strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ parent = glfs_h_mkdir(fs, root, my_dir, 0755, &sb);
+ if (parent == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ my_dir, root, strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ leaf = glfs_h_creat(fs, parent, my_file, O_CREAT, 0644, &sb);
+ if (leaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
+ my_file, parent, strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ dirsrc = glfs_h_mkdir(fs, parent, src_dir, 0755, &sb);
+ if (dirsrc == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ src_dir, parent, strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ dirtgt = glfs_h_mkdir(fs, parent, tgt_dir, 0755, &sb);
+ if (dirtgt == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ tgt_dir, parent, strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ dleaf = glfs_h_creat(fs, dirsrc, my_file, O_CREAT, 0644, &sb);
+ if (dleaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
+ my_file, dirsrc, strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ /* run tests */
+ /* Rename file.txt -> file1.txt */
+ ret = glfs_h_rename(fs, parent, "file.txt", parent, "file1.txt");
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n",
+ "file.txt", "file1.txt", strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+
+ /* rename dir1/file.txt -> file.txt */
+ ret = glfs_h_rename(fs, dirsrc, "file.txt", parent, "file.txt");
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_rename: error renaming %s/%s to %s (%s)\n",
+ src_dir, "file.txt", "file.txt", strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+
+ /* rename file1.txt -> file.txt (exists) */
+ ret = glfs_h_rename(fs, parent, "file1.txt", parent, "file.txt");
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n",
+ "file.txt", "file.txt", strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+
+ /* rename dir1 -> dir3 */
+ ret = glfs_h_rename(fs, parent, "dir1", parent, "dir3");
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", "dir1",
+ "dir3", strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+
+ /* rename dir2 ->dir3 (exists) */
+ ret = glfs_h_rename(fs, parent, "dir2", parent, "dir3");
+ if (ret != 0) {
+ fprintf(stderr, "glfs_h_rename: error renaming %s to %s (%s)\n", "dir2",
+ "dir3", strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+
+ /* rename file.txt -> dir3 (fail) */
+ ret = glfs_h_rename(fs, parent, "file.txt", parent, "dir3");
+ if (ret == 0) {
+ fprintf(stderr, "glfs_h_rename: NO error renaming %s to %s (%s)\n",
+ "file.txt", "dir3", strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+
+ /* rename dir3 -> file.txt (fail) */
+ ret = glfs_h_rename(fs, parent, "dir3", parent, "file.txt");
+ if (ret == 0) {
+ fprintf(stderr, "glfs_h_rename: NO error renaming %s to %s (%s)\n",
+ "dir3", "file.txt", strerror(errno));
+ printf("glfs_h_rename tests: FAILED\n");
+ goto out;
+ }
+
+ printf("glfs_h_rename tests: PASSED\n");
out:
- if (root)
- glfs_h_close (root);
- if (parent)
- glfs_h_close (parent);
- if (leaf)
- glfs_h_close (leaf);
- if (dirsrc)
- glfs_h_close (dirsrc);
- if (dirtgt)
- glfs_h_close (dirtgt);
- if (dleaf)
- glfs_h_close (dleaf);
-
- return;
+ if (root)
+ glfs_h_close(root);
+ if (parent)
+ glfs_h_close(parent);
+ if (leaf)
+ glfs_h_close(leaf);
+ if (dirsrc)
+ glfs_h_close(dirsrc);
+ if (dirtgt)
+ glfs_h_close(dirtgt);
+ if (dleaf)
+ glfs_h_close(dleaf);
+
+ return;
}
void
-assimilatetime (struct timespec *ts, struct timespec ts_st,
- struct timespec ts_ed)
+assimilatetime(struct timespec *ts, struct timespec ts_st,
+ struct timespec ts_ed)
{
- if ((ts_ed.tv_nsec - ts_st.tv_nsec) < 0) {
- ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec - 1;
- ts->tv_nsec += 1000000000 + ts_ed.tv_nsec - ts_st.tv_nsec;
- } else {
- ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec;
- ts->tv_nsec += ts_ed.tv_nsec - ts_st.tv_nsec;
- }
-
- if (ts->tv_nsec > 1000000000) {
- ts->tv_nsec = ts->tv_nsec - 1000000000;
- ts->tv_sec += 1;
- }
-
- return;
+ if ((ts_ed.tv_nsec - ts_st.tv_nsec) < 0) {
+ ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec - 1;
+ ts->tv_nsec += 1000000000 + ts_ed.tv_nsec - ts_st.tv_nsec;
+ } else {
+ ts->tv_sec += ts_ed.tv_sec - ts_st.tv_sec;
+ ts->tv_nsec += ts_ed.tv_nsec - ts_st.tv_nsec;
+ }
+
+ if (ts->tv_nsec > 1000000000) {
+ ts->tv_nsec = ts->tv_nsec - 1000000000;
+ ts->tv_sec += 1;
+ }
+
+ return;
}
#define MAX_FILES_CREATE 10
-#define MAXPATHNAME 512
+#define MAXPATHNAME 512
void
-test_h_performance (void)
+test_h_performance(void)
{
- char *my_dir = "perftest",
- *full_dir_path="/testdir/perftest";
- char *my_file = "file_", my_file_name[MAXPATHNAME];
- struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL;
- struct stat sb;
- int ret, i;
- struct glfs_fd *fd;
- struct timespec c_ts = {0, 0}, c_ts_st, c_ts_ed;
- struct timespec o_ts = {0, 0}, o_ts_st, o_ts_ed;
-
- printf("glfs_h_performance tests: In Progress\n");
-
- /* Prepare tests */
- parent = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, NULL, strerror (errno));
- printf ("glfs_h_performance tests: FAILED\n");
- goto out;
- }
-
- dir = glfs_h_mkdir (fs, parent, my_dir, 0644, &sb);
- if (dir == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
- my_dir, parent, strerror (errno));
- printf ("glfs_h_performance tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- /* create performance */
- ret = clock_gettime (CLOCK_REALTIME, &o_ts_st);
- if(ret != 0) {
- fprintf (stderr, "clock_gettime: error %s\n", strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
+ char *my_dir = "perftest", *full_dir_path = "/testdir/perftest";
+ char *my_file = "file_", my_file_name[MAXPATHNAME];
+ struct glfs_object *parent = NULL, *leaf = NULL, *dir = NULL;
+ struct stat sb;
+ int ret, i;
+ struct glfs_fd *fd;
+ struct timespec c_ts = {0, 0}, c_ts_st, c_ts_ed;
+ struct timespec o_ts = {0, 0}, o_ts_st, o_ts_ed;
+
+ printf("glfs_h_performance tests: In Progress\n");
+
+ /* Prepare tests */
+ parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (parent == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, NULL, strerror(errno));
+ printf("glfs_h_performance tests: FAILED\n");
+ goto out;
+ }
+
+ dir = glfs_h_mkdir(fs, parent, my_dir, 0755, &sb);
+ if (dir == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error creating %s: from (%p),%s\n",
+ my_dir, parent, strerror(errno));
+ printf("glfs_h_performance tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ /* create performance */
+ ret = clock_gettime(CLOCK_REALTIME, &o_ts_st);
+ if (ret != 0) {
+ fprintf(stderr, "clock_gettime: error %s\n", strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+
+ for (i = 0; i < MAX_FILES_CREATE; i++) {
+ sprintf(my_file_name, "%s%d", my_file, i);
+
+ ret = clock_gettime(CLOCK_REALTIME, &c_ts_st);
+ if (ret != 0) {
+ fprintf(stderr, "clock_gettime: error %s\n", strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
}
- for (i = 0; i < MAX_FILES_CREATE; i++) {
- sprintf (my_file_name, "%s%d", my_file, i);
-
- ret = clock_gettime (CLOCK_REALTIME, &c_ts_st);
- if(ret != 0) {
- fprintf (stderr, "clock_gettime: error %s\n",
- strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
- }
-
- leaf = glfs_h_lookupat (fs, dir, my_file_name, &sb, 0);
- if (leaf != NULL) {
- fprintf (stderr, "glfs_h_lookup: exists %s\n",
- my_file_name);
- printf ("glfs_h_performance tests: FAILED\n");
- goto out;
- }
-
- leaf = glfs_h_creat (fs, dir, my_file_name, O_CREAT, 0644, &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
- my_file, dir, strerror (errno));
- printf ("glfs_h_performance tests: FAILED\n");
- goto out;
- }
-
- ret = clock_gettime (CLOCK_REALTIME, &c_ts_ed);
- if(ret != 0) {
- fprintf (stderr, "clock_gettime: error %s\n",
- strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
- }
-
- assimilatetime (&c_ts, c_ts_st, c_ts_ed);
- glfs_h_close (leaf); leaf = NULL;
+ leaf = glfs_h_lookupat(fs, dir, my_file_name, &sb, 0);
+ if (leaf != NULL) {
+ fprintf(stderr, "glfs_h_lookup: exists %s\n", my_file_name);
+ printf("glfs_h_performance tests: FAILED\n");
+ goto out;
}
- ret = clock_gettime (CLOCK_REALTIME, &o_ts_ed);
- if(ret != 0) {
- fprintf (stderr, "clock_gettime: error %s\n", strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
+ leaf = glfs_h_creat(fs, dir, my_file_name, O_CREAT, 0644, &sb);
+ if (leaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error creating %s: from (%p),%s\n",
+ my_file, dir, strerror(errno));
+ printf("glfs_h_performance tests: FAILED\n");
+ goto out;
}
- assimilatetime (&o_ts, o_ts_st, o_ts_ed);
-
- printf ("Creation performance (handle based):\n\t# empty files:%d\n",
- MAX_FILES_CREATE);
- printf ("\tOverall time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n",
- o_ts.tv_sec, o_ts.tv_nsec);
- printf ("\tcreate call time time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n",
- c_ts.tv_sec, c_ts.tv_nsec);
-
- /* create using path */
- c_ts.tv_sec = o_ts.tv_sec = 0;
- c_ts.tv_nsec = o_ts.tv_nsec = 0;
-
- sprintf (my_file_name, "%s1", full_dir_path);
- ret = glfs_mkdir (fs, my_file_name, 0644);
+ ret = clock_gettime(CLOCK_REALTIME, &c_ts_ed);
if (ret != 0) {
- fprintf (stderr, "glfs_mkdir: error creating %s: from (%p),%s\n",
- my_dir, parent, strerror (errno));
- printf ("glfs_h_performance tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- ret = clock_gettime (CLOCK_REALTIME, &o_ts_st);
- if(ret != 0) {
- fprintf (stderr, "clock_gettime: error %s\n", strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
+ fprintf(stderr, "clock_gettime: error %s\n", strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+
+ assimilatetime(&c_ts, c_ts_st, c_ts_ed);
+ glfs_h_close(leaf);
+ leaf = NULL;
+ }
+
+ ret = clock_gettime(CLOCK_REALTIME, &o_ts_ed);
+ if (ret != 0) {
+ fprintf(stderr, "clock_gettime: error %s\n", strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+
+ assimilatetime(&o_ts, o_ts_st, o_ts_ed);
+
+ printf("Creation performance (handle based):\n\t# empty files:%d\n",
+ MAX_FILES_CREATE);
+ printf("\tOverall time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", o_ts.tv_sec,
+ o_ts.tv_nsec);
+ printf("\tcreate call time time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n",
+ c_ts.tv_sec, c_ts.tv_nsec);
+
+ /* create using path */
+ c_ts.tv_sec = o_ts.tv_sec = 0;
+ c_ts.tv_nsec = o_ts.tv_nsec = 0;
+
+ sprintf(my_file_name, "%s1", full_dir_path);
+ ret = glfs_mkdir(fs, my_file_name, 0755);
+ if (ret != 0) {
+ fprintf(stderr, "glfs_mkdir: error creating %s: from (%p),%s\n", my_dir,
+ parent, strerror(errno));
+ printf("glfs_h_performance tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ ret = clock_gettime(CLOCK_REALTIME, &o_ts_st);
+ if (ret != 0) {
+ fprintf(stderr, "clock_gettime: error %s\n", strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+
+ for (i = 0; i < MAX_FILES_CREATE; i++) {
+ sprintf(my_file_name, "%s1/%sn%d", full_dir_path, my_file, i);
+
+ ret = clock_gettime(CLOCK_REALTIME, &c_ts_st);
+ if (ret != 0) {
+ fprintf(stderr, "clock_gettime: error %s\n", strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
}
- for (i = 0; i < MAX_FILES_CREATE; i++) {
- sprintf (my_file_name, "%s1/%sn%d", full_dir_path, my_file, i);
-
- ret = clock_gettime (CLOCK_REALTIME, &c_ts_st);
- if(ret != 0) {
- fprintf (stderr, "clock_gettime: error %s\n",
- strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
- }
-
- ret = glfs_stat (fs, my_file_name, &sb);
- if (ret == 0) {
- fprintf (stderr, "glfs_stat: exists %s\n",
- my_file_name);
- printf ("glfs_h_performance tests: FAILED\n");
- goto out;
- }
-
- fd = glfs_creat (fs, my_file_name, O_CREAT, 0644);
- if (fd == NULL) {
- fprintf (stderr, "glfs_creat: error creating %s: from (%p),%s\n",
- my_file, dir, strerror (errno));
- printf ("glfs_h_performance tests: FAILED\n");
- goto out;
- }
-
- ret = clock_gettime (CLOCK_REALTIME, &c_ts_ed);
- if(ret != 0) {
- fprintf (stderr, "clock_gettime: error %s\n",
- strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
- }
-
- assimilatetime (&c_ts, c_ts_st, c_ts_ed);
- glfs_close (fd);
+ ret = glfs_stat(fs, my_file_name, &sb);
+ if (ret == 0) {
+ fprintf(stderr, "glfs_stat: exists %s\n", my_file_name);
+ printf("glfs_h_performance tests: FAILED\n");
+ goto out;
}
- ret = clock_gettime (CLOCK_REALTIME, &o_ts_ed);
- if(ret != 0) {
- fprintf (stderr, "clock_gettime: error %s\n", strerror (errno));
- printf ("glfs_h_getattrs and setattrs tests: FAILED\n");
- goto out;
+ fd = glfs_creat(fs, my_file_name, O_CREAT, 0644);
+ if (fd == NULL) {
+ fprintf(stderr, "glfs_creat: error creating %s: from (%p),%s\n",
+ my_file, dir, strerror(errno));
+ printf("glfs_h_performance tests: FAILED\n");
+ goto out;
}
- assimilatetime (&o_ts, o_ts_st, o_ts_ed);
-
- printf ("Creation performance (path based):\n\t# empty files:%d\n",
- MAX_FILES_CREATE);
- printf ("\tOverall time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n",
- o_ts.tv_sec, o_ts.tv_nsec);
- printf ("\tcreate call time time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n",
- c_ts.tv_sec, c_ts.tv_nsec);
+ ret = clock_gettime(CLOCK_REALTIME, &c_ts_ed);
+ if (ret != 0) {
+ fprintf(stderr, "clock_gettime: error %s\n", strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+
+ assimilatetime(&c_ts, c_ts_st, c_ts_ed);
+ glfs_close(fd);
+ }
+
+ ret = clock_gettime(CLOCK_REALTIME, &o_ts_ed);
+ if (ret != 0) {
+ fprintf(stderr, "clock_gettime: error %s\n", strerror(errno));
+ printf("glfs_h_getattrs and setattrs tests: FAILED\n");
+ goto out;
+ }
+
+ assimilatetime(&o_ts, o_ts_st, o_ts_ed);
+
+ printf("Creation performance (path based):\n\t# empty files:%d\n",
+ MAX_FILES_CREATE);
+ printf("\tOverall time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n", o_ts.tv_sec,
+ o_ts.tv_nsec);
+ printf("\tcreate call time time:\n\t\tSecs:%ld\n\t\tnSecs:%ld\n",
+ c_ts.tv_sec, c_ts.tv_nsec);
out:
- return;
+ return;
}
int
-test_handleops (int argc, char *argv[])
+test_handleops(int argc, char *argv[])
{
- int ret = 0;
- glfs_fd_t *fd = NULL;
- struct stat sb = {0, };
- struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL,
- *tmp = NULL;
- char readbuf[32], writebuf[32];
- unsigned char leaf_handle[GFAPI_HANDLE_LENGTH];
-
- char *full_leaf_name = "/testdir/testfile.txt",
- *leaf_name = "testfile.txt",
- *relative_leaf_name = "testdir/testfile.txt";
- char *leaf_name1 = "testfile1.txt";
- char *full_newparent_name = "/testdir/dir1",
- *newparent_name = "dir1";
- char *full_newnod_name = "/testdir/nod1",
- *newnod_name = "nod1";
-
- /* Initialize test area */
- ret = glfs_mkdir (fs, full_parent_name, 0644);
- if (ret != 0 && errno != EEXIST) {
- fprintf (stderr, "%s: (%p) %s\n", full_parent_name, fd,
- strerror (errno));
- printf ("Test initialization failed on volume %s\n", argv[1]);
- goto out;
- }
- else if (ret != 0) {
- printf ("Found test directory %s to be existing\n",
- full_parent_name);
- printf ("Cleanup test directory and restart tests\n");
- goto out;
- }
-
- fd = glfs_creat (fs, full_leaf_name, O_CREAT, 0644);
- if (fd == NULL) {
- fprintf (stderr, "%s: (%p) %s\n", full_leaf_name, fd,
- strerror (errno));
- printf ("Test initialization failed on volume %s\n", argv[1]);
- goto out;
- }
- glfs_close (fd);
-
- printf ("Initialized the test area, within volume %s\n", argv[1]);
-
- /* Handle based APIs test area */
-
- /* glfs_lookupat test */
- printf ("glfs_h_lookupat tests: In Progress\n");
- /* start at root of the volume */
- root = glfs_h_lookupat (fs, NULL, "/", &sb, 0);
- if (root == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- "/", NULL, strerror (errno));
- printf ("glfs_h_lookupat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- /* lookup a parent within root */
- parent = glfs_h_lookupat (fs, root, parent_name, &sb, 0);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- parent_name, root, strerror (errno));
- printf ("glfs_h_lookupat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- /* lookup a leaf/child within the parent */
- leaf = glfs_h_lookupat (fs, parent, leaf_name, &sb, 0);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- leaf_name, parent, strerror (errno));
- printf ("glfs_h_lookupat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- /* reset */
- glfs_h_close (root); root = NULL;
- glfs_h_close (leaf); leaf = NULL;
- glfs_h_close (parent); parent = NULL;
-
- /* check absolute paths */
- root = glfs_h_lookupat (fs, NULL, "/", &sb, 0);
- if (root == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- "/", NULL, strerror (errno));
- printf ("glfs_h_lookupat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- parent = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, root, strerror (errno));
- printf ("glfs_h_lookupat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- leaf = glfs_h_lookupat (fs, NULL, full_leaf_name, &sb, 0);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_leaf_name, parent, strerror (errno));
- printf ("glfs_h_lookupat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- /* reset */
- glfs_h_close (leaf); leaf = NULL;
-
- /* check multiple component paths */
- leaf = glfs_h_lookupat (fs, root, relative_leaf_name, &sb, 0);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- relative_leaf_name, parent, strerror (errno));
- goto out;
- }
- peek_stat (&sb);
-
- /* reset */
- glfs_h_close (root); root = NULL;
- glfs_h_close (parent); parent = NULL;
-
- /* check symlinks in path */
-
- /* TODO: -ve test cases */
- /* parent invalid
- * path invalid
- * path does not exist after some components
- * no parent, but relative path
- * parent and full path? -ve?
- */
-
- printf ("glfs_h_lookupat tests: PASSED\n");
-
- /* glfs_openat test */
- printf ("glfs_h_open tests: In Progress\n");
- fd = glfs_h_open (fs, leaf, O_RDWR);
- if (fd == NULL) {
- fprintf (stderr, "glfs_h_open: error on open of %s: %s\n",
- full_leaf_name, strerror (errno));
- printf ("glfs_h_open tests: FAILED\n");
- goto out;
- }
-
- /* test read/write based on fd */
- memcpy (writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32);
- ret = glfs_write (fd, writebuf, 32, 0);
-
- glfs_lseek (fd, 0, SEEK_SET);
-
- ret = glfs_read (fd, readbuf, 32, 0);
- if (memcmp (readbuf, writebuf, 32)) {
- printf ("Failed to read what I wrote: %s %s\n", readbuf,
- writebuf);
- glfs_close (fd);
- printf ("glfs_h_open tests: FAILED\n");
- goto out;
- }
-
- glfs_h_close (leaf); leaf = NULL;
- glfs_close (fd);
-
- printf ("glfs_h_open tests: PASSED\n");
-
- /* Create tests */
- printf ("glfs_h_creat tests: In Progress\n");
- parent = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, root, strerror (errno));
- printf ("glfs_h_creat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- leaf = glfs_h_creat (fs, parent, leaf_name1, O_CREAT, 0644, &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_creat: error on create of %s: from (%p),%s\n",
- leaf_name1, parent, strerror (errno));
- printf ("glfs_h_creat tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- glfs_h_close (leaf); leaf = NULL;
-
- leaf = glfs_h_creat (fs, parent, leaf_name1, O_CREAT | O_EXCL, 0644,
- &sb);
- if (leaf != NULL || errno != EEXIST) {
- fprintf (stderr, "glfs_h_creat: existing file, leaf = (%p), errno = %s\n",
- leaf, strerror (errno));
- printf ("glfs_h_creat tests: FAILED\n");
- if (leaf != NULL) {
- glfs_h_close (leaf); leaf = NULL;
- }
- }
-
- tmp = glfs_h_creat (fs, root, parent_name, O_CREAT, 0644, &sb);
- if (tmp != NULL || !(errno == EISDIR || errno == EINVAL)) {
- fprintf (stderr, "glfs_h_creat: dir create, tmp = (%p), errno = %s\n",
- leaf, strerror (errno));
- printf ("glfs_h_creat tests: FAILED\n");
- if (tmp != NULL) {
- glfs_h_close (tmp); tmp = NULL;
- }
- }
-
- /* TODO: Other combinations and -ve cases as applicable */
- printf ("glfs_h_creat tests: PASSED\n");
-
- /* extract handle and create from handle test */
- printf ("glfs_h_extract_handle and glfs_h_create_from_handle tests: In Progress\n");
- /* TODO: Change the lookup to creat below for a GIFD recovery falure,
- * that needs to be fixed */
- leaf = glfs_h_lookupat (fs, parent, leaf_name1, &sb, 0);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- leaf_name1, parent, strerror (errno));
- printf ("glfs_h_extract_handle tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- ret = glfs_h_extract_handle (leaf, leaf_handle,
- GFAPI_HANDLE_LENGTH);
- if (ret < 0) {
- fprintf (stderr, "glfs_h_extract_handle: error extracting handle of %s: %s\n",
- full_leaf_name, strerror (errno));
- printf ("glfs_h_extract_handle tests: FAILED\n");
- goto out;
- }
- peek_handle (leaf_handle);
+ int ret = 0;
+ glfs_fd_t *fd = NULL;
+ struct stat sb = {
+ 0,
+ };
+ struct glfs_object *root = NULL, *parent = NULL, *leaf = NULL, *tmp = NULL;
+ char readbuf[32], writebuf[32];
+ unsigned char leaf_handle[GFAPI_HANDLE_LENGTH];
+
+ char *full_leaf_name = "/testdir/testfile.txt", *leaf_name = "testfile.txt",
+ *relative_leaf_name = "testdir/testfile.txt";
+ char *leaf_name1 = "testfile1.txt";
+ char *full_newparent_name = "/testdir/dir1", *newparent_name = "dir1";
+ char *full_newnod_name = "/testdir/nod1", *newnod_name = "nod1";
+
+ /* Initialize test area */
+ ret = glfs_mkdir(fs, full_parent_name, 0755);
+ if (ret != 0 && errno != EEXIST) {
+ fprintf(stderr, "%s: (%p) %s\n", full_parent_name, fd, strerror(errno));
+ printf("Test initialization failed on volume %s\n", argv[1]);
+ goto out;
+ } else if (ret != 0) {
+ printf("Found test directory %s to be existing\n", full_parent_name);
+ printf("Cleanup test directory and restart tests\n");
+ goto out;
+ }
+
+ fd = glfs_creat(fs, full_leaf_name, O_CREAT, 0644);
+ if (fd == NULL) {
+ fprintf(stderr, "%s: (%p) %s\n", full_leaf_name, fd, strerror(errno));
+ printf("Test initialization failed on volume %s\n", argv[1]);
+ goto out;
+ }
+ glfs_close(fd);
+
+ printf("Initialized the test area, within volume %s\n", argv[1]);
+
+ /* Handle based APIs test area */
+
+ /* glfs_lookupat test */
+ printf("glfs_h_lookupat tests: In Progress\n");
+ /* start at root of the volume */
+ root = glfs_h_lookupat(fs, NULL, "/", &sb, 0);
+ if (root == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", "/",
+ NULL, strerror(errno));
+ printf("glfs_h_lookupat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ /* lookup a parent within root */
+ parent = glfs_h_lookupat(fs, root, parent_name, &sb, 0);
+ if (parent == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ parent_name, root, strerror(errno));
+ printf("glfs_h_lookupat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ /* lookup a leaf/child within the parent */
+ leaf = glfs_h_lookupat(fs, parent, leaf_name, &sb, 0);
+ if (leaf == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ leaf_name, parent, strerror(errno));
+ printf("glfs_h_lookupat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ /* reset */
+ glfs_h_close(root);
+ root = NULL;
+ glfs_h_close(leaf);
+ leaf = NULL;
+ glfs_h_close(parent);
+ parent = NULL;
+
+ /* check absolute paths */
+ root = glfs_h_lookupat(fs, NULL, "/", &sb, 0);
+ if (root == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n", "/",
+ NULL, strerror(errno));
+ printf("glfs_h_lookupat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (parent == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, root, strerror(errno));
+ printf("glfs_h_lookupat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ leaf = glfs_h_lookupat(fs, NULL, full_leaf_name, &sb, 0);
+ if (leaf == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_leaf_name, parent, strerror(errno));
+ printf("glfs_h_lookupat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ /* reset */
+ glfs_h_close(leaf);
+ leaf = NULL;
+
+ /* check multiple component paths */
+ leaf = glfs_h_lookupat(fs, root, relative_leaf_name, &sb, 0);
+ if (leaf == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ relative_leaf_name, parent, strerror(errno));
+ goto out;
+ }
+ peek_stat(&sb);
+
+ /* reset */
+ glfs_h_close(root);
+ root = NULL;
+ glfs_h_close(parent);
+ parent = NULL;
+
+ /* check symlinks in path */
+
+ /* TODO: -ve test cases */
+ /* parent invalid
+ * path invalid
+ * path does not exist after some components
+ * no parent, but relative path
+ * parent and full path? -ve?
+ */
+
+ printf("glfs_h_lookupat tests: PASSED\n");
+
+ /* glfs_openat test */
+ printf("glfs_h_open tests: In Progress\n");
+ fd = glfs_h_open(fs, leaf, O_RDWR);
+ if (fd == NULL) {
+ fprintf(stderr, "glfs_h_open: error on open of %s: %s\n",
+ full_leaf_name, strerror(errno));
+ printf("glfs_h_open tests: FAILED\n");
+ goto out;
+ }
+
+ /* test read/write based on fd */
+ memcpy(writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32);
+ ret = glfs_write(fd, writebuf, 32, 0);
+
+ glfs_lseek(fd, 0, SEEK_SET);
+
+ ret = glfs_read(fd, readbuf, 32, 0);
+ if (memcmp(readbuf, writebuf, 32)) {
+ printf("Failed to read what I wrote: %s %s\n", readbuf, writebuf);
+ glfs_close(fd);
+ printf("glfs_h_open tests: FAILED\n");
+ goto out;
+ }
+
+ glfs_h_close(leaf);
+ leaf = NULL;
+ glfs_close(fd);
+
+ printf("glfs_h_open tests: PASSED\n");
+
+ /* Create tests */
+ printf("glfs_h_creat tests: In Progress\n");
+ parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (parent == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, root, strerror(errno));
+ printf("glfs_h_creat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ leaf = glfs_h_creat(fs, parent, leaf_name1, O_CREAT, 0644, &sb);
+ if (leaf == NULL) {
+ fprintf(stderr, "glfs_h_creat: error on create of %s: from (%p),%s\n",
+ leaf_name1, parent, strerror(errno));
+ printf("glfs_h_creat tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ glfs_h_close(leaf);
+ leaf = NULL;
+
+ leaf = glfs_h_creat(fs, parent, leaf_name1, O_CREAT | O_EXCL, 0644, &sb);
+ if (leaf != NULL || errno != EEXIST) {
+ fprintf(stderr,
+ "glfs_h_creat: existing file, leaf = (%p), errno = %s\n", leaf,
+ strerror(errno));
+ printf("glfs_h_creat tests: FAILED\n");
+ if (leaf != NULL) {
+ glfs_h_close(leaf);
+ leaf = NULL;
+ }
+ }
+
+ tmp = glfs_h_creat(fs, root, parent_name, O_CREAT, 0644, &sb);
+ if (tmp != NULL || !(errno == EISDIR || errno == EINVAL)) {
+ fprintf(stderr, "glfs_h_creat: dir create, tmp = (%p), errno = %s\n",
+ leaf, strerror(errno));
+ printf("glfs_h_creat tests: FAILED\n");
+ if (tmp != NULL) {
+ glfs_h_close(tmp);
+ tmp = NULL;
+ }
+ }
+
+ /* TODO: Other combinations and -ve cases as applicable */
+ printf("glfs_h_creat tests: PASSED\n");
+
+ /* extract handle and create from handle test */
+ printf(
+ "glfs_h_extract_handle and glfs_h_create_from_handle tests: In "
+ "Progress\n");
+ /* TODO: Change the lookup to create below for a GIFD recovery failure,
+ * that needs to be fixed */
+ leaf = glfs_h_lookupat(fs, parent, leaf_name1, &sb, 0);
+ if (leaf == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ leaf_name1, parent, strerror(errno));
+ printf("glfs_h_extract_handle tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ ret = glfs_h_extract_handle(leaf, leaf_handle, GFAPI_HANDLE_LENGTH);
+ if (ret < 0) {
+ fprintf(stderr,
+ "glfs_h_extract_handle: error extracting handle of %s: %s\n",
+ full_leaf_name, strerror(errno));
+ printf("glfs_h_extract_handle tests: FAILED\n");
+ goto out;
+ }
+ peek_handle(leaf_handle);
+
+ glfs_h_close(leaf);
+ leaf = NULL;
+
+ leaf = glfs_h_create_from_handle(fs, leaf_handle, GFAPI_HANDLE_LENGTH, &sb);
+ if (leaf == NULL) {
+ fprintf(
+ stderr,
+ "glfs_h_create_from_handle: error on create of %s: from (%p),%s\n",
+ leaf_name1, leaf_handle, strerror(errno));
+ printf("glfs_h_create_from_handle tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ fd = glfs_h_open(fs, leaf, O_RDWR);
+ if (fd == NULL) {
+ fprintf(stderr, "glfs_h_open: error on open of %s: %s\n",
+ full_leaf_name, strerror(errno));
+ printf("glfs_h_create_from_handle tests: FAILED\n");
+ goto out;
+ }
+
+ /* test read/write based on fd */
+ memcpy(writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32);
+ ret = glfs_write(fd, writebuf, 32, 0);
+
+ glfs_lseek(fd, 0, SEEK_SET);
+
+ ret = glfs_read(fd, readbuf, 32, 0);
+ if (memcmp(readbuf, writebuf, 32)) {
+ printf("Failed to read what I wrote: %s %s\n", writebuf, writebuf);
+ printf("glfs_h_create_from_handle tests: FAILED\n");
+ glfs_close(fd);
+ goto out;
+ }
+
+ glfs_close(fd);
+ glfs_h_close(leaf);
+ leaf = NULL;
+ glfs_h_close(parent);
+ parent = NULL;
+
+ printf(
+ "glfs_h_extract_handle and glfs_h_create_from_handle tests: PASSED\n");
+
+ /* Mkdir tests */
+ printf("glfs_h_mkdir tests: In Progress\n");
+
+ ret = glfs_rmdir(fs, full_newparent_name);
+ if (ret && errno != ENOENT) {
+ fprintf(stderr, "glfs_rmdir: Failed for %s: %s\n", full_newparent_name,
+ strerror(errno));
+ printf("glfs_h_mkdir tests: FAILED\n");
+ goto out;
+ }
+
+ parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (parent == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, root, strerror(errno));
+ printf("glfs_h_mkdir tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ leaf = glfs_h_mkdir(fs, parent, newparent_name, 0755, &sb);
+ if (leaf == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error on mkdir of %s: from (%p),%s\n",
+ newparent_name, parent, strerror(errno));
+ printf("glfs_h_mkdir tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ glfs_h_close(leaf);
+ leaf = NULL;
+
+ leaf = glfs_h_mkdir(fs, parent, newparent_name, 0755, &sb);
+ if (leaf != NULL || errno != EEXIST) {
+ fprintf(stderr,
+ "glfs_h_mkdir: existing directory, leaf = (%p), errno = %s\n",
+ leaf, strerror(errno));
+ printf("glfs_h_mkdir tests: FAILED\n");
+ if (leaf != NULL) {
+ glfs_h_close(leaf);
+ leaf = NULL;
+ }
+ }
+
+ glfs_h_close(parent);
+ parent = NULL;
+
+ printf("glfs_h_mkdir tests: PASSED\n");
+
+ /* Mknod tests */
+ printf("glfs_h_mknod tests: In Progress\n");
+ ret = glfs_unlink(fs, full_newnod_name);
+ if (ret && errno != ENOENT) {
+ fprintf(stderr, "glfs_unlink: Failed for %s: %s\n", full_newnod_name,
+ strerror(errno));
+ printf("glfs_h_mknod tests: FAILED\n");
+ goto out;
+ }
+
+ parent = glfs_h_lookupat(fs, NULL, full_parent_name, &sb, 0);
+ if (parent == NULL) {
+ fprintf(stderr,
+ "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
+ full_parent_name, root, strerror(errno));
+ printf("glfs_h_mknod tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ leaf = glfs_h_mknod(fs, parent, newnod_name, S_IFIFO, 0, &sb);
+ if (leaf == NULL) {
+ fprintf(stderr, "glfs_h_mkdir: error on mkdir of %s: from (%p),%s\n",
+ newnod_name, parent, strerror(errno));
+ printf("glfs_h_mknod tests: FAILED\n");
+ goto out;
+ }
+ peek_stat(&sb);
+
+ /* TODO: create op on a FIFO node hangs, need to check and fix
+ tmp = glfs_h_creat (fs, parent, newnod_name, O_CREAT, 0644, &sb);
+ if (tmp != NULL || errno != EINVAL) {
+ fprintf (stderr, "glfs_h_creat: node create, tmp = (%p), errno =
+ %s\n", tmp, strerror (errno)); printf ("glfs_h_creat/mknod tests:
+ FAILED\n"); if (tmp != NULL) { glfs_h_close(tmp); tmp = NULL;
+ }
+ } */
+
+ glfs_h_close(leaf);
+ leaf = NULL;
+
+ leaf = glfs_h_mknod(fs, parent, newnod_name, 0644, 0, &sb);
+ if (leaf != NULL || errno != EEXIST) {
+ fprintf(stderr,
+ "glfs_h_mknod: existing node, leaf = (%p), errno = %s\n", leaf,
+ strerror(errno));
+ printf("glfs_h_mknod tests: FAILED\n");
+ if (leaf != NULL) {
+ glfs_h_close(leaf);
+ leaf = NULL;
+ }
+ }
+
+ glfs_h_close(parent);
+ parent = NULL;
+
+ printf("glfs_h_mknod tests: PASSED\n");
+
+ /* unlink tests */
+ test_h_unlink();
+
+ /* TODO: opendir tests */
+
+ /* getattr tests */
+ test_h_getsetattrs();
+
+ /* TODO: setattr tests */
+
+ /* truncate tests */
+ test_h_truncate();
+
+ /* link tests */
+ test_h_links();
+
+ /* rename tests */
+ test_h_rename();
+
+ /* performance tests */
+ test_h_performance();
+
+ /* END: New APIs test area */
- glfs_h_close (leaf); leaf = NULL;
-
- leaf = glfs_h_create_from_handle (fs, leaf_handle, GFAPI_HANDLE_LENGTH,
- &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_create_from_handle: error on create of %s: from (%p),%s\n",
- leaf_name1, leaf_handle, strerror (errno));
- printf ("glfs_h_create_from_handle tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- fd = glfs_h_open (fs, leaf, O_RDWR);
- if (fd == NULL) {
- fprintf (stderr, "glfs_h_open: error on open of %s: %s\n",
- full_leaf_name, strerror (errno));
- printf ("glfs_h_create_from_handle tests: FAILED\n");
- goto out;
- }
-
- /* test read/write based on fd */
- memcpy (writebuf, "abcdefghijklmnopqrstuvwxyz012345", 32);
- ret = glfs_write (fd, writebuf, 32, 0);
-
- glfs_lseek (fd, 0, SEEK_SET);
-
- ret = glfs_read (fd, readbuf, 32, 0);
- if (memcmp (readbuf, writebuf, 32)) {
- printf ("Failed to read what I wrote: %s %s\n", writebuf,
- writebuf);
- printf ("glfs_h_create_from_handle tests: FAILED\n");
- glfs_close (fd);
- goto out;
- }
-
- glfs_close (fd);
- glfs_h_close (leaf); leaf = NULL;
- glfs_h_close (parent); parent = NULL;
-
- printf ("glfs_h_extract_handle and glfs_h_create_from_handle tests: PASSED\n");
-
- /* Mkdir tests */
- printf ("glfs_h_mkdir tests: In Progress\n");
+out:
+ /* Cleanup glfs handles */
+ if (root)
+ glfs_h_close(root);
+ if (parent)
+ glfs_h_close(parent);
+ if (leaf)
+ glfs_h_close(leaf);
+
+ return ret;
+}
- ret = glfs_rmdir (fs, full_newparent_name);
- if (ret && errno != ENOENT) {
- fprintf (stderr, "glfs_rmdir: Failed for %s: %s\n",
- full_newparent_name, strerror (errno));
- printf ("glfs_h_mkdir tests: FAILED\n");
- goto out;
- }
+int
+test_write_apis(glfs_t *fs)
+{
+ /* Add more content here */
+ /* Some apis we can get are */
+ /*
+ 0. glfs_set_xlator_option()
+
+ Read/Write combinations:
+ . glfs_{p,}readv/{p,}writev
+ . glfs_pread/pwrite
+
+ tests/basic/gfapi/gfapi-async-calls-test.c
+ . glfs_read_async/write_async
+ . glfs_pread_async/pwrite_async
+ . glfs_readv_async/writev_async
+ . glfs_preadv_async/pwritev_async
+
+ . ftruncate/ftruncate_async
+ . fsync/fsync_async
+ . fdatasync/fdatasync_async
+
+ */
+
+ glfs_fd_t *fd = NULL;
+ char *filename = "/filename2";
+ int flags = O_RDWR;
+ char *buf = "some bytes!";
+ char writestr[TEST_STR_LEN];
+ struct iovec iov = {&writestr, TEST_STR_LEN};
+ int ret, i;
+
+ for (i = 0; i < TEST_STR_LEN; i++)
+ writestr[i] = 0x11;
+
+ fd = glfs_open(fs, filename, flags);
+ if (!fd)
+ fprintf(stderr, "open(%s): (%p) %s\n", filename, fd, strerror(errno));
+
+ ret = glfs_writev(fd, &iov, 1, flags);
+ if (ret < 0) {
+ fprintf(stderr, "writev(%s): %d (%s)\n", filename, ret,
+ strerror(errno));
+ }
+
+ ret = glfs_pwrite(fd, buf, 10, 4, flags, NULL, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "pwrite(%s): %d (%s)\n", filename, ret,
+ strerror(errno));
+ }
+
+ ret = glfs_pwritev(fd, &iov, 1, 4, flags);
+ if (ret < 0) {
+ fprintf(stderr, "pwritev(%s): %d (%s)\n", filename, ret,
+ strerror(errno));
+ }
+
+ return 0;
+}
- parent = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, root, strerror (errno));
- printf ("glfs_h_mkdir tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
+int
+test_metadata_ops(glfs_t *fs, glfs_t *fs2)
+{
+ glfs_fd_t *fd = NULL;
+ glfs_fd_t *fd2 = NULL;
+ struct stat sb = {
+ 0,
+ };
+ struct glfs_stat gsb = {
+ 0,
+ };
+ struct statvfs sfs;
+ char readbuf[32];
+ char writebuf[32];
- leaf = glfs_h_mkdir (fs, parent, newparent_name, 0644, &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error on mkdir of %s: from (%p),%s\n",
- newparent_name, parent, strerror (errno));
- printf ("glfs_h_mkdir tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- glfs_h_close (leaf); leaf = NULL;
-
- leaf = glfs_h_mkdir (fs, parent, newparent_name, 0644, &sb);
- if (leaf != NULL || errno != EEXIST) {
- fprintf (stderr, "glfs_h_mkdir: existing directory, leaf = (%p), errno = %s\n",
- leaf, strerror (errno));
- printf ("glfs_h_mkdir tests: FAILED\n");
- if (leaf != NULL) {
- glfs_h_close (leaf); leaf = NULL;
- }
- }
+ char *filename = "/filename2";
+ int ret;
- glfs_h_close (parent); parent = NULL;
+ ret = glfs_lstat(fs, filename, &sb);
+ fprintf(stderr, "lstat(%s): (%d) %s\n", filename, ret, strerror(errno));
- printf ("glfs_h_mkdir tests: PASSED\n");
+ fd = glfs_creat(fs, filename, O_RDWR, 0644);
+ fprintf(stderr, "creat(%s): (%p) %s\n", filename, fd, strerror(errno));
- /* Mknod tests */
- printf ("glfs_h_mknod tests: In Progress\n");
- ret = glfs_unlink (fs, full_newnod_name);
- if (ret && errno != ENOENT) {
- fprintf (stderr, "glfs_unlink: Failed for %s: %s\n",
- full_newnod_name, strerror (errno));
- printf ("glfs_h_mknod tests: FAILED\n");
- goto out;
- }
+ fd2 = glfs_open(fs2, filename, O_RDWR);
+ fprintf(stderr, "open(%s): (%p) %s\n", filename, fd, strerror(errno));
- parent = glfs_h_lookupat (fs, NULL, full_parent_name, &sb, 0);
- if (parent == NULL) {
- fprintf (stderr, "glfs_h_lookupat: error on lookup of %s: from (%p),%s\n",
- full_parent_name, root, strerror (errno));
- printf ("glfs_h_mknod tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
+ glfs_lseek(fd2, 0, SEEK_SET);
- leaf = glfs_h_mknod (fs, parent, newnod_name, S_IFIFO, 0, &sb);
- if (leaf == NULL) {
- fprintf (stderr, "glfs_h_mkdir: error on mkdir of %s: from (%p),%s\n",
- newnod_name, parent, strerror (errno));
- printf ("glfs_h_mknod tests: FAILED\n");
- goto out;
- }
- peek_stat (&sb);
-
- /* TODO: creat op on a FIFO node hangs, need to check and fix
- tmp = glfs_h_creat (fs, parent, newnod_name, O_CREAT, 0644, &sb);
- if (tmp != NULL || errno != EINVAL) {
- fprintf (stderr, "glfs_h_creat: node create, tmp = (%p), errno = %s\n",
- tmp, strerror (errno));
- printf ("glfs_h_creat/mknod tests: FAILED\n");
- if (tmp != NULL) {
- glfs_h_close(tmp); tmp = NULL;
- }
- } */
-
- glfs_h_close (leaf); leaf = NULL;
-
- leaf = glfs_h_mknod (fs, parent, newnod_name, 0644, 0, &sb);
- if (leaf != NULL || errno != EEXIST) {
- fprintf (stderr, "glfs_h_mknod: existing node, leaf = (%p), errno = %s\n",
- leaf, strerror (errno));
- printf ("glfs_h_mknod tests: FAILED\n");
- if (leaf != NULL) {
- glfs_h_close (leaf); leaf = NULL;
- }
- }
+ ret = glfs_read(fd2, readbuf, 32, 0);
- glfs_h_close (parent); parent = NULL;
+ printf("read %d, %s", ret, readbuf);
- printf ("glfs_h_mknod tests: PASSED\n");
+ /* get stat */
+ ret = glfs_fstat(fd2, &sb);
- /* unlink tests */
- test_h_unlink ();
+ ret = glfs_access(fs, filename, R_OK);
- /* TODO: opendir tests */
+ /* set stat */
+ /* TODO: got some errors, need to fix */
+ /* ret = glfs_fsetattr(fd2, &gsb); */
- /* getattr tests */
- test_h_getsetattrs ();
+ glfs_close(fd);
+ glfs_close(fd2);
- /* TODO: setattr tests */
+ filename = "/filename3";
+ ret = glfs_mknod(fs, filename, S_IFIFO, 0);
+ fprintf(stderr, "%s: (%d) %s\n", filename, ret, strerror(errno));
- /* truncate tests */
- test_h_truncate();
+ ret = glfs_lstat(fs, filename, &sb);
+ fprintf(stderr, "%s: (%d) %s\n", filename, ret, strerror(errno));
- /* link tests */
- test_h_links ();
+ ret = glfs_rename(fs, filename, "/filename4");
+ fprintf(stderr, "rename(%s): (%d) %s\n", filename, ret, strerror(errno));
- /* rename tests */
- test_h_rename ();
+ ret = glfs_unlink(fs, "/filename4");
+ fprintf(stderr, "unlink(%s): (%d) %s\n", "/filename4", ret,
+ strerror(errno));
- /* performance tests */
- test_h_performance ();
+ filename = "/dirname2";
+ ret = glfs_mkdir(fs, filename, 0);
+ fprintf(stderr, "%s: (%d) %s\n", filename, ret, strerror(errno));
- /* END: New APIs test area */
+ ret = glfs_lstat(fs, filename, &sb);
+ fprintf(stderr, "lstat(%s): (%d) %s\n", filename, ret, strerror(errno));
-out:
- /* Cleanup glfs handles */
- if (root)
- glfs_h_close (root);
- if (parent)
- glfs_h_close (parent);
- if (leaf)
- glfs_h_close (leaf);
-
- return ret;
+ ret = glfs_rmdir(fs, filename);
+ fprintf(stderr, "rmdir(%s): (%d) %s\n", filename, ret, strerror(errno));
}
-
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- glfs_t *fs2 = NULL;
- int ret = 0;
- glfs_fd_t *fd = NULL;
- glfs_fd_t *fd2 = NULL;
- struct stat sb = {0, };
- char readbuf[32];
- char writebuf[32];
-
- char *filename = "/filename2";
-
- if (argc != 3) {
- printf ("Expect following args\n\t%s <volname> <hostname>\n", argv[0]);
- return -1;
- }
-
- fs = glfs_new (argv[1]);
- if (!fs) {
- fprintf (stderr, "glfs_new: returned NULL\n");
- return 1;
- }
-
-// ret = glfs_set_volfile (fs, "/tmp/posix.vol");
-
- ret = glfs_set_volfile_server (fs, "tcp", argv[2], 24007);
-
-// ret = glfs_set_volfile_server (fs, "unix", "/tmp/gluster.sock", 0);
-
- ret = glfs_set_logging (fs, "/dev/stderr", 7);
+ glfs_t *fs2 = NULL;
+ int ret = 0;
+ glfs_fd_t *fd = NULL;
+ glfs_fd_t *fd2 = NULL;
+ struct stat sb = {
+ 0,
+ };
+ struct glfs_stat gsb = {
+ 0,
+ };
+ struct statvfs sfs;
+ char readbuf[32];
+ char writebuf[32];
- ret = glfs_init (fs);
+ char *filename = "/filename2";
- fprintf (stderr, "glfs_init: returned %d\n", ret);
+ if (argc != 3) {
+ printf("Expect following args\n\t%s <volname> <hostname>\n", argv[0]);
+ return -1;
+ }
- sleep (2);
+ fs = glfs_new(argv[1]);
+ if (!fs) {
+ fprintf(stderr, "glfs_new: returned NULL\n");
+ return 1;
+ }
- fs2 = glfs_new (argv[1]);
- if (!fs2) {
- fprintf (stderr, "glfs_new: returned NULL\n");
- return 1;
- }
-
-
-// ret = glfs_set_volfile (fs2, "/tmp/posix.vol");
-
- ret = glfs_set_volfile_server (fs2, "tcp", argv[2], 24007);
+ // ret = glfs_set_volfile (fs, "/tmp/posix.vol");
- ret = glfs_set_logging (fs2, "/dev/stderr", 7);
+ ret = glfs_set_volfile_server(fs, "tcp", argv[2], 24007);
- ret = glfs_init (fs2);
+ // ret = glfs_set_volfile_server (fs, "unix", "/tmp/gluster.sock", 0);
- fprintf (stderr, "glfs_init: returned %d\n", ret);
+ ret = glfs_set_logging(fs, "/dev/stderr", 7);
- ret = glfs_lstat (fs, filename, &sb);
- fprintf (stderr, "%s: (%d) %s\n", filename, ret, strerror (errno));
+ ret = glfs_init(fs);
- fd = glfs_creat (fs, filename, O_RDWR, 0644);
- fprintf (stderr, "%s: (%p) %s\n", filename, fd, strerror (errno));
+ fprintf(stderr, "glfs_init: returned %d\n", ret);
- fd2 = glfs_open (fs2, filename, O_RDWR);
- fprintf (stderr, "%s: (%p) %s\n", filename, fd, strerror (errno));
+ if (ret)
+ goto out;
- sprintf (writebuf, "hi there\n");
- ret = glfs_write (fd, writebuf, 32, 0);
+ sleep(2);
- glfs_lseek (fd2, 0, SEEK_SET);
+ fs2 = glfs_new(argv[1]);
+ if (!fs2) {
+ fprintf(stderr, "glfs_new: returned NULL\n");
+ return 1;
+ }
- ret = glfs_read (fd2, readbuf, 32, 0);
+ // ret = glfs_set_volfile (fs2, "/tmp/posix.vol");
- printf ("read %d, %s", ret, readbuf);
+ ret = glfs_set_volfile_server(fs2, "tcp", argv[2], 24007);
- glfs_close (fd);
- glfs_close (fd2);
+ ret = glfs_set_logging(fs2, "/dev/stderr", 7);
- filename = "/filename3";
- ret = glfs_mknod (fs, filename, S_IFIFO, 0);
- fprintf (stderr, "%s: (%d) %s\n", filename, ret, strerror (errno));
+ ret = glfs_init(fs2);
- ret = glfs_lstat (fs, filename, &sb);
- fprintf (stderr, "%s: (%d) %s\n", filename, ret, strerror (errno));
+ fprintf(stderr, "glfs_init: returned %d\n", ret);
+ test_metadata_ops(fs, fs2);
- ret = glfs_rename (fs, filename, "/filename4");
- fprintf (stderr, "rename(%s): (%d) %s\n", filename, ret,
- strerror (errno));
+ test_dirops(fs);
- ret = glfs_unlink (fs, "/filename4");
- fprintf (stderr, "unlink(%s): (%d) %s\n", "/filename4", ret,
- strerror (errno));
+ test_xattr(fs);
- filename = "/dirname2";
- ret = glfs_mkdir (fs, filename, 0);
- fprintf (stderr, "%s: (%d) %s\n", filename, ret, strerror (errno));
+ test_chdir(fs);
- ret = glfs_lstat (fs, filename, &sb);
- fprintf (stderr, "lstat(%s): (%d) %s\n", filename, ret, strerror (errno));
+ test_handleops(argc, argv);
+ // done
- ret = glfs_rmdir (fs, filename);
- fprintf (stderr, "rmdir(%s): (%d) %s\n", filename, ret, strerror (errno));
+ /* Test some extra apis */
+ test_write_apis(fs);
- test_dirops (fs);
+ glfs_statvfs(fs, "/", &sfs);
- test_xattr (fs);
+ glfs_fini(fs);
+ glfs_fini(fs2);
- test_chdir (fs);
-
- test_handleops (argc, argv);
- // done
-
- glfs_fini (fs);
- glfs_fini (fs2);
-
- return ret;
+ ret = 0;
+out:
+ return ret;
}
diff --git a/api/src/Makefile.am b/api/src/Makefile.am
index 3c517e68072..7f9a7d17b35 100644
--- a/api/src/Makefile.am
+++ b/api/src/Makefile.am
@@ -9,17 +9,20 @@ libgfapi_la_SOURCES = glfs.c glfs-mgmt.c glfs-fops.c glfs-resolve.c \
glfs-handleops.c
libgfapi_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
- $(top_builddir)/rpc/xdr/src/libgfxdr.la \
- $(GF_LDADD)
-
-libgfapi_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \
- -I$(top_srcdir)/libglusterfs/src \
- -I$(top_srcdir)/rpc/rpc-lib/src \
- -I$(top_srcdir)/rpc/xdr/src
+ $(top_builddir)/rpc/xdr/src/libgfxdr.la
-libgfapi_la_LDFLAGS = -version-info $(GFAPI_LT_VERSION) \
+libgfapi_la_LDFLAGS = -version-info $(GFAPI_LT_VERSION) $(GF_LDFLAGS) \
$(GFAPI_EXTRA_LDFLAGS) $(ACL_LIBS)
+libgfapi_la_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/rpc-lib/src \
+ -I$(top_srcdir)/rpc/xdr/src \
+ -I$(top_builddir)/rpc/xdr/src \
+ -DDATADIR=\"$(localstatedir)\" \
+ -D__USE_FILE_OFFSET64 -D__USE_LARGEFILE64
+
+AM_CFLAGS = -Wall $(GF_CFLAGS)
+
xlator_LTLIBRARIES = api.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mount
# workaround for broken parallel install support in automake with LTLIBRARIES
@@ -29,12 +32,12 @@ $(install_xlatorLTLIBRARIES): install-libLTLIBRARIES
api_la_SOURCES = glfs-master.c
api_la_DEPENDENCIES = libgfapi.la
-api_la_LDFLAGS = -module -avoid-version
+api_la_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/xdr/src \
+ -I$(top_builddir)/rpc/xdr/src
+api_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS)
+#api_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS) $(GF_LDFLAGS)
api_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
$(top_builddir)/rpc/xdr/src/libgfxdr.la \
$(top_builddir)/api/src/libgfapi.la
-
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
-
-AM_CFLAGS = -Wall $(GF_CFLAGS)
diff --git a/api/src/README.Symbol_Versions b/api/src/README.Symbol_Versions
index d5cdedd826b..b6ec95f9311 100644
--- a/api/src/README.Symbol_Versions
+++ b/api/src/README.Symbol_Versions
@@ -1,3 +1,3 @@
-See .../doc/gfapi-symbol-versions/gfapi-symbol-versions.md
+See ../../doc/developer-guide/gfapi-symbol-versions.md
diff --git a/api/src/gfapi-messages.h b/api/src/gfapi-messages.h
index 050b9766dea..b9223940416 100644
--- a/api/src/gfapi-messages.h
+++ b/api/src/gfapi-messages.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
+ * Copyright (c) 2015-2018 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
@@ -11,90 +11,137 @@
#ifndef _GFAPI_MESSAGES_H__
#define _GFAPI_MESSAGES_H__
-#include "glfs-message-id.h"
+#include <glusterfs/glfs-message-id.h>
-/*! \file gfapi-messages.h
- * \brief libgfapi log-message IDs and their descriptions
- */
-
-/* NOTE: Rules for message additions
- * 1) Each instance of a message is _better_ left with a unique message ID, even
- * if the message format is the same. Reasoning is that, if the message
- * format needs to change in one instance, the other instances are not
- * impacted or the new change does not change the ID of the instance being
- * modified.
- * 2) Addition of a message,
- * - Should increment the GLFS_NUM_MESSAGES
- * - Append to the list of messages defined, towards the end
- * - Retain macro naming as glfs_msg_X (for redability across developers)
- * NOTE: Rules for message format modifications
- * 3) Check acorss the code if the message ID macro in question is reused
- * anywhere. If reused then then the modifications should ensure correctness
- * everywhere, or needs a new message ID as (1) above was not adhered to. If
- * not used anywhere, proceed with the required modification.
- * NOTE: Rules for message deletion
- * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
- * anywhere, then can be deleted, but will leave a hole by design, as
- * addition rules specify modification to the end of the list and not filling
- * holes.
+/* To add new message IDs, append new identifiers at the end of the list.
+ *
+ * Never remove a message ID. If it's not used anymore, you can rename it or
+ * leave it as it is, but not delete it. This is to prevent reutilization of
+ * IDs by other messages.
+ *
+ * The component name must match one of the entries defined in
+ * glfs-message-id.h.
*/
-#define GLFS_GFAPI_BASE GLFS_MSGID_COMP_API
-#define GLFS_NUM_MESSAGES 47
-#define GLFS_MSGID_END (GLFS_GFAPI_BASE + GLFS_NUM_MESSAGESi + 1)
-/* Messages with message IDs */
-#define glfs_msg_start_x GLFS_GFAPI_BASE, "Invalid: Start of messages"
-/*------------*/
-
-#define API_MSG_MEM_ACCT_INIT_FAILED (GLFS_GFAPI_BASE + 1)
-#define API_MSG_MASTER_XLATOR_INIT_FAILED (GLFS_GFAPI_BASE + 2)
-#define API_MSG_GFAPI_XLATOR_INIT_FAILED (GLFS_GFAPI_BASE + 3)
-#define API_MSG_VOLFILE_OPEN_FAILED (GLFS_GFAPI_BASE + 4)
-#define API_MSG_VOL_SPEC_FILE_ERROR (GLFS_GFAPI_BASE + 5)
-#define API_MSG_GLFS_FSOBJ_NULL (GLFS_GFAPI_BASE + 6)
-#define API_MSG_INVALID_ENTRY (GLFS_GFAPI_BASE + 7)
-#define API_MSG_FSMUTEX_LOCK_FAILED (GLFS_GFAPI_BASE + 8)
-#define API_MSG_COND_WAIT_FAILED (GLFS_GFAPI_BASE + 9)
-#define API_MSG_FSMUTEX_UNLOCK_FAILED (GLFS_GFAPI_BASE + 10)
-#define API_MSG_INODE_REFRESH_FAILED (GLFS_GFAPI_BASE + 11)
-#define API_MSG_GRAPH_CONSTRUCT_FAILED (GLFS_GFAPI_BASE + 12)
-#define API_MSG_FUSE_XLATOR_ERROR (GLFS_GFAPI_BASE + 13)
-#define API_MSG_XDR_PAYLOAD_FAILED (GLFS_GFAPI_BASE + 14)
-#define API_MSG_GET_VOLINFO_CBK_FAILED (GLFS_GFAPI_BASE + 15)
-#define API_MSG_FETCH_VOLUUID_FAILED (GLFS_GFAPI_BASE + 16)
-#define API_MSG_INSUFF_SIZE (GLFS_GFAPI_BASE + 17)
-#define API_MSG_FRAME_CREAT_FAILED (GLFS_GFAPI_BASE + 18)
-#define API_MSG_DICT_SET_FAILED (GLFS_GFAPI_BASE + 19)
-#define API_MSG_XDR_DECODE_FAILED (GLFS_GFAPI_BASE + 20)
-#define API_MSG_GET_VOLFILE_FAILED (GLFS_GFAPI_BASE + 21)
-#define API_MSG_WRONG_OPVERSION (GLFS_GFAPI_BASE + 22)
-#define API_MSG_DICT_SERIALIZE_FAILED (GLFS_GFAPI_BASE + 23)
-#define API_MSG_REMOTE_HOST_CONN_FAILED (GLFS_GFAPI_BASE + 24)
-#define API_MSG_VOLFILE_SERVER_EXHAUST (GLFS_GFAPI_BASE + 25)
-#define API_MSG_CREATE_RPC_CLIENT_FAILED (GLFS_GFAPI_BASE + 26)
-#define API_MSG_REG_NOTIFY_FUNC_FAILED (GLFS_GFAPI_BASE + 27)
-#define API_MSG_REG_CBK_FUNC_FAILED (GLFS_GFAPI_BASE + 28)
-#define API_MSG_GET_CWD_FAILED (GLFS_GFAPI_BASE + 29)
-#define API_MSG_FGETXATTR_FAILED (GLFS_GFAPI_BASE + 30)
-#define API_MSG_LOCKINFO_KEY_MISSING (GLFS_GFAPI_BASE + 31)
-#define API_MSG_FSETXATTR_FAILED (GLFS_GFAPI_BASE + 32)
-#define API_MSG_FSYNC_FAILED (GLFS_GFAPI_BASE + 33)
-#define API_MSG_FDCREATE_FAILED (GLFS_GFAPI_BASE + 34)
-#define API_MSG_INODE_PATH_FAILED (GLFS_GFAPI_BASE + 35)
-#define API_MSG_SYNCOP_OPEN_FAILED (GLFS_GFAPI_BASE + 36)
-#define API_MSG_LOCK_MIGRATE_FAILED (GLFS_GFAPI_BASE + 37)
-#define API_MSG_OPENFD_SKIPPED (GLFS_GFAPI_BASE + 38)
-#define API_MSG_FIRST_LOOKUP_GRAPH_FAILED (GLFS_GFAPI_BASE + 39)
-#define API_MSG_CWD_GRAPH_REF_FAILED (GLFS_GFAPI_BASE + 40)
-#define API_MSG_SWITCHED_GRAPH (GLFS_GFAPI_BASE + 41)
-#define API_MSG_XDR_RESPONSE_DECODE_FAILED (GLFS_GFAPI_BASE + 42)
-#define API_MSG_VOLFILE_INFO (GLFS_GFAPI_BASE + 43)
-#define API_MSG_VOLFILE_CONNECTING (GLFS_GFAPI_BASE + 44)
-#define API_MSG_NEW_GRAPH (GLFS_GFAPI_BASE + 45)
-#define API_MSG_ALLOC_FAILED (GLFS_GFAPI_BASE + 46)
-#define API_MSG_CREATE_HANDLE_FAILED (GLFS_GFAPI_BASE + 47)
+GLFS_MSGID(API, API_MSG_MEM_ACCT_INIT_FAILED, API_MSG_MASTER_XLATOR_INIT_FAILED,
+ API_MSG_GFAPI_XLATOR_INIT_FAILED, API_MSG_VOLFILE_OPEN_FAILED,
+ API_MSG_VOL_SPEC_FILE_ERROR, API_MSG_GLFS_FSOBJ_NULL,
+ API_MSG_INVALID_ENTRY, API_MSG_FSMUTEX_LOCK_FAILED,
+ API_MSG_COND_WAIT_FAILED, API_MSG_FSMUTEX_UNLOCK_FAILED,
+ API_MSG_INODE_REFRESH_FAILED, API_MSG_GRAPH_CONSTRUCT_FAILED,
+ API_MSG_API_XLATOR_ERROR, API_MSG_XDR_PAYLOAD_FAILED,
+ API_MSG_GET_VOLINFO_CBK_FAILED, API_MSG_FETCH_VOLUUID_FAILED,
+ API_MSG_INSUFF_SIZE, API_MSG_FRAME_CREAT_FAILED,
+ API_MSG_DICT_SET_FAILED, API_MSG_XDR_DECODE_FAILED,
+ API_MSG_GET_VOLFILE_FAILED, API_MSG_WRONG_OPVERSION,
+ API_MSG_DICT_SERIALIZE_FAILED, API_MSG_REMOTE_HOST_CONN_FAILED,
+ API_MSG_VOLFILE_SERVER_EXHAUST, API_MSG_CREATE_RPC_CLIENT_FAILED,
+ API_MSG_REG_NOTIFY_FUNC_FAILED, API_MSG_REG_CBK_FUNC_FAILED,
+ API_MSG_GET_CWD_FAILED, API_MSG_FGETXATTR_FAILED,
+ API_MSG_LOCKINFO_KEY_MISSING, API_MSG_FSETXATTR_FAILED,
+ API_MSG_FSYNC_FAILED, API_MSG_FDCREATE_FAILED,
+ API_MSG_INODE_PATH_FAILED, API_MSG_SYNCOP_OPEN_FAILED,
+ API_MSG_LOCK_MIGRATE_FAILED, API_MSG_OPENFD_SKIPPED,
+ API_MSG_FIRST_LOOKUP_GRAPH_FAILED, API_MSG_CWD_GRAPH_REF_FAILED,
+ API_MSG_SWITCHED_GRAPH, API_MSG_XDR_RESPONSE_DECODE_FAILED,
+ API_MSG_VOLFILE_INFO, API_MSG_VOLFILE_CONNECTING, API_MSG_NEW_GRAPH,
+ API_MSG_ALLOC_FAILED, API_MSG_CREATE_HANDLE_FAILED,
+ API_MSG_INODE_LINK_FAILED, API_MSG_STATEDUMP_FAILED,
+ API_MSG_XREADDIRP_R_FAILED, API_MSG_LOCK_INSERT_MERGE_FAILED,
+ API_MSG_SETTING_LOCK_TYPE_FAILED, API_MSG_INODE_FIND_FAILED,
+ API_MSG_FDCTX_SET_FAILED, API_MSG_UPCALL_SYNCOP_FAILED,
+ API_MSG_INVALID_ARG, API_MSG_UPCALL_EVENT_NULL_RECEIVED,
+ API_MSG_FLAGS_HANDLE, API_MSG_FDCREATE_FAILED_ON_GRAPH,
+ API_MSG_TRANS_RDMA_DEP, API_MSG_TRANS_NOT_SUPPORTED,
+ API_MSG_FS_NOT_INIT, API_MSG_INVALID_SYSRQ,
+ API_MSG_DECODE_XDR_FAILED, API_MSG_NULL, API_MSG_CALL_NOT_SUCCESSFUL,
+ API_MSG_CALL_NOT_VALID, API_MSG_UNABLE_TO_DEL,
+ API_MSG_REMOTE_HOST_DISCONN, API_MSG_HANDLE_NOT_SET);
-/*------------*/
-#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
+#define API_MSG_ALLOC_FAILED_STR "Upcall allocation failed"
+#define API_MSG_LOCK_INSERT_MERGE_FAILED_STR \
+ "Lock insertion and splitting/merging failed"
+#define API_MSG_SETTING_LOCK_TYPE_FAILED_STR "Setting lock type failed"
+#define API_MSG_INVALID_ARG_STR "Invalid"
+#define API_MSG_INVALID_ENTRY_STR "Upcall entry validation failed"
+#define API_MSG_INODE_FIND_FAILED_STR "Unable to find inode entry"
+#define API_MSG_CREATE_HANDLE_FAILED_STR "handle creation failed"
+#define API_MSG_UPCALL_EVENT_NULL_RECEIVED_STR \
+ "Upcall_EVENT_NULL received. Skipping it"
+#define API_MSG_UPCALL_SYNCOP_FAILED_STR "Synctask for upcall failed"
+#define API_MSG_FDCREATE_FAILED_STR "Allocating anonymous fd failed"
+#define API_MSG_XREADDIRP_R_FAILED_STR "glfs_x_readdirp_r failed"
+#define API_MSG_FDCTX_SET_FAILED_STR "Setting fd ctx failed"
+#define API_MSG_FLAGS_HANDLE_STR "arg not set. Flags handled are"
+#define API_MSG_INODE_REFRESH_FAILED_STR "inode refresh failed"
+#define API_MSG_INODE_LINK_FAILED_STR "inode linking failed"
+#define API_MSG_GET_CWD_FAILED_STR "Failed to get cwd"
+#define API_MSG_FGETXATTR_FAILED_STR "fgetxattr failed"
+#define API_MSG_LOCKINFO_KEY_MISSING_STR "missing lockinfo key"
+#define API_MSG_FSYNC_FAILED_STR "fsync() failed"
+#define API_MSG_FDCREATE_FAILED_ON_GRAPH_STR "fd_create failed on graph"
+#define API_MSG_INODE_PATH_FAILED_STR "inode_path failed"
+#define API_MSG_SYNCOP_OPEN_FAILED_STR "syncop_open failed"
+#define API_MSG_LOCK_MIGRATE_FAILED_STR "lock migration failed on graph"
+#define API_MSG_OPENFD_SKIPPED_STR "skipping openfd in graph"
+#define API_MSG_FIRST_LOOKUP_GRAPH_FAILED_STR "first lookup on graph failed"
+#define API_MSG_CWD_GRAPH_REF_FAILED_STR "cwd refresh of graph failed"
+#define API_MSG_SWITCHED_GRAPH_STR "switched to graph"
+#define API_MSG_FSETXATTR_FAILED_STR "fsetxattr failed"
+#define API_MSG_MEM_ACCT_INIT_FAILED_STR "Memory accounting init failed"
+#define API_MSG_MASTER_XLATOR_INIT_FAILED_STR \
+ "master xlator for initialization failed"
+#define API_MSG_GFAPI_XLATOR_INIT_FAILED_STR \
+ "failed to initialize gfapi translator"
+#define API_MSG_VOLFILE_OPEN_FAILED_STR "volume file open failed"
+#define API_MSG_VOL_SPEC_FILE_ERROR_STR "Cannot reach volume specification file"
+#define API_MSG_TRANS_RDMA_DEP_STR \
+ "transport RDMA is deprecated, falling back to tcp"
+#define API_MSG_TRANS_NOT_SUPPORTED_STR \
+ "transport is not supported, possible values tcp|unix"
+#define API_MSG_GLFS_FSOBJ_NULL_STR "fs is NULL"
+#define API_MSG_FS_NOT_INIT_STR "fs is not properly initialized"
+#define API_MSG_FSMUTEX_LOCK_FAILED_STR \
+ "pthread lock on glfs mutex, returned error"
+#define API_MSG_FSMUTEX_UNLOCK_FAILED_STR \
+ "pthread unlock on glfs mutex, returned error"
+#define API_MSG_COND_WAIT_FAILED_STR "cond wait failed"
+#define API_MSG_INVALID_SYSRQ_STR "not a valid sysrq"
+#define API_MSG_GRAPH_CONSTRUCT_FAILED_STR "failed to construct the graph"
+#define API_MSG_API_XLATOR_ERROR_STR \
+ "api master xlator cannot be specified in volume file"
+#define API_MSG_STATEDUMP_FAILED_STR "statedump failed"
+#define API_MSG_DECODE_XDR_FAILED_STR \
+ "Failed to decode xdr response for GF_CBK_STATEDUMP"
+#define API_MSG_NULL_STR "NULL"
+#define API_MSG_XDR_PAYLOAD_FAILED_STR "failed to create XDR payload"
+#define API_MSG_CALL_NOT_SUCCESSFUL_STR \
+ "GET_VOLUME_INFO RPC call is not successful"
+#define API_MSG_XDR_RESPONSE_DECODE_FAILED_STR \
+ "Failed to decode xdr response for GET_VOLUME_INFO"
+#define API_MSG_CALL_NOT_VALID_STR \
+ "Response received for GET_VOLUME_INFO RPC is not valid"
+#define API_MSG_GET_VOLINFO_CBK_FAILED_STR \
+ "In GET_VOLUME_INFO cbk, received error"
+#define API_MSG_FETCH_VOLUUID_FAILED_STR "Unable to fetch volume UUID"
+#define API_MSG_INSUFF_SIZE_STR "Insufficient size passed"
+#define API_MSG_FRAME_CREAT_FAILED_STR "failed to create the frame"
+#define API_MSG_DICT_SET_FAILED_STR "failed to set"
+#define API_MSG_XDR_DECODE_FAILED_STR "XDR decoding error"
+#define API_MSG_GET_VOLFILE_FAILED_STR "failed to get the volume file"
+#define API_MSG_VOLFILE_INFO_STR "No change in volfile, continuing"
+#define API_MSG_UNABLE_TO_DEL_STR "unable to delete file"
+#define API_MSG_WRONG_OPVERSION_STR \
+ "Server is operating at an op-version which is not supported"
+#define API_MSG_DICT_SERIALIZE_FAILED_STR "Failed to serialize dictionary"
+#define API_MSG_REMOTE_HOST_CONN_FAILED_STR "Failed to connect to remote-host"
+#define API_MSG_REMOTE_HOST_DISCONN_STR "disconnected from remote-host"
+#define API_MSG_VOLFILE_SERVER_EXHAUST_STR "Exhausted all volfile servers"
+#define API_MSG_VOLFILE_CONNECTING_STR "connecting to next volfile server"
+#define API_MSG_CREATE_RPC_CLIENT_FAILED_STR "failed to create rpc clnt"
+#define API_MSG_REG_NOTIFY_FUNC_FAILED_STR "failed to register notify function"
+#define API_MSG_REG_CBK_FUNC_FAILED_STR "failed to register callback function"
+#define API_MSG_NEW_GRAPH_STR "New graph coming up"
+#define API_MSG_HANDLE_NOT_SET_STR "handle not set. Flags handled for xstat are"
#endif /* !_GFAPI_MESSAGES_H__ */
diff --git a/api/src/gfapi.aliases b/api/src/gfapi.aliases
index 40b6ed21192..bc639e6b99f 100644
--- a/api/src/gfapi.aliases
+++ b/api/src/gfapi.aliases
@@ -18,31 +18,24 @@ _pub_glfs_from_glfd _glfs_from_glfd$GFAPI_3.4.0
_pub_glfs_set_xlator_option _glfs_set_xlator_option$GFAPI_3.4.0
_pub_glfs_read _glfs_read$GFAPI_3.4.0
_pub_glfs_write _glfs_write$GFAPI_3.4.0
-_pub_glfs_read_async _glfs_read_async$GFAPI_3.4.0
-_pub_glfs_write_async _glfs_write_async$GFAPI_3.4.0
_pub_glfs_readv _glfs_readv$GFAPI_3.4.0
_pub_glfs_writev _glfs_writev$GFAPI_3.4.0
-_pub_glfs_readv_async _glfs_readv_async$GFAPI_3.4.0
-_pub_glfs_writev_async _glfs_writev_async$GFAPI_3.4.0
-_pub_glfs_pread _glfs_pread$GFAPI_3.4.0
-_pub_glfs_pwrite _glfs_pwrite$GFAPI_3.4.0
-_pub_glfs_pread_async _glfs_pread_async$GFAPI_3.4.0
-_pub_glfs_pwrite_async _glfs_pwrite_async$GFAPI_3.4.0
+_pub_glfs_pread34 _glfs_pread$GFAPI_3.4.0
+_pub_glfs_pwrite34 _glfs_pwrite$GFAPI_3.4.0
+_pub_glfs_pread_async34 _glfs_pread_async$GFAPI_3.4.0
+_pub_glfs_pwrite_async34 _glfs_pwrite_async$GFAPI_3.4.0
_pub_glfs_preadv _glfs_preadv$GFAPI_3.4.0
_pub_glfs_pwritev _glfs_pwritev$GFAPI_3.4.0
-_pub_glfs_preadv_async _glfs_preadv_async$GFAPI_3.4.0
-_pub_glfs_pwritev_async _glfs_pwritev_async$GFAPI_3.4.0
_pub_glfs_lseek _glfs_lseek$GFAPI_3.4.0
-_pub_glfs_truncate _glfs_truncate$GFAPI_3.4.0
-_pub_glfs_ftruncate _glfs_ftruncate$GFAPI_3.4.0
-_pub_glfs_ftruncate_async _glfs_ftruncate_async$GFAPI_3.4.0
+_pub_glfs_ftruncate34 _glfs_ftruncate$GFAPI_3.4.0
+_pub_glfs_ftruncate_async34 _glfs_ftruncate_async$GFAPI_3.4.0
_pub_glfs_lstat _glfs_lstat$GFAPI_3.4.0
_pub_glfs_stat _glfs_stat$GFAPI_3.4.0
_pub_glfs_fstat _glfs_fstat$GFAPI_3.4.0
-_pub_glfs_fsync _glfs_fsync$GFAPI_3.4.0
-_pub_glfs_fsync_async _glfs_fsync_async$GFAPI_3.4.0
-_pub_glfs_fdatasync _glfs_fdatasync$GFAPI_3.4.0
-_pub_glfs_fdatasync_async _glfs_fdatasync_async$GFAPI_3.4.0
+_pub_glfs_fsync34 _glfs_fsync$GFAPI_3.4.0
+_pub_glfs_fsync_async34 _glfs_fsync_async$GFAPI_3.4.0
+_pub_glfs_fdatasync34 _glfs_fdatasync$GFAPI_3.4.0
+_pub_glfs_fdatasync_async34 _glfs_fdatasync_async$GFAPI_3.4.0
_pub_glfs_access _glfs_access$GFAPI_3.4.0
_pub_glfs_symlink _glfs_symlink$GFAPI_3.4.0
_pub_glfs_readlink _glfs_readlink$GFAPI_3.4.0
@@ -82,7 +75,7 @@ _pub_glfs_fremovexattr _glfs_fremovexattr$GFAPI_3.4.0
_pub_glfs_getcwd _glfs_getcwd$GFAPI_3.4.0
_pub_glfs_chdir _glfs_chdir$GFAPI_3.4.0
_pub_glfs_fchdir _glfs_fchdir$GFAPI_3.4.0
-_pub_glfs_realpath _glfs_realpath$GFAPI_3.4.0
+_pub_glfs_realpath34 _glfs_realpath$GFAPI_3.4.0
_pub_glfs_posix_lock _glfs_posix_lock$GFAPI_3.4.0
_pub_glfs_dup _glfs_dup$GFAPI_3.4.0
@@ -113,9 +106,8 @@ _pub_glfs_readdir _glfs_readdir$GFAPI_3.5.0
_pub_glfs_readdirplus _glfs_readdirplus$GFAPI_3.5.0
_pub_glfs_fallocate _glfs_fallocate$GFAPI_3.5.0
_pub_glfs_discard _glfs_discard$GFAPI_3.5.0
-_pub_glfs_discard_async _glfs_discard_async$GFAPI_3.5.0
_pub_glfs_zerofill _glfs_zerofill$GFAPI_3.5.0
-_pub_glfs_zerofill_async _glfs_zerofill_async$GFAPI_3.5.0
+_pub_glfs_caller_specific_init _glfs_caller_specific_init$GFAPI_3.5.0
_pub_glfs_h_setxattrs _glfs_h_setxattrs$GFAPI_3.5.0
_pub_glfs_unset_volfile_server _glfs_unset_volfile_server$GFAPI_3.5.1
@@ -125,12 +117,10 @@ _pub_glfs_h_removexattrs _glfs_h_removexattrs$GFAPI_3.5.1
_pub_glfs_get_volfile _glfs_get_volfile$GFAPI_3.6.0
_pub_glfs_h_access _glfs_h_access$GFAPI_3.6.0
-_pub_glfs_ipc _glfs_ipc$GFAPI_3.7.0
-_pub_glfs_h_poll_upcall _glfs_h_poll_upcall$GFAPI_3.7.0
+_pub_glfs_h_poll_upcall370 _glfs_h_poll_upcall$GFAPI_3.7.0
_pub_glfs_h_acl_set _glfs_h_acl_set$GFAPI_3.7.0
_pub_glfs_h_acl_get _glfs_h_acl_get$GFAPI_3.7.0
_pub_glfs_h_statfs _glfs_h_statfs$GFAPI_3.7.0
-
_pub_glfs_h_anonymous_read _glfs_h_anonymous_read$GFAPI_3.7.0
_pub_glfs_h_anonymous_write _glfs_h_anonymous_write$GFAPI_3.7.0
@@ -140,3 +130,72 @@ _priv_glfs_resolve _glfs_resolve$GFAPI_PRIVATE_3.7.0
_priv_glfs_process_upcall_event _glfs_process_upcall_event$GFAPI_PRIVATE_3.7.0
_pub_glfs_h_lookupat _glfs_h_lookupat$GFAPI_3.7.4
+
+_pub_glfs_truncate _glfs_truncate$GFAPI_3.7.15
+
+_pub_glfs_free _glfs_free$GFAPI_3.7.16
+_pub_glfs_h_poll_upcall _glfs_h_poll_upcall$GFAPI_3.7.16
+_pub_glfs_upcall_get_fs _glfs_upcall_get_fs$GFAPI_3.7.16
+_pub_glfs_upcall_get_reason _glfs_upcall_get_reason$GFAPI_3.7.16
+_pub_glfs_upcall_get_event _glfs_upcall_get_event$GFAPI_3.7.16
+_pub_glfs_upcall_inode_get_object _glfs_upcall_inode_get_object$GFAPI_3.7.16
+_pub_glfs_upcall_inode_get_flags _glfs_upcall_inode_get_flags$GFAPI_3.7.16
+_pub_glfs_upcall_inode_get_stat _glfs_upcall_inode_get_stat$GFAPI_3.7.16
+_pub_glfs_upcall_inode_get_expire _glfs_upcall_inode_get_expire$GFAPI_3.7.16
+_pub_glfs_upcall_inode_get_pobject _glfs_upcall_inode_get_pobject$GFAPI_3.7.16
+_pub_glfs_upcall_inode_get_pstat _glfs_upcall_inode_get_pstat$GFAPI_3.7.16
+_pub_glfs_upcall_inode_get_oldpobject _glfs_upcall_inode_get_oldpobject$GFAPI_3.7.16
+_pub_glfs_upcall_inode_get_oldpstat _glfs_upcall_inode_get_oldpstat$GFAPI_3.7.16
+
+_pub_glfs_realpath _glfs_realpath$GFAPI_3.7.17
+
+_pub_glfs_sysrq _glfs_sysrq$GFAPI_3.10.0
+
+_pub_glfs_fd_set_lkowner _glfs_fd_set_lkowner$GFAPI_3.10.7
+
+_pub_glfs_xreaddirplus_r _glfs_xreaddirplus_r$GFAPI_3.11.0
+_pub_glfs_xreaddirplus_r_get_stat _glfs_xreaddirplus_r_get_stat$GFAPI_3.11.0
+_pub_glfs_xreaddirplus_r_get_object _glfs_xreaddirplus_r_get_object$GFAPI_3.11.0
+_pub_glfs_object_copy _glfs_object_copy$GFAPI_3.11.0
+
+_priv_glfs_ipc _glfs_ipc$GFAPI_3.12.0
+
+_pub_glfs_upcall_register _glfs_upcall_register$GFAPI_3.13.0
+_pub_glfs_upcall_unregister _glfs_upcall_unregister$GFAPI_3.13.0
+
+_pub_glfs_setfsleaseid _glfs_setfsleaseid$GFAPI_4.0.0
+_pub_glfs_file_lock _glfs_file_lock$GFAPI_4.0.0
+_pub_glfs_lease _glfs_lease$GFAPI_4.0.0
+_pub_glfs_h_lease _glfs_h_lease$GFAPI_4.0.0
+_pub_glfs_upcall_lease_get_object _glfs_upcall_lease_get_object$GFAPI_4.1.6
+_pub_glfs_upcall_lease_get_lease_type _glfs_upcall_lease_get_lease_type$GFAPI_4.1.6
+
+_priv_glfs_statx _glfs_statx$GFAPI_6.0
+_priv_glfs_iatt_from_statx _glfs_iatt_from_statx$GFAPI_6.0
+_priv_glfs_setfspid _glfs_setfspid$GFAPI_6.1
+
+_pub_glfs_read_async _glfs_read_async$GFAPI_6.0
+_pub_glfs_write_async _glfs_write_async$GFAPI_6.0
+_pub_glfs_readv_async _glfs_readv_async$GFAPI_6.0
+_pub_glfs_writev_async _glfs_writev_async$GFAPI_6.0
+_pub_glfs_pread _glfs_pread$GFAPI_6.0
+_pub_glfs_pwrite _glfs_pwrite$GFAPI_6.0
+_pub_glfs_pread_async _glfs_pread_async$GFAPI_6.0
+_pub_glfs_pwrite_async _glfs_pwrite_async$GFAPI_6.0
+_pub_glfs_preadv_async _glfs_preadv_async$GFAPI_6.0
+_pub_glfs_pwritev_async _glfs_pwritev_async$GFAPI_6.0
+_pub_glfs_fsync _glfs_fsync$GFAPI_6.0
+_pub_glfs_fsync_async _glfs_fsync_async$GFAPI_6.0
+_pub_glfs_fdatasync _glfs_fdatasync$GFAPI_6.0
+_pub_glfs_fdatasync_async _glfs_fdatasync_async$GFAPI_6.0
+_pub_glfs_ftruncate _glfs_ftruncate$GFAPI_6.0
+_pub_glfs_ftruncate_async _glfs_ftruncate_async$GFAPI_6.0
+_pub_glfs_discard_async _glfs_discard_async$GFAPI_6.0
+_pub_glfs_zerofill_async _glfs_zerofill_async$GFAPI_6.0
+_pub_glfs_copy_file_range _glfs_copy_file_range$GFAPI_6.0
+_pub_glfs_fsetattr _glfs_fsetattr$GFAPI_6.0
+_pub_glfs_setattr _glfs_setattr$GFAPI_6.0
+
+_pub_glfs_set_statedump_path _glfs_set_statedump_path@GFAPI_7.0
+
+_pub_glfs_h_creat_open _glfs_h_creat_open@GFAPI_6.6
diff --git a/api/src/gfapi.map b/api/src/gfapi.map
index d42ae2b97af..228ac47c084 100644
--- a/api/src/gfapi.map
+++ b/api/src/gfapi.map
@@ -39,7 +39,6 @@ GFAPI_3.4.0 {
glfs_preadv_async;
glfs_pwritev_async;
glfs_lseek;
- glfs_truncate;
glfs_ftruncate;
glfs_ftruncate_async;
glfs_lstat;
@@ -115,6 +114,7 @@ GFAPI_3.4.2 {
glfs_h_create_from_handle;
glfs_h_opendir;
glfs_h_open;
+ glfs_h_lookupat;
} GFAPI_3.4.0;
GFAPI_3.5.0 {
@@ -146,7 +146,6 @@ GFAPI_3.6.0 {
GFAPI_3.7.0 {
global:
- glfs_ipc;
glfs_h_poll_upcall;
glfs_h_acl_set;
glfs_h_acl_get;
@@ -167,3 +166,118 @@ GFAPI_3.7.4 {
global:
glfs_h_lookupat;
} GFAPI_PRIVATE_3.7.0;
+
+GFAPI_3.7.15 {
+ global:
+ glfs_truncate;
+} GFAPI_3.7.4;
+
+GFAPI_3.7.16 {
+ global:
+ glfs_free;
+ glfs_upcall_get_fs;
+ glfs_upcall_get_reason;
+ glfs_upcall_get_event;
+ glfs_upcall_inode_get_object;
+ glfs_upcall_inode_get_flags;
+ glfs_upcall_inode_get_stat;
+ glfs_upcall_inode_get_expire;
+ glfs_upcall_inode_get_pobject;
+ glfs_upcall_inode_get_pstat;
+ glfs_upcall_inode_get_oldpobject;
+ glfs_upcall_inode_get_oldpstat;
+ glfs_h_poll_upcall;
+} GFAPI_3.7.15;
+
+GFAPI_3.7.17 {
+ global:
+ glfs_realpath;
+} GFAPI_3.7.16;
+
+GFAPI_3.10.0 {
+ global:
+ glfs_sysrq;
+} GFAPI_3.7.17;
+
+GFAPI_3.10.7 {
+ global:
+ glfs_fd_set_lkowner;
+} GFAPI_3.10.0;
+
+GFAPI_3.11.0 {
+ glfs_xreaddirplus_r;
+ glfs_xreaddirplus_r_get_stat;
+ glfs_xreaddirplus_r_get_object;
+ glfs_object_copy;
+} GFAPI_3.10.7;
+
+GFAPI_PRIVATE_3.12.0 {
+ global:
+ glfs_ipc;
+} GFAPI_3.11.0;
+
+GFAPI_3.13.0 {
+ global:
+ glfs_upcall_register;
+ glfs_upcall_unregister;
+} GFAPI_PRIVATE_3.12.0;
+
+GFAPI_4.0.0 {
+ global:
+ glfs_setfsleaseid;
+ glfs_file_lock;
+ glfs_lease;
+ glfs_h_lease;
+} GFAPI_3.13.0;
+
+GFAPI_4.1.6 {
+ global:
+ glfs_upcall_lease_get_object;
+ glfs_upcall_lease_get_lease_type;
+} GFAPI_4.0.0;
+
+GFAPI_PRIVATE_6.0 {
+ global:
+ glfs_statx;
+ glfs_iatt_from_statx;
+} GFAPI_4.1.6;
+
+GFAPI_6.0 {
+ global:
+ glfs_read_async;
+ glfs_write_async;
+ glfs_readv_async;
+ glfs_writev_async;
+ glfs_pread;
+ glfs_pwrite;
+ glfs_pread_async;
+ glfs_pwrite_async;
+ glfs_preadv_async;
+ glfs_pwritev_async;
+ glfs_fsync;
+ glfs_fsync_async;
+ glfs_fdatasync;
+ glfs_fdatasync_async;
+ glfs_ftruncate;
+ glfs_ftruncate_async;
+ glfs_discard_async;
+ glfs_zerofill_async;
+ glfs_copy_file_range;
+ glfs_setattr;
+ glfs_fsetattr;
+} GFAPI_PRIVATE_6.0;
+
+GFAPI_PRIVATE_6.1 {
+ global:
+ glfs_setfspid;
+} GFAPI_6.0;
+
+GFAPI_6.6 {
+ global:
+ glfs_h_creat_open;
+} GFAPI_PRIVATE_6.1;
+
+GFAPI_7.0 {
+ global:
+ glfs_set_statedump_path;
+} GFAPI_6.6;
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c
index 4988137f363..6aa3c5602d1 100644
--- a/api/src/glfs-fops.c
+++ b/api/src/glfs-fops.c
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2012-2018 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
@@ -9,15 +9,22 @@
cases as published by the Free Software Foundation.
*/
+/* for SEEK_HOLE and SEEK_DATA */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <unistd.h>
#include "glfs-internal.h"
#include "glfs-mem-types.h"
-#include "syncop.h"
+#include <glusterfs/syncop.h>
#include "glfs.h"
#include "gfapi-messages.h"
-#include "compat-errno.h"
+#include <glusterfs/compat-errno.h>
#include <limits.h>
#include "glusterfs3.h"
+#include <glusterfs/iatt.h>
#ifdef NAME_MAX
#define GF_NAME_MAX NAME_MAX
@@ -25,8 +32,69 @@
#define GF_NAME_MAX 255
#endif
+struct upcall_syncop_args {
+ struct glfs *fs;
+ struct gf_upcall upcall_data;
+};
+
#define READDIRBUF_SIZE (sizeof(struct dirent) + GF_NAME_MAX + 1)
+typedef void (*glfs_io_cbk34)(glfs_fd_t *fd, ssize_t ret, void *data);
+
+/*
+ * This function will mark glfd for deletion and decrement its refcount.
+ */
+int
+glfs_mark_glfd_for_deletion(struct glfs_fd *glfd)
+{
+ LOCK(&glfd->lock);
+ {
+ glfd->state = GLFD_CLOSE;
+ }
+ UNLOCK(&glfd->lock);
+
+ GF_REF_PUT(glfd);
+
+ return 0;
+}
+
+/* This function is useful for all async fops. There is chance that glfd is
+ * closed before async fop is completed. When glfd is closed we change the
+ * state to GLFD_CLOSE.
+ *
+ * This function will return _gf_true if the glfd is still valid else return
+ * _gf_false.
+ */
+gf_boolean_t
+glfs_is_glfd_still_valid(struct glfs_fd *glfd)
+{
+ gf_boolean_t ret = _gf_false;
+
+ LOCK(&glfd->lock);
+ {
+ if (glfd->state != GLFD_CLOSE)
+ ret = _gf_true;
+ }
+ UNLOCK(&glfd->lock);
+
+ return ret;
+}
+
+void
+glfd_set_state_bind(struct glfs_fd *glfd)
+{
+ LOCK(&glfd->lock);
+ {
+ glfd->state = GLFD_OPEN;
+ }
+ UNLOCK(&glfd->lock);
+
+ fd_bind(glfd->fd);
+ glfs_fd_bind(glfd);
+
+ return;
+}
+
/*
* This routine is called when an upcall event of type
* 'GF_UPCALL_CACHE_INVALIDATION' is received.
@@ -35,4014 +103,6343 @@
* maintained by gfapi.
*/
int
-glfs_get_upcall_cache_invalidation (struct gf_upcall *to_up_data,
- struct gf_upcall *from_up_data)
+glfs_get_upcall_cache_invalidation(struct gf_upcall *to_up_data,
+ struct gf_upcall *from_up_data)
{
+ struct gf_upcall_cache_invalidation *ca_data = NULL;
+ struct gf_upcall_cache_invalidation *f_ca_data = NULL;
+ int ret = -1;
- struct gf_upcall_cache_invalidation *ca_data = NULL;
- struct gf_upcall_cache_invalidation *f_ca_data = NULL;
- int ret = -1;
+ GF_VALIDATE_OR_GOTO(THIS->name, to_up_data, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, from_up_data, out);
- GF_VALIDATE_OR_GOTO (THIS->name, to_up_data, out);
- GF_VALIDATE_OR_GOTO (THIS->name, from_up_data, out);
+ f_ca_data = from_up_data->data;
+ GF_VALIDATE_OR_GOTO(THIS->name, f_ca_data, out);
- f_ca_data = from_up_data->data;
- GF_VALIDATE_OR_GOTO (THIS->name, f_ca_data, out);
+ ca_data = GF_CALLOC(1, sizeof(*ca_data), glfs_mt_upcall_entry_t);
- ca_data = GF_CALLOC (1, sizeof(*ca_data),
- glfs_mt_upcall_entry_t);
+ if (!ca_data) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_ALLOC_FAILED, "entry",
+ NULL);
+ goto out;
+ }
- if (!ca_data) {
- gf_msg (THIS->name, GF_LOG_ERROR, errno,
- API_MSG_ALLOC_FAILED,
- "Upcall entry allocation failed.");
- goto out;
- }
-
- to_up_data->data = ca_data;
+ to_up_data->data = ca_data;
- ca_data->flags = f_ca_data->flags;
- ca_data->expire_time_attr = f_ca_data->expire_time_attr;
- ca_data->stat = f_ca_data->stat;
- ca_data->p_stat = f_ca_data->p_stat;
- ca_data->oldp_stat = f_ca_data->oldp_stat;
+ ca_data->flags = f_ca_data->flags;
+ ca_data->expire_time_attr = f_ca_data->expire_time_attr;
+ ca_data->stat = f_ca_data->stat;
+ ca_data->p_stat = f_ca_data->p_stat;
+ ca_data->oldp_stat = f_ca_data->oldp_stat;
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
-glfs_loc_link (loc_t *loc, struct iatt *iatt)
+glfs_get_upcall_lease(struct gf_upcall *to_up_data,
+ struct gf_upcall *from_up_data)
{
- int ret = -1;
- inode_t *old_inode = NULL;
+ struct gf_upcall_recall_lease *ca_data = NULL;
+ struct gf_upcall_recall_lease *f_ca_data = NULL;
+ int ret = -1;
- if (!loc->inode) {
- errno = EINVAL;
- return -1;
- }
+ GF_VALIDATE_OR_GOTO(THIS->name, to_up_data, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, from_up_data, out);
- old_inode = loc->inode;
+ f_ca_data = from_up_data->data;
+ GF_VALIDATE_OR_GOTO(THIS->name, f_ca_data, out);
- /* If the inode already exists in the cache, the inode
- * returned here points to the existing one. We need
- * to update loc.inode accordingly.
- */
- loc->inode = inode_link (loc->inode, loc->parent, loc->name, iatt);
- if (loc->inode) {
- inode_lookup (loc->inode);
- inode_unref (old_inode);
- ret = 0;
- } else {
- ret = -1;
- errno = ENOMEM;
- }
+ ca_data = GF_CALLOC(1, sizeof(*ca_data), glfs_mt_upcall_entry_t);
+
+ if (!ca_data) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_ALLOC_FAILED, "entry",
+ NULL);
+ goto out;
+ }
+
+ to_up_data->data = ca_data;
+
+ ca_data->lease_type = f_ca_data->lease_type;
+ gf_uuid_copy(ca_data->tid, f_ca_data->tid);
+ ca_data->dict = f_ca_data->dict;
- return ret;
+ ret = 0;
+out:
+ return ret;
}
+int
+glfs_loc_link(loc_t *loc, struct iatt *iatt)
+{
+ int ret = -1;
+ inode_t *old_inode = NULL;
+ uint64_t ctx_value = LOOKUP_NOT_NEEDED;
+
+ if (!loc->inode) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ old_inode = loc->inode;
+
+ /* If the inode already exists in the cache, the inode
+ * returned here points to the existing one. We need
+ * to update loc.inode accordingly.
+ */
+ loc->inode = inode_link(loc->inode, loc->parent, loc->name, iatt);
+ if (loc->inode) {
+ inode_ctx_set(loc->inode, THIS, &ctx_value);
+ inode_lookup(loc->inode);
+ inode_unref(old_inode);
+ ret = 0;
+ } else {
+ ret = -1;
+ }
+ return ret;
+}
void
-glfs_iatt_to_stat (struct glfs *fs, struct iatt *iatt, struct stat *stat)
+glfs_iatt_to_stat(struct glfs *fs, struct iatt *iatt, struct stat *stat)
{
- iatt_to_stat (iatt, stat);
- stat->st_dev = fs->dev_id;
+ iatt_to_stat(iatt, stat);
+ stat->st_dev = fs->dev_id;
}
+void
+glfs_iatt_to_statx(struct glfs *fs, const struct iatt *iatt,
+ struct glfs_stat *statx)
+{
+ statx->glfs_st_mask = 0;
+
+ statx->glfs_st_mode = 0;
+ if (IATT_TYPE_VALID(iatt->ia_flags)) {
+ statx->glfs_st_mode |= st_mode_type_from_ia(iatt->ia_type);
+ statx->glfs_st_mask |= GLFS_STAT_TYPE;
+ }
+
+ if (IATT_MODE_VALID(iatt->ia_flags)) {
+ statx->glfs_st_mode |= st_mode_prot_from_ia(iatt->ia_prot);
+ statx->glfs_st_mask |= GLFS_STAT_MODE;
+ }
+
+ if (IATT_NLINK_VALID(iatt->ia_flags)) {
+ statx->glfs_st_nlink = iatt->ia_nlink;
+ statx->glfs_st_mask |= GLFS_STAT_NLINK;
+ }
+
+ if (IATT_UID_VALID(iatt->ia_flags)) {
+ statx->glfs_st_uid = iatt->ia_uid;
+ statx->glfs_st_mask |= GLFS_STAT_UID;
+ }
+
+ if (IATT_GID_VALID(iatt->ia_flags)) {
+ statx->glfs_st_gid = iatt->ia_gid;
+ statx->glfs_st_mask |= GLFS_STAT_GID;
+ }
+
+ if (IATT_ATIME_VALID(iatt->ia_flags)) {
+ statx->glfs_st_atime.tv_sec = iatt->ia_atime;
+ statx->glfs_st_atime.tv_nsec = iatt->ia_atime_nsec;
+ statx->glfs_st_mask |= GLFS_STAT_ATIME;
+ }
+
+ if (IATT_MTIME_VALID(iatt->ia_flags)) {
+ statx->glfs_st_mtime.tv_sec = iatt->ia_mtime;
+ statx->glfs_st_mtime.tv_nsec = iatt->ia_mtime_nsec;
+ statx->glfs_st_mask |= GLFS_STAT_MTIME;
+ }
+
+ if (IATT_CTIME_VALID(iatt->ia_flags)) {
+ statx->glfs_st_ctime.tv_sec = iatt->ia_ctime;
+ statx->glfs_st_ctime.tv_nsec = iatt->ia_ctime_nsec;
+ statx->glfs_st_mask |= GLFS_STAT_CTIME;
+ }
+
+ if (IATT_BTIME_VALID(iatt->ia_flags)) {
+ statx->glfs_st_btime.tv_sec = iatt->ia_btime;
+ statx->glfs_st_btime.tv_nsec = iatt->ia_btime_nsec;
+ statx->glfs_st_mask |= GLFS_STAT_BTIME;
+ }
+
+ if (IATT_INO_VALID(iatt->ia_flags)) {
+ statx->glfs_st_ino = iatt->ia_ino;
+ statx->glfs_st_mask |= GLFS_STAT_INO;
+ }
+
+ if (IATT_SIZE_VALID(iatt->ia_flags)) {
+ statx->glfs_st_size = iatt->ia_size;
+ statx->glfs_st_mask |= GLFS_STAT_SIZE;
+ }
+
+ if (IATT_BLOCKS_VALID(iatt->ia_flags)) {
+ statx->glfs_st_blocks = iatt->ia_blocks;
+ statx->glfs_st_mask |= GLFS_STAT_BLOCKS;
+ }
+
+ /* unconditionally present, encode as is */
+ statx->glfs_st_blksize = iatt->ia_blksize;
+ statx->glfs_st_rdev_major = ia_major(iatt->ia_rdev);
+ statx->glfs_st_rdev_minor = ia_minor(iatt->ia_rdev);
+ statx->glfs_st_dev_major = ia_major(fs->dev_id);
+ statx->glfs_st_dev_minor = ia_minor(fs->dev_id);
+
+ /* At present we do not read any localFS attributes and pass them along,
+ * so setting this to 0. As we start supporting file attributes we can
+ * populate the same here as well */
+ statx->glfs_st_attributes = 0;
+ statx->glfs_st_attributes_mask = 0;
+}
-int
-glfs_loc_unlink (loc_t *loc)
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_iatt_from_statx, 6.0)
+void
+priv_glfs_iatt_from_statx(struct iatt *iatt, const struct glfs_stat *statx)
{
- inode_unlink (loc->inode, loc->parent, loc->name);
+ /* Most code in xlators are not checking validity flags before accessing
+ the items. Hence zero everything before setting valid items */
+ memset(iatt, 0, sizeof(struct iatt));
+
+ if (GLFS_STAT_TYPE_VALID(statx->glfs_st_mask)) {
+ iatt->ia_type = ia_type_from_st_mode(statx->glfs_st_mode);
+ iatt->ia_flags |= IATT_TYPE;
+ }
+
+ if (GLFS_STAT_MODE_VALID(statx->glfs_st_mask)) {
+ iatt->ia_prot = ia_prot_from_st_mode(statx->glfs_st_mode);
+ iatt->ia_flags |= IATT_MODE;
+ }
+
+ if (GLFS_STAT_NLINK_VALID(statx->glfs_st_mask)) {
+ iatt->ia_nlink = statx->glfs_st_nlink;
+ iatt->ia_flags |= IATT_NLINK;
+ }
+
+ if (GLFS_STAT_UID_VALID(statx->glfs_st_mask)) {
+ iatt->ia_uid = statx->glfs_st_uid;
+ iatt->ia_flags |= IATT_UID;
+ }
+
+ if (GLFS_STAT_GID_VALID(statx->glfs_st_mask)) {
+ iatt->ia_gid = statx->glfs_st_gid;
+ iatt->ia_flags |= IATT_GID;
+ }
+
+ if (GLFS_STAT_ATIME_VALID(statx->glfs_st_mask)) {
+ iatt->ia_atime = statx->glfs_st_atime.tv_sec;
+ iatt->ia_atime_nsec = statx->glfs_st_atime.tv_nsec;
+ iatt->ia_flags |= IATT_ATIME;
+ }
+
+ if (GLFS_STAT_MTIME_VALID(statx->glfs_st_mask)) {
+ iatt->ia_mtime = statx->glfs_st_mtime.tv_sec;
+ iatt->ia_mtime_nsec = statx->glfs_st_mtime.tv_nsec;
+ iatt->ia_flags |= IATT_MTIME;
+ }
+
+ if (GLFS_STAT_CTIME_VALID(statx->glfs_st_mask)) {
+ iatt->ia_ctime = statx->glfs_st_ctime.tv_sec;
+ iatt->ia_ctime_nsec = statx->glfs_st_ctime.tv_nsec;
+ iatt->ia_flags |= IATT_CTIME;
+ }
+
+ if (GLFS_STAT_BTIME_VALID(statx->glfs_st_mask)) {
+ iatt->ia_btime = statx->glfs_st_btime.tv_sec;
+ iatt->ia_btime_nsec = statx->glfs_st_btime.tv_nsec;
+ iatt->ia_flags |= IATT_BTIME;
+ }
+
+ if (GLFS_STAT_INO_VALID(statx->glfs_st_mask)) {
+ iatt->ia_ino = statx->glfs_st_ino;
+ iatt->ia_flags |= IATT_INO;
+ }
+
+ if (GLFS_STAT_SIZE_VALID(statx->glfs_st_mask)) {
+ iatt->ia_size = statx->glfs_st_size;
+ iatt->ia_flags |= IATT_SIZE;
+ }
+
+ if (GLFS_STAT_BLOCKS_VALID(statx->glfs_st_mask)) {
+ iatt->ia_blocks = statx->glfs_st_blocks;
+ iatt->ia_flags |= IATT_BLOCKS;
+ }
+
+ /* unconditionally present, encode as is */
+ iatt->ia_blksize = statx->glfs_st_blksize;
+ iatt->ia_rdev = makedev(statx->glfs_st_rdev_major,
+ statx->glfs_st_rdev_minor);
+ iatt->ia_dev = makedev(statx->glfs_st_dev_major, statx->glfs_st_dev_minor);
+ iatt->ia_attributes = statx->glfs_st_attributes;
+ iatt->ia_attributes_mask = statx->glfs_st_attributes_mask;
+}
- return 0;
+void
+glfsflags_from_gfapiflags(struct glfs_stat *stat, int *glvalid)
+{
+ *glvalid = 0;
+ if (stat->glfs_st_mask & GLFS_STAT_MODE) {
+ *glvalid |= GF_SET_ATTR_MODE;
+ }
+
+ if (stat->glfs_st_mask & GLFS_STAT_SIZE) {
+ *glvalid |= GF_SET_ATTR_SIZE;
+ }
+
+ if (stat->glfs_st_mask & GLFS_STAT_UID) {
+ *glvalid |= GF_SET_ATTR_UID;
+ }
+
+ if (stat->glfs_st_mask & GLFS_STAT_GID) {
+ *glvalid |= GF_SET_ATTR_GID;
+ }
+
+ if (stat->glfs_st_mask & GLFS_STAT_ATIME) {
+ *glvalid |= GF_SET_ATTR_ATIME;
+ }
+
+ if (stat->glfs_st_mask & GLFS_STAT_MTIME) {
+ *glvalid |= GF_SET_ATTR_MTIME;
+ }
}
+int
+glfs_loc_unlink(loc_t *loc)
+{
+ inode_unlink(loc->inode, loc->parent, loc->name);
+
+ /* since glfs_h_* objects hold a reference to inode
+ * it is safe to keep lookup count to '0' */
+ if (!inode_has_dentry(loc->inode))
+ inode_forget(loc->inode, 0);
+ return 0;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_open, 3.4.0)
struct glfs_fd *
-pub_glfs_open (struct glfs *fs, const char *path, int flags)
+pub_glfs_open(struct glfs *fs, const char *path, int flags)
{
- int ret = -1;
- struct glfs_fd *glfd = NULL;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
+ int ret = -1;
+ struct glfs_fd *glfd = NULL;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ glfd = glfs_fd_new(fs);
+ if (!glfd)
+ goto out;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+retry:
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- glfd = glfs_fd_new (fs);
- if (!glfd)
- goto out;
+ if (ret)
+ goto out;
-retry:
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+ if (IA_ISDIR(iatt.ia_type)) {
+ ret = -1;
+ errno = EISDIR;
+ goto out;
+ }
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ if (!IA_ISREG(iatt.ia_type)) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
- if (ret)
- goto out;
+ if (glfd->fd) {
+ /* Retry. Safe to touch glfd->fd as we
+ still have not glfs_fd_bind() yet.
+ */
+ fd_unref(glfd->fd);
+ glfd->fd = NULL;
+ }
+
+ glfd->fd = fd_create(loc.inode, getpid());
+ if (!glfd->fd) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+ glfd->fd->flags = flags;
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_open(subvol, &loc, flags, glfd->fd, fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
+out:
+ loc_wipe(&loc);
- if (IA_ISDIR (iatt.ia_type)) {
- ret = -1;
- errno = EISDIR;
- goto out;
- }
+ if (fop_attr)
+ dict_unref(fop_attr);
- if (!IA_ISREG (iatt.ia_type)) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
+ if (ret && glfd) {
+ GF_REF_PUT(glfd);
+ glfd = NULL;
+ } else if (glfd) {
+ glfd_set_state_bind(glfd);
+ }
- if (glfd->fd) {
- /* Retry. Safe to touch glfd->fd as we
- still have not glfs_fd_bind() yet.
- */
- fd_unref (glfd->fd);
- glfd->fd = NULL;
- }
+ glfs_subvol_done(fs, subvol);
- glfd->fd = fd_create (loc.inode, getpid());
- if (!glfd->fd) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
- glfd->fd->flags = flags;
+ __GLFS_EXIT_FS;
- ret = syncop_open (subvol, &loc, flags, glfd->fd, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+invalid_fs:
+ return glfd;
+}
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_close, 3.4.0)
+int
+pub_glfs_close(struct glfs_fd *glfd)
+{
+ xlator_t *subvol = NULL;
+ int ret = -1;
+ fd_t *fd = NULL;
+ struct glfs *fs = NULL;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ if (glfd->lk_owner.len != 0) {
+ ret = syncopctx_setfslkowner(&glfd->lk_owner);
+ if (ret)
+ goto out;
+ }
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_flush(subvol, fd, fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- loc_wipe (&loc);
+ fs = glfd->fs;
- if (ret && glfd) {
- glfs_fd_destroy (glfd);
- glfd = NULL;
- } else if (glfd) {
- fd_bind (glfd->fd);
- glfs_fd_bind (glfd);
- }
+ if (fd)
+ fd_unref(fd);
+ if (fop_attr)
+ dict_unref(fop_attr);
- glfs_subvol_done (fs, subvol);
+ glfs_mark_glfd_for_deletion(glfd);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return glfd;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_open, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lstat, 3.4.0)
int
-pub_glfs_close (struct glfs_fd *glfd)
+pub_glfs_lstat(struct glfs *fs, const char *path, struct stat *stat)
{
- xlator_t *subvol = NULL;
- int ret = -1;
- fd_t *fd = NULL;
- struct glfs *fs = NULL;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+retry:
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- ret = syncop_flush (subvol, fd, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ if (ret == 0 && stat)
+ glfs_iatt_to_stat(fs, &iatt, stat);
out:
- fs = glfd->fs;
- glfs_fd_destroy (glfd);
-
- if (fd)
- fd_unref (fd);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_close, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_stat, 3.4.0)
int
-pub_glfs_lstat (struct glfs *fs, const char *path, struct stat *stat)
+pub_glfs_stat(struct glfs *fs, const char *path, struct stat *stat)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret == 0 && stat)
- glfs_iatt_to_stat (fs, &iatt, stat);
+ if (ret == 0 && stat)
+ glfs_iatt_to_stat(fs, &iatt, stat);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lstat, 3.4.0);
-
-
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_statx, 6.0)
int
-pub_glfs_stat (struct glfs *fs, const char *path, struct stat *stat)
+priv_glfs_statx(struct glfs *fs, const char *path, const unsigned int mask,
+ struct glfs_stat *statxbuf)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ if (path == NULL) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ if (mask & ~GLFS_STAT_ALL) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
retry:
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
-
- if (ret == 0 && stat)
- glfs_iatt_to_stat (fs, &iatt, stat);
+ if (ret == 0 && statxbuf)
+ glfs_iatt_to_statx(fs, &iatt, statxbuf);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_stat, 3.4.0);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fstat, 3.4.0)
+int
+pub_glfs_fstat(struct glfs_fd *glfd, struct stat *stat)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ struct iatt iatt = {
+ 0,
+ };
+ fd_t *fd = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = syncop_fstat(subvol, fd, &iatt, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret == 0 && stat)
+ glfs_iatt_to_stat(glfd->fs, &iatt, stat);
+out:
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ glfs_subvol_done(glfd->fs, subvol);
-int
-pub_glfs_fstat (struct glfs_fd *glfd, struct stat *stat)
+ __GLFS_EXIT_FS;
+
+invalid_fs:
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_creat, 3.4.0)
+struct glfs_fd *
+pub_glfs_creat(struct glfs *fs, const char *path, int flags, mode_t mode)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- struct iatt iatt = {0, };
- fd_t *fd = NULL;
+ int ret = -1;
+ struct glfs_fd *glfd = NULL;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ glfd = glfs_fd_new(fs);
+ if (!glfd)
+ goto out;
+
+ /* This must be glfs_resolve() and NOT glfs_lresolve().
+ That is because open("name", O_CREAT) where "name"
+ is a danging symlink must create the dangling
+ destination.
+ */
+retry:
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ if (ret == -1 && errno != ENOENT)
+ /* Any other type of error is fatal */
+ goto out;
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+ if (ret == -1 && errno == ENOENT && !loc.parent)
+ /* The parent directory or an ancestor even
+ higher does not exist
+ */
+ goto out;
- ret = syncop_fstat (subvol, fd, &iatt, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ if (loc.inode) {
+ if (flags & O_EXCL) {
+ ret = -1;
+ errno = EEXIST;
+ goto out;
+ }
- if (ret == 0 && stat)
- glfs_iatt_to_stat (glfd->fs, &iatt, stat);
-out:
- if (fd)
- fd_unref (fd);
+ if (IA_ISDIR(iatt.ia_type)) {
+ ret = -1;
+ errno = EISDIR;
+ goto out;
+ }
- glfs_subvol_done (glfd->fs, subvol);
+ if (!IA_ISREG(iatt.ia_type)) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+ }
+
+ if (ret == -1 && errno == ENOENT) {
+ loc.inode = inode_new(loc.parent->table);
+ if (!loc.inode) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+ }
- __GLFS_EXIT_FS;
+ if (glfd->fd) {
+ /* Retry. Safe to touch glfd->fd as we
+ still have not glfs_fd_bind() yet.
+ */
+ fd_unref(glfd->fd);
+ glfd->fd = NULL;
+ }
+
+ glfd->fd = fd_create(loc.inode, getpid());
+ if (!glfd->fd) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+ glfd->fd->flags = flags;
+
+ if (get_fop_attr_thrd_key(&xattr_req))
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+ if (ret == 0) {
+ ret = syncop_open(subvol, &loc, flags, glfd->fd, xattr_req, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ } else {
+ ret = syncop_create(subvol, &loc, flags, mode, glfd->fd, &iatt,
+ xattr_req, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ }
+
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
+
+ if (ret == 0)
+ ret = glfs_loc_link(&loc, &iatt);
+out:
+ loc_wipe(&loc);
-invalid_fs:
- return ret;
-}
+ if (xattr_req)
+ dict_unref(xattr_req);
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fstat, 3.4.0);
+ if (ret && glfd) {
+ GF_REF_PUT(glfd);
+ glfd = NULL;
+ } else if (glfd) {
+ glfd_set_state_bind(glfd);
+ }
+ glfs_subvol_done(fs, subvol);
-struct glfs_fd *
-pub_glfs_creat (struct glfs *fs, const char *path, int flags, mode_t mode)
-{
- int ret = -1;
- struct glfs_fd *glfd = NULL;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- uuid_t gfid;
- dict_t *xattr_req = NULL;
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- xattr_req = dict_new ();
- if (!xattr_req) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gf_uuid_generate (gfid);
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- glfd = glfs_fd_new (fs);
- if (!glfd)
- goto out;
-
- /* This must be glfs_resolve() and NOT glfs_lresolve().
- That is because open("name", O_CREAT) where "name"
- is a danging symlink must create the dangling
- destinataion.
- */
-retry:
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
-
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
-
- if (ret == -1 && errno != ENOENT)
- /* Any other type of error is fatal */
- goto out;
-
- if (ret == -1 && errno == ENOENT && !loc.parent)
- /* The parent directory or an ancestor even
- higher does not exist
- */
- goto out;
-
- if (loc.inode) {
- if (flags & O_EXCL) {
- ret = -1;
- errno = EEXIST;
- goto out;
- }
-
- if (IA_ISDIR (iatt.ia_type)) {
- ret = -1;
- errno = EISDIR;
- goto out;
- }
-
- if (!IA_ISREG (iatt.ia_type)) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
- }
-
- if (ret == -1 && errno == ENOENT) {
- loc.inode = inode_new (loc.parent->table);
- if (!loc.inode) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
- }
-
- if (glfd->fd) {
- /* Retry. Safe to touch glfd->fd as we
- still have not glfs_fd_bind() yet.
- */
- fd_unref (glfd->fd);
- glfd->fd = NULL;
- }
-
- glfd->fd = fd_create (loc.inode, getpid());
- if (!glfd->fd) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
- glfd->fd->flags = flags;
-
- if (ret == 0) {
- ret = syncop_open (subvol, &loc, flags, glfd->fd, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- } else {
- ret = syncop_create (subvol, &loc, flags, mode, glfd->fd,
- &iatt, xattr_req, NULL);
- DECODE_SYNCOP_ERR (ret);
- }
-
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
-
- if (ret == 0)
- ret = glfs_loc_link (&loc, &iatt);
-out:
- loc_wipe (&loc);
-
- if (xattr_req)
- dict_unref (xattr_req);
-
- if (ret && glfd) {
- glfs_fd_destroy (glfd);
- glfd = NULL;
- } else if (glfd) {
- fd_bind (glfd->fd);
- glfs_fd_bind (glfd);
- }
-
- glfs_subvol_done (fs, subvol);
-
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return glfd;
+ return glfd;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_creat, 3.4.0);
+#ifdef HAVE_SEEK_HOLE
+static int
+glfs_seek(struct glfs_fd *glfd, off_t offset, int whence)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ gf_seek_what_t what = 0;
+ off_t off = -1;
+
+ switch (whence) {
+ case SEEK_DATA:
+ what = GF_SEEK_DATA;
+ break;
+ case SEEK_HOLE:
+ what = GF_SEEK_HOLE;
+ break;
+ default:
+ /* other SEEK_* do not make sense, all operations get an offset
+ * and the position in the fd is not tracked */
+ errno = EINVAL;
+ goto out;
+ }
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
-off_t
-pub_glfs_lseek (struct glfs_fd *glfd, off_t offset, int whence)
-{
- struct stat sb = {0, };
- int ret = -1;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- switch (whence) {
- case SEEK_SET:
- glfd->offset = offset;
- break;
- case SEEK_CUR:
- glfd->offset += offset;
- break;
- case SEEK_END:
- ret = pub_glfs_fstat (glfd, &sb);
- if (ret) {
- /* seek cannot fail :O */
- break;
- }
- glfd->offset = sb.st_size + offset;
- break;
- }
-
- __GLFS_EXIT_FS;
-
- return glfd->offset;
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ errno = EBADFD;
+ goto done;
+ }
-invalid_fs:
- return -1;
-}
+ ret = syncop_seek(subvol, fd, offset, what, NULL, &off);
+ DECODE_SYNCOP_ERR(ret);
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lseek, 3.4.0);
+ if (ret != -1)
+ glfd->offset = off;
+done:
+ if (fd)
+ fd_unref(fd);
-ssize_t
-pub_glfs_preadv (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
- off_t offset, int flags)
-{
- xlator_t *subvol = NULL;
- ssize_t ret = -1;
- ssize_t size = -1;
- struct iovec *iov = NULL;
- int cnt = 0;
- struct iobref *iobref = NULL;
- fd_t *fd = NULL;
+ glfs_subvol_done(glfd->fs, subvol);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+out:
+ return ret;
+}
+#endif
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lseek, 3.4.0)
+off_t
+pub_glfs_lseek(struct glfs_fd *glfd, off_t offset, int whence)
+{
+ struct stat sb = {
+ 0,
+ };
+ int ret = -1;
+ off_t off = -1;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ switch (whence) {
+ case SEEK_SET:
+ glfd->offset = offset;
+ ret = 0;
+ break;
+ case SEEK_CUR:
+ glfd->offset += offset;
+ ret = 0;
+ break;
+ case SEEK_END:
+ ret = pub_glfs_fstat(glfd, &sb);
+ if (ret) {
+ /* seek cannot fail :O */
+ break;
+ }
+ glfd->offset = sb.st_size + offset;
+ break;
+#ifdef HAVE_SEEK_HOLE
+ case SEEK_DATA:
+ case SEEK_HOLE:
+ ret = glfs_seek(glfd, offset, whence);
+ break;
+#endif
+ default:
+ errno = EINVAL;
+ }
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+ if (glfd)
+ GF_REF_PUT(glfd);
- size = iov_length (iovec, iovcnt);
+ __GLFS_EXIT_FS;
- ret = syncop_readv (subvol, fd, size, offset, 0, &iov, &cnt, &iobref,
- NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret <= 0)
- goto out;
+ if (ret != -1)
+ off = glfd->offset;
- size = iov_copy (iovec, iovcnt, iov, cnt); /* FIXME!!! */
+ return off;
- glfd->offset = (offset + size);
+invalid_fs:
+ return -1;
+}
- ret = size;
+static ssize_t
+glfs_preadv_common(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
+ off_t offset, int flags, struct glfs_stat *poststat)
+{
+ xlator_t *subvol = NULL;
+ ssize_t ret = -1;
+ ssize_t size = -1;
+ struct iovec *iov = NULL;
+ int cnt = 0;
+ struct iobref *iobref = NULL;
+ fd_t *fd = NULL;
+ struct iatt iatt = {
+ 0,
+ };
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ size = iov_length(iovec, iovcnt);
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_readv(subvol, fd, size, offset, 0, &iov, &cnt, &iobref, &iatt,
+ fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret >= 0 && poststat)
+ glfs_iatt_to_statx(glfd->fs, &iatt, poststat);
+
+ if (ret <= 0)
+ goto out;
+
+ size = iov_copy(iovec, iovcnt, iov, cnt); /* FIXME!!! */
+
+ glfd->offset = (offset + size);
+
+ ret = size;
out:
- if (iov)
- GF_FREE (iov);
- if (iobref)
- iobref_unref (iobref);
+ if (iov)
+ GF_FREE(iov);
+ if (iobref)
+ iobref_unref(iobref);
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (fop_attr)
+ dict_unref(fop_attr);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv, 3.4.0)
ssize_t
-pub_glfs_read (struct glfs_fd *glfd, void *buf, size_t count, int flags)
+pub_glfs_preadv(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
+ off_t offset, int flags)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
+ return glfs_preadv_common(glfd, iovec, iovcnt, offset, flags, NULL);
+}
- iov.iov_base = buf;
- iov.iov_len = count;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read, 3.4.0)
+ssize_t
+pub_glfs_read(struct glfs_fd *glfd, void *buf, size_t count, int flags)
+{
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- ret = pub_glfs_preadv (glfd, &iov, 1, glfd->offset, flags);
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
- return ret;
-}
+ iov.iov_base = buf;
+ iov.iov_len = count;
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read, 3.4.0);
+ ret = pub_glfs_preadv(glfd, &iov, 1, glfd->offset, flags);
+ return ret;
+}
+GFAPI_SYMVER_PUBLIC(glfs_pread34, glfs_pread, 3.4.0)
ssize_t
-pub_glfs_pread (struct glfs_fd *glfd, void *buf, size_t count, off_t offset,
- int flags)
+pub_glfs_pread34(struct glfs_fd *glfd, void *buf, size_t count, off_t offset,
+ int flags)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- iov.iov_base = buf;
- iov.iov_len = count;
+ iov.iov_base = buf;
+ iov.iov_len = count;
- ret = pub_glfs_preadv (glfd, &iov, 1, offset, flags);
+ ret = pub_glfs_preadv(glfd, &iov, 1, offset, flags);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread, 6.0)
ssize_t
-pub_glfs_readv (struct glfs_fd *glfd, const struct iovec *iov, int count,
- int flags)
+pub_glfs_pread(struct glfs_fd *glfd, void *buf, size_t count, off_t offset,
+ int flags, struct glfs_stat *poststat)
{
- ssize_t ret = 0;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- ret = pub_glfs_preadv (glfd, iov, count, glfd->offset, flags);
+ iov.iov_base = buf;
+ iov.iov_len = count;
- return ret;
+ ret = glfs_preadv_common(glfd, &iov, 1, offset, flags, poststat);
+
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv, 3.4.0);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv, 3.4.0)
+ssize_t
+pub_glfs_readv(struct glfs_fd *glfd, const struct iovec *iov, int count,
+ int flags)
+{
+ ssize_t ret = 0;
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ ret = pub_glfs_preadv(glfd, iov, count, glfd->offset, flags);
+
+ return ret;
+}
struct glfs_io {
- struct glfs_fd *glfd;
- int op;
- off_t offset;
- struct iovec *iov;
- int count;
- int flags;
- glfs_io_cbk fn;
- void *data;
+ struct glfs_fd *glfd;
+ int op;
+ off_t offset;
+ struct iovec *iov;
+ int count;
+ int flags;
+ gf_boolean_t oldcb;
+ union {
+ glfs_io_cbk34 fn34;
+ glfs_io_cbk fn;
+ };
+ void *data;
};
-
static int
-glfs_io_async_cbk (int ret, call_frame_t *frame, void *data)
+glfs_io_async_cbk(int op_ret, int op_errno, call_frame_t *frame, void *cookie,
+ struct iovec *iovec, int count, struct iatt *prebuf,
+ struct iatt *postbuf)
{
- struct glfs_io *gio = data;
+ struct glfs_io *gio = NULL;
+ xlator_t *subvol = NULL;
+ struct glfs *fs = NULL;
+ struct glfs_fd *glfd = NULL;
+ int ret = -1;
+ struct glfs_stat prestat = {}, *prestatp = NULL;
+ struct glfs_stat poststat = {}, *poststatp = NULL;
+
+ GF_VALIDATE_OR_GOTO("gfapi", frame, inval);
+ GF_VALIDATE_OR_GOTO("gfapi", cookie, inval);
+
+ gio = frame->local;
+ frame->local = NULL;
+ subvol = cookie;
+ glfd = gio->glfd;
+ fs = glfd->fs;
+
+ if (!glfs_is_glfd_still_valid(glfd))
+ goto err;
+
+ if (op_ret <= 0) {
+ goto out;
+ } else if (gio->op == GF_FOP_READ) {
+ if (!iovec) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
- gio->fn (gio->glfd, ret, gio->data);
+ op_ret = iov_copy(gio->iov, gio->count, iovec, count);
+ glfd->offset = gio->offset + op_ret;
+ } else if (gio->op == GF_FOP_WRITE) {
+ glfd->offset = gio->offset + gio->iov->iov_len;
+ }
- GF_FREE (gio->iov);
- GF_FREE (gio);
+out:
+ errno = op_errno;
+ if (gio->oldcb) {
+ gio->fn34(gio->glfd, op_ret, gio->data);
+ } else {
+ if (prebuf) {
+ prestatp = &prestat;
+ glfs_iatt_to_statx(fs, prebuf, prestatp);
+ }
- return 0;
-}
+ if (postbuf) {
+ poststatp = &poststat;
+ glfs_iatt_to_statx(fs, postbuf, poststatp);
+ }
-ssize_t
-pub_glfs_pwritev (struct glfs_fd *, const struct iovec *, int, off_t, int);
+ gio->fn(gio->glfd, op_ret, prestatp, poststatp, gio->data);
+ }
+err:
+ fd_unref(glfd->fd);
+ /* Since the async operation is complete
+ * release the ref taken during the start
+ * of async operation
+ */
+ GF_REF_PUT(glfd);
+
+ GF_FREE(gio->iov);
+ GF_FREE(gio);
+ STACK_DESTROY(frame->root);
+ glfs_subvol_done(fs, subvol);
+
+ ret = 0;
+inval:
+ return ret;
+}
-int
-pub_glfs_ftruncate (struct glfs_fd *, off_t);
+static int
+glfs_preadv_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iovec *iovec, int count,
+ struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+{
+ glfs_io_async_cbk(op_ret, op_errno, frame, cookie, iovec, count, NULL,
+ stbuf);
-int
-pub_glfs_fdatasync (struct glfs_fd *);
+ return 0;
+}
-int
-pub_glfs_fsync (struct glfs_fd *glfd);
+static int
+glfs_preadv_async_common(struct glfs_fd *glfd, const struct iovec *iovec,
+ int count, off_t offset, int flags, gf_boolean_t oldcb,
+ glfs_io_cbk fn, void *data)
+{
+ struct glfs_io *gio = NULL;
+ int ret = 0;
+ call_frame_t *frame = NULL;
+ xlator_t *subvol = NULL;
+ struct glfs *fs = NULL;
+ fd_t *fd = NULL;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ fs = glfd->fs;
+
+ frame = syncop_create_frame(THIS);
+ if (!frame) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio = GF_CALLOC(1, sizeof(*gio), glfs_mt_glfs_io_t);
+ if (!gio) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio->iov = iov_dup(iovec, count);
+ if (!gio->iov) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio->op = GF_FOP_READ;
+ gio->glfd = glfd;
+ gio->count = count;
+ gio->offset = offset;
+ gio->flags = flags;
+ gio->oldcb = oldcb;
+ gio->fn = fn;
+ gio->data = data;
+
+ frame->local = gio;
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ STACK_WIND_COOKIE(frame, glfs_preadv_async_cbk, subvol, subvol,
+ subvol->fops->readv, fd, iov_length(iovec, count), offset,
+ flags, fop_attr);
-int
-pub_glfs_discard (struct glfs_fd *, off_t, size_t);
+out:
+ if (ret) {
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (gio) {
+ GF_FREE(gio->iov);
+ GF_FREE(gio);
+ }
+ if (frame) {
+ STACK_DESTROY(frame->root);
+ }
+ glfs_subvol_done(fs, subvol);
+ }
+ if (fop_attr)
+ dict_unref(fop_attr);
-int
-pub_glfs_zerofill (struct glfs_fd *, off_t, off_t);
+ __GLFS_EXIT_FS;
-static int
-glfs_io_async_task (void *data)
-{
- struct glfs_io *gio = data;
- ssize_t ret = 0;
-
- switch (gio->op) {
- case GF_FOP_WRITE:
- ret = pub_glfs_pwritev (gio->glfd, gio->iov, gio->count,
- gio->offset, gio->flags);
- break;
- case GF_FOP_FTRUNCATE:
- ret = pub_glfs_ftruncate (gio->glfd, gio->offset);
- break;
- case GF_FOP_FSYNC:
- if (gio->flags)
- ret = pub_glfs_fdatasync (gio->glfd);
- else
- ret = pub_glfs_fsync (gio->glfd);
- break;
- case GF_FOP_DISCARD:
- ret = pub_glfs_discard (gio->glfd, gio->offset, gio->count);
- break;
- case GF_FOP_ZEROFILL:
- ret = pub_glfs_zerofill(gio->glfd, gio->offset, gio->count);
- break;
- }
+ return ret;
- return (int) ret;
+invalid_fs:
+ return -1;
}
-
+GFAPI_SYMVER_PUBLIC(glfs_preadv_async34, glfs_preadv_async, 3.4.0)
int
-glfs_preadv_async_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iovec *iovec,
- int count, struct iatt *stbuf, struct iobref *iobref,
- dict_t *xdata)
+pub_glfs_preadv_async34(struct glfs_fd *glfd, const struct iovec *iovec,
+ int count, off_t offset, int flags, glfs_io_cbk34 fn,
+ void *data)
{
- struct glfs_io *gio = NULL;
- xlator_t *subvol = NULL;
- struct glfs *fs = NULL;
- struct glfs_fd *glfd = NULL;
-
+ return glfs_preadv_async_common(glfd, iovec, count, offset, flags, _gf_true,
+ (void *)fn, data);
+}
- gio = frame->local;
- frame->local = NULL;
- subvol = cookie;
- glfd = gio->glfd;
- fs = glfd->fs;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv_async, 6.0)
+int
+pub_glfs_preadv_async(struct glfs_fd *glfd, const struct iovec *iovec,
+ int count, off_t offset, int flags, glfs_io_cbk fn,
+ void *data)
+{
+ return glfs_preadv_async_common(glfd, iovec, count, offset, flags,
+ _gf_false, fn, data);
+}
- if (op_ret <= 0)
- goto out;
+GFAPI_SYMVER_PUBLIC(glfs_read_async34, glfs_read_async, 3.4.0)
+int
+pub_glfs_read_async34(struct glfs_fd *glfd, void *buf, size_t count, int flags,
+ glfs_io_cbk34 fn, void *data)
+{
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- op_ret = iov_copy (gio->iov, gio->count, iovec, count);
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
- glfd->offset = gio->offset + op_ret;
-out:
- errno = op_errno;
- gio->fn (gio->glfd, op_ret, gio->data);
+ iov.iov_base = buf;
+ iov.iov_len = count;
- GF_FREE (gio->iov);
- GF_FREE (gio);
- STACK_DESTROY (frame->root);
- glfs_subvol_done (fs, subvol);
+ ret = glfs_preadv_async_common(glfd, &iov, 1, glfd->offset, flags, _gf_true,
+ (void *)fn, data);
- return 0;
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read_async, 6.0)
int
-pub_glfs_preadv_async (struct glfs_fd *glfd, const struct iovec *iovec,
- int count, off_t offset, int flags, glfs_io_cbk fn,
- void *data)
+pub_glfs_read_async(struct glfs_fd *glfd, void *buf, size_t count, int flags,
+ glfs_io_cbk fn, void *data)
{
- struct glfs_io *gio = NULL;
- int ret = 0;
- call_frame_t *frame = NULL;
- xlator_t *subvol = NULL;
- glfs_t *fs = NULL;
- fd_t *fd = NULL;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
-
- fs = glfd->fs;
-
- frame = syncop_create_frame (THIS);
- if (!frame) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
- if (!gio) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gio->iov = iov_dup (iovec, count);
- if (!gio->iov) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gio->op = GF_FOP_READ;
- gio->glfd = glfd;
- gio->count = count;
- gio->offset = offset;
- gio->flags = flags;
- gio->fn = fn;
- gio->data = data;
-
- frame->local = gio;
-
- STACK_WIND_COOKIE (frame, glfs_preadv_async_cbk, subvol, subvol,
- subvol->fops->readv, fd, iov_length (iovec, count),
- offset, flags, NULL);
-
-out:
- if (ret) {
- if (gio) {
- GF_FREE (gio->iov);
- GF_FREE (gio);
- }
- if (frame) {
- STACK_DESTROY (frame->root);
- }
- glfs_subvol_done (fs, subvol);
- }
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- if (fd)
- fd_unref (fd);
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
- __GLFS_EXIT_FS;
+ iov.iov_base = buf;
+ iov.iov_len = count;
- return ret;
+ ret = glfs_preadv_async_common(glfd, &iov, 1, glfd->offset, flags,
+ _gf_false, fn, data);
-invalid_fs:
- return -1;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv_async, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC(glfs_pread_async34, glfs_pread_async, 3.4.0)
int
-pub_glfs_read_async (struct glfs_fd *glfd, void *buf, size_t count, int flags,
- glfs_io_cbk fn, void *data)
+pub_glfs_pread_async34(struct glfs_fd *glfd, void *buf, size_t count,
+ off_t offset, int flags, glfs_io_cbk34 fn, void *data)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- iov.iov_base = buf;
- iov.iov_len = count;
+ iov.iov_base = buf;
+ iov.iov_len = count;
- ret = pub_glfs_preadv_async (glfd, &iov, 1, glfd->offset, flags, fn, data);
+ ret = glfs_preadv_async_common(glfd, &iov, 1, offset, flags, _gf_true,
+ (void *)fn, data);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read_async, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread_async, 6.0)
int
-pub_glfs_pread_async (struct glfs_fd *glfd, void *buf, size_t count,
- off_t offset, int flags, glfs_io_cbk fn, void *data)
+pub_glfs_pread_async(struct glfs_fd *glfd, void *buf, size_t count,
+ off_t offset, int flags, glfs_io_cbk fn, void *data)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- iov.iov_base = buf;
- iov.iov_len = count;
+ iov.iov_base = buf;
+ iov.iov_len = count;
- ret = pub_glfs_preadv_async (glfd, &iov, 1, offset, flags, fn, data);
+ ret = glfs_preadv_async_common(glfd, &iov, 1, offset, flags, _gf_false, fn,
+ data);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread_async, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC(glfs_readv_async34, glfs_readv_async, 3.4.0)
int
-pub_glfs_readv_async (struct glfs_fd *glfd, const struct iovec *iov, int count,
- int flags, glfs_io_cbk fn, void *data)
+pub_glfs_readv_async34(struct glfs_fd *glfd, const struct iovec *iov, int count,
+ int flags, glfs_io_cbk34 fn, void *data)
{
- ssize_t ret = 0;
-
- ret = pub_glfs_preadv_async (glfd, iov, count, glfd->offset, flags,
- fn, data);
- return ret;
-}
+ ssize_t ret = 0;
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv_async, 3.4.0);
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+ ret = glfs_preadv_async_common(glfd, iov, count, glfd->offset, flags,
+ _gf_true, (void *)fn, data);
+ return ret;
+}
-ssize_t
-pub_glfs_pwritev (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
- off_t offset, int flags)
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readv_async, 6.0)
+int
+pub_glfs_readv_async(struct glfs_fd *glfd, const struct iovec *iov, int count,
+ int flags, glfs_io_cbk fn, void *data)
{
- xlator_t *subvol = NULL;
- int ret = -1;
- size_t size = -1;
- struct iobref *iobref = NULL;
- struct iobuf *iobuf = NULL;
- struct iovec iov = {0, };
- fd_t *fd = NULL;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
-
- size = iov_length (iovec, iovcnt);
-
- iobuf = iobuf_get2 (subvol->ctx->iobuf_pool, size);
- if (!iobuf) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- iobref = iobref_new ();
- if (!iobref) {
- iobuf_unref (iobuf);
- errno = ENOMEM;
- ret = -1;
- goto out;
- }
-
- ret = iobref_add (iobref, iobuf);
- if (ret) {
- iobuf_unref (iobuf);
- iobref_unref (iobref);
- errno = ENOMEM;
- ret = -1;
- goto out;
- }
-
- iov_unload (iobuf_ptr (iobuf), iovec, iovcnt); /* FIXME!!! */
-
- iov.iov_base = iobuf_ptr (iobuf);
- iov.iov_len = size;
-
- ret = syncop_writev (subvol, fd, &iov, 1, offset, iobref, flags, NULL,
- NULL);
- DECODE_SYNCOP_ERR (ret);
+ ssize_t ret = 0;
- iobuf_unref (iobuf);
- iobref_unref (iobref);
-
- if (ret <= 0)
- goto out;
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
- glfd->offset = (offset + size);
+ ret = glfs_preadv_async_common(glfd, iov, count, glfd->offset, flags,
+ _gf_false, fn, data);
+ return ret;
+}
+static ssize_t
+glfs_pwritev_common(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
+ off_t offset, int flags, struct glfs_stat *prestat,
+ struct glfs_stat *poststat)
+{
+ xlator_t *subvol = NULL;
+ int ret = -1;
+ struct iobref *iobref = NULL;
+ struct iobuf *iobuf = NULL;
+ struct iovec iov = {
+ 0,
+ };
+ fd_t *fd = NULL;
+ struct iatt preiatt =
+ {
+ 0,
+ },
+ postiatt = {
+ 0,
+ };
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = iobuf_copy(subvol->ctx->iobuf_pool, iovec, iovcnt, &iobref, &iobuf,
+ &iov);
+ if (ret)
+ goto out;
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_writev(subvol, fd, &iov, 1, offset, iobref, flags, &preiatt,
+ &postiatt, fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret >= 0) {
+ if (prestat)
+ glfs_iatt_to_statx(glfd->fs, &preiatt, prestat);
+ if (poststat)
+ glfs_iatt_to_statx(glfd->fs, &postiatt, poststat);
+ }
+
+ if (ret <= 0)
+ goto out;
+
+ glfd->offset = (offset + iov.iov_len);
out:
- if (fd)
- fd_unref (fd);
+ if (iobuf)
+ iobuf_unref(iobuf);
+ if (iobref)
+ iobref_unref(iobref);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (fop_attr)
+ dict_unref(fop_attr);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_copy_file_range, 6.0)
ssize_t
-pub_glfs_write (struct glfs_fd *glfd, const void *buf, size_t count, int flags)
+pub_glfs_copy_file_range(struct glfs_fd *glfd_in, off64_t *off_in,
+ struct glfs_fd *glfd_out, off64_t *off_out, size_t len,
+ unsigned int flags, struct glfs_stat *statbuf,
+ struct glfs_stat *prestat, struct glfs_stat *poststat)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
+ xlator_t *subvol = NULL;
+ int ret = -1;
+ fd_t *fd_in = NULL;
+ fd_t *fd_out = NULL;
+ struct iatt preiatt =
+ {
+ 0,
+ },
+ iattbuf =
+ {
+ 0,
+ },
+ postiatt = {
+ 0,
+ };
+ dict_t *fop_attr = NULL;
+ off64_t pos_in;
+ off64_t pos_out;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd_in, invalid_fs);
+ __GLFS_ENTRY_VALIDATE_FD(glfd_out, invalid_fs);
+
+ GF_REF_GET(glfd_in);
+ GF_REF_GET(glfd_out);
+
+ if (glfd_in->fs != glfd_out->fs) {
+ ret = -1;
+ errno = EXDEV;
+ goto out;
+ }
+
+ subvol = glfs_active_subvol(glfd_in->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd_in = glfs_resolve_fd(glfd_in->fs, subvol, glfd_in);
+ if (!fd_in) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ fd_out = glfs_resolve_fd(glfd_out->fs, subvol, glfd_out);
+ if (!fd_out) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ /*
+ * This is based on how the vfs layer in the kernel handles
+ * copy_file_range call. Upon receiving it follows the
+ * below method to consider the offset.
+ * if (off_in != NULL)
+ * use the value off_in to perform the op
+ * else if off_in == NULL
+ * use the current file offset position to perform the op
+ *
+ * For gfapi, glfd->offset is used. For a freshly opened
+ * fd, the offset is set to 0.
+ */
+ if (off_in)
+ pos_in = *off_in;
+ else
+ pos_in = glfd_in->offset;
+
+ if (off_out)
+ pos_out = *off_out;
+ else
+ pos_out = glfd_out->offset;
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_copy_file_range(subvol, fd_in, pos_in, fd_out, pos_out, len,
+ flags, &iattbuf, &preiatt, &postiatt, fop_attr,
+ NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret >= 0) {
+ pos_in += ret;
+ pos_out += ret;
+
+ if (off_in)
+ *off_in = pos_in;
+ if (off_out)
+ *off_out = pos_out;
+
+ if (statbuf)
+ glfs_iatt_to_statx(glfd_in->fs, &iattbuf, statbuf);
+ if (prestat)
+ glfs_iatt_to_statx(glfd_in->fs, &preiatt, prestat);
+ if (poststat)
+ glfs_iatt_to_statx(glfd_in->fs, &postiatt, poststat);
+ }
+
+ if (ret <= 0)
+ goto out;
+
+ /*
+ * If *off_in is NULL, then there is no offset info that can
+ * obtained from the input argument. Hence follow below method.
+ * If *off_in is NULL, then
+ * glfd->offset = offset + ret;
+ * else
+ * do nothing.
+ *
+ * According to the man page of copy_file_range, if off_in is
+ * NULL, then the offset of the source file is advanced by
+ * the return value of the fop. The same applies to off_out as
+ * well. Otherwise, if *off_in is not NULL, then the offset
+ * is not advanced by the filesystem. The entity which sends
+ * the copy_file_range call is supposed to advance the offset
+ * value in its buffer (pointed to by *off_in or *off_out)
+ * by the return value of copy_file_range.
+ */
+ if (!off_in)
+ glfd_in->offset += ret;
+
+ if (!off_out)
+ glfd_out->offset += ret;
- iov.iov_base = (void *) buf;
- iov.iov_len = count;
+out:
+ if (fd_in)
+ fd_unref(fd_in);
+ if (fd_out)
+ fd_unref(fd_out);
+ if (glfd_in)
+ GF_REF_PUT(glfd_in);
+ if (glfd_out)
+ GF_REF_PUT(glfd_out);
+ if (fop_attr)
+ dict_unref(fop_attr);
- ret = pub_glfs_pwritev (glfd, &iov, 1, glfd->offset, flags);
+ glfs_subvol_done(glfd_in->fs, subvol);
- return ret;
-}
+ __GLFS_EXIT_FS;
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write, 3.4.0);
+invalid_fs:
+ return ret;
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev, 3.4.0)
+ssize_t
+pub_glfs_pwritev(struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
+ off_t offset, int flags)
+{
+ return glfs_pwritev_common(glfd, iovec, iovcnt, offset, flags, NULL, NULL);
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write, 3.4.0)
ssize_t
-pub_glfs_writev (struct glfs_fd *glfd, const struct iovec *iov, int count,
- int flags)
+pub_glfs_write(struct glfs_fd *glfd, const void *buf, size_t count, int flags)
{
- ssize_t ret = 0;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- ret = pub_glfs_pwritev (glfd, iov, count, glfd->offset, flags);
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
- return ret;
-}
+ iov.iov_base = (void *)buf;
+ iov.iov_len = count;
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev, 3.4.0);
+ ret = pub_glfs_pwritev(glfd, &iov, 1, glfd->offset, flags);
+ return ret;
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev, 3.4.0)
ssize_t
-pub_glfs_pwrite (struct glfs_fd *glfd, const void *buf, size_t count,
- off_t offset, int flags)
+pub_glfs_writev(struct glfs_fd *glfd, const struct iovec *iov, int count,
+ int flags)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
+ ssize_t ret = 0;
- iov.iov_base = (void *) buf;
- iov.iov_len = count;
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
- ret = pub_glfs_pwritev (glfd, &iov, 1, offset, flags);
+ ret = pub_glfs_pwritev(glfd, iov, count, glfd->offset, flags);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite, 3.4.0);
+GFAPI_SYMVER_PUBLIC(glfs_pwrite34, glfs_pwrite, 3.4.0)
+ssize_t
+pub_glfs_pwrite34(struct glfs_fd *glfd, const void *buf, size_t count,
+ off_t offset, int flags)
+{
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
+ iov.iov_base = (void *)buf;
+ iov.iov_len = count;
-extern glfs_t *pub_glfs_from_glfd (glfs_fd_t *);
+ ret = pub_glfs_pwritev(glfd, &iov, 1, offset, flags);
-int
-pub_glfs_pwritev_async (struct glfs_fd *glfd, const struct iovec *iovec,
- int count, off_t offset, int flags, glfs_io_cbk fn,
- void *data)
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite, 6.0)
+ssize_t
+pub_glfs_pwrite(struct glfs_fd *glfd, const void *buf, size_t count,
+ off_t offset, int flags, struct glfs_stat *prestat,
+ struct glfs_stat *poststat)
{
- struct glfs_io *gio = NULL;
- int ret = -1;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ iov.iov_base = (void *)buf;
+ iov.iov_len = count;
- gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
- if (!gio) {
- errno = ENOMEM;
- goto out;
- }
+ ret = glfs_pwritev_common(glfd, &iov, 1, offset, flags, prestat, poststat);
- gio->iov = iov_dup (iovec, count);
- if (!gio->iov) {
- GF_FREE (gio);
- errno = ENOMEM;
- goto out;
- }
+ return ret;
+}
- gio->op = GF_FOP_WRITE;
- gio->glfd = glfd;
- gio->count = count;
- gio->offset = offset;
- gio->flags = flags;
- gio->fn = fn;
- gio->data = data;
+extern glfs_t *
+pub_glfs_from_glfd(glfs_fd_t *);
- ret = synctask_new (pub_glfs_from_glfd (glfd)->ctx->env,
- glfs_io_async_task, glfs_io_async_cbk,
- NULL, gio);
+static int
+glfs_pwritev_async_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)
+{
+ glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, prebuf,
+ postbuf);
- if (ret) {
- GF_FREE (gio->iov);
- GF_FREE (gio);
- }
+ return 0;
+}
+static int
+glfs_pwritev_async_common(struct glfs_fd *glfd, const struct iovec *iovec,
+ int count, off_t offset, int flags,
+ gf_boolean_t oldcb, glfs_io_cbk fn, void *data)
+{
+ struct glfs_io *gio = NULL;
+ int ret = -1;
+ call_frame_t *frame = NULL;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ struct iobref *iobref = NULL;
+ struct iobuf *iobuf = NULL;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ /* Need to take explicit ref so that the fd
+ * is not destroyed before the fop is complete
+ */
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ errno = EBADFD;
+ goto out;
+ }
+
+ gio = GF_CALLOC(1, sizeof(*gio), glfs_mt_glfs_io_t);
+ if (!gio) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio->op = GF_FOP_WRITE;
+ gio->glfd = glfd;
+ gio->offset = offset;
+ gio->flags = flags;
+ gio->oldcb = oldcb;
+ gio->fn = fn;
+ gio->data = data;
+ gio->count = 1;
+ gio->iov = GF_CALLOC(gio->count, sizeof(*(gio->iov)), gf_common_mt_iovec);
+ if (!gio->iov) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = iobuf_copy(subvol->ctx->iobuf_pool, iovec, count, &iobref, &iobuf,
+ gio->iov);
+ if (ret)
+ goto out;
+
+ frame = syncop_create_frame(THIS);
+ if (!frame) {
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
+
+ frame->local = gio;
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ STACK_WIND_COOKIE(frame, glfs_pwritev_async_cbk, subvol, subvol,
+ subvol->fops->writev, fd, gio->iov, gio->count, offset,
+ flags, iobref, fop_attr);
+
+ ret = 0;
out:
- __GLFS_EXIT_FS;
+ if (ret) {
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ GF_FREE(gio);
+ /*
+ * If there is any error condition check after the frame
+ * creation, we have to destroy the frame root.
+ */
+ glfs_subvol_done(glfd->fs, subvol);
+ }
+ if (fop_attr)
+ dict_unref(fop_attr);
+
+ if (iobuf)
+ iobuf_unref(iobuf);
+ if (iobref)
+ iobref_unref(iobref);
+
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev_async, 3.4.0);
-
+GFAPI_SYMVER_PUBLIC(glfs_pwritev_async34, glfs_pwritev_async, 3.4.0)
+int
+pub_glfs_pwritev_async34(struct glfs_fd *glfd, const struct iovec *iovec,
+ int count, off_t offset, int flags, glfs_io_cbk34 fn,
+ void *data)
+{
+ return glfs_pwritev_async_common(glfd, iovec, count, offset, flags,
+ _gf_true, (void *)fn, data);
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev_async, 6.0)
int
-pub_glfs_write_async (struct glfs_fd *glfd, const void *buf, size_t count,
- int flags, glfs_io_cbk fn, void *data)
+pub_glfs_pwritev_async(struct glfs_fd *glfd, const struct iovec *iovec,
+ int count, off_t offset, int flags, glfs_io_cbk fn,
+ void *data)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
+ return glfs_pwritev_async_common(glfd, iovec, count, offset, flags,
+ _gf_false, fn, data);
+}
- iov.iov_base = (void *) buf;
- iov.iov_len = count;
+GFAPI_SYMVER_PUBLIC(glfs_write_async34, glfs_write_async, 3.4.0)
+int
+pub_glfs_write_async34(struct glfs_fd *glfd, const void *buf, size_t count,
+ int flags, glfs_io_cbk34 fn, void *data)
+{
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- ret = pub_glfs_pwritev_async (glfd, &iov, 1, glfd->offset, flags, fn, data);
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
- return ret;
-}
+ iov.iov_base = (void *)buf;
+ iov.iov_len = count;
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write_async, 3.4.0);
+ ret = glfs_pwritev_async_common(glfd, &iov, 1, glfd->offset, flags,
+ _gf_true, (void *)fn, data);
+ return ret;
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_write_async, 6.0)
int
-pub_glfs_pwrite_async (struct glfs_fd *glfd, const void *buf, int count,
- off_t offset, int flags, glfs_io_cbk fn, void *data)
+pub_glfs_write_async(struct glfs_fd *glfd, const void *buf, size_t count,
+ int flags, glfs_io_cbk fn, void *data)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
+
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
- iov.iov_base = (void *) buf;
- iov.iov_len = count;
+ iov.iov_base = (void *)buf;
+ iov.iov_len = count;
- ret = pub_glfs_pwritev_async (glfd, &iov, 1, offset, flags, fn, data);
+ ret = glfs_pwritev_async_common(glfd, &iov, 1, glfd->offset, flags,
+ _gf_false, fn, data);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite_async, 3.4.0);
+GFAPI_SYMVER_PUBLIC(glfs_pwrite_async34, glfs_pwrite_async, 3.4.0)
+int
+pub_glfs_pwrite_async34(struct glfs_fd *glfd, const void *buf, int count,
+ off_t offset, int flags, glfs_io_cbk34 fn, void *data)
+{
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
+ iov.iov_base = (void *)buf;
+ iov.iov_len = count;
+ ret = glfs_pwritev_async_common(glfd, &iov, 1, offset, flags, _gf_true,
+ (void *)fn, data);
+
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite_async, 6.0)
int
-pub_glfs_writev_async (struct glfs_fd *glfd, const struct iovec *iov, int count,
- int flags, glfs_io_cbk fn, void *data)
+pub_glfs_pwrite_async(struct glfs_fd *glfd, const void *buf, int count,
+ off_t offset, int flags, glfs_io_cbk fn, void *data)
{
- ssize_t ret = 0;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
- ret = pub_glfs_pwritev_async (glfd, iov, count, glfd->offset, flags,
- fn, data);
- return ret;
-}
+ iov.iov_base = (void *)buf;
+ iov.iov_len = count;
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev_async, 3.4.0);
+ ret = glfs_pwritev_async_common(glfd, &iov, 1, offset, flags, _gf_false, fn,
+ data);
+ return ret;
+}
+GFAPI_SYMVER_PUBLIC(glfs_writev_async34, glfs_writev_async, 3.4.0)
int
-pub_glfs_fsync (struct glfs_fd *glfd)
+pub_glfs_writev_async34(struct glfs_fd *glfd, const struct iovec *iov,
+ int count, int flags, glfs_io_cbk34 fn, void *data)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
+ ssize_t ret = 0;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ ret = glfs_pwritev_async_common(glfd, iov, count, glfd->offset, flags,
+ _gf_true, (void *)fn, data);
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev_async, 6.0)
+int
+pub_glfs_writev_async(struct glfs_fd *glfd, const struct iovec *iov, int count,
+ int flags, glfs_io_cbk fn, void *data)
+{
+ ssize_t ret = 0;
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ if (glfd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+ ret = glfs_pwritev_async_common(glfd, iov, count, glfd->offset, flags,
+ _gf_false, fn, data);
+ return ret;
+}
- ret = syncop_fsync (subvol, fd, 0, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+static int
+glfs_fsync_common(struct glfs_fd *glfd, struct glfs_stat *prestat,
+ struct glfs_stat *poststat)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ struct iatt preiatt =
+ {
+ 0,
+ },
+ postiatt = {
+ 0,
+ };
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_fsync(subvol, fd, 0, &preiatt, &postiatt, fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret >= 0) {
+ if (prestat)
+ glfs_iatt_to_statx(glfd->fs, &preiatt, prestat);
+ if (poststat)
+ glfs_iatt_to_statx(glfd->fs, &postiatt, poststat);
+ }
out:
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (fop_attr)
+ dict_unref(fop_attr);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync, 3.4.0);
+GFAPI_SYMVER_PUBLIC(glfs_fsync34, glfs_fsync, 3.4.0)
+int
+pub_glfs_fsync34(struct glfs_fd *glfd)
+{
+ return glfs_fsync_common(glfd, NULL, NULL);
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync, 6.0)
+int
+pub_glfs_fsync(struct glfs_fd *glfd, struct glfs_stat *prestat,
+ struct glfs_stat *poststat)
+{
+ return glfs_fsync_common(glfd, prestat, poststat);
+}
static int
-glfs_fsync_async_common (struct glfs_fd *glfd, glfs_io_cbk fn, void *data,
- int dataonly)
+glfs_fsync_async_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 glfs_io *gio = NULL;
- int ret = 0;
-
- gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
- if (!gio) {
- errno = ENOMEM;
- return -1;
- }
-
- gio->op = GF_FOP_FSYNC;
- gio->glfd = glfd;
- gio->flags = dataonly;
- gio->fn = fn;
- gio->data = data;
-
- ret = synctask_new (pub_glfs_from_glfd (glfd)->ctx->env,
- glfs_io_async_task, glfs_io_async_cbk,
- NULL, gio);
+ glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, prebuf,
+ postbuf);
- if (ret) {
- GF_FREE (gio->iov);
- GF_FREE (gio);
- }
+ return 0;
+}
- return ret;
+static int
+glfs_fsync_async_common(struct glfs_fd *glfd, gf_boolean_t oldcb,
+ glfs_io_cbk fn, void *data, int dataonly)
+{
+ struct glfs_io *gio = NULL;
+ int ret = 0;
+ call_frame_t *frame = NULL;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+
+ /* Need to take explicit ref so that the fd
+ * is not destroyed before the fop is complete
+ */
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ frame = syncop_create_frame(THIS);
+ if (!frame) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio = GF_CALLOC(1, sizeof(*gio), glfs_mt_glfs_io_t);
+ if (!gio) {
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
+
+ gio->op = GF_FOP_FSYNC;
+ gio->glfd = glfd;
+ gio->flags = dataonly;
+ gio->oldcb = oldcb;
+ gio->fn = fn;
+ gio->data = data;
+
+ frame->local = gio;
+
+ STACK_WIND_COOKIE(frame, glfs_fsync_async_cbk, subvol, subvol,
+ subvol->fops->fsync, fd, dataonly, NULL);
+out:
+ if (ret) {
+ if (fd)
+ fd_unref(fd);
+ GF_REF_PUT(glfd);
+ GF_FREE(gio);
+ if (frame)
+ STACK_DESTROY(frame->root);
+ glfs_subvol_done(glfd->fs, subvol);
+ }
+
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC(glfs_fsync_async34, glfs_fsync_async, 3.4.0)
int
-pub_glfs_fsync_async (struct glfs_fd *glfd, glfs_io_cbk fn, void *data)
+pub_glfs_fsync_async34(struct glfs_fd *glfd, glfs_io_cbk34 fn, void *data)
{
- int ret = -1;
+ int ret = -1;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
- ret = glfs_fsync_async_common (glfd, fn, data, 0);
+ ret = glfs_fsync_async_common(glfd, _gf_true, (void *)fn, data, 0);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync_async, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsync_async, 6.0)
int
-pub_glfs_fdatasync (struct glfs_fd *glfd)
+pub_glfs_fsync_async(struct glfs_fd *glfd, glfs_io_cbk fn, void *data)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
+ int ret = -1;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ ret = glfs_fsync_async_common(glfd, _gf_false, fn, data, 0);
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ __GLFS_EXIT_FS;
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+invalid_fs:
+ return ret;
+}
- ret = syncop_fsync (subvol, fd, 1, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+static int
+glfs_fdatasync_common(struct glfs_fd *glfd, struct glfs_stat *prestat,
+ struct glfs_stat *poststat)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ struct iatt preiatt =
+ {
+ 0,
+ },
+ postiatt = {
+ 0,
+ };
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_fsync(subvol, fd, 1, &preiatt, &postiatt, fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret >= 0) {
+ if (prestat)
+ glfs_iatt_to_statx(glfd->fs, &preiatt, prestat);
+ if (poststat)
+ glfs_iatt_to_statx(glfd->fs, &postiatt, poststat);
+ }
out:
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (fop_attr)
+ dict_unref(fop_attr);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync, 3.4.0);
+GFAPI_SYMVER_PUBLIC(glfs_fdatasync34, glfs_fdatasync, 3.4.0)
+int
+pub_glfs_fdatasync34(struct glfs_fd *glfd)
+{
+ return glfs_fdatasync_common(glfd, NULL, NULL);
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync, 6.0)
+int
+pub_glfs_fdatasync(struct glfs_fd *glfd, struct glfs_stat *prestat,
+ struct glfs_stat *poststat)
+{
+ return glfs_fdatasync_common(glfd, prestat, poststat);
+}
+GFAPI_SYMVER_PUBLIC(glfs_fdatasync_async34, glfs_fdatasync_async, 3.4.0)
int
-pub_glfs_fdatasync_async (struct glfs_fd *glfd, glfs_io_cbk fn, void *data)
+pub_glfs_fdatasync_async34(struct glfs_fd *glfd, glfs_io_cbk34 fn, void *data)
{
- int ret = -1;
+ int ret = -1;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
- ret = glfs_fsync_async_common (glfd, fn, data, 1);
+ ret = glfs_fsync_async_common(glfd, _gf_true, (void *)fn, data, 1);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync_async, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fdatasync_async, 6.0)
int
-pub_glfs_ftruncate (struct glfs_fd *glfd, off_t offset)
+pub_glfs_fdatasync_async(struct glfs_fd *glfd, glfs_io_cbk fn, void *data)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
+ int ret = -1;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ ret = glfs_fsync_async_common(glfd, _gf_false, fn, data, 1);
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ __GLFS_EXIT_FS;
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+invalid_fs:
+ return ret;
+}
- ret = syncop_ftruncate (subvol, fd, offset, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+static int
+glfs_ftruncate_common(struct glfs_fd *glfd, off_t offset,
+ struct glfs_stat *prestat, struct glfs_stat *poststat)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ struct iatt preiatt =
+ {
+ 0,
+ },
+ postiatt = {
+ 0,
+ };
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_ftruncate(subvol, fd, offset, &preiatt, &postiatt, fop_attr,
+ NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret >= 0) {
+ if (prestat)
+ glfs_iatt_to_statx(glfd->fs, &preiatt, prestat);
+ if (poststat)
+ glfs_iatt_to_statx(glfd->fs, &postiatt, poststat);
+ }
out:
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (fop_attr)
+ dict_unref(fop_attr);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate, 3.4.0);
+GFAPI_SYMVER_PUBLIC(glfs_ftruncate34, glfs_ftruncate, 3.4.0)
+int
+pub_glfs_ftruncate34(struct glfs_fd *glfd, off_t offset)
+{
+ return glfs_ftruncate_common(glfd, offset, NULL, NULL);
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate, 6.0)
+int
+pub_glfs_ftruncate(struct glfs_fd *glfd, off_t offset,
+ struct glfs_stat *prestat, struct glfs_stat *poststat)
+{
+ return glfs_ftruncate_common(glfd, offset, prestat, poststat);
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_truncate, 3.7.15)
int
-pub_glfs_ftruncate_async (struct glfs_fd *glfd, off_t offset, glfs_io_cbk fn,
- void *data)
+pub_glfs_truncate(struct glfs *fs, const char *path, off_t length)
{
- struct glfs_io *gio = NULL;
- int ret = -1;
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+retry:
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
- if (!gio) {
- errno = ENOMEM;
- goto out;
- }
+ if (ret)
+ goto out;
- gio->op = GF_FOP_FTRUNCATE;
- gio->glfd = glfd;
- gio->offset = offset;
- gio->fn = fn;
- gio->data = data;
+ ret = syncop_truncate(subvol, &loc, length, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ret = synctask_new (pub_glfs_from_glfd (glfd)->ctx->env,
- glfs_io_async_task, glfs_io_async_cbk,
- NULL, gio);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
+out:
+ loc_wipe(&loc);
- if (ret) {
- GF_FREE (gio->iov);
- GF_FREE (gio);
- }
+ glfs_subvol_done(fs, subvol);
-out:
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
+}
+
+static int
+glfs_ftruncate_async_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)
+{
+ glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, prebuf,
+ postbuf);
+
+ return 0;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate_async, 3.4.0);
+static int
+glfs_ftruncate_async_common(struct glfs_fd *glfd, off_t offset,
+ gf_boolean_t oldcb, glfs_io_cbk fn, void *data)
+{
+ struct glfs_io *gio = NULL;
+ int ret = -1;
+ call_frame_t *frame = NULL;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ /* Need to take explicit ref so that the fd
+ * is not destroyed before the fop is complete
+ */
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ errno = EBADFD;
+ goto out;
+ }
+
+ frame = syncop_create_frame(THIS);
+ if (!frame) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio = GF_CALLOC(1, sizeof(*gio), glfs_mt_glfs_io_t);
+ if (!gio) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio->op = GF_FOP_FTRUNCATE;
+ gio->glfd = glfd;
+ gio->offset = offset;
+ gio->oldcb = oldcb;
+ gio->fn = fn;
+ gio->data = data;
+
+ frame->local = gio;
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ STACK_WIND_COOKIE(frame, glfs_ftruncate_async_cbk, subvol, subvol,
+ subvol->fops->ftruncate, fd, offset, fop_attr);
+
+ ret = 0;
+out:
+ if (ret) {
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ GF_FREE(gio);
+ if (frame)
+ STACK_DESTROY(frame->root);
+ glfs_subvol_done(glfd->fs, subvol);
+ }
+ if (fop_attr)
+ dict_unref(fop_attr);
+
+ __GLFS_EXIT_FS;
+invalid_fs:
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC(glfs_ftruncate_async34, glfs_ftruncate_async, 3.4.0)
int
-pub_glfs_access (struct glfs *fs, const char *path, int mode)
+pub_glfs_ftruncate_async34(struct glfs_fd *glfd, off_t offset, glfs_io_cbk34 fn,
+ void *data)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
+ return glfs_ftruncate_async_common(glfd, offset, _gf_true, (void *)fn,
+ data);
+}
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ftruncate_async, 6.0)
+int
+pub_glfs_ftruncate_async(struct glfs_fd *glfd, off_t offset, glfs_io_cbk fn,
+ void *data)
+{
+ return glfs_ftruncate_async_common(glfd, offset, _gf_false, fn, data);
+}
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_access, 3.4.0)
+int
+pub_glfs_access(struct glfs *fs, const char *path, int mode)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = syncop_access (subvol, &loc, mode, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_access(subvol, &loc, mode, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_access, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_symlink, 3.4.0)
int
-pub_glfs_symlink (struct glfs *fs, const char *data, const char *path)
+pub_glfs_symlink(struct glfs *fs, const char *data, const char *path)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- uuid_t gfid;
- dict_t *xattr_req = NULL;
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- xattr_req = dict_new ();
- if (!xattr_req) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gf_uuid_generate (gfid);
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
retry:
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (loc.inode) {
- errno = EEXIST;
- ret = -1;
- goto out;
- }
+ if (loc.inode) {
+ errno = EEXIST;
+ ret = -1;
+ goto out;
+ }
- if (ret == -1 && errno != ENOENT)
- /* Any other type of error is fatal */
- goto out;
+ if (ret == -1 && errno != ENOENT)
+ /* Any other type of error is fatal */
+ goto out;
- if (ret == -1 && errno == ENOENT && !loc.parent)
- /* The parent directory or an ancestor even
- higher does not exist
- */
- goto out;
+ if (ret == -1 && errno == ENOENT && !loc.parent)
+ /* The parent directory or an ancestor even
+ higher does not exist
+ */
+ goto out;
- /* ret == -1 && errno == ENOENT */
- loc.inode = inode_new (loc.parent->table);
- if (!loc.inode) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ /* ret == -1 && errno == ENOENT */
+ loc.inode = inode_new(loc.parent->table);
+ if (!loc.inode) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
- ret = syncop_symlink (subvol, &loc, data, &iatt, xattr_req, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_symlink(subvol, &loc, data, &iatt, xattr_req, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret == 0)
- ret = glfs_loc_link (&loc, &iatt);
+ if (ret == 0)
+ ret = glfs_loc_link(&loc, &iatt);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (xattr_req)
- dict_unref (xattr_req);
+ if (xattr_req)
+ dict_unref(xattr_req);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_symlink, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readlink, 3.4.0)
int
-pub_glfs_readlink (struct glfs *fs, const char *path, char *buf, size_t bufsiz)
+pub_glfs_readlink(struct glfs *fs, const char *path, char *buf, size_t bufsiz)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
- char *linkval = NULL;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+ char *linkval = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- if (iatt.ia_type != IA_IFLNK) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
+ if (iatt.ia_type != IA_IFLNK) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
- ret = syncop_readlink (subvol, &loc, &linkval, bufsiz, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret > 0) {
- memcpy (buf, linkval, ret);
- GF_FREE (linkval);
- }
+ ret = syncop_readlink(subvol, &loc, &linkval, bufsiz, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret > 0) {
+ memcpy(buf, linkval, ret);
+ GF_FREE(linkval);
+ }
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readlink, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mknod, 3.4.0)
int
-pub_glfs_mknod (struct glfs *fs, const char *path, mode_t mode, dev_t dev)
+pub_glfs_mknod(struct glfs *fs, const char *path, mode_t mode, dev_t dev)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- uuid_t gfid;
- dict_t *xattr_req = NULL;
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- xattr_req = dict_new ();
- if (!xattr_req) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gf_uuid_generate (gfid);
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
retry:
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (loc.inode) {
- errno = EEXIST;
- ret = -1;
- goto out;
- }
+ if (loc.inode) {
+ errno = EEXIST;
+ ret = -1;
+ goto out;
+ }
- if (ret == -1 && errno != ENOENT)
- /* Any other type of error is fatal */
- goto out;
+ if (ret == -1 && errno != ENOENT)
+ /* Any other type of error is fatal */
+ goto out;
- if (ret == -1 && errno == ENOENT && !loc.parent)
- /* The parent directory or an ancestor even
- higher does not exist
- */
- goto out;
+ if (ret == -1 && errno == ENOENT && !loc.parent)
+ /* The parent directory or an ancestor even
+ higher does not exist
+ */
+ goto out;
- /* ret == -1 && errno == ENOENT */
- loc.inode = inode_new (loc.parent->table);
- if (!loc.inode) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ /* ret == -1 && errno == ENOENT */
+ loc.inode = inode_new(loc.parent->table);
+ if (!loc.inode) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
- ret = syncop_mknod (subvol, &loc, mode, dev, &iatt, xattr_req, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_mknod(subvol, &loc, mode, dev, &iatt, xattr_req, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret == 0)
- ret = glfs_loc_link (&loc, &iatt);
+ if (ret == 0)
+ ret = glfs_loc_link(&loc, &iatt);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (xattr_req)
- dict_unref (xattr_req);
+ if (xattr_req)
+ dict_unref(xattr_req);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mknod, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mkdir, 3.4.0)
int
-pub_glfs_mkdir (struct glfs *fs, const char *path, mode_t mode)
+pub_glfs_mkdir(struct glfs *fs, const char *path, mode_t mode)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- uuid_t gfid;
- dict_t *xattr_req = NULL;
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- xattr_req = dict_new ();
- if (!xattr_req) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gf_uuid_generate (gfid);
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
retry:
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (loc.inode) {
- errno = EEXIST;
- ret = -1;
- goto out;
- }
+ if (loc.inode) {
+ errno = EEXIST;
+ ret = -1;
+ goto out;
+ }
- if (ret == -1 && errno != ENOENT)
- /* Any other type of error is fatal */
- goto out;
+ if (ret == -1 && errno != ENOENT)
+ /* Any other type of error is fatal */
+ goto out;
- if (ret == -1 && errno == ENOENT && !loc.parent)
- /* The parent directory or an ancestor even
- higher does not exist
- */
- goto out;
+ if (ret == -1 && errno == ENOENT && !loc.parent)
+ /* The parent directory or an ancestor even
+ higher does not exist
+ */
+ goto out;
- /* ret == -1 && errno == ENOENT */
- loc.inode = inode_new (loc.parent->table);
- if (!loc.inode) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ /* ret == -1 && errno == ENOENT */
+ loc.inode = inode_new(loc.parent->table);
+ if (!loc.inode) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
- ret = syncop_mkdir (subvol, &loc, mode, &iatt, xattr_req, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_mkdir(subvol, &loc, mode, &iatt, xattr_req, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret == 0)
- ret = glfs_loc_link (&loc, &iatt);
+ if (ret == 0)
+ ret = glfs_loc_link(&loc, &iatt);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (xattr_req)
- dict_unref (xattr_req);
+ if (xattr_req)
+ dict_unref(xattr_req);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_mkdir, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unlink, 3.4.0)
int
-pub_glfs_unlink (struct glfs *fs, const char *path)
+pub_glfs_unlink(struct glfs *fs, const char *path)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- if (iatt.ia_type == IA_IFDIR) {
- ret = -1;
- errno = EISDIR;
- goto out;
- }
+ if (iatt.ia_type == IA_IFDIR) {
+ ret = -1;
+ errno = EISDIR;
+ goto out;
+ }
- ret = syncop_unlink (subvol, &loc, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ /* TODO: Add leaseid */
+ ret = syncop_unlink(subvol, &loc, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret == 0)
- ret = glfs_loc_unlink (&loc);
+ if (ret == 0)
+ ret = glfs_loc_unlink(&loc);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unlink, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rmdir, 3.4.0)
int
-pub_glfs_rmdir (struct glfs *fs, const char *path)
+pub_glfs_rmdir(struct glfs *fs, const char *path)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- if (iatt.ia_type != IA_IFDIR) {
- ret = -1;
- errno = ENOTDIR;
- goto out;
- }
+ if (iatt.ia_type != IA_IFDIR) {
+ ret = -1;
+ errno = ENOTDIR;
+ goto out;
+ }
- ret = syncop_rmdir (subvol, &loc, 0, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_rmdir(subvol, &loc, 0, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret == 0)
- ret = glfs_loc_unlink (&loc);
+ if (ret == 0)
+ ret = glfs_loc_unlink(&loc);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rmdir, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rename, 3.4.0)
int
-pub_glfs_rename (struct glfs *fs, const char *oldpath, const char *newpath)
+pub_glfs_rename(struct glfs *fs, const char *oldpath, const char *newpath)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t oldloc = {0, };
- loc_t newloc = {0, };
- struct iatt oldiatt = {0, };
- struct iatt newiatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t oldloc = {
+ 0,
+ };
+ loc_t newloc = {
+ 0,
+ };
+ struct iatt oldiatt = {
+ 0,
+ };
+ struct iatt newiatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- ret = glfs_lresolve (fs, subvol, oldpath, &oldloc, &oldiatt, reval);
+ ret = glfs_lresolve(fs, subvol, oldpath, &oldloc, &oldiatt, reval);
- ESTALE_RETRY (ret, errno, reval, &oldloc, retry);
+ ESTALE_RETRY(ret, errno, reval, &oldloc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
retrynew:
- ret = glfs_lresolve (fs, subvol, newpath, &newloc, &newiatt, reval);
-
- ESTALE_RETRY (ret, errno, reval, &newloc, retrynew);
-
- if (ret && errno != ENOENT && newloc.parent)
- goto out;
-
- if (newiatt.ia_type != IA_INVAL) {
- if ((oldiatt.ia_type == IA_IFDIR) !=
- (newiatt.ia_type == IA_IFDIR)) {
- /* Either both old and new must be dirs,
- * or both must be non-dirs. Else, fail.
- */
- ret = -1;
- errno = EISDIR;
- goto out;
- }
+ ret = glfs_lresolve(fs, subvol, newpath, &newloc, &newiatt, reval);
+
+ ESTALE_RETRY(ret, errno, reval, &newloc, retrynew);
+
+ if (ret && errno != ENOENT && newloc.parent)
+ goto out;
+
+ if (newiatt.ia_type != IA_INVAL) {
+ if ((oldiatt.ia_type == IA_IFDIR) != (newiatt.ia_type == IA_IFDIR)) {
+ /* Either both old and new must be dirs,
+ * or both must be non-dirs. Else, fail.
+ */
+ ret = -1;
+ errno = EISDIR;
+ goto out;
}
+ }
- /* TODO: check if new or old is a prefix of the other, and fail EINVAL */
+ /* TODO: - check if new or old is a prefix of the other, and fail EINVAL
+ * - Add leaseid */
- ret = syncop_rename (subvol, &oldloc, &newloc, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_rename(subvol, &oldloc, &newloc, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- if (ret == -1 && errno == ESTALE) {
- if (reval < DEFAULT_REVAL_COUNT) {
- reval++;
- loc_wipe (&oldloc);
- loc_wipe (&newloc);
- goto retry;
- }
- }
+ if (ret == -1 && errno == ESTALE) {
+ if (reval < DEFAULT_REVAL_COUNT) {
+ reval++;
+ loc_wipe(&oldloc);
+ loc_wipe(&newloc);
+ goto retry;
+ }
+ }
- if (ret == 0)
- inode_rename (oldloc.parent->table, oldloc.parent, oldloc.name,
- newloc.parent, newloc.name, oldloc.inode,
- &oldiatt);
+ if (ret == 0) {
+ inode_rename(oldloc.parent->table, oldloc.parent, oldloc.name,
+ newloc.parent, newloc.name, oldloc.inode, &oldiatt);
+
+ if (newloc.inode && !inode_has_dentry(newloc.inode))
+ inode_forget(newloc.inode, 0);
+ }
out:
- loc_wipe (&oldloc);
- loc_wipe (&newloc);
+ loc_wipe(&oldloc);
+ loc_wipe(&newloc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_rename, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_link, 3.4.0)
int
-pub_glfs_link (struct glfs *fs, const char *oldpath, const char *newpath)
+pub_glfs_link(struct glfs *fs, const char *oldpath, const char *newpath)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t oldloc = {0, };
- loc_t newloc = {0, };
- struct iatt oldiatt = {0, };
- struct iatt newiatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t oldloc = {
+ 0,
+ };
+ loc_t newloc = {
+ 0,
+ };
+ struct iatt oldiatt = {
+ 0,
+ };
+ struct iatt newiatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- ret = glfs_lresolve (fs, subvol, oldpath, &oldloc, &oldiatt, reval);
+ ret = glfs_lresolve(fs, subvol, oldpath, &oldloc, &oldiatt, reval);
- ESTALE_RETRY (ret, errno, reval, &oldloc, retry);
+ ESTALE_RETRY(ret, errno, reval, &oldloc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
retrynew:
- ret = glfs_lresolve (fs, subvol, newpath, &newloc, &newiatt, reval);
-
- ESTALE_RETRY (ret, errno, reval, &newloc, retrynew);
-
- if (ret == 0) {
- ret = -1;
- errno = EEXIST;
- goto out;
- }
-
- if (oldiatt.ia_type == IA_IFDIR) {
- ret = -1;
- errno = EISDIR;
- goto out;
- }
-
- /* Filling the inode of the hard link to be same as that of the
- original file
- */
- if (newloc.inode) {
- inode_unref (newloc.inode);
- newloc.inode = NULL;
- }
- newloc.inode = inode_ref (oldloc.inode);
-
- ret = syncop_link (subvol, &oldloc, &newloc, &newiatt, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
-
- if (ret == -1 && errno == ESTALE) {
- loc_wipe (&oldloc);
- loc_wipe (&newloc);
- if (reval--)
- goto retry;
- }
-
- if (ret == 0)
- ret = glfs_loc_link (&newloc, &newiatt);
+ ret = glfs_lresolve(fs, subvol, newpath, &newloc, &newiatt, reval);
+
+ ESTALE_RETRY(ret, errno, reval, &newloc, retrynew);
+
+ if (ret == 0) {
+ ret = -1;
+ errno = EEXIST;
+ goto out;
+ }
+
+ if (oldiatt.ia_type == IA_IFDIR) {
+ ret = -1;
+ errno = EISDIR;
+ goto out;
+ }
+
+ /* Filling the inode of the hard link to be same as that of the
+ original file
+ */
+ if (newloc.inode) {
+ inode_unref(newloc.inode);
+ newloc.inode = NULL;
+ }
+ newloc.inode = inode_ref(oldloc.inode);
+
+ ret = syncop_link(subvol, &oldloc, &newloc, &newiatt, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret == -1 && errno == ESTALE) {
+ loc_wipe(&oldloc);
+ loc_wipe(&newloc);
+ if (reval--)
+ goto retry;
+ }
+
+ if (ret == 0)
+ ret = glfs_loc_link(&newloc, &newiatt);
out:
- loc_wipe (&oldloc);
- loc_wipe (&newloc);
+ loc_wipe(&oldloc);
+ loc_wipe(&newloc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_link, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_opendir, 3.4.0)
struct glfs_fd *
-pub_glfs_opendir (struct glfs *fs, const char *path)
-{
- int ret = -1;
- struct glfs_fd *glfd = NULL;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- glfd = glfs_fd_new (fs);
- if (!glfd)
- goto out;
-
- INIT_LIST_HEAD (&glfd->entries);
+pub_glfs_opendir(struct glfs *fs, const char *path)
+{
+ int ret = -1;
+ struct glfs_fd *glfd = NULL;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ glfd = glfs_fd_new(fs);
+ if (!glfd)
+ goto out;
+
+ INIT_LIST_HEAD(&glfd->entries);
retry:
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- if (!IA_ISDIR (iatt.ia_type)) {
- ret = -1;
- errno = ENOTDIR;
- goto out;
- }
+ if (!IA_ISDIR(iatt.ia_type)) {
+ ret = -1;
+ errno = ENOTDIR;
+ goto out;
+ }
- if (glfd->fd) {
- /* Retry. Safe to touch glfd->fd as we
- still have not glfs_fd_bind() yet.
- */
- fd_unref (glfd->fd);
- glfd->fd = NULL;
- }
+ if (glfd->fd) {
+ /* Retry. Safe to touch glfd->fd as we
+ still have not glfs_fd_bind() yet.
+ */
+ fd_unref(glfd->fd);
+ glfd->fd = NULL;
+ }
- glfd->fd = fd_create (loc.inode, getpid());
- if (!glfd->fd) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ glfd->fd = fd_create(loc.inode, getpid());
+ if (!glfd->fd) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
- ret = syncop_opendir (subvol, &loc, glfd->fd, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_opendir(subvol, &loc, glfd->fd, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (ret && glfd) {
- glfs_fd_destroy (glfd);
- glfd = NULL;
- } else if (glfd) {
- fd_bind (glfd->fd);
- glfs_fd_bind (glfd);
- }
+ if (ret && glfd) {
+ GF_REF_PUT(glfd);
+ glfd = NULL;
+ } else if (glfd) {
+ glfd_set_state_bind(glfd);
+ }
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return glfd;
+ return glfd;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_opendir, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_closedir, 3.4.0)
int
-pub_glfs_closedir (struct glfs_fd *glfd)
+pub_glfs_closedir(struct glfs_fd *glfd)
{
- int ret = -1;
+ int ret = -1;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
- gf_dirent_free (list_entry (&glfd->entries, gf_dirent_t, list));
+ gf_dirent_free(list_entry(&glfd->entries, gf_dirent_t, list));
- glfs_fd_destroy (glfd);
+ glfs_mark_glfd_for_deletion(glfd);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
- ret = 0;
+ ret = 0;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_closedir, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_telldir, 3.4.0)
long
-pub_glfs_telldir (struct glfs_fd *fd)
+pub_glfs_telldir(struct glfs_fd *fd)
{
- return fd->offset;
-}
-
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_telldir, 3.4.0);
+ if (fd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+ return fd->offset;
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_seekdir, 3.4.0)
void
-pub_glfs_seekdir (struct glfs_fd *fd, long offset)
+pub_glfs_seekdir(struct glfs_fd *fd, long offset)
{
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
- if (fd->offset == offset)
- return;
+ if (fd == NULL) {
+ errno = EBADF;
+ return;
+ }
- fd->offset = offset;
- fd->next = NULL;
+ if (fd->offset == offset)
+ return;
- list_for_each_entry_safe (entry, tmp, &fd->entries, list) {
- if (entry->d_off != offset)
- continue;
+ fd->offset = offset;
+ fd->next = NULL;
- if (&tmp->list != &fd->entries) {
- /* found! */
- fd->next = tmp;
- return;
- }
- }
- /* could not find entry at requested offset in the cache.
- next readdir_r() will result in glfd_entry_refresh()
- */
-}
-
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_seekdir, 3.4.0);
+ list_for_each_entry_safe(entry, tmp, &fd->entries, list)
+ {
+ if (entry->d_off != offset)
+ continue;
+ if (&tmp->list != &fd->entries) {
+ /* found! */
+ fd->next = tmp;
+ return;
+ }
+ }
+ /* could not find entry at requested offset in the cache.
+ next readdir_r() will result in glfd_entry_refresh()
+ */
+}
-int
-pub_glfs_discard_async (struct glfs_fd *glfd, off_t offset, size_t len,
- glfs_io_cbk fn, void *data)
+static int
+glfs_discard_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *preop_stbuf, struct iatt *postop_stbuf,
+ dict_t *xdata)
{
- struct glfs_io *gio = NULL;
- int ret = -1;
+ glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, preop_stbuf,
+ postop_stbuf);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
- if (!gio) {
- errno = ENOMEM;
- goto out;
- }
-
- gio->op = GF_FOP_DISCARD;
- gio->glfd = glfd;
- gio->offset = offset;
- gio->count = len;
- gio->fn = fn;
- gio->data = data;
-
- ret = synctask_new (pub_glfs_from_glfd (glfd)->ctx->env,
- glfs_io_async_task, glfs_io_async_cbk,
- NULL, gio);
-
- if (ret) {
- GF_FREE (gio->iov);
- GF_FREE (gio);
- }
+ return 0;
+}
+static int
+glfs_discard_async_common(struct glfs_fd *glfd, off_t offset, size_t len,
+ gf_boolean_t oldcb, glfs_io_cbk fn, void *data)
+{
+ struct glfs_io *gio = NULL;
+ int ret = -1;
+ call_frame_t *frame = NULL;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ /* Need to take explicit ref so that the fd
+ * is not destroyed before the fop is complete
+ */
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ errno = EBADFD;
+ goto out;
+ }
+
+ frame = syncop_create_frame(THIS);
+ if (!frame) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio = GF_CALLOC(1, sizeof(*gio), glfs_mt_glfs_io_t);
+ if (!gio) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio->op = GF_FOP_DISCARD;
+ gio->glfd = glfd;
+ gio->offset = offset;
+ gio->count = len;
+ gio->oldcb = oldcb;
+ gio->fn = fn;
+ gio->data = data;
+
+ frame->local = gio;
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ STACK_WIND_COOKIE(frame, glfs_discard_async_cbk, subvol, subvol,
+ subvol->fops->discard, fd, offset, len, fop_attr);
+
+ ret = 0;
out:
- __GLFS_EXIT_FS;
+ if (ret) {
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ GF_FREE(gio);
+ if (frame)
+ STACK_DESTROY(frame->root);
+ glfs_subvol_done(glfd->fs, subvol);
+ }
+
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard_async, 3.5.0);
-
-
+GFAPI_SYMVER_PUBLIC(glfs_discard_async35, glfs_discard_async, 3.5.0)
int
-pub_glfs_zerofill_async (struct glfs_fd *glfd, off_t offset, off_t len,
- glfs_io_cbk fn, void *data)
+pub_glfs_discard_async35(struct glfs_fd *glfd, off_t offset, size_t len,
+ glfs_io_cbk34 fn, void *data)
{
- struct glfs_io *gio = NULL;
- int ret = -1;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t);
- if (!gio) {
- errno = ENOMEM;
- goto out;
- }
+ return glfs_discard_async_common(glfd, offset, len, _gf_true, (void *)fn,
+ data);
+}
- gio->op = GF_FOP_ZEROFILL;
- gio->glfd = glfd;
- gio->offset = offset;
- gio->count = len;
- gio->fn = fn;
- gio->data = data;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard_async, 6.0)
+int
+pub_glfs_discard_async(struct glfs_fd *glfd, off_t offset, size_t len,
+ glfs_io_cbk fn, void *data)
+{
+ return glfs_discard_async_common(glfd, offset, len, _gf_false, fn, data);
+}
- ret = synctask_new (pub_glfs_from_glfd (glfd)->ctx->env,
- glfs_io_async_task, glfs_io_async_cbk,
- NULL, gio);
+static int
+glfs_zerofill_async_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *preop_stbuf, struct iatt *postop_stbuf,
+ dict_t *xdata)
+{
+ glfs_io_async_cbk(op_ret, op_errno, frame, cookie, NULL, 0, preop_stbuf,
+ postop_stbuf);
- if (ret) {
- GF_FREE (gio->iov);
- GF_FREE (gio);
- }
+ return 0;
+}
+static int
+glfs_zerofill_async_common(struct glfs_fd *glfd, off_t offset, off_t len,
+ gf_boolean_t oldcb, glfs_io_cbk fn, void *data)
+{
+ struct glfs_io *gio = NULL;
+ int ret = -1;
+ call_frame_t *frame = NULL;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ /* Need to take explicit ref so that the fd
+ * is not destroyed before the fop is complete
+ */
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ errno = EBADFD;
+ goto out;
+ }
+
+ frame = syncop_create_frame(THIS);
+ if (!frame) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio = GF_CALLOC(1, sizeof(*gio), glfs_mt_glfs_io_t);
+ if (!gio) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gio->op = GF_FOP_ZEROFILL;
+ gio->glfd = glfd;
+ gio->offset = offset;
+ gio->count = len;
+ gio->oldcb = oldcb;
+ gio->fn = fn;
+ gio->data = data;
+
+ frame->local = gio;
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ STACK_WIND_COOKIE(frame, glfs_zerofill_async_cbk, subvol, subvol,
+ subvol->fops->zerofill, fd, offset, len, fop_attr);
+ ret = 0;
out:
- __GLFS_EXIT_FS;
+ if (ret) {
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ GF_FREE(gio);
+ if (frame)
+ STACK_DESTROY(frame->root);
+ glfs_subvol_done(glfd->fs, subvol);
+ }
+ if (fop_attr)
+ dict_unref(fop_attr);
+
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill_async, 3.5.0);
+GFAPI_SYMVER_PUBLIC(glfs_zerofill_async35, glfs_zerofill_async, 3.5.0)
+int
+pub_glfs_zerofill_async35(struct glfs_fd *glfd, off_t offset, off_t len,
+ glfs_io_cbk34 fn, void *data)
+{
+ return glfs_zerofill_async_common(glfd, offset, len, _gf_true, (void *)fn,
+ data);
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill_async, 6.0)
+int
+pub_glfs_zerofill_async(struct glfs_fd *glfd, off_t offset, off_t len,
+ glfs_io_cbk fn, void *data)
+{
+ return glfs_zerofill_async_common(glfd, offset, len, _gf_false, fn, data);
+}
void
-gf_dirent_to_dirent (gf_dirent_t *gf_dirent, struct dirent *dirent)
+gf_dirent_to_dirent(gf_dirent_t *gf_dirent, struct dirent *dirent)
{
- dirent->d_ino = gf_dirent->d_ino;
+ dirent->d_ino = gf_dirent->d_ino;
#ifdef _DIRENT_HAVE_D_OFF
- dirent->d_off = gf_dirent->d_off;
+ dirent->d_off = gf_dirent->d_off;
#endif
#ifdef _DIRENT_HAVE_D_TYPE
- dirent->d_type = gf_dirent->d_type;
+ dirent->d_type = gf_dirent->d_type;
#endif
#ifdef _DIRENT_HAVE_D_NAMLEN
- dirent->d_namlen = strlen (gf_dirent->d_name);
+ dirent->d_namlen = strlen(gf_dirent->d_name);
#endif
- strncpy (dirent->d_name, gf_dirent->d_name, NAME_MAX);
- dirent->d_name[NAME_MAX] = 0;
-}
-
-
-int
-glfd_entry_refresh (struct glfs_fd *glfd, int plus)
-{
- xlator_t *subvol = NULL;
- gf_dirent_t entries;
- gf_dirent_t old;
- gf_dirent_t *entry = NULL;
- int ret = -1;
- fd_t *fd = NULL;
-
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
-
- if (fd->inode->ia_type != IA_IFDIR) {
- ret = -1;
- errno = EBADF;
- goto out;
- }
-
- INIT_LIST_HEAD (&entries.list);
- INIT_LIST_HEAD (&old.list);
-
- if (plus)
- ret = syncop_readdirp (subvol, fd, 131072, glfd->offset,
- &entries, NULL, NULL);
- else
- ret = syncop_readdir (subvol, fd, 131072, glfd->offset,
- &entries, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret >= 0) {
- if (plus) {
- /**
- * Set inode_needs_lookup flag before linking the
- * inode. Doing it later post linkage might lead
- * to a race where a fop comes after inode link
- * but before setting need_lookup flag.
- */
- list_for_each_entry (entry, &glfd->entries, list) {
- if (entry->inode)
- inode_set_need_lookup (entry->inode, THIS);
- }
-
- gf_link_inodes_from_dirent (THIS, fd->inode, &entries);
+ snprintf(dirent->d_name, NAME_MAX + 1, "%s", gf_dirent->d_name);
+}
+
+int
+glfd_entry_refresh(struct glfs_fd *glfd, int plus)
+{
+ xlator_t *subvol = NULL;
+ gf_dirent_t entries;
+ gf_dirent_t old;
+ gf_dirent_t *entry = NULL;
+ int ret = -1;
+ fd_t *fd = NULL;
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ if (fd->inode->ia_type != IA_IFDIR) {
+ ret = -1;
+ errno = EBADF;
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&entries.list);
+ INIT_LIST_HEAD(&old.list);
+
+ if (plus)
+ ret = syncop_readdirp(subvol, fd, 131072, glfd->offset, &entries, NULL,
+ NULL);
+ else
+ ret = syncop_readdir(subvol, fd, 131072, glfd->offset, &entries, NULL,
+ NULL);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret >= 0) {
+ if (plus) {
+ list_for_each_entry(entry, &entries.list, list)
+ {
+ if ((!entry->inode && (!IA_ISDIR(entry->d_stat.ia_type))) ||
+ ((entry->d_stat.ia_ctime == 0) &&
+ strcmp(entry->d_name, ".") &&
+ strcmp(entry->d_name, ".."))) {
+ /* entry->inode for directories will be
+ * always set to null to force a lookup
+ * on the dentry. Hence to not degrade
+ * readdir performance, we skip lookups
+ * for directory entries. Also we will have
+ * proper stat if directory present on
+ * hashed subvolume.
+ *
+ * In addition, if the stat is invalid, force
+ * lookup to fetch proper stat.
+ */
+ gf_fill_iatt_for_dirent(entry, fd->inode, subvol);
}
+ }
- list_splice_init (&glfd->entries, &old.list);
- list_splice_init (&entries.list, &glfd->entries);
+ gf_link_inodes_from_dirent(THIS, fd->inode, &entries);
+ }
- /* spurious errno is dangerous for glfd_entry_next() */
- errno = 0;
- }
+ list_splice_init(&glfd->entries, &old.list);
+ list_splice_init(&entries.list, &glfd->entries);
+ /* spurious errno is dangerous for glfd_entry_next() */
+ errno = 0;
+ }
- if (ret > 0)
- glfd->next = list_entry (glfd->entries.next, gf_dirent_t, list);
+ if (ret > 0)
+ glfd->next = list_entry(glfd->entries.next, gf_dirent_t, list);
- gf_dirent_free (&old);
+ gf_dirent_free(&old);
out:
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- return ret;
+ return ret;
}
-
gf_dirent_t *
-glfd_entry_next (struct glfs_fd *glfd, int plus)
+glfd_entry_next(struct glfs_fd *glfd, int plus)
{
- gf_dirent_t *entry = NULL;
- int ret = -1;
+ gf_dirent_t *entry = NULL;
+ int ret = -1;
- if (!glfd->offset || !glfd->next) {
- ret = glfd_entry_refresh (glfd, plus);
- if (ret < 0)
- return NULL;
- }
+ if (!glfd->offset || !glfd->next) {
+ ret = glfd_entry_refresh(glfd, plus);
+ if (ret < 0)
+ return NULL;
+ }
- entry = glfd->next;
- if (!entry)
- return NULL;
+ entry = glfd->next;
+ if (!entry)
+ return NULL;
- if (&entry->next->list == &glfd->entries)
- glfd->next = NULL;
- else
- glfd->next = entry->next;
+ if (&entry->next->list == &glfd->entries)
+ glfd->next = NULL;
+ else
+ glfd->next = entry->next;
- glfd->offset = entry->d_off;
+ glfd->offset = entry->d_off;
- return entry;
+ return entry;
}
-
-static struct dirent *
-glfs_readdirbuf_get (struct glfs_fd *glfd)
+struct dirent *
+glfs_readdirbuf_get(struct glfs_fd *glfd)
{
- struct dirent *buf = NULL;
-
- LOCK (&glfd->fd->lock);
- {
- buf = glfd->readdirbuf;
- if (buf) {
- memset (buf, 0, READDIRBUF_SIZE);
- goto unlock;
- }
-
- buf = GF_CALLOC (1, READDIRBUF_SIZE, glfs_mt_readdirbuf_t);
- if (!buf) {
- errno = ENOMEM;
- goto unlock;
- }
+ struct dirent *buf = NULL;
+
+ LOCK(&glfd->fd->lock);
+ {
+ buf = glfd->readdirbuf;
+ if (buf) {
+ memset(buf, 0, READDIRBUF_SIZE);
+ goto unlock;
+ }
- glfd->readdirbuf = buf;
+ buf = GF_CALLOC(1, READDIRBUF_SIZE, glfs_mt_readdirbuf_t);
+ if (!buf) {
+ errno = ENOMEM;
+ goto unlock;
}
+
+ glfd->readdirbuf = buf;
+ }
unlock:
- UNLOCK (&glfd->fd->lock);
+ UNLOCK(&glfd->fd->lock);
- return buf;
+ return buf;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus_r, 3.4.0)
int
-pub_glfs_readdirplus_r (struct glfs_fd *glfd, struct stat *stat,
- struct dirent *ext, struct dirent **res)
+pub_glfs_readdirplus_r(struct glfs_fd *glfd, struct stat *stat,
+ struct dirent *ext, struct dirent **res)
{
- int ret = 0;
- gf_dirent_t *entry = NULL;
- struct dirent *buf = NULL;
+ int ret = 0;
+ gf_dirent_t *entry = NULL;
+ struct dirent *buf = NULL;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
- errno = 0;
+ GF_REF_GET(glfd);
- if (ext)
- buf = ext;
- else
- buf = glfs_readdirbuf_get (glfd);
+ errno = 0;
- if (!buf) {
- errno = ENOMEM;
- ret = -1;
- goto out;
- }
+ if (ext)
+ buf = ext;
+ else
+ buf = glfs_readdirbuf_get(glfd);
- entry = glfd_entry_next (glfd, !!stat);
- if (errno)
- ret = -1;
+ if (!buf) {
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
- if (res) {
- if (entry)
- *res = buf;
- else
- *res = NULL;
- }
+ entry = glfd_entry_next(glfd, !!stat);
+ if (errno)
+ ret = -1;
- if (entry) {
- gf_dirent_to_dirent (entry, buf);
- if (stat)
- glfs_iatt_to_stat (glfd->fs, &entry->d_stat, stat);
- }
+ if (res) {
+ if (entry)
+ *res = buf;
+ else
+ *res = NULL;
+ }
+
+ if (entry) {
+ gf_dirent_to_dirent(entry, buf);
+ if (stat)
+ glfs_iatt_to_stat(glfd->fs, &entry->d_stat, stat);
+ }
out:
- __GLFS_EXIT_FS;
+ if (glfd)
+ GF_REF_PUT(glfd);
+
+ __GLFS_EXIT_FS;
- return ret;
+ return ret;
invalid_fs:
- return -1;
+ return -1;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus_r, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir_r, 3.4.0)
int
-pub_glfs_readdir_r (struct glfs_fd *glfd, struct dirent *buf,
- struct dirent **res)
+pub_glfs_readdir_r(struct glfs_fd *glfd, struct dirent *buf,
+ struct dirent **res)
{
- return pub_glfs_readdirplus_r (glfd, 0, buf, res);
+ return pub_glfs_readdirplus_r(glfd, 0, buf, res);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir_r, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus, 3.5.0)
struct dirent *
-pub_glfs_readdirplus (struct glfs_fd *glfd, struct stat *stat)
+pub_glfs_readdirplus(struct glfs_fd *glfd, struct stat *stat)
{
- struct dirent *res = NULL;
- int ret = -1;
+ struct dirent *res = NULL;
+ int ret = -1;
- ret = pub_glfs_readdirplus_r (glfd, stat, NULL, &res);
- if (ret)
- return NULL;
+ ret = pub_glfs_readdirplus_r(glfd, stat, NULL, &res);
+ if (ret)
+ return NULL;
- return res;
+ return res;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdirplus, 3.5.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir, 3.5.0)
struct dirent *
-pub_glfs_readdir (struct glfs_fd *glfd)
+pub_glfs_readdir(struct glfs_fd *glfd)
{
- return pub_glfs_readdirplus (glfd, NULL);
+ return pub_glfs_readdirplus(glfd, NULL);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_readdir, 3.5.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_statvfs, 3.4.0)
int
-pub_glfs_statvfs (struct glfs *fs, const char *path, struct statvfs *buf)
+pub_glfs_statvfs(struct glfs *fs, const char *path, struct statvfs *buf)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = syncop_statfs (subvol, &loc, buf, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_statfs(subvol, &loc, buf, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_statvfs, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setattr, 6.0)
int
-glfs_setattr (struct glfs *fs, const char *path, struct iatt *iatt,
- int valid, int follow)
+pub_glfs_setattr(struct glfs *fs, const char *path, struct glfs_stat *stat,
+ int follow)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt riatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ int glvalid;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt riatt = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ GF_VALIDATE_OR_GOTO("glfs_setattr", stat, out);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &riatt, reval);
- else
- ret = glfs_lresolve (fs, subvol, path, &loc, &riatt, reval);
+ if (follow)
+ ret = glfs_resolve(fs, subvol, path, &loc, &riatt, reval);
+ else
+ ret = glfs_lresolve(fs, subvol, path, &loc, &riatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = syncop_setattr (subvol, &loc, iatt, valid, 0, 0, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ glfs_iatt_from_statx(&iatt, stat);
+ glfsflags_from_gfapiflags(stat, &glvalid);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ /* TODO : Add leaseid */
+ ret = syncop_setattr(subvol, &loc, &iatt, glvalid, 0, 0, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetattr, 6.0)
int
-glfs_fsetattr (struct glfs_fd *glfd, struct iatt *iatt, int valid)
+pub_glfs_fsetattr(struct glfs_fd *glfd, struct glfs_stat *stat)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
-
- ret = syncop_fsetattr (subvol, fd, iatt, valid, 0, 0, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ int ret = -1;
+ int glvalid;
+ struct iatt iatt = {
+ 0,
+ };
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ GF_VALIDATE_OR_GOTO("glfs_fsetattr", stat, out);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ glfs_iatt_from_statx(&iatt, stat);
+ glfsflags_from_gfapiflags(stat, &glvalid);
+
+ /* TODO : Add leaseid */
+ ret = syncop_fsetattr(subvol, fd, &iatt, glvalid, 0, 0, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chmod, 3.4.0)
int
-pub_glfs_chmod (struct glfs *fs, const char *path, mode_t mode)
+pub_glfs_chmod(struct glfs *fs, const char *path, mode_t mode)
{
- int ret = -1;
- struct iatt iatt = {0, };
- int valid = 0;
+ int ret = -1;
+ struct glfs_stat stat = {
+ 0,
+ };
- iatt.ia_prot = ia_prot_from_st_mode (mode);
- valid = GF_SET_ATTR_MODE;
+ stat.glfs_st_mode = mode;
+ stat.glfs_st_mask = GLFS_STAT_MODE;
- ret = glfs_setattr (fs, path, &iatt, valid, 1);
+ ret = glfs_setattr(fs, path, &stat, 1);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chmod, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchmod, 3.4.0)
int
-pub_glfs_fchmod (struct glfs_fd *glfd, mode_t mode)
+pub_glfs_fchmod(struct glfs_fd *glfd, mode_t mode)
{
- int ret = -1;
- struct iatt iatt = {0, };
- int valid = 0;
+ int ret = -1;
+ struct glfs_stat stat = {
+ 0,
+ };
- iatt.ia_prot = ia_prot_from_st_mode (mode);
- valid = GF_SET_ATTR_MODE;
+ stat.glfs_st_mode = mode;
+ stat.glfs_st_mask = GLFS_STAT_MODE;
- ret = glfs_fsetattr (glfd, &iatt, valid);
+ ret = glfs_fsetattr(glfd, &stat);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchmod, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chown, 3.4.0)
int
-pub_glfs_chown (struct glfs *fs, const char *path, uid_t uid, gid_t gid)
+pub_glfs_chown(struct glfs *fs, const char *path, uid_t uid, gid_t gid)
{
- int ret = 0;
- int valid = 0;
- struct iatt iatt = {0, };
+ int ret = 0;
+ struct glfs_stat stat = {
+ 0,
+ };
- if (uid != (uid_t) -1) {
- iatt.ia_uid = uid;
- valid = GF_SET_ATTR_UID;
- }
+ if (uid != (uid_t)-1) {
+ stat.glfs_st_uid = uid;
+ stat.glfs_st_mask = GLFS_STAT_UID;
+ }
- if (gid != (uid_t) -1) {
- iatt.ia_gid = gid;
- valid = valid | GF_SET_ATTR_GID;
- }
+ if (gid != (uid_t)-1) {
+ stat.glfs_st_gid = gid;
+ stat.glfs_st_mask = stat.glfs_st_mask | GLFS_STAT_GID;
+ }
- if (valid)
- ret = glfs_setattr (fs, path, &iatt, valid, 1);
+ if (stat.glfs_st_mask)
+ ret = glfs_setattr(fs, path, &stat, 1);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chown, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lchown, 3.4.0)
int
-pub_glfs_lchown (struct glfs *fs, const char *path, uid_t uid, gid_t gid)
+pub_glfs_lchown(struct glfs *fs, const char *path, uid_t uid, gid_t gid)
{
- int ret = 0;
- int valid = 0;
- struct iatt iatt = {0, };
+ int ret = 0;
+ struct glfs_stat stat = {
+ 0,
+ };
- if (uid != (uid_t) -1) {
- iatt.ia_uid = uid;
- valid = GF_SET_ATTR_UID;
- }
+ if (uid != (uid_t)-1) {
+ stat.glfs_st_uid = uid;
+ stat.glfs_st_mask = GLFS_STAT_UID;
+ }
- if (gid != (uid_t) -1) {
- iatt.ia_gid = gid;
- valid = valid | GF_SET_ATTR_GID;
- }
+ if (gid != (uid_t)-1) {
+ stat.glfs_st_gid = gid;
+ stat.glfs_st_mask = stat.glfs_st_mask | GLFS_STAT_GID;
+ }
- if (valid)
- ret = glfs_setattr (fs, path, &iatt, valid, 0);
+ if (stat.glfs_st_mask)
+ ret = glfs_setattr(fs, path, &stat, 0);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lchown, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchown, 3.4.0)
int
-pub_glfs_fchown (struct glfs_fd *glfd, uid_t uid, gid_t gid)
+pub_glfs_fchown(struct glfs_fd *glfd, uid_t uid, gid_t gid)
{
- int ret = 0;
- int valid = 0;
- struct iatt iatt = {0, };
+ int ret = 0;
+ struct glfs_stat stat = {
+ 0,
+ };
- if (uid != (uid_t) -1) {
- iatt.ia_uid = uid;
- valid = GF_SET_ATTR_UID;
- }
+ if (uid != (uid_t)-1) {
+ stat.glfs_st_uid = uid;
+ stat.glfs_st_mask = GLFS_STAT_UID;
+ }
- if (gid != (uid_t) -1) {
- iatt.ia_gid = gid;
- valid = valid | GF_SET_ATTR_GID;
- }
+ if (gid != (uid_t)-1) {
+ stat.glfs_st_gid = gid;
+ stat.glfs_st_mask = stat.glfs_st_mask | GLFS_STAT_GID;
+ }
- if (valid)
- ret = glfs_fsetattr (glfd, &iatt, valid);
+ if (stat.glfs_st_mask)
+ ret = glfs_fsetattr(glfd, &stat);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchown, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_utimens, 3.4.0)
int
-pub_glfs_utimens (struct glfs *fs, const char *path, struct timespec times[2])
+pub_glfs_utimens(struct glfs *fs, const char *path,
+ const struct timespec times[2])
{
- int ret = -1;
- int valid = 0;
- struct iatt iatt = {0, };
+ int ret = -1;
+ struct glfs_stat stat = {
+ 0,
+ };
- iatt.ia_atime = times[0].tv_sec;
- iatt.ia_atime_nsec = times[0].tv_nsec;
- iatt.ia_mtime = times[1].tv_sec;
- iatt.ia_mtime_nsec = times[1].tv_nsec;
+ stat.glfs_st_atime = times[0];
+ stat.glfs_st_mtime = times[1];
- valid = GF_SET_ATTR_ATIME|GF_SET_ATTR_MTIME;
+ stat.glfs_st_mask = GLFS_STAT_ATIME | GLFS_STAT_MTIME;
- ret = glfs_setattr (fs, path, &iatt, valid, 1);
+ ret = glfs_setattr(fs, path, &stat, 1);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_utimens, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lutimens, 3.4.0)
int
-pub_glfs_lutimens (struct glfs *fs, const char *path, struct timespec times[2])
+pub_glfs_lutimens(struct glfs *fs, const char *path,
+ const struct timespec times[2])
{
- int ret = -1;
- int valid = 0;
- struct iatt iatt = {0, };
+ int ret = -1;
+ struct glfs_stat stat = {
+ 0,
+ };
- iatt.ia_atime = times[0].tv_sec;
- iatt.ia_atime_nsec = times[0].tv_nsec;
- iatt.ia_mtime = times[1].tv_sec;
- iatt.ia_mtime_nsec = times[1].tv_nsec;
+ stat.glfs_st_atime = times[0];
+ stat.glfs_st_mtime = times[1];
- valid = GF_SET_ATTR_ATIME|GF_SET_ATTR_MTIME;
+ stat.glfs_st_mask = GLFS_STAT_ATIME | GLFS_STAT_MTIME;
- ret = glfs_setattr (fs, path, &iatt, valid, 0);
+ ret = glfs_setattr(fs, path, &stat, 0);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lutimens, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_futimens, 3.4.0)
int
-pub_glfs_futimens (struct glfs_fd *glfd, struct timespec times[2])
+pub_glfs_futimens(struct glfs_fd *glfd, const struct timespec times[2])
{
- int ret = -1;
- int valid = 0;
- struct iatt iatt = {0, };
+ int ret = -1;
+ struct glfs_stat stat = {
+ 0,
+ };
- iatt.ia_atime = times[0].tv_sec;
- iatt.ia_atime_nsec = times[0].tv_nsec;
- iatt.ia_mtime = times[1].tv_sec;
- iatt.ia_mtime_nsec = times[1].tv_nsec;
+ stat.glfs_st_atime = times[0];
+ stat.glfs_st_mtime = times[1];
- valid = GF_SET_ATTR_ATIME|GF_SET_ATTR_MTIME;
+ stat.glfs_st_mask = GLFS_STAT_ATIME | GLFS_STAT_MTIME;
- ret = glfs_fsetattr (glfd, &iatt, valid);
+ ret = glfs_fsetattr(glfd, &stat);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_futimens, 3.4.0);
-
-
int
-glfs_getxattr_process (void *value, size_t size, dict_t *xattr,
- const char *name)
+glfs_getxattr_process(void *value, size_t size, dict_t *xattr, const char *name)
{
- data_t *data = NULL;
- int ret = -1;
-
- data = dict_get (xattr, (char *)name);
- if (!data) {
- errno = ENODATA;
- ret = -1;
- goto out;
- }
-
- ret = data->len;
- if (!value || !size)
- goto out;
-
- if (size < ret) {
- ret = -1;
- errno = ERANGE;
- goto out;
- }
-
- memcpy (value, data->data, ret);
+ data_t *data = NULL;
+ int ret = -1;
+
+ data = dict_get(xattr, (char *)name);
+ if (!data) {
+ errno = ENODATA;
+ ret = -1;
+ goto out;
+ }
+
+ ret = data->len;
+ if (!value || !size)
+ goto out;
+
+ if (size < ret) {
+ ret = -1;
+ errno = ERANGE;
+ goto out;
+ }
+
+ memcpy(value, data->data, ret);
out:
- if (xattr)
- dict_unref (xattr);
- return ret;
+ return ret;
}
-
ssize_t
-glfs_getxattr_common (struct glfs *fs, const char *path, const char *name,
- void *value, size_t size, int follow)
-{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- dict_t *xattr = NULL;
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+glfs_getxattr_common(struct glfs *fs, const char *path, const char *name,
+ void *value, size_t size, int follow)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ dict_t *xattr = NULL;
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ if (!name || *name == '\0') {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ if (strlen(name) > GF_XATTR_NAME_MAX) {
+ ret = -1;
+ errno = ENAMETOOLONG;
+ goto out;
+ }
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
retry:
- if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
- else
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ if (follow)
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
+ else
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = syncop_getxattr (subvol, &loc, &xattr, name, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_getxattr(subvol, &loc, &xattr, name, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = glfs_getxattr_process (value, size, xattr, name);
+ ret = glfs_getxattr_process(value, size, xattr, name);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ if (xattr)
+ dict_unref(xattr);
- __GLFS_EXIT_FS;
+ glfs_subvol_done(fs, subvol);
+
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getxattr, 3.4.0)
ssize_t
-pub_glfs_getxattr (struct glfs *fs, const char *path, const char *name,
- void *value, size_t size)
+pub_glfs_getxattr(struct glfs *fs, const char *path, const char *name,
+ void *value, size_t size)
{
- return glfs_getxattr_common (fs, path, name, value, size, 1);
+ return glfs_getxattr_common(fs, path, name, value, size, 1);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getxattr, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lgetxattr, 3.4.0)
ssize_t
-pub_glfs_lgetxattr (struct glfs *fs, const char *path, const char *name,
- void *value, size_t size)
+pub_glfs_lgetxattr(struct glfs *fs, const char *path, const char *name,
+ void *value, size_t size)
{
- return glfs_getxattr_common (fs, path, name, value, size, 0);
+ return glfs_getxattr_common(fs, path, name, value, size, 0);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lgetxattr, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fgetxattr, 3.4.0)
ssize_t
-pub_glfs_fgetxattr (struct glfs_fd *glfd, const char *name, void *value,
- size_t size)
+pub_glfs_fgetxattr(struct glfs_fd *glfd, const char *name, void *value,
+ size_t size)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- dict_t *xattr = NULL;
- fd_t *fd = NULL;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
-
- ret = syncop_fgetxattr (subvol, fd, &xattr, name, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret)
- goto out;
-
- ret = glfs_getxattr_process (value, size, xattr, name);
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ dict_t *xattr = NULL;
+ fd_t *fd = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ if (!name || *name == '\0') {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ if (strlen(name) > GF_XATTR_NAME_MAX) {
+ ret = -1;
+ errno = ENAMETOOLONG;
+ goto out;
+ }
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = syncop_fgetxattr(subvol, fd, &xattr, name, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret)
+ goto out;
+
+ ret = glfs_getxattr_process(value, size, xattr, name);
out:
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (xattr)
+ dict_unref(xattr);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fgetxattr, 3.4.0);
-
-
int
-glfs_listxattr_process (void *value, size_t size, dict_t *xattr)
+glfs_listxattr_process(void *value, size_t size, dict_t *xattr)
{
- int ret = -1;
+ int ret = -1;
- if (!xattr)
- goto out;
+ if (!xattr)
+ goto out;
- ret = dict_keys_join (NULL, 0, xattr, NULL);
+ ret = dict_keys_join(NULL, 0, xattr, NULL);
- if (!value || !size)
- goto out;
+ if (!value || !size)
+ goto out;
- if (size < ret) {
- ret = -1;
- errno = ERANGE;
- } else {
- dict_keys_join (value, size, xattr, NULL);
- }
+ if (size < ret) {
+ ret = -1;
+ errno = ERANGE;
+ } else {
+ dict_keys_join(value, size, xattr, NULL);
+ }
out:
- if (xattr)
- dict_unref (xattr);
-
- return ret;
+ return ret;
}
-
ssize_t
-glfs_listxattr_common (struct glfs *fs, const char *path, void *value,
- size_t size, int follow)
-{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- dict_t *xattr = NULL;
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+glfs_listxattr_common(struct glfs *fs, const char *path, void *value,
+ size_t size, int follow)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ dict_t *xattr = NULL;
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
- else
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ if (follow)
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
+ else
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = syncop_getxattr (subvol, &loc, &xattr, NULL, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_getxattr(subvol, &loc, &xattr, NULL, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = glfs_listxattr_process (value, size, xattr);
+ ret = glfs_listxattr_process(value, size, xattr);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
+
+ if (xattr)
+ dict_unref(xattr);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_listxattr, 3.4.0)
ssize_t
-pub_glfs_listxattr (struct glfs *fs, const char *path, void *value, size_t size)
+pub_glfs_listxattr(struct glfs *fs, const char *path, void *value, size_t size)
{
- return glfs_listxattr_common (fs, path, value, size, 1);
+ return glfs_listxattr_common(fs, path, value, size, 1);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_listxattr, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_llistxattr, 3.4.0)
ssize_t
-pub_glfs_llistxattr (struct glfs *fs, const char *path, void *value, size_t size)
+pub_glfs_llistxattr(struct glfs *fs, const char *path, void *value, size_t size)
{
- return glfs_listxattr_common (fs, path, value, size, 0);
+ return glfs_listxattr_common(fs, path, value, size, 0);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_llistxattr, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_flistxattr, 3.4.0)
ssize_t
-pub_glfs_flistxattr (struct glfs_fd *glfd, void *value, size_t size)
+pub_glfs_flistxattr(struct glfs_fd *glfd, void *value, size_t size)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- dict_t *xattr = NULL;
- fd_t *fd = NULL;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
-
- ret = syncop_fgetxattr (subvol, fd, &xattr, NULL, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret)
- goto out;
-
- ret = glfs_listxattr_process (value, size, xattr);
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ dict_t *xattr = NULL;
+ fd_t *fd = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = syncop_fgetxattr(subvol, fd, &xattr, NULL, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret)
+ goto out;
+
+ ret = glfs_listxattr_process(value, size, xattr);
out:
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (xattr)
+ dict_unref(xattr);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_flistxattr, 3.4.0);
-
int
-glfs_setxattr_common (struct glfs *fs, const char *path, const char *name,
- const void *value, size_t size, int flags, int follow)
+glfs_setxattr_common(struct glfs *fs, const char *path, const char *name,
+ const void *value, size_t size, int flags, int follow)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- dict_t *xattr = NULL;
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ dict_t *xattr = NULL;
+ int reval = 0;
+ void *value_cp = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ if (!name || *name == '\0') {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ if (strlen(name) > GF_XATTR_NAME_MAX) {
+ ret = -1;
+ errno = ENAMETOOLONG;
+ goto out;
+ }
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
retry:
- if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
- else
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ if (follow)
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
+ else
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- xattr = dict_for_key_value (name, value, size);
- if (!xattr) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ value_cp = gf_memdup(value, size);
+ GF_CHECK_ALLOC_AND_LOG(subvol->name, value_cp, ret,
+ "Failed to"
+ " duplicate setxattr value",
+ out);
- ret = syncop_setxattr (subvol, &loc, xattr, flags, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ xattr = dict_for_key_value(name, value_cp, size, _gf_false);
+ if (!xattr) {
+ GF_FREE(value_cp);
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ret = syncop_setxattr(subvol, &loc, xattr, flags, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- loc_wipe (&loc);
- if (xattr)
- dict_unref (xattr);
+ loc_wipe(&loc);
+ if (xattr)
+ dict_unref(xattr);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setxattr, 3.4.0)
int
-pub_glfs_setxattr (struct glfs *fs, const char *path, const char *name,
- const void *value, size_t size, int flags)
+pub_glfs_setxattr(struct glfs *fs, const char *path, const char *name,
+ const void *value, size_t size, int flags)
{
- return glfs_setxattr_common (fs, path, name, value, size, flags, 1);
+ return glfs_setxattr_common(fs, path, name, value, size, flags, 1);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setxattr, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lsetxattr, 3.4.0)
int
-pub_glfs_lsetxattr (struct glfs *fs, const char *path, const char *name,
- const void *value, size_t size, int flags)
+pub_glfs_lsetxattr(struct glfs *fs, const char *path, const char *name,
+ const void *value, size_t size, int flags)
{
- return glfs_setxattr_common (fs, path, name, value, size, flags, 0);
+ return glfs_setxattr_common(fs, path, name, value, size, flags, 0);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lsetxattr, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetxattr, 3.4.0)
int
-pub_glfs_fsetxattr (struct glfs_fd *glfd, const char *name, const void *value,
- size_t size, int flags)
+pub_glfs_fsetxattr(struct glfs_fd *glfd, const char *name, const void *value,
+ size_t size, int flags)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- dict_t *xattr = NULL;
- fd_t *fd = NULL;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
-
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
-
- xattr = dict_for_key_value (name, value, size);
- if (!xattr) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- ret = syncop_fsetxattr (subvol, fd, xattr, flags, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ dict_t *xattr = NULL;
+ fd_t *fd = NULL;
+ void *value_cp = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ if (!name || *name == '\0') {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ if (strlen(name) > GF_XATTR_NAME_MAX) {
+ ret = -1;
+ errno = ENAMETOOLONG;
+ goto out;
+ }
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ value_cp = gf_memdup(value, size);
+ GF_CHECK_ALLOC_AND_LOG(subvol->name, value_cp, ret,
+ "Failed to"
+ " duplicate setxattr value",
+ out);
+
+ xattr = dict_for_key_value(name, value_cp, size, _gf_false);
+ if (!xattr) {
+ GF_FREE(value_cp);
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = syncop_fsetxattr(subvol, fd, xattr, flags, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- if (xattr)
- dict_unref (xattr);
+ if (xattr)
+ dict_unref(xattr);
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fsetxattr, 3.4.0);
-
-
int
-glfs_removexattr_common (struct glfs *fs, const char *path, const char *name,
- int follow)
+glfs_removexattr_common(struct glfs *fs, const char *path, const char *name,
+ int follow)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
retry:
- if (follow)
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
- else
- ret = glfs_lresolve (fs, subvol, path, &loc, &iatt, reval);
+ if (follow)
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
+ else
+ ret = glfs_lresolve(fs, subvol, path, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = syncop_removexattr (subvol, &loc, name, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_removexattr(subvol, &loc, name, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_removexattr, 3.4.0)
int
-pub_glfs_removexattr (struct glfs *fs, const char *path, const char *name)
+pub_glfs_removexattr(struct glfs *fs, const char *path, const char *name)
{
- return glfs_removexattr_common (fs, path, name, 1);
+ return glfs_removexattr_common(fs, path, name, 1);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_removexattr, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lremovexattr, 3.4.0)
int
-pub_glfs_lremovexattr (struct glfs *fs, const char *path, const char *name)
+pub_glfs_lremovexattr(struct glfs *fs, const char *path, const char *name)
{
- return glfs_removexattr_common (fs, path, name, 0);
+ return glfs_removexattr_common(fs, path, name, 0);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lremovexattr, 3.4.0);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fremovexattr, 3.4.0)
+int
+pub_glfs_fremovexattr(struct glfs_fd *glfd, const char *name)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = syncop_fremovexattr(subvol, fd, name, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+out:
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+
+ glfs_subvol_done(glfd->fs, subvol);
+ __GLFS_EXIT_FS;
+invalid_fs:
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fallocate, 3.5.0)
int
-pub_glfs_fremovexattr (struct glfs_fd *glfd, const char *name)
+pub_glfs_fallocate(struct glfs_fd *glfd, int keep_size, off_t offset,
+ size_t len)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_fallocate(subvol, fd, keep_size, offset, len, fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
+out:
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (fop_attr)
+ dict_unref(fop_attr);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ glfs_subvol_done(glfd->fs, subvol);
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ __GLFS_EXIT_FS;
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+invalid_fs:
+ return ret;
+}
- ret = syncop_fremovexattr (subvol, fd, name, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard, 3.5.0)
+int
+pub_glfs_discard(struct glfs_fd *glfd, off_t offset, size_t len)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_discard(subvol, fd, offset, len, fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- if (fd)
- fd_unref (fd);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (fop_attr)
+ dict_unref(fop_attr);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fremovexattr, 3.4.0);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill, 3.5.0)
+int
+pub_glfs_zerofill(struct glfs_fd *glfd, off_t offset, off_t len)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ dict_t *fop_attr = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ errno = EBADFD;
+ goto out;
+ }
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_zerofill(subvol, fd, offset, len, fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
+out:
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+ if (fop_attr)
+ dict_unref(fop_attr);
+ glfs_subvol_done(glfd->fs, subvol);
+ __GLFS_EXIT_FS;
+
+invalid_fs:
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chdir, 3.4.0)
int
-pub_glfs_fallocate (struct glfs_fd *glfd, int keep_size, off_t offset, size_t len)
+pub_glfs_chdir(struct glfs *fs, const char *path)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+retry:
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
+
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ if (ret)
+ goto out;
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ if (!IA_ISDIR(iatt.ia_type)) {
+ ret = -1;
+ errno = ENOTDIR;
+ goto out;
+ }
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+ glfs_cwd_set(fs, loc.inode);
- ret = syncop_fallocate (subvol, fd, keep_size, offset, len, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
out:
- if (fd)
- fd_unref(fd);
+ loc_wipe(&loc);
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fallocate, 3.5.0);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchdir, 3.4.0)
+int
+pub_glfs_fchdir(struct glfs_fd *glfd)
+{
+ int ret = -1;
+ inode_t *inode = NULL;
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ inode = fd->inode;
+
+ if (!IA_ISDIR(inode->ia_type)) {
+ ret = -1;
+ errno = ENOTDIR;
+ goto out;
+ }
+
+ glfs_cwd_set(glfd->fs, inode);
+ ret = 0;
+out:
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+
+ glfs_subvol_done(glfd->fs, subvol);
+ __GLFS_EXIT_FS;
-int
-pub_glfs_discard (struct glfs_fd *glfd, off_t offset, size_t len)
+invalid_fs:
+ return ret;
+}
+
+static gf_boolean_t warn_realpath = _gf_true; /* log once */
+
+static char *
+glfs_realpath_common(struct glfs *fs, const char *path, char *resolved_path,
+ gf_boolean_t warn_deprecated)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
+ int ret = -1;
+ char *retpath = NULL;
+ char *allocpath = NULL;
+ xlator_t *subvol = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int reval = 0;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ if (resolved_path)
+ retpath = resolved_path;
+ else if (warn_deprecated) {
+ retpath = allocpath = malloc(PATH_MAX + 1);
+ if (warn_realpath) {
+ warn_realpath = _gf_false;
+ gf_log(THIS->name, GF_LOG_WARNING,
+ "this application "
+ "is compiled against an old version of "
+ "libgfapi, it should use glfs_free() to "
+ "release the path returned by "
+ "glfs_realpath()");
+ }
+ } else {
+ retpath = allocpath = GLFS_CALLOC(1, PATH_MAX + 1, NULL,
+ glfs_mt_realpath_t);
+ }
+
+ if (!retpath) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+retry:
+ ret = glfs_resolve(fs, subvol, path, &loc, &iatt, reval);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry);
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ if (ret)
+ goto out;
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+ if (loc.path) {
+ snprintf(retpath, PATH_MAX + 1, "%s", loc.path);
+ }
- ret = syncop_discard (subvol, fd, offset, len, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
out:
- if (fd)
- fd_unref(fd);
+ loc_wipe(&loc);
+
+ if (ret == -1) {
+ if (warn_deprecated && allocpath)
+ free(allocpath);
+ else if (allocpath)
+ GLFS_FREE(allocpath);
+ retpath = NULL;
+ }
- glfs_subvol_done (glfd->fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return retpath;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_discard, 3.5.0);
+GFAPI_SYMVER_PUBLIC(glfs_realpath34, glfs_realpath, 3.4.0)
+char *
+pub_glfs_realpath34(struct glfs *fs, const char *path, char *resolved_path)
+{
+ return glfs_realpath_common(fs, path, resolved_path, _gf_true);
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_realpath, 3.7.17)
+char *
+pub_glfs_realpath(struct glfs *fs, const char *path, char *resolved_path)
+{
+ return glfs_realpath_common(fs, path, resolved_path, _gf_false);
+}
-int
-pub_glfs_zerofill (struct glfs_fd *glfd, off_t offset, off_t len)
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getcwd, 3.4.0)
+char *
+pub_glfs_getcwd(struct glfs *fs, char *buf, size_t n)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
+ int ret = -1;
+ inode_t *inode = NULL;
+ char *path = NULL;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- errno = EIO;
- goto out;
- }
+ if (!buf || n < 2) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- errno = EBADFD;
- goto out;
- }
+ inode = glfs_cwd_get(fs);
- ret = syncop_zerofill (subvol, fd, offset, len, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ if (!inode) {
+ strncpy(buf, "/", n);
+ ret = 0;
+ goto out;
+ }
+
+ ret = inode_path(inode, 0, &path);
+ if (n <= ret) {
+ ret = -1;
+ errno = ERANGE;
+ goto out;
+ }
+
+ strncpy(buf, path, n);
+ ret = 0;
out:
- if (fd)
- fd_unref(fd);
+ GF_FREE(path);
- glfs_subvol_done (glfd->fs, subvol);
+ if (inode)
+ inode_unref(inode);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
-}
+ if (ret < 0)
+ return NULL;
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_zerofill, 3.5.0);
+ return buf;
+}
+static void
+gf_flock_to_flock(struct gf_flock *gf_flock, struct flock *flock)
+{
+ flock->l_type = gf_flock->l_type;
+ flock->l_whence = gf_flock->l_whence;
+ flock->l_start = gf_flock->l_start;
+ flock->l_len = gf_flock->l_len;
+ flock->l_pid = gf_flock->l_pid;
+}
-int
-pub_glfs_chdir (struct glfs *fs, const char *path)
+static void
+gf_flock_from_flock(struct gf_flock *gf_flock, struct flock *flock)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
+ gf_flock->l_type = flock->l_type;
+ gf_flock->l_whence = flock->l_whence;
+ gf_flock->l_start = flock->l_start;
+ gf_flock->l_len = flock->l_len;
+ gf_flock->l_pid = flock->l_pid;
+}
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+static int
+glfs_lock_common(struct glfs_fd *glfd, int cmd, struct flock *flock,
+ dict_t *xdata)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ struct gf_flock gf_flock = {
+ 0,
+ };
+ struct gf_flock saved_flock = {
+ 0,
+ };
+ fd_t *fd = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ if (!flock) {
+ errno = EINVAL;
+ goto out;
+ }
+
+ GF_REF_GET(glfd);
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ /* Generate glusterfs flock structure from client flock
+ * structure to be processed by server */
+ gf_flock_from_flock(&gf_flock, flock);
+
+ /* Keep another copy of flock for split/merge of locks
+ * at client side */
+ gf_flock_from_flock(&saved_flock, flock);
+
+ if (glfd->lk_owner.len != 0) {
+ ret = syncopctx_setfslkowner(&glfd->lk_owner);
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-retry:
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+ if (ret)
+ goto out;
+ }
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ ret = get_fop_attr_thrd_key(&xdata);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
- if (ret)
- goto out;
+ ret = syncop_lk(subvol, fd, cmd, &gf_flock, xdata, NULL);
+ DECODE_SYNCOP_ERR(ret);
- if (!IA_ISDIR (iatt.ia_type)) {
- ret = -1;
- errno = ENOTDIR;
- goto out;
- }
+ /* Convert back from gf_flock to flock as expected by application */
+ gf_flock_to_flock(&gf_flock, flock);
- glfs_cwd_set (fs, loc.inode);
+ if (ret == 0 && (cmd == F_SETLK || cmd == F_SETLKW)) {
+ ret = fd_lk_insert_and_merge(fd, cmd, &saved_flock);
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0,
+ API_MSG_LOCK_INSERT_MERGE_FAILED, "gfid=%s",
+ uuid_utoa(fd->inode->gfid), NULL);
+ ret = 0;
+ }
+ }
out:
- loc_wipe (&loc);
+ if (fd)
+ fd_unref(fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_chdir, 3.4.0);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_file_lock, 4.0.0)
+int
+pub_glfs_file_lock(struct glfs_fd *glfd, int cmd, struct flock *flock,
+ glfs_lock_mode_t lk_mode)
+{
+ int ret = -1;
+ dict_t *xdata_in = NULL;
+
+ if (lk_mode == GLFS_LK_MANDATORY) {
+ /* Create a new dictionary */
+ xdata_in = dict_new();
+ if (xdata_in == NULL) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+ /* Set GF_LK_MANDATORY internally within dictionary to map
+ * GLFS_LK_MANDATORY */
+ ret = dict_set_uint32(xdata_in, GF_LOCK_MODE, GF_LK_MANDATORY);
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0,
+ API_MSG_SETTING_LOCK_TYPE_FAILED, NULL);
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ ret = glfs_lock_common(glfd, cmd, flock, xdata_in);
+out:
+ if (xdata_in)
+ dict_unref(xdata_in);
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_posix_lock, 3.4.0)
int
-pub_glfs_fchdir (struct glfs_fd *glfd)
+pub_glfs_posix_lock(struct glfs_fd *glfd, int cmd, struct flock *flock)
{
- int ret = -1;
- inode_t *inode = NULL;
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
+ return glfs_lock_common(glfd, cmd, flock, NULL);
+}
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fd_set_lkowner, 3.10.7)
+int
+pub_glfs_fd_set_lkowner(struct glfs_fd *glfd, void *data, int len)
+{
+ int ret = -1;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ if (!GF_REF_GET(glfd)) {
+ goto invalid_fs;
+ }
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+ GF_VALIDATE_OR_GOTO(THIS->name, data, out);
- inode = fd->inode;
+ if ((len <= 0) || (len > GFAPI_MAX_LOCK_OWNER_LEN)) {
+ errno = EINVAL;
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ARG,
+ "lk_owner len=%d", len, NULL);
+ goto out;
+ }
- if (!IA_ISDIR (inode->ia_type)) {
- ret = -1;
- errno = ENOTDIR;
- goto out;
- }
+ glfd->lk_owner.len = len;
- glfs_cwd_set (glfd->fs, inode);
- ret = 0;
+ memcpy(glfd->lk_owner.data, data, len);
+
+ ret = 0;
out:
- if (fd)
- fd_unref (fd);
+ if (glfd)
+ GF_REF_PUT(glfd);
- glfs_subvol_done (glfd->fs, subvol);
+ __GLFS_EXIT_FS;
- __GLFS_EXIT_FS;
+invalid_fs:
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_dup, 3.4.0)
+struct glfs_fd *
+pub_glfs_dup(struct glfs_fd *glfd)
+{
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ struct glfs_fd *dupfd = NULL;
+ struct glfs *fs = NULL;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ fs = glfd->fs;
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(fs, subvol, glfd);
+ if (!fd) {
+ errno = EBADFD;
+ goto out;
+ }
+
+ dupfd = glfs_fd_new(fs);
+ if (!dupfd) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ dupfd->fd = fd_ref(fd);
+ dupfd->state = glfd->state;
+out:
+ if (fd)
+ fd_unref(fd);
+ if (dupfd)
+ glfs_fd_bind(dupfd);
+ if (glfd)
+ GF_REF_PUT(glfd);
+
+ glfs_subvol_done(fs, subvol);
+
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return dupfd;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fchdir, 3.4.0);
+static void
+glfs_enqueue_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data)
+{
+ int ret = -1;
+ upcall_entry *u_list = NULL;
+ if (!fs || !upcall_data)
+ goto out;
-char *
-pub_glfs_realpath (struct glfs *fs, const char *path, char *resolved_path)
-{
- int ret = -1;
- char *retpath = NULL;
- char *allocpath = NULL;
- xlator_t *subvol = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int reval = 0;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- if (resolved_path)
- retpath = resolved_path;
- else
- retpath = allocpath = malloc (PATH_MAX + 1);
-
- if (!retpath) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-retry:
- ret = glfs_resolve (fs, subvol, path, &loc, &iatt, reval);
+ u_list = GF_CALLOC(1, sizeof(*u_list), glfs_mt_upcall_entry_t);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
+ if (!u_list) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, "entry",
+ NULL);
+ goto out;
+ }
- if (ret)
- goto out;
+ INIT_LIST_HEAD(&u_list->upcall_list);
- if (loc.path) {
- strncpy (retpath, loc.path, PATH_MAX);
- retpath[PATH_MAX] = 0;
- }
+ gf_uuid_copy(u_list->upcall_data.gfid, upcall_data->gfid);
+ u_list->upcall_data.event_type = upcall_data->event_type;
-out:
- loc_wipe (&loc);
+ switch (upcall_data->event_type) {
+ case GF_UPCALL_CACHE_INVALIDATION:
+ ret = glfs_get_upcall_cache_invalidation(&u_list->upcall_data,
+ upcall_data);
+ break;
+ case GF_UPCALL_RECALL_LEASE:
+ ret = glfs_get_upcall_lease(&u_list->upcall_data, upcall_data);
+ break;
+ default:
+ break;
+ }
- if (ret == -1) {
- if (allocpath)
- free (allocpath);
- retpath = NULL;
- }
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY, NULL);
+ goto out;
+ }
- glfs_subvol_done (fs, subvol);
+ pthread_mutex_lock(&fs->upcall_list_mutex);
+ {
+ list_add_tail(&u_list->upcall_list, &fs->upcall_list);
+ }
+ pthread_mutex_unlock(&fs->upcall_list_mutex);
- __GLFS_EXIT_FS;
+ ret = 0;
-invalid_fs:
- return retpath;
+out:
+ if (ret && u_list) {
+ GF_FREE(u_list->upcall_data.data);
+ GF_FREE(u_list);
+ }
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_realpath, 3.4.0);
+static void
+glfs_free_upcall_lease(void *to_free)
+{
+ struct glfs_upcall_lease *arg = to_free;
+ if (!arg)
+ return;
-char *
-pub_glfs_getcwd (struct glfs *fs, char *buf, size_t n)
+ if (arg->object)
+ glfs_h_close(arg->object);
+
+ GF_FREE(arg);
+}
+
+int
+glfs_recall_lease_fd(struct glfs *fs, struct gf_upcall *up_data)
{
- int ret = -1;
- inode_t *inode = NULL;
- char *path = NULL;
+ struct gf_upcall_recall_lease *recall_lease = NULL;
+ xlator_t *subvol = NULL;
+ int ret = 0;
+ inode_t *inode = NULL;
+ struct glfs_fd *glfd = NULL;
+ struct glfs_fd *tmp = NULL;
+ struct list_head glfd_list;
+ fd_t *fd = NULL;
+ uint64_t value = 0;
+ struct glfs_lease lease = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO("gfapi", up_data, out);
+ GF_VALIDATE_OR_GOTO("gfapi", fs, out);
+
+ recall_lease = up_data->data;
+ GF_VALIDATE_OR_GOTO("gfapi", recall_lease, out);
+
+ INIT_LIST_HEAD(&glfd_list);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ gf_msg_debug(THIS->name, 0, "Recall lease received for gfid:%s",
+ uuid_utoa(up_data->gfid));
+
+ inode = inode_find(subvol->itable, up_data->gfid);
+ if (!inode) {
+ ret = -1;
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INODE_FIND_FAILED,
+ "gfid=%s", uuid_utoa(up_data->gfid), "graph_id=%d",
+ subvol->graph->id, NULL);
+ goto out;
+ }
+
+ LOCK(&inode->lock);
+ {
+ list_for_each_entry(fd, &inode->fd_list, inode_list)
+ {
+ ret = fd_ctx_get(fd, subvol, &value);
+ glfd = (struct glfs_fd *)(uintptr_t)value;
+ if (glfd) {
+ gf_msg_trace(THIS->name, 0, "glfd (%p) has held lease", glfd);
+ GF_REF_GET(glfd);
+ list_add_tail(&glfd->list, &glfd_list);
+ }
+ }
+ }
+ UNLOCK(&inode->lock);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ if (!list_empty(&glfd_list)) {
+ list_for_each_entry_safe(glfd, tmp, &glfd_list, list)
+ {
+ LOCK(&glfd->lock);
+ {
+ if (glfd->state != GLFD_CLOSE) {
+ gf_msg_trace(THIS->name, 0,
+ "glfd (%p) has held lease, "
+ "calling recall cbk",
+ glfd);
+ glfd->cbk(lease, glfd->cookie);
+ }
+ }
+ UNLOCK(&glfd->lock);
- if (!buf || n < 2) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
+ list_del_init(&glfd->list);
+ GF_REF_PUT(glfd);
+ }
+ }
- inode = glfs_cwd_get (fs);
+out:
+ return ret;
+}
- if (!inode) {
- strncpy (buf, "/", n);
- ret = 0;
- goto out;
- }
+static int
+glfs_recall_lease_upcall(struct glfs *fs, struct glfs_upcall *up_arg,
+ struct gf_upcall *up_data)
+{
+ struct gf_upcall_recall_lease *recall_lease = NULL;
+ struct glfs_object *object = NULL;
+ xlator_t *subvol = NULL;
+ int ret = -1;
+ struct glfs_upcall_lease *up_lease_arg = NULL;
+
+ GF_VALIDATE_OR_GOTO("gfapi", up_data, out);
+ GF_VALIDATE_OR_GOTO("gfapi", fs, out);
+
+ recall_lease = up_data->data;
+ GF_VALIDATE_OR_GOTO("gfapi", recall_lease, out);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
+
+ gf_msg_debug(THIS->name, 0, "Recall lease received for gfid:%s",
+ uuid_utoa(up_data->gfid));
+
+ object = glfs_h_find_handle(fs, up_data->gfid, GFAPI_HANDLE_LENGTH);
+ if (!object) {
+ /* The reason handle creation will fail is because we
+ * couldn't find the inode in the gfapi inode table.
+ *
+ * But since application would have taken inode_ref, the
+ * only case when this can happen is when it has closed
+ * the handle and hence will no more be interested in
+ * the upcall for this particular gfid.
+ */
+ gf_smsg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_CREATE_HANDLE_FAILED,
+ "gfid=%s", uuid_utoa(up_data->gfid), NULL);
+ errno = ESTALE;
+ goto out;
+ }
- ret = inode_path (inode, 0, &path);
- if (n <= ret) {
- ret = -1;
- errno = ERANGE;
- goto out;
- }
+ up_lease_arg = GF_CALLOC(1, sizeof(struct glfs_upcall_lease),
+ glfs_mt_upcall_inode_t);
+ up_lease_arg->object = object;
- strncpy (buf, path, n);
- ret = 0;
-out:
- GF_FREE (path);
+ GF_VALIDATE_OR_GOTO("glfs_recall_lease", up_lease_arg, out);
- if (inode)
- inode_unref (inode);
+ up_lease_arg->lease_type = recall_lease->lease_type;
- __GLFS_EXIT_FS;
+ up_arg->reason = GLFS_UPCALL_RECALL_LEASE;
+ up_arg->event = up_lease_arg;
+ up_arg->free_event = glfs_free_upcall_lease;
-invalid_fs:
- if (ret < 0)
- return NULL;
+ ret = 0;
- return buf;
+out:
+ if (ret) {
+ /* Close p_object and oldp_object as well if being referenced.*/
+ if (object)
+ glfs_h_close(object);
+
+ /* Set reason to prevent applications from using ->event */
+ up_arg->reason = GF_UPCALL_EVENT_NULL;
+ }
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_getcwd, 3.4.0);
+static int
+upcall_syncop_args_free(struct upcall_syncop_args *args)
+{
+ dict_t *dict = NULL;
+ struct gf_upcall *upcall_data = NULL;
+ if (args) {
+ upcall_data = &args->upcall_data;
+ switch (upcall_data->event_type) {
+ case GF_UPCALL_CACHE_INVALIDATION:
+ dict = ((struct gf_upcall_cache_invalidation *)(upcall_data
+ ->data))
+ ->dict;
+ break;
+ case GF_UPCALL_RECALL_LEASE:
+ dict = ((struct gf_upcall_recall_lease *)(upcall_data->data))
+ ->dict;
+ break;
+ }
+ if (dict)
+ dict_unref(dict);
+
+ GF_FREE(upcall_data->client_uid);
+ GF_FREE(upcall_data->data);
+ }
+ GF_FREE(args);
+ return 0;
+}
-static void
-gf_flock_to_flock (struct gf_flock *gf_flock, struct flock *flock)
+static int
+glfs_upcall_syncop_cbk(int ret, call_frame_t *frame, void *opaque)
{
- flock->l_type = gf_flock->l_type;
- flock->l_whence = gf_flock->l_whence;
- flock->l_start = gf_flock->l_start;
- flock->l_len = gf_flock->l_len;
- flock->l_pid = gf_flock->l_pid;
-}
+ struct upcall_syncop_args *args = opaque;
+ (void)upcall_syncop_args_free(args);
-static void
-gf_flock_from_flock (struct gf_flock *gf_flock, struct flock *flock)
-{
- gf_flock->l_type = flock->l_type;
- gf_flock->l_whence = flock->l_whence;
- gf_flock->l_start = flock->l_start;
- gf_flock->l_len = flock->l_len;
- gf_flock->l_pid = flock->l_pid;
+ return 0;
}
+static int
+glfs_cbk_upcall_syncop(void *opaque)
+{
+ struct upcall_syncop_args *args = opaque;
+ struct gf_upcall *upcall_data = NULL;
+ struct glfs_upcall *up_arg = NULL;
+ struct glfs *fs;
+ int ret = -1;
+
+ fs = args->fs;
+ upcall_data = &args->upcall_data;
+
+ if (!upcall_data) {
+ goto out;
+ }
+
+ up_arg = GLFS_CALLOC(1, sizeof(struct gf_upcall), glfs_release_upcall,
+ glfs_mt_upcall_entry_t);
+ if (!up_arg) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, "entry",
+ NULL);
+ goto out;
+ }
+
+ switch (upcall_data->event_type) {
+ case GF_UPCALL_CACHE_INVALIDATION:
+ ret = glfs_h_poll_cache_invalidation(fs, up_arg, upcall_data);
+ break;
+ case GF_UPCALL_RECALL_LEASE:
+ ret = glfs_recall_lease_upcall(fs, up_arg, upcall_data);
+ break;
+ default:
+ errno = EINVAL;
+ }
+
+ /* It could so happen that the file which got
+ * upcall notification may have got deleted by
+ * the same client. In such cases up_arg->reason
+ * is set to GLFS_UPCALL_EVENT_NULL. No need to
+ * send upcall then
+ */
+ if (up_arg->reason == GLFS_UPCALL_EVENT_NULL) {
+ gf_smsg(THIS->name, GF_LOG_DEBUG, errno,
+ API_MSG_UPCALL_EVENT_NULL_RECEIVED, NULL);
+ ret = 0;
+ GLFS_FREE(up_arg);
+ goto out;
+ } else if (ret) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY, NULL);
+ GLFS_FREE(up_arg);
+ goto out;
+ }
+
+ if (fs->up_cbk && up_arg)
+ (fs->up_cbk)(up_arg, fs->up_data);
-int
-pub_glfs_posix_lock (struct glfs_fd *glfd, int cmd, struct flock *flock)
+ /* application takes care of calling glfs_free on up_arg post
+ * their processing */
+
+out:
+ return ret;
+}
+
+static struct gf_upcall_cache_invalidation *
+gf_copy_cache_invalidation(struct gf_upcall_cache_invalidation *src)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- struct gf_flock gf_flock = {0, };
- struct gf_flock saved_flock = {0, };
- fd_t *fd = NULL;
+ struct gf_upcall_cache_invalidation *dst = NULL;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ if (!src)
+ goto out;
- subvol = glfs_active_subvol (glfd->fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ dst = GF_CALLOC(1, sizeof(struct gf_upcall_cache_invalidation),
+ glfs_mt_upcall_entry_t);
- fd = glfs_resolve_fd (glfd->fs, subvol, glfd);
- if (!fd) {
- ret = -1;
- errno = EBADFD;
- goto out;
- }
+ if (!dst) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, "entry",
+ NULL);
+ goto out;
+ }
- gf_flock_from_flock (&gf_flock, flock);
- gf_flock_from_flock (&saved_flock, flock);
- ret = syncop_lk (subvol, fd, cmd, &gf_flock, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- gf_flock_to_flock (&gf_flock, flock);
+ dst->flags = src->flags;
+ dst->expire_time_attr = src->expire_time_attr;
+ dst->stat = src->stat;
+ dst->p_stat = src->p_stat;
+ dst->oldp_stat = src->oldp_stat;
- if (ret == 0 && (cmd == F_SETLK || cmd == F_SETLKW))
- fd_lk_insert_and_merge (fd, cmd, &saved_flock);
+ if (src->dict)
+ dst->dict = dict_copy_with_ref(src->dict, NULL);
+
+ return dst;
out:
- if (fd)
- fd_unref (fd);
+ return NULL;
+}
- glfs_subvol_done (glfd->fs, subvol);
+static struct gf_upcall_recall_lease *
+gf_copy_recall_lease(struct gf_upcall_recall_lease *src)
+{
+ struct gf_upcall_recall_lease *dst = NULL;
- __GLFS_EXIT_FS;
+ if (!src)
+ goto out;
-invalid_fs:
- return ret;
-}
+ dst = GF_CALLOC(1, sizeof(struct gf_upcall_recall_lease),
+ glfs_mt_upcall_entry_t);
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_posix_lock, 3.4.0);
+ if (!dst) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, "entry",
+ NULL);
+ goto out;
+ }
+ dst->lease_type = src->lease_type;
+ memcpy(dst->tid, src->tid, 16);
-struct glfs_fd *
-pub_glfs_dup (struct glfs_fd *glfd)
+ if (src->dict)
+ dst->dict = dict_copy_with_ref(src->dict, NULL);
+
+ return dst;
+out:
+ return NULL;
+}
+
+static struct upcall_syncop_args *
+upcall_syncop_args_init(struct glfs *fs, struct gf_upcall *upcall_data)
{
- xlator_t *subvol = NULL;
- fd_t *fd = NULL;
- glfs_fd_t *dupfd = NULL;
- struct glfs *fs = NULL;
+ struct upcall_syncop_args *args = NULL;
+ int ret = -1;
+ struct gf_upcall *t_data = NULL;
+
+ if (!fs || !upcall_data)
+ goto out;
+
+ args = GF_CALLOC(1, sizeof(struct upcall_syncop_args),
+ glfs_mt_upcall_entry_t);
+ if (!args) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED,
+ "syncop args", NULL);
+ goto out;
+ }
+
+ /* Note: we are not taking any ref on fs here.
+ * Ideally applications have to unregister for upcall events
+ * or stop polling for upcall events before performing
+ * glfs_fini. And as for outstanding synctasks created, we wait
+ * for all syncenv threads to finish tasks before cleaning up the
+ * fs->ctx. Hence it seems safe to process these callback
+ * notification without taking any lock/ref.
+ */
+ args->fs = fs;
+ t_data = &(args->upcall_data);
+ t_data->client_uid = gf_strdup(upcall_data->client_uid);
+
+ gf_uuid_copy(t_data->gfid, upcall_data->gfid);
+ t_data->event_type = upcall_data->event_type;
+
+ switch (t_data->event_type) {
+ case GF_UPCALL_CACHE_INVALIDATION:
+ t_data->data = gf_copy_cache_invalidation(
+ (struct gf_upcall_cache_invalidation *)upcall_data->data);
+ break;
+ case GF_UPCALL_RECALL_LEASE:
+ t_data->data = gf_copy_recall_lease(
+ (struct gf_upcall_recall_lease *)upcall_data->data);
+ break;
+ }
+
+ if (!t_data->data)
+ goto out;
+
+ return args;
+out:
+ if (ret) {
+ if (args) {
+ GF_FREE(args->upcall_data.client_uid);
+ GF_FREE(args);
+ }
+ }
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
+ return NULL;
+}
- fs = glfd->fs;
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- errno = EIO;
- goto out;
- }
+static void
+glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data)
+{
+ struct upcall_syncop_args *args = NULL;
+ int ret = -1;
- fd = glfs_resolve_fd (fs, subvol, glfd);
- if (!fd) {
- errno = EBADFD;
- goto out;
- }
+ if (!fs || !upcall_data)
+ goto out;
- dupfd = glfs_fd_new (fs);
- if (!dupfd) {
- errno = ENOMEM;
- goto out;
- }
+ if (!(fs->upcall_events & upcall_data->event_type)) {
+ /* ignore events which application hasn't registered*/
+ goto out;
+ }
- dupfd->fd = fd_ref (fd);
-out:
- if (fd)
- fd_unref (fd);
- if (dupfd)
- glfs_fd_bind (dupfd);
+ args = upcall_syncop_args_init(fs, upcall_data);
- glfs_subvol_done (fs, subvol);
+ if (!args)
+ goto out;
- __GLFS_EXIT_FS;
+ ret = synctask_new(THIS->ctx->env, glfs_cbk_upcall_syncop,
+ glfs_upcall_syncop_cbk, NULL, args);
+ /* should we retry incase of failure? */
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_UPCALL_SYNCOP_FAILED,
+ "event_type=%d", upcall_data->event_type, "gfid=%s",
+ (char *)(upcall_data->gfid), NULL);
+ upcall_syncop_args_free(args);
+ }
-invalid_fs:
- return dupfd;
+out:
+ return;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_dup, 3.4.0);
-
/*
* This routine is called in case of any notification received
* from the server. All the upcall events are queued up in a list
* to be read by the applications.
*
- * XXX: Applications may register a cbk function for each 'fs'
- * which then needs to be called by this routine incase of any
- * event received. The cbk fn is responsible for notifying the
+ * In case if the application registers a cbk function, that shall
+ * be called by this routine in case of any event received.
+ * The cbk fn is responsible for notifying the
* applications the way it desires for each event queued (for eg.,
* can raise a signal or broadcast a cond variable etc.)
+ *
+ * Otherwise all the upcall events are queued up in a list
+ * to be read/polled by the applications.
*/
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_process_upcall_event, 3.7.0)
void
-priv_glfs_process_upcall_event (struct glfs *fs, void *data)
+priv_glfs_process_upcall_event(struct glfs *fs, void *data)
{
- int ret = -1;
- upcall_entry *u_list = NULL;
- glusterfs_ctx_t *ctx = NULL;
- struct gf_upcall *upcall_data = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ struct gf_upcall *upcall_data = NULL;
- gf_msg_debug (THIS->name, 0,
- "Upcall gfapi callback is called");
+ DECLARE_OLD_THIS;
- if (!fs || !data)
- goto out;
+ gf_msg_debug(THIS->name, 0, "Upcall gfapi callback is called");
- /* Unlike in I/O path, "glfs_fini" would not have freed
- * 'fs' by the time we take lock as it waits for all epoll
- * threads to exit including this
- */
- pthread_mutex_lock (&fs->mutex);
- {
- ctx = fs->ctx;
+ __GLFS_ENTRY_VALIDATE_FS(fs, err);
- if (ctx->cleanup_started) {
- pthread_mutex_unlock (&fs->mutex);
- goto out;
- }
+ if (!data)
+ goto out;
+
+ /* Unlike in I/O path, "glfs_fini" would not have freed
+ * 'fs' by the time we take lock as it waits for all epoll
+ * threads to exit including this
+ */
+ pthread_mutex_lock(&fs->mutex);
+ {
+ ctx = fs->ctx;
- fs->pin_refcnt++;
+ /* if we're not interested in upcalls (anymore), skip them */
+ if (ctx->cleanup_started || !fs->cache_upcalls) {
+ pthread_mutex_unlock(&fs->mutex);
+ goto out;
}
- pthread_mutex_unlock (&fs->mutex);
+ fs->pin_refcnt++;
+ }
+ pthread_mutex_unlock(&fs->mutex);
+
+ upcall_data = (struct gf_upcall *)data;
+
+ gf_msg_trace(THIS->name, 0, "Upcall gfapi gfid = %s",
+ (char *)(upcall_data->gfid));
+
+ /* *
+ * TODO: RECALL LEASE for each glfd
+ *
+ * In case of RECALL_LEASE, we could associate separate
+ * cbk function for each glfd either by
+ * - extending pub_glfs_lease to accept new args (recall_cbk_fn, cookie)
+ * - or by defining new API "glfs_register_recall_cbk_fn (glfd,
+ * recall_cbk_fn, cookie) . In such cases, flag it and instead of calling
+ * below upcall functions, define a new one to go through the glfd list and
+ * invoke each of theirs recall_cbk_fn.
+ * */
+
+ if (fs->up_cbk) { /* upcall cbk registered */
+ (void)glfs_cbk_upcall_data(fs, upcall_data);
+ } else {
+ (void)glfs_enqueue_upcall_data(fs, upcall_data);
+ }
+
+ pthread_mutex_lock(&fs->mutex);
+ {
+ fs->pin_refcnt--;
+ }
+ pthread_mutex_unlock(&fs->mutex);
- upcall_data = (struct gf_upcall *)data;
+out:
+ __GLFS_EXIT_FS;
+err:
+ return;
+}
- gf_msg_trace (THIS->name, 0, "Upcall gfapi gfid = %s"
- "ret = %d", (char *)(upcall_data->gfid), ret);
+ssize_t
+glfs_anonymous_pwritev(struct glfs *fs, struct glfs_object *object,
+ const struct iovec *iovec, int iovcnt, off_t offset,
+ int flags)
+{
+ xlator_t *subvol = NULL;
+ struct iobref *iobref = NULL;
+ struct iobuf *iobuf = NULL;
+ struct iovec iov = {
+ 0,
+ };
+ inode_t *inode = NULL;
+ fd_t *fd = NULL;
+ int ret = -1;
+ size_t size = -1;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ ret = -1;
+ errno = ESTALE;
+ goto out;
+ }
+
+ fd = fd_anonymous(inode);
+ if (!fd) {
+ ret = -1;
+ gf_smsg("gfapi", GF_LOG_ERROR, ENOMEM, API_MSG_FDCREATE_FAILED, NULL);
+ errno = ENOMEM;
+ goto out;
+ }
+
+ size = iov_length(iovec, iovcnt);
+
+ iobuf = iobuf_get2(subvol->ctx->iobuf_pool, size);
+ if (!iobuf) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ iobref = iobref_new();
+ if (!iobref) {
+ iobuf_unref(iobuf);
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
+
+ ret = iobref_add(iobref, iobuf);
+ if (ret) {
+ iobuf_unref(iobuf);
+ iobref_unref(iobref);
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
+
+ iov_unload(iobuf_ptr(iobuf), iovec, iovcnt);
+
+ iov.iov_base = iobuf_ptr(iobuf);
+ iov.iov_len = size;
+
+ /* TODO : set leaseid */
+ ret = syncop_writev(subvol, fd, &iov, 1, offset, iobref, flags, NULL, NULL,
+ NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ iobuf_unref(iobuf);
+ iobref_unref(iobref);
+
+ if (ret <= 0)
+ goto out;
- u_list = GF_CALLOC (1, sizeof(*u_list),
- glfs_mt_upcall_entry_t);
+out:
- if (!u_list) {
- gf_msg (THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED,
- "Upcall entry allocation failed.");
- goto out;
- }
+ if (fd)
+ fd_unref(fd);
- INIT_LIST_HEAD (&u_list->upcall_list);
+ if (inode)
+ inode_unref(inode);
- gf_uuid_copy (u_list->upcall_data.gfid, upcall_data->gfid);
- u_list->upcall_data.event_type = upcall_data->event_type;
+ glfs_subvol_done(fs, subvol);
- switch (upcall_data->event_type) {
- case GF_UPCALL_CACHE_INVALIDATION:
- ret = glfs_get_upcall_cache_invalidation (&u_list->upcall_data,
- upcall_data);
- break;
- default:
- goto out;
- }
+ __GLFS_EXIT_FS;
- if (ret) {
- gf_msg (THIS->name, GF_LOG_ERROR, errno,
- API_MSG_INVALID_ENTRY,
- "Upcall entry validation failed.");
- goto out;
- }
+invalid_fs:
+ return ret;
+}
- pthread_mutex_lock (&fs->upcall_list_mutex);
- {
- list_add_tail (&u_list->upcall_list,
- &fs->upcall_list);
- }
- pthread_mutex_unlock (&fs->upcall_list_mutex);
+ssize_t
+glfs_anonymous_preadv(struct glfs *fs, struct glfs_object *object,
+ const struct iovec *iovec, int iovcnt, off_t offset,
+ int flags)
+{
+ xlator_t *subvol = NULL;
+ struct iovec *iov = NULL;
+ struct iobref *iobref = NULL;
+ inode_t *inode = NULL;
+ fd_t *fd = NULL;
+ int cnt = 0;
+ ssize_t ret = -1;
+ ssize_t size = -1;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ ret = -1;
+ errno = ESTALE;
+ goto out;
+ }
+
+ fd = fd_anonymous(inode);
+ if (!fd) {
+ ret = -1;
+ gf_smsg("gfapi", GF_LOG_ERROR, ENOMEM, API_MSG_FDCREATE_FAILED, NULL);
+ errno = ENOMEM;
+ goto out;
+ }
+
+ size = iov_length(iovec, iovcnt);
+
+ /* TODO : set leaseid */
+ ret = syncop_readv(subvol, fd, size, offset, flags, &iov, &cnt, &iobref,
+ NULL, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret <= 0)
+ goto out;
+
+ size = iov_copy(iovec, iovcnt, iov, cnt);
+
+ ret = size;
+out:
+ if (iov)
+ GF_FREE(iov);
+ if (iobref)
+ iobref_unref(iobref);
+ if (fd)
+ fd_unref(fd);
- pthread_mutex_lock (&fs->mutex);
- {
- fs->pin_refcnt--;
- }
- pthread_mutex_unlock (&fs->mutex);
+ if (inode)
+ inode_unref(inode);
- ret = 0;
-out:
- if (ret && u_list)
- GF_FREE(u_list);
- return;
+ glfs_subvol_done(fs, subvol);
+
+ __GLFS_EXIT_FS;
+
+invalid_fs:
+ return ret;
}
-GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_process_upcall_event, 3.7.0);
+static void
+glfs_release_xreaddirp_stat(void *ptr)
+{
+ struct glfs_xreaddirp_stat *to_free = ptr;
-ssize_t
-glfs_anonymous_pwritev (struct glfs *fs, struct glfs_object *object,
- const struct iovec *iovec, int iovcnt,
- off_t offset, int flags)
-{
- xlator_t *subvol = NULL;
- struct iobref *iobref = NULL;
- struct iobuf *iobuf = NULL;
- struct iovec iov = {0, };
- inode_t *inode = NULL;
- fd_t *fd = NULL;
- int ret = -1;
- size_t size = -1;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ if (to_free->object)
+ glfs_h_close(to_free->object);
+}
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- ret = -1;
- errno = ESTALE;
- goto out;
- }
+/*
+ * Given glfd of a directory, this function does readdirp and returns
+ * xstat along with dirents.
+ */
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_r, 3.11.0)
+int
+pub_glfs_xreaddirplus_r(struct glfs_fd *glfd, uint32_t flags,
+ struct glfs_xreaddirp_stat **xstat_p,
+ struct dirent *ext, struct dirent **res)
+{
+ int ret = -1;
+ gf_dirent_t *entry = NULL;
+ struct dirent *buf = NULL;
+ struct glfs_xreaddirp_stat *xstat = NULL;
- fd = fd_anonymous (inode);
- if (!fd) {
- ret = -1;
- gf_msg ("gfapi", GF_LOG_ERROR, ENOMEM, API_MSG_FDCREATE_FAILED,
- "Allocating anonymous fd failed");
- errno = ENOMEM;
- goto out;
- }
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
- size = iov_length (iovec, iovcnt);
+ GF_REF_GET(glfd);
- iobuf = iobuf_get2 (subvol->ctx->iobuf_pool, size);
- if (!iobuf) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ GF_VALIDATE_OR_GOTO(THIS->name, xstat_p, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, res, out);
- iobref = iobref_new ();
- if (!iobref) {
- iobuf_unref (iobuf);
- errno = ENOMEM;
- ret = -1;
- goto out;
- }
+ errno = 0;
- ret = iobref_add (iobref, iobuf);
- if (ret) {
- iobuf_unref (iobuf);
- iobref_unref (iobref);
- errno = ENOMEM;
- ret = -1;
- goto out;
- }
+ if (ext)
+ buf = ext;
+ else
+ buf = glfs_readdirbuf_get(glfd);
- iov_unload (iobuf_ptr (iobuf), iovec, iovcnt);
+ if (!buf)
+ goto out;
- iov.iov_base = iobuf_ptr (iobuf);
- iov.iov_len = size;
+ xstat = GLFS_CALLOC(1, sizeof(struct glfs_xreaddirp_stat),
+ glfs_release_xreaddirp_stat, glfs_mt_xreaddirp_stat_t);
- ret = syncop_writev (subvol, fd, &iov, 1, offset, iobref, flags,
- NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ if (!xstat)
+ goto out;
- iobuf_unref (iobuf);
- iobref_unref (iobref);
+ /* this is readdirplus operation */
+ entry = glfd_entry_next(glfd, 1);
- if (ret <= 0)
- goto out;
+ /* XXX: Ideally when we reach EOD, errno should have been
+ * set to ENOENT. But that doesn't seem to be the case.
+ *
+ * The only way to confirm if its EOD at this point is that
+ * errno == 0 and entry == NULL
+ */
+ if (errno)
+ goto out;
+
+ if (!entry) {
+ /* reached EOD, ret = 0 */
+ ret = 0;
+ *res = NULL;
+ *xstat_p = NULL;
+
+ /* free xstat as applications shall not be using it */
+ GLFS_FREE(xstat);
+
+ goto out;
+ }
+
+ *res = buf;
+ gf_dirent_to_dirent(entry, buf);
+
+ if (flags & GFAPI_XREADDIRP_STAT) {
+ glfs_iatt_to_stat(glfd->fs, &entry->d_stat, &xstat->st);
+ xstat->flags_handled |= GFAPI_XREADDIRP_STAT;
+ }
+
+ if ((flags & GFAPI_XREADDIRP_HANDLE) &&
+ /* skip . and .. */
+ strcmp(buf->d_name, ".") && strcmp(buf->d_name, "..")) {
+ /* Now create object.
+ * We can use "glfs_h_find_handle" as well as inodes would have
+ * already got linked as part of 'gf_link_inodes_from_dirent' */
+ xstat->object = glfs_h_create_from_handle(
+ glfd->fs, entry->d_stat.ia_gfid, GFAPI_HANDLE_LENGTH, NULL);
+
+ if (xstat->object) { /* success */
+ /* note: xstat->object->inode->ref is taken
+ * This shall be unref'ed when application does
+ * glfs_free(xstat) */
+ xstat->flags_handled |= GFAPI_XREADDIRP_HANDLE;
+ }
+ }
+
+ ret = xstat->flags_handled;
+ *xstat_p = xstat;
+
+ gf_msg_debug(THIS->name, 0,
+ "xreaddirp- requested_flags (%x) , processed_flags (%x)",
+ flags, xstat->flags_handled);
out:
+ GF_REF_PUT(glfd);
- if (fd)
- fd_unref(fd);
+ if (ret < 0) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, errno, API_MSG_XREADDIRP_R_FAILED,
+ "reason=%s", strerror(errno), NULL);
+
+ if (xstat)
+ GLFS_FREE(xstat);
+ }
- glfs_subvol_done (fs, subvol);
+ __GLFS_EXIT_FS;
- __GLFS_EXIT_FS;
+ return ret;
invalid_fs:
- return ret;
+ return -1;
}
-ssize_t
-glfs_anonymous_preadv (struct glfs *fs, struct glfs_object *object,
- const struct iovec *iovec, int iovcnt,
- off_t offset, int flags)
-{
- xlator_t *subvol = NULL;
- struct iovec *iov = NULL;
- struct iobref *iobref = NULL;
- inode_t *inode = NULL;
- fd_t *fd = NULL;
- int cnt = 0;
- ssize_t ret = -1;
- ssize_t size = -1;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_stat, 3.11.0)
+struct stat *
+pub_glfs_xreaddirplus_get_stat(struct glfs_xreaddirp_stat *xstat)
+{
+ GF_VALIDATE_OR_GOTO("glfs_xreaddirplus_get_stat", xstat, out);
+
+ if (!xstat->flags_handled & GFAPI_XREADDIRP_STAT)
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_FLAGS_HANDLE,
+ "GFAPI_XREADDIRP_STAT"
+ "xstat=%p",
+ xstat, "handles=%x", xstat->flags_handled, NULL);
+ return &xstat->st;
+
+out:
+ return NULL;
+}
+
+void
+gf_lease_to_glfs_lease(struct gf_lease *gf_lease, struct glfs_lease *lease)
+{
+ u_int lease_type = gf_lease->lease_type;
+ lease->cmd = gf_lease->cmd;
+ lease->lease_type = lease_type;
+ memcpy(lease->lease_id, gf_lease->lease_id, LEASE_ID_SIZE);
+}
+
+void
+glfs_lease_to_gf_lease(struct glfs_lease *lease, struct gf_lease *gf_lease)
+{
+ u_int lease_type = lease->lease_type;
+ gf_lease->cmd = lease->cmd;
+ gf_lease->lease_type = lease_type;
+ memcpy(gf_lease->lease_id, lease->lease_id, LEASE_ID_SIZE);
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lease, 4.0.0)
+int
+pub_glfs_lease(struct glfs_fd *glfd, struct glfs_lease *lease,
+ glfs_recall_cbk fn, void *data)
+{
+ int ret = -1;
+ loc_t loc = {
+ 0,
+ };
+ xlator_t *subvol = NULL;
+ fd_t *fd = NULL;
+ struct gf_lease gf_lease = {
+ 0,
+ };
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FD(glfd, invalid_fs);
+
+ GF_REF_GET(glfd);
+
+ if (!is_valid_lease_id(lease->lease_id)) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ subvol = glfs_active_subvol(glfd->fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ fd = glfs_resolve_fd(glfd->fs, subvol, glfd);
+ if (!fd) {
+ ret = -1;
+ errno = EBADFD;
+ goto out;
+ }
+
+ switch (lease->lease_type) {
+ case GLFS_RD_LEASE:
+ if ((fd->flags != O_RDONLY) && !(fd->flags & O_RDWR)) {
ret = -1;
- errno = EIO;
+ errno = EINVAL;
goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
+ }
+ break;
+ case GLFS_RW_LEASE:
+ if (!((fd->flags & O_WRONLY) || (fd->flags & O_RDWR))) {
ret = -1;
- errno = ESTALE;
+ errno = EINVAL;
goto out;
- }
-
- fd = fd_anonymous (inode);
- if (!fd) {
+ }
+ break;
+ default:
+ if (lease->cmd != GLFS_GET_LEASE) {
ret = -1;
- gf_msg ("gfapi", GF_LOG_ERROR, ENOMEM, API_MSG_FDCREATE_FAILED,
- "Allocating anonymous fd failed");
- errno = ENOMEM;
+ errno = EINVAL;
goto out;
- }
+ }
+ break;
+ }
- size = iov_length (iovec, iovcnt);
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(fd->inode, loc, out);
- ret = syncop_readv (subvol, fd, size, offset, flags, &iov, &cnt,
- &iobref, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret <= 0)
- goto out;
+ glfs_lease_to_gf_lease(lease, &gf_lease);
- size = iov_copy (iovec, iovcnt, iov, cnt);
+ ret = syncop_lease(subvol, &loc, &gf_lease, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ gf_lease_to_glfs_lease(&gf_lease, lease);
+
+ /* TODO: Add leases for client replay
+ if (ret == 0 && (cmd == F_SETLK || cmd == F_SETLKW))
+ fd_lk_insert_and_merge (fd, cmd, &saved_flock);
+ */
+ if (ret == 0) {
+ ret = fd_ctx_set(glfd->fd, subvol, (uint64_t)(long)glfd);
+ if (ret) {
+ gf_smsg(subvol->name, GF_LOG_ERROR, ENOMEM,
+ API_MSG_FDCTX_SET_FAILED, "fd=%p", glfd->fd, NULL);
+ goto out;
+ }
+ glfd->cbk = fn;
+ glfd->cookie = data;
+ }
- ret = size;
out:
- if (iov)
- GF_FREE (iov);
- if (iobref)
- iobref_unref (iobref);
- if (fd)
- fd_unref(fd);
- glfs_subvol_done (fs, subvol);
+ if (glfd)
+ GF_REF_PUT(glfd);
+
+ if (subvol)
+ glfs_subvol_done(glfd->fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c
index 0f201a2b99d..53c2ee896f9 100644
--- a/api/src/glfs-handleops.c
+++ b/api/src/glfs-handleops.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ * Copyright (c) 2013-2018 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
@@ -8,2141 +8,2648 @@
* cases as published by the Free Software Foundation.
*/
-
#include "glfs-internal.h"
#include "glfs-mem-types.h"
-#include "syncop.h"
+#include <glusterfs/syncop.h>
#include "glfs.h"
#include "glfs-handles.h"
#include "gfapi-messages.h"
int
-glfs_listxattr_process (void *value, size_t size, dict_t *xattr);
+glfs_listxattr_process(void *value, size_t size, dict_t *xattr);
-static void
-glfs_iatt_from_stat (struct stat *stat, int valid, struct iatt *iatt,
- int *glvalid)
+void
+glfs_iatt_from_stat(struct stat *stat, int valid, struct iatt *iatt,
+ int *glvalid)
{
- /* validate in args */
- if ((stat == NULL) || (iatt == NULL) || (glvalid == NULL)) {
- errno = EINVAL;
- return;
- }
-
- *glvalid = 0;
-
- if (valid & GFAPI_SET_ATTR_MODE) {
- iatt->ia_prot = ia_prot_from_st_mode (stat->st_mode);
- *glvalid |= GF_SET_ATTR_MODE;
- }
-
- if (valid & GFAPI_SET_ATTR_UID) {
- iatt->ia_uid = stat->st_uid;
- *glvalid |= GF_SET_ATTR_UID;
- }
-
- if (valid & GFAPI_SET_ATTR_GID) {
- iatt->ia_gid = stat->st_gid;
- *glvalid |= GF_SET_ATTR_GID;
- }
-
- if (valid & GFAPI_SET_ATTR_ATIME) {
- iatt->ia_atime = stat->st_atime;
- iatt->ia_atime_nsec = ST_ATIM_NSEC (stat);
- *glvalid |= GF_SET_ATTR_ATIME;
- }
-
- if (valid & GFAPI_SET_ATTR_MTIME) {
- iatt->ia_mtime = stat->st_mtime;
- iatt->ia_mtime_nsec = ST_MTIM_NSEC (stat);
- *glvalid |= GF_SET_ATTR_MTIME;
- }
-
+ /* validate in args */
+ if ((stat == NULL) || (iatt == NULL) || (glvalid == NULL)) {
+ errno = EINVAL;
return;
+ }
+
+ *glvalid = 0;
+
+ if (valid & GFAPI_SET_ATTR_MODE) {
+ iatt->ia_prot = ia_prot_from_st_mode(stat->st_mode);
+ *glvalid |= GF_SET_ATTR_MODE;
+ }
+
+ if (valid & GFAPI_SET_ATTR_UID) {
+ iatt->ia_uid = stat->st_uid;
+ *glvalid |= GF_SET_ATTR_UID;
+ }
+
+ if (valid & GFAPI_SET_ATTR_GID) {
+ iatt->ia_gid = stat->st_gid;
+ *glvalid |= GF_SET_ATTR_GID;
+ }
+
+ if (valid & GFAPI_SET_ATTR_ATIME) {
+ iatt->ia_atime = stat->st_atime;
+ iatt->ia_atime_nsec = ST_ATIM_NSEC(stat);
+ *glvalid |= GF_SET_ATTR_ATIME;
+ }
+
+ if (valid & GFAPI_SET_ATTR_MTIME) {
+ iatt->ia_mtime = stat->st_mtime;
+ iatt->ia_mtime_nsec = ST_MTIM_NSEC(stat);
+ *glvalid |= GF_SET_ATTR_MTIME;
+ }
+
+ return;
}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lookupat, 3.7.4)
struct glfs_object *
-pub_glfs_h_lookupat (struct glfs *fs, struct glfs_object *parent,
- const char *path, struct stat *stat, int follow)
+pub_glfs_h_lookupat(struct glfs *fs, struct glfs_object *parent,
+ const char *path, struct stat *stat, int follow)
{
- int ret = 0;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- struct iatt iatt = {0, };
- struct glfs_object *object = NULL;
- loc_t loc = {0, };
-
- DECLARE_OLD_THIS;
-
- /* validate in args */
- if (path == NULL) {
- errno = EINVAL;
- return NULL;
- }
+ int ret = 0;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ struct iatt iatt = {
+ 0,
+ };
+ struct glfs_object *object = NULL;
+ loc_t loc = {
+ 0,
+ };
+
+ DECLARE_OLD_THIS;
+
+ /* validate in args */
+ if (path == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- errno = EIO;
- goto out;
- }
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
- /* get/refresh the in arg objects inode in correlation to the xlator */
- if (parent) {
- inode = glfs_resolve_inode (fs, subvol, parent);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ if (parent) {
+ inode = glfs_resolve_inode(fs, subvol, parent);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
}
+ }
- /* fop/op */
- ret = glfs_resolve_at (fs, subvol, inode, path, &loc, &iatt,
- follow, 0);
+ /* fop/op */
+ ret = glfs_resolve_at(fs, subvol, inode, path, &loc, &iatt, follow, 0);
- /* populate out args */
- if (!ret) {
- if (stat)
- glfs_iatt_to_stat (fs, &iatt, stat);
+ /* populate out args */
+ if (!ret) {
+ if (stat)
+ glfs_iatt_to_stat(fs, &iatt, stat);
- ret = glfs_create_object (&loc, &object);
- }
+ ret = glfs_create_object(&loc, &object);
+ }
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return object;
+ return object;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lookupat, 3.7.4);
-
+GFAPI_SYMVER_PUBLIC(glfs_h_lookupat34, glfs_h_lookupat, 3.4.2)
struct glfs_object *
-pub_glfs_h_lookupat34 (struct glfs *fs, struct glfs_object *parent,
- const char *path, struct stat *stat)
+pub_glfs_h_lookupat34(struct glfs *fs, struct glfs_object *parent,
+ const char *path, struct stat *stat)
{
- return pub_glfs_h_lookupat (fs, parent, path, stat, 0);
+ return pub_glfs_h_lookupat(fs, parent, path, stat, 0);
}
-GFAPI_SYMVER_PUBLIC(glfs_h_lookupat34, glfs_h_lookupat, 3.4.2);
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_statfs, 3.7.0)
int
-pub_glfs_h_statfs (struct glfs *fs, struct glfs_object *object,
- struct statvfs *statvfs)
+pub_glfs_h_statfs(struct glfs *fs, struct glfs_object *object,
+ struct statvfs *statvfs)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
-
- DECLARE_OLD_THIS;
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL || statvfs == NULL)) {
- errno = EINVAL;
- return -1;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+
+ DECLARE_OLD_THIS;
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL || statvfs == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
- /* populate loc */
- GLFS_LOC_FILL_INODE (inode, loc, out);
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(inode, loc, out);
- /* fop/op */
- ret = syncop_statfs (subvol, &loc, statvfs, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ /* fop/op */
+ ret = syncop_statfs(subvol, &loc, statvfs, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- loc_wipe (&loc);
+ loc_wipe(&loc);
out:
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_statfs, 3.7.0);
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_stat, 3.4.2)
int
-pub_glfs_h_stat (struct glfs *fs, struct glfs_object *object, struct stat *stat)
+pub_glfs_h_stat(struct glfs *fs, struct glfs_object *object, struct stat *stat)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
-
- DECLARE_OLD_THIS;
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL)) {
- errno = EINVAL;
- return -1;
- }
-
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
-
- /* populate loc */
- GLFS_LOC_FILL_INODE (inode, loc, out);
-
- /* fop/op */
- ret = syncop_stat (subvol, &loc, &iatt, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
-
- /* populate out args */
- if (!ret && stat) {
- glfs_iatt_to_stat (fs, &iatt, stat);
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+
+ DECLARE_OLD_THIS;
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(inode, loc, out);
+
+ /* fop/op */
+ ret = syncop_stat(subvol, &loc, &iatt, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ /* populate out args */
+ if (!ret && stat) {
+ glfs_iatt_to_stat(fs, &iatt, stat);
+ }
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_stat, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getattrs, 3.4.2)
int
-pub_glfs_h_getattrs (struct glfs *fs, struct glfs_object *object,
- struct stat *stat)
+pub_glfs_h_getattrs(struct glfs *fs, struct glfs_object *object,
+ struct stat *stat)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- struct iatt iatt = {0, };
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL)) {
- errno = EINVAL;
- return -1;
- }
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- ret = 0;
- errno = ESTALE;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ struct iatt iatt = {
+ 0,
+ };
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ ret = 0;
+ errno = ESTALE;
+ goto out;
+ }
- /* fop/op */
- ret = glfs_resolve_base (fs, subvol, inode, &iatt);
+ /* fop/op */
+ ret = glfs_resolve_base(fs, subvol, inode, &iatt);
- /* populate out args */
- if (!ret && stat) {
- glfs_iatt_to_stat (fs, &iatt, stat);
- }
+ /* populate out args */
+ if (!ret && stat) {
+ glfs_iatt_to_stat(fs, &iatt, stat);
+ }
out:
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getattrs, 3.4.2);
-
-
int
-glfs_h_getxattrs_common (struct glfs *fs, struct glfs_object *object,
- dict_t **xattr, const char *name)
+glfs_h_getxattrs_common(struct glfs *fs, struct glfs_object *object,
+ dict_t **xattr, const char *name,
+ gf_boolean_t is_listxattr)
{
- int ret = 0;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL)) {
- errno = EINVAL;
- return -1;
- }
+ int ret = 0;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
+ if (!is_listxattr) {
+ if (!name || *name == '\0') {
+ errno = EINVAL;
+ return -1;
}
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
+ if (strlen(name) > GF_XATTR_NAME_MAX) {
+ errno = ENAMETOOLONG;
+ return -1;
}
+ }
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
- /* populate loc */
- GLFS_LOC_FILL_INODE (inode, loc, out);
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(inode, loc, out);
- ret = syncop_getxattr (subvol, &loc, xattr, name, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_getxattr(subvol, &loc, xattr, name, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- return ret;
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getxattrs, 3.5.1)
int
-pub_glfs_h_getxattrs (struct glfs *fs, struct glfs_object *object,
- const char *name, void *value, size_t size)
+pub_glfs_h_getxattrs(struct glfs *fs, struct glfs_object *object,
+ const char *name, void *value, size_t size)
{
- int ret = -1;
- dict_t *xattr = NULL;
+ int ret = -1;
+ dict_t *xattr = NULL;
- /* validate in args */
- if ((fs == NULL) || (object == NULL)) {
- errno = EINVAL;
- return -1;
- }
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- ret = glfs_h_getxattrs_common (fs, object, &xattr, name);
- if (ret)
- goto out;
+ ret = glfs_h_getxattrs_common(fs, object, &xattr, name, (name == NULL));
+ if (ret)
+ goto out;
- /* If @name is NULL, means get all the xattrs (i.e listxattr). */
- if (name)
- ret = glfs_getxattr_process (value, size, xattr, name);
- else
- ret = glfs_listxattr_process (value, size, xattr);
+ /* If @name is NULL, means get all the xattrs (i.e listxattr). */
+ if (name)
+ ret = glfs_getxattr_process(value, size, xattr, name);
+ else
+ ret = glfs_listxattr_process(value, size, xattr);
out:
- if (xattr)
- dict_unref (xattr);
+ if (xattr)
+ dict_unref(xattr);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_getxattrs, 3.5.1);
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setattrs, 3.4.2)
int
-pub_glfs_h_setattrs (struct glfs *fs, struct glfs_object *object,
- struct stat *stat, int valid)
+pub_glfs_h_setattrs(struct glfs *fs, struct glfs_object *object,
+ struct stat *stat, int valid)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- int glvalid = 0;
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL) || (stat == NULL)) {
- errno = EINVAL;
- return -1;
- }
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
-
- /* map valid masks from in args */
- glfs_iatt_from_stat (stat, valid, &iatt, &glvalid);
-
- /* populate loc */
- GLFS_LOC_FILL_INODE (inode, loc, out);
-
- /* fop/op */
- ret = syncop_setattr (subvol, &loc, &iatt, glvalid, 0, 0, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ int glvalid = 0;
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL) || (stat == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ /* map valid masks from in args */
+ glfs_iatt_from_stat(stat, valid, &iatt, &glvalid);
+
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(inode, loc, out);
+
+ /* fop/op */
+ ret = syncop_setattr(subvol, &loc, &iatt, glvalid, 0, 0, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setattrs, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setxattrs, 3.5.0)
int
-pub_glfs_h_setxattrs (struct glfs *fs, struct glfs_object *object,
- const char *name, const void *value, size_t size,
- int flags)
+pub_glfs_h_setxattrs(struct glfs *fs, struct glfs_object *object,
+ const char *name, const void *value, size_t size,
+ int flags)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
- dict_t *xattr = NULL;
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL) ||
- (name == NULL) || (value == NULL)) {
- errno = EINVAL;
- return -1;
- }
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
-
- xattr = dict_for_key_value (name, value, size);
- if (!xattr) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ dict_t *xattr = NULL;
+ void *value_cp = NULL;
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL) || (name == NULL) || (value == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
- /* populate loc */
- GLFS_LOC_FILL_INODE (inode, loc, out);
+ if (!name || *name == '\0') {
+ errno = EINVAL;
+ return -1;
+ }
- /* fop/op */
- ret = syncop_setxattr (subvol, &loc, xattr, flags, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ if (strlen(name) > GF_XATTR_NAME_MAX) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ value_cp = gf_memdup(value, size);
+ GF_CHECK_ALLOC_AND_LOG(subvol->name, value_cp, ret,
+ "Failed to"
+ " duplicate setxattr value",
+ out);
+
+ xattr = dict_for_key_value(name, value_cp, size, _gf_false);
+ if (!xattr) {
+ GF_FREE(value_cp);
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(inode, loc, out);
+
+ /* fop/op */
+ ret = syncop_setxattr(subvol, &loc, xattr, flags, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- if (xattr)
- dict_unref (xattr);
+ if (xattr)
+ dict_unref(xattr);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_setxattrs, 3.5.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_removexattrs, 3.5.1)
int
-pub_glfs_h_removexattrs (struct glfs *fs, struct glfs_object *object,
- const char *name)
+pub_glfs_h_removexattrs(struct glfs *fs, struct glfs_object *object,
+ const char *name)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL) || (name == NULL)) {
- errno = EINVAL;
- return -1;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL) || (name == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
- /* populate loc */
- GLFS_LOC_FILL_INODE (inode, loc, out);
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(inode, loc, out);
- /* fop/op */
- ret = syncop_removexattr (subvol, &loc, name, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ /* fop/op */
+ ret = syncop_removexattr(subvol, &loc, name, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_removexattrs, 3.5.1);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_open, 3.4.2)
struct glfs_fd *
-pub_glfs_h_open (struct glfs *fs, struct glfs_object *object, int flags)
+pub_glfs_h_open(struct glfs *fs, struct glfs_object *object, int flags)
{
- int ret = -1;
- struct glfs_fd *glfd = NULL;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL)) {
- errno = EINVAL;
- return NULL;
- }
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
-
- /* check types to open */
- if (IA_ISDIR (inode->ia_type)) {
- ret = -1;
- errno = EISDIR;
- goto out;
- }
-
- if (!IA_ISREG (inode->ia_type)) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
-
- glfd = glfs_fd_new (fs);
- if (!glfd) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- glfd->fd = fd_create (inode, getpid());
- if (!glfd->fd) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
- glfd->fd->flags = flags;
-
- /* populate loc */
- GLFS_LOC_FILL_INODE (inode, loc, out);
-
- /* fop/op */
- ret = syncop_open (subvol, &loc, flags, glfd->fd, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
-
- glfd->fd->flags = flags;
- fd_bind (glfd->fd);
- glfs_fd_bind (glfd);
+ int ret = -1;
+ struct glfs_fd *glfd = NULL;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ dict_t *fop_attr = NULL;
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ /* check types to open */
+ if (IA_ISDIR(inode->ia_type)) {
+ ret = -1;
+ errno = EISDIR;
+ goto out;
+ }
+
+ if (!IA_ISREG(inode->ia_type)) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ glfd = glfs_fd_new(fs);
+ if (!glfd) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ glfd->fd = fd_create(inode, getpid());
+ if (!glfd->fd) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+ glfd->fd->flags = flags;
+
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(inode, loc, out);
+
+ /* fop/op */
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ ret = syncop_open(subvol, &loc, flags, glfd->fd, fop_attr, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ glfd->fd->flags = flags;
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
+ if (fop_attr)
+ dict_unref(fop_attr);
- if (ret && glfd) {
- glfs_fd_destroy (glfd);
- glfd = NULL;
- }
+ if (ret && glfd) {
+ GF_REF_PUT(glfd);
+ glfd = NULL;
+ } else if (glfd) {
+ glfd_set_state_bind(glfd);
+ }
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return glfd;
+ return glfd;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_open, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat, 3.4.2)
struct glfs_object *
-pub_glfs_h_creat (struct glfs *fs, struct glfs_object *parent, const char *path,
- int flags, mode_t mode, struct stat *stat)
+pub_glfs_h_creat(struct glfs *fs, struct glfs_object *parent, const char *path,
+ int flags, mode_t mode, struct stat *stat)
{
- int ret = -1;
- struct glfs_fd *glfd = NULL;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- uuid_t gfid;
- dict_t *xattr_req = NULL;
- struct glfs_object *object = NULL;
-
- /* validate in args */
- if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
- errno = EINVAL;
- return NULL;
+ int ret = -1;
+ fd_t *fd = NULL;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ struct glfs_object *object = NULL;
+
+ /* validate in args */
+ if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, parent);
+ if (!inode) {
+ ret = -1;
+ errno = ESTALE;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
+
+ fd = fd_create(loc.inode, getpid());
+ if (!fd) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+ fd->flags = flags;
+
+ /* fop/op */
+ ret = syncop_create(subvol, &loc, flags, mode, fd, &iatt, xattr_req, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ /* populate out args */
+ if (ret == 0) {
+ ret = glfs_loc_link(&loc, &iatt);
+ if (ret != 0) {
+ goto out;
}
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ if (stat)
+ glfs_iatt_to_stat(fs, &iatt, stat);
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ ret = glfs_create_object(&loc, &object);
+ }
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, parent);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
+out:
+ if (ret && object != NULL) {
+ /* Release the held reference */
+ glfs_h_close(object);
+ object = NULL;
+ }
- xattr_req = dict_new ();
- if (!xattr_req) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ loc_wipe(&loc);
- gf_uuid_generate (gfid);
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ if (inode)
+ inode_unref(inode);
- GLFS_LOC_FILL_PINODE (inode, loc, ret, errno, out, path);
+ if (xattr_req)
+ dict_unref(xattr_req);
- glfd = glfs_fd_new (fs);
- if (!glfd) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
+ if (fd)
+ fd_unref(fd);
- glfd->fd = fd_create (loc.inode, getpid());
- if (!glfd->fd) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
- glfd->fd->flags = flags;
+ glfs_subvol_done(fs, subvol);
- /* fop/op */
- ret = syncop_create (subvol, &loc, flags, mode, glfd->fd,
- &iatt, xattr_req, NULL);
- DECODE_SYNCOP_ERR (ret);
+ __GLFS_EXIT_FS;
- /* populate out args */
- if (ret == 0) {
- ret = glfs_loc_link (&loc, &iatt);
- if (ret != 0) {
- goto out;
- }
+invalid_fs:
+ return object;
+}
- if (stat)
- glfs_iatt_to_stat (fs, &iatt, stat);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat_open, 6.6)
+struct glfs_object *
+pub_glfs_h_creat_open(struct glfs *fs, struct glfs_object *parent,
+ const char *path, int flags, mode_t mode,
+ struct stat *stat, struct glfs_fd **out_fd)
+{
+ int ret = -1;
+ struct glfs_fd *glfd = NULL;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ struct glfs_object *object = NULL;
+ dict_t *fop_attr = NULL;
+
+ /* validate in args */
+ if ((fs == NULL) || (parent == NULL) || (path == NULL) ||
+ (out_fd == NULL)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, parent);
+ if (!inode) {
+ ret = -1;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
+
+ glfd = glfs_fd_new(fs);
+ if (!glfd) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ glfd->fd = fd_create(loc.inode, getpid());
+ if (!glfd->fd) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+ glfd->fd->flags = flags;
+
+ ret = get_fop_attr_thrd_key(&fop_attr);
+ if (ret)
+ gf_msg_debug("gfapi", 0, "Getting leaseid from thread failed");
+
+ /* fop/op */
+ ret = syncop_create(subvol, &loc, flags, mode, glfd->fd, &iatt, xattr_req,
+ NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ /* populate out args */
+ if (ret == 0) {
+ glfd->fd->flags = flags;
- ret = glfs_create_object (&loc, &object);
+ ret = glfs_loc_link(&loc, &iatt);
+ if (ret != 0) {
+ goto out;
}
- glfd->fd->flags = flags;
- fd_bind (glfd->fd);
- glfs_fd_bind (glfd);
+ if (stat)
+ glfs_iatt_to_stat(fs, &iatt, stat);
+
+ ret = glfs_create_object(&loc, &object);
+ }
out:
- if (ret && object != NULL) {
- /* Release the held reference */
- glfs_h_close (object);
- object = NULL;
- }
+ if (ret && object != NULL) {
+ /* Release the held reference */
+ glfs_h_close(object);
+ object = NULL;
+ }
- loc_wipe(&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- if (xattr_req)
- dict_unref (xattr_req);
+ if (fop_attr)
+ dict_unref(fop_attr);
- if (glfd) {
- glfs_fd_destroy (glfd);
- glfd = NULL;
- }
+ if (xattr_req)
+ dict_unref(xattr_req);
+
+ if (ret && glfd) {
+ GF_REF_PUT(glfd);
+ } else if (glfd) {
+ glfd_set_state_bind(glfd);
+ *out_fd = glfd;
+ }
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return object;
+ return object;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_creat, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mkdir, 3.4.2)
struct glfs_object *
-pub_glfs_h_mkdir (struct glfs *fs, struct glfs_object *parent, const char *path,
- mode_t mode, struct stat *stat)
+pub_glfs_h_mkdir(struct glfs *fs, struct glfs_object *parent, const char *path,
+ mode_t mode, struct stat *stat)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- uuid_t gfid;
- dict_t *xattr_req = NULL;
- struct glfs_object *object = NULL;
-
- /* validate in args */
- if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
- errno = EINVAL;
- return NULL;
- }
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, parent);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
-
- xattr_req = dict_new ();
- if (!xattr_req) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gf_uuid_generate (gfid);
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- ret = -1;
- errno = ENOMEM;
- goto out;
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ struct glfs_object *object = NULL;
+
+ /* validate in args */
+ if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, parent);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
+
+ /* fop/op */
+ ret = syncop_mkdir(subvol, &loc, mode, &iatt, xattr_req, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ /* populate out args */
+ if (ret == 0) {
+ ret = glfs_loc_link(&loc, &iatt);
+ if (ret != 0) {
+ goto out;
}
- GLFS_LOC_FILL_PINODE (inode, loc, ret, errno, out, path);
-
- /* fop/op */
- ret = syncop_mkdir (subvol, &loc, mode, &iatt, xattr_req, NULL);
- DECODE_SYNCOP_ERR (ret);
-
- /* populate out args */
- if ( ret == 0 ) {
- ret = glfs_loc_link (&loc, &iatt);
- if (ret != 0) {
- goto out;
- }
-
- if (stat)
- glfs_iatt_to_stat (fs, &iatt, stat);
+ if (stat)
+ glfs_iatt_to_stat(fs, &iatt, stat);
- ret = glfs_create_object (&loc, &object);
- }
+ ret = glfs_create_object(&loc, &object);
+ }
out:
- if (ret && object != NULL) {
- glfs_h_close (object);
- object = NULL;
- }
+ if (ret && object != NULL) {
+ glfs_h_close(object);
+ object = NULL;
+ }
- loc_wipe(&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- if (xattr_req)
- dict_unref (xattr_req);
+ if (xattr_req)
+ dict_unref(xattr_req);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return object;
+ return object;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mkdir, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mknod, 3.4.2)
struct glfs_object *
-pub_glfs_h_mknod (struct glfs *fs, struct glfs_object *parent, const char *path,
- mode_t mode, dev_t dev, struct stat *stat)
+pub_glfs_h_mknod(struct glfs *fs, struct glfs_object *parent, const char *path,
+ mode_t mode, dev_t dev, struct stat *stat)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- uuid_t gfid;
- dict_t *xattr_req = NULL;
- struct glfs_object *object = NULL;
-
- /* validate in args */
- if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
- errno = EINVAL;
- return NULL;
- }
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, parent);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
-
- xattr_req = dict_new ();
- if (!xattr_req) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gf_uuid_generate (gfid);
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- ret = -1;
- errno = ENOMEM;
- goto out;
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ struct glfs_object *object = NULL;
+
+ /* validate in args */
+ if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, parent);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, path);
+
+ /* fop/op */
+ ret = syncop_mknod(subvol, &loc, mode, dev, &iatt, xattr_req, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ /* populate out args */
+ if (ret == 0) {
+ ret = glfs_loc_link(&loc, &iatt);
+ if (ret != 0) {
+ goto out;
}
- GLFS_LOC_FILL_PINODE (inode, loc, ret, errno, out, path);
-
- /* fop/op */
- ret = syncop_mknod (subvol, &loc, mode, dev, &iatt, xattr_req, NULL);
- DECODE_SYNCOP_ERR (ret);
-
- /* populate out args */
- if (ret == 0) {
- ret = glfs_loc_link (&loc, &iatt);
- if (ret != 0) {
- goto out;
- }
-
- if (stat)
- glfs_iatt_to_stat (fs, &iatt, stat);
+ if (stat)
+ glfs_iatt_to_stat(fs, &iatt, stat);
- ret = glfs_create_object (&loc, &object);
- }
+ ret = glfs_create_object(&loc, &object);
+ }
out:
- if (ret && object != NULL) {
- glfs_h_close (object);
- object = NULL;
- }
+ if (ret && object != NULL) {
+ glfs_h_close(object);
+ object = NULL;
+ }
- loc_wipe(&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- if (xattr_req)
- dict_unref (xattr_req);
+ if (xattr_req)
+ dict_unref(xattr_req);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return object;
+ return object;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_mknod, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_unlink, 3.4.2)
int
-pub_glfs_h_unlink (struct glfs *fs, struct glfs_object *parent, const char *path)
+pub_glfs_h_unlink(struct glfs *fs, struct glfs_object *parent, const char *path)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
-
- /* validate in args */
- if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
- errno = EINVAL;
- return -1;
- }
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if ( !subvol ) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, parent);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
-
- ret = glfs_resolve_at (fs, subvol, inode, path, &loc, NULL, 0 , 0);
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+
+ /* validate in args */
+ if ((fs == NULL) || (parent == NULL) || (path == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, parent);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ ret = glfs_resolve_at(fs, subvol, inode, path, &loc, NULL, 0, 0);
+ if (ret != 0) {
+ goto out;
+ }
+
+ if (!IA_ISDIR(loc.inode->ia_type)) {
+ ret = syncop_unlink(subvol, &loc, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
if (ret != 0) {
- goto out;
+ goto out;
}
-
- if (!IA_ISDIR(loc.inode->ia_type)) {
- ret = syncop_unlink (subvol, &loc, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret != 0) {
- goto out;
- }
- } else {
- ret = syncop_rmdir (subvol, &loc, 0, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret != 0) {
- goto out;
- }
+ } else {
+ ret = syncop_rmdir(subvol, &loc, 0, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret != 0) {
+ goto out;
}
+ }
- if (ret == 0)
- ret = glfs_loc_unlink (&loc);
+ if (ret == 0)
+ ret = glfs_loc_unlink(&loc);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_unlink, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_opendir, 3.4.2)
struct glfs_fd *
-pub_glfs_h_opendir (struct glfs *fs, struct glfs_object *object)
+pub_glfs_h_opendir(struct glfs *fs, struct glfs_object *object)
{
- int ret = -1;
- struct glfs_fd *glfd = NULL;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL)) {
- errno = EINVAL;
- return NULL;
- }
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
-
- if (!IA_ISDIR (inode->ia_type)) {
- ret = -1;
- errno = ENOTDIR;
- goto out;
- }
-
- glfd = glfs_fd_new (fs);
- if (!glfd)
- goto out;
-
- INIT_LIST_HEAD (&glfd->entries);
-
- glfd->fd = fd_create (inode, getpid());
- if (!glfd->fd) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- GLFS_LOC_FILL_INODE (inode, loc, out);
-
- /* fop/op */
- ret = syncop_opendir (subvol, &loc, glfd->fd, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ int ret = -1;
+ struct glfs_fd *glfd = NULL;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ if (!IA_ISDIR(inode->ia_type)) {
+ ret = -1;
+ errno = ENOTDIR;
+ goto out;
+ }
+
+ glfd = glfs_fd_new(fs);
+ if (!glfd)
+ goto out;
+
+ INIT_LIST_HEAD(&glfd->entries);
+
+ glfd->fd = fd_create(inode, getpid());
+ if (!glfd->fd) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ GLFS_LOC_FILL_INODE(inode, loc, out);
+
+ /* fop/op */
+ ret = syncop_opendir(subvol, &loc, glfd->fd, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- if (ret && glfd) {
- glfs_fd_destroy (glfd);
- glfd = NULL;
- } else {
- fd_bind (glfd->fd);
- glfs_fd_bind (glfd);
- }
+ if (ret && glfd) {
+ GF_REF_PUT(glfd);
+ glfd = NULL;
+ } else if (glfd) {
+ glfd_set_state_bind(glfd);
+ }
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return glfd;
+ return glfd;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_opendir, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_access, 3.6.0)
int
-pub_glfs_h_access (struct glfs *fs, struct glfs_object *object, int mask)
+pub_glfs_h_access(struct glfs *fs, struct glfs_object *object, int mask)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
-
- DECLARE_OLD_THIS;
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL)) {
- errno = EINVAL;
- return ret;
- }
-
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+
+ DECLARE_OLD_THIS;
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return ret;
+ }
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
- GLFS_LOC_FILL_INODE (inode, loc, out);
+ GLFS_LOC_FILL_INODE(inode, loc, out);
- /* fop/op */
+ /* fop/op */
- ret = syncop_access (subvol, &loc, mask, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_access(subvol, &loc, mask, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
+ glfs_subvol_done(fs, subvol);
- glfs_subvol_done (fs, subvol);
-
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_access, 3.6.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_extract_handle, 3.4.2)
ssize_t
-pub_glfs_h_extract_handle (struct glfs_object *object, unsigned char *handle,
- int len)
+pub_glfs_h_extract_handle(struct glfs_object *object, unsigned char *handle,
+ int len)
{
- ssize_t ret = -1;
+ ssize_t ret = -1;
- /* validate in args */
- if (object == NULL) {
- errno = EINVAL;
- goto out;
- }
+ /* validate in args */
+ if (object == NULL) {
+ errno = EINVAL;
+ goto out;
+ }
- if (!handle || !len) {
- ret = GFAPI_HANDLE_LENGTH;
- goto out;
- }
+ if (!handle || !len) {
+ ret = GFAPI_HANDLE_LENGTH;
+ goto out;
+ }
- if (len < GFAPI_HANDLE_LENGTH)
- {
- errno = ERANGE;
- goto out;
- }
+ if (len < GFAPI_HANDLE_LENGTH) {
+ errno = ERANGE;
+ goto out;
+ }
- memcpy (handle, object->gfid, GFAPI_HANDLE_LENGTH);
+ memcpy(handle, object->gfid, GFAPI_HANDLE_LENGTH);
- ret = GFAPI_HANDLE_LENGTH;
+ ret = GFAPI_HANDLE_LENGTH;
out:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_extract_handle, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_create_from_handle, 3.4.2)
struct glfs_object *
-pub_glfs_h_create_from_handle (struct glfs *fs, unsigned char *handle, int len,
- struct stat *stat)
+pub_glfs_h_create_from_handle(struct glfs *fs, unsigned char *handle, int len,
+ struct stat *stat)
{
- loc_t loc = {0, };
- int ret = -1;
- struct iatt iatt = {0, };
- inode_t *newinode = NULL;
- xlator_t *subvol = NULL;
- struct glfs_object *object = NULL;
-
- /* validate in args */
- if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) {
- errno = EINVAL;
- return NULL;
- }
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- errno = EIO;
- goto out;
- }
+ loc_t loc = {
+ 0,
+ };
+ int ret = -1;
+ struct iatt iatt = {
+ 0,
+ };
+ inode_t *newinode = NULL;
+ xlator_t *subvol = NULL;
+ struct glfs_object *object = NULL;
+ uint64_t ctx_value = LOOKUP_NOT_NEEDED;
+ gf_boolean_t lookup_needed = _gf_false;
+
+ /* validate in args */
+ if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) {
+ errno = EINVAL;
+ return NULL;
+ }
- memcpy (loc.gfid, handle, GFAPI_HANDLE_LENGTH);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- newinode = inode_find (subvol->itable, loc.gfid);
- if (newinode) {
- if (!stat) /* No need of lookup */
- goto found;
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
- loc.inode = newinode;
- } else {
- loc.inode = inode_new (subvol->itable);
- if (!loc.inode) {
- errno = ENOMEM;
- goto out;
- }
- }
+ memcpy(loc.gfid, handle, GFAPI_HANDLE_LENGTH);
- ret = syncop_lookup (subvol, &loc, &iatt, 0, 0, 0);
- DECODE_SYNCOP_ERR (ret);
- if (ret) {
- gf_msg (subvol->name, GF_LOG_WARNING, errno,
- API_MSG_INODE_REFRESH_FAILED,
- "inode refresh of %s failed: %s",
- uuid_utoa (loc.gfid), strerror (errno));
- goto out;
- }
+ /* make sure the gfid received is valid */
+ GF_VALIDATE_OR_GOTO("glfs_h_create_from_handle",
+ !(gf_uuid_is_null(loc.gfid)), out);
- newinode = inode_link (loc.inode, 0, 0, &iatt);
- if (newinode)
- inode_lookup (newinode);
- else {
- gf_msg (subvol->name, GF_LOG_WARNING, EINVAL,
- API_MSG_INVALID_ENTRY,
- "inode linking of %s failed: %s",
- uuid_utoa (loc.gfid), strerror (errno));
- errno = EINVAL;
- goto out;
- }
+ newinode = inode_find(subvol->itable, loc.gfid);
+ if (newinode) {
+ if (!stat) /* No need of lookup */
+ goto found;
- /* populate stat */
- if (stat)
- glfs_iatt_to_stat (fs, &iatt, stat);
+ lookup_needed = inode_needs_lookup(newinode, THIS);
+ if (lookup_needed) {
+ loc.inode = newinode;
+ } else {
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(newinode, loc, fill_out);
+
+ /* fop/op */
+ ret = syncop_stat(subvol, &loc, &iatt, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret) {
+ fill_out:
+ /* Drop the reference hold in inode_find */
+ inode_unref(newinode);
+ goto out;
+ }
+
+ glfs_iatt_to_stat(fs, &iatt, stat);
+ goto found;
+ }
+ } else {
+ loc.inode = inode_new(subvol->itable);
+ if (!loc.inode) {
+ errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ ret = syncop_lookup(subvol, &loc, &iatt, 0, 0, 0);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret) {
+ gf_smsg(subvol->name, GF_LOG_WARNING, errno,
+ API_MSG_INODE_REFRESH_FAILED, "gfid=%s", uuid_utoa(loc.gfid),
+ "error=%s", strerror(errno), NULL);
+ goto out;
+ }
+
+ newinode = inode_link(loc.inode, 0, 0, &iatt);
+ if (newinode) {
+ if (newinode == loc.inode) {
+ inode_ctx_set(newinode, THIS, &ctx_value);
+ }
+ inode_lookup(newinode);
+ } else {
+ gf_smsg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED,
+ "gfid=%s", uuid_utoa(loc.gfid), NULL);
+ goto out;
+ }
+
+ /* populate stat */
+ if (stat)
+ glfs_iatt_to_stat(fs, &iatt, stat);
found:
- object = GF_CALLOC (1, sizeof(struct glfs_object),
- glfs_mt_glfs_object_t);
- if (object == NULL) {
- errno = ENOMEM;
- ret = -1;
- goto out;
- }
+ object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
+ if (object == NULL) {
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
- /* populate the return object */
- object->inode = newinode;
- gf_uuid_copy (object->gfid, object->inode->gfid);
+ /* populate the return object */
+ object->inode = newinode;
+ gf_uuid_copy(object->gfid, object->inode->gfid);
out:
- /* TODO: Check where the inode ref is being held? */
- loc_wipe (&loc);
+ /* TODO: Check where the inode ref is being held? */
+ loc_wipe(&loc);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return object;
+ return object;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_create_from_handle, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_close, 3.4.2)
int
-pub_glfs_h_close (struct glfs_object *object)
+pub_glfs_h_close(struct glfs_object *object)
{
- inode_unref (object->inode);
- GF_FREE (object);
+ /* since glfs_h_* objects hold a reference to inode
+ * it is safe to keep lookup count to '0' */
+ inode_forget(object->inode, 0);
+ inode_unref(object->inode);
+ GF_FREE(object);
- return 0;
+ return 0;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_close, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_truncate, 3.4.2)
int
-pub_glfs_h_truncate (struct glfs *fs, struct glfs_object *object, off_t offset)
+pub_glfs_h_truncate(struct glfs *fs, struct glfs_object *object, off_t offset)
{
- loc_t loc = {0, };
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
-
- DECLARE_OLD_THIS;
-
- /* validate in args */
- if (object == NULL) {
- errno = EINVAL;
- return -1;
- }
+ loc_t loc = {
+ 0,
+ };
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+
+ DECLARE_OLD_THIS;
+
+ /* validate in args */
+ if (object == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
- GLFS_LOC_FILL_INODE (inode, loc, out);
+ GLFS_LOC_FILL_INODE(inode, loc, out);
- /* fop/op */
- ret = syncop_truncate (subvol, &loc, (off_t)offset, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ /* fop/op */
+ ret = syncop_truncate(subvol, &loc, (off_t)offset, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- /* populate out args */
- if (ret == 0)
- ret = glfs_loc_unlink (&loc);
+ /* populate out args */
+ if (ret == 0)
+ ret = glfs_loc_unlink(&loc);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_truncate, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_symlink, 3.4.2)
struct glfs_object *
-pub_glfs_h_symlink (struct glfs *fs, struct glfs_object *parent,
- const char *name, const char *data, struct stat *stat)
+pub_glfs_h_symlink(struct glfs *fs, struct glfs_object *parent,
+ const char *name, const char *data, struct stat *stat)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- loc_t loc = {0, };
- struct iatt iatt = {0, };
- uuid_t gfid;
- dict_t *xattr_req = NULL;
- struct glfs_object *object = NULL;
-
- DECLARE_OLD_THIS;
-
- /* validate in args */
- if ((parent == NULL) || (name == NULL) ||
- (data == NULL)) {
- errno = EINVAL;
- return NULL;
- }
-
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, parent);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
-
- xattr_req = dict_new ();
- if (!xattr_req) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- gf_uuid_generate (gfid);
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- ret = -1;
- errno = ENOMEM;
- goto out;
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ struct glfs_object *object = NULL;
+
+ DECLARE_OLD_THIS;
+
+ /* validate in args */
+ if ((parent == NULL) || (name == NULL) || (data == NULL)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, parent);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ GLFS_LOC_FILL_PINODE(inode, loc, ret, errno, out, name);
+
+ /* fop/op */
+ ret = syncop_symlink(subvol, &loc, data, &iatt, xattr_req, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ /* populate out args */
+ if (ret == 0) {
+ ret = glfs_loc_link(&loc, &iatt);
+ if (ret != 0) {
+ goto out;
}
- GLFS_LOC_FILL_PINODE (inode, loc, ret, errno, out, name);
-
- /* fop/op */
- ret = syncop_symlink (subvol, &loc, data, &iatt, xattr_req, NULL);
- DECODE_SYNCOP_ERR (ret);
-
- /* populate out args */
- if (ret == 0) {
- ret = glfs_loc_link (&loc, &iatt);
- if (ret != 0) {
- goto out;
- }
+ if (stat)
+ glfs_iatt_to_stat(fs, &iatt, stat);
- if (stat)
- glfs_iatt_to_stat (fs, &iatt, stat);
-
- ret = glfs_create_object (&loc, &object);
- }
+ ret = glfs_create_object(&loc, &object);
+ }
out:
- if (ret && object != NULL) {
- pub_glfs_h_close (object);
- object = NULL;
- }
+ if (ret && object != NULL) {
+ pub_glfs_h_close(object);
+ object = NULL;
+ }
- loc_wipe(&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- if (xattr_req)
- dict_unref (xattr_req);
+ if (xattr_req)
+ dict_unref(xattr_req);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return object;
+ return object;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_symlink, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_readlink, 3.4.2)
int
-pub_glfs_h_readlink (struct glfs *fs, struct glfs_object *object, char *buf,
- size_t bufsiz)
+pub_glfs_h_readlink(struct glfs *fs, struct glfs_object *object, char *buf,
+ size_t bufsiz)
{
- loc_t loc = {0, };
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- char *linkval = NULL;
-
- DECLARE_OLD_THIS;
-
- /* validate in args */
- if ((object == NULL) || (buf == NULL)) {
- errno = EINVAL;
- return -1;
- }
+ loc_t loc = {
+ 0,
+ };
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ char *linkval = NULL;
+
+ DECLARE_OLD_THIS;
+
+ /* validate in args */
+ if ((object == NULL) || (buf == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, object);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
- GLFS_LOC_FILL_INODE (inode, loc, out);
+ GLFS_LOC_FILL_INODE(inode, loc, out);
- /* fop/op */
- ret = syncop_readlink (subvol, &loc, &linkval, bufsiz, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ /* fop/op */
+ ret = syncop_readlink(subvol, &loc, &linkval, bufsiz, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
- /* populate out args */
- if (ret > 0)
- memcpy (buf, linkval, ret);
+ /* populate out args */
+ if (ret > 0)
+ memcpy(buf, linkval, ret);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- if (inode)
- inode_unref (inode);
+ if (inode)
+ inode_unref(inode);
- if (linkval)
- GF_FREE (linkval);
+ if (linkval)
+ GF_FREE(linkval);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_readlink, 3.4.2);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_link, 3.4.2)
int
-pub_glfs_h_link (struct glfs *fs, struct glfs_object *linksrc,
- struct glfs_object *parent, const char *name)
+pub_glfs_h_link(struct glfs *fs, struct glfs_object *linksrc,
+ struct glfs_object *parent, const char *name)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *inode = NULL;
- inode_t *pinode = NULL;
- loc_t oldloc = {0, };
- loc_t newloc = {0, };
- struct iatt iatt = {0, };
-
- DECLARE_OLD_THIS;
-
- /* validate in args */
- if ((linksrc == NULL) || (parent == NULL) ||
- (name == NULL)) {
- errno = EINVAL;
- return -1;
- }
-
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- /* get/refresh the in arg objects inode in correlation to the xlator */
- inode = glfs_resolve_inode (fs, subvol, linksrc);
- if (!inode) {
- errno = ESTALE;
- goto out;
- }
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ inode_t *pinode = NULL;
+ loc_t oldloc = {
+ 0,
+ };
+ loc_t newloc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+
+ DECLARE_OLD_THIS;
+
+ /* validate in args */
+ if ((linksrc == NULL) || (parent == NULL) || (name == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, linksrc);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ if (inode->ia_type == IA_IFDIR) {
+ ret = -1;
+ errno = EISDIR;
+ goto out;
+ }
+
+ GLFS_LOC_FILL_INODE(inode, oldloc, out);
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ pinode = glfs_resolve_inode(fs, subvol, parent);
+ if (!pinode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ /* setup newloc based on parent */
+ newloc.parent = inode_ref(pinode);
+ newloc.name = name;
+ ret = glfs_loc_touchup(&newloc);
+ if (ret != 0) {
+ errno = EINVAL;
+ goto out;
+ }
+
+ /* Filling the inode of the hard link to be same as that of the
+ * original file
+ */
+ newloc.inode = inode_ref(inode);
+
+ /* fop/op */
+ ret = syncop_link(subvol, &oldloc, &newloc, &iatt, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret == 0)
+ ret = glfs_loc_link(&newloc, &iatt);
+out:
+ loc_wipe(&oldloc);
+ loc_wipe(&newloc);
- if (inode->ia_type == IA_IFDIR) {
- ret = -1;
- errno = EISDIR;
- goto out;
- }
+ if (inode)
+ inode_unref(inode);
- GLFS_LOC_FILL_INODE (inode, oldloc, out);
+ if (pinode)
+ inode_unref(pinode);
- /* get/refresh the in arg objects inode in correlation to the xlator */
- pinode = glfs_resolve_inode (fs, subvol, parent);
- if (!pinode) {
- errno = ESTALE;
- goto out;
- }
+ glfs_subvol_done(fs, subvol);
- /* setup newloc based on parent */
- newloc.parent = inode_ref (pinode);
- newloc.name = name;
- ret = glfs_loc_touchup (&newloc);
- if (ret != 0) {
- errno = EINVAL;
- goto out;
- }
+ __GLFS_EXIT_FS;
- /* Filling the inode of the hard link to be same as that of the
- * original file
- */
- newloc.inode = inode_ref (inode);
+invalid_fs:
+ return ret;
+}
- /* fop/op */
- ret = syncop_link (subvol, &oldloc, &newloc, &iatt, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2)
+int
+pub_glfs_h_rename(struct glfs *fs, struct glfs_object *olddir,
+ const char *oldname, struct glfs_object *newdir,
+ const char *newname)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *oldpinode = NULL;
+ inode_t *newpinode = NULL;
+ loc_t oldloc = {
+ 0,
+ };
+ loc_t newloc = {
+ 0,
+ };
+ struct iatt oldiatt = {
+ 0,
+ };
+ struct iatt newiatt = {
+ 0,
+ };
+
+ DECLARE_OLD_THIS;
+
+ /* validate in args */
+ if ((olddir == NULL) || (oldname == NULL) || (newdir == NULL) ||
+ (newname == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ oldpinode = glfs_resolve_inode(fs, subvol, olddir);
+ if (!oldpinode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ ret = glfs_resolve_at(fs, subvol, oldpinode, oldname, &oldloc, &oldiatt, 0,
+ 0);
+ if (ret != 0) {
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ newpinode = glfs_resolve_inode(fs, subvol, newdir);
+ if (!newpinode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ ret = glfs_resolve_at(fs, subvol, newpinode, newname, &newloc, &newiatt, 0,
+ 0);
+
+ if (ret && errno != ENOENT && newloc.parent)
+ goto out;
+
+ if (newiatt.ia_type != IA_INVAL) {
+ if ((oldiatt.ia_type == IA_IFDIR) != (newiatt.ia_type == IA_IFDIR)) {
+ /* Either both old and new must be dirs,
+ * or both must be non-dirs. Else, fail.
+ */
+ ret = -1;
+ errno = EEXIST;
+ goto out;
+ }
+ }
+
+ /* TODO: check if new or old is a prefix of the other, and fail EINVAL */
+
+ ret = syncop_rename(subvol, &oldloc, &newloc, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret == 0) {
+ inode_rename(oldloc.parent->table, oldloc.parent, oldloc.name,
+ newloc.parent, newloc.name, oldloc.inode, &oldiatt);
+
+ if (newloc.inode && !inode_has_dentry(newloc.inode))
+ inode_forget(newloc.inode, 0);
+ }
- if (ret == 0)
- ret = glfs_loc_link (&newloc, &iatt);
out:
- loc_wipe (&oldloc);
- loc_wipe (&newloc);
+ loc_wipe(&oldloc);
+ loc_wipe(&newloc);
- if (inode)
- inode_unref (inode);
+ if (oldpinode)
+ inode_unref(oldpinode);
- if (pinode)
- inode_unref (pinode);
+ if (newpinode)
+ inode_unref(newpinode);
- glfs_subvol_done (fs, subvol);
+ glfs_subvol_done(fs, subvol);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_link, 3.4.2);
-
-
-int
-pub_glfs_h_rename (struct glfs *fs, struct glfs_object *olddir,
- const char *oldname, struct glfs_object *newdir,
- const char *newname)
+/*
+ * Given a handle/gfid, find if the corresponding inode is present in
+ * the inode table. If yes create and return the corresponding glfs_object.
+ */
+struct glfs_object *
+glfs_h_find_handle(struct glfs *fs, unsigned char *handle, int len)
{
- int ret = -1;
- xlator_t *subvol = NULL;
- inode_t *oldpinode = NULL;
- inode_t *newpinode = NULL;
- loc_t oldloc = {0, };
- loc_t newloc = {0, };
- struct iatt oldiatt = {0, };
- struct iatt newiatt = {0, };
-
- DECLARE_OLD_THIS;
-
- /* validate in args */
- if ((olddir == NULL) || (oldname == NULL) ||
- (newdir == NULL) || (newname == NULL)) {
- errno = EINVAL;
- return -1;
- }
+ inode_t *newinode = NULL;
+ xlator_t *subvol = NULL;
+ struct glfs_object *object = NULL;
+ uuid_t gfid;
+
+ /* validate in args */
+ if ((fs == NULL) || (handle == NULL) || (len != GFAPI_HANDLE_LENGTH)) {
+ errno = EINVAL;
+ return NULL;
+ }
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
- if ( !subvol ) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ errno = EIO;
+ goto out;
+ }
- /* get/refresh the in arg objects inode in correlation to the xlator */
- oldpinode = glfs_resolve_inode (fs, subvol, olddir);
- if (!oldpinode) {
- errno = ESTALE;
- goto out;
- }
+ memcpy(gfid, handle, GFAPI_HANDLE_LENGTH);
- ret = glfs_resolve_at (fs, subvol, oldpinode, oldname, &oldloc,
- &oldiatt, 0 , 0);
- if (ret != 0) {
- goto out;
- }
+ /* make sure the gfid received is valid */
+ GF_VALIDATE_OR_GOTO("glfs_h_find_handle", !(gf_uuid_is_null(gfid)), out);
- /* get/refresh the in arg objects inode in correlation to the xlator */
- newpinode = glfs_resolve_inode (fs, subvol, newdir);
- if (!newpinode) {
- errno = ESTALE;
- goto out;
- }
+ newinode = inode_find(subvol->itable, gfid);
+ if (!newinode) {
+ goto out;
+ }
- ret = glfs_resolve_at (fs, subvol, newpinode, newname, &newloc,
- &newiatt, 0, 0);
-
- if (ret && errno != ENOENT && newloc.parent)
- goto out;
-
- if (newiatt.ia_type != IA_INVAL) {
- if ((oldiatt.ia_type == IA_IFDIR) !=
- (newiatt.ia_type == IA_IFDIR)) {
- /* Either both old and new must be dirs,
- * or both must be non-dirs. Else, fail.
- */
- ret = -1;
- errno = EEXIST;
- goto out;
- }
- }
+ object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
+ if (object == NULL) {
+ errno = ENOMEM;
+ goto out;
+ }
- /* TODO: check if new or old is a prefix of the other, and fail EINVAL */
+ /* populate the return object. The ref taken here
+ * is un'refed when the application does glfs_h_close() */
+ object->inode = inode_ref(newinode);
+ gf_uuid_copy(object->gfid, object->inode->gfid);
- ret = syncop_rename (subvol, &oldloc, &newloc, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+out:
+ /* inode_find takes a reference. Unref it. */
+ if (newinode)
+ inode_unref(newinode);
- if (ret == 0)
- inode_rename (oldloc.parent->table, oldloc.parent, oldloc.name,
- newloc.parent, newloc.name, oldloc.inode,
- &oldiatt);
+ glfs_subvol_done(fs, subvol);
-out:
- loc_wipe (&oldloc);
- loc_wipe (&newloc);
+ __GLFS_EXIT_FS;
- if (oldpinode)
- inode_unref (oldpinode);
+invalid_fs:
+ return object;
+}
- if (newpinode)
- inode_unref (newpinode);
+static void
+glfs_free_upcall_inode(void *to_free)
+{
+ struct glfs_upcall_inode *arg = to_free;
- glfs_subvol_done (fs, subvol);
+ if (!arg)
+ return;
- __GLFS_EXIT_FS;
+ if (arg->object)
+ glfs_h_close(arg->object);
+ if (arg->p_object)
+ glfs_h_close(arg->p_object);
+ if (arg->oldp_object)
+ glfs_h_close(arg->oldp_object);
-invalid_fs:
- return ret;
+ GF_FREE(arg);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_rename, 3.4.2);
-
int
-glfs_h_poll_cache_invalidation (struct glfs *fs,
- struct callback_arg *up_arg,
- struct gf_upcall *upcall_data)
+glfs_h_poll_cache_invalidation(struct glfs *fs, struct glfs_upcall *up_arg,
+ struct gf_upcall *upcall_data)
{
- int ret = -1;
- struct glfs_object *p_object = NULL;
- struct glfs_object *oldp_object = NULL;
- struct glfs_object *object = NULL;
- struct gf_upcall_cache_invalidation *ca_data = NULL;
- struct callback_inode_arg *up_inode_arg = NULL;
-
- ca_data = upcall_data->data;
- GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
- ca_data, out);
-
- object = glfs_h_create_from_handle (fs, upcall_data->gfid,
- GFAPI_HANDLE_LENGTH,
- NULL);
- GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
- object, out);
-
- up_inode_arg = calloc (1, sizeof (struct callback_inode_arg));
- GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
- up_inode_arg, out);
-
- up_arg->event_arg = up_inode_arg;
-
- up_inode_arg->object = object;
- up_inode_arg->flags = ca_data->flags;
- up_inode_arg->expire_time_attr = ca_data->expire_time_attr;
-
- /* XXX: Update stat as well incase of UP_*_TIMES.
- * This will be addressed as part of INODE_UPDATE */
- if (ca_data->flags & GFAPI_INODE_UPDATE_FLAGS) {
- glfs_iatt_to_stat (fs, &ca_data->stat, &up_inode_arg->buf);
- }
-
- if (ca_data->flags & GFAPI_UP_PARENT_TIMES) {
- p_object = glfs_h_create_from_handle (fs,
- ca_data->p_stat.ia_gfid,
- GFAPI_HANDLE_LENGTH,
- NULL);
- GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
- p_object, out);
+ int ret = -1;
+ struct glfs_object *p_object = NULL;
+ struct glfs_object *oldp_object = NULL;
+ struct glfs_object *object = NULL;
+ struct gf_upcall_cache_invalidation *ca_data = NULL;
+ struct glfs_upcall_inode *up_inode_arg = NULL;
+
+ ca_data = upcall_data->data;
+ GF_VALIDATE_OR_GOTO("glfs_h_poll_cache_invalidation", ca_data, out);
+
+ object = glfs_h_find_handle(fs, upcall_data->gfid, GFAPI_HANDLE_LENGTH);
+ if (!object) {
+ /* The reason handle creation will fail is because we
+ * couldn't find the inode in the gfapi inode table.
+ *
+ * But since application would have taken inode_ref, the
+ * only case when this can happen is when it has closed
+ * the handle and hence will no more be interested in
+ * the upcall for this particular gfid.
+ */
+ gf_smsg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_CREATE_HANDLE_FAILED,
+ "gfid=%s", uuid_utoa(upcall_data->gfid), NULL);
+ errno = ESTALE;
+ goto out;
+ }
+
+ up_inode_arg = GF_CALLOC(1, sizeof(struct glfs_upcall_inode),
+ glfs_mt_upcall_inode_t);
+ GF_VALIDATE_OR_GOTO("glfs_h_poll_cache_invalidation", up_inode_arg, out);
+
+ up_inode_arg->object = object;
+ up_inode_arg->flags = ca_data->flags;
+ up_inode_arg->expire_time_attr = ca_data->expire_time_attr;
+
+ /* XXX: Update stat as well in case of UP_*_TIMES.
+ * This will be addressed as part of INODE_UPDATE */
+ if (ca_data->flags & GFAPI_INODE_UPDATE_FLAGS) {
+ glfs_iatt_to_stat(fs, &ca_data->stat, &up_inode_arg->buf);
+ }
+
+ if (ca_data->flags & GFAPI_UP_PARENT_TIMES) {
+ p_object = glfs_h_find_handle(fs, ca_data->p_stat.ia_gfid,
+ GFAPI_HANDLE_LENGTH);
+ if (!p_object) {
+ gf_smsg(THIS->name, GF_LOG_DEBUG, errno,
+ API_MSG_CREATE_HANDLE_FAILED, "gfid=%s",
+ uuid_utoa(ca_data->p_stat.ia_gfid), NULL);
+ errno = ESTALE;
+ goto out;
+ }
+
+ glfs_iatt_to_stat(fs, &ca_data->p_stat, &up_inode_arg->p_buf);
+ }
+ up_inode_arg->p_object = p_object;
+
+ /* In case of RENAME, update old parent as well */
+ if (ca_data->flags & GFAPI_UP_RENAME) {
+ oldp_object = glfs_h_find_handle(fs, ca_data->oldp_stat.ia_gfid,
+ GFAPI_HANDLE_LENGTH);
+ if (!oldp_object) {
+ gf_smsg(THIS->name, GF_LOG_DEBUG, errno,
+ API_MSG_CREATE_HANDLE_FAILED, "gfid=%s",
+ uuid_utoa(ca_data->oldp_stat.ia_gfid), NULL);
+ errno = ESTALE;
+ /* By the time we receive upcall old parent_dir may
+ * have got removed. We still need to send upcall
+ * for the file/dir and current parent handles. */
+ up_inode_arg->oldp_object = NULL;
+ ret = 0;
+ }
+
+ glfs_iatt_to_stat(fs, &ca_data->oldp_stat, &up_inode_arg->oldp_buf);
+ }
+ up_inode_arg->oldp_object = oldp_object;
+
+ up_arg->reason = GLFS_UPCALL_INODE_INVALIDATE;
+ up_arg->event = up_inode_arg;
+ up_arg->free_event = glfs_free_upcall_inode;
+
+ ret = 0;
- glfs_iatt_to_stat (fs, &ca_data->p_stat, &up_inode_arg->p_buf);
- }
- up_inode_arg->p_object = p_object;
-
- /* In case of RENAME, update old parent as well */
- if (ca_data->flags & GFAPI_UP_RENAME) {
- oldp_object = glfs_h_create_from_handle (fs,
- ca_data->oldp_stat.ia_gfid,
- GFAPI_HANDLE_LENGTH,
- NULL);
- GF_VALIDATE_OR_GOTO ("glfs_h_poll_cache_invalidation",
- oldp_object, out);
-
- glfs_iatt_to_stat (fs, &ca_data->oldp_stat,
- &up_inode_arg->oldp_buf);
- }
- up_inode_arg->oldp_object = oldp_object;
+out:
+ if (ret) {
+ /* Close p_object and oldp_object as well if being referenced.*/
+ if (object)
+ glfs_h_close(object);
+
+ /* Set reason to prevent applications from using ->event */
+ up_arg->reason = GLFS_UPCALL_EVENT_NULL;
+ GF_FREE(up_inode_arg);
+ }
+ return ret;
+}
- ret = 0;
+void
+glfs_release_upcall(void *ptr)
+{
+ struct glfs_upcall *to_free = ptr;
-out:
- return ret;
+ if (to_free->event)
+ to_free->free_event(to_free->event);
}
/*
- * This API is used to poll for upcall events stored in the
- * upcall list. Current users of this API is NFS-Ganesha.
- * Incase of any event received, it will be mapped appropriately
- * into 'callback_arg' along with the handle object to be passed
- * to NFS-Ganesha.
- *
- * On success, applications need to check for 'reason' to decide
- * if any upcall event is received.
+ * This API is used to poll for upcall events stored in the upcall list.
+ * Current users of this API is NFS-Ganesha. In case of any event received, it
+ * will be mapped appropriately into 'glfs_upcall' along with the handle object
+ * to be passed to NFS-Ganesha.
*
- * Current supported upcall_events -
- * GFAPI_INODE_INVALIDATE -
- * 'arg - callback_inode_arg
+ * On success, applications need to check if up_arg is not-NULL or errno is not
+ * ENOENT. glfs_upcall_get_reason() can be used to decide what kind of event
+ * has been received.
*
- * After processing the event, applications need to free 'event_arg'.
+ * Current supported upcall_events:
+ * GLFS_UPCALL_INODE_INVALIDATE
*
- * Incase of INODE_INVALIDATE, applications need to free "object",
- * "p_object" and "oldp_object" using glfs_h_close(..).
+ * After processing the event, applications need to free 'up_arg' by calling
+ * glfs_free().
*
- * Also similar to I/Os, the application should ideally stop polling
- * before calling glfs_fini(..). Hence making an assumption that
- * 'fs' & ctx structures cannot be freed while in this routine.
+ * Also similar to I/Os, the application should ideally stop polling before
+ * calling glfs_fini(..). Hence making an assumption that 'fs' & ctx structures
+ * cannot be freed while in this routine.
*/
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_poll_upcall, 3.7.16)
int
-pub_glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *up_arg)
+pub_glfs_h_poll_upcall(struct glfs *fs, struct glfs_upcall **up_arg)
{
- upcall_entry *u_list = NULL;
- upcall_entry *tmp = NULL;
- xlator_t *subvol = NULL;
- int found = 0;
- int reason = 0;
- glusterfs_ctx_t *ctx = NULL;
- int ret = -1;
- struct gf_upcall *upcall_data = NULL;
-
- DECLARE_OLD_THIS;
-
- if (!up_arg) {
- errno = EINVAL;
- goto err;
- }
+ upcall_entry *u_list = NULL;
+ upcall_entry *tmp = NULL;
+ xlator_t *subvol = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = -1;
+ struct gf_upcall *upcall_data = NULL;
+
+ DECLARE_OLD_THIS;
+
+ if (!up_arg) {
+ errno = EINVAL;
+ goto err;
+ }
+
+ __GLFS_ENTRY_VALIDATE_FS(fs, err);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ errno = EIO;
+ goto restore;
+ }
+
+ /* Ideally applications should stop polling before calling
+ * 'glfs_fini'. Yet cross check if cleanup has started. */
+ pthread_mutex_lock(&fs->mutex);
+ {
+ ctx = fs->ctx;
+
+ if (ctx->cleanup_started) {
+ pthread_mutex_unlock(&fs->mutex);
+ goto out;
+ }
+
+ fs->pin_refcnt++;
+
+ /* once we call this function, the applications seems to be
+ * interested in events, enable caching them */
+ fs->cache_upcalls = _gf_true;
+ }
+ pthread_mutex_unlock(&fs->mutex);
+
+ pthread_mutex_lock(&fs->upcall_list_mutex);
+ {
+ list_for_each_entry_safe(u_list, tmp, &fs->upcall_list, upcall_list)
+ {
+ list_del_init(&u_list->upcall_list);
+ upcall_data = &u_list->upcall_data;
+ break;
+ }
+ }
+ /* No other thread can delete this entry. So unlock it */
+ pthread_mutex_unlock(&fs->upcall_list_mutex);
+
+ if (upcall_data) {
+ switch (upcall_data->event_type) {
+ case GF_UPCALL_CACHE_INVALIDATION:
+ *up_arg = GLFS_CALLOC(1, sizeof(struct gf_upcall),
+ glfs_release_upcall,
+ glfs_mt_upcall_entry_t);
+ if (!*up_arg) {
+ errno = ENOMEM;
+ break; /* goto free u_list */
+ }
- __GLFS_ENTRY_VALIDATE_FS (fs, err);
+ /* XXX: Need to revisit this to support
+ * GLFS_UPCALL_INODE_UPDATE if required. */
+ ret = glfs_h_poll_cache_invalidation(fs, *up_arg, upcall_data);
+ if (ret || (*up_arg)->reason == GLFS_UPCALL_EVENT_NULL) {
+ /* It could so happen that the file which got
+ * upcall notification may have got deleted by
+ * the same client. Irrespective of the error,
+ * return with an error or success+ENOENT. */
+ if ((*up_arg)->reason == GLFS_UPCALL_EVENT_NULL)
+ errno = ENOENT;
+
+ GLFS_FREE(*up_arg);
+ *up_arg = NULL;
+ }
+ break;
+ case GF_UPCALL_RECALL_LEASE:
+ gf_log("glfs_h_poll_upcall", GF_LOG_DEBUG,
+ "UPCALL_RECALL_LEASE is not implemented yet");
+ /* fallthrough till we support leases */
+ case GF_UPCALL_EVENT_NULL:
+ /* no 'default:' label, to force handling all upcall events */
+ errno = ENOENT;
+ break;
+ }
+
+ GF_FREE(u_list->upcall_data.data);
+ GF_FREE(u_list);
+ } else {
+ /* fs->upcall_list was empty, no upcall events cached */
+ errno = ENOENT;
+ }
+
+ ret = 0;
- /* get the active volume */
- subvol = glfs_active_subvol (fs);
+out:
+ pthread_mutex_lock(&fs->mutex);
+ {
+ fs->pin_refcnt--;
+ }
+ pthread_mutex_unlock(&fs->mutex);
- if (!subvol) {
- errno = EIO;
- goto restore;
- }
+ glfs_subvol_done(fs, subvol);
- /* Ideally applications should stop polling before calling
- * 'glfs_fini'. Yet cross check if cleanup has started
- */
- pthread_mutex_lock (&fs->mutex);
- {
- ctx = fs->ctx;
+restore:
+ __GLFS_EXIT_FS;
+err:
+ return ret;
+}
- if (ctx->cleanup_started) {
- pthread_mutex_unlock (&fs->mutex);
- goto out;
- }
+static gf_boolean_t log_upcall370 = _gf_true; /* log once */
- fs->pin_refcnt++;
- }
- pthread_mutex_unlock (&fs->mutex);
+/* The old glfs_h_poll_upcall interface requires intimate knowledge of the
+ * structures that are returned to the calling application. This is not
+ * recommended, as the returned structures need to returned correctly (handles
+ * closed, memory free'd with the unavailable GF_FREE(), and possibly more.)
+ *
+ * To the best of our knowledge, only NFS-Ganesha uses the upcall events
+ * through gfapi. We keep this backwards compatibility function around so that
+ * applications using the existing implementation do not break.
+ *
+ * WARNING: this function will be removed in the future.
+ */
+GFAPI_SYMVER_PUBLIC(glfs_h_poll_upcall370, glfs_h_poll_upcall, 3.7.0)
+int
+pub_glfs_h_poll_upcall370(struct glfs *fs, struct glfs_callback_arg *up_arg)
+{
+ struct glfs_upcall *upcall = NULL;
+ int ret = -1;
+
+ if (log_upcall370) {
+ log_upcall370 = _gf_false;
+ gf_log(THIS->name, GF_LOG_WARNING,
+ "this application is "
+ "compiled against an old version of libgfapi, it "
+ "should use glfs_free() to release the structure "
+ "returned by glfs_h_poll_upcall() - for more details, "
+ "see http://review.gluster.org/14701");
+ }
+
+ ret = pub_glfs_h_poll_upcall(fs, &upcall);
+ if (ret == 0) {
+ up_arg->fs = fs;
+ if ((errno == ENOENT) || !upcall || !upcall->event) {
+ up_arg->reason = GLFS_UPCALL_EVENT_NULL;
+ goto out;
+ }
+
+ up_arg->reason = upcall->reason;
+
+ if (upcall->reason == GLFS_UPCALL_INODE_INVALIDATE) {
+ struct glfs_callback_inode_arg *cb_inode = NULL;
+ struct glfs_upcall_inode *up_inode = NULL;
+
+ cb_inode = GF_CALLOC(1, sizeof(struct glfs_callback_inode_arg),
+ glfs_mt_upcall_inode_t);
+ if (!cb_inode) {
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
- pthread_mutex_lock (&fs->upcall_list_mutex);
- {
- list_for_each_entry_safe (u_list, tmp,
- &fs->upcall_list,
- upcall_list) {
- found = 1;
- break;
- }
- }
- /* No other thread can delete this entry. So unlock it */
- pthread_mutex_unlock (&fs->upcall_list_mutex);
-
- if (found) {
- upcall_data = &u_list->upcall_data;
-
- switch (upcall_data->event_type) {
- case GF_UPCALL_CACHE_INVALIDATION:
- /* XXX: Need to revisit this to support
- * GFAPI_INODE_UPDATE if required.
- */
- reason = GFAPI_INODE_INVALIDATE;
- ret = glfs_h_poll_cache_invalidation (fs,
- up_arg,
- upcall_data);
- if (!ret) {
- break;
- }
- /* It could so happen that the file which got
- * upcall notification may have got deleted
- * by other thread. Irrespective of the error,
- * log it and return with CBK_NULL reason.
- *
- * Applications will ignore this notification
- * as up_arg->object will be NULL */
- gf_msg (subvol->name, GF_LOG_WARNING, errno,
- API_MSG_CREATE_HANDLE_FAILED,
- "handle creation of %s failed",
- uuid_utoa (upcall_data->gfid));
-
- reason = GFAPI_CBK_EVENT_NULL;
- break;
- default:
- break;
- }
+ up_inode = upcall->event;
- up_arg->reason = reason;
+ /* copy attributes one by one, the memory layout might
+ * be different between the old glfs_callback_inode_arg
+ * and new glfs_upcall_inode */
+ cb_inode->object = up_inode->object;
+ cb_inode->flags = up_inode->flags;
+ memcpy(&cb_inode->buf, &up_inode->buf, sizeof(struct stat));
+ cb_inode->expire_time_attr = up_inode->expire_time_attr;
+ cb_inode->p_object = up_inode->p_object;
+ memcpy(&cb_inode->p_buf, &up_inode->p_buf, sizeof(struct stat));
+ cb_inode->oldp_object = up_inode->oldp_object;
+ memcpy(&cb_inode->oldp_buf, &up_inode->oldp_buf,
+ sizeof(struct stat));
- list_del_init (&u_list->upcall_list);
- GF_FREE (u_list->upcall_data.data);
- GF_FREE (u_list);
+ up_arg->event_arg = cb_inode;
}
-
- ret = 0;
+ }
out:
- pthread_mutex_lock (&fs->mutex);
- {
- fs->pin_refcnt--;
- }
- pthread_mutex_unlock (&fs->mutex);
+ if (upcall) {
+ /* we can not use glfs_free() here, objects need to stay */
+ GF_FREE(upcall->event);
+ GF_FREE(upcall);
+ }
- glfs_subvol_done (fs, subvol);
-
-restore:
- __GLFS_EXIT_FS;
-err:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_poll_upcall, 3.7.0);
-
#ifdef HAVE_ACL_LIBACL_H
-#include "glusterfs-acl.h"
+#include <glusterfs/glusterfs-acl.h>
#include <acl/libacl.h>
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0)
int
-pub_glfs_h_acl_set (struct glfs *fs, struct glfs_object *object,
- const acl_type_t type, const acl_t acl)
+pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object,
+ const acl_type_t type, const acl_t acl)
{
- int ret = -1;
- char *acl_s = NULL;
- const char *acl_key = NULL;
- struct glfs_object *new_object = NULL;
+ int ret = -1;
+ char *acl_s = NULL;
+ const char *acl_key = NULL;
+ struct glfs_object *new_object = NULL;
- DECLARE_OLD_THIS;
+ DECLARE_OLD_THIS;
- if (!object || !acl) {
- errno = EINVAL;
- return ret;
- }
+ if (!object || !acl) {
+ errno = EINVAL;
+ return ret;
+ }
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- acl_key = gf_posix_acl_get_key (type);
- if (!acl_key)
- goto out;
+ acl_key = gf_posix_acl_get_key(type);
+ if (!acl_key)
+ goto out;
- acl_s = acl_to_any_text (acl, NULL, ',',
- TEXT_ABBREVIATE | TEXT_NUMERIC_IDS);
- if (!acl_s)
- goto out;
+ acl_s = acl_to_any_text(acl, NULL, ',', TEXT_ABBREVIATE | TEXT_NUMERIC_IDS);
+ if (!acl_s)
+ goto out;
- if (IA_ISLNK (object->inode->ia_type)) {
- new_object = glfs_h_resolve_symlink (fs, object);
- if (new_object == NULL)
- goto out;
- } else
- new_object = object;
+ if (IA_ISLNK(object->inode->ia_type)) {
+ new_object = glfs_h_resolve_symlink(fs, object);
+ if (new_object == NULL)
+ goto out;
+ } else
+ new_object = object;
- ret = pub_glfs_h_setxattrs (fs, new_object, acl_key, acl_s,
- strlen (acl_s) + 1, 0);
+ ret = pub_glfs_h_setxattrs(fs, new_object, acl_key, acl_s,
+ strlen(acl_s) + 1, 0);
- acl_free (acl_s);
+ acl_free(acl_s);
out:
- if (IA_ISLNK (object->inode->ia_type) && new_object)
- glfs_h_close (new_object);
+ if (IA_ISLNK(object->inode->ia_type) && new_object)
+ glfs_h_close(new_object);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0)
acl_t
-pub_glfs_h_acl_get (struct glfs *fs, struct glfs_object *object,
- const acl_type_t type)
+pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object,
+ const acl_type_t type)
{
- int ret = 0;
- acl_t acl = NULL;
- char *acl_s = NULL;
- dict_t *xattr = NULL;
- const char *acl_key = NULL;
- struct glfs_object *new_object = NULL;
-
- DECLARE_OLD_THIS;
-
- if (!object) {
- errno = EINVAL;
- return NULL;
- }
+ int ret = 0;
+ acl_t acl = NULL;
+ char *acl_s = NULL;
+ dict_t *xattr = NULL;
+ const char *acl_key = NULL;
+ struct glfs_object *new_object = NULL;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ DECLARE_OLD_THIS;
- acl_key = gf_posix_acl_get_key (type);
- if (!acl_key)
- goto out;
+ if (!object) {
+ errno = EINVAL;
+ return NULL;
+ }
- if (IA_ISLNK (object->inode->ia_type)) {
- new_object = glfs_h_resolve_symlink (fs, object);
- if (new_object == NULL)
- goto out;
- } else
- new_object = object;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- ret = glfs_h_getxattrs_common (fs, new_object, &xattr, acl_key);
- if (ret)
- goto out;
+ acl_key = gf_posix_acl_get_key(type);
+ if (!acl_key)
+ goto out;
- ret = dict_get_str (xattr, (char *)acl_key, &acl_s);
- if (ret == -1)
- goto out;
+ if (IA_ISLNK(object->inode->ia_type)) {
+ new_object = glfs_h_resolve_symlink(fs, object);
+ if (new_object == NULL)
+ goto out;
+ } else
+ new_object = object;
+
+ ret = glfs_h_getxattrs_common(fs, new_object, &xattr, acl_key, _gf_false);
+ if (ret)
+ goto out;
- acl = acl_from_text (acl_s);
+ ret = dict_get_str(xattr, (char *)acl_key, &acl_s);
+ if (ret)
+ goto out;
+
+ acl = acl_from_text(acl_s);
out:
- GF_FREE (acl_s);
- if (IA_ISLNK (object->inode->ia_type) && new_object)
- glfs_h_close (new_object);
+ if (xattr)
+ dict_unref(xattr);
+
+ if (IA_ISLNK(object->inode->ia_type) && new_object)
+ glfs_h_close(new_object);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return acl;
+ return acl;
}
#else /* !HAVE_ACL_LIBACL_H */
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0)
acl_t
-pub_glfs_h_acl_get (struct glfs *fs, struct glfs_object *object,
- const acl_type_t type)
+pub_glfs_h_acl_get(struct glfs *fs, struct glfs_object *object,
+ const acl_type_t type)
{
- errno = ENOTSUP;
- return NULL;
+ errno = ENOTSUP;
+ return NULL;
}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0)
int
-pub_glfs_h_acl_set (struct glfs *fs, struct glfs_object *object,
- const acl_type_t type, const acl_t acl)
+pub_glfs_h_acl_set(struct glfs *fs, struct glfs_object *object,
+ const acl_type_t type, const acl_t acl)
{
- errno = ENOTSUP;
- return -1;
+ errno = ENOTSUP;
+ return -1;
}
#endif
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_set, 3.7.0);
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_acl_get, 3.7.0);
/* The API to perform read using anonymous fd */
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_read, 3.7.0)
ssize_t
-pub_glfs_h_anonymous_read (struct glfs *fs, struct glfs_object *object,
- const void *buf, size_t count, off_t offset)
+pub_glfs_h_anonymous_read(struct glfs *fs, struct glfs_object *object,
+ const void *buf, size_t count, off_t offset)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
-
- /* validate in args */
- if ((fs == NULL) || (object == NULL)) {
- errno = EINVAL;
- return -1;
- }
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
- iov.iov_base = (void *) buf;
- iov.iov_len = count;
+ iov.iov_base = (void *)buf;
+ iov.iov_len = count;
- ret = glfs_anonymous_preadv (fs, object, &iov, 1, offset, 0);
+ ret = glfs_anonymous_preadv(fs, object, &iov, 1, offset, 0);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_read, 3.7.0);
-
/* The API to perform write using anonymous fd */
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_write, 3.7.0)
ssize_t
-pub_glfs_h_anonymous_write (struct glfs *fs, struct glfs_object *object,
- const void *buf, size_t count, off_t offset)
+pub_glfs_h_anonymous_write(struct glfs *fs, struct glfs_object *object,
+ const void *buf, size_t count, off_t offset)
{
- struct iovec iov = {0, };
- ssize_t ret = 0;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t ret = 0;
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
- /* validate in args */
- if ((fs == NULL) || (object == NULL)) {
- errno = EINVAL;
- return -1;
- }
+ iov.iov_base = (void *)buf;
+ iov.iov_len = count;
- iov.iov_base = (void *) buf;
- iov.iov_len = count;
+ ret = glfs_anonymous_pwritev(fs, object, &iov, 1, offset, 0);
- ret = glfs_anonymous_pwritev (fs, object, &iov, 1, offset, 0);
+ return ret;
+}
- return ret;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_object_copy, 3.11.0)
+struct glfs_object *
+pub_glfs_object_copy(struct glfs_object *src)
+{
+ struct glfs_object *object = NULL;
+
+ GF_VALIDATE_OR_GOTO("glfs_dup_object", src, out);
+
+ object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
+ if (object == NULL) {
+ errno = ENOMEM;
+ gf_smsg(THIS->name, GF_LOG_WARNING, errno, API_MSG_CREATE_HANDLE_FAILED,
+ "glfs_dup_object gfid=%s", uuid_utoa(src->inode->gfid), NULL);
+ return NULL;
+ }
+
+ object->inode = inode_ref(src->inode);
+ gf_uuid_copy(object->gfid, src->inode->gfid);
+
+out:
+ return object;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_xreaddirplus_get_object, 3.11.0)
+struct glfs_object *
+pub_glfs_xreaddirplus_get_object(struct glfs_xreaddirp_stat *xstat)
+{
+ GF_VALIDATE_OR_GOTO("glfs_xreaddirplus_get_object", xstat, out);
+
+ if (!(xstat->flags_handled & GFAPI_XREADDIRP_HANDLE))
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_HANDLE_NOT_SET,
+ "GFAPI_XREADDIRP_HANDLE xstat=%p", xstat, "handle=%x",
+ xstat->flags_handled, NULL);
+
+ return xstat->object;
+
+out:
+ return NULL;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_anonymous_write, 3.7.0);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_h_lease, 4.0.0)
+int
+pub_glfs_h_lease(struct glfs *fs, struct glfs_object *object,
+ struct glfs_lease *lease)
+{
+ int ret = -1;
+ xlator_t *subvol = NULL;
+ inode_t *inode = NULL;
+ loc_t loc = {
+ 0,
+ };
+ struct gf_lease gf_lease = {
+ 0,
+ };
+
+ /* validate in args */
+ if ((fs == NULL) || (object == NULL)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* get the active volume */
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ /* get/refresh the in arg objects inode in correlation to the xlator */
+ inode = glfs_resolve_inode(fs, subvol, object);
+ if (!inode) {
+ errno = ESTALE;
+ goto out;
+ }
+
+ /* populate loc */
+ GLFS_LOC_FILL_INODE(inode, loc, out);
+
+ glfs_lease_to_gf_lease(lease, &gf_lease);
+
+ ret = syncop_lease(subvol, &loc, &gf_lease, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ gf_lease_to_glfs_lease(&gf_lease, lease);
+
+out:
+ loc_wipe(&loc);
+
+ if (inode)
+ inode_unref(inode);
+
+ glfs_subvol_done(fs, subvol);
+
+ __GLFS_EXIT_FS;
+
+invalid_fs:
+ return ret;
+}
diff --git a/api/src/glfs-handles.h b/api/src/glfs-handles.h
index 6446cc30c7d..4d039b9c76b 100644
--- a/api/src/glfs-handles.h
+++ b/api/src/glfs-handles.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2013-2018 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
@@ -46,46 +46,39 @@
*
*/
-/* Values for valid falgs to be used when using XXXsetattr, to set multiple
- attribute values passed via the related stat structure.
- */
-#define GFAPI_SET_ATTR_MODE 0x1
-#define GFAPI_SET_ATTR_UID 0x2
-#define GFAPI_SET_ATTR_GID 0x4
-#define GFAPI_SET_ATTR_SIZE 0x8
-#define GFAPI_SET_ATTR_ATIME 0x10
-#define GFAPI_SET_ATTR_MTIME 0x20
-
/* Handle length for object handles returned from glfs_h_extract_handle or
* glfs_h_create_from_handle */
#define GFAPI_HANDLE_LENGTH 16
/* These flags should be in sync to the ones defined in upcall.h */
-#define GFAPI_UP_NLINK 0x00000001 /* update nlink */
-#define GFAPI_UP_MODE 0x00000002 /* update mode and ctime */
-#define GFAPI_UP_OWN 0x00000004 /* update mode,uid,gid and ctime */
-#define GFAPI_UP_SIZE 0x00000008 /* update fsize */
-#define GFAPI_UP_TIMES 0x00000010 /* update all times */
-#define GFAPI_UP_ATIME 0x00000020 /* update atime only */
-#define GFAPI_UP_PERM 0x00000040 /* update fields needed for
- permission checking */
-#define GFAPI_UP_RENAME 0x00000080 /* this is a rename op -
- delete the cache entry */
-#define GFAPI_UP_FORGET 0x00000100 /* inode_forget on server side -
- invalidate the cache entry */
-#define GFAPI_UP_PARENT_TIMES 0x00000200 /* update parent dir times */
-
-#define GFAPI_INODE_UPDATE_FLAGS (GFAPI_UP_NLINK | GFAPI_UP_MODE | \
- GFAPI_UP_OWN | GFAPI_UP_SIZE | \
- GFAPI_UP_TIMES | GFAPI_UP_ATIME)
+#define GFAPI_UP_NLINK 0x00000001 /* update nlink */
+#define GFAPI_UP_MODE 0x00000002 /* update mode and ctime */
+#define GFAPI_UP_OWN 0x00000004 /* update mode,uid,gid and ctime */
+#define GFAPI_UP_SIZE 0x00000008 /* update fsize */
+#define GFAPI_UP_TIMES 0x00000010 /* update all times */
+#define GFAPI_UP_ATIME 0x00000020 /* update atime only */
+#define GFAPI_UP_PERM \
+ 0x00000040 /* update fields needed for \
+ permission checking */
+#define GFAPI_UP_RENAME \
+ 0x00000080 /* this is a rename op - \
+ delete the cache entry */
+#define GFAPI_UP_FORGET \
+ 0x00000100 /* inode_forget on server side - \
+ invalidate the cache entry */
+#define GFAPI_UP_PARENT_TIMES 0x00000200 /* update parent dir times */
+
+#define GFAPI_INODE_UPDATE_FLAGS \
+ (GFAPI_UP_NLINK | GFAPI_UP_MODE | GFAPI_UP_OWN | GFAPI_UP_SIZE | \
+ GFAPI_UP_TIMES | GFAPI_UP_ATIME)
/* Portability non glibc c++ build systems */
#ifndef __THROW
-# if defined __cplusplus
-# define __THROW throw ()
-# else
-# define __THROW
-# endif
+#if defined __cplusplus
+#define __THROW throw()
+#else
+#define __THROW
+#endif
#endif
__BEGIN_DECLS
@@ -101,168 +94,167 @@ __BEGIN_DECLS
struct glfs_object;
typedef struct glfs_object glfs_object_t;
-/*
- * Applications (currently NFS-Ganesha) can make use of this
- * structure to read upcall notifications sent by server.
- *
- * On success, applications need to check for 'reason' to decide
- * if any upcall event is received.
- *
- * Currently supported upcall_events -
- * GFAPI_INODE_INVALIDATE -
- * 'event_arg' - callback_inode_arg
+/* Functions for getting details about the glfs_upcall_inode
*
- * After processing the event, applications need to free 'event_arg'.
+ * None of the pointers returned by the below functions should be free()'d,
+ * glfs_free()'d or glfs_h_close()'d by the application.
*
- * Also similar to I/Os, the application should ideally stop polling
- * before calling glfs_fini(..). Hence making an assumption that
- * 'fs' & ctx structures cannot be freed while in this routine.
+ * Releasing of the structures is done by passing the glfs_upcall pointer
+ * to glfs_free().
*/
-struct callback_arg {
- struct glfs *fs; /* glfs object */
- int reason; /* Upcall event type */
- void *event_arg; /* changes based in the event type */
-};
+struct glfs_upcall_inode;
+typedef struct glfs_upcall_inode glfs_upcall_inode_t;
-/*
- * After processing upcall event, they need to free "object" , "p_object",
- * "oldp_object" using glfs_h_close(..).
- */
-struct callback_inode_arg {
- struct glfs_object *object; /* Object which need to be acted upon */
- int flags; /* Cache UPDATE/INVALIDATE flags */
- struct stat buf; /* Latest stat of this entry */
- unsigned int expire_time_attr; /* the amount of time for which
- * the application need to cache
- * this entry
- */
- struct glfs_object *p_object; /* parent Object to be updated */
- struct stat p_buf; /* Latest stat of parent dir handle */
- struct glfs_object *oldp_object; /* Old parent Object
- * to be updated */
- struct stat oldp_buf; /* Latest stat of old parent
- * dir handle */
-};
-
-/* reason list in callback_arg */
-enum gfapi_callback_type {
- GFAPI_CBK_EVENT_NULL,
- GFAPI_INODE_INVALIDATE, /* invalidate cache entry */
-};
+glfs_object_t *
+glfs_upcall_inode_get_object(glfs_upcall_inode_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_inode_get_object, 3.7.16);
+
+uint64_t
+glfs_upcall_inode_get_flags(glfs_upcall_inode_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_inode_get_flags, 3.7.16);
+
+struct stat *
+glfs_upcall_inode_get_stat(glfs_upcall_inode_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_inode_get_stat, 3.7.16);
+
+uint64_t
+glfs_upcall_inode_get_expire(glfs_upcall_inode_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_inode_get_expire, 3.7.16);
+
+glfs_object_t *
+glfs_upcall_inode_get_pobject(glfs_upcall_inode_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_inode_get_pobject, 3.7.16);
+
+struct stat *
+glfs_upcall_inode_get_pstat(glfs_upcall_inode_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_inode_get_pstat, 3.7.16);
+
+glfs_object_t *
+glfs_upcall_inode_get_oldpobject(glfs_upcall_inode_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_inode_get_oldpobject, 3.7.16);
+
+struct stat *
+glfs_upcall_inode_get_oldpstat(glfs_upcall_inode_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_inode_get_oldpstat, 3.7.16);
/* Handle based operations */
/* Operations that generate handles */
-struct glfs_object *glfs_h_lookupat (struct glfs *fs,
- struct glfs_object *parent,
- const char *path,
- struct stat *stat, int follow) __THROW
- GFAPI_PUBLIC(glfs_h_lookupat, 3.7.4);
-
-struct glfs_object *glfs_h_creat (struct glfs *fs, struct glfs_object *parent,
- const char *path, int flags, mode_t mode,
- struct stat *sb) __THROW
- GFAPI_PUBLIC(glfs_h_create, 3.4.2);
-
-struct glfs_object *glfs_h_mkdir (struct glfs *fs, struct glfs_object *parent,
- const char *path, mode_t flags,
- struct stat *sb) __THROW
- GFAPI_PUBLIC(glfs_h_mkdir, 3.4.2);
-
-struct glfs_object *glfs_h_mknod (struct glfs *fs, struct glfs_object *parent,
- const char *path, mode_t mode, dev_t dev,
- struct stat *sb) __THROW
- GFAPI_PUBLIC(glfs_h_mknod, 3.4.2);
-
-struct glfs_object *glfs_h_symlink (struct glfs *fs, struct glfs_object *parent,
- const char *name, const char *data,
- struct stat *stat) __THROW
- GFAPI_PUBLIC(glfs_h_symlink, 3.4.2);
+glfs_object_t *
+glfs_h_lookupat(glfs_t *fs, glfs_object_t *parent, const char *path,
+ struct stat *stat, int follow) __THROW
+ GFAPI_PUBLIC(glfs_h_lookupat, 3.7.4);
+
+glfs_object_t *
+glfs_h_creat(glfs_t *fs, glfs_object_t *parent, const char *path, int flags,
+ mode_t mode, struct stat *sb) __THROW
+ GFAPI_PUBLIC(glfs_h_creat, 3.4.2);
+
+glfs_object_t *
+glfs_h_mkdir(glfs_t *fs, glfs_object_t *parent, const char *path, mode_t flags,
+ struct stat *sb) __THROW GFAPI_PUBLIC(glfs_h_mkdir, 3.4.2);
+
+glfs_object_t *
+glfs_h_mknod(glfs_t *fs, glfs_object_t *parent, const char *path, mode_t mode,
+ dev_t dev, struct stat *sb) __THROW
+ GFAPI_PUBLIC(glfs_h_mknod, 3.4.2);
+
+glfs_object_t *
+glfs_h_symlink(glfs_t *fs, glfs_object_t *parent, const char *name,
+ const char *data, struct stat *stat) __THROW
+ GFAPI_PUBLIC(glfs_h_symlink, 3.4.2);
/* Operations on the actual objects */
-int glfs_h_unlink (struct glfs *fs, struct glfs_object *parent,
- const char *path) __THROW
- GFAPI_PUBLIC(glfs_h_unlink, 3.4.2);
+int
+glfs_h_unlink(glfs_t *fs, glfs_object_t *parent, const char *path) __THROW
+ GFAPI_PUBLIC(glfs_h_unlink, 3.4.2);
-int glfs_h_close (struct glfs_object *object) __THROW
- GFAPI_PUBLIC(glfs_h_close, 3.4.2);
+int
+glfs_h_close(glfs_object_t *object) __THROW GFAPI_PUBLIC(glfs_h_close, 3.4.2);
-int glfs_caller_specific_init (void *uid_caller_key, void *gid_caller_key,
- void *future) __THROW
- GFAPI_PUBLIC(glfs_caller_specific_init, 3.5.0);
+int
+glfs_caller_specific_init(void *uid_caller_key, void *gid_caller_key,
+ void *future) __THROW
+ GFAPI_PUBLIC(glfs_caller_specific_init, 3.5.0);
-int glfs_h_truncate (struct glfs *fs, struct glfs_object *object,
- off_t offset) __THROW
- GFAPI_PUBLIC(glfs_h_truncate, 3.4.2);
+int
+glfs_h_truncate(glfs_t *fs, glfs_object_t *object, off_t offset) __THROW
+ GFAPI_PUBLIC(glfs_h_truncate, 3.4.2);
-int glfs_h_stat(struct glfs *fs, struct glfs_object *object,
- struct stat *stat) __THROW
- GFAPI_PUBLIC(glfs_h_stat, 3.4.2);
+int
+glfs_h_stat(glfs_t *fs, glfs_object_t *object, struct stat *stat) __THROW
+ GFAPI_PUBLIC(glfs_h_stat, 3.4.2);
-int glfs_h_statfs(struct glfs *fs, struct glfs_object *object,
- struct statvfs *stat) __THROW
- GFAPI_PUBLIC(glfs_h_statfs, 3.7.0);
+int
+glfs_h_statfs(glfs_t *fs, glfs_object_t *object, struct statvfs *stat) __THROW
+ GFAPI_PUBLIC(glfs_h_statfs, 3.7.0);
-int glfs_h_getattrs (struct glfs *fs, struct glfs_object *object,
- struct stat *stat) __THROW
- GFAPI_PUBLIC(glfs_h_getattrs, 3.4.2);
+int
+glfs_h_getattrs(glfs_t *fs, glfs_object_t *object, struct stat *stat) __THROW
+ GFAPI_PUBLIC(glfs_h_getattrs, 3.4.2);
-int glfs_h_getxattrs (struct glfs *fs, struct glfs_object *object,
- const char *name, void *value,
- size_t size) __THROW
- GFAPI_PUBLIC(glfs_h_getxattrs, 3.5.1);
+int
+glfs_h_getxattrs(glfs_t *fs, glfs_object_t *object, const char *name,
+ void *value, size_t size) __THROW
+ GFAPI_PUBLIC(glfs_h_getxattrs, 3.5.1);
-int glfs_h_setattrs (struct glfs *fs, struct glfs_object *object,
- struct stat *sb, int valid) __THROW
- GFAPI_PUBLIC(glfs_h_setattrs, 3.4.2);
+int
+glfs_h_setattrs(glfs_t *fs, glfs_object_t *object, struct stat *sb,
+ int valid) __THROW GFAPI_PUBLIC(glfs_h_setattrs, 3.4.2);
-int glfs_h_setxattrs (struct glfs *fs, struct glfs_object *object,
- const char *name, const void *value,
- size_t size, int flags) __THROW
- GFAPI_PUBLIC(glfs_h_setxattrs, 3.5.0);
+int
+glfs_h_setxattrs(glfs_t *fs, glfs_object_t *object, const char *name,
+ const void *value, size_t size, int flags) __THROW
+ GFAPI_PUBLIC(glfs_h_setxattrs, 3.5.0);
-int glfs_h_readlink (struct glfs *fs, struct glfs_object *object, char *buf,
- size_t bufsiz) __THROW
- GFAPI_PUBLIC(glfs_h_readlink, 3.4.2);
+int
+glfs_h_readlink(glfs_t *fs, glfs_object_t *object, char *buf,
+ size_t bufsiz) __THROW GFAPI_PUBLIC(glfs_h_readlink, 3.4.2);
-int glfs_h_link (struct glfs *fs, struct glfs_object *linktgt,
- struct glfs_object *parent, const char *name) __THROW
- GFAPI_PUBLIC(glfs_h_link, 3.4.2);
+int
+glfs_h_link(glfs_t *fs, glfs_object_t *linktgt, glfs_object_t *parent,
+ const char *name) __THROW GFAPI_PUBLIC(glfs_h_link, 3.4.2);
-int glfs_h_rename (struct glfs *fs, struct glfs_object *olddir,
- const char *oldname, struct glfs_object *newdir,
- const char *newname) __THROW
- GFAPI_PUBLIC(glfs_h_rename, 3.4.2);
+int
+glfs_h_rename(glfs_t *fs, glfs_object_t *olddir, const char *oldname,
+ glfs_object_t *newdir, const char *newname) __THROW
+ GFAPI_PUBLIC(glfs_h_rename, 3.4.2);
-int glfs_h_removexattrs (struct glfs *fs, struct glfs_object *object,
- const char *name) __THROW
- GFAPI_PUBLIC(glfs_h_removexattrs, 3.5.1);
+int
+glfs_h_removexattrs(glfs_t *fs, glfs_object_t *object, const char *name) __THROW
+ GFAPI_PUBLIC(glfs_h_removexattrs, 3.5.1);
/* Operations enabling opaque invariant handle to object transitions */
-ssize_t glfs_h_extract_handle (struct glfs_object *object,
- unsigned char *handle, int len) __THROW
- GFAPI_PUBLIC(glfs_h_extract_handle, 3.4.2);
+ssize_t
+glfs_h_extract_handle(glfs_object_t *object, unsigned char *handle,
+ int len) __THROW
+ GFAPI_PUBLIC(glfs_h_extract_handle, 3.4.2);
/* Given a handle, looks up the inode and creates glfs_object.
* In addition, if provided 'stat', copies the inode attributes
*/
-struct glfs_object *glfs_h_create_from_handle (struct glfs *fs,
- unsigned char *handle, int len,
- struct stat *stat) __THROW
- GFAPI_PUBLIC(glfs_h_create_from_handle, 3.4.2);
+glfs_object_t *
+glfs_h_create_from_handle(glfs_t *fs, unsigned char *handle, int len,
+ struct stat *stat) __THROW
+ GFAPI_PUBLIC(glfs_h_create_from_handle, 3.4.2);
/* Operations enabling object handles to fd transitions */
-struct glfs_fd *glfs_h_opendir (struct glfs *fs,
- struct glfs_object *object) __THROW
- GFAPI_PUBLIC(glfs_h_opendir, 3.4.2);
+glfs_fd_t *
+glfs_h_opendir(glfs_t *fs, glfs_object_t *object) __THROW
+ GFAPI_PUBLIC(glfs_h_opendir, 3.4.2);
-struct glfs_fd *glfs_h_open (struct glfs *fs, struct glfs_object *object,
- int flags) __THROW
- GFAPI_PUBLIC(glfs_h_open, 3.4.2);
+glfs_fd_t *
+glfs_h_open(glfs_t *fs, glfs_object_t *object, int flags) __THROW
+ GFAPI_PUBLIC(glfs_h_open, 3.4.2);
int
-glfs_h_access (struct glfs *fs, struct glfs_object *object, int mask) __THROW
- GFAPI_PUBLIC(glfs_h_access, 3.6.0);
-
+glfs_h_access(glfs_t *fs, glfs_object_t *object, int mask) __THROW
+ GFAPI_PUBLIC(glfs_h_access, 3.6.0);
+
+struct glfs_object *
+glfs_h_creat_open(struct glfs *fs, struct glfs_object *parent, const char *path,
+ int flags, mode_t mode, struct stat *stat,
+ struct glfs_fd **out_fd) __THROW
+ GFAPI_PUBLIC(glfs_h_creat_open, 6.6);
/*
SYNOPSIS
@@ -272,8 +264,8 @@ glfs_h_access (struct glfs *fs, struct glfs_object *object, int mask) __THROW
This API is used to poll for upcall events stored in the
upcall list. Current users of this API is NFS-Ganesha.
- Incase of any event received, it will be mapped appropriately
- into 'callback_arg' along with the handle('glfs_object') to be
+ In case of any event received, it will be mapped appropriately
+ into 'glfs_upcall' along with the handle('glfs_object') to be
passed to NFS-Ganesha.
In case of success, applications need to check the value of
@@ -283,11 +275,8 @@ glfs_h_access (struct glfs *fs, struct glfs_object *object, int mask) __THROW
PARAMETERS
@fs: glfs object to poll the upcall events for
- @cbk: Structure to store upcall events as desired by the application.
- Application is responsible for allocating and passing the
- references of all the pointers of this structure except for
- "handle". In case of any events received, it needs to free
- "handle"
+ @cbk: Pointer that will contain an upcall event for use by the application.
+ Application is responsible for free'ing the structure with glfs_free().
RETURN VALUES
@@ -297,28 +286,69 @@ glfs_h_access (struct glfs *fs, struct glfs_object *object, int mask) __THROW
*/
int
-glfs_h_poll_upcall (struct glfs *fs, struct callback_arg *cbk) __THROW
- GFAPI_PUBLIC(glfs_h_poll_upcall, 3.7.0);
+glfs_h_poll_upcall(glfs_t *fs, glfs_upcall_t **cbk) __THROW
+ GFAPI_PUBLIC(glfs_h_poll_upcall, 3.7.16);
int
-glfs_h_acl_set (struct glfs *fs, struct glfs_object *object,
- const acl_type_t type, const acl_t acl) __THROW
- GFAPI_PUBLIC(glfs_h_acl_set, 3.7.0);
+glfs_h_acl_set(glfs_t *fs, glfs_object_t *object, const acl_type_t type,
+ const acl_t acl) __THROW GFAPI_PUBLIC(glfs_h_acl_set, 3.7.0);
acl_t
-glfs_h_acl_get (struct glfs *fs, struct glfs_object *object,
- const acl_type_t type) __THROW
- GFAPI_PUBLIC(glfs_h_acl_get, 3.7.0);
+glfs_h_acl_get(glfs_t *fs, glfs_object_t *object, const acl_type_t type) __THROW
+ GFAPI_PUBLIC(glfs_h_acl_get, 3.7.0);
size_t
-glfs_h_anonymous_write (struct glfs *fs, struct glfs_object *object,
- const void *buf, size_t count, off_t offset) __THROW
- GFAPI_PUBLIC(glfs_h_anonymous_write, 3.7.0);
+glfs_h_anonymous_write(glfs_t *fs, glfs_object_t *object, const void *buf,
+ size_t count, off_t offset) __THROW
+ GFAPI_PUBLIC(glfs_h_anonymous_write, 3.7.0);
ssize_t
-glfs_h_anonymous_read (struct glfs *fs, struct glfs_object *object,
- const void *buf, size_t count, off_t offset) __THROW
- GFAPI_PUBLIC(glfs_h_anonymous_read, 3.7.0);
+glfs_h_anonymous_read(glfs_t *fs, glfs_object_t *object, const void *buf,
+ size_t count, off_t offset) __THROW
+ GFAPI_PUBLIC(glfs_h_anonymous_read, 3.7.0);
+
+/*
+ * Caution: The object returned by this object gets freed as part
+ * of 'glfs_free(xstat)'. Make sure to have a copy using 'glfs_object_copy()'
+ * to use post that.
+ */
+glfs_object_t *
+glfs_xreaddirplus_get_object(struct glfs_xreaddirp_stat *xstat) __THROW
+ GFAPI_PUBLIC(glfs_xreaddirplus_get_object, 3.11.0);
+
+/* Applications should close the object returned by this routine
+ * explicitly using 'glfs_h_close()'
+ */
+glfs_object_t *
+glfs_object_copy(glfs_object_t *src) __THROW
+ GFAPI_PUBLIC(glfs_object_copy, 3.11.0);
+
+int
+glfs_h_lease(glfs_t *fs, glfs_object_t *object, glfs_lease_t *lease) __THROW
+ GFAPI_PUBLIC(glfs_h_lease, 4.0.0);
+
+glfs_object_t *
+glfs_h_find_handle(glfs_t *fs, unsigned char *handle, int len) __THROW
+ GFAPI_PUBLIC(glfs_h_lease, 4.0.0);
+
+/* Functions for getting details about the glfs_upcall_lease
+ *
+ * None of the pointers returned by the below functions should be free()'d,
+ * glfs_free()'d or glfs_h_close()'d by the application.
+ *
+ * Releasing of the structures is done by passing the glfs_upcall pointer
+ * to glfs_free().
+ */
+struct glfs_upcall_lease;
+typedef struct glfs_upcall_lease glfs_upcall_lease_t;
+
+glfs_object_t *
+glfs_upcall_lease_get_object(glfs_upcall_lease_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_lease_get_object, 4.1.6);
+
+uint32_t
+glfs_upcall_lease_get_lease_type(glfs_upcall_lease_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_lease_get_lease_type, 4.1.6);
__END_DECLS
diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h
index 2702505f765..7cc3b18a104 100644
--- a/api/src/glfs-internal.h
+++ b/api/src/glfs-internal.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2012-2018 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
@@ -8,24 +8,25 @@
cases as published by the Free Software Foundation.
*/
-
#ifndef _GLFS_INTERNAL_H
#define _GLFS_INTERNAL_H
-#include "xlator.h"
-#include "glusterfs.h"
-#include "upcall-utils.h"
+#include <glusterfs/xlator.h>
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/upcall-utils.h>
#include "glfs-handles.h"
+#include <glusterfs/refcount.h>
+#include <glusterfs/syncop.h>
#define GLFS_SYMLINK_MAX_FOLLOW 2048
#define DEFAULT_REVAL_COUNT 1
/*
- * According to pthread mutex and conditional variable ( cond, child_down_count,
- * upcall mutex and mutex) initialization of struct glfs members,
- * below GLFS_INIT_* flags are set in 'pthread_flags' member of struct glfs.
- * The flags are set from glfs_init() and glfs_new_from_ctx() functions
+ * According to pthread mutex and conditional variable ( cond,
+ * child_down_count, upcall mutex and mutex) initialization of struct glfs
+ * members, below GLFS_INIT_* flags are set in 'pthread_flags' member of struct
+ * glfs. The flags are set from glfs_init() and glfs_new_from_ctx() functions
* as part of fs inititialization.
*
* These flag bits are validated in glfs_fini() to destroy all or partially
@@ -36,39 +37,42 @@
*
*/
-#define PTHREAD_MUTEX_INIT(mutex, attr, flags, mask, label) do { \
- int __ret = -1; \
- __ret = pthread_mutex_init (mutex, attr); \
- if (__ret == 0) \
- flags |= mask; \
- else \
- goto label; \
-} while (0)
-
-#define PTHREAD_MUTEX_DESTROY(mutex, flags, mask) do { \
- if (flags & mask) \
- (void) pthread_mutex_destroy (mutex); \
-} while (0)
-
-#define PTHREAD_COND_INIT(cond, attr, flags, mask, label) do { \
- int __ret = -1; \
- __ret = pthread_cond_init (cond, attr); \
- if (__ret == 0) \
- flags |= mask; \
- else \
- goto label; \
-} while (0)
-
-#define PTHREAD_COND_DESTROY(cond, flags, mask) do { \
- if (flags & mask) \
- (void) pthread_cond_destroy (cond); \
-} while (0)
-
-#define GLFS_INIT_MUTEX 0x00000001 /* pthread_mutex_flag */
-#define GLFS_INIT_COND 0x00000002 /* pthread_cond_flag */
-#define GLFS_INIT_COND_CHILD 0x00000004 /* pthread_cond_child_down_flag */
-#define GLFS_INIT_MUTEX_UPCALL 0x00000008 /* pthread_mutex_upcall_flag */
-
+#define PTHREAD_MUTEX_INIT(mutex, attr, flags, mask, label) \
+ do { \
+ int __ret = -1; \
+ __ret = pthread_mutex_init(mutex, attr); \
+ if (__ret == 0) \
+ flags |= mask; \
+ else \
+ goto label; \
+ } while (0)
+
+#define PTHREAD_MUTEX_DESTROY(mutex, flags, mask) \
+ do { \
+ if (flags & mask) \
+ (void)pthread_mutex_destroy(mutex); \
+ } while (0)
+
+#define PTHREAD_COND_INIT(cond, attr, flags, mask, label) \
+ do { \
+ int __ret = -1; \
+ __ret = pthread_cond_init(cond, attr); \
+ if (__ret == 0) \
+ flags |= mask; \
+ else \
+ goto label; \
+ } while (0)
+
+#define PTHREAD_COND_DESTROY(cond, flags, mask) \
+ do { \
+ if (flags & mask) \
+ (void)pthread_cond_destroy(cond); \
+ } while (0)
+
+#define GLFS_INIT_MUTEX 0x00000001 /* pthread_mutex_flag */
+#define GLFS_INIT_COND 0x00000002 /* pthread_cond_flag */
+#define GLFS_INIT_COND_CHILD 0x00000004 /* pthread_cond_child_down_flag */
+#define GLFS_INIT_MUTEX_UPCALL 0x00000008 /* pthread_mutex_upcall_flag */
#ifndef GF_DARWIN_HOST_OS
#ifndef GFAPI_PUBLIC
@@ -77,204 +81,411 @@
#ifndef GFAPI_PRIVATE
#define GFAPI_PRIVATE(sym, ver) /**/
#endif
-#define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, ver) \
- asm(".symver pub_"STR(fn)", "STR(fn)"@@GFAPI_"STR(ver))
+#if __GNUC__ >= 10
+#define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, ver) \
+ __attribute__((__symver__(STR(fn) "@@GFAPI_" STR(ver))))
+
+#define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, ver) \
+ __attribute__((__symver__(STR(fn) "@@GFAPI_PRIVATE_" STR(ver))))
+
+#define GFAPI_SYMVER_PUBLIC(fn1, fn2, ver) \
+ __attribute__((__symver__(STR(fn2) "@GFAPI_" STR(ver))))
-#define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, ver) \
- asm(".symver priv_"STR(fn)", "STR(fn)"@@GFAPI_PRIVATE_"STR(ver))
+#define GFAPI_SYMVER_PRIVATE(fn1, fn2, ver) \
+ __attribute__((__symver__(STR(fn2) "@GFAPI_PRIVATE_" STR(ver))))
-#define GFAPI_SYMVER_PUBLIC(fn1, fn2, ver) \
- asm(".symver pub_"STR(fn1)", "STR(fn2)"@GFAPI_"STR(ver))
+#else
+#define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, ver) \
+ asm(".symver pub_" STR(fn) ", " STR(fn) "@@GFAPI_" STR(ver));
+
+#define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, ver) \
+ asm(".symver priv_" STR(fn) ", " STR(fn) "@@GFAPI_PRIVATE_" STR(ver));
-#define GFAPI_SYMVER_PRIVATE(fn1, fn2, ver) \
- asm(".symver priv_"STR(fn1)", "STR(fn2)"@GFAPI_PRIVATE_"STR(ver))
+#define GFAPI_SYMVER_PUBLIC(fn1, fn2, ver) \
+ asm(".symver pub_" STR(fn1) ", " STR(fn2) "@GFAPI_" STR(ver));
+
+#define GFAPI_SYMVER_PRIVATE(fn1, fn2, ver) \
+ asm(".symver priv_" STR(fn1) ", " STR(fn2) "@GFAPI_PRIVATE_" STR(ver));
+#endif
#define STR(str) #str
#else
#ifndef GFAPI_PUBLIC
-#define GFAPI_PUBLIC(sym, ver) __asm("_" __STRING(sym) "$GFAPI_" __STRING(ver))
+#define GFAPI_PUBLIC(sym, ver) __asm("_" __STRING(sym) "$GFAPI_" __STRING(ver));
#endif
#ifndef GFAPI_PRIVATE
-#define GFAPI_PRIVATE(sym, ver) __asm("_" __STRING(sym) "$GFAPI_PRIVATE_" __STRING(ver))
+#define GFAPI_PRIVATE(sym, ver) \
+ __asm("_" __STRING(sym) "$GFAPI_PRIVATE_" __STRING(ver));
#endif
-#define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, dotver) /**/
+#define GFAPI_SYMVER_PUBLIC_DEFAULT(fn, dotver) /**/
#define GFAPI_SYMVER_PRIVATE_DEFAULT(fn, dotver) /**/
-#define GFAPI_SYMVER_PUBLIC(fn1, fn2, dotver) /**/
-#define GFAPI_SYMVER_PRIVATE(fn1, fn2, dotver) /**/
+#define GFAPI_SYMVER_PUBLIC(fn1, fn2, dotver) /**/
+#define GFAPI_SYMVER_PRIVATE(fn1, fn2, dotver) /**/
#endif
-/*
- * syncop_xxx() calls are executed in two ways, one is inside a synctask where
- * the executing function will do 'swapcontext' and the other is without
- * synctask where the executing thread is made to wait using pthread_cond_wait.
- * Executing thread may change when syncop_xxx() is executed inside a synctask.
- * This leads to errno_location change i.e. errno may give errno of
- * non-executing thread. So errno is not touched inside a synctask execution.
- * All gfapi calls are executed using the second way of executing syncop_xxx()
- * where the executing thread waits using pthread_cond_wait so it is ok to set
- * errno in these cases. The following macro makes syncop_xxx() behave just
- * like a system call, where -1 is returned and errno is set when a failure
- * occurs.
- */
-#define DECODE_SYNCOP_ERR(ret) do { \
- if (ret < 0) { \
- errno = -ret; \
- ret = -1; \
- } \
- } while (0)
-
-#define ESTALE_RETRY(ret,errno,reval,loc,label) do { \
- if (ret == -1 && errno == ESTALE) { \
- if (reval < DEFAULT_REVAL_COUNT) { \
- reval++; \
- loc_wipe (loc); \
- goto label; \
- } \
- } \
- } while (0)
-
-#define GLFS_LOC_FILL_INODE(oinode, loc, label) do { \
- loc.inode = inode_ref (oinode); \
- gf_uuid_copy (loc.gfid, oinode->gfid); \
- ret = glfs_loc_touchup (&loc); \
- if (ret != 0) { \
- errno = EINVAL; \
- goto label; \
- } \
- } while (0)
-
-#define GLFS_LOC_FILL_PINODE(pinode, loc, ret, errno, label, path) do { \
- loc.inode = inode_new (pinode->table); \
- if (!loc.inode) { \
- ret = -1; \
- errno = ENOMEM; \
- goto label; \
- } \
- loc.parent = inode_ref (pinode); \
- loc.name = path; \
- ret = glfs_loc_touchup (&loc); \
- if (ret != 0) { \
- errno = EINVAL; \
- goto label; \
- } \
- } while (0)
+#define ESTALE_RETRY(ret, errno, reval, loc, label) \
+ do { \
+ if (ret == -1 && errno == ESTALE) { \
+ if (reval < DEFAULT_REVAL_COUNT) { \
+ reval++; \
+ loc_wipe(loc); \
+ goto label; \
+ } \
+ } \
+ } while (0)
+
+#define GLFS_LOC_FILL_INODE(oinode, loc, label) \
+ do { \
+ loc.inode = inode_ref(oinode); \
+ gf_uuid_copy(loc.gfid, oinode->gfid); \
+ ret = glfs_loc_touchup(&loc); \
+ if (ret != 0) { \
+ errno = EINVAL; \
+ goto label; \
+ } \
+ } while (0)
+
+#define GLFS_LOC_FILL_PINODE(pinode, loc, ret, errno, label, path) \
+ do { \
+ loc.inode = inode_new(pinode->table); \
+ if (!loc.inode) { \
+ ret = -1; \
+ errno = ENOMEM; \
+ goto label; \
+ } \
+ loc.parent = inode_ref(pinode); \
+ loc.name = path; \
+ ret = glfs_loc_touchup(&loc); \
+ if (ret != 0) { \
+ errno = EINVAL; \
+ goto label; \
+ } \
+ } while (0)
struct glfs;
-struct _upcall_entry_t {
- struct list_head upcall_list;
- struct gf_upcall upcall_data;
+struct _upcall_entry {
+ struct list_head upcall_list;
+ struct gf_upcall upcall_data;
};
-typedef struct _upcall_entry_t upcall_entry;
+typedef struct _upcall_entry upcall_entry;
-typedef int (*glfs_init_cbk) (struct glfs *fs, int ret);
+typedef int (*glfs_init_cbk)(struct glfs *fs, int ret);
struct glfs {
- char *volname;
- uuid_t vol_uuid;
+ char *volname;
+ uuid_t vol_uuid;
+
+ glusterfs_ctx_t *ctx;
+
+ pthread_t poller;
+
+ glfs_init_cbk init_cbk;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ pthread_cond_t child_down_cond; /* for broadcasting CHILD_DOWN */
+ int init;
+ int ret;
+ int err;
+
+ xlator_t *active_subvol; /* active graph */
+ xlator_t *mip_subvol; /* graph for which migration is in
+ * progress */
+ xlator_t *next_subvol; /* Any new graph is put to
+ * next_subvol, the graph in
+ * next_subvol can either be moved
+ * to mip_subvol (if any IO picks it
+ * up for migration), or be
+ * destroyed (if there is a new
+ * graph, and this was never picked
+ * for migration) */
+ xlator_t *old_subvol;
+
+ char *oldvolfile;
+ ssize_t oldvollen;
+
+ inode_t *cwd;
+
+ uint32_t dev_id; /* Used to fill st_dev in struct stat */
+
+ struct list_head openfds;
+
+ gf_boolean_t migration_in_progress;
+
+ gf_boolean_t cache_upcalls; /* add upcalls to the upcall_list? */
+ struct list_head upcall_list;
+ pthread_mutex_t upcall_list_mutex; /* mutex for upcall entry list */
+
+ uint32_t pin_refcnt;
+ uint32_t pthread_flags; /* GLFS_INIT_* # defines set this flag */
+
+ uint32_t upcall_events; /* Mask of upcall events application
+ * is interested in */
+ glfs_upcall_cbk up_cbk; /* upcall cbk function to be registered */
+ void *up_data; /* Opaque data provided by application
+ * during upcall registration */
+ struct list_head waitq; /* waiting synctasks */
+};
- glusterfs_ctx_t *ctx;
+/* This enum is used to maintain the state of glfd. In case of async fops
+ * fd might be closed before the actual fop is complete. Therefore we need
+ * to track whether the fd is closed or not, instead actually closing it.*/
+enum glfs_fd_state { GLFD_INIT, GLFD_OPEN, GLFD_CLOSE };
- pthread_t poller;
+struct glfs_fd {
+ struct list_head openfds;
+ struct list_head list;
+ GF_REF_DECL;
+ struct glfs *fs;
+ enum glfs_fd_state state;
+ off_t offset;
+ fd_t *fd; /* Currently guared by @fs->mutex. TODO: per-glfd lock */
+ struct list_head entries;
+ gf_dirent_t *next;
+ struct dirent *readdirbuf;
+ gf_lkowner_t lk_owner;
+ glfs_leaseid_t lease_id; /* Stores lease_id of client in glfd */
+ gf_lock_t lock; /* lock taken before updating fd state */
+ glfs_recall_cbk cbk;
+ void *cookie;
+};
- glfs_init_cbk init_cbk;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- pthread_cond_t child_down_cond; /* for broadcasting CHILD_DOWN */
- int init;
- int ret;
- int err;
+/* glfs object handle introduced for the alternate gfapi implementation based
+ on glfs handles/gfid/inode
+*/
+struct glfs_object {
+ inode_t *inode;
+ uuid_t gfid;
+};
- xlator_t *active_subvol;
- xlator_t *next_subvol;
- xlator_t *old_subvol;
+struct glfs_upcall {
+ struct glfs *fs; /* glfs object */
+ enum glfs_upcall_reason reason; /* Upcall event type */
+ void *event; /* changes based in the event type */
+ void (*free_event)(void *); /* free event after the usage */
+};
- char *oldvolfile;
- ssize_t oldvollen;
+struct glfs_upcall_inode {
+ struct glfs_object *object; /* Object which need to be acted upon */
+ int flags; /* Cache UPDATE/INVALIDATE flags */
+ struct stat buf; /* Latest stat of this entry */
+ unsigned int expire_time_attr; /* the amount of time for which
+ * the application need to cache
+ * this entry */
+ struct glfs_object *p_object; /* parent Object to be updated */
+ struct stat p_buf; /* Latest stat of parent dir handle */
+ struct glfs_object *oldp_object; /* Old parent Object to be updated */
+ struct stat oldp_buf; /* Latest stat of old parent dir handle */
+};
- inode_t *cwd;
+struct glfs_upcall_lease {
+ struct glfs_object *object; /* Object which need to be acted upon */
+ uint32_t lease_type; /* Lease type to which client can downgrade to*/
+};
- uint32_t dev_id; /* Used to fill st_dev in struct stat */
+struct glfs_upcall_lease_fd {
+ uint32_t lease_type; /* Lease type to which client can downgrade to*/
+ void *fd_cookie; /* Object which need to be acted upon */
+};
- struct list_head openfds;
+struct glfs_xreaddirp_stat {
+ struct stat
+ st; /* Stat for that dirent - corresponds to GFAPI_XREADDIRP_STAT */
+ struct glfs_object *object; /* handled for GFAPI_XREADDIRP_HANDLE */
+ uint32_t flags_handled; /* final set of flags successfulyy handled */
+};
- gf_boolean_t migration_in_progress;
+#define DEFAULT_EVENT_POOL_SIZE 16384
+#define GF_MEMPOOL_COUNT_OF_DICT_T 4096
+#define GF_MEMPOOL_COUNT_OF_DATA_T (GF_MEMPOOL_COUNT_OF_DICT_T * 4)
+#define GF_MEMPOOL_COUNT_OF_DATA_PAIR_T (GF_MEMPOOL_COUNT_OF_DICT_T * 4)
- struct list_head upcall_list;
- pthread_mutex_t upcall_list_mutex; /* mutex for upcall entry list */
+#define GF_MEMPOOL_COUNT_OF_LRU_BUF_T 256
- uint32_t pin_refcnt;
- uint32_t pthread_flags; /* GLFS_INIT_* # defines set this flag */
-};
+typedef void(glfs_mem_release_t)(void *ptr);
-struct glfs_fd {
- struct list_head openfds;
- struct glfs *fs;
- off_t offset;
- fd_t *fd; /* Currently guared by @fs->mutex. TODO: per-glfd lock */
- struct list_head entries;
- gf_dirent_t *next;
- struct dirent *readdirbuf;
+struct glfs_mem_header {
+ uint32_t magic;
+ size_t nmemb;
+ size_t size;
+ glfs_mem_release_t *release;
};
-/* glfs object handle introduced for the alternate gfapi implementation based
- on glfs handles/gfid/inode
-*/
-struct glfs_object {
- inode_t *inode;
- uuid_t gfid;
-};
+#define GLFS_MEM_HEADER_SIZE (sizeof(struct glfs_mem_header))
+#define GLFS_MEM_HEADER_MAGIC 0x20170830
+
+static inline void *
+__glfs_calloc(size_t nmemb, size_t size, glfs_mem_release_t release,
+ uint32_t type, const char *typestr)
+{
+ struct glfs_mem_header *header = NULL;
+
+ header = __gf_calloc(nmemb, (size + GLFS_MEM_HEADER_SIZE), type, typestr);
+ if (!header)
+ return NULL;
+
+ header->magic = GLFS_MEM_HEADER_MAGIC;
+ header->nmemb = nmemb;
+ header->size = size;
+ header->release = release;
+
+ return header + 1;
+}
+
+static inline void *
+__glfs_malloc(size_t size, glfs_mem_release_t release, uint32_t type,
+ const char *typestr)
+{
+ struct glfs_mem_header *header = NULL;
+
+ header = __gf_malloc((size + GLFS_MEM_HEADER_SIZE), type, typestr);
+ if (!header)
+ return NULL;
+
+ header->magic = GLFS_MEM_HEADER_MAGIC;
+ header->nmemb = 1;
+ header->size = size;
+ header->release = release;
+
+ return header + 1;
+}
+
+static inline void *
+__glfs_realloc(void *ptr, size_t size)
+{
+ struct glfs_mem_header *old_header = NULL;
+ struct glfs_mem_header *new_header = NULL;
+ struct glfs_mem_header tmp_header;
+ void *new_ptr = NULL;
+
+ GF_ASSERT(NULL != ptr);
+
+ old_header = (struct glfs_mem_header *)(ptr - GLFS_MEM_HEADER_SIZE);
+ GF_ASSERT(old_header->magic == GLFS_MEM_HEADER_MAGIC);
+ tmp_header = *old_header;
+
+ new_ptr = __gf_realloc(old_header, (size + GLFS_MEM_HEADER_SIZE));
+ if (!new_ptr)
+ return NULL;
+
+ new_header = (struct glfs_mem_header *)new_ptr;
+ *new_header = tmp_header;
+ new_header->size = size;
+
+ return new_header + 1;
+}
+
+static inline void
+__glfs_free(void *free_ptr)
+{
+ struct glfs_mem_header *header = NULL;
+ void *release_ptr = NULL;
+ int i = 0;
+
+ if (!free_ptr)
+ return;
+
+ header = (struct glfs_mem_header *)(free_ptr - GLFS_MEM_HEADER_SIZE);
+ GF_ASSERT(header->magic == GLFS_MEM_HEADER_MAGIC);
+
+ if (header->release) {
+ release_ptr = free_ptr;
+ for (i = 0; i < header->nmemb; i++) {
+ header->release(release_ptr);
+ release_ptr += header->size;
+ }
+ }
+
+ __gf_free(header);
+}
+
+#define GLFS_CALLOC(nmemb, size, release, type) \
+ __glfs_calloc(nmemb, size, release, type, #type)
-#define DEFAULT_EVENT_POOL_SIZE 16384
-#define GF_MEMPOOL_COUNT_OF_DICT_T 4096
-#define GF_MEMPOOL_COUNT_OF_DATA_T (GF_MEMPOOL_COUNT_OF_DICT_T * 4)
-#define GF_MEMPOOL_COUNT_OF_DATA_PAIR_T (GF_MEMPOOL_COUNT_OF_DICT_T * 4)
-
-#define GF_MEMPOOL_COUNT_OF_LRU_BUF_T 256
-
-int glfs_mgmt_init (struct glfs *fs);
-void glfs_init_done (struct glfs *fs, int ret)
- GFAPI_PRIVATE(glfs_init_done, 3.4.0);
-int glfs_process_volfp (struct glfs *fs, FILE *fp);
-int glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *path,
- loc_t *loc, struct iatt *iatt, int reval)
- GFAPI_PRIVATE(glfs_resolve, 3.7.0);
-int glfs_lresolve (struct glfs *fs, xlator_t *subvol, const char *path, loc_t *loc,
- struct iatt *iatt, int reval);
-fd_t *glfs_resolve_fd (struct glfs *fs, xlator_t *subvol, struct glfs_fd *glfd);
-
-fd_t *__glfs_migrate_fd (struct glfs *fs, xlator_t *subvol, struct glfs_fd *glfd);
-
-int glfs_first_lookup (xlator_t *subvol);
-
-void glfs_process_upcall_event (struct glfs *fs, void *data)
- GFAPI_PRIVATE(glfs_process_upcall_event, 3.7.0);
-
-
-#define __GLFS_ENTRY_VALIDATE_FS(fs, label) \
-do { \
- if (!fs) { \
- errno = EINVAL; \
- goto label; \
- } \
- old_THIS = THIS; \
- THIS = fs->ctx->master; \
-} while (0)
-
-#define __GLFS_EXIT_FS \
-do { \
- THIS = old_THIS; \
-} while (0)
-
-#define __GLFS_ENTRY_VALIDATE_FD(glfd, label) \
-do { \
- if (!glfd || !glfd->fd || !glfd->fd->inode) { \
- errno = EBADF; \
- goto label; \
- } \
- old_THIS = THIS; \
- THIS = glfd->fd->inode->table->xl->ctx->master; \
-} while (0)
+#define GLFS_MALLOC(size, release, type) \
+ __glfs_malloc(size, release, type, #type)
+#define GLFS_REALLOC(ptr, size) __glfs_realloc(ptr, size)
+
+#define GLFS_FREE(free_ptr) __glfs_free(free_ptr)
+
+int
+glfs_mgmt_init(struct glfs *fs);
+void
+glfs_init_done(struct glfs *fs, int ret) GFAPI_PRIVATE(glfs_init_done, 3.4.0);
+int
+glfs_process_volfp(struct glfs *fs, FILE *fp);
+int
+glfs_resolve(struct glfs *fs, xlator_t *subvol, const char *path, loc_t *loc,
+ struct iatt *iatt, int reval) GFAPI_PRIVATE(glfs_resolve, 3.7.0);
+int
+glfs_lresolve(struct glfs *fs, xlator_t *subvol, const char *path, loc_t *loc,
+ struct iatt *iatt, int reval);
+fd_t *
+glfs_resolve_fd(struct glfs *fs, xlator_t *subvol, struct glfs_fd *glfd);
+
+fd_t *
+__glfs_migrate_fd(struct glfs *fs, xlator_t *subvol, struct glfs_fd *glfd);
+
+int
+glfs_first_lookup(xlator_t *subvol);
+
+void
+glfs_process_upcall_event(struct glfs *fs, void *data)
+ GFAPI_PRIVATE(glfs_process_upcall_event, 3.7.0);
+
+#define __GLFS_ENTRY_VALIDATE_FS(fs, label) \
+ do { \
+ if (!fs) { \
+ errno = EINVAL; \
+ goto label; \
+ } \
+ old_THIS = THIS; \
+ THIS = fs->ctx->master; \
+ } while (0)
+
+#define __GLFS_EXIT_FS \
+ do { \
+ THIS = old_THIS; \
+ } while (0)
+
+#define __GLFS_ENTRY_VALIDATE_FD(glfd, label) \
+ do { \
+ if (!glfd || !glfd->fd || !glfd->fd->inode || \
+ glfd->state != GLFD_OPEN) { \
+ errno = EBADF; \
+ goto label; \
+ } \
+ old_THIS = THIS; \
+ THIS = glfd->fd->inode->table->xl->ctx->master; \
+ } while (0)
+
+#define __GLFS_LOCK_WAIT(fs) \
+ do { \
+ struct synctask *task = NULL; \
+ \
+ task = synctask_get(); \
+ \
+ if (task) { \
+ list_add_tail(&task->waitq, &fs->waitq); \
+ pthread_mutex_unlock(&fs->mutex); \
+ synctask_yield(task, NULL); \
+ pthread_mutex_lock(&fs->mutex); \
+ } else { \
+ /* non-synctask */ \
+ pthread_cond_wait(&fs->cond, &fs->mutex); \
+ } \
+ } while (0)
+
+#define __GLFS_SYNCTASK_WAKE(fs) \
+ do { \
+ struct synctask *waittask = NULL; \
+ \
+ while (!list_empty(&fs->waitq)) { \
+ waittask = list_entry(fs->waitq.next, struct synctask, waitq); \
+ list_del_init(&waittask->waitq); \
+ synctask_wake(waittask); \
+ } \
+ } while (0)
/*
By default all lock attempts from user context must
@@ -283,67 +494,93 @@ do { \
we can give up the mutex during syncop calls so
that bottom up calls (particularly CHILD_UP notify)
can do a mutex_lock() on @glfs without deadlocking
- the filesystem
+ the filesystem.
+
+ All the fops should wait for graph migration to finish
+ before starting the fops. Therefore these functions should
+ call glfs_lock with wait_for_migration as true. But waiting
+ for migration to finish in call-back path can result thread
+ dead-locks. The reason for this is we only have finite
+ number of epoll threads. so if we wait on epoll threads
+ there will not be any thread left to handle outstanding
+ rpc replies.
*/
static inline int
-glfs_lock (struct glfs *fs)
+glfs_lock(struct glfs *fs, gf_boolean_t wait_for_migration)
{
- pthread_mutex_lock (&fs->mutex);
+ pthread_mutex_lock(&fs->mutex);
- while (!fs->init)
- pthread_cond_wait (&fs->cond, &fs->mutex);
+ while (!fs->init)
+ __GLFS_LOCK_WAIT(fs);
- while (fs->migration_in_progress)
- pthread_cond_wait (&fs->cond, &fs->mutex);
+ while (wait_for_migration && fs->migration_in_progress)
+ __GLFS_LOCK_WAIT(fs);
- return 0;
+ return 0;
}
-
static inline void
-glfs_unlock (struct glfs *fs)
+glfs_unlock(struct glfs *fs)
{
- pthread_mutex_unlock (&fs->mutex);
+ pthread_mutex_unlock(&fs->mutex);
}
+struct glfs_fd *
+glfs_fd_new(struct glfs *fs);
+void
+glfs_fd_bind(struct glfs_fd *glfd);
+void
+glfd_set_state_bind(struct glfs_fd *glfd);
+
+xlator_t *
+glfs_active_subvol(struct glfs *fs) GFAPI_PRIVATE(glfs_active_subvol, 3.4.0);
+xlator_t *
+__glfs_active_subvol(struct glfs *fs);
+void
+glfs_subvol_done(struct glfs *fs, xlator_t *subvol)
+ GFAPI_PRIVATE(glfs_subvol_done, 3.4.0);
+
+inode_t *
+glfs_refresh_inode(xlator_t *subvol, inode_t *inode);
+
+inode_t *
+glfs_cwd_get(struct glfs *fs);
+int
+glfs_cwd_set(struct glfs *fs, inode_t *inode);
+inode_t *
+glfs_resolve_inode(struct glfs *fs, xlator_t *subvol,
+ struct glfs_object *object);
+int
+glfs_create_object(loc_t *loc, struct glfs_object **retobject);
+int
+__glfs_cwd_set(struct glfs *fs, inode_t *inode);
+
+int
+glfs_resolve_base(struct glfs *fs, xlator_t *subvol, inode_t *inode,
+ struct iatt *iatt);
-void glfs_fd_destroy (struct glfs_fd *glfd);
-
-struct glfs_fd *glfs_fd_new (struct glfs *fs);
-void glfs_fd_bind (struct glfs_fd *glfd);
-
-xlator_t *glfs_active_subvol (struct glfs *fs)
- GFAPI_PRIVATE(glfs_active_subvol, 3.4.0);
-xlator_t *__glfs_active_subvol (struct glfs *fs);
-void glfs_subvol_done (struct glfs *fs, xlator_t *subvol)
- GFAPI_PRIVATE(glfs_subvol_done, 3.4.0);
-
-inode_t *glfs_refresh_inode (xlator_t *subvol, inode_t *inode);
-
-inode_t *glfs_cwd_get (struct glfs *fs);
-int glfs_cwd_set (struct glfs *fs, inode_t *inode);
-inode_t *glfs_resolve_inode (struct glfs *fs, xlator_t *subvol,
- struct glfs_object *object);
-int glfs_create_object (loc_t *loc, struct glfs_object **retobject);
-int __glfs_cwd_set (struct glfs *fs, inode_t *inode);
-
-int glfs_resolve_base (struct glfs *fs, xlator_t *subvol, inode_t *inode,
- struct iatt *iatt);
-int glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
- const char *origpath, loc_t *loc, struct iatt *iatt,
- int follow, int reval)
- GFAPI_PRIVATE(glfs_resolve_at, 3.4.0);
-int glfs_loc_touchup (loc_t *loc)
- GFAPI_PRIVATE(glfs_loc_touchup, 3.4.0);
-void glfs_iatt_to_stat (struct glfs *fs, struct iatt *iatt, struct stat *stat);
-int glfs_loc_link (loc_t *loc, struct iatt *iatt);
-int glfs_loc_unlink (loc_t *loc);
-dict_t *dict_for_key_value (const char *name, const char *value, size_t size);
-int glfs_getxattr_process (void *value, size_t size, dict_t *xattr,
- const char *name);
+int
+glfs_resolve_at(struct glfs *fs, xlator_t *subvol, inode_t *at,
+ const char *origpath, loc_t *loc, struct iatt *iatt, int follow,
+ int reval) GFAPI_PRIVATE(glfs_resolve_at, 3.4.0);
+int
+glfs_loc_touchup(loc_t *loc) GFAPI_PRIVATE(glfs_loc_touchup, 3.4.0);
+void
+glfs_iatt_to_stat(struct glfs *fs, struct iatt *iatt, struct stat *stat);
+void
+glfs_iatt_from_stat(struct stat *stat, int valid, struct iatt *iatt,
+ int *gvalid);
+int
+glfs_loc_link(loc_t *loc, struct iatt *iatt);
+int
+glfs_loc_unlink(loc_t *loc);
+int
+glfs_getxattr_process(void *value, size_t size, dict_t *xattr,
+ const char *name);
/* Sends RPC call to glusterd to fetch required volume info */
-int glfs_get_volume_info (struct glfs *fs);
+int
+glfs_get_volume_info(struct glfs *fs);
/*
SYNOPSIS
@@ -369,8 +606,8 @@ int glfs_get_volume_info (struct glfs *fs);
NULL : Otherwise.
*/
-struct glfs *glfs_new_from_ctx (glusterfs_ctx_t *ctx)
- GFAPI_PRIVATE(glfs_new_from_ctx, 3.7.0);
+struct glfs *
+glfs_new_from_ctx(glusterfs_ctx_t *ctx) GFAPI_PRIVATE(glfs_new_from_ctx, 3.7.0);
/*
SYNOPSIS
@@ -395,26 +632,125 @@ struct glfs *glfs_new_from_ctx (glusterfs_ctx_t *ctx)
void
*/
-void glfs_free_from_ctx (struct glfs *fs)
- GFAPI_PRIVATE(glfs_free_from_ctx, 3.7.0);
+void
+glfs_free_from_ctx(struct glfs *fs) GFAPI_PRIVATE(glfs_free_from_ctx, 3.7.0);
-int glfs_get_upcall_cache_invalidation (struct gf_upcall *to_up_data,
- struct gf_upcall *from_up_data);
int
-glfs_h_poll_cache_invalidation (struct glfs *fs,
- struct callback_arg *up_arg,
- struct gf_upcall *upcall_data);
+glfs_recall_lease_fd(struct glfs *fs, struct gf_upcall *up_data);
+
+int
+glfs_get_upcall_cache_invalidation(struct gf_upcall *to_up_data,
+ struct gf_upcall *from_up_data);
+int
+glfs_h_poll_cache_invalidation(struct glfs *fs, struct glfs_upcall *up_arg,
+ struct gf_upcall *upcall_data);
ssize_t
-glfs_anonymous_preadv (struct glfs *fs, struct glfs_object *object,
- const struct iovec *iovec, int iovcnt,
- off_t offset, int flags);
+glfs_anonymous_preadv(struct glfs *fs, struct glfs_object *object,
+ const struct iovec *iovec, int iovcnt, off_t offset,
+ int flags);
ssize_t
-glfs_anonymous_pwritev (struct glfs *fs, struct glfs_object *object,
- const struct iovec *iovec, int iovcnt,
- off_t offset, int flags);
+glfs_anonymous_pwritev(struct glfs *fs, struct glfs_object *object,
+ const struct iovec *iovec, int iovcnt, off_t offset,
+ int flags);
struct glfs_object *
-glfs_h_resolve_symlink (struct glfs *fs, struct glfs_object *object);
+glfs_h_resolve_symlink(struct glfs *fs, struct glfs_object *object);
+/* Deprecated structures that were passed to client applications, replaced by
+ * accessor functions. Do not use these in new applications, and update older
+ * usage.
+ *
+ * See http://review.gluster.org/14701 for more details.
+ *
+ * WARNING: These structures will be removed in the future.
+ */
+struct glfs_callback_arg {
+ struct glfs *fs;
+ enum glfs_upcall_reason reason;
+ void *event_arg;
+};
+
+struct glfs_callback_inode_arg {
+ struct glfs_object *object; /* Object which need to be acted upon */
+ int flags; /* Cache UPDATE/INVALIDATE flags */
+ struct stat buf; /* Latest stat of this entry */
+ unsigned int expire_time_attr; /* the amount of time for which
+ * the application need to cache
+ * this entry
+ */
+ struct glfs_object *p_object; /* parent Object to be updated */
+ struct stat p_buf; /* Latest stat of parent dir handle */
+ struct glfs_object *oldp_object; /* Old parent Object
+ * to be updated */
+ struct stat oldp_buf; /* Latest stat of old parent
+ * dir handle */
+};
+struct dirent *
+glfs_readdirbuf_get(struct glfs_fd *glfd);
+
+gf_dirent_t *
+glfd_entry_next(struct glfs_fd *glfd, int plus);
+
+void
+gf_dirent_to_dirent(gf_dirent_t *gf_dirent, struct dirent *dirent);
+
+void
+gf_lease_to_glfs_lease(struct gf_lease *gf_lease, struct glfs_lease *lease);
+
+void
+glfs_lease_to_gf_lease(struct glfs_lease *lease, struct gf_lease *gf_lease);
+
+void
+glfs_release_upcall(void *ptr);
+
+int
+get_fop_attr_glfd(dict_t **fop_attr, struct glfs_fd *glfd);
+
+int
+set_fop_attr_glfd(struct glfs_fd *glfd);
+
+int
+get_fop_attr_thrd_key(dict_t **fop_attr);
+
+void
+unset_fop_attr(dict_t **fop_attr);
+
+/*
+ SYNOPSIS
+ glfs_statx: Fetch extended file attributes for the given path.
+
+ DESCRIPTION
+ This function fetches extended file attributes for the given path.
+
+ PARAMETERS
+ @fs: The 'virtual mount' object referencing a volume, under which file exists.
+ @path: Path of the file within the virtual mount.
+ @mask: Requested extended file attributes mask, (See mask defines above)
+
+ RETURN VALUES
+ -1 : Failure. @errno will be set with the type of failure.
+ 0 : Filled in statxbuf with appropriate masks for valid items in the
+ structure.
+
+ ERRNO VALUES
+ EINVAL: fs is invalid
+ EINVAL: mask has unsupported bits set
+ Other errors as returned by stat(2)
+ */
+
+int
+glfs_statx(struct glfs *fs, const char *path, unsigned int mask,
+ struct glfs_stat *statxbuf) GFAPI_PRIVATE(glfs_statx, 6.0);
+
+void
+glfs_iatt_from_statx(struct iatt *, const struct glfs_stat *)
+ GFAPI_PRIVATE(glfs_iatt_from_statx, 6.0);
+
+/*
+ * This API is a per thread setting, similar to glfs_setfs{u/g}id, because of
+ * the call to syncopctx_setfspid.
+ */
+int
+glfs_setfspid(struct glfs *, pid_t) GFAPI_PRIVATE(glfs_setfspid, 6.1);
#endif /* !_GLFS_INTERNAL_H */
diff --git a/api/src/glfs-master.c b/api/src/glfs-master.c
index bb657695489..100dcc16cc0 100644
--- a/api/src/glfs-master.c
+++ b/api/src/glfs-master.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2012-2016 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
@@ -8,158 +8,176 @@
cases as published by the Free Software Foundation.
*/
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
#include <stdio.h>
-#include <inttypes.h>
-#include <limits.h>
-#include "xlator.h"
-#include "glusterfs.h"
+#include <glusterfs/glusterfs.h>
#include "glfs-internal.h"
#include "glfs-mem-types.h"
#include "gfapi-messages.h"
-
int
-graph_setup (struct glfs *fs, glusterfs_graph_t *graph)
+graph_setup(struct glfs *fs, glusterfs_graph_t *graph)
{
- xlator_t *new_subvol = NULL;
- xlator_t *old_subvol = NULL;
- inode_table_t *itable = NULL;
- int ret = -1;
-
- new_subvol = graph->top;
-
- /* This is called in a bottom-up context, it should specifically
- NOT be glfs_lock()
- */
- pthread_mutex_lock (&fs->mutex);
- {
- if (new_subvol->switched ||
- new_subvol == fs->active_subvol ||
- new_subvol == fs->next_subvol) {
- /* Spurious CHILD_UP event on old graph */
- ret = 0;
- goto unlock;
- }
-
- if (!new_subvol->itable) {
- itable = inode_table_new (131072, new_subvol);
- if (!itable) {
- errno = ENOMEM;
- ret = -1;
- goto unlock;
- }
-
- new_subvol->itable = itable;
- }
-
- old_subvol = fs->next_subvol;
- fs->next_subvol = new_subvol;
- fs->next_subvol->winds++; /* first ref */
- ret = 0;
- }
+ xlator_t *new_subvol = NULL;
+ xlator_t *old_subvol = NULL;
+ inode_table_t *itable = NULL;
+ int ret = -1;
+
+ new_subvol = graph->top;
+
+ /* This is called in a bottom-up context, it should specifically
+ NOT be glfs_lock()
+ */
+ pthread_mutex_lock(&fs->mutex);
+ {
+ if (new_subvol->switched || new_subvol == fs->active_subvol ||
+ new_subvol == fs->next_subvol || new_subvol == fs->mip_subvol) {
+ /* Spurious CHILD_UP event on old graph */
+ ret = 0;
+ goto unlock;
+ }
+
+ if (!new_subvol->itable) {
+ itable = inode_table_new(131072, new_subvol);
+ if (!itable) {
+ errno = ENOMEM;
+ ret = -1;
+ goto unlock;
+ }
+
+ new_subvol->itable = itable;
+ }
+
+ old_subvol = fs->next_subvol;
+ fs->next_subvol = new_subvol;
+ fs->next_subvol->winds++; /* first ref */
+ ret = 0;
+ }
unlock:
- pthread_mutex_unlock (&fs->mutex);
+ pthread_mutex_unlock(&fs->mutex);
- if (old_subvol)
- /* wasn't picked up so far, skip */
- glfs_subvol_done (fs, old_subvol);
+ if (old_subvol)
+ /* wasn't picked up so far, skip */
+ glfs_subvol_done(fs, old_subvol);
- return ret;
+ return ret;
}
-
int
-notify (xlator_t *this, int event, void *data, ...)
+notify(xlator_t *this, int event, void *data, ...)
{
- glusterfs_graph_t *graph = NULL;
- struct glfs *fs = NULL;
-
- graph = data;
- fs = this->private;
-
- switch (event) {
- case GF_EVENT_GRAPH_NEW:
- gf_msg (this->name, GF_LOG_INFO, 0, API_MSG_NEW_GRAPH,
- "New graph %s (%d) coming up",
- uuid_utoa ((unsigned char *)graph->graph_uuid),
- graph->id);
- break;
- case GF_EVENT_CHILD_UP:
- pthread_mutex_lock (&fs->mutex);
- {
- graph->used = 1;
- }
- pthread_mutex_unlock (&fs->mutex);
- graph_setup (fs, graph);
- glfs_init_done (fs, 0);
- break;
- case GF_EVENT_CHILD_DOWN:
- pthread_mutex_lock (&fs->mutex);
- {
- graph->used = 0;
- pthread_cond_broadcast (&fs->child_down_cond);
- }
- pthread_mutex_unlock (&fs->mutex);
- graph_setup (fs, graph);
- glfs_init_done (fs, 1);
- break;
- case GF_EVENT_CHILD_CONNECTING:
- break;
+ glusterfs_graph_t *graph = NULL;
+ struct glfs *fs = NULL;
+
+ graph = data;
+ fs = this->private;
+
+ switch (event) {
+ case GF_EVENT_GRAPH_NEW:
+ gf_smsg(this->name, GF_LOG_INFO, 0, API_MSG_NEW_GRAPH,
+ "graph-uuid=%s",
+ uuid_utoa((unsigned char *)graph->graph_uuid), "id=%d",
+ graph->id, NULL);
+ break;
+ case GF_EVENT_CHILD_UP:
+ pthread_mutex_lock(&fs->mutex);
+ {
+ graph->used = 1;
+ }
+ pthread_mutex_unlock(&fs->mutex);
+ graph_setup(fs, graph);
+ glfs_init_done(fs, 0);
+ break;
+ case GF_EVENT_CHILD_DOWN:
+ pthread_mutex_lock(&fs->mutex);
+ {
+ graph->used = 0;
+ pthread_cond_broadcast(&fs->child_down_cond);
+ }
+ pthread_mutex_unlock(&fs->mutex);
+ glfs_init_done(fs, 1);
+ break;
+ case GF_EVENT_CHILD_CONNECTING:
+ break;
case GF_EVENT_UPCALL:
- glfs_process_upcall_event (fs, data);
- break;
- default:
- gf_msg_debug (this->name, 0, "got notify event %d", event);
- break;
- }
-
- return 0;
+ glfs_process_upcall_event(fs, data);
+ break;
+ default:
+ gf_msg_debug(this->name, 0, "got notify event %d", event);
+ break;
+ }
+
+ return 0;
}
-
int
-mem_acct_init (xlator_t *this)
+mem_acct_init(xlator_t *this)
{
- int ret = -1;
+ int ret = -1;
- if (!this)
- return ret;
+ if (!this)
+ return ret;
- ret = xlator_mem_acct_init (this, glfs_mt_end + 1);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
- API_MSG_MEM_ACCT_INIT_FAILED, "Failed to initialise "
- "memory accounting");
- return ret;
- }
+ ret = xlator_mem_acct_init(this, glfs_mt_end + 1);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, ENOMEM, API_MSG_MEM_ACCT_INIT_FAILED,
+ NULL);
+ return ret;
+ }
- return 0;
+ return 0;
}
-
int
-init (xlator_t *this)
+init(xlator_t *this)
{
- return 0;
+ return 0;
}
-
void
-fini (xlator_t *this)
+fini(xlator_t *this)
{
+}
+/* place-holder fops */
+int
+glfs_forget(xlator_t *this, inode_t *inode)
+{
+ return 0;
}
+int
+glfs_release(xlator_t *this, fd_t *fd)
+{
+ return 0;
+}
-struct xlator_dumpops dumpops;
+int
+glfs_releasedir(xlator_t *this, fd_t *fd)
+{
+ return 0;
+}
+struct xlator_dumpops dumpops;
struct xlator_fops fops;
-
-struct xlator_cbks cbks;
+struct xlator_cbks cbks = {
+ .forget = glfs_forget,
+ .release = glfs_release,
+ .releasedir = glfs_releasedir,
+};
+
+xlator_api_t xlator_api = {
+ .init = init,
+ .fini = fini,
+ .notify = notify,
+ .mem_acct_init = mem_acct_init,
+ .op_version = {1},
+ .dumpops = &dumpops,
+ .fops = &fops,
+ .cbks = &cbks,
+ .identifier = "glfs-api",
+ .category = GF_MAINTAINED,
+};
diff --git a/api/src/glfs-mem-types.h b/api/src/glfs-mem-types.h
index cad1ca95d4f..bfa325a3ad9 100644
--- a/api/src/glfs-mem-types.h
+++ b/api/src/glfs-mem-types.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2012-2017 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
@@ -11,22 +11,25 @@
#ifndef _GLFS_MEM_TYPES_H
#define _GLFS_MEM_TYPES_H
-#include "mem-types.h"
+#include <glusterfs/mem-types.h>
#define GF_MEM_TYPE_START (gf_common_mt_end + 1)
enum glfs_mem_types_ {
- glfs_mt_call_pool_t = GF_MEM_TYPE_START,
- glfs_mt_xlator_t,
- glfs_mt_glfs_fd_t,
- glfs_mt_glfs_io_t,
- glfs_mt_volfile_t,
- glfs_mt_xlator_cmdline_option_t,
- glfs_mt_server_cmdline_t,
- glfs_mt_glfs_object_t,
- glfs_mt_readdirbuf_t,
- glfs_mt_upcall_entry_t,
- glfs_mt_acl_t,
- glfs_mt_end
+ glfs_mt_call_pool_t = GF_MEM_TYPE_START,
+ glfs_mt_xlator_t,
+ glfs_mt_glfs_fd_t,
+ glfs_mt_glfs_io_t,
+ glfs_mt_volfile_t,
+ glfs_mt_xlator_cmdline_option_t,
+ glfs_mt_server_cmdline_t,
+ glfs_mt_glfs_object_t,
+ glfs_mt_readdirbuf_t,
+ glfs_mt_upcall_entry_t,
+ glfs_mt_acl_t,
+ glfs_mt_upcall_inode_t,
+ glfs_mt_realpath_t,
+ glfs_mt_xreaddirp_stat_t,
+ glfs_mt_end
};
#endif
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c
index 48fd618ff68..7c82b8cd162 100644
--- a/api/src/glfs-mgmt.c
+++ b/api/src/glfs-mgmt.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2012-2018 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
@@ -8,7 +8,6 @@
cases as published by the Free Software Foundation.
*/
-
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -16,885 +15,1035 @@
#include <signal.h>
#include <pthread.h>
-#include "glusterfs.h"
+#include <glusterfs/glusterfs.h>
#include "glfs.h"
-#include "stack.h"
-#include "dict.h"
-#include "event.h"
-#include "defaults.h"
+#include <glusterfs/dict.h>
#include "rpc-clnt.h"
#include "protocol-common.h"
-#include "glusterfs3.h"
-#include "portmap-xdr.h"
-#include "xdr-common.h"
#include "xdr-generic.h"
+#include "rpc-common-xdr.h"
-#include "syncop.h"
-#include "xlator.h"
+#include <glusterfs/syncop.h>
#include "glfs-internal.h"
-#include "glfs-mem-types.h"
#include "gfapi-messages.h"
+#include <glusterfs/syscall.h>
-int glfs_volfile_fetch (struct glfs *fs);
-int32_t glfs_get_volume_info_rpc (call_frame_t *frame, xlator_t *this,
- struct glfs *fs);
+int
+glfs_volfile_fetch(struct glfs *fs);
+int32_t
+glfs_get_volume_info_rpc(call_frame_t *frame, xlator_t *this, struct glfs *fs);
int
-glfs_process_volfp (struct glfs *fs, FILE *fp)
+glfs_process_volfp(struct glfs *fs, FILE *fp)
{
- glusterfs_graph_t *graph = NULL;
- int ret = -1;
- xlator_t *trav = NULL;
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = fs->ctx;
- graph = glusterfs_graph_construct (fp);
- if (!graph) {
- gf_msg ("glfs", GF_LOG_ERROR, errno,
- API_MSG_GRAPH_CONSTRUCT_FAILED,
- "failed to construct the graph");
- goto out;
- }
-
- for (trav = graph->first; trav; trav = trav->next) {
- if (strcmp (trav->type, "mount/fuse") == 0) {
- gf_msg ("glfs", GF_LOG_ERROR, EINVAL,
- API_MSG_FUSE_XLATOR_ERROR,
- "fuse xlator cannot be specified "
- "in volume file");
- goto out;
- }
- }
-
- ret = glusterfs_graph_prepare (graph, ctx);
- if (ret) {
- glusterfs_graph_destroy (graph);
- goto out;
- }
-
- ret = glusterfs_graph_activate (graph, ctx);
-
- if (ret) {
- glusterfs_graph_destroy (graph);
- goto out;
- }
-
- ret = 0;
+ glusterfs_graph_t *graph = NULL;
+ int ret = -1;
+ xlator_t *trav = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = fs->ctx;
+ graph = glusterfs_graph_construct(fp);
+ if (!graph) {
+ gf_smsg("glfs", GF_LOG_ERROR, errno, API_MSG_GRAPH_CONSTRUCT_FAILED,
+ NULL);
+ goto out;
+ }
+
+ for (trav = graph->first; trav; trav = trav->next) {
+ if (strcmp(trav->type, "mount/api") == 0) {
+ gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_API_XLATOR_ERROR,
+ NULL);
+ goto out;
+ }
+ }
+
+ ret = glusterfs_graph_prepare(graph, ctx, fs->volname);
+ if (ret) {
+ glusterfs_graph_destroy(graph);
+ goto out;
+ }
+
+ ret = glusterfs_graph_activate(graph, ctx);
+
+ if (ret) {
+ glusterfs_graph_destroy(graph);
+ goto out;
+ }
+
+ gf_log_dump_graph(fp, graph);
+
+ ret = 0;
out:
- if (fp)
- fclose (fp);
+ if (fp)
+ fclose(fp);
- if (!ctx->active) {
- ret = -1;
- }
+ if (!ctx->active) {
+ ret = -1;
+ }
- return ret;
+ return ret;
}
-
int
-mgmt_cbk_spec (struct rpc_clnt *rpc, void *mydata, void *data)
+mgmt_cbk_spec(struct rpc_clnt *rpc, void *mydata, void *data)
{
- struct glfs *fs = NULL;
- xlator_t *this = NULL;
+ struct glfs *fs = NULL;
+ xlator_t *this = NULL;
- this = mydata;
- fs = this->private;
+ this = mydata;
+ fs = this->private;
- glfs_volfile_fetch (fs);
+ glfs_volfile_fetch(fs);
- return 0;
+ return 0;
}
-
int
-mgmt_cbk_event (struct rpc_clnt *rpc, void *mydata, void *data)
+mgmt_cbk_event(struct rpc_clnt *rpc, void *mydata, void *data)
{
- return 0;
+ return 0;
}
+static int
+mgmt_cbk_statedump(struct rpc_clnt *rpc, void *mydata, void *data)
+{
+ struct glfs *fs = NULL;
+ xlator_t *this = NULL;
+ gf_statedump target_pid = {
+ 0,
+ };
+ struct iovec *iov = NULL;
+ int ret = -1;
+
+ this = mydata;
+ if (!this) {
+ gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_NULL, "mydata", NULL);
+ errno = EINVAL;
+ goto out;
+ }
+
+ fs = this->private;
+ if (!fs) {
+ gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_NULL, "glfs", NULL);
+ errno = EINVAL;
+ goto out;
+ }
+
+ iov = (struct iovec *)data;
+ if (!iov) {
+ gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_NULL, "iovec data", NULL);
+ errno = EINVAL;
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &target_pid, (xdrproc_t)xdr_gf_statedump);
+ if (ret < 0) {
+ gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_DECODE_XDR_FAILED, NULL);
+ goto out;
+ }
+
+ gf_msg_trace("glfs", 0, "statedump requested for pid: %d", target_pid.pid);
+
+ if ((uint64_t)getpid() == target_pid.pid) {
+ gf_msg_debug("glfs", 0, "Taking statedump for pid: %d", target_pid.pid);
+
+ ret = glfs_sysrq(fs, GLFS_SYSRQ_STATEDUMP);
+ if (ret < 0) {
+ gf_smsg("glfs", GF_LOG_INFO, 0, API_MSG_STATEDUMP_FAILED, NULL);
+ }
+ }
+out:
+ return ret;
+}
-rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = {
- [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec },
- [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY,
- mgmt_cbk_event},
+static rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = {
+ [GF_CBK_FETCHSPEC] = {"FETCHSPEC", mgmt_cbk_spec, GF_CBK_FETCHSPEC},
+ [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", mgmt_cbk_event,
+ GF_CBK_EVENT_NOTIFY},
+ [GF_CBK_STATEDUMP] = {"STATEDUMP", mgmt_cbk_statedump, GF_CBK_STATEDUMP},
};
-
-struct rpcclnt_cb_program mgmt_cbk_prog = {
- .progname = "GlusterFS Callback",
- .prognum = GLUSTER_CBK_PROGRAM,
- .progver = GLUSTER_CBK_VERSION,
- .actors = mgmt_cbk_actors,
- .numactors = GF_CBK_MAXVALUE,
+static struct rpcclnt_cb_program mgmt_cbk_prog = {
+ .progname = "GlusterFS Callback",
+ .prognum = GLUSTER_CBK_PROGRAM,
+ .progver = GLUSTER_CBK_VERSION,
+ .actors = mgmt_cbk_actors,
+ .numactors = GF_CBK_MAXVALUE,
};
-char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
- [GF_HNDSK_NULL] = "NULL",
- [GF_HNDSK_SETVOLUME] = "SETVOLUME",
- [GF_HNDSK_GETSPEC] = "GETSPEC",
- [GF_HNDSK_PING] = "PING",
- [GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY",
- [GF_HNDSK_GET_VOLUME_INFO] = "GETVOLUMEINFO",
+static char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
+ [GF_HNDSK_NULL] = "NULL",
+ [GF_HNDSK_SETVOLUME] = "SETVOLUME",
+ [GF_HNDSK_GETSPEC] = "GETSPEC",
+ [GF_HNDSK_PING] = "PING",
+ [GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY",
+ [GF_HNDSK_GET_VOLUME_INFO] = "GETVOLUMEINFO",
};
-rpc_clnt_prog_t clnt_handshake_prog = {
- .progname = "GlusterFS Handshake",
- .prognum = GLUSTER_HNDSK_PROGRAM,
- .progver = GLUSTER_HNDSK_VERSION,
- .procnames = clnt_handshake_procs,
+static rpc_clnt_prog_t clnt_handshake_prog = {
+ .progname = "GlusterFS Handshake",
+ .prognum = GLUSTER_HNDSK_PROGRAM,
+ .progver = GLUSTER_HNDSK_VERSION,
+ .procnames = clnt_handshake_procs,
};
-
int
-mgmt_submit_request (void *req, call_frame_t *frame,
- glusterfs_ctx_t *ctx,
- rpc_clnt_prog_t *prog, int procnum,
- fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
+mgmt_submit_request(void *req, call_frame_t *frame, glusterfs_ctx_t *ctx,
+ rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn,
+ xdrproc_t xdrproc)
{
- int ret = -1;
- int count = 0;
- struct iovec iov = {0, };
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- ssize_t xdr_size = 0;
-
- iobref = iobref_new ();
- if (!iobref) {
- goto out;
- }
-
- if (req) {
- xdr_size = xdr_sizeof (xdrproc, req);
-
- iobuf = iobuf_get2 (ctx->iobuf_pool, xdr_size);
- if (!iobuf) {
- goto out;
- };
-
- iobref_add (iobref, iobuf);
-
- iov.iov_base = iobuf->ptr;
- iov.iov_len = iobuf_pagesize (iobuf);
-
- /* Create the xdr payload */
- ret = xdr_serialize_generic (iov, req, xdrproc);
- if (ret == -1) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- API_MSG_XDR_PAYLOAD_FAILED,
- "failed to create XDR payload");
- goto out;
- }
- iov.iov_len = ret;
- count = 1;
- }
-
- /* Send the msg */
- ret = rpc_clnt_submit (ctx->mgmt, prog, procnum, cbkfn,
- &iov, count,
- NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
+ int ret = -1;
+ int count = 0;
+ struct iovec iov = {
+ 0,
+ };
+ struct iobuf *iobuf = NULL;
+ struct iobref *iobref = NULL;
+ ssize_t xdr_size = 0;
+
+ iobref = iobref_new();
+ if (!iobref) {
+ goto out;
+ }
+
+ if (req) {
+ xdr_size = xdr_sizeof(xdrproc, req);
+
+ iobuf = iobuf_get2(ctx->iobuf_pool, xdr_size);
+ if (!iobuf) {
+ goto out;
+ };
+
+ iobref_add(iobref, iobuf);
+
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = iobuf_pagesize(iobuf);
+
+ /* Create the xdr payload */
+ ret = xdr_serialize_generic(iov, req, xdrproc);
+ if (ret == -1) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, API_MSG_XDR_PAYLOAD_FAILED,
+ NULL);
+ goto out;
+ }
+ iov.iov_len = ret;
+ count = 1;
+ }
+
+ /* Send the msg */
+ ret = rpc_clnt_submit(ctx->mgmt, prog, procnum, cbkfn, &iov, count, NULL, 0,
+ iobref, frame, NULL, 0, NULL, 0, NULL);
out:
- if (iobref)
- iobref_unref (iobref);
+ if (iobref)
+ iobref_unref(iobref);
- if (iobuf)
- iobuf_unref (iobuf);
- return ret;
+ if (iobuf)
+ iobuf_unref(iobuf);
+ return ret;
}
/*
* Callback routine for 'GF_HNDSK_GET_VOLUME_INFO' rpc request
*/
int
-mgmt_get_volinfo_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+mgmt_get_volinfo_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- int ret = 0;
- char *volume_id_str = NULL;
- dict_t *dict = NULL;
- char key[1024] = {0};
- gf_get_volume_info_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- glusterfs_ctx_t *ctx = NULL;
- struct glfs *fs = NULL;
- struct syncargs *args;
-
- frame = myframe;
- ctx = frame->this->ctx;
- args = frame->local;
-
- if (!ctx) {
- gf_msg (frame->this->name, GF_LOG_ERROR, EINVAL,
- API_MSG_INVALID_ENTRY, "NULL context");
- errno = EINVAL;
- ret = -1;
- goto out;
- }
-
- fs = ((xlator_t *)ctx->master)->private;
-
- if (-1 == req->rpc_status) {
- gf_msg (frame->this->name, GF_LOG_ERROR, EINVAL,
- API_MSG_INVALID_ENTRY,
- "GET_VOLUME_INFO RPC call is not successfull");
- errno = EINVAL;
- ret = -1;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_get_volume_info_rsp);
-
- if (ret < 0) {
- gf_msg (frame->this->name, GF_LOG_ERROR, 0,
- API_MSG_XDR_RESPONSE_DECODE_FAILED,
- "Failed to decode xdr response for GET_VOLUME_INFO");
- goto out;
- }
-
- gf_msg_debug (frame->this->name, 0, "Received resp to GET_VOLUME_INFO "
- "RPC: %d", rsp.op_ret);
-
- if (rsp.op_ret == -1) {
- errno = rsp.op_errno;
- ret = -1;
- goto out;
- }
-
- if (!rsp.dict.dict_len) {
- gf_msg (frame->this->name, GF_LOG_ERROR, EINVAL,
- API_MSG_INVALID_ENTRY, "Response received for "
- "GET_VOLUME_INFO RPC call is not valid");
- ret = -1;
- errno = EINVAL;
- goto out;
- }
-
- dict = dict_new ();
-
- if (!dict) {
- ret = -1;
- errno = ENOMEM;
- goto out;
- }
-
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &dict);
-
- if (ret) {
- errno = ENOMEM;
- goto out;
- }
-
- snprintf (key, sizeof (key), "volume_id");
- ret = dict_get_str (dict, key, &volume_id_str);
- if (ret) {
- errno = EINVAL;
- goto out;
- }
-
- ret = 0;
+ int ret = 0;
+ char *volume_id_str = NULL;
+ dict_t *dict = NULL;
+ gf_get_volume_info_rsp rsp = {
+ 0,
+ };
+ call_frame_t *frame = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ struct glfs *fs = NULL;
+ struct syncargs *args;
+
+ frame = myframe;
+ ctx = frame->this->ctx;
+ args = frame->local;
+
+ if (!ctx) {
+ gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_NULL,
+ "context", NULL);
+ errno = EINVAL;
+ ret = -1;
+ goto out;
+ }
+
+ fs = ((xlator_t *)ctx->master)->private;
+
+ if (-1 == req->rpc_status) {
+ gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL,
+ API_MSG_CALL_NOT_SUCCESSFUL, NULL);
+ errno = EINVAL;
+ ret = -1;
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_get_volume_info_rsp);
+
+ if (ret < 0) {
+ gf_smsg(frame->this->name, GF_LOG_ERROR, 0,
+ API_MSG_XDR_RESPONSE_DECODE_FAILED, NULL);
+ goto out;
+ }
+
+ gf_msg_debug(frame->this->name, 0,
+ "Received resp to GET_VOLUME_INFO "
+ "RPC: %d",
+ rsp.op_ret);
+
+ if (rsp.op_ret == -1) {
+ errno = rsp.op_errno;
+ ret = -1;
+ goto out;
+ }
+
+ if (!rsp.dict.dict_len) {
+ gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_CALL_NOT_VALID,
+ NULL);
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ dict = dict_new();
+
+ if (!dict) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+
+ if (ret) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(dict, "volume_id", &volume_id_str);
+ if (ret) {
+ errno = EINVAL;
+ goto out;
+ }
+
+ ret = 0;
out:
- if (volume_id_str) {
- gf_msg_debug (frame->this->name, 0,
- "Volume Id: %s", volume_id_str);
- pthread_mutex_lock (&fs->mutex);
- gf_uuid_parse (volume_id_str, fs->vol_uuid);
- pthread_mutex_unlock (&fs->mutex);
- }
+ if (volume_id_str) {
+ gf_msg_debug(frame->this->name, 0, "Volume Id: %s", volume_id_str);
+ pthread_mutex_lock(&fs->mutex);
+ gf_uuid_parse(volume_id_str, fs->vol_uuid);
+ pthread_mutex_unlock(&fs->mutex);
+ }
- if (ret) {
- gf_msg (frame->this->name, GF_LOG_ERROR, errno,
- API_MSG_GET_VOLINFO_CBK_FAILED, "In GET_VOLUME_INFO "
- "cbk, received error: %s", strerror(errno));
- }
+ if (ret) {
+ gf_smsg(frame->this->name, GF_LOG_ERROR, errno,
+ API_MSG_GET_VOLINFO_CBK_FAILED, "error=%s", strerror(errno),
+ NULL);
+ }
- if (dict)
- dict_destroy (dict);
+ if (dict)
+ dict_unref(dict);
- if (rsp.dict.dict_val)
- free (rsp.dict.dict_val);
+ if (rsp.dict.dict_val)
+ free(rsp.dict.dict_val);
- if (rsp.op_errstr && *rsp.op_errstr)
- free (rsp.op_errstr);
+ if (rsp.op_errstr)
+ free(rsp.op_errstr);
- gf_msg_debug (frame->this->name, 0, "Returning: %d", ret);
+ gf_msg_debug(frame->this->name, 0, "Returning: %d", ret);
- __wake (args);
+ __wake(args);
- return ret;
+ return ret;
}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volumeid, 3.5.0)
int
-pub_glfs_get_volumeid (struct glfs *fs, char *volid, size_t size)
+pub_glfs_get_volumeid(struct glfs *fs, char *volid, size_t size)
{
- /* TODO: Define a global macro to store UUID size */
- size_t uuid_size = 16;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- pthread_mutex_lock (&fs->mutex);
- {
- /* check if the volume uuid is initialized */
- if (!gf_uuid_is_null (fs->vol_uuid)) {
- pthread_mutex_unlock (&fs->mutex);
- goto done;
- }
+ /* TODO: Define a global macro to store UUID size */
+ size_t uuid_size = 16;
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ pthread_mutex_lock(&fs->mutex);
+ {
+ /* check if the volume uuid is initialized */
+ if (!gf_uuid_is_null(fs->vol_uuid)) {
+ pthread_mutex_unlock(&fs->mutex);
+ goto done;
}
- pthread_mutex_unlock (&fs->mutex);
+ }
+ pthread_mutex_unlock(&fs->mutex);
- /* Need to fetch volume_uuid */
- glfs_get_volume_info (fs);
+ /* Need to fetch volume_uuid */
+ glfs_get_volume_info(fs);
- if (gf_uuid_is_null (fs->vol_uuid)) {
- gf_msg (THIS->name, GF_LOG_ERROR, EINVAL,
- API_MSG_FETCH_VOLUUID_FAILED, "Unable to fetch "
- "volume UUID");
- goto out;
- }
+ if (gf_uuid_is_null(fs->vol_uuid)) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_FETCH_VOLUUID_FAILED,
+ NULL);
+ goto out;
+ }
done:
- if (!volid || !size) {
- gf_msg_debug (THIS->name, 0, "volumeid/size is null");
- __GLFS_EXIT_FS;
- return uuid_size;
- }
+ if (!volid || !size) {
+ gf_msg_debug(THIS->name, 0, "volumeid/size is null");
+ __GLFS_EXIT_FS;
+ return uuid_size;
+ }
- if (size < uuid_size) {
- gf_msg (THIS->name, GF_LOG_ERROR, ERANGE, API_MSG_INSUFF_SIZE,
- "Insufficient size passed");
- errno = ERANGE;
- goto out;
- }
+ if (size < uuid_size) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ERANGE, API_MSG_INSUFF_SIZE, NULL);
+ errno = ERANGE;
+ goto out;
+ }
- memcpy (volid, fs->vol_uuid, uuid_size);
+ memcpy(volid, fs->vol_uuid, uuid_size);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
- return uuid_size;
+ return uuid_size;
out:
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return -1;
+ return -1;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volumeid, 3.5.0);
-
int
-glfs_get_volume_info (struct glfs *fs)
+glfs_get_volume_info(struct glfs *fs)
{
- call_frame_t *frame = NULL;
- glusterfs_ctx_t *ctx = NULL;
- struct syncargs args = {0, };
- int ret = 0;
-
- ctx = fs->ctx;
- frame = create_frame (THIS, ctx->pool);
- if (!frame) {
- gf_msg ("glfs", GF_LOG_ERROR, ENOMEM,
- API_MSG_FRAME_CREAT_FAILED,
- "failed to create the frame");
- ret = -1;
- goto out;
- }
+ call_frame_t *frame = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ struct syncargs args = {
+ 0,
+ };
+ int ret = 0;
- frame->local = &args;
+ ctx = fs->ctx;
+ frame = create_frame(THIS, ctx->pool);
+ if (!frame) {
+ gf_smsg("glfs", GF_LOG_ERROR, ENOMEM, API_MSG_FRAME_CREAT_FAILED, NULL);
+ ret = -1;
+ goto out;
+ }
- __yawn ((&args));
+ frame->local = &args;
- ret = glfs_get_volume_info_rpc (frame, THIS, fs);
- if (ret)
- goto out;
+ __yawn((&args));
- __yield ((&args));
+ ret = glfs_get_volume_info_rpc(frame, THIS, fs);
+ if (ret)
+ goto out;
- frame->local = NULL;
- STACK_DESTROY (frame->root);
+ __yield((&args));
+
+ frame->local = NULL;
+ STACK_DESTROY(frame->root);
out:
- return ret;
+ return ret;
}
int32_t
-glfs_get_volume_info_rpc (call_frame_t *frame, xlator_t *this,
- struct glfs *fs)
+glfs_get_volume_info_rpc(call_frame_t *frame, xlator_t *this, struct glfs *fs)
{
- gf_get_volume_info_req req = {{0,}};
- int ret = 0;
- glusterfs_ctx_t *ctx = NULL;
- dict_t *dict = NULL;
- int32_t flags = 0;
-
- if (!frame || !this || !fs) {
- ret = -1;
- goto out;
- }
-
- ctx = fs->ctx;
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- if (fs->volname) {
- ret = dict_set_str (dict, "volname", fs->volname);
- if (ret)
- goto out;
- }
-
- // Set the flags for the fields which we are interested in
- flags = (int32_t)GF_GET_VOLUME_UUID; //ctx->flags;
- ret = dict_set_int32 (dict, "flags", flags);
- if (ret) {
- gf_msg (frame->this->name, GF_LOG_ERROR, EINVAL,
- API_MSG_DICT_SET_FAILED, "failed to set flags");
- goto out;
- }
-
- 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_GET_VOLUME_INFO,
- mgmt_get_volinfo_cbk,
- (xdrproc_t)xdr_gf_get_volume_info_req);
+ gf_get_volume_info_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ glusterfs_ctx_t *ctx = NULL;
+ dict_t *dict = NULL;
+ int32_t flags = 0;
+
+ if (!frame || !this || !fs) {
+ ret = -1;
+ goto out;
+ }
+
+ ctx = fs->ctx;
+
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ if (fs->volname) {
+ ret = dict_set_str(dict, "volname", fs->volname);
+ if (ret)
+ goto out;
+ }
+
+ // Set the flags for the fields which we are interested in
+ flags = (int32_t)GF_GET_VOLUME_UUID; // ctx->flags;
+ ret = dict_set_int32(dict, "flags", flags);
+ if (ret) {
+ gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL,
+ API_MSG_DICT_SET_FAILED, "flags", NULL);
+ goto out;
+ }
+
+ 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_GET_VOLUME_INFO, mgmt_get_volinfo_cbk,
+ (xdrproc_t)xdr_gf_get_volume_info_req);
out:
- if (dict) {
- dict_unref (dict);
- }
+ if (dict) {
+ dict_unref(dict);
+ }
- GF_FREE (req.dict.dict_val);
+ GF_FREE(req.dict.dict_val);
- return ret;
+ return ret;
}
static int
-glusterfs_oldvolfile_update (struct glfs *fs, char *volfile, ssize_t size)
+glusterfs_oldvolfile_update(struct glfs *fs, char *volfile, ssize_t size)
{
- int ret = -1;
-
- pthread_mutex_lock (&fs->mutex);
-
- fs->oldvollen = size;
- if (!fs->oldvolfile) {
- fs->oldvolfile = GF_CALLOC (1, size+1, glfs_mt_volfile_t);
- } else {
- fs->oldvolfile = GF_REALLOC (fs->oldvolfile, size+1);
- }
-
- if (!fs->oldvolfile) {
- fs->oldvollen = 0;
- } else {
- memcpy (fs->oldvolfile, volfile, size);
- fs->oldvollen = size;
- ret = 0;
- }
+ int ret = -1;
+
+ pthread_mutex_lock(&fs->mutex);
+
+ fs->oldvollen = size;
+ if (!fs->oldvolfile) {
+ fs->oldvolfile = CALLOC(1, size + 1);
+ } else {
+ fs->oldvolfile = REALLOC(fs->oldvolfile, size + 1);
+ }
+
+ if (!fs->oldvolfile) {
+ fs->oldvollen = 0;
+ } else {
+ memcpy(fs->oldvolfile, volfile, size);
+ fs->oldvollen = size;
+ ret = 0;
+ }
- pthread_mutex_unlock (&fs->mutex);
+ pthread_mutex_unlock(&fs->mutex);
- return ret;
+ return ret;
}
-
int
-glfs_mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
+glfs_mgmt_getspec_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- gf_getspec_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- glusterfs_ctx_t *ctx = NULL;
- int ret = 0;
- ssize_t size = 0;
- FILE *tmpfp = NULL;
- int need_retry = 0;
- struct glfs *fs = NULL;
-
- frame = myframe;
- ctx = frame->this->ctx;
-
- if (!ctx) {
- gf_msg (frame->this->name, GF_LOG_ERROR, EINVAL,
- API_MSG_INVALID_ENTRY, "NULL context");
- errno = EINVAL;
- ret = -1;
- goto out;
- }
-
- fs = ((xlator_t *)ctx->master)->private;
-
- if (-1 == req->rpc_status) {
- ret = -1;
- need_retry = 1;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
- if (ret < 0) {
- gf_msg (frame->this->name, GF_LOG_ERROR, 0,
- API_MSG_XDR_DECODE_FAILED, "XDR decoding error");
- ret = -1;
- goto out;
- }
-
- if (-1 == rsp.op_ret) {
- gf_msg (frame->this->name, GF_LOG_ERROR, rsp.op_errno,
- API_MSG_GET_VOLFILE_FAILED,
- "failed to get the 'volume file' from server");
- ret = -1;
- errno = rsp.op_errno;
- goto out;
- }
-
- ret = 0;
- size = rsp.op_ret;
-
- if ((size == fs->oldvollen) &&
- (memcmp (fs->oldvolfile, rsp.spec, size) == 0)) {
- gf_msg (frame->this->name, GF_LOG_INFO, 0,
- API_MSG_VOLFILE_INFO,
- "No change in volfile, continuing");
- goto out;
- }
-
- tmpfp = tmpfile ();
- if (!tmpfp) {
- ret = -1;
- goto out;
- }
-
- fwrite (rsp.spec, size, 1, tmpfp);
- fflush (tmpfp);
- if (ferror (tmpfp)) {
- ret = -1;
- goto out;
- }
-
- /* Check if only options have changed. No need to reload the
- * volfile if topology hasn't changed.
- * glusterfs_volfile_reconfigure returns 3 possible return states
- * return 0 =======> reconfiguration of options has succeeded
- * return 1 =======> the graph has to be reconstructed and all the xlators should be inited
- * return -1(or -ve) =======> Some Internal Error occurred during the operation
- */
-
- ret = glusterfs_volfile_reconfigure (fs->oldvollen, tmpfp, fs->ctx,
- fs->oldvolfile);
- if (ret == 0) {
- gf_msg_debug ("glusterfsd-mgmt", 0, "No need to re-load "
- "volfile, reconfigure done");
- ret = glusterfs_oldvolfile_update (fs, rsp.spec, size);
- goto out;
- }
-
- if (ret < 0) {
- gf_msg_debug ("glusterfsd-mgmt", 0, "Reconfigure failed !!");
- goto out;
- }
-
- ret = glfs_process_volfp (fs, tmpfp);
- /* tmpfp closed */
- tmpfp = NULL;
- if (ret)
- goto out;
-
- ret = glusterfs_oldvolfile_update (fs, rsp.spec, size);
+ gf_getspec_rsp rsp = {
+ 0,
+ };
+ call_frame_t *frame = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = 0;
+ ssize_t size = 0;
+ FILE *tmpfp = NULL;
+ int need_retry = 0;
+ struct glfs *fs = NULL;
+ dict_t *dict = NULL;
+ char *servers_list = NULL;
+ int tmp_fd = -1;
+ char template[] = "/tmp/gfapi.volfile.XXXXXX";
+
+ frame = myframe;
+ ctx = frame->this->ctx;
+
+ if (!ctx) {
+ gf_smsg(frame->this->name, GF_LOG_ERROR, EINVAL, API_MSG_NULL,
+ "context", NULL);
+ errno = EINVAL;
+ ret = -1;
+ goto out;
+ }
+
+ fs = ((xlator_t *)ctx->master)->private;
+
+ if (-1 == req->rpc_status) {
+ ret = -1;
+ need_retry = 1;
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
+ if (ret < 0) {
+ gf_smsg(frame->this->name, GF_LOG_ERROR, 0, API_MSG_XDR_DECODE_FAILED,
+ NULL);
+ ret = -1;
+ goto out;
+ }
+
+ if (-1 == rsp.op_ret) {
+ gf_smsg(frame->this->name, GF_LOG_ERROR, rsp.op_errno,
+ API_MSG_GET_VOLFILE_FAILED, "from server", NULL);
+ ret = -1;
+ errno = rsp.op_errno;
+ goto out;
+ }
+
+ if (!rsp.xdata.xdata_len) {
+ goto volfile;
+ }
+
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = dict_unserialize(rsp.xdata.xdata_val, rsp.xdata.xdata_len, &dict);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR,
+ "failed to unserialize xdata to dictionary");
+ goto out;
+ }
+ dict->extra_stdfree = rsp.xdata.xdata_val;
+
+ /* glusterd2 only */
+ ret = dict_get_str(dict, "servers-list", &servers_list);
+ if (ret) {
+ goto volfile;
+ }
+
+ gf_log(frame->this->name, GF_LOG_INFO,
+ "Received list of available volfile servers: %s", servers_list);
+
+ ret = gf_process_getspec_servers_list(&ctx->cmd_args, servers_list);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR,
+ "Failed (%s) to process servers list: %s", strerror(errno),
+ servers_list);
+ }
+
+volfile:
+ ret = 0;
+ size = rsp.op_ret;
+
+ pthread_mutex_lock(&fs->mutex);
+ if ((size == fs->oldvollen) &&
+ (memcmp(fs->oldvolfile, rsp.spec, size) == 0)) {
+ pthread_mutex_unlock(&fs->mutex);
+ gf_smsg(frame->this->name, GF_LOG_INFO, 0, API_MSG_VOLFILE_INFO, NULL);
+ goto out;
+ }
+ pthread_mutex_unlock(&fs->mutex);
+
+ /* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
+ tmp_fd = mkstemp(template);
+ if (-1 == tmp_fd) {
+ ret = -1;
+ goto out;
+ }
+
+ /* Calling unlink so that when the file is closed or program
+ * terminates the temporary file is deleted.
+ */
+ ret = sys_unlink(template);
+ if (ret < 0) {
+ gf_smsg(frame->this->name, GF_LOG_INFO, 0, API_MSG_UNABLE_TO_DEL,
+ "template=%s", template, NULL);
+ ret = 0;
+ }
+
+ tmpfp = fdopen(tmp_fd, "w+b");
+ if (!tmpfp) {
+ ret = -1;
+ goto out;
+ }
+
+ fwrite(rsp.spec, size, 1, tmpfp);
+ fflush(tmpfp);
+ if (ferror(tmpfp)) {
+ ret = -1;
+ goto out;
+ }
+
+ /* Check if only options have changed. No need to reload the
+ * volfile if topology hasn't changed.
+ * glusterfs_volfile_reconfigure returns 3 possible return states
+ * return 0 =======> reconfiguration of options has succeeded
+ * return 1 =======> the graph has to be reconstructed and all
+ * the xlators should be inited return -1(or -ve) =======> Some Internal
+ * Error occurred during the operation
+ */
+
+ pthread_mutex_lock(&fs->mutex);
+ ret = gf_volfile_reconfigure(fs->oldvollen, tmpfp, fs->ctx, fs->oldvolfile);
+ pthread_mutex_unlock(&fs->mutex);
+
+ if (ret == 0) {
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "No need to re-load "
+ "volfile, reconfigure done");
+ ret = glusterfs_oldvolfile_update(fs, rsp.spec, size);
+ goto out;
+ }
+
+ if (ret < 0) {
+ gf_msg_debug("glusterfsd-mgmt", 0, "Reconfigure failed !!");
+ goto out;
+ }
+
+ ret = glfs_process_volfp(fs, tmpfp);
+ /* tmpfp closed */
+ tmpfp = NULL;
+ tmp_fd = -1;
+ if (ret)
+ goto out;
+
+ ret = glusterfs_oldvolfile_update(fs, rsp.spec, size);
out:
- STACK_DESTROY (frame->root);
-
- if (rsp.spec)
- free (rsp.spec);
-
- // Stop if server is running at an unsupported op-version
- if (ENOTSUP == ret) {
- gf_msg ("mgmt", GF_LOG_ERROR, ENOTSUP, API_MSG_WRONG_OPVERSION,
- "Server is operating at an op-version which is not "
- "supported");
- errno = ENOTSUP;
- glfs_init_done (fs, -1);
- }
-
- if (ret && ctx && !ctx->active) {
- /* Do it only for the first time */
- /* Failed to get the volume file, something wrong,
- restart the process */
- gf_msg ("glfs-mgmt", GF_LOG_ERROR, EINVAL,
- API_MSG_INVALID_ENTRY,
- "failed to fetch volume file (key:%s)",
- ctx->cmd_args.volfile_id);
- if (!need_retry) {
- if (!errno)
- errno = EINVAL;
- glfs_init_done (fs, -1);
- }
- }
-
- if (tmpfp)
- fclose (tmpfp);
-
- return 0;
-}
-
-
-int
-glfs_volfile_fetch (struct glfs *fs)
-{
- cmd_args_t *cmd_args = NULL;
- gf_getspec_req req = {0, };
- int ret = 0;
- call_frame_t *frame = NULL;
- glusterfs_ctx_t *ctx = NULL;
- dict_t *dict = NULL;
-
- ctx = fs->ctx;
- cmd_args = &ctx->cmd_args;
-
- frame = create_frame (THIS, ctx->pool);
-
- req.key = cmd_args->volfile_id;
- req.flags = 0;
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- // Set the supported min and max op-versions, so glusterd can make a
- // decision
- ret = dict_set_int32 (dict, "min-op-version", GD_OP_VERSION_MIN);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_ERROR, EINVAL,
- API_MSG_DICT_SET_FAILED,
- "Failed to set min-op-version in request dict");
- goto out;
+ STACK_DESTROY(frame->root);
+
+ if (rsp.spec)
+ free(rsp.spec);
+
+ if (dict)
+ dict_unref(dict);
+
+ // Stop if server is running at an unsupported op-version
+ if (ENOTSUP == ret) {
+ gf_smsg("mgmt", GF_LOG_ERROR, ENOTSUP, API_MSG_WRONG_OPVERSION, NULL);
+ errno = ENOTSUP;
+ glfs_init_done(fs, -1);
+ }
+
+ if (ret && ctx && !ctx->active) {
+ /* Do it only for the first time */
+ /* Failed to get the volume file, something wrong,
+ restart the process */
+ gf_smsg("glfs-mgmt", GF_LOG_ERROR, EINVAL, API_MSG_GET_VOLFILE_FAILED,
+ "key=%s", ctx->cmd_args.volfile_id, NULL);
+ if (!need_retry) {
+ if (!errno)
+ errno = EINVAL;
+ glfs_init_done(fs, -1);
}
+ }
- ret = dict_set_int32 (dict, "max-op-version", GD_OP_VERSION_MAX);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_ERROR, EINVAL,
- API_MSG_DICT_SET_FAILED,
- "Failed to set max-op-version in request dict");
- goto out;
- }
+ if (tmpfp)
+ fclose(tmpfp);
+ else if (tmp_fd != -1)
+ sys_close(tmp_fd);
- ret = dict_allocate_and_serialize (dict, &req.xdata.xdata_val,
- &req.xdata.xdata_len);
- if (ret < 0) {
- gf_msg (THIS->name, GF_LOG_ERROR, 0,
- API_MSG_DICT_SERIALIZE_FAILED,
- "Failed to serialize dictionary");
- goto out;
- }
+ return 0;
+}
- ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,
- GF_HNDSK_GETSPEC, glfs_mgmt_getspec_cbk,
- (xdrproc_t)xdr_gf_getspec_req);
+int
+glfs_volfile_fetch(struct glfs *fs)
+{
+ cmd_args_t *cmd_args = NULL;
+ gf_getspec_req req = {
+ 0,
+ };
+ int ret = -1;
+ call_frame_t *frame = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ dict_t *dict = NULL;
+
+ ctx = fs->ctx;
+ cmd_args = &ctx->cmd_args;
+
+ req.key = cmd_args->volfile_id;
+ req.flags = 0;
+
+ dict = dict_new();
+ if (!dict) {
+ goto out;
+ }
+
+ // Set the supported min and max op-versions, so glusterd can make a
+ // decision
+ ret = dict_set_int32(dict, "min-op-version", GD_OP_VERSION_MIN);
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED,
+ "min-op-version", NULL);
+ goto out;
+ }
+
+ ret = dict_set_int32(dict, "max-op-version", GD_OP_VERSION_MAX);
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, EINVAL, API_MSG_DICT_SET_FAILED,
+ "max-op-version", NULL);
+ goto out;
+ }
+
+ /* Ask for a list of volfile (glusterd2 only) servers */
+ if (GF_CLIENT_PROCESS == ctx->process_mode) {
+ req.flags = req.flags | GF_GETSPEC_FLAG_SERVERS_LIST;
+ }
+
+ ret = dict_allocate_and_serialize(dict, &req.xdata.xdata_val,
+ &req.xdata.xdata_len);
+ if (ret < 0) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, API_MSG_DICT_SERIALIZE_FAILED,
+ NULL);
+ goto out;
+ }
+
+ frame = create_frame(THIS, ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = mgmt_submit_request(&req, frame, ctx, &clnt_handshake_prog,
+ GF_HNDSK_GETSPEC, glfs_mgmt_getspec_cbk,
+ (xdrproc_t)xdr_gf_getspec_req);
out:
- return ret;
-}
+ if (req.xdata.xdata_val)
+ GF_FREE(req.xdata.xdata_val);
+ if (dict)
+ dict_unref(dict);
+ return ret;
+}
static int
-mgmt_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
- void *data)
+mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
+ void *data)
{
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
- server_cmdline_t *server = NULL;
- rpc_transport_t *rpc_trans = NULL;
- struct glfs *fs = NULL;
- int ret = 0;
-
- this = mydata;
- rpc_trans = rpc->conn.trans;
-
- ctx = this->ctx;
- if (!ctx)
- goto out;
-
- fs = ((xlator_t *)ctx->master)->private;
-
- switch (event) {
- case RPC_CLNT_DISCONNECT:
- if (!ctx->active) {
- gf_msg ("glfs-mgmt", GF_LOG_ERROR, errno,
- API_MSG_REMOTE_HOST_CONN_FAILED,
- "failed to connect with remote-host: %s (%s)",
- ctx->cmd_args.volfile_server,
- strerror (errno));
- server = ctx->cmd_args.curr_server;
- if (server->list.next == &ctx->cmd_args.volfile_servers) {
- errno = ENOTCONN;
- gf_msg ("glfs-mgmt", GF_LOG_INFO, ENOTCONN,
- API_MSG_VOLFILE_SERVER_EXHAUST,
- "Exhausted all volfile servers");
- glfs_init_done (fs, -1);
- break;
- }
- server = list_entry (server->list.next, typeof(*server),
- list);
- ctx->cmd_args.curr_server = server;
- ctx->cmd_args.volfile_server_port = server->port;
- ctx->cmd_args.volfile_server = server->volfile_server;
- ctx->cmd_args.volfile_server_transport = server->transport;
-
- ret = dict_set_int32 (rpc_trans->options,
- "remote-port",
- server->port);
- if (ret != 0) {
- gf_msg ("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
- API_MSG_DICT_SET_FAILED,
- "failed to set remote-port: %d",
- server->port);
- errno = ENOTCONN;
- glfs_init_done (fs, -1);
- break;
- }
-
- ret = dict_set_str (rpc_trans->options,
- "remote-host",
- server->volfile_server);
- if (ret != 0) {
- gf_msg ("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
- API_MSG_DICT_SET_FAILED,
- "failed to set remote-host: %s",
- server->volfile_server);
- errno = ENOTCONN;
- glfs_init_done (fs, -1);
- break;
- }
-
- ret = dict_set_str (rpc_trans->options,
- "transport-type",
- server->transport);
- if (ret != 0) {
- gf_msg ("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
- API_MSG_DICT_SET_FAILED,
- "failed to set transport-type: %s",
- server->transport);
- errno = ENOTCONN;
- glfs_init_done (fs, -1);
- break;
- }
- gf_msg ("glfs-mgmt", GF_LOG_INFO, 0,
- API_MSG_VOLFILE_CONNECTING,
- "connecting to next volfile server %s"
- " at port %d with transport: %s",
- server->volfile_server, server->port,
- server->transport);
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ server_cmdline_t *server = NULL;
+ rpc_transport_t *rpc_trans = NULL;
+ struct glfs *fs = NULL;
+ int ret = 0;
+ struct dnscache6 *dnscache = NULL;
+
+ this = mydata;
+ rpc_trans = rpc->conn.trans;
+
+ ctx = this->ctx;
+ if (!ctx)
+ goto out;
+
+ fs = ((xlator_t *)ctx->master)->private;
+
+ switch (event) {
+ case RPC_CLNT_DISCONNECT:
+ if (!ctx->active) {
+ if (rpc_trans->connect_failed)
+ gf_smsg("glfs-mgmt", GF_LOG_ERROR, 0,
+ API_MSG_REMOTE_HOST_CONN_FAILED, "server=%s",
+ ctx->cmd_args.volfile_server, NULL);
+ else
+ gf_smsg("glfs-mgmt", GF_LOG_INFO, 0,
+ API_MSG_REMOTE_HOST_CONN_FAILED, "server=%s",
+ ctx->cmd_args.volfile_server, NULL);
+
+ if (!rpc->disabled) {
+ /*
+ * Check if dnscache is exhausted for current server
+ * and continue until cache is exhausted
+ */
+ dnscache = rpc_trans->dnscache;
+ if (dnscache && dnscache->next) {
+ break;
+ }
+ }
+ server = ctx->cmd_args.curr_server;
+ if (server->list.next == &ctx->cmd_args.volfile_servers) {
+ errno = ENOTCONN;
+ gf_smsg("glfs-mgmt", GF_LOG_INFO, ENOTCONN,
+ API_MSG_VOLFILE_SERVER_EXHAUST, NULL);
+ glfs_init_done(fs, -1);
+ break;
}
- break;
- case RPC_CLNT_CONNECT:
- rpc_clnt_set_connected (&((struct rpc_clnt*)ctx->mgmt)->conn);
-
- ret = glfs_volfile_fetch (fs);
- if (ret && (ctx->active == NULL)) {
- /* Do it only for the first time */
- /* Exit the process.. there are some wrong options */
- gf_msg ("glfs-mgmt", GF_LOG_ERROR, EINVAL,
- API_MSG_INVALID_ENTRY,
- "failed to fetch volume file (key:%s)",
- ctx->cmd_args.volfile_id);
- errno = EINVAL;
- glfs_init_done (fs, -1);
+ server = list_entry(server->list.next, typeof(*server), list);
+ ctx->cmd_args.curr_server = server;
+ ctx->cmd_args.volfile_server_port = server->port;
+ ctx->cmd_args.volfile_server = server->volfile_server;
+ ctx->cmd_args.volfile_server_transport = server->transport;
+
+ ret = dict_set_str(rpc_trans->options, "transport-type",
+ server->transport);
+ if (ret != 0) {
+ gf_smsg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
+ API_MSG_DICT_SET_FAILED, "transport-type=%s",
+ server->transport, NULL);
+ errno = ENOTCONN;
+ glfs_init_done(fs, -1);
+ break;
}
- break;
- default:
- break;
- }
+ if (strcmp(server->transport, "unix") == 0) {
+ ret = dict_set_str(rpc_trans->options,
+ "transport.socket.connect-path",
+ server->volfile_server);
+ if (ret != 0) {
+ gf_smsg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
+ API_MSG_DICT_SET_FAILED,
+ "socket.connect-path=%s",
+ server->volfile_server, NULL);
+ errno = ENOTCONN;
+ glfs_init_done(fs, -1);
+ break;
+ }
+ /* delete the remote-host and remote-port keys
+ * in case they were set while looping through
+ * list of volfile servers previously
+ */
+ dict_del(rpc_trans->options, "remote-host");
+ dict_del(rpc_trans->options, "remote-port");
+ } else {
+ ret = dict_set_int32(rpc_trans->options, "remote-port",
+ server->port);
+ if (ret != 0) {
+ gf_smsg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
+ API_MSG_DICT_SET_FAILED, "remote-port=%d",
+ server->port, NULL);
+ errno = ENOTCONN;
+ glfs_init_done(fs, -1);
+ break;
+ }
+
+ ret = dict_set_str(rpc_trans->options, "remote-host",
+ server->volfile_server);
+ if (ret != 0) {
+ gf_smsg("glfs-mgmt", GF_LOG_ERROR, ENOTCONN,
+ API_MSG_DICT_SET_FAILED, "remote-host=%s",
+ server->volfile_server, NULL);
+ errno = ENOTCONN;
+ glfs_init_done(fs, -1);
+ break;
+ }
+ /* delete the "transport.socket.connect-path"
+ * key in case if it was set while looping
+ * through list of volfile servers previously
+ */
+ dict_del(rpc_trans->options,
+ "transport.socket.connect-path");
+ }
+
+ gf_smsg("glfs-mgmt", GF_LOG_INFO, 0, API_MSG_VOLFILE_CONNECTING,
+ "server=%s", server->volfile_server, "port=%d",
+ server->port, "transport=%s", server->transport, NULL);
+ }
+ break;
+ case RPC_CLNT_CONNECT:
+ ret = glfs_volfile_fetch(fs);
+ if (ret && (ctx->active == NULL)) {
+ /* Do it only for the first time */
+ /* Exit the process.. there are some wrong options */
+ gf_smsg("glfs-mgmt", GF_LOG_ERROR, EINVAL,
+ API_MSG_GET_VOLFILE_FAILED, "key=%s",
+ ctx->cmd_args.volfile_id, NULL);
+ errno = EINVAL;
+ glfs_init_done(fs, -1);
+ }
+
+ break;
+ default:
+ break;
+ }
out:
- return 0;
+ return 0;
}
-
int
-glusterfs_mgmt_notify (int32_t op, void *data, ...)
+glusterfs_mgmt_notify(int32_t op, void *data, ...)
{
- int ret = 0;
+ int ret = 0;
- switch (op)
- {
- case GF_EN_DEFRAG_STATUS:
- break;
+ switch (op) {
+ case GF_EN_DEFRAG_STATUS:
+ break;
- default:
- break;
- }
+ default:
+ break;
+ }
- return ret;
+ return ret;
}
-
int
-glfs_mgmt_init (struct glfs *fs)
+glfs_mgmt_init(struct glfs *fs)
{
- cmd_args_t *cmd_args = NULL;
- struct rpc_clnt *rpc = NULL;
- dict_t *options = NULL;
- int ret = -1;
- int port = GF_DEFAULT_BASE_PORT;
- char *host = NULL;
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = fs->ctx;
- cmd_args = &ctx->cmd_args;
-
- if (ctx->mgmt)
- return 0;
-
- if (cmd_args->volfile_server_port)
- port = cmd_args->volfile_server_port;
-
- host = "localhost";
- if (cmd_args->volfile_server)
- host = cmd_args->volfile_server;
-
- ret = rpc_transport_inet_options_build (&options, host, port);
- if (ret)
- goto out;
-
- rpc = rpc_clnt_new (options, THIS, THIS->name, 8);
- if (!rpc) {
- ret = -1;
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- API_MSG_CREATE_RPC_CLIENT_FAILED,
- "failed to create rpc clnt");
- goto out;
- }
-
- ret = rpc_clnt_register_notify (rpc, mgmt_rpc_notify, THIS);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- API_MSG_REG_NOTIFY_FUNC_FAILED,
- "failed to register notify function");
- goto out;
- }
-
- ret = rpcclnt_cbk_program_register (rpc, &mgmt_cbk_prog, THIS);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- API_MSG_REG_CBK_FUNC_FAILED,
- "failed to register callback function");
- goto out;
- }
-
- ctx->notify = glusterfs_mgmt_notify;
-
- /* This value should be set before doing the 'rpc_clnt_start()' as
- the notify function uses this variable */
- ctx->mgmt = rpc;
-
- ret = rpc_clnt_start (rpc);
+ cmd_args_t *cmd_args = NULL;
+ struct rpc_clnt *rpc = NULL;
+ dict_t *options = NULL;
+ int ret = -1;
+ int port = GF_DEFAULT_BASE_PORT;
+ char *host = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = fs->ctx;
+ cmd_args = &ctx->cmd_args;
+
+ if (ctx->mgmt)
+ return 0;
+
+ options = dict_new();
+ if (!options)
+ goto out;
+
+ if (cmd_args->volfile_server_port)
+ port = cmd_args->volfile_server_port;
+
+ if (cmd_args->volfile_server) {
+ host = cmd_args->volfile_server;
+ } else if (cmd_args->volfile_server_transport &&
+ !strcmp(cmd_args->volfile_server_transport, "unix")) {
+ host = DEFAULT_GLUSTERD_SOCKFILE;
+ } else {
+ host = "localhost";
+ }
+
+ if (cmd_args->volfile_server_transport &&
+ !strcmp(cmd_args->volfile_server_transport, "unix")) {
+ ret = rpc_transport_unix_options_build(options, host, 0);
+ } else {
+ xlator_cmdline_option_t *opt = find_xlator_option_in_cmd_args_t(
+ "address-family", cmd_args);
+ ret = rpc_transport_inet_options_build(options, host, port,
+ (opt ? opt->value : NULL));
+ }
+
+ if (ret)
+ goto out;
+
+ rpc = rpc_clnt_new(options, THIS, THIS->name, 8);
+ if (!rpc) {
+ ret = -1;
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, API_MSG_CREATE_RPC_CLIENT_FAILED,
+ NULL);
+ goto out;
+ }
+
+ ret = rpc_clnt_register_notify(rpc, mgmt_rpc_notify, THIS);
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, API_MSG_REG_NOTIFY_FUNC_FAILED,
+ NULL);
+ goto out;
+ }
+
+ ret = rpcclnt_cbk_program_register(rpc, &mgmt_cbk_prog, THIS);
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, API_MSG_REG_CBK_FUNC_FAILED,
+ NULL);
+ 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;
+ if (options)
+ dict_unref(options);
+ return ret;
}
diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c
index 65fe590144d..8a393ecb464 100644
--- a/api/src/glfs-resolve.c
+++ b/api/src/glfs-resolve.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2012-2018 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
@@ -8,7 +8,6 @@
cases as published by the Free Software Foundation.
*/
-
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
@@ -16,59 +15,61 @@
#include <inttypes.h>
#include <limits.h>
-#include "glusterfs.h"
-#include "logging.h"
-#include "stack.h"
-#include "event.h"
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/logging.h>
+#include <glusterfs/stack.h>
+#include <glusterfs/gf-event.h>
#include "glfs-mem-types.h"
-#include "common-utils.h"
-#include "syncop.h"
-#include "call-stub.h"
+#include <glusterfs/common-utils.h>
+#include <glusterfs/syncop.h>
+#include <glusterfs/call-stub.h>
#include "gfapi-messages.h"
-
+#include <glusterfs/inode.h>
#include "glfs-internal.h"
-#define graphid_str(subvol) (uuid_utoa((unsigned char *)subvol->graph->graph_uuid))
-
-
+#define graphid_str(subvol) \
+ (uuid_utoa((unsigned char *)subvol->graph->graph_uuid))
int
-glfs_first_lookup_safe (xlator_t *subvol)
+glfs_first_lookup_safe(xlator_t *subvol)
{
- loc_t loc = {0, };
- int ret = -1;
+ loc_t loc = {
+ 0,
+ };
+ int ret = -1;
- loc.inode = subvol->itable->root;
- memset (loc.gfid, 0, 16);
- loc.gfid[15] = 1;
- loc.path = "/";
- loc.name = "";
+ loc.inode = subvol->itable->root;
+ memset(loc.gfid, 0, 16);
+ loc.gfid[15] = 1;
+ loc.path = "/";
+ loc.name = "";
- ret = syncop_lookup (subvol, &loc, 0, 0, 0, 0);
- DECODE_SYNCOP_ERR (ret);
+ ret = syncop_lookup(subvol, &loc, 0, 0, 0, 0);
+ DECODE_SYNCOP_ERR(ret);
- gf_msg_debug (subvol->name, 0, "first lookup complete %d", ret);
+ gf_msg_debug(subvol->name, 0, "first lookup complete %d", ret);
- return ret;
+ return ret;
}
-
int
-__glfs_first_lookup (struct glfs *fs, xlator_t *subvol)
+__glfs_first_lookup(struct glfs *fs, xlator_t *subvol)
{
- int ret = -1;
-
- fs->migration_in_progress = 1;
- pthread_mutex_unlock (&fs->mutex);
- {
- ret = glfs_first_lookup_safe (subvol);
- }
- pthread_mutex_lock (&fs->mutex);
- fs->migration_in_progress = 0;
- pthread_cond_broadcast (&fs->cond);
-
- return ret;
-}
+ int ret = -1;
+
+ fs->migration_in_progress = 1;
+ pthread_mutex_unlock(&fs->mutex);
+ {
+ ret = glfs_first_lookup_safe(subvol);
+ }
+ pthread_mutex_lock(&fs->mutex);
+ fs->migration_in_progress = 0;
+ pthread_cond_broadcast(&fs->cond);
+ /* wake up other waiting tasks */
+ __GLFS_SYNCTASK_WAKE(fs);
+
+ return ret;
+}
/**
* We have to check if need_lookup flag is set in both old and the new inodes.
@@ -78,1006 +79,1121 @@ __glfs_first_lookup (struct glfs *fs, xlator_t *subvol)
* below xlators can set their respective contexts.
*/
inode_t *
-glfs_refresh_inode_safe (xlator_t *subvol, inode_t *oldinode,
- gf_boolean_t need_lookup)
+glfs_refresh_inode_safe(xlator_t *subvol, inode_t *oldinode,
+ gf_boolean_t need_lookup)
{
- loc_t loc = {0, };
- int ret = -1;
- struct iatt iatt = {0, };
- inode_t *newinode = NULL;
- gf_boolean_t lookup_needed = _gf_false;
-
-
- if (!oldinode)
- return NULL;
-
- if (!need_lookup && oldinode->table->xl == subvol)
- return inode_ref (oldinode);
-
- newinode = inode_find (subvol->itable, oldinode->gfid);
- if (!need_lookup && newinode) {
-
- lookup_needed = inode_needs_lookup (newinode, THIS);
- if (!lookup_needed)
- return newinode;
- }
-
- gf_uuid_copy (loc.gfid, oldinode->gfid);
- if (!newinode)
- loc.inode = inode_new (subvol->itable);
- else
- loc.inode = newinode;
-
- if (!loc.inode)
- return NULL;
-
- ret = syncop_lookup (subvol, &loc, &iatt, 0, 0, 0);
- DECODE_SYNCOP_ERR (ret);
-
- if (ret) {
- gf_msg (subvol->name, GF_LOG_WARNING, errno,
- API_MSG_INODE_REFRESH_FAILED,
- "inode refresh of %s failed: %s",
- uuid_utoa (oldinode->gfid), strerror (errno));
- loc_wipe (&loc);
- return NULL;
- }
-
- newinode = inode_link (loc.inode, 0, 0, &iatt);
- if (newinode)
- inode_lookup (newinode);
-
- loc_wipe (&loc);
-
- return newinode;
+ loc_t loc = {
+ 0,
+ };
+ int ret = -1;
+ struct iatt iatt = {
+ 0,
+ };
+ inode_t *newinode = NULL;
+ gf_boolean_t lookup_needed = _gf_false;
+ uint64_t ctx_value = LOOKUP_NOT_NEEDED;
+
+ if (!oldinode)
+ return NULL;
+
+ if (!need_lookup && oldinode->table->xl == subvol)
+ return inode_ref(oldinode);
+
+ newinode = inode_find(subvol->itable, oldinode->gfid);
+ if (!need_lookup && newinode) {
+ lookup_needed = inode_needs_lookup(newinode, THIS);
+ if (!lookup_needed)
+ return newinode;
+ }
+
+ gf_uuid_copy(loc.gfid, oldinode->gfid);
+ if (!newinode)
+ loc.inode = inode_new(subvol->itable);
+ else
+ loc.inode = newinode;
+
+ if (!loc.inode)
+ return NULL;
+
+ ret = syncop_lookup(subvol, &loc, &iatt, 0, 0, 0);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret) {
+ gf_smsg(subvol->name, GF_LOG_WARNING, errno,
+ API_MSG_INODE_REFRESH_FAILED, "gfid=%s",
+ uuid_utoa(oldinode->gfid), "err=%s", strerror(errno), NULL);
+ loc_wipe(&loc);
+ return NULL;
+ }
+
+ newinode = inode_link(loc.inode, 0, 0, &iatt);
+ if (newinode) {
+ if (newinode == loc.inode)
+ inode_ctx_set(newinode, THIS, &ctx_value);
+ inode_lookup(newinode);
+ } else {
+ gf_smsg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED,
+ "gfid=%s", uuid_utoa((unsigned char *)&iatt.ia_gfid), NULL);
+ }
+
+ loc_wipe(&loc);
+
+ return newinode;
}
-
inode_t *
-__glfs_refresh_inode (struct glfs *fs, xlator_t *subvol, inode_t *inode,
- gf_boolean_t need_lookup)
+__glfs_refresh_inode(struct glfs *fs, xlator_t *subvol, inode_t *inode,
+ gf_boolean_t need_lookup)
{
- inode_t *newinode = NULL;
-
- fs->migration_in_progress = 1;
- pthread_mutex_unlock (&fs->mutex);
- {
- newinode = glfs_refresh_inode_safe (subvol, inode, need_lookup);
- }
- pthread_mutex_lock (&fs->mutex);
- fs->migration_in_progress = 0;
- pthread_cond_broadcast (&fs->cond);
-
- return newinode;
+ inode_t *newinode = NULL;
+
+ fs->migration_in_progress = 1;
+ pthread_mutex_unlock(&fs->mutex);
+ {
+ newinode = glfs_refresh_inode_safe(subvol, inode, need_lookup);
+ }
+ pthread_mutex_lock(&fs->mutex);
+ fs->migration_in_progress = 0;
+ pthread_cond_broadcast(&fs->cond);
+
+ /* wake up other waiting tasks */
+ __GLFS_SYNCTASK_WAKE(fs);
+
+ return newinode;
}
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_loc_touchup, 3.4.0)
int
-priv_glfs_loc_touchup (loc_t *loc)
+priv_glfs_loc_touchup(loc_t *loc)
{
- int ret = 0;
+ int ret = 0;
- ret = loc_touchup (loc, loc->name);
- if (ret < 0) {
- errno = -ret;
- ret = -1;
- }
+ ret = loc_touchup(loc, loc->name);
+ if (ret < 0) {
+ errno = -ret;
+ ret = -1;
+ }
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_loc_touchup, 3.4.0);
-
int
-glfs_resolve_symlink (struct glfs *fs, xlator_t *subvol, inode_t *inode,
- char **lpath)
+glfs_resolve_symlink(struct glfs *fs, xlator_t *subvol, inode_t *inode,
+ char **lpath)
{
- loc_t loc = {0, };
- char *path = NULL;
- char *rpath = NULL;
- int ret = -1;
-
- loc.inode = inode_ref (inode);
- gf_uuid_copy (loc.gfid, inode->gfid);
- ret = inode_path (inode, NULL, &rpath);
- if (ret < 0)
- goto out;
- loc.path = rpath;
-
- ret = syncop_readlink (subvol, &loc, &path, 4096, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
-
- if (ret < 0)
- goto out;
-
- if (lpath)
- *lpath = path;
+ loc_t loc = {
+ 0,
+ };
+ char *path = NULL;
+ char *rpath = NULL;
+ int ret = -1;
+
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ ret = inode_path(inode, NULL, &rpath);
+ if (ret < 0)
+ goto out;
+ loc.path = rpath;
+
+ ret = syncop_readlink(subvol, &loc, &path, 4096, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+
+ if (ret < 0)
+ goto out;
+
+ if (lpath)
+ *lpath = path;
out:
- loc_wipe (&loc);
- return ret;
+ loc_wipe(&loc);
+ return ret;
}
-
int
-glfs_resolve_base (struct glfs *fs, xlator_t *subvol, inode_t *inode,
- struct iatt *iatt)
+glfs_resolve_base(struct glfs *fs, xlator_t *subvol, inode_t *inode,
+ struct iatt *iatt)
{
- loc_t loc = {0, };
- int ret = -1;
- char *path = NULL;
-
- loc.inode = inode_ref (inode);
- gf_uuid_copy (loc.gfid, inode->gfid);
-
- ret = inode_path (loc.inode, NULL, &path);
- loc.path = path;
- if (ret < 0)
- goto out;
-
- ret = syncop_lookup (subvol, &loc, iatt, NULL, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ loc_t loc = {
+ 0,
+ };
+ int ret = -1;
+ char *path = NULL;
+
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+
+ ret = inode_path(loc.inode, NULL, &path);
+ loc.path = path;
+ if (ret < 0)
+ goto out;
+
+ ret = syncop_lookup(subvol, &loc, iatt, NULL, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
out:
- loc_wipe (&loc);
+ loc_wipe(&loc);
- return ret;
+ return ret;
}
+/*
+ * This function can be used to call named lookup on root.
+ * If you use glfs_resolve_base, that will be a nameless lookup.
+ */
+static int
+glfs_resolve_root(struct glfs *fs, xlator_t *subvol, inode_t *inode,
+ struct iatt *iatt)
+{
+ loc_t loc = {
+ 0,
+ };
+ int ret = -1;
+ char *path = NULL;
+
+ loc.inode = inode_ref(inode);
+
+ ret = inode_path(loc.inode, ".", &path);
+ loc.path = path;
+ loc.name = ".";
+ /* Having a value in loc.name will help to bypass md-cache check for
+ * nameless lookup.
+ * TODO: Re-visit on nameless lookup and md-cache.
+ * Github issue : https://github.com/gluster/glusterfs/issues/232
+ */
+ loc.parent = inode_ref(inode);
+ if (ret < 0)
+ goto out;
+
+ ret = syncop_lookup(subvol, &loc, iatt, NULL, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+out:
+ loc_wipe(&loc);
+ return ret;
+}
inode_t *
-glfs_resolve_component (struct glfs *fs, xlator_t *subvol, inode_t *parent,
- const char *component, struct iatt *iatt,
- int force_lookup)
+glfs_resolve_component(struct glfs *fs, xlator_t *subvol, inode_t *parent,
+ const char *component, struct iatt *iatt,
+ int force_lookup)
{
- loc_t loc = {0, };
- inode_t *inode = NULL;
- int reval = 0;
- int ret = -1;
- int glret = -1;
- struct iatt ciatt = {0, };
- uuid_t gfid;
- dict_t *xattr_req = NULL;
-
- loc.name = component;
-
- loc.parent = inode_ref (parent);
- gf_uuid_copy (loc.pargfid, parent->gfid);
-
- /* /.. and /. should point back to /
- we lookup using inode and gfid of root
- Fill loc.name so that we make use md-cache.
- md-cache is not valid for nameless lookups.
- */
- if (__is_root_gfid (parent->gfid) &&
- (strcmp (component, "..") == 0)) {
- loc.inode = inode_ref (parent);
- loc.name = ".";
+ loc_t loc = {
+ 0,
+ };
+ inode_t *inode = NULL;
+ inode_t *temp_parent = NULL;
+ int reval = 0;
+ int ret = -1;
+ int glret = -1;
+ struct iatt ciatt = {
+ 0,
+ };
+ uuid_t gfid;
+ dict_t *xattr_req = NULL;
+ uint64_t ctx_value = LOOKUP_NOT_NEEDED;
+
+ loc.parent = inode_ref(parent);
+ gf_uuid_copy(loc.pargfid, parent->gfid);
+
+ if (__is_root_gfid(parent->gfid) &&
+ ((strcmp(component, ".") == 0) || (strcmp(component, "..") == 0) ||
+ (strcmp(component, "") == 0))) {
+ if (!force_lookup) {
+ inode = inode_ref(parent);
} else {
- if (strcmp (component, ".") == 0)
- loc.inode = inode_ref (parent);
- else if (strcmp (component, "..") == 0)
- loc.inode = inode_parent (parent, 0, 0);
- else
- loc.inode = inode_grep (parent->table, parent,
- component);
+ ret = glfs_resolve_root(fs, subvol, parent, &ciatt);
+ if (!ret)
+ inode = inode_ref(parent);
+ }
+ goto found;
+ }
+ /* *
+ * if the component name is either "." or "..", it will try to
+ * resolve that if inode has a proper parent (named lookup).
+ *
+ * Below condition works like this
+ *
+ * Example 1 :
+ * Path /out_dir/dir/in_dir/.
+ * In put values :
+ * parent = in_dir
+ * component : "."
+ *
+ * Out put values:
+ * parent : dir
+ * component : "in_dir"
+ *
+ * Example 2 :
+ * Path /out_dir/dir/in_dir/..
+ * In put values :
+ * parent = in_dir
+ * component : ".."
+ *
+ * Out put values:
+ * parent : output_dir
+ * component : "dir"
+ *
+ * In case of nameless lookup, both "." and ".." retained
+ */
+
+ if (strcmp(component, ".") == 0) {
+ loc.inode = inode_ref(parent);
+ temp_parent = inode_parent(loc.inode, 0, 0);
+ if (temp_parent) {
+ inode_unref(loc.parent);
+ loc.parent = temp_parent;
+ gf_uuid_copy(loc.pargfid, temp_parent->gfid);
+ inode_find_directory_name(loc.inode, &loc.name);
}
+ } else if (strcmp(component, "..") == 0) {
+ loc.inode = inode_parent(parent, 0, 0);
+ if (loc.inode) {
+ temp_parent = inode_parent(loc.inode, 0, 0);
+ if (temp_parent) {
+ inode_unref(loc.parent);
+ loc.parent = temp_parent;
+ gf_uuid_copy(loc.pargfid, temp_parent->gfid);
+ inode_find_directory_name(loc.inode, &loc.name);
+ } else if (__is_root_gfid(loc.inode->gfid)) {
+ inode_unref(loc.parent);
+ loc.parent = inode_ref(loc.inode);
+ gf_uuid_copy(loc.pargfid, loc.inode->gfid);
+ loc.name = ".";
+ } else {
+ inode_unref(loc.inode);
+ loc.inode = NULL;
+ }
+ }
+ } else
+ loc.inode = inode_grep(parent->table, parent, component);
- if (loc.inode) {
- gf_uuid_copy (loc.gfid, loc.inode->gfid);
- reval = 1;
-
- if (!force_lookup) {
- inode = inode_ref (loc.inode);
- ciatt.ia_type = inode->ia_type;
- goto found;
- }
- } else {
- gf_uuid_generate (gfid);
- loc.inode = inode_new (parent->table);
- if (!loc.inode) {
- errno = ENOMEM;
- goto out;
- }
+ if (!loc.name)
+ loc.name = component;
- xattr_req = dict_new ();
- if (!xattr_req) {
- errno = ENOMEM;
- goto out;
- }
+ if (loc.inode) {
+ gf_uuid_copy(loc.gfid, loc.inode->gfid);
+ reval = 1;
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- errno = ENOMEM;
- goto out;
- }
+ if (!(force_lookup || inode_needs_lookup(loc.inode, THIS))) {
+ inode = inode_ref(loc.inode);
+ goto found;
+ }
+ } else {
+ gf_uuid_generate(gfid);
+ loc.inode = inode_new(parent->table);
+ if (!loc.inode) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ glret = priv_glfs_loc_touchup(&loc);
+ if (glret < 0) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = syncop_lookup(subvol, &loc, &ciatt, NULL, xattr_req, NULL);
+ if (ret && reval) {
+ /*
+ * A stale mapping might exist for a dentry/inode that has been
+ * removed from another client.
+ */
+ if (-ret == ENOENT) {
+ inode_unlink(loc.inode, loc.parent, loc.name);
+ if (!inode_has_dentry(loc.inode))
+ inode_forget(loc.inode, 0);
+ }
+
+ inode_unref(loc.inode);
+ gf_uuid_clear(loc.gfid);
+ loc.inode = inode_new(parent->table);
+ if (!loc.inode) {
+ errno = ENOMEM;
+ goto out;
+ }
- }
-
- glret = priv_glfs_loc_touchup (&loc);
- if (glret < 0) {
- ret = -1;
- goto out;
- }
-
- ret = syncop_lookup (subvol, &loc, &ciatt, NULL, xattr_req, NULL);
- if (ret && reval) {
- /*
- * A stale mapping might exist for a dentry/inode that has been
- * removed from another client.
- */
- if (-ret == ENOENT)
- inode_unlink(loc.inode, loc.parent,
- loc.name);
- inode_unref (loc.inode);
- loc.inode = inode_new (parent->table);
- if (!loc.inode) {
- errno = ENOMEM;
- goto out;
- }
-
- xattr_req = dict_new ();
- if (!xattr_req) {
- errno = ENOMEM;
- goto out;
- }
-
- gf_uuid_generate (gfid);
-
- ret = dict_set_static_bin (xattr_req, "gfid-req", gfid, 16);
- if (ret) {
- errno = ENOMEM;
- goto out;
- }
-
- ret = syncop_lookup (subvol, &loc, &ciatt, NULL,
- xattr_req, NULL);
- }
- DECODE_SYNCOP_ERR (ret);
- if (ret)
- goto out;
-
- inode = inode_link (loc.inode, loc.parent, component, &ciatt);
+ xattr_req = dict_new();
+ if (!xattr_req) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ gf_uuid_generate(gfid);
+
+ ret = dict_set_gfuuid(xattr_req, "gfid-req", gfid, true);
+ if (ret) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = syncop_lookup(subvol, &loc, &ciatt, NULL, xattr_req, NULL);
+ }
+ DECODE_SYNCOP_ERR(ret);
+ if (ret)
+ goto out;
+
+ inode = inode_link(loc.inode, loc.parent, component, &ciatt);
+
+ if (!inode) {
+ gf_smsg(subvol->name, GF_LOG_WARNING, errno, API_MSG_INODE_LINK_FAILED,
+ "gfid=%s", uuid_utoa((unsigned char *)&ciatt.ia_gfid), NULL);
+ goto out;
+ } else if (inode == loc.inode)
+ inode_ctx_set(inode, THIS, &ctx_value);
found:
- if (inode)
- inode_lookup (inode);
- if (iatt)
- *iatt = ciatt;
+ if (inode) {
+ ciatt.ia_type = inode->ia_type;
+ inode_lookup(inode);
+ }
+ if (iatt)
+ *iatt = ciatt;
out:
- if (xattr_req)
- dict_unref (xattr_req);
+ if (xattr_req)
+ dict_unref(xattr_req);
+ loc_wipe(&loc);
- loc_wipe (&loc);
-
- return inode;
+ return inode;
}
-
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve_at, 3.4.0)
int
-priv_glfs_resolve_at (struct glfs *fs, xlator_t *subvol, inode_t *at,
- const char *origpath, loc_t *loc, struct iatt *iatt,
- int follow, int reval)
+priv_glfs_resolve_at(struct glfs *fs, xlator_t *subvol, inode_t *at,
+ const char *origpath, loc_t *loc, struct iatt *iatt,
+ int follow, int reval)
{
- inode_t *inode = NULL;
- inode_t *parent = NULL;
- char *saveptr = NULL;
- char *path = NULL;
- char *component = NULL;
- char *next_component = NULL;
- int ret = -1;
- struct iatt ciatt = {0, };
-
- path = gf_strdup (origpath);
- if (!path) {
- errno = ENOMEM;
- return -1;
- }
-
- parent = NULL;
- if (at && path[0] != '/') {
- /* A relative resolution of a path which starts with '/'
- is equal to an absolute path resolution.
- */
- inode = inode_ref (at);
- } else {
- inode = inode_ref (subvol->itable->root);
-
- if (strcmp (path, "/") == 0)
- glfs_resolve_base (fs, subvol, inode, &ciatt);
- }
-
- for (component = strtok_r (path, "/", &saveptr);
- component; component = next_component) {
-
- next_component = strtok_r (NULL, "/", &saveptr);
-
- if (parent)
- inode_unref (parent);
-
- parent = inode;
-
- inode = glfs_resolve_component (fs, subvol, parent,
- component, &ciatt,
- /* force hard lookup on the last
- component, as the caller
- wants proper iatt filled
- */
- (reval || (!next_component &&
- iatt)));
- if (!inode) {
- ret = -1;
- break;
- }
+ inode_t *inode = NULL;
+ inode_t *parent = NULL;
+ char *saveptr = NULL;
+ char *path = NULL;
+ char *component = NULL;
+ char *next_component = NULL;
+ int ret = -1;
+ struct iatt ciatt = {
+ 0,
+ };
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ if (origpath[0] == '\0') {
+ errno = EINVAL;
+ goto invalid_fs;
+ }
+
+ parent = NULL;
+ if (at && origpath[0] != '/') {
+ /* A relative resolution of a path which starts with '/'
+ is equal to an absolute path resolution.
+ */
+ inode = inode_ref(at);
+ } else {
+ inode = inode_ref(subvol->itable->root);
+
+ if (strcmp(origpath, "/") == 0)
+ glfs_resolve_root(fs, subvol, inode, &ciatt);
+ }
+
+ path = gf_strdup(origpath);
+ if (!path)
+ goto invalid_fs;
+
+ for (component = strtok_r(path, "/", &saveptr); component;
+ component = next_component) {
+ next_component = strtok_r(NULL, "/", &saveptr);
+
+ if (parent)
+ inode_unref(parent);
+ parent = inode;
+ inode = glfs_resolve_component(fs, subvol, parent, component, &ciatt,
+ /* force hard lookup on the last
+ component, as the caller
+ wants proper iatt filled
+ */
+ (reval || (!next_component && iatt)));
+ if (!inode) {
+ ret = -1;
+ break;
+ }
- if (IA_ISLNK (ciatt.ia_type) && (next_component || follow)) {
- /* If the component is not the last piece,
- then following it is necessary even if
- not requested by the caller
- */
- char *lpath = NULL;
- loc_t sym_loc = {0,};
-
- if (follow > GLFS_SYMLINK_MAX_FOLLOW) {
- errno = ELOOP;
- ret = -1;
- if (inode) {
- inode_unref (inode);
- inode = NULL;
- }
- break;
- }
-
- ret = glfs_resolve_symlink (fs, subvol, inode, &lpath);
- inode_unref (inode);
- inode = NULL;
- if (ret < 0)
- break;
-
- ret = priv_glfs_resolve_at (fs, subvol, parent, lpath,
- &sym_loc,
- /* followed iatt becomes the
- component iatt
- */
- &ciatt,
- /* always recurisvely follow while
- following symlink
- */
- follow + 1, reval);
- if (ret == 0)
- inode = inode_ref (sym_loc.inode);
- loc_wipe (&sym_loc);
- GF_FREE (lpath);
- }
-
- if (!next_component)
- break;
-
- if (!IA_ISDIR (ciatt.ia_type)) {
- /* next_component exists and this component is
- not a directory
- */
- inode_unref (inode);
- inode = NULL;
- ret = -1;
- errno = ENOTDIR;
- break;
- }
- }
-
- if (parent && next_component)
- /* resolution failed mid-way */
- goto out;
-
- /* At this point, all components up to the last parent directory
- have been resolved successfully (@parent). Resolution of basename
- might have failed (@inode) if at all.
- */
-
- loc->parent = parent;
- if (parent) {
- gf_uuid_copy (loc->pargfid, parent->gfid);
- loc->name = component;
- }
-
- loc->inode = inode;
- if (inode) {
- gf_uuid_copy (loc->gfid, inode->gfid);
- if (iatt)
- *iatt = ciatt;
- ret = 0;
- }
-
- if (priv_glfs_loc_touchup (loc) < 0) {
+ if (IA_ISLNK(ciatt.ia_type) && (next_component || follow)) {
+ /* If the component is not the last piece,
+ then following it is necessary even if
+ not requested by the caller
+ */
+ char *lpath = NULL;
+ loc_t sym_loc = {
+ 0,
+ };
+
+ if (follow > GLFS_SYMLINK_MAX_FOLLOW) {
+ errno = ELOOP;
ret = -1;
+ if (inode) {
+ inode_unref(inode);
+ inode = NULL;
+ }
+ break;
+ }
+
+ ret = glfs_resolve_symlink(fs, subvol, inode, &lpath);
+ inode_unref(inode);
+ inode = NULL;
+ if (ret < 0)
+ break;
+
+ ret = priv_glfs_resolve_at(fs, subvol, parent, lpath, &sym_loc,
+ /* followed iatt becomes the
+ component iatt
+ */
+ &ciatt,
+ /* always recurisvely follow while
+ following symlink
+ */
+ follow + 1, reval);
+ if (ret == 0)
+ inode = inode_ref(sym_loc.inode);
+ loc_wipe(&sym_loc);
+ GF_FREE(lpath);
}
-out:
- GF_FREE (path);
- /* do NOT loc_wipe here as only last component might be missing */
+ if (!next_component)
+ break;
+
+ if (!IA_ISDIR(ciatt.ia_type)) {
+ /* next_component exists and this component is
+ not a directory
+ */
+ inode_unref(inode);
+ inode = NULL;
+ ret = -1;
+ errno = ENOTDIR;
+ break;
+ }
+ }
+
+ if (parent && next_component)
+ /* resolution failed mid-way */
+ goto out;
+
+ /* At this point, all components up to the last parent directory
+ have been resolved successfully (@parent). Resolution of basename
+ might have failed (@inode) if at all.
+ */
+
+ loc->parent = parent;
+ if (parent) {
+ gf_uuid_copy(loc->pargfid, parent->gfid);
+ loc->name = component;
+ }
+
+ loc->inode = inode;
+ if (inode) {
+ gf_uuid_copy(loc->gfid, inode->gfid);
+ if (iatt)
+ *iatt = ciatt;
+ ret = 0;
+ }
+
+ if (priv_glfs_loc_touchup(loc) < 0) {
+ ret = -1;
+ }
+out:
+ GF_FREE(path);
+ __GLFS_EXIT_FS;
- return ret;
+ /* do NOT loc_wipe here as only last component might be missing */
+invalid_fs:
+ return ret;
}
-GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve_at, 3.4.0);
-
-
int
-glfs_resolve_path (struct glfs *fs, xlator_t *subvol, const char *origpath,
- loc_t *loc, struct iatt *iatt, int follow, int reval)
+glfs_resolve_path(struct glfs *fs, xlator_t *subvol, const char *origpath,
+ loc_t *loc, struct iatt *iatt, int follow, int reval)
{
- int ret = -1;
- inode_t *cwd = NULL;
-
- if (origpath[0] == '/')
- return priv_glfs_resolve_at (fs, subvol, NULL, origpath, loc,
- iatt, follow, reval);
-
- cwd = glfs_cwd_get (fs);
- if (NULL == cwd) {
- gf_msg (subvol->name, GF_LOG_WARNING, EIO,
- API_MSG_GET_CWD_FAILED, "Failed to get cwd");
- errno = EIO;
- goto out;
- }
+ int ret = -1;
+ inode_t *cwd = NULL;
- ret = priv_glfs_resolve_at (fs, subvol, cwd, origpath, loc, iatt,
+ if (origpath[0] == '/')
+ return priv_glfs_resolve_at(fs, subvol, NULL, origpath, loc, iatt,
follow, reval);
- if (cwd)
- inode_unref (cwd);
+
+ cwd = glfs_cwd_get(fs);
+ if (NULL == cwd) {
+ gf_smsg(subvol->name, GF_LOG_WARNING, EIO, API_MSG_GET_CWD_FAILED,
+ NULL);
+ errno = EIO;
+ goto out;
+ }
+
+ ret = priv_glfs_resolve_at(fs, subvol, cwd, origpath, loc, iatt, follow,
+ reval);
+ if (cwd)
+ inode_unref(cwd);
out:
- return ret;
+ return ret;
}
-
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve, 3.7.0)
int
-priv_glfs_resolve (struct glfs *fs, xlator_t *subvol, const char *origpath,
- loc_t *loc, struct iatt *iatt, int reval)
+priv_glfs_resolve(struct glfs *fs, xlator_t *subvol, const char *origpath,
+ loc_t *loc, struct iatt *iatt, int reval)
{
- int ret = -1;
+ int ret = -1;
- ret = glfs_resolve_path (fs, subvol, origpath, loc, iatt, 1, reval);
+ ret = glfs_resolve_path(fs, subvol, origpath, loc, iatt, 1, reval);
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_resolve, 3.7.0);
int
-glfs_lresolve (struct glfs *fs, xlator_t *subvol, const char *origpath,
- loc_t *loc, struct iatt *iatt, int reval)
+glfs_lresolve(struct glfs *fs, xlator_t *subvol, const char *origpath,
+ loc_t *loc, struct iatt *iatt, int reval)
{
- int ret = -1;
+ int ret = -1;
- ret = glfs_resolve_path (fs, subvol, origpath, loc, iatt, 0, reval);
+ ret = glfs_resolve_path(fs, subvol, origpath, loc, iatt, 0, reval);
- return ret;
+ return ret;
}
-
int
-glfs_migrate_fd_locks_safe (struct glfs *fs, xlator_t *oldsubvol, fd_t *oldfd,
- xlator_t *newsubvol, fd_t *newfd)
+glfs_migrate_fd_locks_safe(struct glfs *fs, xlator_t *oldsubvol, fd_t *oldfd,
+ xlator_t *newsubvol, fd_t *newfd)
{
- dict_t *lockinfo = NULL;
- int ret = 0;
- char uuid1[64];
-
- if (!oldfd->lk_ctx || fd_lk_ctx_empty (oldfd->lk_ctx))
- return 0;
-
- newfd->lk_ctx = fd_lk_ctx_ref (oldfd->lk_ctx);
-
- ret = syncop_fgetxattr (oldsubvol, oldfd, &lockinfo,
- GF_XATTR_LOCKINFO_KEY, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret < 0) {
- gf_msg (fs->volname, GF_LOG_WARNING, errno,
- API_MSG_FGETXATTR_FAILED,
- "fgetxattr (%s) failed (%s) on graph %s (%d)",
- uuid_utoa_r (oldfd->inode->gfid, uuid1),
- strerror (errno),
- graphid_str (oldsubvol), oldsubvol->graph->id);
- goto out;
- }
-
- if (!dict_get (lockinfo, GF_XATTR_LOCKINFO_KEY)) {
- gf_msg (fs->volname, GF_LOG_WARNING, 0,
- API_MSG_LOCKINFO_KEY_MISSING,
- "missing lockinfo key (%s) on graph %s (%d)",
- uuid_utoa_r (oldfd->inode->gfid, uuid1),
- graphid_str (oldsubvol), oldsubvol->graph->id);
- goto out;
- }
-
- ret = syncop_fsetxattr (newsubvol, newfd, lockinfo, 0, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret < 0) {
- gf_msg (fs->volname, GF_LOG_WARNING, 0,
- API_MSG_FSETXATTR_FAILED,
- "fsetxattr (%s) failed (%s) on graph %s (%d)",
- uuid_utoa_r (newfd->inode->gfid, uuid1),
- strerror (errno),
- graphid_str (newsubvol), newsubvol->graph->id);
- goto out;
- }
+ dict_t *lockinfo = NULL;
+ int ret = 0;
+ char uuid1[64];
+
+ if (!oldfd->lk_ctx || fd_lk_ctx_empty(oldfd->lk_ctx))
+ return 0;
+
+ newfd->lk_ctx = fd_lk_ctx_ref(oldfd->lk_ctx);
+
+ ret = syncop_fgetxattr(oldsubvol, oldfd, &lockinfo, GF_XATTR_LOCKINFO_KEY,
+ NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret < 0) {
+ gf_smsg(fs->volname, GF_LOG_WARNING, errno, API_MSG_FGETXATTR_FAILED,
+ "gfid=%s", uuid_utoa_r(oldfd->inode->gfid, uuid1), "err=%s",
+ strerror(errno), "subvol=%s", graphid_str(oldsubvol), "id=%d",
+ oldsubvol->graph->id, NULL);
+ goto out;
+ }
+
+ if (!dict_get(lockinfo, GF_XATTR_LOCKINFO_KEY)) {
+ gf_smsg(fs->volname, GF_LOG_WARNING, 0, API_MSG_LOCKINFO_KEY_MISSING,
+ "gfid=%s", uuid_utoa_r(oldfd->inode->gfid, uuid1), "subvol=%s",
+ graphid_str(oldsubvol), "id=%d", oldsubvol->graph->id, NULL);
+ goto out;
+ }
+
+ ret = syncop_fsetxattr(newsubvol, newfd, lockinfo, 0, NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret < 0) {
+ gf_smsg(fs->volname, GF_LOG_WARNING, 0, API_MSG_FSETXATTR_FAILED,
+ "gfid=%s", uuid_utoa_r(newfd->inode->gfid, uuid1), "err=%s",
+ strerror(errno), "subvol=%s", graphid_str(newsubvol), "id=%d",
+ newsubvol->graph->id, NULL);
+ goto out;
+ }
out:
- if (lockinfo)
- dict_unref (lockinfo);
- return ret;
+ if (lockinfo)
+ dict_unref(lockinfo);
+ return ret;
}
-
fd_t *
-glfs_migrate_fd_safe (struct glfs *fs, xlator_t *newsubvol, fd_t *oldfd)
+glfs_migrate_fd_safe(struct glfs *fs, xlator_t *newsubvol, fd_t *oldfd)
{
- fd_t *newfd = NULL;
- inode_t *oldinode = NULL;
- inode_t *newinode = NULL;
- xlator_t *oldsubvol = NULL;
- int ret = -1;
- loc_t loc = {0, };
- char uuid1[64];
-
-
- oldinode = oldfd->inode;
- oldsubvol = oldinode->table->xl;
-
- if (oldsubvol == newsubvol)
- return fd_ref (oldfd);
-
- if (!oldsubvol->switched) {
- ret = syncop_fsync (oldsubvol, oldfd, 0, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- if (ret) {
- gf_msg (fs->volname, GF_LOG_WARNING, errno,
- API_MSG_FSYNC_FAILED, "fsync() failed "
- "(%s) on %s graph %s (%d)", strerror (errno),
- uuid_utoa_r (oldfd->inode->gfid, uuid1),
- graphid_str (oldsubvol), oldsubvol->graph->id);
- }
- }
-
- newinode = glfs_refresh_inode_safe (newsubvol, oldinode, _gf_false);
- if (!newinode) {
- gf_msg (fs->volname, GF_LOG_WARNING, errno,
- API_MSG_INODE_REFRESH_FAILED,
- "inode (%s) refresh failed (%s) on graph %s (%d)",
- uuid_utoa_r (oldinode->gfid, uuid1),
- strerror (errno),
- graphid_str (newsubvol), newsubvol->graph->id);
- goto out;
- }
-
- newfd = fd_create (newinode, getpid());
- if (!newfd) {
- gf_msg (fs->volname, GF_LOG_WARNING, errno,
- API_MSG_FDCREATE_FAILED,
- "fd_create (%s) failed (%s) on graph %s (%d)",
- uuid_utoa_r (newinode->gfid, uuid1),
- strerror (errno),
- graphid_str (newsubvol), newsubvol->graph->id);
- goto out;
- }
-
- loc.inode = inode_ref (newinode);
-
- ret = inode_path (oldfd->inode, NULL, (char **)&loc.path);
- if (ret < 0) {
- gf_msg (fs->volname, GF_LOG_INFO, 0, API_MSG_INODE_PATH_FAILED,
- "inode_path failed");
- goto out;
+ fd_t *newfd = NULL;
+ inode_t *oldinode = NULL;
+ inode_t *newinode = NULL;
+ xlator_t *oldsubvol = NULL;
+ int ret = -1;
+ loc_t loc = {
+ 0,
+ };
+ char uuid1[64];
+ dict_t *xdata = NULL;
+
+ oldinode = oldfd->inode;
+ oldsubvol = oldinode->table->xl;
+
+ if (oldsubvol == newsubvol)
+ return fd_ref(oldfd);
+
+ if (!oldsubvol->switched) {
+ xdata = dict_new();
+ if (!xdata || dict_set_int8(xdata, "last-fsync", 1)) {
+ gf_smsg(fs->volname, GF_LOG_WARNING, ENOMEM, API_MSG_FSYNC_FAILED,
+ "err=%s", "last-fsync set failed", "gfid=%s",
+ uuid_utoa_r(oldfd->inode->gfid, uuid1), "subvol=%s",
+ graphid_str(oldsubvol), "id=%d", oldsubvol->graph->id,
+ NULL);
}
- gf_uuid_copy (loc.gfid, oldinode->gfid);
-
-
- if (IA_ISDIR (oldinode->ia_type))
- ret = syncop_opendir (newsubvol, &loc, newfd, NULL, NULL);
- else
- ret = syncop_open (newsubvol, &loc,
- oldfd->flags & ~(O_TRUNC|O_EXCL|O_CREAT),
- newfd, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
- loc_wipe (&loc);
-
- if (ret) {
- gf_msg (fs->volname, GF_LOG_WARNING, errno,
- API_MSG_SYNCOP_OPEN_FAILED,
- "syncop_open%s (%s) failed (%s) on graph %s (%d)",
- IA_ISDIR (oldinode->ia_type) ? "dir" : "",
- uuid_utoa_r (newinode->gfid, uuid1),
- strerror (errno),
- graphid_str (newsubvol), newsubvol->graph->id);
- goto out;
- }
-
- ret = glfs_migrate_fd_locks_safe (fs, oldsubvol, oldfd, newsubvol,
- newfd);
-
- if (ret) {
- gf_msg (fs->volname, GF_LOG_WARNING, errno,
- API_MSG_LOCK_MIGRATE_FAILED,
- "lock migration (%s) failed (%s) on graph %s (%d)",
- uuid_utoa_r (newinode->gfid, uuid1),
- strerror (errno),
- graphid_str (newsubvol), newsubvol->graph->id);
- goto out;
- }
-
- newfd->flags = oldfd->flags;
- fd_bind (newfd);
+ ret = syncop_fsync(oldsubvol, oldfd, 0, NULL, NULL, xdata, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ if (ret) {
+ gf_smsg(fs->volname, GF_LOG_WARNING, errno, API_MSG_FSYNC_FAILED,
+ "err=%s", strerror(errno), "gfid=%s",
+ uuid_utoa_r(oldfd->inode->gfid, uuid1), "subvol=%s",
+ graphid_str(oldsubvol), "id=%d", oldsubvol->graph->id,
+ NULL);
+ }
+ }
+
+ newinode = glfs_refresh_inode_safe(newsubvol, oldinode, _gf_false);
+ if (!newinode) {
+ gf_smsg(fs->volname, GF_LOG_WARNING, errno,
+ API_MSG_INODE_REFRESH_FAILED, "gfid=%s",
+ uuid_utoa_r(oldinode->gfid, uuid1), "err=%s", strerror(errno),
+ "subvol=%s", graphid_str(newsubvol), "id=%d",
+ newsubvol->graph->id, NULL);
+ goto out;
+ }
+
+ newfd = fd_create(newinode, getpid());
+ if (!newfd) {
+ gf_smsg(fs->volname, GF_LOG_WARNING, errno,
+ API_MSG_FDCREATE_FAILED_ON_GRAPH, "gfid=%s",
+ uuid_utoa_r(newinode->gfid, uuid1), "err=%s", strerror(errno),
+ "subvol=%s", graphid_str(newsubvol), "id=%d",
+ newsubvol->graph->id, NULL);
+ goto out;
+ }
+
+ loc.inode = inode_ref(newinode);
+
+ ret = inode_path(oldfd->inode, NULL, (char **)&loc.path);
+ if (ret < 0) {
+ gf_smsg(fs->volname, GF_LOG_INFO, 0, API_MSG_INODE_PATH_FAILED, NULL);
+ goto out;
+ }
+
+ gf_uuid_copy(loc.gfid, oldinode->gfid);
+
+ if (IA_ISDIR(oldinode->ia_type))
+ ret = syncop_opendir(newsubvol, &loc, newfd, NULL, NULL);
+ else
+ ret = syncop_open(newsubvol, &loc,
+ oldfd->flags & ~(O_TRUNC | O_EXCL | O_CREAT), newfd,
+ NULL, NULL);
+ DECODE_SYNCOP_ERR(ret);
+ loc_wipe(&loc);
+
+ if (ret) {
+ gf_smsg(fs->volname, GF_LOG_WARNING, errno, API_MSG_SYNCOP_OPEN_FAILED,
+ "type=%s", IA_ISDIR(oldinode->ia_type) ? "dir" : "", "gfid=%s",
+ uuid_utoa_r(newinode->gfid, uuid1), "err=%s", strerror(errno),
+ "subvol=%s", graphid_str(newsubvol), "id=%d",
+ newsubvol->graph->id, NULL);
+ goto out;
+ }
+
+ ret = glfs_migrate_fd_locks_safe(fs, oldsubvol, oldfd, newsubvol, newfd);
+
+ if (ret) {
+ gf_smsg(fs->volname, GF_LOG_WARNING, errno, API_MSG_LOCK_MIGRATE_FAILED,
+ "gfid=%s", uuid_utoa_r(newinode->gfid, uuid1), "err=%s",
+ strerror(errno), "subvol=%s", graphid_str(newsubvol), "id=%d",
+ newsubvol->graph->id, NULL);
+ goto out;
+ }
+
+ newfd->flags = oldfd->flags;
+ fd_bind(newfd);
out:
- if (newinode)
- inode_unref (newinode);
+ if (newinode)
+ inode_unref(newinode);
- if (ret) {
- fd_unref (newfd);
- newfd = NULL;
- }
+ if (ret) {
+ fd_unref(newfd);
+ newfd = NULL;
+ }
- return newfd;
-}
+ if (xdata)
+ dict_unref(xdata);
+ return newfd;
+}
fd_t *
-__glfs_migrate_fd (struct glfs *fs, xlator_t *newsubvol, struct glfs_fd *glfd)
+__glfs_migrate_fd(struct glfs *fs, xlator_t *newsubvol, struct glfs_fd *glfd)
{
- fd_t *oldfd = NULL;
- fd_t *newfd = NULL;
+ fd_t *oldfd = NULL;
+ fd_t *newfd = NULL;
- oldfd = glfd->fd;
+ oldfd = glfd->fd;
- fs->migration_in_progress = 1;
- pthread_mutex_unlock (&fs->mutex);
- {
- newfd = glfs_migrate_fd_safe (fs, newsubvol, oldfd);
- }
- pthread_mutex_lock (&fs->mutex);
- fs->migration_in_progress = 0;
- pthread_cond_broadcast (&fs->cond);
+ fs->migration_in_progress = 1;
+ pthread_mutex_unlock(&fs->mutex);
+ {
+ newfd = glfs_migrate_fd_safe(fs, newsubvol, oldfd);
+ }
+ pthread_mutex_lock(&fs->mutex);
+ fs->migration_in_progress = 0;
+ pthread_cond_broadcast(&fs->cond);
- return newfd;
-}
+ /* wake up other waiting tasks */
+ __GLFS_SYNCTASK_WAKE(fs);
+ return newfd;
+}
fd_t *
-__glfs_resolve_fd (struct glfs *fs, xlator_t *subvol, struct glfs_fd *glfd)
+__glfs_resolve_fd(struct glfs *fs, xlator_t *subvol, struct glfs_fd *glfd)
{
- fd_t *fd = NULL;
+ fd_t *fd = NULL;
- if (glfd->fd->inode->table->xl == subvol)
- return fd_ref (glfd->fd);
+ if (glfd->fd->inode->table->xl == subvol)
+ return fd_ref(glfd->fd);
- fd = __glfs_migrate_fd (fs, subvol, glfd);
- if (!fd)
- return NULL;
+ fd = __glfs_migrate_fd(fs, subvol, glfd);
+ if (!fd)
+ return NULL;
- if (subvol == fs->active_subvol) {
- fd_unref (glfd->fd);
- glfd->fd = fd_ref (fd);
- }
+ if (subvol == fs->active_subvol) {
+ fd_unref(glfd->fd);
+ glfd->fd = fd_ref(fd);
+ }
- return fd;
+ return fd;
}
-
fd_t *
-glfs_resolve_fd (struct glfs *fs, xlator_t *subvol, struct glfs_fd *glfd)
+glfs_resolve_fd(struct glfs *fs, xlator_t *subvol, struct glfs_fd *glfd)
{
- fd_t *fd = NULL;
+ fd_t *fd = NULL;
- glfs_lock (fs);
- {
- fd = __glfs_resolve_fd (fs, subvol, glfd);
- }
- glfs_unlock (fs);
+ glfs_lock(fs, _gf_true);
+ {
+ fd = __glfs_resolve_fd(fs, subvol, glfd);
+ }
+ glfs_unlock(fs);
- return fd;
+ return fd;
}
-
void
-__glfs_migrate_openfds (struct glfs *fs, xlator_t *subvol)
+__glfs_migrate_openfds(struct glfs *fs, xlator_t *subvol)
{
- struct glfs_fd *glfd = NULL;
- fd_t *fd = NULL;
-
- list_for_each_entry (glfd, &fs->openfds, openfds) {
- if (gf_uuid_is_null (glfd->fd->inode->gfid)) {
- gf_msg (fs->volname, GF_LOG_INFO, 0,
- API_MSG_OPENFD_SKIPPED,
- "skipping openfd %p/%p in graph %s (%d)",
- glfd, glfd->fd, graphid_str(subvol),
- subvol->graph->id);
- /* create in progress, defer */
- continue;
- }
-
- fd = __glfs_migrate_fd (fs, subvol, glfd);
- if (fd) {
- fd_unref (glfd->fd);
- glfd->fd = fd;
- }
- }
-}
+ struct glfs_fd *glfd = NULL;
+ fd_t *fd = NULL;
+
+ list_for_each_entry(glfd, &fs->openfds, openfds)
+ {
+ if (gf_uuid_is_null(glfd->fd->inode->gfid)) {
+ gf_smsg(fs->volname, GF_LOG_INFO, 0, API_MSG_OPENFD_SKIPPED,
+ "glfd=%p", glfd, "glfd->fd=%p", glfd->fd, "subvol=%s",
+ graphid_str(subvol), "id=%d", subvol->graph->id, NULL);
+ /* create in progress, defer */
+ continue;
+ }
+ fd = __glfs_migrate_fd(fs, subvol, glfd);
+ if (fd) {
+ fd_unref(glfd->fd);
+ glfd->fd = fd;
+ }
+ }
+}
+/* Note that though it appears that this function executes under fs->mutex,
+ * it is not fully executed under fs->mutex. i.e. there are functions like
+ * __glfs_first_lookup, __glfs_refresh_inode, __glfs_migrate_openfds which
+ * unlocks fs->mutex before sending any network fop, and reacquire fs->mutex
+ * once the fop is complete. Hence the variable read from fs at the start of the
+ * function need not have the same value by the end of the function.
+ */
xlator_t *
-__glfs_active_subvol (struct glfs *fs)
+__glfs_active_subvol(struct glfs *fs)
{
- xlator_t *new_subvol = NULL;
- int ret = -1;
- inode_t *new_cwd = NULL;
-
- if (!fs->next_subvol)
- return fs->active_subvol;
-
- new_subvol = fs->next_subvol;
-
- ret = __glfs_first_lookup (fs, new_subvol);
- if (ret) {
- gf_msg (fs->volname, GF_LOG_INFO, errno,
- API_MSG_FIRST_LOOKUP_GRAPH_FAILED,
- "first lookup on graph %s (%d) failed (%s)",
- graphid_str (new_subvol), new_subvol->graph->id,
- strerror (errno));
- return NULL;
- }
-
- if (fs->cwd) {
- new_cwd = __glfs_refresh_inode (fs, new_subvol, fs->cwd,
- _gf_false);
-
- if (!new_cwd) {
- char buf1[64];
- gf_msg (fs->volname, GF_LOG_INFO, errno,
- API_MSG_CWD_GRAPH_REF_FAILED,
- "cwd refresh of %s graph %s (%d) failed (%s)",
- uuid_utoa_r (fs->cwd->gfid, buf1),
- graphid_str (new_subvol),
- new_subvol->graph->id, strerror (errno));
- return NULL;
- }
- }
-
- __glfs_migrate_openfds (fs, new_subvol);
-
- /* switching @active_subvol and @cwd
- should be atomic
- */
- fs->old_subvol = fs->active_subvol;
- fs->active_subvol = fs->next_subvol;
- fs->next_subvol = NULL;
-
- if (new_cwd) {
- __glfs_cwd_set (fs, new_cwd);
- inode_unref (new_cwd);
- }
-
- gf_msg (fs->volname, GF_LOG_INFO, 0, API_MSG_SWITCHED_GRAPH,
- "switched to graph %s (%d)",
- graphid_str (new_subvol), new_subvol->graph->id);
-
- return new_subvol;
-}
+ xlator_t *new_subvol = NULL;
+ int ret = -1;
+ inode_t *new_cwd = NULL;
+
+ if (!fs->next_subvol)
+ return fs->active_subvol;
+
+ new_subvol = fs->mip_subvol = fs->next_subvol;
+ fs->next_subvol = NULL;
+
+ ret = __glfs_first_lookup(fs, new_subvol);
+ if (ret) {
+ gf_smsg(fs->volname, GF_LOG_INFO, errno,
+ API_MSG_FIRST_LOOKUP_GRAPH_FAILED, "subvol=%s",
+ graphid_str(new_subvol), "id=%d", new_subvol->graph->id,
+ "err=%s", strerror(errno), NULL);
+ return NULL;
+ }
+
+ if (fs->cwd) {
+ new_cwd = __glfs_refresh_inode(fs, new_subvol, fs->cwd, _gf_false);
+
+ if (!new_cwd) {
+ char buf1[64];
+ gf_smsg(fs->volname, GF_LOG_INFO, errno,
+ API_MSG_CWD_GRAPH_REF_FAILED, "buf=%s",
+ uuid_utoa_r(fs->cwd->gfid, buf1), "subvol=%s",
+ graphid_str(new_subvol), "id=%d", new_subvol->graph->id,
+ "err=%s", strerror(errno), NULL);
+ return NULL;
+ }
+ }
+
+ __glfs_migrate_openfds(fs, new_subvol);
+ /* TODO: Migrate the fds and inodes which have leases to the new graph
+ * (issue #350)*/
+ /* switching @active_subvol and @cwd
+ should be atomic
+ */
+ fs->old_subvol = fs->active_subvol;
+ fs->active_subvol = fs->mip_subvol;
+ fs->mip_subvol = NULL;
+ if (new_cwd) {
+ __glfs_cwd_set(fs, new_cwd);
+ inode_unref(new_cwd);
+ }
+
+ gf_smsg(fs->volname, GF_LOG_INFO, 0, API_MSG_SWITCHED_GRAPH, "subvol=%s",
+ graphid_str(new_subvol), "id=%d", new_subvol->graph->id, NULL);
+
+ return new_subvol;
+}
+
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_subvol_done, 3.4.0)
void
-priv_glfs_subvol_done (struct glfs *fs, xlator_t *subvol)
+priv_glfs_subvol_done(struct glfs *fs, xlator_t *subvol)
{
- int ref = 0;
- xlator_t *active_subvol = NULL;
-
- if (!subvol)
- return;
-
- glfs_lock (fs);
- {
- ref = (--subvol->winds);
- active_subvol = fs->active_subvol;
- }
- glfs_unlock (fs);
-
- if (ref == 0) {
- assert (subvol != active_subvol);
- xlator_notify (subvol, GF_EVENT_PARENT_DOWN, subvol, NULL);
- }
+ int ref = 0;
+ xlator_t *active_subvol = NULL;
+
+ if (!subvol)
+ return;
+
+ /* For decrementing subvol->wind ref count we need not check/wait for
+ * migration-in-progress flag.
+ * Also glfs_subvol_done is called in call-back path therefore waiting
+ * for migration-in-progress flag can lead to dead-lock.
+ */
+ glfs_lock(fs, _gf_false);
+ {
+ ref = (--subvol->winds);
+ active_subvol = fs->active_subvol;
+ }
+ glfs_unlock(fs);
+
+ if (ref == 0) {
+ assert(subvol != active_subvol);
+ xlator_notify(subvol, GF_EVENT_PARENT_DOWN, subvol, NULL);
+ }
}
-GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_subvol_done, 3.4.0);
-
-
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_active_subvol, 3.4.0)
xlator_t *
-priv_glfs_active_subvol (struct glfs *fs)
+priv_glfs_active_subvol(struct glfs *fs)
{
- xlator_t *subvol = NULL;
- xlator_t *old_subvol = NULL;
+ xlator_t *subvol = NULL;
+ xlator_t *old_subvol = NULL;
- glfs_lock (fs);
- {
- subvol = __glfs_active_subvol (fs);
+ glfs_lock(fs, _gf_true);
+ {
+ subvol = __glfs_active_subvol(fs);
- if (subvol)
- subvol->winds++;
+ if (subvol)
+ subvol->winds++;
- if (fs->old_subvol) {
- old_subvol = fs->old_subvol;
- fs->old_subvol = NULL;
- old_subvol->switched = 1;
- }
- }
- glfs_unlock (fs);
+ if (fs->old_subvol) {
+ old_subvol = fs->old_subvol;
+ fs->old_subvol = NULL;
+ old_subvol->switched = 1;
+ }
+ }
+ glfs_unlock(fs);
- if (old_subvol)
- priv_glfs_subvol_done (fs, old_subvol);
+ if (old_subvol)
+ priv_glfs_subvol_done(fs, old_subvol);
- return subvol;
+ return subvol;
}
-GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_active_subvol, 3.4.0);
-
int
-__glfs_cwd_set (struct glfs *fs, inode_t *inode)
+__glfs_cwd_set(struct glfs *fs, inode_t *inode)
{
- if (inode->table->xl != fs->active_subvol) {
- inode = __glfs_refresh_inode (fs, fs->active_subvol, inode,
- _gf_false);
- if (!inode)
- return -1;
- } else {
- inode_ref (inode);
- }
+ if (inode->table->xl != fs->active_subvol) {
+ inode = __glfs_refresh_inode(fs, fs->active_subvol, inode, _gf_false);
+ if (!inode)
+ return -1;
+ } else {
+ inode_ref(inode);
+ }
- if (fs->cwd)
- inode_unref (fs->cwd);
+ if (fs->cwd)
+ inode_unref(fs->cwd);
- fs->cwd = inode;
+ fs->cwd = inode;
- return 0;
+ return 0;
}
-
int
-glfs_cwd_set (struct glfs *fs, inode_t *inode)
+glfs_cwd_set(struct glfs *fs, inode_t *inode)
{
- int ret = 0;
+ int ret = 0;
- glfs_lock (fs);
- {
- ret = __glfs_cwd_set (fs, inode);
- }
- glfs_unlock (fs);
+ glfs_lock(fs, _gf_true);
+ {
+ ret = __glfs_cwd_set(fs, inode);
+ }
+ glfs_unlock(fs);
- return ret;
+ return ret;
}
-
inode_t *
-__glfs_cwd_get (struct glfs *fs)
+__glfs_cwd_get(struct glfs *fs)
{
- inode_t *cwd = NULL;
+ inode_t *cwd = NULL;
- if (!fs->cwd)
- return NULL;
+ if (!fs->cwd)
+ return NULL;
- if (fs->cwd->table->xl == fs->active_subvol) {
- cwd = inode_ref (fs->cwd);
- return cwd;
- }
+ if (fs->cwd->table->xl == fs->active_subvol) {
+ cwd = inode_ref(fs->cwd);
+ return cwd;
+ }
- cwd = __glfs_refresh_inode (fs, fs->active_subvol, fs->cwd, _gf_false);
+ cwd = __glfs_refresh_inode(fs, fs->active_subvol, fs->cwd, _gf_false);
- return cwd;
+ return cwd;
}
inode_t *
-glfs_cwd_get (struct glfs *fs)
+glfs_cwd_get(struct glfs *fs)
{
- inode_t *cwd = NULL;
+ inode_t *cwd = NULL;
- glfs_lock (fs);
- {
- cwd = __glfs_cwd_get (fs);
- }
- glfs_unlock (fs);
+ glfs_lock(fs, _gf_true);
+ {
+ cwd = __glfs_cwd_get(fs);
+ }
+ glfs_unlock(fs);
- return cwd;
+ return cwd;
}
inode_t *
-__glfs_resolve_inode (struct glfs *fs, xlator_t *subvol,
- struct glfs_object *object)
+__glfs_resolve_inode(struct glfs *fs, xlator_t *subvol,
+ struct glfs_object *object)
{
- inode_t *inode = NULL;
- gf_boolean_t lookup_needed = _gf_false;
+ inode_t *inode = NULL;
+ gf_boolean_t lookup_needed = _gf_false;
- lookup_needed = inode_needs_lookup (object->inode, THIS);
+ lookup_needed = inode_needs_lookup(object->inode, THIS);
- if (!lookup_needed && object->inode->table->xl == subvol)
- return inode_ref (object->inode);
+ if (!lookup_needed && object->inode->table->xl == subvol)
+ return inode_ref(object->inode);
- inode = __glfs_refresh_inode (fs, fs->active_subvol,
- object->inode, lookup_needed);
- if (!inode)
- return NULL;
+ inode = __glfs_refresh_inode(fs, fs->active_subvol, object->inode,
+ lookup_needed);
+ if (!inode)
+ return NULL;
- if (subvol == fs->active_subvol) {
- inode_unref (object->inode);
- object->inode = inode_ref (inode);
- }
+ if (subvol == fs->active_subvol) {
+ inode_unref(object->inode);
+ object->inode = inode_ref(inode);
+ }
- return inode;
+ return inode;
}
inode_t *
-glfs_resolve_inode (struct glfs *fs, xlator_t *subvol,
- struct glfs_object *object)
+glfs_resolve_inode(struct glfs *fs, xlator_t *subvol,
+ struct glfs_object *object)
{
- inode_t *inode = NULL;
+ inode_t *inode = NULL;
- glfs_lock (fs);
- {
- inode = __glfs_resolve_inode(fs, subvol, object);
- }
- glfs_unlock (fs);
+ glfs_lock(fs, _gf_true);
+ {
+ inode = __glfs_resolve_inode(fs, subvol, object);
+ }
+ glfs_unlock(fs);
- return inode;
+ return inode;
}
int
-glfs_create_object (loc_t *loc, struct glfs_object **retobject)
+glfs_create_object(loc_t *loc, struct glfs_object **retobject)
{
- struct glfs_object *object = NULL;
+ struct glfs_object *object = NULL;
- object = GF_CALLOC (1, sizeof(struct glfs_object),
- glfs_mt_glfs_object_t);
- if (object == NULL) {
- errno = ENOMEM;
- return -1;
- }
+ object = GF_CALLOC(1, sizeof(struct glfs_object), glfs_mt_glfs_object_t);
+ if (object == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
- object->inode = loc->inode;
- gf_uuid_copy (object->gfid, object->inode->gfid);
+ object->inode = loc->inode;
+ gf_uuid_copy(object->gfid, object->inode->gfid);
- /* we hold the reference */
- loc->inode = NULL;
+ /* we hold the reference */
+ loc->inode = NULL;
- *retobject = object;
+ *retobject = object;
- return 0;
+ return 0;
}
struct glfs_object *
-glfs_h_resolve_symlink (struct glfs *fs, struct glfs_object *object)
+glfs_h_resolve_symlink(struct glfs *fs, struct glfs_object *object)
{
-
- xlator_t *subvol = NULL;
- loc_t sym_loc = {0,};
- struct iatt iatt = {0,};
- char *lpath = NULL;
- int ret = 0;
- struct glfs_object *target_object = NULL;
-
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
-
- ret = glfs_resolve_symlink (fs, subvol, object->inode, &lpath);
- if (ret < 0)
- goto out;
-
- ret = glfs_resolve_at (fs, subvol, NULL, lpath,
- &sym_loc, &iatt,
- /* always recurisvely follow while
- following symlink
- */
- 1, 0);
- if (ret == 0)
- ret = glfs_create_object (&sym_loc, &target_object);
+ xlator_t *subvol = NULL;
+ loc_t sym_loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ char *lpath = NULL;
+ int ret = 0;
+ struct glfs_object *target_object = NULL;
+
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
+
+ ret = glfs_resolve_symlink(fs, subvol, object->inode, &lpath);
+ if (ret < 0)
+ goto out;
+
+ ret = glfs_resolve_at(fs, subvol, NULL, lpath, &sym_loc, &iatt,
+ /* always recurisvely follow while
+ following symlink
+ */
+ 1, 0);
+ if (ret == 0)
+ ret = glfs_create_object(&sym_loc, &target_object);
out:
- loc_wipe (&sym_loc);
- GF_FREE (lpath);
- return target_object;
+ loc_wipe(&sym_loc);
+ GF_FREE(lpath);
+ return target_object;
}
diff --git a/api/src/glfs.c b/api/src/glfs.c
index 490dbde9c1e..b4bf1423f6d 100644
--- a/api/src/glfs.c
+++ b/api/src/glfs.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2012-2018 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
@@ -8,10 +8,8 @@
cases as published by the Free Software Foundation.
*/
-
/*
TODO:
- - merge locks in glfs_posix_lock for lock self-healing
- set proper pid/lk_owner to call frames (currently buried in syncop)
- fix logging.c/h to store logfp and loglevel in glusterfs_ctx_t and
reach it via THIS.
@@ -32,1195 +30,1777 @@
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
-
-#include "glusterfs.h"
-#include "logging.h"
-#include "stack.h"
-#include "event.h"
+#ifdef GF_LINUX_HOST_OS
+#include <sys/prctl.h>
+#endif
+
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/logging.h>
+#include <glusterfs/stack.h>
+#include <glusterfs/gf-event.h>
#include "glfs-mem-types.h"
-#include "common-utils.h"
-#include "syncop.h"
-#include "call-stub.h"
-#include "gfapi-messages.h"
+#include <glusterfs/common-utils.h>
+#include <glusterfs/syncop.h>
+#include <glusterfs/call-stub.h>
+#include <glusterfs/hashfn.h>
+#include "rpc-clnt.h"
+#include <glusterfs/statedump.h>
+#include <glusterfs/syscall.h>
+#include "gfapi-messages.h"
#include "glfs.h"
#include "glfs-internal.h"
-#include "hashfn.h"
-#include "rpc-clnt.h"
-
static gf_boolean_t
-vol_assigned (cmd_args_t *args)
+vol_assigned(cmd_args_t *args)
{
- return args->volfile || args->volfile_server;
+ return args->volfile || args->volfile_server;
}
-
static int
-glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
+glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx)
{
- call_pool_t *pool = NULL;
- int ret = -1;
+ call_pool_t *pool = NULL;
+ int ret = -1;
- if (!ctx) {
- goto err;
- }
-
- ret = xlator_mem_acct_init (THIS, glfs_mt_end + 1);
- if (ret != 0) {
- gf_msg (THIS->name, GF_LOG_ERROR, ENOMEM,
- API_MSG_MEM_ACCT_INIT_FAILED,
- "Memory accounting init failed");
- return ret;
- }
+ if (!ctx) {
+ goto err;
+ }
- /* reset ret to -1 so that we don't need to explicitly
- * set it in all error paths before "goto err"
- */
-
- ret = -1;
-
- ctx->process_uuid = generate_glusterfs_ctx_id ();
- if (!ctx->process_uuid) {
- goto err;
- }
-
- ctx->page_size = 128 * GF_UNIT_KB;
-
- ctx->iobuf_pool = iobuf_pool_new ();
- if (!ctx->iobuf_pool) {
- goto err;
- }
-
- ctx->event_pool = event_pool_new (DEFAULT_EVENT_POOL_SIZE,
- STARTING_EVENT_THREADS);
- if (!ctx->event_pool) {
- goto err;
- }
-
- ctx->env = syncenv_new (0, 0, 0);
- if (!ctx->env) {
- goto err;
- }
-
- pool = GF_CALLOC (1, sizeof (call_pool_t),
- glfs_mt_call_pool_t);
- if (!pool) {
- goto err;
- }
-
- /* frame_mem_pool size 112 * 4k */
- pool->frame_mem_pool = mem_pool_new (call_frame_t, 4096);
- if (!pool->frame_mem_pool) {
- goto err;
- }
- /* stack_mem_pool size 256 * 1024 */
- pool->stack_mem_pool = mem_pool_new (call_stack_t, 1024);
- if (!pool->stack_mem_pool) {
- goto err;
- }
-
- ctx->stub_mem_pool = mem_pool_new (call_stub_t, 1024);
- if (!ctx->stub_mem_pool) {
- goto err;
- }
-
- ctx->dict_pool = mem_pool_new (dict_t, GF_MEMPOOL_COUNT_OF_DICT_T);
- if (!ctx->dict_pool)
- goto err;
-
- ctx->dict_pair_pool = mem_pool_new (data_pair_t,
- GF_MEMPOOL_COUNT_OF_DATA_PAIR_T);
- if (!ctx->dict_pair_pool)
- goto err;
-
- ctx->dict_data_pool = mem_pool_new (data_t, GF_MEMPOOL_COUNT_OF_DATA_T);
- if (!ctx->dict_data_pool)
- goto err;
-
- ctx->logbuf_pool = mem_pool_new (log_buf_t,
- GF_MEMPOOL_COUNT_OF_LRU_BUF_T);
- if (!ctx->logbuf_pool)
- goto err;
-
- INIT_LIST_HEAD (&pool->all_frames);
- INIT_LIST_HEAD (&ctx->cmd_args.xlator_options);
- INIT_LIST_HEAD (&ctx->cmd_args.volfile_servers);
-
- LOCK_INIT (&pool->lock);
- ctx->pool = pool;
-
- pthread_mutex_init (&(ctx->lock), NULL);
-
- ret = 0;
+ ret = xlator_mem_acct_init(THIS, glfs_mt_end + 1);
+ if (ret != 0) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_MEM_ACCT_INIT_FAILED,
+ NULL);
+ return ret;
+ }
+
+ /* reset ret to -1 so that we don't need to explicitly
+ * set it in all error paths before "goto err"
+ */
+
+ ret = -1;
+
+ ctx->process_uuid = generate_glusterfs_ctx_id();
+ if (!ctx->process_uuid) {
+ goto err;
+ }
+
+ ctx->page_size = 128 * GF_UNIT_KB;
+
+ ctx->iobuf_pool = iobuf_pool_new();
+ if (!ctx->iobuf_pool) {
+ goto err;
+ }
+
+ ctx->event_pool = gf_event_pool_new(DEFAULT_EVENT_POOL_SIZE,
+ STARTING_EVENT_THREADS);
+ if (!ctx->event_pool) {
+ goto err;
+ }
+
+ ctx->env = syncenv_new(0, 0, 0);
+ if (!ctx->env) {
+ goto err;
+ }
+
+ pool = GF_CALLOC(1, sizeof(call_pool_t), glfs_mt_call_pool_t);
+ if (!pool) {
+ goto err;
+ }
+
+ /* frame_mem_pool size 112 * 4k */
+ pool->frame_mem_pool = mem_pool_new(call_frame_t, 4096);
+ if (!pool->frame_mem_pool) {
+ goto err;
+ }
+ /* stack_mem_pool size 256 * 1024 */
+ pool->stack_mem_pool = mem_pool_new(call_stack_t, 1024);
+ if (!pool->stack_mem_pool) {
+ goto err;
+ }
+
+ ctx->stub_mem_pool = mem_pool_new(call_stub_t, 1024);
+ if (!ctx->stub_mem_pool) {
+ goto err;
+ }
+
+ ctx->dict_pool = mem_pool_new(dict_t, GF_MEMPOOL_COUNT_OF_DICT_T);
+ if (!ctx->dict_pool)
+ goto err;
+
+ ctx->dict_pair_pool = mem_pool_new(data_pair_t,
+ GF_MEMPOOL_COUNT_OF_DATA_PAIR_T);
+ if (!ctx->dict_pair_pool)
+ goto err;
+
+ ctx->dict_data_pool = mem_pool_new(data_t, GF_MEMPOOL_COUNT_OF_DATA_T);
+ if (!ctx->dict_data_pool)
+ goto err;
+
+ ctx->logbuf_pool = mem_pool_new(log_buf_t, GF_MEMPOOL_COUNT_OF_LRU_BUF_T);
+ if (!ctx->logbuf_pool)
+ goto err;
+
+ INIT_LIST_HEAD(&pool->all_frames);
+ INIT_LIST_HEAD(&ctx->cmd_args.xlator_options);
+ INIT_LIST_HEAD(&ctx->cmd_args.volfile_servers);
+
+ LOCK_INIT(&pool->lock);
+ ctx->pool = pool;
+
+ ret = 0;
err:
- if (ret && pool) {
- if (pool->frame_mem_pool)
- mem_pool_destroy (pool->frame_mem_pool);
- if (pool->stack_mem_pool)
- mem_pool_destroy (pool->stack_mem_pool);
- GF_FREE (pool);
- }
-
- if (ret && ctx) {
- if (ctx->stub_mem_pool)
- mem_pool_destroy (ctx->stub_mem_pool);
- if (ctx->dict_pool)
- mem_pool_destroy (ctx->dict_pool);
- if (ctx->dict_data_pool)
- mem_pool_destroy (ctx->dict_data_pool);
- if (ctx->dict_pair_pool)
- mem_pool_destroy (ctx->dict_pair_pool);
- if (ctx->logbuf_pool)
- mem_pool_destroy (ctx->logbuf_pool);
- }
-
- return ret;
-}
+ if (ret && pool) {
+ if (pool->frame_mem_pool)
+ mem_pool_destroy(pool->frame_mem_pool);
+ if (pool->stack_mem_pool)
+ mem_pool_destroy(pool->stack_mem_pool);
+ GF_FREE(pool);
+ }
+
+ if (ret && ctx) {
+ if (ctx->stub_mem_pool)
+ mem_pool_destroy(ctx->stub_mem_pool);
+ if (ctx->dict_pool)
+ mem_pool_destroy(ctx->dict_pool);
+ if (ctx->dict_data_pool)
+ mem_pool_destroy(ctx->dict_data_pool);
+ if (ctx->dict_pair_pool)
+ mem_pool_destroy(ctx->dict_pair_pool);
+ if (ctx->logbuf_pool)
+ mem_pool_destroy(ctx->logbuf_pool);
+ }
+ return ret;
+}
static int
-create_master (struct glfs *fs)
+create_master(struct glfs *fs)
{
- int ret = 0;
- xlator_t *master = NULL;
-
- master = GF_CALLOC (1, sizeof (*master),
- glfs_mt_xlator_t);
- if (!master)
- goto err;
+ int ret = 0;
+ xlator_t *master = NULL;
- master->name = gf_strdup ("gfapi");
- if (!master->name)
- goto err;
+ master = GF_CALLOC(1, sizeof(*master), glfs_mt_xlator_t);
+ if (!master)
+ goto err;
- if (xlator_set_type (master, "mount/api") == -1) {
- gf_msg ("glfs", GF_LOG_ERROR, 0,
- API_MSG_MASTER_XLATOR_INIT_FAILED, "master xlator "
- "for %s initialization failed", fs->volname);
- goto err;
- }
+ master->name = gf_strdup("gfapi");
+ if (!master->name)
+ goto err;
- master->ctx = fs->ctx;
- master->private = fs;
- master->options = get_new_dict ();
- if (!master->options)
- goto err;
+ if (xlator_set_type(master, "mount/api") == -1) {
+ gf_smsg("glfs", GF_LOG_ERROR, 0, API_MSG_MASTER_XLATOR_INIT_FAILED,
+ "name=%s", fs->volname, NULL);
+ goto err;
+ }
+ master->ctx = fs->ctx;
+ master->private = fs;
+ master->options = dict_new();
+ if (!master->options)
+ goto err;
- ret = xlator_init (master);
- if (ret) {
- gf_msg ("glfs", GF_LOG_ERROR, 0,
- API_MSG_GFAPI_XLATOR_INIT_FAILED,
- "failed to initialize gfapi translator");
- goto err;
- }
+ ret = xlator_init(master);
+ if (ret) {
+ gf_smsg("glfs", GF_LOG_ERROR, 0, API_MSG_GFAPI_XLATOR_INIT_FAILED,
+ NULL);
+ goto err;
+ }
- fs->ctx->master = master;
- THIS = master;
+ fs->ctx->master = master;
+ THIS = master;
- return 0;
+ return 0;
err:
- if (master) {
- xlator_destroy (master);
- }
+ if (master) {
+ xlator_destroy(master);
+ }
- return -1;
+ return -1;
}
-
static FILE *
-get_volfp (struct glfs *fs)
+get_volfp(struct glfs *fs)
{
- cmd_args_t *cmd_args = NULL;
- FILE *specfp = NULL;
+ cmd_args_t *cmd_args = NULL;
+ FILE *specfp = NULL;
- cmd_args = &fs->ctx->cmd_args;
+ cmd_args = &fs->ctx->cmd_args;
- if ((specfp = fopen (cmd_args->volfile, "r")) == NULL) {
- gf_msg ("glfs", GF_LOG_ERROR, errno,
- API_MSG_VOLFILE_OPEN_FAILED,
- "volume file %s open failed: %s",
- cmd_args->volfile,
- strerror (errno));
- return NULL;
- }
+ if ((specfp = fopen(cmd_args->volfile, "r")) == NULL) {
+ gf_smsg("glfs", GF_LOG_ERROR, errno, API_MSG_VOLFILE_OPEN_FAILED,
+ "file=%s", cmd_args->volfile, "err=%s", strerror(errno), NULL);
+ return NULL;
+ }
- gf_msg_debug ("glfs", 0, "loading volume file %s", cmd_args->volfile);
+ gf_msg_debug("glfs", 0, "loading volume file %s", cmd_args->volfile);
- return specfp;
+ return specfp;
}
-
int
-glfs_volumes_init (struct glfs *fs)
+glfs_volumes_init(struct glfs *fs)
{
- FILE *fp = NULL;
- cmd_args_t *cmd_args = NULL;
- int ret = 0;
+ FILE *fp = NULL;
+ cmd_args_t *cmd_args = NULL;
+ int ret = 0;
+
+ cmd_args = &fs->ctx->cmd_args;
- cmd_args = &fs->ctx->cmd_args;
+ if (!vol_assigned(cmd_args))
+ return -1;
- if (!vol_assigned (cmd_args))
- return -1;
+ if (sys_access(SECURE_ACCESS_FILE, F_OK) == 0) {
+ fs->ctx->secure_mgmt = 1;
+ fs->ctx->ssl_cert_depth = glusterfs_read_secure_access_file();
+ }
- if (cmd_args->volfile_server) {
- ret = glfs_mgmt_init (fs);
- goto out;
- }
+ if (cmd_args->volfile_server) {
+ ret = glfs_mgmt_init(fs);
+ goto out;
+ }
- fp = get_volfp (fs);
+ fp = get_volfp(fs);
- if (!fp) {
- gf_msg ("glfs", GF_LOG_ERROR, ENOENT,
- API_MSG_VOL_SPEC_FILE_ERROR,
- "Cannot reach volume specification file");
- ret = -1;
- goto out;
- }
+ if (!fp) {
+ gf_smsg("glfs", GF_LOG_ERROR, ENOENT, API_MSG_VOL_SPEC_FILE_ERROR,
+ NULL);
+ ret = -1;
+ goto out;
+ }
- ret = glfs_process_volfp (fs, fp);
- if (ret)
- goto out;
+ ret = glfs_process_volfp(fs, fp);
+ if (ret)
+ goto out;
out:
- return ret;
+ return ret;
}
-
///////////////////////////////////////////////////////////////////////////////
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_xlator_option, 3.4.0)
int
-pub_glfs_set_xlator_option (struct glfs *fs, const char *xlator,
- const char *key, const char *value)
+pub_glfs_set_xlator_option(struct glfs *fs, const char *xlator, const char *key,
+ const char *value)
{
- xlator_cmdline_option_t *option = NULL;
+ xlator_cmdline_option_t *option = NULL;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- option = GF_CALLOC (1, sizeof (*option),
- glfs_mt_xlator_cmdline_option_t);
- if (!option)
- goto enomem;
+ option = GF_CALLOC(1, sizeof(*option), glfs_mt_xlator_cmdline_option_t);
+ if (!option)
+ goto enomem;
- INIT_LIST_HEAD (&option->cmd_args);
+ INIT_LIST_HEAD(&option->cmd_args);
- option->volume = gf_strdup (xlator);
- if (!option->volume)
- goto enomem;
- option->key = gf_strdup (key);
- if (!option->key)
- goto enomem;
- option->value = gf_strdup (value);
- if (!option->value)
- goto enomem;
+ option->volume = gf_strdup(xlator);
+ if (!option->volume)
+ goto enomem;
+ option->key = gf_strdup(key);
+ if (!option->key)
+ goto enomem;
+ option->value = gf_strdup(value);
+ if (!option->value)
+ goto enomem;
- list_add (&option->cmd_args, &fs->ctx->cmd_args.xlator_options);
+ list_add(&option->cmd_args, &fs->ctx->cmd_args.xlator_options);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
- return 0;
+ return 0;
enomem:
- errno = ENOMEM;
+ errno = ENOMEM;
- if (!option) {
- __GLFS_EXIT_FS;
- return -1;
- }
+ if (!option) {
+ __GLFS_EXIT_FS;
+ return -1;
+ }
- GF_FREE (option->volume);
- GF_FREE (option->key);
- GF_FREE (option->value);
- GF_FREE (option);
+ GF_FREE(option->volume);
+ GF_FREE(option->key);
+ GF_FREE(option->value);
+ GF_FREE(option);
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return -1;
+ return -1;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_xlator_option, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unset_volfile_server, 3.5.1)
int
-pub_glfs_unset_volfile_server (struct glfs *fs, const char *transport,
- const char *host, const int port)
+pub_glfs_unset_volfile_server(struct glfs *fs, const char *transport,
+ const char *host, const int port)
{
- cmd_args_t *cmd_args = NULL;
- server_cmdline_t *server = NULL;
- int ret = -1;
+ cmd_args_t *cmd_args = NULL;
+ server_cmdline_t *server = NULL;
+ server_cmdline_t *tmp = NULL;
+ char *transport_val = NULL;
+ int port_val = 0;
+ int ret = -1;
+
+ if (!fs || !host) {
+ errno = EINVAL;
+ return ret;
+ }
- if (!transport || !host || !port) {
- errno = EINVAL;
- return ret;
- }
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- cmd_args = &fs->ctx->cmd_args;
- list_for_each_entry(server, &cmd_args->curr_server->list, list) {
- if ((!strcmp(server->volfile_server, host) &&
- !strcmp(server->transport, transport) &&
- (server->port == port))) {
- list_del (&server->list);
- ret = 0;
- goto out;
- }
+ cmd_args = &fs->ctx->cmd_args;
+
+ if (transport) {
+ transport_val = gf_strdup(transport);
+ } else {
+ transport_val = gf_strdup(GF_DEFAULT_VOLFILE_TRANSPORT);
+ }
+
+ if (!transport_val) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ if (port) {
+ port_val = port;
+ } else {
+ port_val = GF_DEFAULT_BASE_PORT;
+ }
+
+ list_for_each_entry_safe(server, tmp, &cmd_args->curr_server->list, list)
+ {
+ if (!server->volfile_server || !server->transport)
+ continue;
+ if ((!strcmp(server->volfile_server, host) &&
+ !strcmp(server->transport, transport_val) &&
+ (server->port == port_val))) {
+ list_del(&server->list);
+ ret = 0;
+ goto out;
}
+ }
out:
- __GLFS_EXIT_FS;
+ GF_FREE(transport_val);
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_unset_volfile_server, 3.5.1);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile_server, 3.4.0)
int
-pub_glfs_set_volfile_server (struct glfs *fs, const char *transport,
- const char *host, int port)
+pub_glfs_set_volfile_server(struct glfs *fs, const char *transport,
+ const char *host, int port)
{
- cmd_args_t *cmd_args = NULL;
- server_cmdline_t *server = NULL;
- server_cmdline_t *tmp = NULL;
- int ret = -1;
-
- if (!fs || !host) {
- errno = EINVAL;
- return ret;
- }
+ cmd_args_t *cmd_args = NULL;
+ int ret = -1;
+ char *server_host = NULL;
+ char *server_transport = NULL;
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- cmd_args = &fs->ctx->cmd_args;
-
- cmd_args->max_connect_attempts = 1;
-
- server = GF_CALLOC (1, sizeof (server_cmdline_t),
- glfs_mt_server_cmdline_t);
-
- if (!server) {
- errno = ENOMEM;
- goto out;
- }
+ if (!fs || !host) {
+ errno = EINVAL;
+ return ret;
+ }
- INIT_LIST_HEAD (&server->list);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- server->volfile_server = gf_strdup (host);
- if (!server->volfile_server) {
- errno = ENOMEM;
- goto out;
- }
+ cmd_args = &fs->ctx->cmd_args;
+ cmd_args->max_connect_attempts = 1;
- if (transport) {
- server->transport = gf_strdup (transport);
- if (!server->transport) {
- errno = ENOMEM;
- goto out;
- }
+ server_host = gf_strdup(host);
+ if (!server_host) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ if (transport) {
+ /* volfile fetch support over tcp|unix only */
+ if (!strcmp(transport, "tcp") || !strcmp(transport, "unix")) {
+ server_transport = gf_strdup(transport);
+ } else if (!strcmp(transport, "rdma")) {
+ server_transport = gf_strdup(GF_DEFAULT_VOLFILE_TRANSPORT);
+ gf_smsg("glfs", GF_LOG_WARNING, EINVAL, API_MSG_TRANS_RDMA_DEP,
+ NULL);
+ } else {
+ gf_smsg("glfs", GF_LOG_TRACE, EINVAL, API_MSG_TRANS_NOT_SUPPORTED,
+ "transport=%s", transport, NULL);
+ goto out;
}
+ } else {
+ server_transport = gf_strdup(GF_DEFAULT_VOLFILE_TRANSPORT);
+ }
- server->port = port;
+ if (!server_transport) {
+ errno = ENOMEM;
+ goto out;
+ }
- if (!cmd_args->volfile_server) {
- cmd_args->volfile_server = server->volfile_server;
- cmd_args->volfile_server_transport = server->transport;
- cmd_args->volfile_server_port = server->port;
- cmd_args->curr_server = server;
- }
+ if (!port) {
+ port = GF_DEFAULT_BASE_PORT;
+ }
- list_for_each_entry(tmp, &cmd_args->volfile_servers, list) {
- if ((!strcmp(tmp->volfile_server, host) &&
- !strcmp(tmp->transport, transport) &&
- (tmp->port == port))) {
- errno = EEXIST;
- ret = -1;
- goto out;
- }
- }
+ if (!strcmp(server_transport, "unix")) {
+ port = 0;
+ }
- list_add_tail (&server->list, &cmd_args->volfile_servers);
+ ret = gf_set_volfile_server_common(cmd_args, server_host, server_transport,
+ port);
+ if (ret) {
+ gf_log("glfs", GF_LOG_ERROR, "failed to set volfile server: %s",
+ strerror(errno));
+ }
- ret = 0;
out:
- if (ret == -1) {
- if (server) {
- GF_FREE (server->volfile_server);
- GF_FREE (server->transport);
- GF_FREE (server);
- }
- }
+ if (server_host) {
+ GF_FREE(server_host);
+ }
- __GLFS_EXIT_FS;
+ if (server_transport) {
+ GF_FREE(server_transport);
+ }
+
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile_server, 3.4.0);
+/* *
+ * Used to free the arguments allocated by glfs_set_volfile_server()
+ */
+static void
+glfs_free_volfile_servers(cmd_args_t *cmd_args)
+{
+ server_cmdline_t *server = NULL;
+ server_cmdline_t *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO(THIS->name, cmd_args, out);
+
+ list_for_each_entry_safe(server, tmp, &cmd_args->volfile_servers, list)
+ {
+ list_del_init(&server->list);
+ GF_FREE(server->volfile_server);
+ GF_FREE(server->transport);
+ GF_FREE(server);
+ }
+ cmd_args->curr_server = NULL;
+out:
+ return;
+}
+static void
+glfs_free_xlator_options(cmd_args_t *cmd_args)
+{
+ xlator_cmdline_option_t *xo = NULL;
+ xlator_cmdline_option_t *tmp_xo = NULL;
+
+ if (!&(cmd_args->xlator_options))
+ return;
+
+ list_for_each_entry_safe(xo, tmp_xo, &cmd_args->xlator_options, cmd_args)
+ {
+ list_del_init(&xo->cmd_args);
+ GF_FREE(xo->volume);
+ GF_FREE(xo->key);
+ GF_FREE(xo->value);
+ GF_FREE(xo);
+ }
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsuid, 3.4.2)
int
-pub_glfs_setfsuid (uid_t fsuid)
+pub_glfs_setfsuid(uid_t fsuid)
{
- /* TODO:
- * - Set the THIS and restore it appropriately
- */
- return syncopctx_setfsuid (&fsuid);
+ /* TODO:
+ * - Set the THIS and restore it appropriately
+ */
+ return syncopctx_setfsuid(&fsuid);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsuid, 3.4.2);
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgid, 3.4.2)
+int
+pub_glfs_setfsgid(gid_t fsgid)
+{
+ /* TODO:
+ * - Set the THIS and restore it appropriately
+ */
+ return syncopctx_setfsgid(&fsgid);
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgroups, 3.4.2)
int
-pub_glfs_setfsgid (gid_t fsgid)
+pub_glfs_setfsgroups(size_t size, const gid_t *list)
{
- /* TODO:
- * - Set the THIS and restore it appropriately
- */
- return syncopctx_setfsgid (&fsgid);
+ /* TODO:
+ * - Set the THIS and restore it appropriately
+ */
+ return syncopctx_setfsgroups(size, list);
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgid, 3.4.2);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsleaseid, 4.0.0)
+int
+pub_glfs_setfsleaseid(glfs_leaseid_t leaseid)
+{
+ int ret = -1;
+ char *gleaseid = NULL;
+
+ gleaseid = gf_leaseid_get();
+ if (gleaseid) {
+ if (leaseid)
+ memcpy(gleaseid, leaseid, LEASE_ID_SIZE);
+ else /* reset leaseid */
+ memset(gleaseid, 0, LEASE_ID_SIZE);
+ ret = 0;
+ }
+ if (ret)
+ gf_log("glfs", GF_LOG_ERROR, "failed to set leaseid: %s",
+ strerror(errno));
+ return ret;
+}
int
-pub_glfs_setfsgroups (size_t size, const gid_t *list)
+get_fop_attr_glfd(dict_t **fop_attr, struct glfs_fd *glfd)
{
- /* TODO:
- * - Set the THIS and restore it appropriately
- */
- return syncopctx_setfsgroups(size, list);
+ char *leaseid = NULL;
+ int ret = 0;
+ gf_boolean_t dict_create = _gf_false;
+
+ leaseid = GF_MALLOC(LEASE_ID_SIZE, gf_common_mt_char);
+ GF_CHECK_ALLOC_AND_LOG("gfapi", leaseid, ret, "lease id alloc failed", out);
+ memcpy(leaseid, glfd->lease_id, LEASE_ID_SIZE);
+ if (*fop_attr == NULL) {
+ *fop_attr = dict_new();
+ dict_create = _gf_true;
+ }
+ GF_CHECK_ALLOC_AND_LOG("gfapi", *fop_attr, ret, "dict_new failed", out);
+ ret = dict_set_bin(*fop_attr, "lease-id", leaseid, LEASE_ID_SIZE);
+out:
+ if (ret) {
+ GF_FREE(leaseid);
+ if (dict_create) {
+ if (*fop_attr)
+ dict_unref(*fop_attr);
+ *fop_attr = NULL;
+ }
+ }
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_setfsgroups, 3.4.2);
+int
+set_fop_attr_glfd(struct glfs_fd *glfd)
+{
+ char *lease_id = NULL;
+ int ret = -1;
+
+ lease_id = gf_existing_leaseid();
+ if (lease_id) {
+ memcpy(glfd->lease_id, lease_id, LEASE_ID_SIZE);
+ ret = 0;
+ }
+ return ret;
+}
+int
+get_fop_attr_thrd_key(dict_t **fop_attr)
+{
+ char *existing_leaseid = NULL, *leaseid = NULL;
+ int ret = 0;
+ gf_boolean_t dict_create = _gf_false;
+
+ existing_leaseid = gf_existing_leaseid();
+ if (existing_leaseid) {
+ leaseid = GF_MALLOC(LEASE_ID_SIZE, gf_common_mt_char);
+ GF_CHECK_ALLOC_AND_LOG("gfapi", leaseid, ret, "lease id alloc failed",
+ out);
+ memcpy(leaseid, existing_leaseid, LEASE_ID_SIZE);
+ if (*fop_attr == NULL) {
+ *fop_attr = dict_new();
+ dict_create = _gf_true;
+ }
+ GF_CHECK_ALLOC_AND_LOG("gfapi", *fop_attr, ret, "dict_new failed", out);
+ ret = dict_set_bin(*fop_attr, "lease-id", leaseid, LEASE_ID_SIZE);
+ }
-struct glfs *
-pub_glfs_from_glfd (struct glfs_fd *glfd)
+out:
+ if (ret) {
+ GF_FREE(leaseid);
+ if (dict_create) {
+ if (*fop_attr)
+ dict_unref(*fop_attr);
+ *fop_attr = NULL;
+ }
+ }
+ return ret;
+}
+
+void
+unset_fop_attr(dict_t **fop_attr)
{
- return glfd->fs;
+ char *lease_id = NULL;
+ lease_id = gf_existing_leaseid();
+ if (lease_id)
+ memset(lease_id, 0, LEASE_ID_SIZE);
+ if (*fop_attr) {
+ dict_unref(*fop_attr);
+ *fop_attr = NULL;
+ }
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_from_glfd, 3.4.0);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_from_glfd, 3.4.0)
+struct glfs *
+pub_glfs_from_glfd(struct glfs_fd *glfd)
+{
+ if (glfd == NULL) {
+ errno = EBADF;
+ return NULL;
+ }
+ return glfd->fs;
+}
-struct glfs_fd *
-glfs_fd_new (struct glfs *fs)
+static void
+glfs_fd_destroy(struct glfs_fd *glfd)
{
- struct glfs_fd *glfd = NULL;
+ if (!glfd)
+ return;
- glfd = GF_CALLOC (1, sizeof (*glfd), glfs_mt_glfs_fd_t);
- if (!glfd)
- return NULL;
+ glfs_lock(glfd->fs, _gf_true);
+ {
+ list_del_init(&glfd->openfds);
+ }
+ glfs_unlock(glfd->fs);
- glfd->fs = fs;
+ if (glfd->fd) {
+ fd_unref(glfd->fd);
+ glfd->fd = NULL;
+ }
- INIT_LIST_HEAD (&glfd->openfds);
+ GF_FREE(glfd->readdirbuf);
- return glfd;
+ GF_FREE(glfd);
}
-
-void
-glfs_fd_bind (struct glfs_fd *glfd)
+struct glfs_fd *
+glfs_fd_new(struct glfs *fs)
{
- struct glfs *fs = NULL;
+ struct glfs_fd *glfd = NULL;
- fs = glfd->fs;
+ glfd = GF_CALLOC(1, sizeof(*glfd), glfs_mt_glfs_fd_t);
+ if (!glfd)
+ return NULL;
+
+ glfd->fs = fs;
+
+ INIT_LIST_HEAD(&glfd->openfds);
- glfs_lock (fs);
- {
- list_add_tail (&glfd->openfds, &fs->openfds);
- }
- glfs_unlock (fs);
+ GF_REF_INIT(glfd, glfs_fd_destroy);
+
+ return glfd;
}
void
-glfs_fd_destroy (struct glfs_fd *glfd)
+glfs_fd_bind(struct glfs_fd *glfd)
{
- if (!glfd)
- return;
-
- glfs_lock (glfd->fs);
- {
- list_del_init (&glfd->openfds);
- }
- glfs_unlock (glfd->fs);
-
- if (glfd->fd) {
- fd_unref (glfd->fd);
- glfd->fd = NULL;
- }
+ struct glfs *fs = NULL;
- GF_FREE (glfd->readdirbuf);
+ fs = glfd->fs;
- GF_FREE (glfd);
+ glfs_lock(fs, _gf_true);
+ {
+ list_add_tail(&glfd->openfds, &fs->openfds);
+ }
+ glfs_unlock(fs);
}
-
static void *
-glfs_poller (void *data)
+glfs_poller(void *data)
{
- struct glfs *fs = NULL;
+ struct glfs *fs = NULL;
- fs = data;
+ fs = data;
- event_dispatch (fs->ctx->event_pool);
+ gf_event_dispatch(fs->ctx->event_pool);
- return NULL;
+ return NULL;
}
static struct glfs *
-glfs_new_fs (const char *volname)
+glfs_new_fs(const char *volname)
{
- struct glfs *fs = NULL;
+ struct glfs *fs = NULL;
- fs = CALLOC (1, sizeof (*fs));
- if (!fs)
- return NULL;
+ fs = CALLOC(1, sizeof(*fs));
+ if (!fs)
+ return NULL;
- INIT_LIST_HEAD (&fs->openfds);
- INIT_LIST_HEAD (&fs->upcall_list);
+ INIT_LIST_HEAD(&fs->openfds);
+ INIT_LIST_HEAD(&fs->upcall_list);
+ INIT_LIST_HEAD(&fs->waitq);
- PTHREAD_MUTEX_INIT (&fs->mutex, NULL, fs->pthread_flags,
- GLFS_INIT_MUTEX, err);
+ PTHREAD_MUTEX_INIT(&fs->mutex, NULL, fs->pthread_flags, GLFS_INIT_MUTEX,
+ err);
- PTHREAD_COND_INIT (&fs->cond, NULL, fs->pthread_flags,
- GLFS_INIT_COND, err);
+ PTHREAD_COND_INIT(&fs->cond, NULL, fs->pthread_flags, GLFS_INIT_COND, err);
- PTHREAD_COND_INIT (&fs->child_down_cond, NULL, fs->pthread_flags,
- GLFS_INIT_COND_CHILD, err);
+ PTHREAD_COND_INIT(&fs->child_down_cond, NULL, fs->pthread_flags,
+ GLFS_INIT_COND_CHILD, err);
- PTHREAD_MUTEX_INIT (&fs->upcall_list_mutex, NULL, fs->pthread_flags,
- GLFS_INIT_MUTEX_UPCALL, err);
+ PTHREAD_MUTEX_INIT(&fs->upcall_list_mutex, NULL, fs->pthread_flags,
+ GLFS_INIT_MUTEX_UPCALL, err);
- fs->volname = strdup (volname);
- if (!fs->volname)
- goto err;
+ fs->volname = strdup(volname);
+ if (!fs->volname)
+ goto err;
- fs->pin_refcnt = 0;
+ fs->pin_refcnt = 0;
+ fs->upcall_events = 0;
+ fs->up_cbk = NULL;
+ fs->up_data = NULL;
- return fs;
+ return fs;
err:
- glfs_free_from_ctx (fs);
- return NULL;
+ glfs_free_from_ctx(fs);
+ return NULL;
+}
+
+extern xlator_t global_xlator;
+extern glusterfs_ctx_t *global_ctx;
+extern pthread_mutex_t global_ctx_mutex;
+
+static int
+glfs_init_global_ctx()
+{
+ int ret = 0;
+ glusterfs_ctx_t *ctx = NULL;
+
+ pthread_mutex_lock(&global_ctx_mutex);
+ {
+ if (global_xlator.ctx)
+ goto unlock;
+
+ ctx = glusterfs_ctx_new();
+ if (!ctx) {
+ ret = -1;
+ goto unlock;
+ }
+
+ gf_log_globals_init(ctx, GF_LOG_NONE);
+
+ global_ctx = ctx;
+ global_xlator.ctx = global_ctx;
+
+ ret = glusterfs_ctx_defaults_init(ctx);
+ if (ret) {
+ global_ctx = NULL;
+ global_xlator.ctx = NULL;
+ goto unlock;
+ }
+ }
+unlock:
+ pthread_mutex_unlock(&global_ctx_mutex);
+
+ if (ret)
+ FREE(ctx);
+
+ return ret;
}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_new, 3.4.0)
struct glfs *
-pub_glfs_new (const char *volname)
+pub_glfs_new(const char *volname)
{
- struct glfs *fs = NULL;
- int ret = -1;
- glusterfs_ctx_t *ctx = NULL;
- xlator_t *old_THIS = NULL;
-
- if (!volname) {
- errno = EINVAL;
- return NULL;
+ if (!volname) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ struct glfs *fs = NULL;
+ int i = 0;
+ int ret = -1;
+ glusterfs_ctx_t *ctx = NULL;
+ xlator_t *old_THIS = NULL;
+ char pname[16] = "";
+ char msg[32] = "";
+
+ if (volname[0] == '/' || volname[0] == '-') {
+ if (strncmp(volname, "/snaps/", 7) == 0) {
+ goto label;
}
+ errno = EINVAL;
+ return NULL;
+ }
- fs = glfs_new_fs (volname);
- if (!fs)
- return NULL;
+ for (i = 0; i < strlen(volname); i++) {
+ if (!isalnum(volname[i]) && (volname[i] != '_') &&
+ (volname[i] != '-')) {
+ errno = EINVAL;
+ return NULL;
+ }
+ }
- ctx = glusterfs_ctx_new ();
- if (!ctx)
- goto fini;
+label:
+ /*
+ * Do this as soon as possible in case something else depends on
+ * pool allocations.
+ */
+ mem_pools_init();
- /* first globals init, for gf_mem_acct_enable_set () */
+ fs = glfs_new_fs(volname);
+ if (!fs)
+ goto out;
- ret = glusterfs_globals_init (ctx);
- if (ret)
- goto fini;
+ ctx = glusterfs_ctx_new();
+ if (!ctx)
+ goto out;
- old_THIS = THIS;
- /* THIS is set to NULL so that we do not modify the caller xlators'
- * ctx, instead we set the global_xlator->ctx
- */
- THIS = NULL;
- THIS->ctx = ctx;
+ /* first globals init, for gf_mem_acct_enable_set () */
- /* then ctx_defaults_init, for xlator_mem_acct_init(THIS) */
+ ret = glusterfs_globals_init(ctx);
+ if (ret)
+ goto out;
- ret = glusterfs_ctx_defaults_init (ctx);
- if (ret)
- goto fini;
+ old_THIS = THIS;
+ ret = glfs_init_global_ctx();
+ if (ret)
+ goto out;
- fs->ctx = ctx;
+ /* then ctx_defaults_init, for xlator_mem_acct_init(THIS) */
- ret = glfs_set_logging (fs, "/dev/null", 0);
- if (ret)
- goto fini;
+ ret = glusterfs_ctx_defaults_init(ctx);
+ if (ret)
+ goto out;
- fs->ctx->cmd_args.volfile_id = gf_strdup (volname);
- if (!(fs->ctx->cmd_args.volfile_id))
- goto fini;
+ fs->ctx = ctx;
+ fs->ctx->process_mode = GF_CLIENT_PROCESS;
+ ret = glfs_set_logging(fs, "/dev/null", 0);
+ if (ret)
goto out;
-fini:
- glfs_fini (fs);
- fs = NULL;
-out:
- if (old_THIS)
- THIS = old_THIS;
+ fs->ctx->cmd_args.volfile_id = gf_strdup(volname);
+ if (!(fs->ctx->cmd_args.volfile_id)) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = -1;
+#ifdef GF_LINUX_HOST_OS
+ ret = prctl(PR_GET_NAME, (unsigned long)pname, 0, 0, 0);
+#endif
+ if (ret)
+ fs->ctx->cmd_args.process_name = gf_strdup("gfapi");
+ else {
+ snprintf(msg, sizeof(msg), "gfapi.%s", pname);
+ fs->ctx->cmd_args.process_name = gf_strdup(msg);
+ }
+ ret = 0;
- return fs;
-}
+out:
+ if (ret) {
+ if (fs) {
+ glfs_fini(fs);
+ fs = NULL;
+ } else {
+ /* glfs_fini() calls mem_pools_fini() too */
+ mem_pools_fini();
+ }
+ }
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_new, 3.4.0);
+ if (old_THIS)
+ THIS = old_THIS;
+ return fs;
+}
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_new_from_ctx, 3.7.0)
struct glfs *
-priv_glfs_new_from_ctx (glusterfs_ctx_t *ctx)
+priv_glfs_new_from_ctx(glusterfs_ctx_t *ctx)
{
- struct glfs *fs = NULL;
+ struct glfs *fs = NULL;
- if (!ctx)
- goto out;
+ if (!ctx)
+ goto out;
- fs = glfs_new_fs ("");
- if (!fs)
- goto out;
+ fs = glfs_new_fs("");
+ if (!fs)
+ goto out;
- fs->ctx = ctx;
+ fs->ctx = ctx;
out:
- return fs;
+ return fs;
}
-GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_new_from_ctx, 3.7.0);
-
-
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_free_from_ctx, 3.7.0)
void
-priv_glfs_free_from_ctx (struct glfs *fs)
+priv_glfs_free_from_ctx(struct glfs *fs)
{
- upcall_entry *u_list = NULL;
- upcall_entry *tmp = NULL;
-
- if (!fs)
- return;
-
- /* cleanup upcall structures */
- list_for_each_entry_safe (u_list, tmp,
- &fs->upcall_list,
- upcall_list) {
- list_del_init (&u_list->upcall_list);
- GF_FREE (u_list->upcall_data.data);
- GF_FREE (u_list);
- }
+ upcall_entry *u_list = NULL;
+ upcall_entry *tmp = NULL;
- PTHREAD_MUTEX_DESTROY (&fs->mutex, fs->pthread_flags, GLFS_INIT_MUTEX);
+ if (!fs)
+ return;
- PTHREAD_COND_DESTROY (&fs->cond, fs->pthread_flags, GLFS_INIT_COND);
+ /* cleanup upcall structures */
+ list_for_each_entry_safe(u_list, tmp, &fs->upcall_list, upcall_list)
+ {
+ list_del_init(&u_list->upcall_list);
+ GF_FREE(u_list->upcall_data.data);
+ GF_FREE(u_list);
+ }
- PTHREAD_COND_DESTROY (&fs->child_down_cond, fs->pthread_flags,
- GLFS_INIT_COND_CHILD);
+ PTHREAD_MUTEX_DESTROY(&fs->mutex, fs->pthread_flags, GLFS_INIT_MUTEX);
- PTHREAD_MUTEX_DESTROY (&fs->upcall_list_mutex, fs->pthread_flags,
- GLFS_INIT_MUTEX_UPCALL);
+ PTHREAD_COND_DESTROY(&fs->cond, fs->pthread_flags, GLFS_INIT_COND);
- FREE (fs->volname);
+ PTHREAD_COND_DESTROY(&fs->child_down_cond, fs->pthread_flags,
+ GLFS_INIT_COND_CHILD);
- FREE (fs);
-}
+ PTHREAD_MUTEX_DESTROY(&fs->upcall_list_mutex, fs->pthread_flags,
+ GLFS_INIT_MUTEX_UPCALL);
-GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_free_from_ctx, 3.7.0);
+ if (fs->oldvolfile)
+ FREE(fs->oldvolfile);
+ FREE(fs->volname);
+ FREE(fs);
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile, 3.4.0)
int
-pub_glfs_set_volfile (struct glfs *fs, const char *volfile)
+pub_glfs_set_volfile(struct glfs *fs, const char *volfile)
{
- cmd_args_t *cmd_args = NULL;
+ cmd_args_t *cmd_args = NULL;
- cmd_args = &fs->ctx->cmd_args;
+ cmd_args = &fs->ctx->cmd_args;
- if (vol_assigned (cmd_args))
- return -1;
+ if (vol_assigned(cmd_args))
+ return -1;
- cmd_args->volfile = gf_strdup (volfile);
- if (!cmd_args->volfile)
- return -1;
- return 0;
+ cmd_args->volfile = gf_strdup(volfile);
+ if (!cmd_args->volfile)
+ return -1;
+ return 0;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_volfile, 3.4.0);
-
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_logging, 3.4.0)
int
-pub_glfs_set_logging (struct glfs *fs, const char *logfile, int loglevel)
+pub_glfs_set_logging(struct glfs *fs, const char *logfile, int loglevel)
{
- int ret = -1;
- char *tmplog = NULL;
-
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
-
- if (!logfile) {
- ret = gf_set_log_file_path (&fs->ctx->cmd_args);
- if (ret)
- goto out;
- tmplog = fs->ctx->cmd_args.log_file;
- } else {
- tmplog = (char *)logfile;
- }
+ int ret = -1;
+ char *tmplog = NULL;
- /* finish log set parameters before init */
- if (loglevel >= 0)
- gf_log_set_loglevel (loglevel);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- ret = gf_log_init (fs->ctx, tmplog, NULL);
+ if (!logfile) {
+ ret = gf_set_log_file_path(&fs->ctx->cmd_args, fs->ctx);
if (ret)
- goto out;
+ goto out;
+ tmplog = fs->ctx->cmd_args.log_file;
+ } else {
+ tmplog = (char *)logfile;
+ }
+
+ /* finish log set parameters before init */
+ if (loglevel >= 0)
+ gf_log_set_loglevel(fs->ctx, loglevel);
+
+ ret = gf_log_init(fs->ctx, tmplog, NULL);
+ if (ret)
+ goto out;
- ret = gf_log_inject_timer_event (fs->ctx);
- if (ret)
- goto out;
+ ret = gf_log_inject_timer_event(fs->ctx);
+ if (ret)
+ goto out;
out:
- __GLFS_EXIT_FS;
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_logging, 3.4.0);
-
-
int
-glfs_init_wait (struct glfs *fs)
+glfs_init_wait(struct glfs *fs)
{
- int ret = -1;
-
- /* Always a top-down call, use glfs_lock() */
- glfs_lock (fs);
- {
- while (!fs->init)
- pthread_cond_wait (&fs->cond,
- &fs->mutex);
- ret = fs->ret;
- errno = fs->err;
- }
- glfs_unlock (fs);
-
- return ret;
+ int ret = -1;
+
+ /* Always a top-down call, use glfs_lock() */
+ glfs_lock(fs, _gf_true);
+ {
+ while (!fs->init)
+ pthread_cond_wait(&fs->cond, &fs->mutex);
+ ret = fs->ret;
+ errno = fs->err;
+ }
+ glfs_unlock(fs);
+
+ return ret;
}
-
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_init_done, 3.4.0)
void
-priv_glfs_init_done (struct glfs *fs, int ret)
+priv_glfs_init_done(struct glfs *fs, int ret)
{
- glfs_init_cbk init_cbk;
-
- if (!fs) {
- gf_msg ("glfs", GF_LOG_ERROR, EINVAL, API_MSG_GLFS_FSOBJ_NULL,
- "fs is NULL");
- goto out;
- }
-
- init_cbk = fs->init_cbk;
-
- /* Always a bottom-up call, use mutex_lock() */
- pthread_mutex_lock (&fs->mutex);
- {
- fs->init = 1;
- fs->ret = ret;
- fs->err = errno;
-
- if (!init_cbk)
- pthread_cond_broadcast (&fs->cond);
- }
- pthread_mutex_unlock (&fs->mutex);
-
- if (init_cbk)
- init_cbk (fs, ret);
+ glfs_init_cbk init_cbk;
+
+ if (!fs) {
+ gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_GLFS_FSOBJ_NULL, NULL);
+ goto out;
+ }
+
+ init_cbk = fs->init_cbk;
+
+ /* Always a bottom-up call, use mutex_lock() */
+ pthread_mutex_lock(&fs->mutex);
+ {
+ fs->init = 1;
+ fs->ret = ret;
+ fs->err = errno;
+
+ if (!init_cbk)
+ pthread_cond_broadcast(&fs->cond);
+ }
+ pthread_mutex_unlock(&fs->mutex);
+
+ if (init_cbk)
+ init_cbk(fs, ret);
out:
- return;
+ return;
}
-GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_init_done, 3.4.0);
+int
+glfs_init_common(struct glfs *fs)
+{
+ int ret = -1;
+
+ ret = create_master(fs);
+ if (ret)
+ return ret;
+
+ ret = gf_thread_create(&fs->poller, NULL, glfs_poller, fs, "glfspoll");
+ if (ret)
+ return ret;
+ ret = glfs_volumes_init(fs);
+ if (ret)
+ return ret;
+
+ fs->dev_id = gf_dm_hashfn(fs->volname, strlen(fs->volname));
+ return ret;
+}
int
-glfs_init_common (struct glfs *fs)
+glfs_init_async(struct glfs *fs, glfs_init_cbk cbk)
{
- int ret = -1;
+ int ret = -1;
- ret = create_master (fs);
- if (ret)
- return ret;
+ if (!fs || !fs->ctx) {
+ gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_FS_NOT_INIT, NULL);
+ errno = EINVAL;
+ return ret;
+ }
- ret = gf_thread_create (&fs->poller, NULL, glfs_poller, fs);
- if (ret)
- return ret;
+ fs->init_cbk = cbk;
- ret = glfs_volumes_init (fs);
- if (ret)
- return ret;
+ ret = glfs_init_common(fs);
- fs->dev_id = gf_dm_hashfn (fs->volname, strlen (fs->volname));
- return ret;
+ return ret;
}
-
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_init, 3.4.0)
int
-glfs_init_async (struct glfs *fs, glfs_init_cbk cbk)
+pub_glfs_init(struct glfs *fs)
{
- int ret = -1;
+ int ret = -1;
+
+ DECLARE_OLD_THIS;
+
+ if (!fs || !fs->ctx) {
+ gf_smsg("glfs", GF_LOG_ERROR, EINVAL, API_MSG_FS_NOT_INIT, NULL);
+ errno = EINVAL;
+ return ret;
+ }
- if (!fs || !fs->ctx) {
- gf_msg ("glfs", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
- "fs is not properly initialized.");
- errno = EINVAL;
- return ret;
- }
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- fs->init_cbk = cbk;
+ ret = glfs_init_common(fs);
+ if (ret)
+ goto out;
+
+ ret = glfs_init_wait(fs);
+out:
+ __GLFS_EXIT_FS;
- ret = glfs_init_common (fs);
+ /* Set the initial current working directory to "/" */
+ if (ret >= 0) {
+ ret = glfs_chdir(fs, "/");
+ }
- return ret;
+invalid_fs:
+ return ret;
}
+static int
+glusterfs_ctx_destroy(glusterfs_ctx_t *ctx)
+{
+ call_pool_t *pool = NULL;
+ int ret = 0;
+ glusterfs_graph_t *trav_graph = NULL;
+ glusterfs_graph_t *tmp = NULL;
+
+ if (ctx == NULL)
+ return 0;
+
+ if (ctx->cmd_args.curr_server)
+ glfs_free_volfile_servers(&ctx->cmd_args);
+
+ glfs_free_xlator_options(&ctx->cmd_args);
+
+ /* For all the graphs, crawl through the xlator_t structs and free
+ * all its members except for the mem_acct member,
+ * as GF_FREE will be referencing it.
+ */
+ list_for_each_entry_safe(trav_graph, tmp, &ctx->graphs, list)
+ {
+ xlator_tree_free_members(trav_graph->first);
+ }
+
+ /* Free the memory pool */
+ if (ctx->stub_mem_pool)
+ mem_pool_destroy(ctx->stub_mem_pool);
+ if (ctx->dict_pool)
+ mem_pool_destroy(ctx->dict_pool);
+ if (ctx->dict_data_pool)
+ mem_pool_destroy(ctx->dict_data_pool);
+ if (ctx->dict_pair_pool)
+ mem_pool_destroy(ctx->dict_pair_pool);
+ if (ctx->logbuf_pool)
+ mem_pool_destroy(ctx->logbuf_pool);
+
+ pool = ctx->pool;
+ if (pool) {
+ if (pool->frame_mem_pool)
+ mem_pool_destroy(pool->frame_mem_pool);
+ if (pool->stack_mem_pool)
+ mem_pool_destroy(pool->stack_mem_pool);
+ LOCK_DESTROY(&pool->lock);
+ GF_FREE(pool);
+ }
+
+ /* Free the event pool */
+ ret = gf_event_pool_destroy(ctx->event_pool);
+
+ /* Free the iobuf pool */
+ iobuf_pool_destroy(ctx->iobuf_pool);
+
+ GF_FREE(ctx->process_uuid);
+ GF_FREE(ctx->cmd_args.volfile_id);
+ GF_FREE(ctx->cmd_args.process_name);
+
+ LOCK_DESTROY(&ctx->lock);
+ pthread_mutex_destroy(&ctx->notify_lock);
+ pthread_cond_destroy(&ctx->notify_cond);
+
+ /* Free all the graph structs and its containing xlator_t structs
+ * from this point there should be no reference to GF_FREE/GF_CALLOC
+ * as it will try to access mem_acct and the below function would
+ * have freed the same.
+ */
+ list_for_each_entry_safe(trav_graph, tmp, &ctx->graphs, list)
+ {
+ glusterfs_graph_destroy_residual(trav_graph);
+ }
+
+ GF_FREE(ctx->statedump_path);
+ FREE(ctx);
+
+ return ret;
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fini, 3.4.0)
int
-pub_glfs_init (struct glfs *fs)
+pub_glfs_fini(struct glfs *fs)
{
- int ret = -1;
+ int ret = -1;
+ int countdown = 100;
+ xlator_t *subvol = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *graph = NULL;
+ call_pool_t *call_pool = NULL;
+ int fs_init = 0;
+ int err = -1;
+ struct synctask *waittask = NULL;
+
+ DECLARE_OLD_THIS;
+
+ if (!fs) {
+ errno = EINVAL;
+ goto invalid_fs;
+ }
+
+ ctx = fs->ctx;
+ if (!ctx) {
+ goto free_fs;
+ }
+
+ THIS = fs->ctx->master;
+
+ if (ctx->mgmt) {
+ rpc_clnt_disable(ctx->mgmt);
+ }
+
+ call_pool = fs->ctx->pool;
+
+ /* Wake up any suspended synctasks */
+ while (!list_empty(&fs->waitq)) {
+ waittask = list_entry(fs->waitq.next, struct synctask, waitq);
+ list_del_init(&waittask->waitq);
+ synctask_wake(waittask);
+ }
+
+ while (countdown--) {
+ /* give some time for background frames to finish */
+ pthread_mutex_lock(&fs->mutex);
+ {
+ /* Do we need to increase countdown? */
+ if ((!call_pool->cnt) && (!fs->pin_refcnt)) {
+ gf_msg_trace("glfs", 0,
+ "call_pool_cnt - %" PRId64
+ ","
+ "pin_refcnt - %d",
+ call_pool->cnt, fs->pin_refcnt);
+
+ ctx->cleanup_started = 1;
+ pthread_mutex_unlock(&fs->mutex);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&fs->mutex);
+ gf_nanosleep(100000 * GF_US_IN_NS);
+ }
+
+ /* leaked frames may exist, we ignore */
+
+ /*We deem glfs_fini as successful if there are no pending frames in the call
+ *pool*/
+ ret = (call_pool->cnt == 0) ? 0 : -1;
+
+ pthread_mutex_lock(&fs->mutex);
+ {
+ fs_init = fs->init;
+ }
+ pthread_mutex_unlock(&fs->mutex);
+
+ if (fs_init != 0) {
+ subvol = glfs_active_subvol(fs);
+ if (subvol) {
+ /* PARENT_DOWN within glfs_subvol_done() is issued
+ only on graph switch (new graph should activiate
+ and decrement the extra @winds count taken in
+ glfs_graph_setup()
+
+ Since we are explicitly destroying,
+ PARENT_DOWN is necessary
+ */
+ xlator_notify(subvol, GF_EVENT_PARENT_DOWN, subvol, 0);
+ /* Here we wait for GF_EVENT_CHILD_DOWN before exiting,
+ in case of asynchrnous cleanup
+ */
+ graph = subvol->graph;
+ err = pthread_mutex_lock(&fs->mutex);
+ if (err != 0) {
+ gf_smsg("glfs", GF_LOG_ERROR, err, API_MSG_FSMUTEX_LOCK_FAILED,
+ "error=%s", strerror(err), NULL);
+ goto fail;
+ }
+ /* check and wait for CHILD_DOWN for active subvol*/
+ {
+ while (graph->used) {
+ err = pthread_cond_wait(&fs->child_down_cond, &fs->mutex);
+ if (err != 0)
+ gf_smsg("glfs", GF_LOG_INFO, err,
+ API_MSG_COND_WAIT_FAILED, "name=%s",
+ subvol->name, "err=%s", strerror(err), NULL);
+ }
+ }
+
+ err = pthread_mutex_unlock(&fs->mutex);
+ if (err != 0) {
+ gf_smsg("glfs", GF_LOG_ERROR, err,
+ API_MSG_FSMUTEX_UNLOCK_FAILED, "error=%s",
+ strerror(err), NULL);
+ goto fail;
+ }
+ }
+ glfs_subvol_done(fs, subvol);
+ }
+
+ ctx->cleanup_started = 1;
+
+ if (fs_init != 0) {
+ /* Destroy all the inode tables of all the graphs.
+ * NOTE:
+ * - inode objects should be destroyed before calling fini()
+ * of each xlator, as fini() and forget() of the xlators
+ * can share few common locks or data structures, calling
+ * fini first might destroy those required by forget
+ * ( eg: in quick-read)
+ * - The call to inode_table_destroy_all is not required when
+ * the cleanup during graph switch is implemented to perform
+ * inode table destroy.
+ */
+ inode_table_destroy_all(ctx);
+
+ /* Call fini() of all the xlators in the active graph
+ * NOTE:
+ * - xlator fini() should be called before destroying any of
+ * the threads. (eg: fini() in protocol-client uses timer
+ * thread) */
+ glusterfs_graph_deactivate(ctx->active);
+
+ /* Join the syncenv_processor threads and cleanup
+ * syncenv resources*/
+ syncenv_destroy(ctx->env);
+
+ /* Join the poller thread */
+ if (gf_event_dispatch_destroy(ctx->event_pool) < 0)
+ ret = -1;
+ }
+
+ /* Avoid dispatching events to mgmt after freed,
+ * unreference mgmt after the event_dispatch_destroy */
+ if (ctx->mgmt) {
+ rpc_clnt_unref(ctx->mgmt);
+ ctx->mgmt = NULL;
+ }
+
+ /* log infra has to be brought down before destroying
+ * timer registry, as logging uses timer infra
+ */
+ if (gf_log_fini(ctx) != 0)
+ ret = -1;
- DECLARE_OLD_THIS;
+ /* Join the timer thread */
+ if (fs_init != 0) {
+ gf_timer_registry_destroy(ctx);
+ }
- if (!fs || !fs->ctx) {
- gf_msg ("glfs", GF_LOG_ERROR, EINVAL, API_MSG_INVALID_ENTRY,
- "fs is not properly initialized.");
- errno = EINVAL;
- return ret;
- }
+ /* Destroy the context and the global pools */
+ if (glusterfs_ctx_destroy(ctx) != 0)
+ ret = -1;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+free_fs:
+ glfs_free_from_ctx(fs);
- ret = glfs_init_common (fs);
- if (ret)
- goto out;
+ /*
+ * Do this as late as possible in case anything else has (or
+ * grows) a dependency on mem-pool allocations.
+ */
+ mem_pools_fini();
- ret = glfs_init_wait (fs);
-out:
- __GLFS_EXIT_FS;
+fail:
+ if (!ret)
+ ret = err;
- /* Set the initial current working directory to "/" */
- if (ret >= 0) {
- ret = glfs_chdir (fs, "/");
- }
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_init, 3.4.0);
-
-static int
-glusterfs_ctx_destroy (glusterfs_ctx_t *ctx)
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volfile, 3.6.0)
+ssize_t
+pub_glfs_get_volfile(struct glfs *fs, void *buf, size_t len)
{
- call_pool_t *pool = NULL;
- int ret = 0;
- glusterfs_graph_t *trav_graph = NULL;
- glusterfs_graph_t *tmp = NULL;
+ ssize_t res = -1;
- if (ctx == NULL)
- return 0;
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- /* For all the graphs, crawl through the xlator_t structs and free
- * all its members except for the mem_acct member,
- * as GF_FREE will be referencing it.
- */
- list_for_each_entry_safe (trav_graph, tmp, &ctx->graphs, list) {
- xlator_tree_free_members (trav_graph->first);
- }
+ glfs_lock(fs, _gf_true);
+ if (len >= fs->oldvollen) {
+ gf_msg_trace("glfs", 0, "copying %zu to %p", len, buf);
+ memcpy(buf, fs->oldvolfile, len);
+ res = len;
+ } else {
+ res = len - fs->oldvollen;
+ gf_msg_trace("glfs", 0, "buffer is %zd too short", -res);
+ }
+ glfs_unlock(fs);
- /* Free the memory pool */
- if (ctx->stub_mem_pool)
- mem_pool_destroy (ctx->stub_mem_pool);
- if (ctx->dict_pool)
- mem_pool_destroy (ctx->dict_pool);
- if (ctx->dict_data_pool)
- mem_pool_destroy (ctx->dict_data_pool);
- if (ctx->dict_pair_pool)
- mem_pool_destroy (ctx->dict_pair_pool);
- if (ctx->logbuf_pool)
- mem_pool_destroy (ctx->logbuf_pool);
-
- pool = ctx->pool;
- if (pool) {
- if (pool->frame_mem_pool)
- mem_pool_destroy (pool->frame_mem_pool);
- if (pool->stack_mem_pool)
- mem_pool_destroy (pool->stack_mem_pool);
- LOCK_DESTROY (&pool->lock);
- GF_FREE (pool);
- }
+ __GLFS_EXIT_FS;
- /* Free the event pool */
- ret = event_pool_destroy (ctx->event_pool);
+invalid_fs:
+ return res;
+}
- /* Free the iobuf pool */
- iobuf_pool_destroy (ctx->iobuf_pool);
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_ipc, 3.12.0)
+int
+priv_glfs_ipc(struct glfs *fs, int opcode, void *xd_in, void **xd_out)
+{
+ xlator_t *subvol = NULL;
+ int ret = -1;
- GF_FREE (ctx->process_uuid);
- GF_FREE (ctx->cmd_args.volfile_id);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- pthread_mutex_destroy (&(ctx->lock));
- pthread_mutex_destroy (&(ctx->notify_lock));
- pthread_cond_destroy (&(ctx->notify_cond));
+ subvol = glfs_active_subvol(fs);
+ if (!subvol) {
+ ret = -1;
+ errno = EIO;
+ goto out;
+ }
- /* Free all the graph structs and its containing xlator_t structs
- * from this point there should be no reference to GF_FREE/GF_CALLOC
- * as it will try to access mem_acct and the below funtion would
- * have freed the same.
- */
- list_for_each_entry_safe (trav_graph, tmp, &ctx->graphs, list) {
- glusterfs_graph_destroy_residual (trav_graph);
- }
+ ret = syncop_ipc(subvol, opcode, (dict_t *)xd_in, (dict_t **)xd_out);
+ DECODE_SYNCOP_ERR(ret);
- FREE (ctx);
+out:
+ glfs_subvol_done(fs, subvol);
+ __GLFS_EXIT_FS;
- return ret;
+invalid_fs:
+ return ret;
}
+GFAPI_SYMVER_PRIVATE_DEFAULT(glfs_setfspid, 6.1)
int
-pub_glfs_fini (struct glfs *fs)
+priv_glfs_setfspid(struct glfs *fs, pid_t pid)
{
- int ret = -1;
- int countdown = 100;
- xlator_t *subvol = NULL;
- glusterfs_ctx_t *ctx = NULL;
- glusterfs_graph_t *graph = NULL;
- call_pool_t *call_pool = NULL;
- int fs_init = 0;
- int err = -1;
+ cmd_args_t *cmd_args = NULL;
+ int ret = 0;
- DECLARE_OLD_THIS;
+ cmd_args = &fs->ctx->cmd_args;
+ cmd_args->client_pid = pid;
+ cmd_args->client_pid_set = 1;
+ ret = syncopctx_setfspid(&pid);
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ return ret;
+}
- ctx = fs->ctx;
- if (!ctx) {
- goto free_fs;
- }
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_free, 3.7.16)
+void
+pub_glfs_free(void *ptr)
+{
+ GLFS_FREE(ptr);
+}
- if (ctx->mgmt) {
- rpc_clnt_disable (ctx->mgmt);
- ctx->mgmt = NULL;
- }
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_fs, 3.7.16)
+struct glfs *
+pub_glfs_upcall_get_fs(struct glfs_upcall *arg)
+{
+ return arg->fs;
+}
- call_pool = fs->ctx->pool;
-
- while (countdown--) {
- /* give some time for background frames to finish */
- pthread_mutex_lock (&fs->mutex);
- {
- /* Do we need to increase countdown? */
- if ((!call_pool->cnt) && (!fs->pin_refcnt)) {
- gf_msg_trace ("glfs", 0,
- "call_pool_cnt - %ld,"
- "pin_refcnt - %d",
- call_pool->cnt, fs->pin_refcnt);
-
- ctx->cleanup_started = 1;
- pthread_mutex_unlock (&fs->mutex);
- break;
- }
- }
- pthread_mutex_unlock (&fs->mutex);
- usleep (100000);
- }
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_reason, 3.7.16)
+enum glfs_upcall_reason
+pub_glfs_upcall_get_reason(struct glfs_upcall *arg)
+{
+ return arg->reason;
+}
- /* leaked frames may exist, we ignore */
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_get_event, 3.7.16)
+void *
+pub_glfs_upcall_get_event(struct glfs_upcall *arg)
+{
+ return arg->event;
+}
- /*We deem glfs_fini as successful if there are no pending frames in the call
- *pool*/
- ret = (call_pool->cnt == 0)? 0: -1;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_object, 3.7.16)
+struct glfs_object *
+pub_glfs_upcall_inode_get_object(struct glfs_upcall_inode *arg)
+{
+ return arg->object;
+}
- pthread_mutex_lock (&fs->mutex);
- {
- fs_init = fs->init;
- }
- pthread_mutex_unlock (&fs->mutex);
-
- if (fs_init != 0) {
- subvol = glfs_active_subvol (fs);
- if (subvol) {
- /* PARENT_DOWN within glfs_subvol_done() is issued
- only on graph switch (new graph should activiate
- and decrement the extra @winds count taken in
- glfs_graph_setup()
-
- Since we are explicitly destroying,
- PARENT_DOWN is necessary
- */
- xlator_notify (subvol, GF_EVENT_PARENT_DOWN, subvol, 0);
- /* Here we wait for GF_EVENT_CHILD_DOWN before exiting,
- in case of asynchrnous cleanup
- */
- graph = subvol->graph;
- err = pthread_mutex_lock (&fs->mutex);
- if (err != 0) {
- gf_msg ("glfs", GF_LOG_ERROR, err,
- API_MSG_FSMUTEX_LOCK_FAILED,
- "pthread lock on glfs mutex, "
- "returned error: (%s)", strerror (err));
- goto fail;
- }
- /* check and wait for CHILD_DOWN for active subvol*/
- {
- while (graph->used) {
- err = pthread_cond_wait (&fs->child_down_cond,
- &fs->mutex);
- if (err != 0)
- gf_msg ("glfs", GF_LOG_INFO, err,
- API_MSG_COND_WAIT_FAILED,
- "%s cond wait failed %s",
- subvol->name,
- strerror (err));
- }
- }
-
- err = pthread_mutex_unlock (&fs->mutex);
- if (err != 0) {
- gf_msg ("glfs", GF_LOG_ERROR, err,
- API_MSG_FSMUTEX_UNLOCK_FAILED,
- "pthread unlock on glfs mutex, "
- "returned error: (%s)", strerror (err));
- goto fail;
- }
- }
- glfs_subvol_done (fs, subvol);
- }
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_flags, 3.7.16)
+uint64_t
+pub_glfs_upcall_inode_get_flags(struct glfs_upcall_inode *arg)
+{
+ return arg->flags;
+}
- ctx->cleanup_started = 1;
-
- if (fs_init != 0) {
- /* Destroy all the inode tables of all the graphs.
- * NOTE:
- * - inode objects should be destroyed before calling fini()
- * of each xlator, as fini() and forget() of the xlators
- * can share few common locks or data structures, calling
- * fini first might destroy those required by forget
- * ( eg: in quick-read)
- * - The call to inode_table_destroy_all is not required when
- * the cleanup during graph switch is implemented to perform
- * inode table destroy.
- */
- inode_table_destroy_all (ctx);
-
- /* Call fini() of all the xlators in the active graph
- * NOTE:
- * - xlator fini() should be called before destroying any of
- * the threads. (eg: fini() in protocol-client uses timer
- * thread) */
- glusterfs_graph_deactivate (ctx->active);
-
- /* Join the syncenv_processor threads and cleanup
- * syncenv resources*/
- syncenv_destroy (ctx->env);
-
- /* Join the poller thread */
- if (event_dispatch_destroy (ctx->event_pool) != 0)
- ret = -1;
- }
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_stat, 3.7.16)
+struct stat *
+pub_glfs_upcall_inode_get_stat(struct glfs_upcall_inode *arg)
+{
+ return &arg->buf;
+}
- /* log infra has to be brought down before destroying
- * timer registry, as logging uses timer infra
- */
- if (gf_log_fini (ctx) != 0)
- ret = -1;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_expire, 3.7.16)
+uint64_t
+pub_glfs_upcall_inode_get_expire(struct glfs_upcall_inode *arg)
+{
+ return arg->expire_time_attr;
+}
- /* Join the timer thread */
- if (fs_init != 0) {
- gf_timer_registry_destroy (ctx);
- }
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pobject, 3.7.16)
+struct glfs_object *
+pub_glfs_upcall_inode_get_pobject(struct glfs_upcall_inode *arg)
+{
+ return arg->p_object;
+}
- /* Destroy the context and the global pools */
- if (glusterfs_ctx_destroy (ctx) != 0)
- ret = -1;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_pstat, 3.7.16)
+struct stat *
+pub_glfs_upcall_inode_get_pstat(struct glfs_upcall_inode *arg)
+{
+ return &arg->p_buf;
+}
-free_fs:
- glfs_free_from_ctx (fs);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpobject, 3.7.16)
+struct glfs_object *
+pub_glfs_upcall_inode_get_oldpobject(struct glfs_upcall_inode *arg)
+{
+ return arg->oldp_object;
+}
-fail:
- if (!ret)
- ret = err;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_inode_get_oldpstat, 3.7.16)
+struct stat *
+pub_glfs_upcall_inode_get_oldpstat(struct glfs_upcall_inode *arg)
+{
+ return &arg->oldp_buf;
+}
- __GLFS_EXIT_FS;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_object, 4.1.6)
+struct glfs_object *
+pub_glfs_upcall_lease_get_object(struct glfs_upcall_lease *arg)
+{
+ return arg->object;
+}
-invalid_fs:
- return ret;
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_lease_get_lease_type, 4.1.6)
+uint32_t
+pub_glfs_upcall_lease_get_lease_type(struct glfs_upcall_lease *arg)
+{
+ return arg->lease_type;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fini, 3.4.0);
+/* definitions of the GLFS_SYSRQ_* chars are in glfs.h */
+static struct glfs_sysrq_help {
+ char sysrq;
+ char *msg;
+} glfs_sysrq_help[] = {{GLFS_SYSRQ_HELP, "(H)elp"},
+ {GLFS_SYSRQ_STATEDUMP, "(S)tatedump"},
+ {0, NULL}};
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_sysrq, 3.10.0)
+int
+pub_glfs_sysrq(struct glfs *fs, char sysrq)
+{
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = 0;
+ int msg_len;
+ char msg[1024] = {
+ 0,
+ }; /* should not exceed 1024 chars */
+
+ if (!fs || !fs->ctx) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ ctx = fs->ctx;
+ switch (sysrq) {
+ case GLFS_SYSRQ_HELP: {
+ struct glfs_sysrq_help *usage = NULL;
-ssize_t
-pub_glfs_get_volfile (struct glfs *fs, void *buf, size_t len)
+ for (usage = glfs_sysrq_help; usage->sysrq; usage++) {
+ msg_len = strlen(msg);
+ snprintf(msg + msg_len, /* append to msg */
+ sizeof(msg) - msg_len - 2,
+ /* - 2 for the " " + terminating \0 */
+ " %s", usage->msg);
+ }
+
+ /* not really an 'error', but make sure it gets logged */
+ gf_log("glfs", GF_LOG_ERROR, "available events: %s", msg);
+
+ break;
+ }
+ case GLFS_SYSRQ_STATEDUMP:
+ gf_proc_dump_info(SIGUSR1, ctx);
+ break;
+ default:
+ gf_smsg("glfs", GF_LOG_ERROR, ENOTSUP, API_MSG_INVALID_SYSRQ,
+ "sysrq=%c", sysrq, NULL);
+ errno = ENOTSUP;
+ ret = -1;
+ }
+out:
+ return ret;
+}
+
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_register, 3.13.0)
+int
+pub_glfs_upcall_register(struct glfs *fs, uint32_t event_list,
+ glfs_upcall_cbk cbk, void *data)
{
- ssize_t res = -1;
+ int ret = 0;
+
+ /* list of supported upcall events */
+ uint32_t up_events = (GLFS_EVENT_INODE_INVALIDATE |
+ GLFS_EVENT_RECALL_LEASE);
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
- glfs_lock(fs);
- if (len >= fs->oldvollen) {
- gf_msg_trace ("glfs", 0, "copying %zu to %p", len, buf);
- memcpy(buf,fs->oldvolfile,len);
- res = len;
+ GF_VALIDATE_OR_GOTO(THIS->name, cbk, out);
+
+ /* Event list should be either GLFS_EVENT_ANY
+ * or list of supported individual events (up_events)
+ */
+ if ((event_list != GLFS_EVENT_ANY) && (event_list & ~up_events)) {
+ errno = EINVAL;
+ ret = -1;
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ARG,
+ "event_list=(0x%08x)", event_list, NULL);
+ goto out;
+ }
+
+ /* in case other thread does unregister */
+ pthread_mutex_lock(&fs->mutex);
+ {
+ if (event_list & GLFS_EVENT_INODE_INVALIDATE) {
+ /* @todo: Check if features.cache-invalidation is
+ * enabled.
+ */
+ fs->upcall_events |= GF_UPCALL_CACHE_INVALIDATION;
+ ret |= GLFS_EVENT_INODE_INVALIDATE;
}
- else {
- res = len - fs->oldvollen;
- gf_msg_trace ("glfs", 0, "buffer is %zd too short", -res);
+ if (event_list & GLFS_EVENT_RECALL_LEASE) {
+ /* @todo: Check if features.leases is enabled */
+ fs->upcall_events |= GF_UPCALL_RECALL_LEASE;
+ ret |= GLFS_EVENT_RECALL_LEASE;
}
- glfs_unlock(fs);
+ /* Override cbk function if existing */
+ fs->up_cbk = cbk;
+ fs->up_data = data;
+ fs->cache_upcalls = _gf_true;
+ }
+ pthread_mutex_unlock(&fs->mutex);
- __GLFS_EXIT_FS;
+out:
+ __GLFS_EXIT_FS;
invalid_fs:
- return res;
+ return ret;
}
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_get_volfile, 3.6.0);
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_upcall_unregister, 3.13.0)
+int
+pub_glfs_upcall_unregister(struct glfs *fs, uint32_t event_list)
+{
+ int ret = 0;
+ /* list of supported upcall events */
+ uint32_t up_events = (GLFS_EVENT_INODE_INVALIDATE |
+ GLFS_EVENT_RECALL_LEASE);
+
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ /* Event list should be either GLFS_EVENT_ANY
+ * or list of supported individual events (up_events)
+ */
+ if ((event_list != GLFS_EVENT_ANY) && (event_list & ~up_events)) {
+ errno = EINVAL;
+ ret = -1;
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ARG,
+ "event_list=(0x%08x)", event_list, NULL);
+ goto out;
+ }
+
+ pthread_mutex_lock(&fs->mutex);
+ {
+ /* We already checked if event_list contains list of supported
+ * upcall events. No other specific checks needed as of now for
+ * unregister */
+ fs->upcall_events &= ~(event_list);
+ ret |= ((event_list == GLFS_EVENT_ANY) ? up_events : event_list);
+
+ /* If there are no upcall events registered, reset cbk */
+ if (fs->upcall_events == 0) {
+ fs->up_cbk = NULL;
+ fs->up_data = NULL;
+ fs->cache_upcalls = _gf_false;
+ }
+ }
+ pthread_mutex_unlock(&fs->mutex);
+
+out:
+ __GLFS_EXIT_FS;
+
+invalid_fs:
+ return ret;
+}
+GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_set_statedump_path, 7.0)
int
-pub_glfs_ipc (struct glfs *fs, int opcode)
+pub_glfs_set_statedump_path(struct glfs *fs, const char *path)
{
- xlator_t *subvol = NULL;
- int ret = -1;
+ struct stat st;
+ int ret;
+ DECLARE_OLD_THIS;
+ __GLFS_ENTRY_VALIDATE_FS(fs, invalid_fs);
+
+ if (!path) {
+ gf_log("glfs", GF_LOG_ERROR, "path is NULL");
+ errno = EINVAL;
+ goto err;
+ }
+
+ /* If path is not present OR, if it is directory AND has enough permission
+ * to create files, then proceed */
+ ret = sys_stat(path, &st);
+ if (ret && errno != ENOENT) {
+ gf_log("glfs", GF_LOG_ERROR, "%s: not a valid path (%s)", path,
+ strerror(errno));
+ errno = EINVAL;
+ goto err;
+ }
+
+ if (!ret) {
+ /* file is present, now check other things */
+ if (!S_ISDIR(st.st_mode)) {
+ gf_log("glfs", GF_LOG_ERROR, "%s: path is not directory", path);
+ errno = EINVAL;
+ goto err;
+ }
+ if (sys_access(path, W_OK | X_OK) < 0) {
+ gf_log("glfs", GF_LOG_ERROR,
+ "%s: path doesn't have write permission", path);
+ errno = EPERM;
+ goto err;
+ }
+ }
- DECLARE_OLD_THIS;
- __GLFS_ENTRY_VALIDATE_FS (fs, invalid_fs);
+ /* If set, it needs to be freed, so we don't have leak */
+ GF_FREE(fs->ctx->statedump_path);
- subvol = glfs_active_subvol (fs);
- if (!subvol) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ fs->ctx->statedump_path = gf_strdup(path);
+ if (!fs->ctx->statedump_path) {
+ gf_log("glfs", GF_LOG_ERROR,
+ "%s: failed to set statedump path, no memory", path);
+ errno = ENOMEM;
+ goto err;
+ }
- ret = syncop_ipc (subvol, opcode, NULL, NULL);
- DECODE_SYNCOP_ERR (ret);
+ __GLFS_EXIT_FS;
-out:
- glfs_subvol_done (fs, subvol);
- __GLFS_EXIT_FS;
+ return 0;
+err:
+ __GLFS_EXIT_FS;
invalid_fs:
- return ret;
+ return -1;
}
-
-GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_ipc, 3.7.0);
diff --git a/api/src/glfs.h b/api/src/glfs.h
index b073d8d1b17..279d11d58ee 100644
--- a/api/src/glfs.h
+++ b/api/src/glfs.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2012-2018 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
@@ -8,7 +8,6 @@
cases as published by the Free Software Foundation.
*/
-
#ifndef _GLFS_H
#define _GLFS_H
@@ -21,6 +20,17 @@
both the library and the application.
*/
+/* Values for valid flags to be used when using XXXsetattr, to set multiple
+ attribute values passed via the related stat structure.
+ */
+
+#define GFAPI_SET_ATTR_MODE 0x1
+#define GFAPI_SET_ATTR_UID 0x2
+#define GFAPI_SET_ATTR_GID 0x4
+#define GFAPI_SET_ATTR_SIZE 0x8
+#define GFAPI_SET_ATTR_ATIME 0x10
+#define GFAPI_SET_ATTR_MTIME 0x20
+
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
#endif
@@ -41,6 +51,40 @@
#include <sys/cdefs.h>
#include <dirent.h>
#include <sys/statvfs.h>
+#include <stdint.h>
+#include <sys/time.h>
+
+/*
+ * For off64_t to be defined, we need both
+ * __USE_LARGEFILE64 to be true and __off64_t_defnined to be
+ * false. But, making __USE_LARGEFILE64 true causes other issues
+ * such as redinition of stat and fstat to stat64 and fstat64
+ * respectively which again causes compilation issues.
+ * Without off64_t being defined, this will not compile as
+ * copy_file_range uses off64_t. Hence define it here. First
+ * check whether __off64_t_defined is true or not. <unistd.h>
+ * sets that flag when it defines off64_t. If __off64_t_defined
+ * is false and __USE_FILE_OFFSET64 is true, then go on to define
+ * off64_t using __off64_t.
+ */
+#ifndef GF_BSD_HOST_OS
+#if defined(__USE_FILE_OFFSET64) && !defined(__off64_t_defined)
+typedef __off64_t off64_t;
+#endif /* defined(__USE_FILE_OFFSET64) && !defined(__off64_t_defined) */
+#else
+#include <stdio.h>
+#ifndef _OFF64_T_DECLARED
+/*
+ * Including <stdio.h> (done above) should actually define
+ * _OFF64_T_DECLARED with off64_t data type being available
+ * for consumption. But, off64_t data type is not recognizable
+ * for FreeBSD versions less than 11. Hence, int64_t is typedefed
+ * to off64_t.
+ */
+#define _OFF64_T_DECLARED
+typedef int64_t off64_t;
+#endif /* _OFF64_T_DECLARED */
+#endif /* GF_BSD_HOST_OS */
#if defined(HAVE_SYS_ACL_H) || (defined(USE_POSIX_ACLS) && USE_POSIX_ACLS)
#include <sys/acl.h>
@@ -51,19 +95,20 @@ typedef int acl_type_t;
/* Portability non glibc c++ build systems */
#ifndef __THROW
-# if defined __cplusplus
-# define __THROW throw ()
-# else
-# define __THROW
-# endif
+#if defined __cplusplus
+#define __THROW throw()
+#else
+#define __THROW
+#endif
#endif
#ifndef GF_DARWIN_HOST_OS
-#define GFAPI_PUBLIC(sym, ver) /**/
+#define GFAPI_PUBLIC(sym, ver) /**/
#define GFAPI_PRIVATE(sym, ver) /**/
#else
#define GFAPI_PUBLIC(sym, ver) __asm("_" __STRING(sym) "$GFAPI_" __STRING(ver))
-#define GFAPI_PRIVATE(sym, ver) __asm("_" __STRING(sym) "$GFAPI_PRIVATE_" __STRING(ver))
+#define GFAPI_PRIVATE(sym, ver) \
+ __asm("_" __STRING(sym) "$GFAPI_PRIVATE_" __STRING(ver))
#endif
__BEGIN_DECLS
@@ -72,7 +117,6 @@ __BEGIN_DECLS
struct glfs;
typedef struct glfs glfs_t;
-
/*
SYNOPSIS
@@ -93,8 +137,8 @@ typedef struct glfs glfs_t;
@volname: Name of the volume. This identifies the server-side volume and
the fetched volfile (equivalent of --volfile-id command line
- parameter to glusterfsd). When used with glfs_set_volfile() the
- @volname has no effect (except for appearing in log messages).
+ parameter to glusterfsd). When used with glfs_set_volfile() the
+ @volname has no effect (except for appearing in log messages).
RETURN VALUES
@@ -103,9 +147,8 @@ typedef struct glfs glfs_t;
*/
-glfs_t *glfs_new (const char *volname) __THROW
- GFAPI_PUBLIC(glfs_new, 3.4.0);
-
+glfs_t *
+glfs_new(const char *volname) __THROW GFAPI_PUBLIC(glfs_new, 3.4.0);
/*
SYNOPSIS
@@ -134,9 +177,9 @@ glfs_t *glfs_new (const char *volname) __THROW
*/
-int glfs_set_volfile (glfs_t *fs, const char *volfile) __THROW
- GFAPI_PUBLIC(glfs_set_volfile, 3.4.0);
-
+int
+glfs_set_volfile(glfs_t *fs, const char *volfile) __THROW
+ GFAPI_PUBLIC(glfs_set_volfile, 3.4.0);
/*
SYNOPSIS
@@ -161,15 +204,16 @@ int glfs_set_volfile (glfs_t *fs, const char *volfile) __THROW
specification file.
@transport: String specifying the transport used to connect to the
- management daemon. Specifying NULL will result in the usage
- of the default (tcp) transport type. Permitted values
- are those what you specify as transport-type in a volume
- specification file (e.g "tcp", "rdma" etc.)
+ management daemon. Specifying NULL will result in the
+ usage of the default (tcp) transport type. Permitted
+ values are "tcp" or "unix".
@host: String specifying the address where to find the management daemon.
+ Socket path, while using Unix domain socket as transport type.
This would either be
- - FQDN (e.g: "storage01.company.com") or
- - ASCII (e.g: "192.168.22.1")
+ - FQDN (e.g : "storage01.company.com") or
+ - ASCII (e.g : "192.168.22.1") or
+ - Socket path (e.g : "/var/run/glusterd.socket")
NOTE: This API is special, multiple calls to this function with different
volfile servers, port or transport-type would create a list of volfile
@@ -186,12 +230,15 @@ int glfs_set_volfile (glfs_t *fs, const char *volfile) __THROW
*/
-int glfs_set_volfile_server (glfs_t *fs, const char *transport,
- const char *host, int port) __THROW
- GFAPI_PUBLIC(glfs_set_volfile_server, 3.4.0);
-int glfs_unset_volfile_server (glfs_t *fs, const char *transport,
- const char *host, int port) __THROW
- GFAPI_PUBLIC(glfs_unset_volfile_server, 3.5.1);
+int
+glfs_set_volfile_server(glfs_t *fs, const char *transport, const char *host,
+ int port) __THROW
+ GFAPI_PUBLIC(glfs_set_volfile_server, 3.4.0);
+
+int
+glfs_unset_volfile_server(glfs_t *fs, const char *transport, const char *host,
+ int port) __THROW
+ GFAPI_PUBLIC(glfs_unset_volfile_server, 3.5.1);
/*
SYNOPSIS
@@ -221,9 +268,9 @@ int glfs_unset_volfile_server (glfs_t *fs, const char *transport,
*/
-int glfs_set_logging (glfs_t *fs, const char *logfile, int loglevel) __THROW
- GFAPI_PUBLIC(glfs_set_logging, 3.4.0);
-
+int
+glfs_set_logging(glfs_t *fs, const char *logfile, int loglevel) __THROW
+ GFAPI_PUBLIC(glfs_set_logging, 3.4.0);
/*
SYNOPSIS
@@ -249,9 +296,8 @@ int glfs_set_logging (glfs_t *fs, const char *logfile, int loglevel) __THROW
*/
-int glfs_init (glfs_t *fs) __THROW
- GFAPI_PUBLIC(glfs_init, 3.4.0);
-
+int
+glfs_init(glfs_t *fs) __THROW GFAPI_PUBLIC(glfs_init, 3.4.0);
/*
SYNOPSIS
@@ -283,8 +329,8 @@ int glfs_init (glfs_t *fs) __THROW
0 : Success.
*/
-int glfs_fini (glfs_t *fs) __THROW
- GFAPI_PUBLIC(glfs_fini, 3.4.0);
+int
+glfs_fini(glfs_t *fs) __THROW GFAPI_PUBLIC(glfs_fini, 3.4.0);
/*
SYNOPSIS
@@ -314,9 +360,9 @@ int glfs_fini (glfs_t *fs) __THROW
<0: volfile length exceeds @len by N bytes (@buf unchanged)
*/
-ssize_t glfs_get_volfile (glfs_t *fs, void *buf, size_t len) __THROW
- GFAPI_PUBLIC(glfs_get_volfile, 3.6.0);
-
+ssize_t
+glfs_get_volfile(glfs_t *fs, void *buf, size_t len) __THROW
+ GFAPI_PUBLIC(glfs_get_volfile, 3.6.0);
/*
SYNOPSIS
@@ -329,9 +375,9 @@ ssize_t glfs_get_volfile (glfs_t *fs, void *buf, size_t len) __THROW
the management server (glusterd) to fetch volume uuid and stores it
in the glusterfs_context linked to the glfs object fs which can be used
in the subsequent calls. Later it parses that UUID to convert it from
- cannonical string format into an opaque byte array and copy it into
- the volid array. Incase if either of the input parameters, volid or size,
- is NULL, number of bytes required to copy the volume UUID is returned.
+ canonical string format into an opaque byte array and copy it into
+ the volid array. In case if either of the input parameters, volid or
+ size, is NULL, number of bytes required to copy the volume UUID is returned.
PARAMETERS
@@ -346,9 +392,9 @@ ssize_t glfs_get_volfile (glfs_t *fs, void *buf, size_t len) __THROW
Others : length of the volume UUID stored.
*/
-int glfs_get_volumeid (struct glfs *fs, char *volid, size_t size) __THROW
- GFAPI_PUBLIC(glfs_get_volumeid, 3.5.0);
-
+int
+glfs_get_volumeid(glfs_t *fs, char *volid, size_t size) __THROW
+ GFAPI_PUBLIC(glfs_get_volumeid, 3.5.0);
/*
* FILE OPERATION
@@ -370,6 +416,119 @@ struct glfs_fd;
typedef struct glfs_fd glfs_fd_t;
/*
+ * Mask for request/result items in the struct glfs_stat.
+ *
+ * Query request/result mask for glfs_stat() (family of functions) and
+ * struct glfs_stat::glfs_st_mask.
+ *
+ * These bits should be set in the mask argument of glfs_stat() (family of
+ * functions) to request particular items when calling glfs_stat().
+ *
+ * NOTE: Lower order 32 bits are used to reflect statx(2) bits. For Gluster
+ * specific attrs/extensions, use higher order 32 bits.
+ *
+ */
+#define GLFS_STAT_TYPE 0x0000000000000001U /* Want/got stx_mode & S_IFMT */
+#define GLFS_STAT_MODE 0x0000000000000002U /* Want/got stx_mode & ~S_IFMT */
+#define GLFS_STAT_NLINK 0x0000000000000004U /* Want/got stx_nlink */
+#define GLFS_STAT_UID 0x0000000000000008U /* Want/got stx_uid */
+#define GLFS_STAT_GID 0x0000000000000010U /* Want/got stx_gid */
+#define GLFS_STAT_ATIME 0x0000000000000020U /* Want/got stx_atime */
+#define GLFS_STAT_MTIME 0x0000000000000040U /* Want/got stx_mtime */
+#define GLFS_STAT_CTIME 0x0000000000000080U /* Want/got stx_ctime */
+#define GLFS_STAT_INO 0x0000000000000100U /* Want/got stx_ino */
+#define GLFS_STAT_SIZE 0x0000000000000200U /* Want/got stx_size */
+#define GLFS_STAT_BLOCKS 0x0000000000000400U /* Want/got stx_blocks */
+#define GLFS_STAT_BASIC_STATS \
+ 0x00000000000007ffU /* Items in the normal stat struct */
+#define GLFS_STAT_BTIME 0x0000000000000800U /* Want/got stx_btime */
+#define GLFS_STAT_ALL 0x0000000000000fffU /* All currently supported flags */
+#define GLFS_STAT_RESERVED \
+ 0x8000000000000000U /* Reserved to denote future expansion */
+
+/* Macros for checking validity of struct glfs_stat members.*/
+#define GLFS_STAT_TYPE_VALID(stmask) (stmask & GLFS_STAT_TYPE)
+#define GLFS_STAT_MODE_VALID(stmask) (stmask & GLFS_STAT_MODE)
+#define GLFS_STAT_NLINK_VALID(stmask) (stmask & GLFS_STAT_NLINK)
+#define GLFS_STAT_UID_VALID(stmask) (stmask & GLFS_STAT_UID)
+#define GLFS_STAT_GID_VALID(stmask) (stmask & GLFS_STAT_GID)
+#define GLFS_STAT_ATIME_VALID(stmask) (stmask & GLFS_STAT_ATIME)
+#define GLFS_STAT_MTIME_VALID(stmask) (stmask & GLFS_STAT_MTIME)
+#define GLFS_STAT_CTIME_VALID(stmask) (stmask & GLFS_STAT_CTIME)
+#define GLFS_STAT_INO_VALID(stmask) (stmask & GLFS_STAT_INO)
+#define GLFS_STAT_SIZE_VALID(stmask) (stmask & GLFS_STAT_SIZE)
+#define GLFS_STAT_BLOCKS_VALID(stmask) (stmask & GLFS_STAT_BLOCKS)
+#define GLFS_STAT_BTIME_VALID(stmask) (stmask & GLFS_STAT_BTIME)
+#define GLFS_STAT_GFID_VALID(stmask) (stmask & GLFS_STAT_GFID)
+
+/*
+ * Attributes to be found in glfs_st_attributes and masked in
+ * glfs_st_attributes_mask.
+ *
+ * These give information about the features or the state of a file that might
+ * be of use to programs.
+ *
+ * NOTE: Lower order 32 bits are used to reflect statx(2) attribute bits. For
+ * Gluster specific attrs, use higher order 32 bits.
+ *
+ * NOTE: We do not support any file attributes or state as yet!
+ */
+#define GLFS_STAT_ATTR_RESERVED \
+ 0x8000000000000000U /* Reserved to denote future expansion */
+
+/* Extended file attribute structure.
+ *
+ * The caller passes a mask of what they're specifically interested in as a
+ * parameter to glfs_stat(). What glfs_stat() actually got will be indicated
+ * in glfs_st_mask upon return.
+ *
+ * For each bit in the mask argument:
+ *
+ * - if the datum is not supported:
+ *
+ * - the bit will be cleared, and
+ *
+ * - the datum value is undefined
+ *
+ * - otherwise, if explicitly requested:
+ *
+ * - the field will be filled in and the bit will be set;
+ *
+ * - otherwise, if not requested, but available in, it will be filled in
+ * anyway, and the bit will be set upon return;
+ *
+ * - otherwise the field and the bit will be cleared before returning.
+ *
+ */
+
+struct glfs_stat {
+ uint64_t glfs_st_mask; /* What results were written [uncond] */
+ uint64_t glfs_st_attributes; /* Flags conveying information about the file
+ [uncond] */
+ uint64_t glfs_st_attributes_mask; /* Mask to show what's supported in
+ st_attributes [ucond] */
+ struct timespec glfs_st_atime; /* Last access time */
+ struct timespec glfs_st_btime; /* File creation time */
+ struct timespec glfs_st_ctime; /* Last attribute change time */
+ struct timespec glfs_st_mtime; /* Last data modification time */
+ ino_t glfs_st_ino; /* Inode number */
+ off_t glfs_st_size; /* File size */
+ blkcnt_t glfs_st_blocks; /* Number of 512-byte blocks allocated */
+ uint32_t glfs_st_rdev_major; /* Device ID of special file [if bdev/cdev] */
+ uint32_t glfs_st_rdev_minor;
+ uint32_t glfs_st_dev_major; /* ID of device containing file [uncond] */
+ uint32_t glfs_st_dev_minor;
+ blksize_t glfs_st_blksize; /* Preferred general I/O size [uncond] */
+ nlink_t glfs_st_nlink; /* Number of hard links */
+ uid_t glfs_st_uid; /* User ID of owner */
+ gid_t glfs_st_gid; /* Group ID of owner */
+ mode_t glfs_st_mode; /* File mode */
+};
+
+#define GLFS_LEASE_ID_SIZE 16 /* 128bits */
+typedef char glfs_leaseid_t[GLFS_LEASE_ID_SIZE];
+
+/*
* PER THREAD IDENTITY MODIFIERS
*
* The following operations enable to set a per thread identity context
@@ -386,18 +545,27 @@ typedef struct glfs_fd glfs_fd_t;
* caller
* - The groups once set, need to be unset by setting the size to 0 (in which
* case the list argument is a do not care)
+ * - In case of leases feature enables, setfsleaseid is used to set and reset
+ * leaseid before and after every I/O operation.
* - Once a process for a thread of operation choses to set the IDs, all glfs
* calls made from that thread would default to the IDs set for the thread.
* As a result use these APIs with care and ensure that the set IDs are
* reverted to global process defaults as required.
*
*/
-int glfs_setfsuid (uid_t fsuid) __THROW
- GFAPI_PUBLIC(glfs_setfsuid, 3.4.2);
-int glfs_setfsgid (gid_t fsgid) __THROW
- GFAPI_PUBLIC(glfs_setfsgid, 3.4.2);
-int glfs_setfsgroups (size_t size, const gid_t *list) __THROW
- GFAPI_PUBLIC(glfs_setfsgroups, 3.4.2);
+int
+glfs_setfsuid(uid_t fsuid) __THROW GFAPI_PUBLIC(glfs_setfsuid, 3.4.2);
+
+int
+glfs_setfsgid(gid_t fsgid) __THROW GFAPI_PUBLIC(glfs_setfsgid, 3.4.2);
+
+int
+glfs_setfsgroups(size_t size, const gid_t *list) __THROW
+ GFAPI_PUBLIC(glfs_setfsgroups, 3.4.2);
+
+int
+glfs_setfsleaseid(glfs_leaseid_t leaseid) __THROW
+ GFAPI_PUBLIC(glfs_setfsleaseid, 4.0.0);
/*
SYNOPSIS
@@ -424,9 +592,9 @@ int glfs_setfsgroups (size_t size, const gid_t *list) __THROW
*/
-glfs_fd_t *glfs_open (glfs_t *fs, const char *path, int flags) __THROW
- GFAPI_PUBLIC(glfs_open, 3.4.0);
-
+glfs_fd_t *
+glfs_open(glfs_t *fs, const char *path, int flags) __THROW
+ GFAPI_PUBLIC(glfs_open, 3.4.0);
/*
SYNOPSIS
@@ -454,19 +622,20 @@ glfs_fd_t *glfs_open (glfs_t *fs, const char *path, int flags) __THROW
*/
-glfs_fd_t *glfs_creat (glfs_t *fs, const char *path, int flags,
- mode_t mode) __THROW
- GFAPI_PUBLIC(glfs_creat, 3.4.0);
+glfs_fd_t *
+glfs_creat(glfs_t *fs, const char *path, int flags, mode_t mode) __THROW
+ GFAPI_PUBLIC(glfs_creat, 3.4.0);
-int glfs_close (glfs_fd_t *fd) __THROW
- GFAPI_PUBLIC(glfs_close, 3.4.0);
+int
+glfs_close(glfs_fd_t *fd) __THROW GFAPI_PUBLIC(glfs_close, 3.4.0);
-glfs_t *glfs_from_glfd (glfs_fd_t *fd) __THROW
- GFAPI_PUBLIC(glfs_from_glfd, 3.4.0);
+glfs_t *
+glfs_from_glfd(glfs_fd_t *fd) __THROW GFAPI_PUBLIC(glfs_from_glfd, 3.4.0);
-int glfs_set_xlator_option (glfs_t *fs, const char *xlator, const char *key,
- const char *value) __THROW
- GFAPI_PUBLIC(glfs_set_xlator_options, 3.4.0);
+int
+glfs_set_xlator_option(glfs_t *fs, const char *xlator, const char *key,
+ const char *value) __THROW
+ GFAPI_PUBLIC(glfs_set_xlator_option, 3.4.0);
/*
@@ -489,292 +658,828 @@ int glfs_set_xlator_option (glfs_t *fs, const char *xlator, const char *key,
time of issuing the async IO call. This can be used by the
caller to differentiate different instances of the async requests
in a common callback function.
+
+ @prestat and @poststat are allocated on the stack, that are auto destroyed
+ post the callback function returns.
*/
-typedef void (*glfs_io_cbk) (glfs_fd_t *fd, ssize_t ret, void *data);
+typedef void (*glfs_io_cbk)(glfs_fd_t *fd, ssize_t ret,
+ struct glfs_stat *prestat,
+ struct glfs_stat *poststat, void *data);
// glfs_{read,write}[_async]
-ssize_t glfs_read (glfs_fd_t *fd, void *buf,
- size_t count, int flags) __THROW
- GFAPI_PUBLIC(glfs_read, 3.4.0);
-ssize_t glfs_write (glfs_fd_t *fd, const void *buf,
- size_t count, int flags) __THROW
- GFAPI_PUBLIC(glfs_write, 3.4.0);
-int glfs_read_async (glfs_fd_t *fd, void *buf, size_t count, int flags,
- glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_read_async, 3.4.0);
-int glfs_write_async (glfs_fd_t *fd, const void *buf, size_t count, int flags,
- glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_write_async, 3.4.0);
+ssize_t
+glfs_read(glfs_fd_t *fd, void *buf, size_t count, int flags) __THROW
+ GFAPI_PUBLIC(glfs_read, 3.4.0);
+
+ssize_t
+glfs_write(glfs_fd_t *fd, const void *buf, size_t count, int flags) __THROW
+ GFAPI_PUBLIC(glfs_write, 3.4.0);
+
+int
+glfs_read_async(glfs_fd_t *fd, void *buf, size_t count, int flags,
+ glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_read_async, 6.0);
+
+int
+glfs_write_async(glfs_fd_t *fd, const void *buf, size_t count, int flags,
+ glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_write_async, 6.0);
// glfs_{read,write}v[_async]
-ssize_t glfs_readv (glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
- int flags) __THROW
- GFAPI_PUBLIC(glfs_readv, 3.4.0);
-ssize_t glfs_writev (glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
- int flags) __THROW
- GFAPI_PUBLIC(glfs_writev, 3.4.0);
-int glfs_readv_async (glfs_fd_t *fd, const struct iovec *iov, int count,
- int flags, glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_readv_async, 3.4.0);
-int glfs_writev_async (glfs_fd_t *fd, const struct iovec *iov, int count,
- int flags, glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_writev_async, 3.4.0);
+ssize_t
+glfs_readv(glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
+ int flags) __THROW GFAPI_PUBLIC(glfs_readv, 3.4.0);
+
+ssize_t
+glfs_writev(glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
+ int flags) __THROW GFAPI_PUBLIC(glfs_writev, 3.4.0);
+
+int
+glfs_readv_async(glfs_fd_t *fd, const struct iovec *iov, int count, int flags,
+ glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_readv_async, 6.0);
+
+int
+glfs_writev_async(glfs_fd_t *fd, const struct iovec *iov, int count, int flags,
+ glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_writev_async, 6.0);
// glfs_p{read,write}[_async]
-ssize_t glfs_pread (glfs_fd_t *fd, void *buf, size_t count, off_t offset,
- int flags) __THROW
- GFAPI_PUBLIC(glfs_pread, 3.4.0);
-ssize_t glfs_pwrite (glfs_fd_t *fd, const void *buf, size_t count,
- off_t offset, int flags) __THROW
- GFAPI_PUBLIC(glfs_pwrite, 3.4.0);
-int glfs_pread_async (glfs_fd_t *fd, void *buf, size_t count, off_t offset,
- int flags, glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_pread_async, 3.4.0);
-int glfs_pwrite_async (glfs_fd_t *fd, const void *buf, int count, off_t offset,
- int flags, glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_pwrite_async, 3.4.0);
+ssize_t
+glfs_pread(glfs_fd_t *fd, void *buf, size_t count, off_t offset, int flags,
+ struct glfs_stat *poststat) __THROW GFAPI_PUBLIC(glfs_pread, 6.0);
+
+ssize_t
+glfs_pwrite(glfs_fd_t *fd, const void *buf, size_t count, off_t offset,
+ int flags, struct glfs_stat *prestat,
+ struct glfs_stat *poststat) __THROW GFAPI_PUBLIC(glfs_pwrite, 6.0);
+
+int
+glfs_pread_async(glfs_fd_t *fd, void *buf, size_t count, off_t offset,
+ int flags, glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_pread_async, 6.0);
+
+int
+glfs_pwrite_async(glfs_fd_t *fd, const void *buf, int count, off_t offset,
+ int flags, glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_pwrite_async, 6.0);
// glfs_p{read,write}v[_async]
-ssize_t glfs_preadv (glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
- off_t offset, int flags) __THROW
- GFAPI_PUBLIC(glfs_preadv, 3.4.0);
-ssize_t glfs_pwritev (glfs_fd_t *fd, const struct iovec *iov, int iovcnt,
- off_t offset, int flags) __THROW
- GFAPI_PUBLIC(glfs_pwritev, 3.4.0);
-int glfs_preadv_async (glfs_fd_t *fd, const struct iovec *iov,
- int count, off_t offset, int flags,
- glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_preadv_async, 3.4.0);
-int glfs_pwritev_async (glfs_fd_t *fd, const struct iovec *iov,
- int count, off_t offset, int flags,
- glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_pwritev_async, 3.4.0);
+ssize_t
+glfs_preadv(glfs_fd_t *fd, const struct iovec *iov, int iovcnt, off_t offset,
+ int flags) __THROW GFAPI_PUBLIC(glfs_preadv, 3.4.0);
+
+ssize_t
+glfs_pwritev(glfs_fd_t *fd, const struct iovec *iov, int iovcnt, off_t offset,
+ int flags) __THROW GFAPI_PUBLIC(glfs_pwritev, 3.4.0);
+
+int
+glfs_preadv_async(glfs_fd_t *fd, const struct iovec *iov, int count,
+ off_t offset, int flags, glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_preadv_async, 6.0);
+
+int
+glfs_pwritev_async(glfs_fd_t *fd, const struct iovec *iov, int count,
+ off_t offset, int flags, glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_pwritev_async, 6.0);
+
+off_t
+glfs_lseek(glfs_fd_t *fd, off_t offset, int whence) __THROW
+ GFAPI_PUBLIC(glfs_lseek, 3.4.0);
+
+ssize_t
+glfs_copy_file_range(struct glfs_fd *glfd_in, off64_t *off_in,
+ struct glfs_fd *glfd_out, off64_t *off_out, size_t len,
+ unsigned int flags, struct glfs_stat *statbuf,
+ struct glfs_stat *prestat,
+ struct glfs_stat *poststat) __THROW
+ GFAPI_PUBLIC(glfs_copy_file_range, 6.0);
+
+int
+glfs_truncate(glfs_t *fs, const char *path, off_t length) __THROW
+ GFAPI_PUBLIC(glfs_truncate, 3.7.15);
+
+int
+glfs_ftruncate(glfs_fd_t *fd, off_t length, struct glfs_stat *prestat,
+ struct glfs_stat *poststat) __THROW
+ GFAPI_PUBLIC(glfs_ftruncate, 6.0);
+
+int
+glfs_ftruncate_async(glfs_fd_t *fd, off_t length, glfs_io_cbk fn,
+ void *data) __THROW
+ GFAPI_PUBLIC(glfs_ftruncate_async, 6.0);
+
+int
+glfs_lstat(glfs_t *fs, const char *path, struct stat *buf) __THROW
+ GFAPI_PUBLIC(glfs_lstat, 3.4.0);
+
+int
+glfs_stat(glfs_t *fs, const char *path, struct stat *buf) __THROW
+ GFAPI_PUBLIC(glfs_stat, 3.4.0);
+
+int
+glfs_fstat(glfs_fd_t *fd, struct stat *buf) __THROW
+ GFAPI_PUBLIC(glfs_fstat, 3.4.0);
+
+int
+glfs_fsync(glfs_fd_t *fd, struct glfs_stat *prestat,
+ struct glfs_stat *poststat) __THROW GFAPI_PUBLIC(glfs_fsync, 6.0);
+
+int
+glfs_fsync_async(glfs_fd_t *fd, glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_fsync_async, 6.0);
+
+int
+glfs_fdatasync(glfs_fd_t *fd, struct glfs_stat *prestat,
+ struct glfs_stat *poststat) __THROW
+ GFAPI_PUBLIC(glfs_fdatasync, 6.0);
+
+int
+glfs_fdatasync_async(glfs_fd_t *fd, glfs_io_cbk fn, void *data) __THROW
+ GFAPI_PUBLIC(glfs_fdatasync_async, 6.0);
+
+int
+glfs_access(glfs_t *fs, const char *path, int mode) __THROW
+ GFAPI_PUBLIC(glfs_access, 3.4.0);
+
+int
+glfs_symlink(glfs_t *fs, const char *oldpath, const char *newpath) __THROW
+ GFAPI_PUBLIC(glfs_symlink, 3.4.0);
+
+int
+glfs_readlink(glfs_t *fs, const char *path, char *buf, size_t bufsiz) __THROW
+ GFAPI_PUBLIC(glfs_readlink, 3.4.0);
+
+int
+glfs_mknod(glfs_t *fs, const char *path, mode_t mode, dev_t dev) __THROW
+ GFAPI_PUBLIC(glfs_mknod, 3.4.0);
+
+int
+glfs_mkdir(glfs_t *fs, const char *path, mode_t mode) __THROW
+ GFAPI_PUBLIC(glfs_mkdir, 3.4.0);
+
+int
+glfs_unlink(glfs_t *fs, const char *path) __THROW
+ GFAPI_PUBLIC(glfs_unlink, 3.4.0);
+
+int
+glfs_rmdir(glfs_t *fs, const char *path) __THROW
+ GFAPI_PUBLIC(glfs_rmdir, 3.4.0);
+
+int
+glfs_rename(glfs_t *fs, const char *oldpath, const char *newpath) __THROW
+ GFAPI_PUBLIC(glfs_rename, 3.4.0);
+
+int
+glfs_link(glfs_t *fs, const char *oldpath, const char *newpath) __THROW
+ GFAPI_PUBLIC(glfs_link, 3.4.0);
+
+glfs_fd_t *
+glfs_opendir(glfs_t *fs, const char *path) __THROW
+ GFAPI_PUBLIC(glfs_opendir, 3.4.0);
+
+/*
+ * @glfs_readdir_r and @glfs_readdirplus_r ARE thread safe AND re-entrant,
+ * but the interface has ambiguity about the size of @dirent to be allocated
+ * before calling the APIs. 512 byte buffer (for @dirent) is sufficient for
+ * all known systems which are tested againt glusterfs/gfapi, but may be
+ * insufficient in the future.
+ */
+
+int
+glfs_readdir_r(glfs_fd_t *fd, struct dirent *dirent,
+ struct dirent **result) __THROW
+ GFAPI_PUBLIC(glfs_readdir_r, 3.4.0);
+
+int
+glfs_readdirplus_r(glfs_fd_t *fd, struct stat *stat, struct dirent *dirent,
+ struct dirent **result) __THROW
+ GFAPI_PUBLIC(glfs_readdirplus_r, 3.4.0);
+
+/*
+ * @glfs_readdir and @glfs_readdirplus are NEITHER thread safe NOR re-entrant
+ * when called on the same directory handle. However they ARE thread safe
+ * AND re-entrant when called on different directory handles (which may be
+ * referring to the same directory too.)
+ */
+
+struct dirent *
+glfs_readdir(glfs_fd_t *fd) __THROW GFAPI_PUBLIC(glfs_readdir, 3.5.0);
+
+struct dirent *
+glfs_readdirplus(glfs_fd_t *fd, struct stat *stat) __THROW
+ GFAPI_PUBLIC(glfs_readdirplus, 3.5.0);
+
+long
+glfs_telldir(glfs_fd_t *fd) __THROW GFAPI_PUBLIC(glfs_telldir, 3.4.0);
+
+void
+glfs_seekdir(glfs_fd_t *fd, long offset) __THROW
+ GFAPI_PUBLIC(glfs_seekdir, 3.4.0);
+
+int
+glfs_closedir(glfs_fd_t *fd) __THROW GFAPI_PUBLIC(glfs_closedir, 3.4.0);
+
+int
+glfs_statvfs(glfs_t *fs, const char *path, struct statvfs *buf) __THROW
+ GFAPI_PUBLIC(glfs_statvfs, 3.4.0);
+
+int
+glfs_chmod(glfs_t *fs, const char *path, mode_t mode) __THROW
+ GFAPI_PUBLIC(glfs_chmod, 3.4.0);
+
+int
+glfs_fchmod(glfs_fd_t *fd, mode_t mode) __THROW
+ GFAPI_PUBLIC(glfs_fchmod, 3.4.0);
+
+int
+glfs_chown(glfs_t *fs, const char *path, uid_t uid, gid_t gid) __THROW
+ GFAPI_PUBLIC(glfs_chown, 3.4.0);
+
+int
+glfs_lchown(glfs_t *fs, const char *path, uid_t uid, gid_t gid) __THROW
+ GFAPI_PUBLIC(glfs_lchown, 3.4.0);
+int
+glfs_fchown(glfs_fd_t *fd, uid_t uid, gid_t gid) __THROW
+ GFAPI_PUBLIC(glfs_fchown, 3.4.0);
-off_t glfs_lseek (glfs_fd_t *fd, off_t offset, int whence) __THROW
- GFAPI_PUBLIC(glfs_lseek, 3.4.0);
+int
+glfs_utimens(glfs_t *fs, const char *path,
+ const struct timespec times[2]) __THROW
+ GFAPI_PUBLIC(glfs_utimens, 3.4.0);
-int glfs_truncate (glfs_t *fs, const char *path, off_t length) __THROW
- GFAPI_PUBLIC(glfs_truncate, 3.4.0);
+int
+glfs_lutimens(glfs_t *fs, const char *path,
+ const struct timespec times[2]) __THROW
+ GFAPI_PUBLIC(glfs_lutimens, 3.4.0);
-int glfs_ftruncate (glfs_fd_t *fd, off_t length) __THROW
- GFAPI_PUBLIC(glfs_ftruncate, 3.4.0);
-int glfs_ftruncate_async (glfs_fd_t *fd, off_t length, glfs_io_cbk fn,
- void *data) __THROW
- GFAPI_PUBLIC(glfs_ftruncate_async, 3.4.0);
+int
+glfs_futimens(glfs_fd_t *fd, const struct timespec times[2]) __THROW
+ GFAPI_PUBLIC(glfs_futimens, 3.4.0);
-int glfs_lstat (glfs_t *fs, const char *path, struct stat *buf) __THROW
- GFAPI_PUBLIC(glfs_lstat, 3.4.0);
-int glfs_stat (glfs_t *fs, const char *path, struct stat *buf) __THROW
- GFAPI_PUBLIC(glfs_stat, 3.4.0);
-int glfs_fstat (glfs_fd_t *fd, struct stat *buf) __THROW
- GFAPI_PUBLIC(glfs_fstat, 3.4.0);
+ssize_t
+glfs_getxattr(glfs_t *fs, const char *path, const char *name, void *value,
+ size_t size) __THROW GFAPI_PUBLIC(glfs_getxattr, 3.4.0);
-int glfs_fsync (glfs_fd_t *fd) __THROW
- GFAPI_PUBLIC(glfs_fsync, 3.4.0);
-int glfs_fsync_async (glfs_fd_t *fd, glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_fsync_async, 3.4.0);
+ssize_t
+glfs_lgetxattr(glfs_t *fs, const char *path, const char *name, void *value,
+ size_t size) __THROW GFAPI_PUBLIC(glfs_lgetxattr, 3.4.0);
-int glfs_fdatasync (glfs_fd_t *fd) __THROW
- GFAPI_PUBLIC(glfs_fdatasync, 3.4.0);
-int glfs_fdatasync_async (glfs_fd_t *fd, glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_fdatasync_async, 3.4.0);
+ssize_t
+glfs_fgetxattr(glfs_fd_t *fd, const char *name, void *value,
+ size_t size) __THROW GFAPI_PUBLIC(glfs_fgetxattr, 3.4.0);
-int glfs_access (glfs_t *fs, const char *path, int mode) __THROW
- GFAPI_PUBLIC(glfs_access, 3.4.0);
+ssize_t
+glfs_listxattr(glfs_t *fs, const char *path, void *value, size_t size) __THROW
+ GFAPI_PUBLIC(glfs_listxattr, 3.4.0);
-int glfs_symlink (glfs_t *fs, const char *oldpath, const char *newpath) __THROW
- GFAPI_PUBLIC(glfs_symlink, 3.4.0);
+ssize_t
+glfs_llistxattr(glfs_t *fs, const char *path, void *value, size_t size) __THROW
+ GFAPI_PUBLIC(glfs_llistxattr, 3.4.0);
-int glfs_readlink (glfs_t *fs, const char *path,
- char *buf, size_t bufsiz) __THROW
- GFAPI_PUBLIC(glfs_readlink, 3.4.0);
+ssize_t
+glfs_flistxattr(glfs_fd_t *fd, void *value, size_t size) __THROW
+ GFAPI_PUBLIC(glfs_flistxattr, 3.4.0);
-int glfs_mknod (glfs_t *fs, const char *path, mode_t mode, dev_t dev) __THROW
- GFAPI_PUBLIC(glfs_mknod, 3.4.0);
+int
+glfs_setxattr(glfs_t *fs, const char *path, const char *name, const void *value,
+ size_t size, int flags) __THROW
+ GFAPI_PUBLIC(glfs_setxattr, 3.4.0);
-int glfs_mkdir (glfs_t *fs, const char *path, mode_t mode) __THROW
- GFAPI_PUBLIC(glfs_mkdir, 3.4.0);
+int
+glfs_lsetxattr(glfs_t *fs, const char *path, const char *name,
+ const void *value, size_t size, int flags) __THROW
+ GFAPI_PUBLIC(glfs_lsetxattr, 3.4.0);
-int glfs_unlink (glfs_t *fs, const char *path) __THROW
- GFAPI_PUBLIC(glfs_unlink, 3.4.0);
+int
+glfs_fsetxattr(glfs_fd_t *fd, const char *name, const void *value, size_t size,
+ int flags) __THROW GFAPI_PUBLIC(glfs_fsetxattr, 3.4.0);
-int glfs_rmdir (glfs_t *fs, const char *path) __THROW
- GFAPI_PUBLIC(glfs_rmdir, 3.4.0);
+int
+glfs_removexattr(glfs_t *fs, const char *path, const char *name) __THROW
+ GFAPI_PUBLIC(glfs_removexattr, 3.4.0);
-int glfs_rename (glfs_t *fs, const char *oldpath, const char *newpath) __THROW
- GFAPI_PUBLIC(glfs_rename, 3.4.0);
+int
+glfs_lremovexattr(glfs_t *fs, const char *path, const char *name) __THROW
+ GFAPI_PUBLIC(glfs_lremovexattr, 3.4.0);
-int glfs_link (glfs_t *fs, const char *oldpath, const char *newpath) __THROW
- GFAPI_PUBLIC(glfs_link, 3.4.0);
+int
+glfs_fremovexattr(glfs_fd_t *fd, const char *name) __THROW
+ GFAPI_PUBLIC(glfs_fremovexattr, 3.4.0);
-glfs_fd_t *glfs_opendir (glfs_t *fs, const char *path) __THROW
- GFAPI_PUBLIC(glfs_opendir, 3.4.0);
+int
+glfs_fallocate(glfs_fd_t *fd, int keep_size, off_t offset, size_t len) __THROW
+ GFAPI_PUBLIC(glfs_fallocate, 3.5.0);
+
+int
+glfs_discard(glfs_fd_t *fd, off_t offset, size_t len) __THROW
+ GFAPI_PUBLIC(glfs_discard, 3.5.0);
+
+int
+glfs_discard_async(glfs_fd_t *fd, off_t length, size_t lent, glfs_io_cbk fn,
+ void *data) __THROW GFAPI_PUBLIC(glfs_discard_async, 6.0);
+
+int
+glfs_zerofill(glfs_fd_t *fd, off_t offset, off_t len) __THROW
+ GFAPI_PUBLIC(glfs_zerofill, 3.5.0);
+
+int
+glfs_zerofill_async(glfs_fd_t *fd, off_t length, off_t len, glfs_io_cbk fn,
+ void *data) __THROW GFAPI_PUBLIC(glfs_zerofill_async, 6.0);
+
+char *
+glfs_getcwd(glfs_t *fs, char *buf, size_t size) __THROW
+ GFAPI_PUBLIC(glfs_getcwd, 3.4.0);
+
+int
+glfs_chdir(glfs_t *fs, const char *path) __THROW
+ GFAPI_PUBLIC(glfs_chdir, 3.4.0);
+
+int
+glfs_fchdir(glfs_fd_t *fd) __THROW GFAPI_PUBLIC(glfs_fchdir, 3.4.0);
+
+char *
+glfs_realpath(glfs_t *fs, const char *path, char *resolved_path) __THROW
+ GFAPI_PUBLIC(glfs_realpath, 3.7.17);
/*
- * @glfs_readdir_r and @glfs_readdirplus_r ARE thread safe AND re-entrant,
- * but the interface has ambiguity about the size of @dirent to be allocated
- * before calling the APIs. 512 byte buffer (for @dirent) is sufficient for
- * all known systems which are tested againt glusterfs/gfapi, but may be
- * insufficient in the future.
+ * @cmd and @flock are as specified in man fcntl(2).
+ */
+int
+glfs_posix_lock(glfs_fd_t *fd, int cmd, struct flock *flock) __THROW
+ GFAPI_PUBLIC(glfs_posix_lock, 3.4.0);
+
+/*
+ SYNOPSIS
+
+ glfs_file_lock: Request extended byte range lock on a file
+
+ DESCRIPTION
+
+ This function is capable of requesting either advisory or mandatory type
+ byte range locks on a file.
+
+ Note: To set a unique owner key for locks based on a particular file
+ descriptor, make use of glfs_fd_set_lkowner() api to do so before
+ requesting lock via this api. This owner key will be further consumed
+ by other incoming data modifying file operations via the same file
+ descriptor.
+
+ PARAMETERS
+
+ @fd: File descriptor
+
+ @cmd: As specified in man fcntl(2).
+
+ @flock: As specified in man fcntl(2).
+
+ @lk_mode: Required lock type from options available with the
+ enum glfs_lock_mode_t defined below.
+
+ RETURN VALUES
+
+ 0 : Success. Lock has been granted.
+ -1 : Failure. @errno will be set indicating the type of failure.
+
*/
-int glfs_readdir_r (glfs_fd_t *fd, struct dirent *dirent,
- struct dirent **result) __THROW
- GFAPI_PUBLIC(glfs_readdir_r, 3.4.0);
+/* Lock modes used by glfs_file_lock() */
+enum glfs_lock_mode { GLFS_LK_ADVISORY = 0, GLFS_LK_MANDATORY };
+typedef enum glfs_lock_mode glfs_lock_mode_t;
+
+int
+glfs_file_lock(glfs_fd_t *fd, int cmd, struct flock *flock,
+ glfs_lock_mode_t lk_mode) __THROW
+ GFAPI_PUBLIC(glfs_file_lock, 3.13.0);
-int glfs_readdirplus_r (glfs_fd_t *fd, struct stat *stat, struct dirent *dirent,
- struct dirent **result) __THROW
- GFAPI_PUBLIC(glfs_readdirplus_r, 3.4.0);
+glfs_fd_t *
+glfs_dup(glfs_fd_t *fd) __THROW GFAPI_PUBLIC(glfs_dup, 3.4.0);
+
+void
+glfs_free(void *ptr) __THROW GFAPI_PUBLIC(glfs_free, 3.7.16);
/*
- * @glfs_readdir and @glfs_readdirplus are NEITHER thread safe NOR re-entrant
- * when called on the same directory handle. However they ARE thread safe
- * AND re-entrant when called on different directory handles (which may be
- * referring to the same directory too.)
+ * glfs_sysrq: send a system request to the @fs instance
+ *
+ * Different commands for @sysrq are possible, the defines for these are listed
+ * below the function definition.
+ *
+ * This function always returns success if the @sysrq is recognized. The return
+ * value does not way anythin about the result of the @sysrq execution. Not all
+ * @sysrq command will be able to return a success/failure status.
*/
+int
+glfs_sysrq(glfs_t *fs, char sysrq) __THROW GFAPI_PUBLIC(glfs_sysrq, 3.10.0);
-struct dirent *glfs_readdir (glfs_fd_t *fd) __THROW
- GFAPI_PUBLIC(glfs_readdir, 3.5.0);
+#define GLFS_SYSRQ_HELP 'h' /* log a message with supported sysrq commands */
+#define GLFS_SYSRQ_STATEDUMP 's' /* create a statedump */
-struct dirent *glfs_readdirplus (glfs_fd_t *fd, struct stat *stat) __THROW
- GFAPI_PUBLIC(glfs_readdirplus, 3.5.0);
+/*
+ * Structure returned as part of xreaddirplus
+ */
+struct glfs_xreaddirp_stat;
+typedef struct glfs_xreaddirp_stat glfs_xreaddirp_stat_t;
-long glfs_telldir (glfs_fd_t *fd) __THROW
- GFAPI_PUBLIC(glfs_telldir, 3.4.0);
+/* Request flags to be used in XREADDIRP operation */
+#define GFAPI_XREADDIRP_NULL \
+ 0x00000000 /* by default, no stat will be fetched */
+#define GFAPI_XREADDIRP_STAT 0x00000001 /* Get stat */
+#define GFAPI_XREADDIRP_HANDLE 0x00000002 /* Get object handle */
-void glfs_seekdir (glfs_fd_t *fd, long offset) __THROW
- GFAPI_PUBLIC(glfs_seekdir, 3.4.0);
+/*
+ * This stat structure returned gets freed as part of glfs_free(xstat)
+ */
+struct stat *
+glfs_xreaddirplus_get_stat(glfs_xreaddirp_stat_t *xstat) __THROW
+ GFAPI_PUBLIC(glfs_xreaddirplus_get_stat, 3.11.0);
-int glfs_closedir (glfs_fd_t *fd) __THROW
- GFAPI_PUBLIC(glfs_closedir, 3.4.0);
+/*
+ * SYNOPSIS
+ *
+ * glfs_xreaddirplus_r: Extended Readirplus operation
+ *
+ * DESCRIPTION
+ *
+ * This API does readdirplus operation, but along with stat it can fetch other
+ * extra information like object handles etc for each of the dirents returned
+ * based on requested flags. On success it returns the set of flags successfully
+ * processed.
+ *
+ * Note that there are chances that some of the requested information may not be
+ * available or returned (for example if reached EOD). Ensure to validate the
+ * returned value to determine what flags have been successfully processed
+ * & set.
+ *
+ * PARAMETERS
+ *
+ * INPUT:
+ * @glfd: GFAPI file descriptor of the directory
+ * @flags: Flags determining xreaddirp_stat requested
+ * Current available values are:
+ * GFAPI_XREADDIRP_NULL
+ * GFAPI_XREADDIRP_STAT
+ * GFAPI_XREADDIRP_HANDLE
+ * @ext: Dirent struture to copy the values to
+ * (though optional recommended to be allocated by application
+ * esp., in multi-threaded environment)
+ *
+ * OUTPUT:
+ * @res: to store the next dirent value. If NULL and return value is '0',
+ * it means it reached end of the directory.
+ * @xstat_p: Pointer to contain all the requested data returned
+ * for that dirent. Application should make use of glfs_free() API
+ * to free this pointer and the variables returned by
+ * glfs_xreaddirplus_get_*() APIs.
+ *
+ * RETURN VALUE:
+ * >=0: SUCCESS (value contains the flags successfully processed)
+ * -1: FAILURE
+ */
+int
+glfs_xreaddirplus_r(glfs_fd_t *glfd, uint32_t flags,
+ glfs_xreaddirp_stat_t **xstat_p, struct dirent *ext,
+ struct dirent **res) __THROW
+ GFAPI_PUBLIC(glfs_xreaddirplus_r, 3.11.0);
-int glfs_statvfs (glfs_t *fs, const char *path, struct statvfs *buf) __THROW
- GFAPI_PUBLIC(glfs_statvfs, 3.4.0);
+#define GFAPI_MAX_LOCK_OWNER_LEN 255
-int glfs_chmod (glfs_t *fs, const char *path, mode_t mode) __THROW
- GFAPI_PUBLIC(glfs_chmod, 3.4.0);
+/*
+ *
+ * DESCRIPTION
+ *
+ * This API allows application to set lk_owner on a fd.
+ * A glfd can be associated with only single lk_owner. In case if there
+ * is need to set another lk_owner, applications can make use of
+ * 'glfs_dup' to get duplicate glfd and set new lk_owner on that second
+ * glfd.
+ *
+ * Also its not recommended to override or clear lk_owner value as the
+ * same shall be used to flush any outstanding locks while closing the fd.
+ *
+ * PARAMETERS
+ *
+ * INPUT:
+ * @glfd: GFAPI file descriptor
+ * @len: Size of lk_owner buffer. Max value can be GFAPI_MAX_LOCK_OWNER_LEN
+ * @data: lk_owner data buffer.
+ *
+ * OUTPUT:
+ * 0: SUCCESS
+ * -1: FAILURE
+ */
+int
+glfs_fd_set_lkowner(glfs_fd_t *glfd, void *data, int len) __THROW
+ GFAPI_PUBLIC(glfs_fd_set_lkowner, 3.10.7);
-int glfs_fchmod (glfs_fd_t *fd, mode_t mode) __THROW
- GFAPI_PUBLIC(glfs_fchmod, 3.4.0);
+/*
+ * Applications (currently NFS-Ganesha) can make use of this
+ * structure to read upcall notifications sent by server either
+ * by polling or registering a callback function.
+ *
+ * On success, applications need to check for 'reason' to decide
+ * if any upcall event is received.
+ *
+ * Currently supported upcall_events -
+ * GLFS_UPCALL_INODE_INVALIDATE -
+ * 'event_arg' - glfs_upcall_inode
+ *
+ * After processing the event, applications need to free 'event_arg' with
+ * glfs_free().
+ *
+ * Also similar to I/Os, the application should ideally stop polling
+ * or unregister upcall_cbk function before calling glfs_fini(..).
+ * Hence making an assumption that 'fs' & ctx structures cannot be
+ * freed while in this routine.
+ */
+struct glfs_upcall;
+typedef struct glfs_upcall glfs_upcall_t;
-int glfs_chown (glfs_t *fs, const char *path, uid_t uid, gid_t gid) __THROW
- GFAPI_PUBLIC(glfs_chown, 3.4.0);
+glfs_t *
+glfs_upcall_get_fs(glfs_upcall_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_get_fs, 3.7.16);
-int glfs_lchown (glfs_t *fs, const char *path, uid_t uid, gid_t gid) __THROW
- GFAPI_PUBLIC(glfs_lchown, 3.4.0);
+enum glfs_upcall_reason {
+ GLFS_UPCALL_EVENT_NULL = 0,
+ GLFS_UPCALL_INODE_INVALIDATE, /* invalidate cache entry */
+ GLFS_UPCALL_RECALL_LEASE, /* recall lease */
+};
+typedef enum glfs_upcall_reason glfs_upcall_reason_t;
-int glfs_fchown (glfs_fd_t *fd, uid_t uid, gid_t gid) __THROW
- GFAPI_PUBLIC(glfs_fchown, 3.4.0);
+glfs_upcall_reason_t
+glfs_upcall_get_reason(glfs_upcall_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_get_reason, 3.7.16);
-int glfs_utimens (glfs_t *fs, const char *path,
- struct timespec times[2]) __THROW
- GFAPI_PUBLIC(glfs_utimens, 3.4.0);
+/*
+ * Applications first need to make use of above API i.e,
+ * "glfs_upcall_get_reason" to determine which upcall event it has
+ * received. Post that below API - "glfs_upcall_get_event" should
+ * be used to get corresponding upcall event object.
+ *
+ * Below are the upcall_reason and corresponding upcall_event objects:
+ * ==========================================================
+ * glfs_upcall_reason - event_object
+ * ==========================================================
+ * GLFS_UPCALL_EVENT_NULL - NULL
+ * GLFS_UPCALL_INODE_INVALIDATE - struct glfs_upcall_inode
+ * GLFS_UPCALL_RECALL_LEASE - struct glfs_upcall_lease
+ *
+ * After processing upcall event, glfs_free() should be called on the
+ * glfs_upcall.
+ */
+void *
+glfs_upcall_get_event(glfs_upcall_t *arg) __THROW
+ GFAPI_PUBLIC(glfs_upcall_get_event, 3.7.16);
-int glfs_lutimens (glfs_t *fs, const char *path,
- struct timespec times[2]) __THROW
- GFAPI_PUBLIC(glfs_lutimens, 3.4.0);
+/*
+ * SYNOPSIS
+ *
+ * glfs_upcall_cbk: Upcall callback definition
+ *
+ * This is function type definition of the callback function pointer
+ * which has to be provided by the caller while registering for any
+ * upcall events.
+ *
+ * This function is called whenever any upcall which the application
+ * has registered for is received from the server.
+ *
+ * @up_arg: Upcall structure whose contents need to be interpreted by
+ * making use of glfs_upcall_* helper routines.
+ *
+ * @data: The same context pointer provided by the caller at the time of
+ * registering of upcall events. This may be used by the caller for any
+ * of its internal use while processing upcalls.
+ */
+typedef void (*glfs_upcall_cbk)(glfs_upcall_t *up_arg, void *data);
-int glfs_futimens (glfs_fd_t *fd, struct timespec times[2]) __THROW
- GFAPI_PUBLIC(glfs_futimens, 3.4.0);
+/*
+ * List of upcall events supported by gluster/gfapi
+ */
+#define GLFS_EVENT_INODE_INVALIDATE 0x00000001 /* invalidate cache entry */
+#define GLFS_EVENT_RECALL_LEASE 0x00000002 /* Recall lease */
+#define GLFS_EVENT_ANY 0xffffffff /* for all the above events */
-ssize_t glfs_getxattr (glfs_t *fs, const char *path, const char *name,
- void *value, size_t size) __THROW
- GFAPI_PUBLIC(glfs_getxattr, 3.4.0);
+/*
+ * SYNOPSIS
+ *
+ * glfs_upcall_register: Register for upcall events
+ *
+ * DESCRIPTION
+ *
+ * This function is used to register for various upcall events application
+ * is interested in and the callback function to be invoked when such
+ * events are triggered.
+ *
+ * Multiple calls of this routine shall override cbk function. That means
+ * only one cbk function can be used for all the upcall events registered
+ * and that shall be the one last updated.
+ *
+ * PARAMETERS:
+ *
+ * INPUT:
+ * @fs: The 'virtual mount' object
+ *
+ * @event_list: List of upcall events to be registered.
+ * Current available values are:
+ * - GLFS_EVENT_INODE_INVALIDATE
+ * - GLFS_EVENT_RECALL_LEASE
+ *
+ * @cbk: The cbk routine to be invoked in case of any upcall received
+ * @data: Any opaque pointer provided by caller which shall be using while
+ * making cbk calls. This pointer may be used by caller for any of its
+ * internal use while processing upcalls. Can be NULL.
+ *
+ * RETURN VALUE:
+ * >0: SUCCESS (value contains the events successfully registered)
+ * -1: FAILURE
+ */
+int
+glfs_upcall_register(glfs_t *fs, uint32_t event_list, glfs_upcall_cbk cbk,
+ void *data) __THROW
+ GFAPI_PUBLIC(glfs_upcall_register, 3.13.0);
-ssize_t glfs_lgetxattr (glfs_t *fs, const char *path, const char *name,
- void *value, size_t size) __THROW
- GFAPI_PUBLIC(glfs_lgetxattr, 3.4.0);
+/*
+ * SYNOPSIS
+ *
+ * glfs_upcall_unregister: Unregister for upcall events
+ *
+ * DESCRIPTION
+ *
+ * This function is used to unregister the upcall events application
+ * is not interested in. In case if the caller unregisters all the events
+ * it has registered for, it shall no more receive any upcall event.
+ *
+ * PARAMETERS:
+ *
+ * INPUT:
+ * @fs: The 'virtual mount' object
+ *
+ * @event_list: List of upcall events to be unregistered.
+ * Current available values are:
+ * - GLFS_EVENT_INODE_INVALIDATE
+ * - GLFS_EVENT_RECALL_LEASE
+ * RETURN VALUE:
+ * >0: SUCCESS (value contains the events successfully unregistered)
+ * -1: FAILURE
+ */
+int
+glfs_upcall_unregister(glfs_t *fs, uint32_t event_list) __THROW
+ GFAPI_PUBLIC(glfs_upcall_unregister, 3.13.0);
+
+/* Lease Types */
+enum glfs_lease_types {
+ GLFS_LEASE_NONE = 0,
+ GLFS_RD_LEASE = 1,
+ GLFS_RW_LEASE = 2,
+};
+typedef enum glfs_lease_types glfs_lease_types_t;
+
+/* Lease cmds */
+enum glfs_lease_cmds {
+ GLFS_GET_LEASE = 1,
+ GLFS_SET_LEASE = 2,
+ GLFS_UNLK_LEASE = 3,
+};
+typedef enum glfs_lease_cmds glfs_lease_cmds_t;
+
+struct glfs_lease {
+ glfs_lease_cmds_t cmd;
+ glfs_lease_types_t lease_type;
+ glfs_leaseid_t lease_id;
+ unsigned int lease_flags;
+};
+typedef struct glfs_lease glfs_lease_t;
+
+typedef void (*glfs_recall_cbk)(glfs_lease_t lease, void *data);
-ssize_t glfs_fgetxattr (glfs_fd_t *fd, const char *name,
- void *value, size_t size) __THROW
- GFAPI_PUBLIC(glfs_fgetxattr, 3.4.0);
+/*
+ SYNOPSIS
-ssize_t glfs_listxattr (glfs_t *fs, const char *path,
- void *value, size_t size) __THROW
- GFAPI_PUBLIC(glfs_listxattr, 3.4.0);
+ glfs_lease: Takes a lease on a file.
-ssize_t glfs_llistxattr (glfs_t *fs, const char *path, void *value,
- size_t size) __THROW
- GFAPI_PUBLIC(glfs_llistxattr, 3.4.0);
+ DESCRIPTION
-ssize_t glfs_flistxattr (glfs_fd_t *fd, void *value, size_t size) __THROW
- GFAPI_PUBLIC(glfs_flistxattr, 3.4.0);
+ This function takes lease on an open file.
-int glfs_setxattr (glfs_t *fs, const char *path, const char *name,
- const void *value, size_t size, int flags) __THROW
- GFAPI_PUBLIC(glfs_setxattr, 3.4.0);
+ PARAMETERS
-int glfs_lsetxattr (glfs_t *fs, const char *path, const char *name,
- const void *value, size_t size, int flags) __THROW
- GFAPI_PUBLIC(glfs_lsetxattr, 3.4.0);
+ @glfd: The fd of the file on which lease should be taken,
+ this fd is returned by glfs_open/glfs_create.
-int glfs_fsetxattr (glfs_fd_t *fd, const char *name,
- const void *value, size_t size, int flags) __THROW
- GFAPI_PUBLIC(glfs_fsetxattr, 3.4.0);
+ @lease: Struct that defines the lease operation to be performed
+ on the file.
+ @lease.cmd - Can be one of the following values
+ GF_GET_LEASE: Get the lease type currently present on the file,
+ lease.lease_type will contain GF_RD_LEASE
+ or GF_RW_LEASE or 0 if no leases.
+ GF_SET_LEASE: Set the lease of given lease.lease_type on the file.
+ GF_UNLK_LEASE: Unlock the lease present on the given fd.
+ Note that the every lease request should have
+ a corresponding unlk_lease.
-int glfs_removexattr (glfs_t *fs, const char *path, const char *name) __THROW
- GFAPI_PUBLIC(glfs_removexattr, 3.4.0);
+ @lease.lease_type - Can be one of the following values
+ GF_RD_LEASE: Read lease on a file, shared lease.
+ GF_RW_LEASE: Read-Write lease on a file, exclusive lease.
-int glfs_lremovexattr (glfs_t *fs, const char *path, const char *name) __THROW
- GFAPI_PUBLIC(glfs_lremovexattr, 3.4.0);
+ @lease.lease_id - A unique identification of lease, 128bits.
-int glfs_fremovexattr (glfs_fd_t *fd, const char *name) __THROW
- GFAPI_PUBLIC(glfs_fremovexattr, 3.4.0);
+ @fn: This is the function that is invoked when the lease has to be recalled
+ @data: It is a cookie, this pointer is returned as a part of recall
+
+ fn and data field are stored as a part of glfs_fd, hence if there are multiple
+ glfs_lease calls, each of them updates the fn and data fields. glfs_recall_cbk
+ will be invoked with the last updated fn and data
+
+ RETURN VALUES
+ 0: Successful completion
+ <0: Failure. @errno will be set with the type of failure
+*/
-int glfs_fallocate(glfs_fd_t *fd, int keep_size,
- off_t offset, size_t len) __THROW
- GFAPI_PUBLIC(glfs_fallocate, 3.5.0);
+int
+glfs_lease(glfs_fd_t *glfd, glfs_lease_t *lease, glfs_recall_cbk fn,
+ void *data) __THROW GFAPI_PUBLIC(glfs_lease, 4.0.0);
-int glfs_discard(glfs_fd_t *fd, off_t offset, size_t len) __THROW
- GFAPI_PUBLIC(glfs_discard, 3.5.0);
+/*
+ SYNOPSIS
+ glfs_fsetattr: Function to set attributes.
+ glfs_setattr: Function to set attributes
-int glfs_discard_async (glfs_fd_t *fd, off_t length, size_t lent,
- glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_discard_async, 3.5.0);
+ DESCRIPTION
-int glfs_zerofill(glfs_fd_t *fd, off_t offset, off_t len) __THROW
- GFAPI_PUBLIC(glfs_zerofill, 3.5.0);
+ The functions are used to set attributes on the file.
-int glfs_zerofill_async (glfs_fd_t *fd, off_t length, off_t len,
- glfs_io_cbk fn, void *data) __THROW
- GFAPI_PUBLIC(glfs_zerofill_async, 3.5.0);
+ PARAMETERS
-char *glfs_getcwd (glfs_t *fs, char *buf, size_t size) __THROW
- GFAPI_PUBLIC(glfs_getcwd, 3.4.0);
+ @glfs_fsetattr
-int glfs_chdir (glfs_t *fs, const char *path) __THROW
- GFAPI_PUBLIC(glfs_chdir, 3.4.0);
+ @glfd: The fd of the file for which the attributes are to be set,
+ this fd is returned by glfs_open/glfs_create.
-int glfs_fchdir (glfs_fd_t *fd) __THROW
- GFAPI_PUBLIC(glfs_fchdir, 3.4.0);
+ @glfs_setattr
-char *glfs_realpath (glfs_t *fs, const char *path, char *resolved_path) __THROW
- GFAPI_PUBLIC(glfs_realpath, 3.4.0);
+ @fs: File object.
+
+ @path: The path of the file that is being operated on.
+
+ @follow: Flag used to resolve symlink.
+
+
+ @stat: Struct that has information about the file.
+
+ @valid: This is the mask bit, that accepts GFAPI_SET_ATTR* masks.
+ Refer glfs.h to see the mask definitions.
+
+ Both functions are similar in functionality, just that the
+ func setattr() uses file path whereas the func fsetattr()
+ uses the fd.
+
+ RETURN VALUES
+ 0: Successful completion
+ <0: Failure. @errno will be set with the type of failure
-/*
- * @cmd and @flock are as specified in man fcntl(2).
*/
-int glfs_posix_lock (glfs_fd_t *fd, int cmd, struct flock *flock) __THROW
- GFAPI_PUBLIC(glfs_posix_lock, 3.4.0);
-glfs_fd_t *glfs_dup (glfs_fd_t *fd) __THROW
- GFAPI_PUBLIC(glfs_dup, 3.4.0);
+int
+glfs_fsetattr(struct glfs_fd *glfd, struct glfs_stat *stat) __THROW
+ GFAPI_PUBLIC(glfs_fsetattr, 6.0);
+
+int
+glfs_setattr(struct glfs *fs, const char *path, struct glfs_stat *stat,
+ int follow) __THROW GFAPI_PUBLIC(glfs_setattr, 6.0);
/*
- * No xdata support for now. Nobody needs this call at all yet except for the
- * test script, and that doesn't need xdata. Adding dict_t support and a new
- * header-file requirement doesn't seem worth it until the need is greater.
+ SYNOPSIS
+
+ glfs_set_statedump_path: Function to set statedump path.
+
+ DESCRIPTION
+
+ This function is used to set statedump directory
+
+ PARAMETERS
+
+ @fs: The 'virtual mount' object to be configured with the volume
+ specification file.
+
+ @path: statedump path. Should be a directory. But the API won't fail if the
+ directory doesn't exist yet, as one may create it later.
+
+ RETURN VALUES
+
+ 0 : Success.
+ -1 : Failure. @errno will be set with the type of failure.
+
*/
-int glfs_ipc (glfs_fd_t *fd, int cmd) __THROW
- GFAPI_PUBLIC(glfs_ipc, 3.7.0);
-__END_DECLS
+int
+glfs_set_statedump_path(struct glfs *fs, const char *path) __THROW
+ GFAPI_PUBLIC(glfs_set_statedump_path, 7.0);
+__END_DECLS
#endif /* !_GLFS_H */
diff --git a/autogen.sh b/autogen.sh
index fef2f037426..c8cdc3f89fa 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -85,11 +85,7 @@ $TOOL --automake --copy --force
echo Running ${AUTOCONF}...
$AUTOCONF
echo Running ${AUTOMAKE}...
-$AUTOMAKE --add-missing --copy --foreign
-
-# Run autogen in the argp-standalone sub-directory
-echo "Running autogen.sh in argp-standalone ..."
-( cd contrib/argp-standalone;./autogen.sh )
+$AUTOMAKE --add-missing --force-missing --copy
# Instruct user on next steps
echo
diff --git a/extras/checkpatch.pl b/build-aux/checkpatch.pl
index 5a314258142..17ae4e4d579 100755
--- a/extras/checkpatch.pl
+++ b/build-aux/checkpatch.pl
@@ -612,7 +612,6 @@ sub top_of_glusterfs_tree {
"geo-replication",
"glusterfs-api.pc.in",
"glusterfsd",
- "glusterfs-hadoop",
"glusterfs.spec.in",
"heal",
"INSTALL",
@@ -2084,6 +2083,8 @@ sub process {
"Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
}
+# check we are in .spec file, then ignore this hunk
+ next if ($realfile eq "glusterfs.spec.in");
# check we are in a valid source file if not then ignore this hunk
next if ($realfile !~ /\.(h|c|pl|py|l|y|sh|in)$/);
@@ -2633,17 +2634,6 @@ sub process {
}
}
-# check for new typedefs, only function parameters and sparse annotations
-# make sense.
- if ($line =~ /\btypedef\s/ &&
- $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
- $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
- $line !~ /\b$typeTypedefs\b/ &&
- $line !~ /\b__bitwise(?:__|)\b/) {
- WARN("NEW_TYPEDEFS",
- "do not add new typedefs\n" . $herecurr);
- }
-
# * goes on variable not on type
# (char*[ const])
while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
@@ -2702,8 +2692,8 @@ sub process {
# function brace can't be on same line, except for #defines of do while,
# or if closed on same line
- if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and
- !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) {
+ if (($line=~/$Type\s*$Ident\(.*\).*\s\{/) and
+ !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) {
ERROR("OPEN_BRACE",
"open brace '{' following function declarations go on the next line\n" . $herecurr);
}
@@ -3104,12 +3094,12 @@ sub process {
## }
#need space before brace following if, while, etc
- if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
- $line =~ /do{/) {
+ if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
+ $line =~ /do\{/) {
if (ERROR("SPACING",
"space required before the open brace '{'\n" . $herecurr) &&
$fix) {
- $fixed[$linenr - 1] =~ s/^(\+.*(?:do|\))){/$1 {/;
+ $fixed[$linenr - 1] =~ s/^(\+.*(?:do|\)))\{/$1 {/;
}
}
@@ -3493,7 +3483,7 @@ sub process {
$dstat !~ /^for\s*$Constant$/ && # for (...)
$dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
$dstat !~ /^do\s*{/ && # do {...
- $dstat !~ /^\({/ && # ({...
+ $dstat !~ /^\(\{/ && # ({...
$ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
{
$ctx =~ s/\n*$//;
diff --git a/build-aux/config.guess.dist b/build-aux/config.guess.dist
new file mode 100755
index 00000000000..881ba7a0438
--- /dev/null
+++ b/build-aux/config.guess.dist
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# This script is intentionally left empty. Distributions that package GlusterFS
+# may want to to replace it with an updated copy from the automake project.
+#
+
+cat << EOM
+It is not expected to execute this script. When you are building from a
+released tarball (generated with 'make dist'), you are expected to pass
+--build=... and --host=... to ./configure or replace this config.guess script
+in the sources with an updated version.
+EOM
+
+exit 0
diff --git a/build-aux/config.sub.dist b/build-aux/config.sub.dist
new file mode 100755
index 00000000000..c5a0dbad282
--- /dev/null
+++ b/build-aux/config.sub.dist
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# This script is intentionally left empty. Distributions that package GlusterFS
+# may want to to replace it with an updated copy from the automake project.
+#
+
+cat << EOM
+It is not expected to execute this script. When you are building from a
+released tarball (generated with 'make dist'), you are expected to pass
+--build=... and --host=... to ./configure or replace this config.sub script in
+the sources with an updated version.
+EOM
+
+exit 0
diff --git a/build-aux/pkg-version b/build-aux/pkg-version
index 83d4a5f9136..17ceab70c03 100755
--- a/build-aux/pkg-version
+++ b/build-aux/pkg-version
@@ -1,9 +1,13 @@
-#!/bin/sh
+#!/bin/bash
# To override version/release from git,
# create VERSION file containing text with version/release
# eg. v3.4.0-1
-PKG_VERSION=`cat VERSION 2> /dev/null || git describe --tags --match "v[0-9]*"`
+
+# One thing to note, If one does 'git clone --depth N glusterfs.git',
+# the git describe command doesn't work. Hence you notice below that
+# we have added timestamp as version (YYYY.MM.DD) and release (HH.mmss)
+PKG_VERSION=`cat VERSION 2> /dev/null || git describe --tags --match "v[0-9]*" 2>/dev/null`
get_version()
{
@@ -18,7 +22,11 @@ get_version()
sub(/^v/,"") ; print $1
}'
- echo $PKG_VERSION | awk "$AWK_VERSION" | tr -cd '[:alnum:].'
+ version=$(echo $PKG_VERSION | awk "$AWK_VERSION" | tr -cd '[:alnum:].')
+ if [ "x${version}" == "x" ] ; then
+ version=$(date +%Y.%m.%d | tr -d '\n')
+ fi
+ echo $version | tr -d '\n'
}
get_release()
@@ -37,7 +45,11 @@ get_release()
else if (NF == 4) print $2, $3, "git" substr($4, 2)
}'
- echo $PKG_VERSION | awk "$AWK_RELEASE" | tr -cd '[:alnum:].'
+ release=$(echo $PKG_VERSION | awk "$AWK_RELEASE" | tr -cd '[:alnum:].')
+ if [ "x${release}" == "x" ] ; then
+ release=$(date +%H.%M%S | tr -d '\n')
+ fi
+ echo $release | tr -d '\n'
}
if test "x$1" = "x--full"; then
diff --git a/build-aux/xdrgen b/build-aux/xdrgen
deleted file mode 100755
index 0cefc9b4890..00000000000
--- a/build-aux/xdrgen
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/bin/sh
-
-append_licence_header ()
-{
- local src_file=$1;
- local dst_file=$2;
-
- cat >$dst_file <<EOF
-/*
- Copyright (c) 2007-2014 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#include "compat.h"
-#include "xdr-common.h"
-#include "xdr-nfs3.h"
-
-#if defined(__GNUC__)
-#if __GNUC__ >= 4
-#if !defined(__clang__)
-#if !defined(__NetBSD__)
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
-#pragma GCC diagnostic ignored "-Wunused-variable"
-#endif
-#else
-#pragma clang diagnostic ignored "-Wunused-variable"
-#pragma clang diagnostic ignored "-Wunused-value"
-#endif
-#endif
-#endif
-
-EOF
-
- cat $src_file >> $dst_file;
-
-}
-
-gen_sources ()
-{
- local xfile="$1";
-
- local cfile="${1%.x}.c";
- local hfile="${1%.x}.h";
-
- local tmp_cfile="$1.c.tmp";
- local tmp_hfile="$1.h.tmp";
-
- rm -f $cfile;
- rpcgen -c -o $cfile $xfile;
- append_licence_header $cfile $tmp_cfile;
- mv $tmp_cfile $cfile;
- # remove unwanted temporary files (if any)
- rm -f $tmp_cfile;
- echo "Generated $cfile"
- return
-}
-
-gen_headers ()
-{
- local xfile="$1";
-
- local cfile="${1%.x}.c";
- local hfile="${1%.x}.h";
-
- local tmp_cfile="$1.c.tmp";
- local tmp_hfile="$1.h.tmp";
-
- # no need for a temporary file here as there are no changes from glusterfs
- rm -f $hfile;
- rpcgen -h -o $hfile $xfile;
- # the '#ifdef' part of file should be fixed
- sed -e 's/-/_/g' $hfile > ${hfile}.new && mv ${hfile}.new $hfile;
- # Gen header to temp file and append generated file
- append_licence_header $hfile $tmp_hfile;
- # now move the destination file to actual original file
- mv $tmp_hfile $hfile;
- rm -f $tmp_hfile;
- echo "Generated $hfile";
- return
-}
-
-main ()
-{
- if [ $# -ne 2 ]; then
- echo "wrong number of arguments given"
- echo " $0 [header|source] <XDR-definition-file>.x"
- exit 1;
- fi
-
- if [ $1 = "header" ]; then
- gen_headers $2
- fi
-
- if [ $1 = "source" ]; then
- gen_sources $2
- fi
-}
-
-main "$@";
diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am
index 92cf35a581c..16063f27c7f 100644
--- a/cli/src/Makefile.am
+++ b/cli/src/Makefile.am
@@ -5,6 +5,7 @@ gluster_SOURCES = cli.c registry.c input.c cli-cmd.c cli-rl.c cli-cmd-global.c \
cli-cmd-system.c cli-cmd-misc.c cli-xml-output.c cli-quotad-client.c cli-cmd-snapshot.c
gluster_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(GF_LDADD) \
+ $(top_builddir)/libglusterd/src/libglusterd.la \
$(RLLIBS) $(top_builddir)/rpc/xdr/src/libgfxdr.la \
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
$(XML_LIBS)
@@ -13,20 +14,24 @@ gluster_LDFLAGS = $(GF_LDFLAGS)
noinst_HEADERS = cli.h cli-mem-types.h cli-cmd.h cli-quotad-client.h
AM_CPPFLAGS = $(GF_CPPFLAGS) \
- -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/rpc-lib/src\
- -I$(top_srcdir)/rpc/xdr/src\
+ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/rpc-lib/src \
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_srcdir)/libglusterd/src \
+ -I$(top_builddir)/rpc/xdr/src \
-DDATADIR=\"$(localstatedir)\" \
-DCONFDIR=\"$(sysconfdir)/glusterfs\" \
- -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\
- -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) -DSBIN_DIR=\"$(sbindir)\"\
- $(XML_CPPFLAGS)
+ -DGSYNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\"\
+ -DGLFSHEAL_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\"\
+ -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE)
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+AM_CFLAGS = -Wall $(GF_CFLAGS) $(XML_CFLAGS)
CLEANFILES =
$(top_builddir)/libglusterfs/src/libglusterfs.la:
$(MAKE) -C $(top_builddir)/libglusterfs/src/ all
+$(top_builddir)/libglusterd/src/libglusterd.la:
+ $(MAKE) -C $(top_builddir)/libglusterd/src/ all
+
install-data-hook:
- $(MKDIR_P) $(DESTDIR)$(localstatedir)/run/gluster
+ $(mkdir_p) $(DESTDIR)$(localstatedir)/run/gluster
diff --git a/cli/src/cli-cmd-global.c b/cli/src/cli-cmd-global.c
index 3c526f8a828..2c9a5f01bb1 100644
--- a/cli/src/cli-cmd-global.c
+++ b/cli/src/cli-cmd-global.c
@@ -23,104 +23,173 @@
#include "cli-cmd.h"
#include "cli-mem-types.h"
#include "cli1-xdr.h"
-#include "run.h"
-#include "syscall.h"
-#include "common-utils.h"
-
-extern rpc_clnt_prog_t *cli_rpc_prog;
+#include <glusterfs/run.h>
+#include <glusterfs/syscall.h>
+#include <glusterfs/common-utils.h>
int
-cli_cmd_global_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
- const char **words, int wordcount);
-int cli_cmd_ganesha_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount);
+cli_cmd_global_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount);
+int
+cli_cmd_get_state_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount);
+int
+cli_cmd_ganesha_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount);
struct cli_cmd global_cmds[] = {
- { "global help",
- cli_cmd_global_help_cbk,
- "list global commands",
- },
- { "nfs-ganesha {enable| disable} ",
- cli_cmd_ganesha_cbk,
- "Enable/disable NFS-Ganesha support",
- },
- {NULL, NULL, NULL}
-};
+ {
+ "global help",
+ cli_cmd_global_help_cbk,
+ "list global commands",
+ },
+ {
+ "get-state [<daemon>] [[odir </path/to/output/dir/>] "
+ "[file <filename>]] [detail|volumeoptions]",
+ cli_cmd_get_state_cbk,
+ "Get local state representation of mentioned daemon",
+ },
+ {
+ "nfs-ganesha {enable| disable} ",
+ cli_cmd_ganesha_cbk,
+ "Enable/disable NFS-Ganesha support",
+ },
+ {NULL, NULL, NULL}};
int
-cli_cmd_global_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
- const char **words, int wordcount)
+cli_cmd_global_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount)
{
- struct cli_cmd *cmd = NULL;
-
- for (cmd = global_cmds; cmd->pattern; cmd++)
- if (_gf_false == cmd->disable)
- cli_out ("%s - %s", cmd->pattern, cmd->desc);
-
- return 0;
+ struct cli_cmd *cmd = NULL;
+ struct cli_cmd *global_cmd = NULL;
+ int count = 0;
+
+ cmd = GF_MALLOC(sizeof(global_cmds), cli_mt_cli_cmd);
+ memcpy(cmd, global_cmds, sizeof(global_cmds));
+ count = (sizeof(global_cmds) / sizeof(struct cli_cmd));
+ cli_cmd_sort(cmd, count);
+
+ cli_out("\ngluster global commands");
+ cli_out("========================\n");
+ for (global_cmd = cmd; global_cmd->pattern; global_cmd++)
+ if (_gf_false == global_cmd->disable)
+ cli_out("%s - %s", global_cmd->pattern, global_cmd->desc);
+
+ cli_out("\n");
+ GF_FREE(cmd);
+ return 0;
}
int
-cli_cmd_global_register (struct cli_state *state)
+cli_cmd_global_register(struct cli_state *state)
{
- int ret = 0;
- struct cli_cmd *cmd = NULL;
- for (cmd = global_cmds; cmd->pattern; cmd++) {
- ret = cli_cmd_register (&state->tree, cmd);
- if (ret)
- goto out;
- }
+ int ret = 0;
+ struct cli_cmd *cmd = NULL;
+ for (cmd = global_cmds; cmd->pattern; cmd++) {
+ ret = cli_cmd_register(&state->tree, cmd);
+ if (ret)
+ goto out;
+ }
out:
- return ret;
-
+ return ret;
}
-int cli_cmd_ganesha_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+int
+cli_cmd_ganesha_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- int sent = 0;
- int parse_error = 0;
- int ret = -1;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- dict_t *options = NULL;
- cli_local_t *local = NULL;
- char *op_errstr = NULL;
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GANESHA];
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- ret = cli_cmd_ganesha_parse (state, words, wordcount,
- &options, &op_errstr);
- if (ret) {
- if (op_errstr) {
- cli_err ("%s", op_errstr);
- GF_FREE (op_errstr);
- } else
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- CLI_LOCAL_INIT (local, words, frame, options);
-
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ int sent = 0;
+ int parse_error = 0;
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+ cli_local_t *local = NULL;
+ char *op_errstr = NULL;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GANESHA];
+
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ ret = cli_cmd_ganesha_parse(state, words, wordcount, &options, &op_errstr);
+ if (ret) {
+ if (op_errstr) {
+ cli_err("%s", op_errstr);
+ GF_FREE(op_errstr);
+ } else
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ CLI_LOCAL_INIT(local, words, frame, options);
+
+ 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 ("Setting global option failed");
- }
-
- CLI_STACK_DESTROY (frame);
- return ret;
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Setting global option failed");
+ }
+
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
+int
+cli_cmd_get_state_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ int sent = 0;
+ int parse_error = 0;
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+ cli_local_t *local = NULL;
+ char *op_errstr = NULL;
+
+ ret = cli_cmd_get_state_parse(state, words, wordcount, &options,
+ &op_errstr);
+
+ if (ret) {
+ if (op_errstr) {
+ cli_err("%s", op_errstr);
+ cli_usage_out(word->pattern);
+ GF_FREE(op_errstr);
+ } else
+ cli_usage_out(word->pattern);
+
+ parse_error = 1;
+ goto out;
+ }
+
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ CLI_LOCAL_INIT(local, words, frame, options);
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_STATE];
+ 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("Getting daemon state failed");
+ }
+
+ CLI_STACK_DESTROY(frame);
+
+ return ret;
+}
diff --git a/cli/src/cli-cmd-misc.c b/cli/src/cli-cmd-misc.c
index 9f8c159f073..e961d88da86 100644
--- a/cli/src/cli-cmd-misc.c
+++ b/cli/src/cli-cmd-misc.c
@@ -18,11 +18,9 @@
#include "cli-mem-types.h"
#include "protocol-common.h"
-extern struct rpc_clnt *global_rpc;
-
-extern rpc_clnt_prog_t *cli_rpc_prog;
-
extern struct cli_cmd volume_cmds[];
+extern struct cli_cmd bitrot_cmds[];
+extern struct cli_cmd quota_cmds[];
extern struct cli_cmd cli_probe_cmds[];
extern struct cli_cmd cli_log_cmds[];
extern struct cli_cmd cli_system_cmds[];
@@ -32,63 +30,88 @@ extern struct cli_cmd global_cmds[];
struct cli_cmd cli_misc_cmds[];
int
-cli_cmd_quit_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_quit_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- exit (0);
+ exit(0);
}
-int
-cli_cmd_display_help (struct cli_state *state, struct cli_cmd_word *in_word,
- const char **words, int wordcount)
+static gf_boolean_t
+cli_is_help_command(const char *pattern)
{
- struct cli_cmd *cmd[] = {volume_cmds, cli_probe_cmds,
- cli_misc_cmds, snapshot_cmds,
- global_cmds, NULL};
- struct cli_cmd *cmd_ind = NULL;
- int i = 0;
-
- /* cli_system_cmds commands for internal usage
- they are not exposed
- */
- for (i=0; cmd[i]!=NULL; i++)
- for (cmd_ind = cmd[i]; cmd_ind->pattern; cmd_ind++)
- if (_gf_false == cmd_ind->disable)
- cli_out ("%s - %s", cmd_ind->pattern,
- cmd_ind->desc);
-
- return 0;
+ /* FixFixFix
+ * This is not the best way to determine whether
+ * this is a help command
+ */
+ if (strstr(pattern, "help"))
+ return _gf_true;
+
+ return _gf_false;
}
-struct cli_cmd cli_misc_cmds[] = {
- { "quit",
- cli_cmd_quit_cbk,
- "quit"},
+int
+cli_cmd_display_help(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount)
+{
+ static struct cli_cmd *cmd[] = {
+ cli_misc_cmds, cli_probe_cmds, volume_cmds, bitrot_cmds,
+ quota_cmds, snapshot_cmds, global_cmds, NULL};
+ struct cli_cmd *cmd_ind = NULL;
+ int i = 0;
+ gf_boolean_t list_all = _gf_false;
+
+ /* cli_system_cmds commands for internal usage
+ they are not exposed
+ */
+
+ /* If "help all" */
+ if (wordcount == 2)
+ list_all = _gf_true;
+
+ for (i = 0; cmd[i] != NULL; i++) {
+ for (cmd_ind = cmd[i]; cmd_ind->pattern; cmd_ind++) {
+ if ((_gf_false == cmd_ind->disable) &&
+ cli_is_help_command(cmd_ind->pattern)) {
+ if (list_all && (cmd_ind->cbk)) {
+ cmd_ind->cbk(state, in_word, words, wordcount);
+ } else {
+ cli_out(" %-25s- %s", cmd_ind->pattern, cmd_ind->desc);
+ }
+ }
+ }
+ }
- { "help",
- cli_cmd_display_help,
- "display command options"},
+ cli_out("\n");
+ return 0;
+}
+
+struct cli_cmd cli_help_cmds[] = {
+ {"help [all]", cli_cmd_display_help, "display help for command classes"},
- { "exit",
- cli_cmd_quit_cbk,
- "exit"},
+ {NULL, NULL, NULL}};
- { NULL, NULL, NULL }
-};
+struct cli_cmd cli_misc_cmds[] = {{"quit", cli_cmd_quit_cbk, "quit"},
+ {"exit", cli_cmd_quit_cbk, "exit"},
+ {NULL, NULL, NULL}};
int
-cli_cmd_misc_register (struct cli_state *state)
+cli_cmd_misc_register(struct cli_state *state)
{
- int ret = 0;
- struct cli_cmd *cmd = NULL;
-
- for (cmd = cli_misc_cmds; cmd->pattern; cmd++) {
-
- ret = cli_cmd_register (&state->tree, cmd);
- if (ret)
- goto out;
- }
+ int ret = 0;
+ struct cli_cmd *cmd = NULL;
+
+ for (cmd = cli_misc_cmds; cmd->pattern; cmd++) {
+ ret = cli_cmd_register(&state->tree, cmd);
+ if (ret)
+ goto out;
+ }
+
+ for (cmd = cli_help_cmds; cmd->pattern; cmd++) {
+ ret = cli_cmd_register(&state->tree, cmd);
+ if (ret)
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index bd931ded3e0..34620b4a31b 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -12,3768 +12,4226 @@
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
+#include <fnmatch.h>
+#include <time.h>
#include "cli.h"
#include "cli-cmd.h"
#include "cli-mem-types.h"
-#include "dict.h"
+#include <glusterfs/dict.h>
+#include <glusterfs/list.h>
#include "protocol-common.h"
#include "cli1-xdr.h"
#define MAX_SNAP_DESCRIPTION_LEN 1024
-struct snap_config_opt_vals_ snap_confopt_vals[] = {
- {.op_name = "snap-max-hard-limit",
- .question = "Changing snapshot-max-hard-limit "
- "will limit the creation of new snapshots "
- "if they exceed the new limit.\n"
- "Do you want to continue?"
- },
- {.op_name = "snap-max-soft-limit",
- .question = "If Auto-delete is enabled, snap-max-soft-limit will"
- " trigger deletion of oldest snapshot, on the "
- "creation of new snapshot, when the "
- "snap-max-soft-limit is reached.\n"
- "Do you want to change the snap-max-soft-limit?"
- },
- {.op_name = "both",
- .question = "Changing snapshot-max-hard-limit "
- "will limit the creation of new snapshots "
- "if they exceed the new snapshot-max-hard-limit.\n"
- "If Auto-delete is enabled, snap-max-soft-limit will"
- " trigger deletion of oldest snapshot, on the "
- "creation of new snapshot, when the "
- "snap-max-soft-limit is reached.\n"
- "Do you want to continue?"
- },
- {.op_name = NULL,
- }
-};
+static struct snap_config_opt_vals_ snap_confopt_vals[] = {
+ {.op_name = "snap-max-hard-limit",
+ .question = "Changing snapshot-max-hard-limit "
+ "will limit the creation of new snapshots "
+ "if they exceed the new limit.\n"
+ "Do you want to continue?"},
+ {.op_name = "snap-max-soft-limit",
+ .question = "If Auto-delete is enabled, snap-max-soft-limit will"
+ " trigger deletion of oldest snapshot, on the "
+ "creation of new snapshot, when the "
+ "snap-max-soft-limit is reached.\n"
+ "Do you want to change the snap-max-soft-limit?"},
+ {.op_name = "both",
+ .question = "Changing snapshot-max-hard-limit "
+ "will limit the creation of new snapshots "
+ "if they exceed the new snapshot-max-hard-limit.\n"
+ "If Auto-delete is enabled, snap-max-soft-limit will"
+ " trigger deletion of oldest snapshot, on the "
+ "creation of new snapshot, when the "
+ "snap-max-soft-limit is reached.\n"
+ "Do you want to continue?"},
+ {
+ .op_name = NULL,
+ }};
enum cli_snap_config_set_types {
- GF_SNAP_CONFIG_SET_HARD = 0,
- GF_SNAP_CONFIG_SET_SOFT = 1,
- GF_SNAP_CONFIG_SET_BOTH = 2,
+ GF_SNAP_CONFIG_SET_HARD = 0,
+ GF_SNAP_CONFIG_SET_SOFT = 1,
+ GF_SNAP_CONFIG_SET_BOTH = 2,
};
typedef enum cli_snap_config_set_types cli_snap_config_set_types;
+typedef struct _cli_brick {
+ struct list_head list;
+ const char *name;
+ int32_t len;
+} cli_brick_t;
+
int
-cli_cmd_validate_volume (char *volname);
+cli_cmd_validate_volume(char *volname);
static const char *
-id_sel (void *wcon)
+id_sel(void *wcon)
{
- return (const char *)wcon;
+ return (const char *)wcon;
}
static char *
-str_getunamb (const char *tok, char **opwords)
+str_getunamb(const char *tok, char **opwords)
{
- return (char *)cli_getunamb (tok, (void **)opwords, id_sel);
+ 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)
+cli_cmd_ta_brick_parse(const char **words, int wordcount, char **ta_brick)
{
- int ret = 0;
- char *tmp_list = NULL;
- char brick_list[120000] = {0,};
- char *space = " ";
- char *delimiter = NULL;
- char *host_name = 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);
- GF_ASSERT (bricks);
- GF_ASSERT (brick_index > 0);
- GF_ASSERT (brick_index < wordcount);
-
- strncpy (brick_list, space, strlen (space));
- brick_list_len++;
- while (brick_index < wordcount) {
- 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 {
- delimiter = strrchr (words[brick_index], ':');
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
-
- if ((brick_list_len + strlen (words[brick_index]) + 1) > sizeof (brick_list)) {
- cli_err ("Total brick list is larger than a request. "
- "Can take (brick_count %d)", *brick_count);
- ret = -1;
- goto out;
- }
+ char *host_name = NULL;
+ char *tmp_host = NULL;
+ char *delimiter = NULL;
+ cli_brick_t *brick = NULL;
+ int ret = 0;
+
+ GF_ASSERT(words);
+ GF_ASSERT(wordcount);
+
+ if (validate_brick_name((char *)words[wordcount - 1])) {
+ cli_err(
+ "Wrong brick type: %s, use <HOSTNAME>:"
+ "<export-dir-abs-path>",
+ words[wordcount - 1]);
+ ret = -1;
+ goto out;
+ } else {
+ delimiter = strrchr(words[wordcount - 1], ':');
+ ret = gf_canonicalize_path(delimiter + 1);
+ if (ret)
+ goto out;
+ }
- 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 "
- "memory");
- goto out;
- }
+ tmp_host = gf_strdup((char *)words[wordcount - 1]);
+ 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 retrieve "
+ "hostname");
+ goto out;
+ }
+
+ if (!(strcmp(host_name, "localhost") && strcmp(host_name, "127.0.0.1") &&
+ strncmp(host_name, "0.", 2))) {
+ cli_err(
+ "Please provide a valid hostname/ip other "
+ "than localhost, 127.0.0.1 or loopback "
+ "address (0.0.0.0 to 0.255.255.255).");
+ ret = -1;
+ goto out;
+ }
+ if (!valid_internet_address(host_name, _gf_false, _gf_false)) {
+ cli_err(
+ "internet address '%s' does not conform to "
+ "standards",
+ host_name);
+ }
+
+ brick = GF_MALLOC(sizeof(cli_brick_t), gf_common_list_node);
+ if (brick == NULL) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Out of memory");
+ goto out;
+ }
- if (!(strcmp (host_name, "localhost") &&
- strcmp (host_name, "127.0.0.1") &&
- strncmp (host_name, "0.", 2))) {
- cli_err ("Please provide a valid hostname/ip other "
- "than localhost, 127.0.0.1 or loopback "
- "address (0.0.0.0 to 0.255.255.255).");
- ret = -1;
- GF_FREE (tmp_host);
- goto out;
- }
- if (!valid_internet_address (host_name, _gf_false)) {
- cli_err ("internet address '%s' does not conform to "
- "standards", host_name);
- }
- GF_FREE (tmp_host);
- tmp_list = gf_strdup (brick_list + 1);
- if (free_list_ptr) {
- GF_FREE (free_list_ptr);
- free_list_ptr = NULL;
- }
- free_list_ptr = tmp_list;
- j = 0;
- while(j < *brick_count) {
- strtok_r (tmp_list, " ", &tmpptr);
- if (!(strcmp (tmp_list, words[brick_index]))) {
- ret = -1;
- cli_err ("Found duplicate"
- " exports %s",words[brick_index]);
- goto out;
- }
- tmp_list = tmpptr;
- j++;
- }
- strcat (brick_list, words[brick_index]);
- strcat (brick_list, " ");
- brick_list_len += (strlen (words[brick_index]) + 1);
- ++(*brick_count);
- ++brick_index;
- }
+ brick->name = words[wordcount - 1];
+ brick->len = strlen(words[wordcount - 1]);
+ *ta_brick = GF_MALLOC(brick->len + 3, gf_common_mt_char);
+ if (*ta_brick == NULL) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Out of memory");
+ goto out;
+ }
- *bricks = gf_strdup (brick_list);
- if (!*bricks)
- ret = -1;
+ strcat(*ta_brick, " ");
+ strcat(*ta_brick, brick->name);
+ strcat(*ta_brick, " ");
out:
- GF_FREE (free_list_ptr);
- return ret;
+ if (tmp_host) {
+ GF_FREE(tmp_host);
+ tmp_host = NULL;
+ }
+ if (brick) {
+ GF_FREE(brick);
+ brick = NULL;
+ }
+
+ return ret;
}
int32_t
-cli_cmd_create_disperse_check (struct cli_state *state, int *disperse,
- int *redundancy, int *data, int count)
+cli_cmd_bricks_parse(const char **words, int wordcount, int brick_index,
+ char **bricks, int *brick_count)
{
- int i = 0;
- int tmp = 0;
- gf_answer_t answer = GF_ANSWER_NO;
- char question[128];
-
- const char *question1 = "There isn't an optimal redundancy value "
- "for this configuration. Do you want to "
- "create the volume with redundancy 1 ?";
-
- const char *question2 = "The optimal redundancy for this "
- "configuration is %d. Do you want to create "
- "the volume with this value ?";
-
- const char *question3 = "This configuration is not optimal on most "
- "workloads. Do you want to use it ?";
-
- const char *question4 = "Redundancy for this configuration is %d. "
- "Do you want to create "
- "the volume with this value ?";
-
- if (*data > 0) {
- if (*disperse > 0 && *redundancy > 0) {
- if (*disperse != (*data + *redundancy)) {
- cli_err ("Disperse count(%d) should be equal "
- "to sum of disperse-data count(%d) and "
- "redundancy count(%d)", *disperse,
- *data, *redundancy);
- return -1;
- }
- } else if (*redundancy > 0) {
- *disperse = *data + *redundancy;
- } else if (*disperse > 0) {
- *redundancy = *disperse - *data;
- } else {
- if ((count - *data) >= *data) {
- cli_err ("Please provide redundancy count "
- "along with disperse-data count");
- return -1;
- } else {
- sprintf (question, question4, count - *data);
- answer = cli_cmd_get_confirmation (state,
- question);
- if (answer == GF_ANSWER_NO)
- return -1;
- *redundancy = count - *data;
- *disperse = count;
- }
- }
+ int ret = 0;
+ char *delimiter = NULL;
+ char *host_name = NULL;
+ char *tmp_host = NULL;
+ char *bricks_str = NULL;
+ int len = 0;
+ int brick_list_len = 1; /* For initial space */
+ struct list_head brick_list = {
+ 0,
+ };
+ cli_brick_t *brick = NULL;
+
+ GF_ASSERT(words);
+ GF_ASSERT(wordcount);
+ GF_ASSERT(bricks);
+ GF_ASSERT(brick_index > 0);
+ GF_ASSERT(brick_index < wordcount);
+
+ INIT_LIST_HEAD(&brick_list);
+
+ while (brick_index < wordcount) {
+ 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 {
+ delimiter = strrchr(words[brick_index], ':');
+ ret = gf_canonicalize_path(delimiter + 1);
+ if (ret)
+ goto out;
}
- if (*disperse <= 0) {
- if (count < 3) {
- cli_err ("number of bricks must be greater "
- "than 2");
+ 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 "
+ "memory");
+ GF_FREE(tmp_host);
+ goto out;
+ }
+
+ if (!(strcmp(host_name, "localhost") &&
+ strcmp(host_name, "127.0.0.1") && strncmp(host_name, "0.", 2))) {
+ cli_err(
+ "Please provide a valid hostname/ip other "
+ "than localhost, 127.0.0.1 or loopback "
+ "address (0.0.0.0 to 0.255.255.255).");
+ ret = -1;
+ GF_FREE(tmp_host);
+ goto out;
+ }
+ if (!valid_internet_address(host_name, _gf_false, _gf_false)) {
+ cli_err(
+ "internet address '%s' does not conform to "
+ "standards",
+ host_name);
+ }
+ GF_FREE(tmp_host);
+ list_for_each_entry(brick, &brick_list, list)
+ {
+ if (strcmp(brick->name, words[brick_index]) == 0) {
+ ret = -1;
+ cli_err("Found duplicate exports %s", words[brick_index]);
+ goto out;
+ }
+ }
- return -1;
- }
- *disperse = count;
+ brick = GF_MALLOC(sizeof(cli_brick_t), gf_common_list_node);
+ if (brick == NULL) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Out of memory");
+ goto out;
}
+ len = strlen(words[brick_index]);
+ brick->name = words[brick_index];
+ brick->len = len;
+ list_add_tail(&brick->list, &brick_list);
- if (*redundancy == -1) {
- tmp = *disperse - 1;
- for (i = tmp / 2;
- (i > 0) && ((tmp & -tmp) != tmp);
- i--, tmp--);
+ brick_list_len += len + 1; /* Brick name + space */
+ ++(*brick_count);
+ ++brick_index;
+ }
- if (i == 0) {
- answer = cli_cmd_get_confirmation(state, question1);
- if (answer == GF_ANSWER_NO)
- return -1;
+ /* If brick count is not valid exit here */
+ if (!*brick_count) {
+ cli_err("No bricks specified");
+ ret = -1;
+ goto out;
+ }
- *redundancy = 1;
- }
- else
- {
- *redundancy = *disperse - tmp;
- if (*redundancy > 1) {
- sprintf(question, question2, *redundancy);
- answer = cli_cmd_get_confirmation(state,
- question);
- if (answer == GF_ANSWER_NO)
- return -1;
- }
- }
+ brick_list_len++; /* For terminating null char */
+
+ bricks_str = GF_MALLOC(brick_list_len, gf_common_mt_char);
+ if (bricks_str == NULL) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Out of memory");
+ goto out;
+ }
+ *bricks = bricks_str;
+ *bricks_str = ' ';
+ bricks_str++;
+ while (!list_empty(&brick_list)) {
+ brick = list_first_entry(&brick_list, cli_brick_t, list);
+ list_del_init(&brick->list);
+ memcpy(bricks_str, brick->name, brick->len);
+ bricks_str[brick->len] = ' ';
+ bricks_str += brick->len + 1;
+ GF_FREE(brick);
+ }
+ *bricks_str = 0;
+
+out:
+ while (!list_empty(&brick_list)) {
+ brick = list_first_entry(&brick_list, cli_brick_t, list);
+ list_del_init(&brick->list);
+ GF_FREE(brick);
+ }
- tmp = 0;
+ return ret;
+}
+
+int32_t
+cli_cmd_create_disperse_check(struct cli_state *state, int *disperse,
+ int *redundancy, int *data, int count)
+{
+ int i = 0;
+ int tmp = 0;
+ gf_answer_t answer = GF_ANSWER_NO;
+ char question[128];
+
+ const char *question1 =
+ "There isn't an optimal redundancy value "
+ "for this configuration. Do you want to "
+ "create the volume with redundancy 1 ?";
+
+ const char *question2 =
+ "The optimal redundancy for this "
+ "configuration is %d. Do you want to create "
+ "the volume with this value ?";
+
+ const char *question3 =
+ "This configuration is not optimal on most "
+ "workloads. Do you want to use it ?";
+
+ const char *question4 =
+ "Redundancy for this configuration is %d. "
+ "Do you want to create "
+ "the volume with this value ?";
+
+ if (*data > 0) {
+ if (*disperse > 0 && *redundancy > 0) {
+ if (*disperse != (*data + *redundancy)) {
+ cli_err(
+ "Disperse count(%d) should be equal "
+ "to sum of disperse-data count(%d) and "
+ "redundancy count(%d)",
+ *disperse, *data, *redundancy);
+ return -1;
+ }
+ } else if (*redundancy > 0) {
+ *disperse = *data + *redundancy;
+ } else if (*disperse > 0) {
+ *redundancy = *disperse - *data;
} else {
- tmp = *disperse - *redundancy;
+ if ((count - *data) >= *data) {
+ cli_err(
+ "Please provide redundancy count "
+ "along with disperse-data count");
+ return -1;
+ } else {
+ sprintf(question, question4, count - *data);
+ answer = cli_cmd_get_confirmation(state, question);
+ if (answer == GF_ANSWER_NO)
+ return -1;
+ *redundancy = count - *data;
+ *disperse = count;
+ }
}
+ }
- if (*redundancy > (*disperse - 1) / 2) {
- cli_err ("redundancy must be less than %d for a "
- "disperse %d volume",
- (*disperse + 1) / 2, *disperse);
+ if (*disperse <= 0) {
+ if (count < 3) {
+ cli_err(
+ "number of bricks must be greater "
+ "than 2");
- return -1;
+ return -1;
}
+ *disperse = count;
+ }
+
+ if (*redundancy == -1) {
+ tmp = *disperse - 1;
+ for (i = tmp / 2; (i > 0) && ((tmp & -tmp) != tmp); i--, tmp--)
+ ;
+
+ if (i == 0) {
+ answer = cli_cmd_get_confirmation(state, question1);
+ if (answer == GF_ANSWER_NO)
+ return -1;
- if ((tmp & -tmp) != tmp) {
- answer = cli_cmd_get_confirmation(state, question3);
+ *redundancy = 1;
+ } else {
+ *redundancy = *disperse - tmp;
+ if (*redundancy > 1) {
+ sprintf(question, question2, *redundancy);
+ answer = cli_cmd_get_confirmation(state, question);
if (answer == GF_ANSWER_NO)
- return -1;
+ return -1;
+ }
}
- return 0;
+ tmp = 0;
+ } else {
+ tmp = *disperse - *redundancy;
+ }
+
+ if ((*redundancy < 1) || (*redundancy > (*disperse - 1) / 2)) {
+ cli_err(
+ "redundancy must be greater than or equal to 1 and "
+ "less than %d for a disperse %d volume",
+ (*disperse + 1) / 2, *disperse);
+
+ return -1;
+ }
+
+ if ((tmp & -tmp) != tmp) {
+ answer = cli_cmd_get_confirmation(state, question3);
+ if (answer == GF_ANSWER_NO)
+ return -1;
+ }
+
+ return 0;
}
static int32_t
-cli_validate_disperse_volume (char *word, gf1_cluster_type type,
- const char **words, int32_t wordcount,
- int32_t index, int32_t *disperse_count,
- int32_t *redundancy_count,
- int32_t *data_count)
+cli_validate_disperse_volume(char *word, gf1_cluster_type type,
+ const char **words, int32_t wordcount,
+ int32_t index, int32_t *disperse_count,
+ int32_t *redundancy_count, int32_t *data_count)
{
- int ret = -1;
+ int ret = -1;
- switch (type) {
+ switch (type) {
case GF_CLUSTER_TYPE_NONE:
case GF_CLUSTER_TYPE_DISPERSE:
- if (strcmp (word, "disperse") == 0) {
- if (*disperse_count >= 0) {
- cli_err ("disperse option given twice");
- goto out;
- }
- if (wordcount < (index+2)) {
- goto out;
- }
- ret = gf_string2int (words[index + 1], disperse_count);
- if (ret == -1 && errno == EINVAL) {
- *disperse_count = 0;
- ret = 1;
- } else if (ret == -1) {
- goto out;
- } else {
- if (*disperse_count < 3) {
- cli_err ("disperse count must "
- "be greater than 2");
- goto out;
- }
- ret = 2;
- }
- } else if (strcmp (word, "disperse-data") == 0) {
- if (*data_count >= 0) {
- cli_err ("disperse-data option given twice");
- goto out;
- }
- if (wordcount < (index+2)) {
- goto out;
- }
- ret = gf_string2int (words[index+1], data_count);
- if (ret == -1 || *data_count < 2) {
- cli_err ("disperse-data must be greater than 1");
- goto out;
- }
- ret = 2;
- } else if (strcmp (word, "redundancy") == 0) {
- if (*redundancy_count >= 0) {
- cli_err ("redundancy option given twice");
- goto out;
- }
- if (wordcount < (index+2)) {
- goto out;
- }
- ret = gf_string2int (words[index+1], redundancy_count);
- if (ret == -1 || *redundancy_count < 1) {
- cli_err ("redundancy must be greater than 0");
- goto out;
- }
- ret = 2;
- }
- break;
- case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
- cli_err ("striped-replicated-dispersed volume "
- "is not supported");
- goto out;
- case GF_CLUSTER_TYPE_TIER:
- cli_err ("tier-dispersed volume is not "
- "supported");
- goto out;
- case GF_CLUSTER_TYPE_STRIPE:
- cli_err ("striped-dispersed volume is not "
- "supported");
- goto out;
+ if (strcmp(word, "disperse") == 0) {
+ if (*disperse_count >= 0) {
+ cli_err("disperse option given twice");
+ goto out;
+ }
+ if (wordcount < (index + 2)) {
+ goto out;
+ }
+ ret = gf_string2int(words[index + 1], disperse_count);
+ if (ret == -1 && errno == EINVAL) {
+ *disperse_count = 0;
+ ret = 1;
+ } else if (ret == -1) {
+ goto out;
+ } else {
+ if (*disperse_count < 3) {
+ cli_err(
+ "disperse count must "
+ "be greater than 2");
+ goto out;
+ }
+ ret = 2;
+ }
+ } else if (strcmp(word, "disperse-data") == 0) {
+ if (*data_count >= 0) {
+ cli_err("disperse-data option given twice");
+ goto out;
+ }
+ if (wordcount < (index + 2)) {
+ goto out;
+ }
+ ret = gf_string2int(words[index + 1], data_count);
+ if (ret == -1 || *data_count < 2) {
+ cli_err("disperse-data must be greater than 1");
+ goto out;
+ }
+ ret = 2;
+ } else if (strcmp(word, "redundancy") == 0) {
+ if (*redundancy_count >= 0) {
+ cli_err("redundancy option given twice");
+ goto out;
+ }
+ if (wordcount < (index + 2)) {
+ goto out;
+ }
+ ret = gf_string2int(words[index + 1], redundancy_count);
+ if (ret == -1 || *redundancy_count < 1) {
+ cli_err("redundancy must be greater than 0");
+ goto out;
+ }
+ ret = 2;
+ }
+ break;
case GF_CLUSTER_TYPE_REPLICATE:
- cli_err ("replicated-dispersed volume is not "
- "supported");
- goto out;
+ cli_err(
+ "replicated-dispersed volume is not "
+ "supported");
+ goto out;
default:
- cli_err ("Invalid type given");
- break;
- }
+ cli_err("Invalid type given");
+ break;
+ }
out:
- return ret;
+ return ret;
}
int32_t
-cli_validate_volname (const char *volname)
+cli_validate_volname(const char *volname)
{
- int32_t ret = -1;
- int32_t i = -1;
- static const char * const invalid_volnames[] = {
- "volume", "type", "subvolumes", "option",
- "end-volume", "all", "volume_not_in_ring",
- "description", "force",
- "snap-max-hard-limit",
- "snap-max-soft-limit", "auto-delete",
- "activate-on-create", NULL};
-
- if (volname[0] == '-')
- goto out;
-
- for (i = 0; invalid_volnames[i]; i++) {
- if (!strcmp (volname, invalid_volnames[i])) {
- cli_err ("\"%s\" cannot be the name of a volume.",
- volname);
- goto out;
- }
- }
+ int32_t ret = -1;
+ int32_t i = -1;
+ int volname_len;
+ static const char *const invalid_volnames[] = {"volume",
+ "type",
+ "subvolumes",
+ "option",
+ "end-volume",
+ "all",
+ "volume_not_in_ring",
+ "description",
+ "force",
+ "snap-max-hard-limit",
+ "snap-max-soft-limit",
+ "auto-delete",
+ "activate-on-create",
+ NULL};
- if (strchr (volname, '/'))
- goto out;
+ if (volname[0] == '-')
+ goto out;
- if (strlen (volname) > GD_VOLUME_NAME_MAX) {
- cli_err("Volume name exceeds %d characters.",
- GD_VOLUME_NAME_MAX);
- goto out;
+ for (i = 0; invalid_volnames[i]; i++) {
+ if (!strcmp(volname, invalid_volnames[i])) {
+ cli_err("\"%s\" cannot be the name of a volume.", volname);
+ goto out;
}
+ }
- for (i = 0; i < strlen (volname); i++) {
- if (!isalnum (volname[i]) && (volname[i] != '_') &&
- (volname[i] != '-')) {
- cli_err ("Volume name should not contain \"%c\""
- " character.\nVolume names can only"
- "contain alphanumeric, '-' and '_' "
- "characters.", volname[i]);
- goto out;
- }
- }
+ if (strchr(volname, '/'))
+ goto out;
- ret = 0;
+ volname_len = strlen(volname);
+ if (volname_len > GD_VOLUME_NAME_MAX) {
+ cli_err("Volume name exceeds %d characters.", GD_VOLUME_NAME_MAX);
+ goto out;
+ }
+
+ for (i = 0; i < volname_len; i++) {
+ if (!isalnum(volname[i]) && (volname[i] != '_') &&
+ (volname[i] != '-')) {
+ cli_err(
+ "Volume name should not contain \"%c\""
+ " character.\nVolume names can only"
+ "contain alphanumeric, '-' and '_' "
+ "characters.",
+ volname[i]);
+ goto out;
+ }
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
int32_t
-cli_cmd_volume_create_parse (struct cli_state *state, const char **words,
- int wordcount, dict_t **options)
+cli_cmd_volume_create_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **brick_list)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- int ret = -1;
- gf1_cluster_type type = GF_CLUSTER_TYPE_NONE;
- int count = 1;
- int sub_count = 1;
- int brick_index = 0;
- char *trans_type = NULL;
- int32_t index = 0;
- char *bricks = NULL;
- int32_t brick_count = 0;
- char *opwords[] = { "replica", "stripe", "transport", "disperse",
- "redundancy", "disperse-data", "arbiter", NULL };
-
- char *w = NULL;
- char *ptr = NULL;
- int op_count = 0;
- int32_t replica_count = 1;
- int32_t arbiter_count = 0;
- int32_t stripe_count = 1;
- int32_t disperse_count = -1;
- int32_t redundancy_count = -1;
- int32_t disperse_data_count = -1;
- gf_boolean_t is_force = _gf_false;
- int wc = wordcount;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
-
- dict = dict_new ();
-
- if (!dict)
- goto out;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int ret = -1;
+ gf1_cluster_type type = GF_CLUSTER_TYPE_NONE;
+ int sub_count = 1;
+ int brick_index = 0;
+ char *trans_type = NULL;
+ int32_t index = 0;
+ char *bricks = NULL;
+ char *ta_brick = NULL;
+ int32_t brick_count = 0;
+ static char *opwords[] = {"replica", "stripe", "transport",
+ "disperse", "redundancy", "disperse-data",
+ "arbiter", "thin-arbiter", NULL};
+
+ char *w = NULL;
+ int op_count = 0;
+ int32_t replica_count = 1;
+ int32_t arbiter_count = 0;
+ int32_t thin_arbiter_count = 0;
+ int32_t stripe_count = 1;
+ int32_t disperse_count = -1;
+ int32_t redundancy_count = -1;
+ int32_t disperse_data_count = -1;
+ gf_boolean_t is_force = _gf_false;
+ int wc = wordcount;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *question = NULL;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ dict = dict_new();
+
+ if (!dict)
+ goto out;
- if (wordcount < 3)
- goto out;
+ if (wordcount < 3)
+ goto out;
- volname = (char *)words[2];
+ volname = (char *)words[2];
- GF_ASSERT (volname);
+ GF_ASSERT(volname);
- /* Validate the volume name here itself */
- if (cli_validate_volname (volname) < 0)
- goto out;
+ /* Validate the volume name here itself */
+ if (cli_validate_volname(volname) < 0)
+ goto out;
- if (wordcount < 4) {
- ret = -1;
- goto out;
- }
+ if (wordcount < 4) {
+ ret = -1;
+ goto out;
+ }
- type = GF_CLUSTER_TYPE_NONE;
- index = 3;
+ type = GF_CLUSTER_TYPE_NONE;
+ index = 3;
- while (op_count < 3) {
+ while (op_count < 3) {
+ ret = -1;
+ 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:
+ cli_err("stripe option not supported");
+ goto out;
+ case GF_CLUSTER_TYPE_DISPERSE:
+ cli_err(
+ "replicated-dispersed volume is not "
+ "supported");
+ goto out;
+ default:
+ cli_err("Invalid type given");
+ goto out;
+ }
+
+ if (wordcount < (index + 2)) {
ret = -1;
- 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;
- case GF_CLUSTER_TYPE_TIER:
- cli_err ("replicated-tiered volume is not "
- "supported");
- goto out;
- break;
- case GF_CLUSTER_TYPE_DISPERSE:
- cli_err ("replicated-dispersed volume is not "
- "supported");
- goto out;
- default:
- cli_err ("Invalid type given");
- 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;
- if (words[index]) {
- if (!strcmp (words[index], "arbiter")) {
- ret = gf_string2int (words[index+1],
- &arbiter_count);
- if (ret == -1 || arbiter_count != 1 ||
- replica_count != 3) {
- cli_err ("For arbiter "
- "configuration, "
- "replica count must be"
- " 3 and arbiter count "
- "must be 1. The 3rd "
- "brick of the replica "
- "will be the arbiter");
- ret = -1;
- goto out;
- }
- ret = dict_set_int32 (dict, "arbiter-count",
- arbiter_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;
- case GF_CLUSTER_TYPE_DISPERSE:
- cli_err ("striped-dispersed volume is not "
- "supported");
- goto out;
- case GF_CLUSTER_TYPE_TIER:
- cli_err ("striped-tier volume is not "
- "supported");
- goto out;
- default:
- cli_err ("Invalid type given");
- goto out;
- }
- 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;
-
- index += 2;
+ goto out;
+ }
- } 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 if ((strcmp (w, "disperse") == 0) ||
- (strcmp (w, "redundancy") == 0) ||
- (strcmp (w, "disperse-data") == 0)) {
- ret = cli_validate_disperse_volume (w, type, words,
- wordcount, index, &disperse_count,
- &redundancy_count, &disperse_data_count);
- if (ret < 0)
- goto out;
- index += ret;
- type = GF_CLUSTER_TYPE_DISPERSE;
- } else {
- GF_ASSERT (!"opword mismatch");
+ 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;
+ }
+
+ index += 2;
+ if (words[index]) {
+ if (!strcmp(words[index], "arbiter")) {
+ ret = gf_string2int(words[index + 1], &arbiter_count);
+ if ((ret == -1) || (arbiter_count != 1)) {
+ cli_err(
+ "For arbiter "
+ "configuration, "
+ "replica count must be"
+ " 2 and arbiter count "
+ "must be 1. The 3rd "
+ "brick of the replica "
+ "will be the arbiter");
ret = -1;
goto out;
- }
- op_count++;
- }
-
- if (!trans_type)
- trans_type = gf_strdup ("tcp");
-
- /* reset the count value now */
- count = 1;
-
- if (index >= wordcount) {
+ }
+ ret = dict_set_int32(dict, "arbiter-count", arbiter_count);
+ if (ret)
+ goto out;
+ index += 2;
+ } else if (!strcmp(words[index], "thin-arbiter")) {
+ ret = gf_string2int(words[index + 1], &thin_arbiter_count);
+ if ((ret == -1) || (thin_arbiter_count != 1) ||
+ (replica_count != 2)) {
+ cli_err(
+ "For thin-arbiter "
+ "configuration, "
+ "replica count must be"
+ " 2 and thin-arbiter count "
+ "must be 1. The 3rd "
+ "brick of the replica "
+ "will be the thin-arbiter brick");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_int32(dict, "thin-arbiter-count",
+ thin_arbiter_count);
+ if (ret)
+ goto out;
+ index += 2;
+ }
+ }
+
+ /* Do this to keep glusterd happy with sending
+ "replica 3 arbiter 1" options to server */
+ if ((arbiter_count == 1) && (replica_count == 2))
+ replica_count += arbiter_count;
+
+ if (replica_count == 2 && thin_arbiter_count == 0) {
+ if (strcmp(words[wordcount - 1], "force")) {
+ question =
+ "Replica 2 volumes are prone"
+ " to split-brain. Use "
+ "Arbiter or Replica 3 to "
+ "avoid this. See: "
+ "http://docs.gluster.org/en/latest/"
+ "Administrator%20Guide/"
+ "Split%20brain%20and%20ways%20to%20deal%20with%20it/."
+ "\nDo you still want to "
+ "continue?\n";
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Volume create "
+ "cancelled, exiting");
+ ret = -1;
+ goto out;
+ }
+ }
+ }
+ ret = dict_set_int32(dict, "replica-count", replica_count);
+ if (ret)
+ goto out;
+
+ } else if ((strcmp(w, "stripe")) == 0) {
+ cli_err("stripe option not supported");
+ goto out;
+ } 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 if ((strcmp(w, "disperse") == 0) ||
+ (strcmp(w, "redundancy") == 0) ||
+ (strcmp(w, "disperse-data") == 0)) {
+ ret = cli_validate_disperse_volume(
+ w, type, words, wordcount, index, &disperse_count,
+ &redundancy_count, &disperse_data_count);
+ if (ret < 0)
+ goto out;
+ index += ret;
+ type = GF_CLUSTER_TYPE_DISPERSE;
+ } else if ((strcmp(w, "arbiter") == 0)) {
+ cli_err(
+ "arbiter option must be preceded by replica "
+ "option.");
+ ret = -1;
+ goto out;
+ } else if ((strcmp(w, "thin-arbiter") == 0)) {
+ cli_err(
+ "thin-arbiter option must be preceded by replica "
+ "option.");
+ ret = -1;
+ goto out;
+ } else {
+ GF_ASSERT(!"opword mismatch");
+ ret = -1;
+ goto out;
}
+ op_count++;
+ }
- brick_index = index;
+ if (!trans_type)
+ trans_type = gf_strdup("tcp");
- if (strcmp (words[wordcount - 1], "force") == 0) {
- is_force = _gf_true;
- wc = wordcount - 1;
- }
+ if (index >= wordcount) {
+ ret = -1;
+ goto out;
+ }
- ret = cli_cmd_bricks_parse (words, wc, brick_index, &bricks,
- &brick_count);
- if (ret)
- goto out;
+ brick_index = index;
- /* If brick-count is not valid when replica or stripe is
- given, exit here */
- if (!brick_count) {
- cli_err ("No bricks specified");
- ret = -1;
- goto out;
- }
+ if (strcmp(words[wordcount - 1], "force") == 0) {
+ is_force = _gf_true;
+ wc = wordcount - 1;
+ }
- if (type == GF_CLUSTER_TYPE_DISPERSE) {
- ret = cli_cmd_create_disperse_check (state, &disperse_count,
- &redundancy_count,
- &disperse_data_count,
- brick_count);
- if (!ret)
- ret = dict_set_int32 (dict, "disperse-count",
- disperse_count);
- if (!ret)
- ret = dict_set_int32 (dict, "redundancy-count",
- redundancy_count);
- if (ret)
- goto out;
+ // Exclude the thin-arbiter-brick i.e. last brick in the bricks list
+ if (thin_arbiter_count == 1) {
+ ret = cli_cmd_bricks_parse(words, wc - 1, brick_index, &bricks,
+ &brick_count);
+ if (ret)
+ goto out;
- sub_count = disperse_count;
- } else
- sub_count = stripe_count * replica_count;
-
- if (brick_count % sub_count) {
- if (type == GF_CLUSTER_TYPE_STRIPE)
- cli_err ("number of bricks is not a multiple of "
- "stripe count");
- else if (type == GF_CLUSTER_TYPE_REPLICATE)
- cli_err ("number of bricks is not a multiple of "
- "replica count");
- else if (type == GF_CLUSTER_TYPE_DISPERSE)
- cli_err ("number of bricks is not a multiple of "
- "disperse count");
- else
- cli_err ("number of bricks given doesn't match "
- "required count");
+ ret = cli_cmd_ta_brick_parse(words, wc, &ta_brick);
- ret = -1;
- goto out;
- }
+ } else {
+ ret = cli_cmd_bricks_parse(words, wc, brick_index, &bricks,
+ &brick_count);
+ }
- /* Everything is parsed fine. start setting info in dict */
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "type", type);
+ if (type == GF_CLUSTER_TYPE_DISPERSE) {
+ ret = cli_cmd_create_disperse_check(state, &disperse_count,
+ &redundancy_count,
+ &disperse_data_count, brick_count);
+ if (!ret)
+ ret = dict_set_int32(dict, "disperse-count", disperse_count);
+ if (!ret)
+ ret = dict_set_int32(dict, "redundancy-count", redundancy_count);
if (ret)
- goto out;
+ goto out;
+
+ sub_count = disperse_count;
+ } else
+ sub_count = stripe_count * replica_count;
+
+ if (brick_count % sub_count) {
+ if (type == GF_CLUSTER_TYPE_STRIPE)
+ cli_err(
+ "number of bricks is not a multiple of "
+ "stripe count");
+ else if (type == GF_CLUSTER_TYPE_REPLICATE)
+ cli_err(
+ "number of bricks is not a multiple of "
+ "replica count");
+ else if (type == GF_CLUSTER_TYPE_DISPERSE)
+ cli_err(
+ "number of bricks is not a multiple of "
+ "disperse count");
+ else
+ cli_err(
+ "number of bricks given doesn't match "
+ "required count");
- ret = dict_set_dynstr (dict, "transport", trans_type);
- if (ret)
- goto out;
- trans_type = NULL;
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_dynstr (dict, "bricks", bricks);
- if (ret)
- goto out;
+ /* Everything is parsed fine. start setting info in dict */
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "count", brick_count);
- if (ret)
- goto out;
+ ret = dict_set_int32(dict, "type", type);
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "force", is_force);
+ ret = dict_set_dynstr(dict, "transport", trans_type);
+ if (ret)
+ goto out;
+ trans_type = NULL;
+
+ ret = dict_set_dynstr(dict, "bricks", bricks);
+ if (ret)
+ goto out;
+
+ if (thin_arbiter_count == 1) {
+ ret = dict_set_dynstr(dict, "ta-brick", ta_brick);
if (ret)
- goto out;
+ goto out;
+ }
- *options = dict;
+ ret = dict_set_int32(dict, "count", brick_count);
+ if (ret)
+ goto out;
+
+ ret = dict_set_int32(dict, "force", is_force);
+ if (ret)
+ goto out;
+ *options = dict;
+ *brick_list = bricks;
out:
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to parse create volume CLI");
- if (dict)
- dict_destroy (dict);
- }
+ if (ret) {
+ GF_FREE(bricks);
+ GF_FREE(ta_brick);
+ gf_log("cli", GF_LOG_ERROR, "Unable to parse create volume CLI");
+ if (dict)
+ dict_unref(dict);
+ }
- GF_FREE (trans_type);
+ GF_FREE(trans_type);
- return ret;
+ return ret;
}
int32_t
-cli_cmd_volume_reset_parse (const char **words, int wordcount, dict_t **options)
+cli_cmd_volume_reset_parse(const char **words, int wordcount, dict_t **options)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- int ret = -1;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int ret = -1;
- GF_ASSERT (words);
- GF_ASSERT (options);
+ GF_ASSERT(words);
+ GF_ASSERT(options);
- dict = dict_new ();
+ dict = dict_new();
- if (!dict)
- goto out;
+ if (!dict)
+ goto out;
- if (wordcount < 3)
- goto out;
+ if (wordcount < 3)
+ goto out;
- if (wordcount > 5)
- goto out;
+ if (wordcount > 5)
+ goto out;
- volname = (char *)words[2];
+ volname = (char *)words[2];
- if (!volname) {
- ret = -1;
- goto out;
- }
+ if (!volname) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- if (wordcount == 3) {
- ret = dict_set_str (dict, "key", "all");
- if (ret)
- goto out;
- }
+ 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 >= 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 {
- ret = dict_set_int32 (dict, "force", 1);
- if (ret)
- goto out;
- }
+ if (wordcount == 5) {
+ if (strcmp("force", (char *)words[4])) {
+ ret = -1;
+ goto out;
+ } else {
+ ret = dict_set_int32(dict, "force", 1);
+ if (ret)
+ goto out;
}
+ }
- *options = dict;
+ *options = dict;
out:
- if (ret && dict) {
- dict_destroy (dict);
- }
+ if (ret && dict) {
+ dict_unref(dict);
+ }
- return ret;
+ return ret;
}
-/* Parsing global option for NFS-Ganesha config
- * gluster nfs-ganesha enable/disable */
-
int32_t
-cli_cmd_ganesha_parse (struct cli_state *state,
- const char **words, int wordcount,
- dict_t **options, char **op_errstr)
+cli_cmd_get_state_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **op_errstr)
{
- dict_t *dict = NULL;
- int ret = -1;
- int flags = 0;
- char *key = NULL;
- char *value = NULL;
- int i = 0;
- char *w = NULL;
- char *opwords[] = { "enable", "disable", NULL };
- const char *question = NULL;
- gf_answer_t answer = GF_ANSWER_NO;
+ dict_t *dict = NULL;
+ int ret = -1;
+ char *odir = NULL;
+ char *filename = NULL;
+ char *daemon_name = NULL;
+ int count = 0;
+ uint32_t cmd = 0;
+
+ GF_VALIDATE_OR_GOTO("cli", options, out);
+ GF_VALIDATE_OR_GOTO("cli", words, out);
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
+ if (wordcount < 1 || wordcount > 7) {
+ *op_errstr = gf_strdup(
+ "Problem parsing arguments."
+ " Check usage.");
+ goto out;
+ }
+
+ if (wordcount >= 1) {
+ gf_asprintf(&daemon_name, "%s", "glusterd");
+
+ for (count = 1; count < wordcount; count++) {
+ if (strcmp(words[count], "odir") == 0 ||
+ strcmp(words[count], "file") == 0) {
+ if (strcmp(words[count], "odir") == 0) {
+ if (++count < wordcount) {
+ odir = (char *)words[count];
+ continue;
+ } else {
+ ret = -1;
+ goto out;
+ }
+ } else if (strcmp(words[count], "file") == 0) {
+ if (++count < wordcount) {
+ filename = (char *)words[count];
+ continue;
+ } else {
+ ret = -1;
+ goto out;
+ }
+ }
+ } else {
+ if (count > 1) {
+ if (count == wordcount - 1) {
+ if (strcmp(words[count], "detail") == 0) {
+ cmd = GF_CLI_GET_STATE_DETAIL;
+ continue;
+ } else if (strcmp(words[count], "volumeoptions") == 0) {
+ cmd = GF_CLI_GET_STATE_VOLOPTS;
+ continue;
+ }
+ } else {
+ *op_errstr = gf_strdup(
+ "Problem"
+ " parsing arguments. "
+ "Check usage.");
+ ret = -1;
+ goto out;
+ }
+ }
+ if (strcmp(words[count], "glusterd") == 0) {
+ continue;
+ } else {
+ if (count == wordcount - 1) {
+ if (strcmp(words[count], "detail") == 0) {
+ cmd = GF_CLI_GET_STATE_DETAIL;
+ continue;
+ } else if (strcmp(words[count], "volumeoptions") == 0) {
+ cmd = GF_CLI_GET_STATE_VOLOPTS;
+ continue;
+ }
+ }
- GF_ASSERT (words);
- GF_ASSERT (options);
+ *op_errstr = gf_strdup(
+ "glusterd is "
+ "the only supported daemon.");
+ ret = -1;
+ goto out;
+ }
+ }
+ }
- dict = dict_new ();
+ ret = dict_set_dynstr(dict, "daemon", daemon_name);
+ if (ret) {
+ *op_errstr = gf_strdup(
+ "Command failed. Please check "
+ " log file for more details.");
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "Setting daemon name to dictionary failed");
+ goto out;
+ }
+ daemon_name = NULL;
+
+ if (odir) {
+ ret = dict_set_str(dict, "odir", odir);
+ if (ret) {
+ *op_errstr = gf_strdup(
+ "Command failed. Please"
+ " check log file for"
+ " more details.");
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "Setting output directory to"
+ "dictionary failed");
+ goto out;
+ }
+ }
+
+ if (filename) {
+ ret = dict_set_str(dict, "filename", filename);
+ if (ret) {
+ *op_errstr = gf_strdup(
+ "Command failed. Please"
+ " check log file for"
+ " more details.");
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "Setting filename to dictionary failed");
+ goto out;
+ }
+ }
+
+ if (cmd) {
+ ret = dict_set_uint32(dict, "getstate-cmd", cmd);
+ if (ret) {
+ *op_errstr = gf_strdup(
+ "Command failed. Please"
+ " check log file for"
+ " more details.");
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "Setting "
+ "get-state command type to dictionary "
+ "failed");
+ goto out;
+ }
+ }
+ }
- if (!dict)
- goto out;
+out:
+ if (dict)
+ *options = dict;
- if (wordcount != 2)
- goto out;
+ if (ret && dict)
+ dict_unref(dict);
- key = (char *) words[0];
- value = (char *) words[1];
+ GF_FREE(daemon_name);
- if (!key || !value) {
- cli_out ("Usage : nfs-ganesha <enable/disable>");
- ret = -1;
- goto out;
- }
+ return ret;
+}
- ret = gf_strip_whitespace (value, strlen (value));
- if (ret == -1)
- goto out;
+int32_t
+cli_cmd_inode_quota_parse(const char **words, int wordcount, dict_t **options)
+{
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int ret = -1;
- if (strcmp (key, "nfs-ganesha")) {
- gf_asprintf (op_errstr, "Global option: error: ' %s '"
- "is not a valid global option.", key);
- ret = -1;
- goto out;
- }
+ GF_ASSERT(words);
+ GF_ASSERT(options);
- w = str_getunamb (value, opwords);
- if (!w) {
- cli_out ("Invalid global option \n"
- "Usage : nfs-ganesha <enable/disable>");
- ret = -1;
- goto out;
- }
+ dict = dict_new();
+ if (!dict) {
+ gf_log("cli", GF_LOG_ERROR, "dict_new failed");
+ goto out;
+ }
- question = "Enabling NFS-Ganesha requires Gluster-NFS to be"
- " disabled across the trusted pool. Do you "
- "still want to continue?\n";
+ if (wordcount != 4)
+ goto out;
- if (strcmp (value, "enable") == 0) {
- answer = cli_cmd_get_confirmation (state, question);
- if (GF_ANSWER_NO == answer) {
- gf_log ("cli", GF_LOG_ERROR, "Global operation "
- "cancelled, exiting");
- ret = -1;
- goto out;
- }
- }
- cli_out ("This will take a few minutes to complete. Please wait ..");
+ volname = (char *)words[2];
+ if (!volname) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_str (dict, "key", key);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "dict set on key failed");
- goto out;
- }
+ /* Validate the volume name here itself */
+ if (cli_validate_volname(volname) < 0)
+ goto out;
- ret = dict_set_str (dict, "value", value);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "dict set on value failed");
- goto out;
- }
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret < 0)
+ goto out;
- ret = dict_set_str (dict, "globalname", "All");
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "dict set on global"
- " key failed.");
- goto out;
- }
+ if (strcmp(words[3], "enable") != 0) {
+ cli_out("Invalid quota option : %s", words[3]);
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_int32 (dict, "hold_global_locks", _gf_true);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "dict set on global key "
- "failed.");
- goto out;
- }
+ ret = dict_set_int32(dict, "type", GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS);
+ if (ret < 0)
+ goto out;
- *options = dict;
+ *options = dict;
out:
- if (ret)
- dict_unref (dict);
+ if (ret < 0) {
+ if (dict)
+ dict_unref(dict);
+ }
- return ret;
+ return ret;
}
int32_t
-cli_cmd_inode_quota_parse (const char **words, int wordcount, dict_t **options)
+cli_cmd_quota_parse(const char **words, int wordcount, dict_t **options)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- int ret = -1;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int ret = -1;
+ int i = -1;
+ char key[20] = {
+ 0,
+ };
+ int64_t value = 0;
+ gf_quota_type type = GF_QUOTA_OPTION_TYPE_NONE;
+ static char *opwords[] = {"enable",
+ "disable",
+ "limit-usage",
+ "remove",
+ "list",
+ "alert-time",
+ "soft-timeout",
+ "hard-timeout",
+ "default-soft-limit",
+ "limit-objects",
+ "list-objects",
+ "remove-objects",
+ NULL};
+ char *w = NULL;
+ uint32_t time = 0;
+ double percent = 0;
+ char *end_ptr = NULL;
+ int64_t limit = 0;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ dict = dict_new();
+ if (!dict) {
+ gf_log("cli", GF_LOG_ERROR, "dict_new failed");
+ goto out;
+ }
- dict = dict_new ();
- if (!dict) {
- gf_log ("cli", GF_LOG_ERROR, "dict_new failed");
- goto out;
+ if (wordcount < 4) {
+ if ((wordcount == 3) && !(strcmp(words[2], "help"))) {
+ ret = 1;
}
+ goto out;
+ }
- if (wordcount != 4)
- goto out;
+ volname = (char *)words[2];
+ if (!volname) {
+ ret = -1;
+ goto out;
+ }
- volname = (char *)words[2];
- if (!volname) {
- ret = -1;
- goto out;
- }
+ /* Validate the volume name here itself */
+ if (cli_validate_volname(volname) < 0)
+ goto out;
- /* Validate the volume name here itself */
- if (cli_validate_volname (volname) < 0)
- goto out;
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret < 0)
+ goto out;
- ret = dict_set_str (dict, "volname", volname);
- if (ret < 0)
- goto out;
+ w = str_getunamb(words[3], opwords);
+ if (!w) {
+ cli_out("Invalid quota option : %s", words[3]);
+ ret = -1;
+ goto out;
+ }
- if (strcmp (words[3], "enable") != 0) {
- cli_out ("Invalid quota option : %s", words[3]);
- ret = -1;
- goto out;
+ if (strcmp(w, "enable") == 0) {
+ if (wordcount == 4) {
+ type = GF_QUOTA_OPTION_TYPE_ENABLE;
+ ret = 0;
+ goto set_type;
+ } else {
+ ret = -1;
+ goto out;
}
+ }
- ret = dict_set_int32 (dict, "type",
- GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS);
- if (ret < 0)
- goto out;
-
- *options = dict;
-out:
- if (ret < 0) {
- if (dict)
- dict_destroy (dict);
+ if (strcmp(w, "disable") == 0) {
+ if (wordcount == 4) {
+ type = GF_QUOTA_OPTION_TYPE_DISABLE;
+ ret = 0;
+ goto set_type;
+ } else {
+ ret = -1;
+ goto out;
}
+ }
- return ret;
-}
+ if (strcmp(w, "limit-usage") == 0) {
+ type = GF_QUOTA_OPTION_TYPE_LIMIT_USAGE;
+ } else if (strcmp(w, "limit-objects") == 0) {
+ type = GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS;
+ }
-int32_t
-cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
-{
- dict_t *dict = NULL;
- char *volname = NULL;
- int ret = -1;
- int i = -1;
- char key[20] = {0, };
- int64_t value = 0;
- gf_quota_type type = GF_QUOTA_OPTION_TYPE_NONE;
- char *opwords[] = { "enable", "disable", "limit-usage",
- "remove", "list", "alert-time",
- "soft-timeout", "hard-timeout",
- "default-soft-limit", "limit-objects",
- "list-objects", "remove-objects", NULL};
- char *w = NULL;
- uint32_t time = 0;
- double percent = 0;
- char *end_ptr = NULL;
- int64_t limit = 0;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
-
- dict = dict_new ();
- if (!dict) {
- gf_log ("cli", GF_LOG_ERROR, "dict_new failed");
- goto out;
+ if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE ||
+ type == GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS) {
+ if (wordcount < 6 || wordcount > 7) {
+ ret = -1;
+ goto out;
}
- if (wordcount < 4)
+ if (words[4][0] != '/') {
+ cli_err("Please enter absolute path");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_str(dict, "path", (char *)words[4]);
+ if (ret)
+ goto out;
+
+ if (!words[5]) {
+ cli_err("Please enter the limit value to be set");
+ ret = -1;
+ goto out;
+ }
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) {
+ ret = gf_string2bytesize_int64(words[5], &value);
+ if (ret != 0 || value <= 0) {
+ if (errno == ERANGE || value <= 0) {
+ ret = -1;
+ cli_err(
+ "Please enter an integer "
+ "value in the range of "
+ "(1 - %" PRId64 ")",
+ INT64_MAX);
+ } else
+ cli_err(
+ "Please enter a correct "
+ "value");
goto out;
-
- volname = (char *)words[2];
- if (!volname) {
+ }
+ } else {
+ errno = 0;
+ limit = strtol(words[5], &end_ptr, 10);
+ if (errno == ERANGE || errno == EINVAL || limit <= 0 ||
+ strcmp(end_ptr, "") != 0) {
ret = -1;
+ cli_err(
+ "Please enter an integer value in "
+ "the range 1 - %" PRId64,
+ INT64_MAX);
goto out;
+ }
}
- /* Validate the volume name here itself */
- if (cli_validate_volname (volname) < 0)
- goto out;
-
- ret = dict_set_str (dict, "volname", volname);
+ ret = dict_set_str(dict, "hard-limit", (char *)words[5]);
if (ret < 0)
- goto out;
+ goto out;
- w = str_getunamb (words[3], opwords);
- if (!w) {
- cli_out ("Invalid quota option : %s", words[3]);
- ret = - 1;
+ if (wordcount == 7) {
+ ret = gf_string2percent(words[6], &percent);
+ if (ret != 0 || percent > 100) {
+ ret = -1;
+ cli_err(
+ "Please enter a correct value "
+ "in the range of 0 to 100");
goto out;
- }
+ }
- if (strcmp (w, "enable") == 0) {
- if (wordcount == 4) {
- type = GF_QUOTA_OPTION_TYPE_ENABLE;
- ret = 0;
- goto set_type;
- } else {
- ret = -1;
- goto out;
- }
+ ret = dict_set_str(dict, "soft-limit", (char *)words[6]);
+ if (ret < 0)
+ goto out;
}
- if (strcmp (w, "disable") == 0) {
- if (wordcount == 4) {
- type = GF_QUOTA_OPTION_TYPE_DISABLE;
- ret = 0;
- goto set_type;
- } else {
- ret = -1;
- goto out;
- }
- }
+ goto set_type;
+ }
- if (strcmp (w, "limit-usage") == 0) {
- type = GF_QUOTA_OPTION_TYPE_LIMIT_USAGE;
- } else if (strcmp (w, "limit-objects") == 0) {
- type = GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS;
+ if (strcmp(w, "remove") == 0) {
+ if (wordcount != 5) {
+ ret = -1;
+ goto out;
}
- if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE ||
- type == GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS) {
-
- if (wordcount < 6 || wordcount > 7) {
- ret = -1;
- goto out;
- }
+ type = GF_QUOTA_OPTION_TYPE_REMOVE;
- if (words[4][0] != '/') {
- cli_err ("Please enter absolute path");
- ret = -1;
- goto out;
- }
- ret = dict_set_str (dict, "path", (char *) words[4]);
- if (ret)
- goto out;
-
- if (!words[5]) {
- cli_err ("Please enter the limit value to be set");
- ret = -1;
- goto out;
- }
-
- if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) {
- ret = gf_string2bytesize_int64 (words[5], &value);
- if (ret != 0 || value < 0) {
- if (errno == ERANGE || value < 0)
- cli_err ("Value out of range "
- "(0 - %"PRId64 "): %s",
- INT64_MAX, words[5]);
- else
- cli_err ("Please enter a correct "
- "value");
- goto out;
- }
- } else {
- errno = 0;
- limit = strtol (words[5], &end_ptr, 10);
- if (errno == ERANGE || errno == EINVAL || limit <= 0
- || strcmp (end_ptr, "") != 0) {
- ret = -1;
- cli_err ("Please enter an interger value in "
- "the range 1 - %"PRId64, INT64_MAX);
- goto out;
- }
- }
-
- ret = dict_set_str (dict, "hard-limit", (char *) words[5]);
- if (ret < 0)
- goto out;
-
- if (wordcount == 7) {
-
- ret = gf_string2percent (words[6], &percent);
- if (ret != 0 || percent > 100) {
- ret = -1;
- cli_err ("Please enter a correct value "
- "in the range of 0 to 100");
- goto out;
- }
-
- ret = dict_set_str (dict, "soft-limit",
- (char *) words[6]);
- if (ret < 0)
- goto out;
- }
-
- goto set_type;
+ if (words[4][0] != '/') {
+ cli_err("Please enter absolute path");
+ ret = -1;
+ goto out;
}
- if (strcmp (w, "remove") == 0) {
- if (wordcount != 5) {
- ret = -1;
- goto out;
- }
-
- type = GF_QUOTA_OPTION_TYPE_REMOVE;
-
- if (words[4][0] != '/') {
- cli_err ("Please enter absolute path");
- ret = -1;
- goto out;
- }
+ ret = dict_set_str(dict, "path", (char *)words[4]);
+ if (ret < 0)
+ goto out;
+ goto set_type;
+ }
- ret = dict_set_str (dict, "path", (char *) words[4]);
- if (ret < 0)
- goto out;
- goto set_type;
+ if (strcmp(w, "remove-objects") == 0) {
+ if (wordcount != 5) {
+ ret = -1;
+ goto out;
}
- if (strcmp (w, "remove-objects") == 0) {
- if (wordcount != 5) {
- ret = -1;
- goto out;
- }
-
- type = GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS;
+ type = GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS;
- if (words[4][0] != '/') {
- cli_err ("Please enter absolute path");
- ret = -1;
- goto out;
- }
-
- ret = dict_set_str (dict, "path", (char *) words[4]);
- if (ret < 0)
- goto out;
- goto set_type;
+ if (words[4][0] != '/') {
+ cli_err("Please enter absolute path");
+ ret = -1;
+ goto out;
}
- if (strcmp (w, "list") == 0) {
-
- type = GF_QUOTA_OPTION_TYPE_LIST;
-
- if (words[4] && words[4][0] != '/') {
- cli_err ("Please enter absolute path");
- ret = -1;
- goto out;
- }
+ ret = dict_set_str(dict, "path", (char *)words[4]);
+ if (ret < 0)
+ goto out;
+ goto set_type;
+ }
- i = 4;
- while (i < wordcount) {
- snprintf (key, 20, "path%d", i-4);
+ if (strcmp(w, "list") == 0) {
+ type = GF_QUOTA_OPTION_TYPE_LIST;
- ret = dict_set_str (dict, key, (char *) words [i++]);
- if (ret < 0)
- goto out;
- }
+ if (words[4] && words[4][0] != '/') {
+ cli_err("Please enter absolute path");
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_int32 (dict, "count", i - 4);
- if (ret < 0)
- goto out;
+ i = 4;
+ while (i < wordcount) {
+ snprintf(key, 20, "path%d", i - 4);
- goto set_type;
+ ret = dict_set_str(dict, key, (char *)words[i++]);
+ if (ret < 0)
+ goto out;
}
- if (strcmp (w, "list-objects") == 0) {
- if (wordcount < 4) {
- ret = -1;
- goto out;
- }
+ ret = dict_set_int32(dict, "count", i - 4);
+ if (ret < 0)
+ goto out;
- type = GF_QUOTA_OPTION_TYPE_LIST_OBJECTS;
+ goto set_type;
+ }
- i = 4;
- while (i < wordcount) {
- snprintf (key, 20, "path%d", i-4);
+ if (strcmp(w, "list-objects") == 0) {
+ type = GF_QUOTA_OPTION_TYPE_LIST_OBJECTS;
- ret = dict_set_str (dict, key, (char *) words[i++]);
- if (ret < 0) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set "
- "quota patch in request dictionary");
- goto out;
- }
- }
+ i = 4;
+ while (i < wordcount) {
+ snprintf(key, 20, "path%d", i - 4);
- ret = dict_set_int32 (dict, "count", i - 4);
- if (ret < 0) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set quota "
- "limit count in request dictionary");
- goto out;
- }
+ ret = dict_set_str(dict, key, (char *)words[i++]);
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to set "
+ "quota patch in request dictionary");
+ goto out;
+ }
+ }
- goto set_type;
+ ret = dict_set_int32(dict, "count", i - 4);
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to set quota "
+ "limit count in request dictionary");
+ goto out;
}
- if (strcmp (w, "alert-time") == 0) {
- if (wordcount != 5) {
- ret = -1;
- goto out;
- }
- type = GF_QUOTA_OPTION_TYPE_ALERT_TIME;
+ goto set_type;
+ }
- ret = gf_string2time (words[4], &time);
- if (ret) {
- cli_err ("Invalid argument %s. Please enter a valid "
- "string", words[4]);
- goto out;
- }
+ if (strcmp(w, "alert-time") == 0) {
+ if (wordcount != 5) {
+ ret = -1;
+ goto out;
+ }
+ type = GF_QUOTA_OPTION_TYPE_ALERT_TIME;
- ret = dict_set_str (dict, "value", (char *)words[4]);
- if (ret < 0)
- goto out;
- goto set_type;
+ ret = gf_string2time(words[4], &time);
+ if (ret) {
+ cli_err(
+ "Invalid argument %s. Please enter a valid "
+ "string",
+ words[4]);
+ goto out;
}
- if (strcmp (w, "soft-timeout") == 0) {
- if (wordcount != 5) {
- ret = -1;
- goto out;
- }
- type = GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT;
+ ret = dict_set_str(dict, "value", (char *)words[4]);
+ if (ret < 0)
+ goto out;
+ goto set_type;
+ }
- ret = gf_string2time (words[4], &time);
- if (ret) {
- cli_err ("Invalid argument %s. Please enter a valid "
- "string", words[4]);
- goto out;
- }
+ if (strcmp(w, "soft-timeout") == 0) {
+ if (wordcount != 5) {
+ ret = -1;
+ goto out;
+ }
+ type = GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT;
- ret = dict_set_str (dict, "value", (char *)words[4]);
- if (ret < 0)
- goto out;
- goto set_type;
+ ret = gf_string2time(words[4], &time);
+ if (ret) {
+ cli_err(
+ "Invalid argument %s. Please enter a valid "
+ "string",
+ words[4]);
+ goto out;
}
- if (strcmp (w, "hard-timeout") == 0) {
- if(wordcount != 5) {
- ret = -1;
- goto out;
- }
- type = GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT;
+ ret = dict_set_str(dict, "value", (char *)words[4]);
+ if (ret < 0)
+ goto out;
+ goto set_type;
+ }
- ret = gf_string2time (words[4], &time);
- if (ret) {
- cli_err ("Invalid argument %s. Please enter a valid "
- "string", words[4]);
- goto out;
- }
+ if (strcmp(w, "hard-timeout") == 0) {
+ if (wordcount != 5) {
+ ret = -1;
+ goto out;
+ }
+ type = GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT;
- ret = dict_set_str (dict, "value", (char *)words[4]);
- if (ret < 0)
- goto out;
- goto set_type;
+ ret = gf_string2time(words[4], &time);
+ if (ret) {
+ cli_err(
+ "Invalid argument %s. Please enter a valid "
+ "string",
+ words[4]);
+ goto out;
}
- if (strcmp (w, "default-soft-limit") == 0) {
- if(wordcount != 5) {
- ret = -1;
- goto out;
- }
- type = GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT;
- ret = dict_set_str (dict, "value", (char *)words[4]);
- if (ret < 0)
- goto out;
- goto set_type;
- } else {
- GF_ASSERT (!"opword mismatch");
+ ret = dict_set_str(dict, "value", (char *)words[4]);
+ if (ret < 0)
+ goto out;
+ goto set_type;
+ }
+ if (strcmp(w, "default-soft-limit") == 0) {
+ if (wordcount != 5) {
+ ret = -1;
+ goto out;
}
+ type = GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT;
-set_type:
- ret = dict_set_int32 (dict, "type", type);
+ ret = dict_set_str(dict, "value", (char *)words[4]);
if (ret < 0)
- goto out;
+ goto out;
+ goto set_type;
+ } else {
+ GF_ASSERT(!"opword mismatch");
+ }
- *options = dict;
+set_type:
+ ret = dict_set_int32(dict, "type", type);
+ if (ret < 0)
+ goto out;
+
+ *options = dict;
out:
- if (ret < 0) {
- if (dict)
- dict_destroy (dict);
- }
+ if (ret < 0) {
+ if (dict)
+ dict_unref(dict);
+ }
- return ret;
+ return ret;
}
static gf_boolean_t
-cli_is_key_spl (char *key)
+cli_is_key_spl(char *key)
{
- return (strcmp (key, "group") == 0);
+ return (strcmp(key, "group") == 0);
}
-static int
-cli_add_key_group (dict_t *dict, char *key, char *value, char **op_errstr)
+static int32_t
+cli_add_key_group_value(dict_t *dict, const char *name, const char *value,
+ int32_t id, char **op_errstr)
{
- 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,};
- char errstr[2048] = "";
- FILE *fp = NULL;
-
- ret = gf_asprintf (&tagpath, "%s/groups/%s",
- GLUSTERD_DEFAULT_WORKDIR, value);
- if (ret == -1) {
- tagpath = NULL;
- goto out;
- }
+ char *key = NULL;
+ char *data = NULL;
+ int32_t ret = -1;
- fp = fopen (tagpath, "r");
- if (!fp) {
- ret = -1;
- snprintf(errstr, sizeof(errstr), "Unable to open file '%s'."
- " Error: %s", tagpath, strerror (errno));
- if (op_errstr)
- *op_errstr = gf_strdup(errstr);
- goto out;
- }
+ ret = gf_asprintf(&key, "%s%d", name, id);
+ if (ret < 0) {
+ goto out;
+ }
+ data = gf_strdup(value);
+ if (data == NULL) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Failed to allocate memory for data");
+ ret = -1;
+ goto out;
+ }
- opt_count = 0;
- buf = line;
- while (fscanf (fp, "%s", buf) != EOF) {
+ ret = dict_set_dynstr(dict, key, data);
+ if (ret == 0) {
+ data = NULL;
+ }
- opt_count++;
- tok_key = strtok_r (line, "=", &saveptr);
- tok_val = strtok_r (NULL, "=", &saveptr);
- if (!tok_key || !tok_val) {
- ret = -1;
- snprintf(errstr, sizeof(errstr), "'%s' file format "
- "not valid.", tagpath);
- if (op_errstr)
- *op_errstr = gf_strdup(errstr);
- goto out;
- }
+out:
+ GF_FREE(key);
+ GF_FREE(data);
- 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;
+ if ((ret != 0) && (op_errstr != NULL)) {
+ *op_errstr = gf_strdup("Failed to allocate memory");
+ }
- 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;
+ return ret;
+}
- }
+static int
+cli_add_key_group(dict_t *dict, char *key, char *value, char **op_errstr)
+{
+ int ret = -1;
+ int opt_count = 0;
+ char *saveptr = NULL;
+ char *tok_key = NULL;
+ char *tok_val = NULL;
+ char *tagpath = 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;
+ }
- if (!opt_count) {
- ret = -1;
- snprintf(errstr, sizeof(errstr), "'%s' file format "
- "not valid.", tagpath);
- if (op_errstr)
- *op_errstr = gf_strdup(errstr);
- goto out;
+ fp = fopen(tagpath, "r");
+ if (!fp) {
+ ret = -1;
+ if (op_errstr) {
+ gf_asprintf(op_errstr,
+ "Unable to open file '%s'. "
+ "Error: %s",
+ tagpath, strerror(errno));
}
- ret = dict_set_int32 (dict, "count", opt_count);
+ goto out;
+ }
+
+ opt_count = 0;
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ if (strlen(line) >= sizeof(line) - 1) {
+ ret = -1;
+ if (op_errstr != NULL) {
+ *op_errstr = gf_strdup("Line too long");
+ }
+ goto out;
+ }
+
+ /* Treat line that start with "#" as comments */
+ if ('#' == line[0])
+ continue;
+
+ opt_count++;
+ tok_key = strtok_r(line, "=", &saveptr);
+ tok_val = strtok_r(NULL, "\r\n", &saveptr);
+ if (!tok_key || !tok_val) {
+ ret = -1;
+ if (op_errstr) {
+ gf_asprintf(op_errstr,
+ "'%s' file format "
+ "not valid.",
+ tagpath);
+ }
+ goto out;
+ }
+
+ ret = cli_add_key_group_value(dict, "key", tok_key, opt_count,
+ op_errstr);
+ if (ret != 0) {
+ goto out;
+ }
+ ret = cli_add_key_group_value(dict, "value", tok_val, opt_count,
+ op_errstr);
+ if (ret != 0) {
+ goto out;
+ }
+ }
+
+ if (!opt_count) {
+ ret = -1;
+ if (op_errstr) {
+ gf_asprintf(op_errstr, "'%s' file format not valid.", tagpath);
+ }
+ goto out;
+ }
+ ret = dict_set_int32(dict, "count", opt_count);
out:
- GF_FREE (tagpath);
+ GF_FREE(tagpath);
- if (ret) {
- GF_FREE (dkey);
- GF_FREE (dval);
- }
+ if (fp)
+ fclose(fp);
- if (fp)
- fclose (fp);
-
- return ret;
+ return ret;
}
int32_t
-cli_cmd_volume_set_parse (struct cli_state *state, const char **words,
- int wordcount, dict_t **options, char **op_errstr)
+cli_cmd_volume_set_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **op_errstr)
{
- 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,};
- const char *question = NULL;
- gf_answer_t answer = GF_ANSWER_NO;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
-
- dict = dict_new ();
-
- if (!dict)
- goto out;
-
- if (wordcount < 3)
- goto out;
+ 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,
+ };
+ const char *question = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ dict = dict_new();
+
+ if (!dict)
+ goto out;
- volname = (char *)words[2];
+ if (wordcount < 3)
+ goto out;
- GF_ASSERT (volname);
+ volname = (char *)words[2];
- ret = dict_set_str (dict, "volname", volname);
+ GF_ASSERT(volname);
- if (ret)
- goto out;
+ ret = dict_set_str(dict, "volname", volname);
- if (!strcmp (volname, "all")) {
- ret = dict_set_str (dict, "globalname", "All");
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "dict set on global key failed.");
- goto out;
- }
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "hold_global_locks", _gf_true);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "dict set on global key failed.");
- goto out;
- }
+ if (!strcmp(volname, "all")) {
+ ret = dict_set_str(dict, "globalname", "All");
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "dict set on global key failed.");
+ goto out;
}
- if ((!strcmp (volname, "help") || !strcmp (volname, "help-xml"))
- && wordcount == 3 ) {
- ret = dict_set_str (dict, volname, volname);
- if (ret)
- goto out;
+ ret = dict_set_int32(dict, "hold_global_locks", _gf_true);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "dict set on global key failed.");
+ goto out;
+ }
+ }
- } else if (wordcount < 5) {
- ret = -1;
- 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 && cli_is_key_spl ((char *)words[3])) {
- key = (char *) words[3];
- value = (char *) words[4];
- if ( !key || !value) {
- ret = -1;
- goto out;
- }
+ } else if (wordcount < 5) {
+ ret = -1;
+ goto out;
- ret = gf_strip_whitespace (value, strlen (value));
- if (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;
+ }
- if (strlen (value) == 0) {
- ret = -1;
- goto out;
- }
+ ret = gf_strip_whitespace(value, strlen(value));
+ if (ret == -1)
+ goto out;
- ret = cli_add_key_group (dict, key, value, op_errstr);
- if (ret == 0)
- *options = dict;
- goto out;
+ if (strlen(value) == 0) {
+ ret = -1;
+ goto out;
}
- for (i = 3; i < wordcount; i+=2) {
-
- key = (char *) words[i];
- value = (char *) words[i+1];
+ ret = cli_add_key_group(dict, key, value, op_errstr);
+ if (ret == 0)
+ *options = dict;
+ goto out;
+ }
- if ( !key || !value) {
- ret = -1;
- goto out;
- }
+ for (i = 3; i < wordcount; i += 2) {
+ key = (char *)words[i];
+ value = (char *)words[i + 1];
- count++;
+ if (!key || !value) {
+ ret = -1;
+ goto out;
+ }
- ret = gf_strip_whitespace (value, strlen (value));
- if (ret == -1)
- goto out;
+ count++;
- if (strlen (value) == 0) {
- ret = -1;
- goto out;
- }
+ if (fnmatch("user.*", key, FNM_NOESCAPE) != 0) {
+ ret = gf_strip_whitespace(value, strlen(value));
+ if (ret == -1)
+ goto out;
+ }
- if (cli_is_key_spl (key)) {
- ret = -1;
- goto out;
- }
+ if (strlen(value) == 0) {
+ ret = -1;
+ goto out;
+ }
- sprintf (str, "key%d", count);
- ret = dict_set_str (dict, str, key);
- if (ret)
- goto out;
+ if (cli_is_key_spl(key)) {
+ ret = -1;
+ goto out;
+ }
- sprintf (str, "value%d", count);
- ret = dict_set_str (dict, str, value);
+ sprintf(str, "key%d", count);
+ ret = dict_set_str(dict, str, key);
+ if (ret)
+ goto out;
- if (ret)
- goto out;
+ sprintf(str, "value%d", count);
+ ret = dict_set_str(dict, str, value);
- if ((!strcmp (key, "cluster.enable-shared-storage")) &&
- (!strcmp (value, "disable"))) {
- question = "Disabling cluster.enable-shared-storage "
- "will delete the shared storage volume"
- "(gluster_shared_storage), which is used "
- "by snapshot scheduler, geo-replication "
- "and NFS-Ganesha. Do you still want to "
- "continue?";
- answer = cli_cmd_get_confirmation (state, question);
- if (GF_ANSWER_NO == answer) {
- gf_log ("cli", GF_LOG_ERROR, "Operation "
- "cancelled, exiting");
- *op_errstr = gf_strdup ("Aborted by user.");
- ret = -1;
- goto out;
- }
- }
+ if (ret)
+ goto out;
+
+ if ((!strcmp(key, "cluster.enable-shared-storage")) &&
+ (!strcmp(value, "disable"))) {
+ question =
+ "Disabling cluster.enable-shared-storage "
+ "will delete the shared storage volume"
+ "(gluster_shared_storage), which is used "
+ "by snapshot scheduler, geo-replication "
+ "and NFS-Ganesha. Do you still want to "
+ "continue?";
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Operation "
+ "cancelled, exiting");
+ *op_errstr = gf_strdup("Aborted by user.");
+ ret = -1;
+ goto out;
+ }
+ }
+ if ((!strcmp(key, "nfs.disable")) && (!strcmp(value, "off"))) {
+ question =
+ "Gluster NFS is being deprecated in favor "
+ "of NFS-Ganesha Enter \"yes\" to continue "
+ "using Gluster NFS";
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Operation "
+ "cancelled, exiting");
+ *op_errstr = gf_strdup("Aborted by user.");
+ ret = -1;
+ goto out;
+ }
}
+ }
- ret = dict_set_int32 (dict, "count", wordcount-3);
+ ret = dict_set_int32(dict, "count", wordcount - 3);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- *options = dict;
+ *options = dict;
out:
- if (ret)
- dict_destroy (dict);
+ if (ret && dict)
+ dict_unref(dict);
- return ret;
+ return ret;
}
int32_t
-cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
- dict_t **options, int *ret_type)
+cli_cmd_volume_add_brick_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, int *ret_type)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- 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_boolean_t is_force = _gf_false;
- int wc = wordcount;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
-
- dict = dict_new ();
-
- if (!dict)
- goto out;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int ret = -1;
+ int brick_count = 0, brick_index = 0;
+ char *bricks = NULL;
+ static char *opwords_cl[] = {"replica", "stripe", NULL};
+ gf1_cluster_type type = GF_CLUSTER_TYPE_NONE;
+ int count = 1;
+ int arbiter_count = 0;
+ char *w = NULL;
+ int index;
+ gf_boolean_t is_force = _gf_false;
+ int wc = wordcount;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *question = NULL;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ dict = dict_new();
+
+ if (!dict)
+ goto out;
- if (wordcount < 3)
- goto out;
+ if (wordcount < 3)
+ goto out;
- volname = (char *)words[2];
+ volname = (char *)words[2];
- GF_ASSERT (volname);
+ GF_ASSERT(volname);
- ret = dict_set_str (dict, "volname", volname);
+ ret = dict_set_str(dict, "volname", volname);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
+
+ if (wordcount < 4) {
+ 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;
+ }
- if (wordcount < 4) {
+ 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;
+ 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;
+ if (words[index] && !strcmp(words[index], "arbiter")) {
+ arbiter_count = strtol(words[6], NULL, 0);
+ if (arbiter_count != 1 || count != 3) {
+ cli_err(
+ "For arbiter configuration, replica "
+ "count must be 3 and arbiter count "
+ "must be 1. The 3rd brick of the "
+ "replica will be the arbiter");
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;
+ }
+ ret = dict_set_int32(dict, "arbiter-count", arbiter_count);
+ if (ret)
+ goto out;
+ index = 7;
}
- 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;
- 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;
- count = strtol (words[4], NULL, 0);
- if (!count || (count < 2)) {
- cli_err ("stripe count should be greater than 1");
- ret = -1;
- goto out;
+ if (count == 2) {
+ if (strcmp(words[wordcount - 1], "force")) {
+ question =
+ "Replica 2 volumes are prone to "
+ "split-brain. Use Arbiter or "
+ "Replica 3 to avoid this. See: "
+ "http://docs.gluster.org/en/latest/Administrator%20Guide/"
+ "Split%20brain%20and%20ways%20to%20deal%20with%20it/."
+ "\nDo you still want to continue?\n";
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Add brick"
+ " cancelled, exiting");
+ 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;
+ }
}
+ } else if ((strcmp(w, "stripe")) == 0) {
+ cli_err("stripe option not supported");
+ goto out;
+ } else {
+ GF_ASSERT(!"opword mismatch");
+ ret = -1;
+ goto out;
+ }
- brick_index = index;
+ brick_index = index;
parse_bricks:
- if (strcmp (words[wordcount - 1], "force") == 0) {
- is_force = _gf_true;
- wc = wordcount - 1;
- }
+ if (strcmp(words[wordcount - 1], "force") == 0) {
+ is_force = _gf_true;
+ wc = wordcount - 1;
+ }
- ret = cli_cmd_bricks_parse (words, wc, brick_index, &bricks,
- &brick_count);
- if (ret)
- goto out;
+ ret = cli_cmd_bricks_parse(words, wc, brick_index, &bricks, &brick_count);
+ if (ret)
+ goto out;
- ret = dict_set_dynstr (dict, "bricks", bricks);
- if (ret)
- goto out;
+ ret = dict_set_dynstr(dict, "bricks", bricks);
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "count", brick_count);
+ ret = dict_set_int32(dict, "count", brick_count);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "force", is_force);
- if (ret)
- goto out;
+ ret = dict_set_int32(dict, "force", is_force);
+ if (ret)
+ goto out;
- *options = dict;
+ *options = dict;
out:
- if (ret_type)
- *ret_type = type;
+ if (ret_type)
+ *ret_type = type;
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to parse add-brick CLI");
- if (dict)
- dict_destroy (dict);
- }
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to parse add-brick CLI");
+ if (dict)
+ dict_unref(dict);
+ }
- return ret;
+ return ret;
}
int32_t
-cli_cmd_volume_tier_parse (const char **words, int wordcount,
- dict_t **options)
+cli_cmd_volume_remove_brick_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options,
+ int *question, int *brick_count,
+ int32_t *comm)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- char *word = NULL;
- int ret = -1;
- int32_t command = GF_OP_CMD_NONE;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ char *delimiter = NULL;
+ int ret = -1;
+ char key[50];
+ int brick_index = 0;
+ int32_t tmp_index = 0;
+ int32_t j = 0;
+ char *tmp_brick = NULL;
+ char *tmp_brick1 = NULL;
+ static char *type_opword[] = {"replica", NULL};
+ static char *opwords[] = {"start", "commit", "stop",
+ "status", "force", NULL};
+ char *w = NULL;
+ int32_t command = GF_OP_CMD_NONE;
+ long count = 0;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *ques = NULL;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ if (wordcount < 5)
+ goto out;
- dict = dict_new ();
+ dict = dict_new();
+ if (!dict)
+ goto out;
- if (!dict)
- goto out;
+ volname = (char *)words[2];
- if (wordcount != 4) {
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- ret = -1;
- goto out;
- }
+ GF_ASSERT(volname);
- volname = (char *)words[2];
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- GF_ASSERT (volname);
+ brick_index = 3;
+ w = str_getunamb(words[3], type_opword);
+ if (w && !strcmp("replica", w)) {
+ if (wordcount < 6) {
+ 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;
+ }
+
+ if (count == 2) {
+ if (strcmp(words[wordcount - 1], "force")) {
+ ques =
+ "Replica 2 volumes are prone to "
+ "split-brain. Use Arbiter or Replica 3 "
+ "to avoid this. See: "
+ "http://docs.gluster.org/en/latest/Administrator%20Guide/"
+ "Split%20brain%20and%20ways%20to%20deal%20with%20it/."
+ "\nDo you still want to continue?\n";
+ answer = cli_cmd_get_confirmation(state, ques);
+ if (GF_ANSWER_NO == answer) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Remove "
+ "brick cancelled, exiting");
+ ret = -1;
+ goto out;
+ }
+ }
+ }
- ret = cli_cmd_validate_volume (volname);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to validate volume name");
- 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) {
+ ret = -1;
+ goto out;
+ } else {
+ /* handled this option */
+ wordcount--;
+ if (!strcmp("start", w)) {
+ command = GF_OP_CMD_START;
+ if (question)
+ *question = 1;
+ } else if (!strcmp("commit", w)) {
+ command = GF_OP_CMD_COMMIT;
+ } 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;
}
+ }
- ret = dict_set_str (dict, "volname", volname);
+ ret = dict_set_int32(dict, "command", command);
+ if (ret)
+ gf_log("cli", GF_LOG_INFO, "failed to set 'command' %d", command);
- if (ret)
- goto out;
+ tmp_index = brick_index;
+ tmp_brick = GF_MALLOC(2048 * sizeof(*tmp_brick), gf_common_mt_char);
- volname = (char *)words[2];
+ if (!tmp_brick) {
+ gf_log("", GF_LOG_ERROR,
+ "cli_cmd_volume_remove_brick_parse: "
+ "Unable to get memory");
+ ret = -1;
+ goto out;
+ }
- word = (char *)words[3];
- if (!strcmp(word, "status"))
- command = GF_DEFRAG_CMD_STATUS_TIER;
- else {
+ tmp_brick1 = GF_MALLOC(2048 * sizeof(*tmp_brick1), gf_common_mt_char);
+
+ if (!tmp_brick1) {
+ gf_log("", GF_LOG_ERROR,
+ "cli_cmd_volume_remove_brick_parse: "
+ "Unable to get memory");
+ ret = -1;
+ goto out;
+ }
+
+ while (brick_index < wordcount) {
+ 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 {
+ delimiter = strrchr(words[brick_index], ':');
+ ret = gf_canonicalize_path(delimiter + 1);
+ if (ret)
+ goto out;
+ }
+
+ j = tmp_index;
+ strcpy(tmp_brick, words[brick_index]);
+ while (j < brick_index) {
+ strcpy(tmp_brick1, words[j]);
+ if (!(strcmp(tmp_brick, tmp_brick1))) {
+ gf_log("", GF_LOG_ERROR,
+ "Duplicate bricks"
+ " found %s",
+ words[brick_index]);
+ cli_err("Duplicate bricks found %s", words[brick_index]);
ret = -1;
goto out;
+ }
+ j++;
}
+ snprintf(key, 50, "brick%d", ++(*brick_count));
+ ret = dict_set_str(dict, key, (char *)words[brick_index++]);
- ret = dict_set_int32 (dict, "rebalance-command", command);
if (ret)
- goto out;
+ goto out;
+ }
+
+ if (command != GF_OP_CMD_STATUS && command != GF_OP_CMD_STOP) {
+ ret = dict_set_int32(dict, "count", *brick_count);
+ if (ret)
+ goto out;
+ }
+
+ *options = dict;
- *options = dict;
out:
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to parse remove-brick CLI");
+ if (dict)
+ dict_unref(dict);
+ }
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to parse tier CLI");
- if (dict)
- dict_destroy (dict);
- }
+ GF_FREE(tmp_brick);
+ GF_FREE(tmp_brick1);
- return ret;
+ *comm = command;
+
+ return ret;
}
int32_t
-cli_cmd_volume_detach_tier_parse (const char **words, int wordcount,
- dict_t **options)
+cli_cmd_brick_op_validate_bricks(const char **words, dict_t *dict, int src,
+ int dst)
{
- int ret = -1;
- char *word = NULL;
- dict_t *dict = NULL;
- int32_t command = GF_OP_CMD_NONE;
- int force = 0;
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_set_str (dict, "volname", (char *)words[2]);
+ int ret = -1;
+ char *delimiter = NULL;
+
+ if (validate_brick_name((char *)words[src])) {
+ cli_err(
+ "wrong brick type: %s, use "
+ "<HOSTNAME>:<export-dir-abs-path>",
+ words[3]);
+ ret = -1;
+ goto out;
+ } else {
+ delimiter = strrchr((char *)words[src], '/');
+ ret = gf_canonicalize_path(delimiter);
if (ret)
- goto out;
-
- if (wordcount == 3 && !strcmp ((char *)words[2], "help")) {
- return -1;
- }
+ goto out;
+ }
- if (!((wordcount == 4) || (wordcount == 5))) {
- ret = -1;
- goto out;
- }
-
- if (wordcount == 5) {
- word = (char *)words[4];
- if (!strcmp(word, "force"))
- force = 1;
- else {
- ret = -1;
- goto out;
- }
- }
+ ret = dict_set_str(dict, "src-brick", (char *)words[src]);
+ if (ret)
+ goto out;
- word = (char *)words[3];
+ if (dst == -1) {
+ ret = 0;
+ goto out;
+ }
+ if (validate_brick_name((char *)words[dst])) {
+ cli_err(
+ "wrong brick type: %s, use "
+ "<HOSTNAME>:<export-dir-abs-path>",
+ words[dst]);
ret = -1;
-
- if (!strcmp(word, "start")) {
- command = GF_OP_CMD_DETACH_START;
- } else if (!strcmp(word, "commit")) {
- if (force)
- command = GF_OP_CMD_DETACH_COMMIT_FORCE;
- else
- command = GF_OP_CMD_DETACH_COMMIT;
- } else if (!strcmp(word, "stop"))
- command = GF_OP_CMD_STOP_DETACH_TIER;
- else if (!strcmp(word, "status"))
- command = GF_OP_CMD_STATUS;
- else
- goto out;
-
- ret = dict_set_int32 (dict, "command", command);
+ goto out;
+ } else {
+ delimiter = strrchr((char *)words[dst], '/');
+ ret = gf_canonicalize_path(delimiter);
if (ret)
- goto out;
+ goto out;
+ }
- *options = dict;
- ret = 0;
+ ret = dict_set_str(dict, "dst-brick", (char *)words[dst]);
+ if (ret)
+ goto out;
+ ret = 0;
out:
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to parse detach-tier CLI");
- if (dict)
- dict_unref (dict);
- }
-
- return ret;
+ return ret;
}
int32_t
-cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
- dict_t **options, int *question)
+cli_cmd_volume_reset_brick_parse(const char **words, int wordcount,
+ dict_t **options)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- char *delimiter = NULL;
- int ret = -1;
- char key[50];
- int brick_count = 0, brick_index = 0;
- int32_t tmp_index = 0;
- 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);
-
- if (wordcount < 5)
- goto out;
+ int ret = -1;
+ char *volname = NULL;
+ dict_t *dict = NULL;
- dict = dict_new ();
- if (!dict)
- goto out;
+ if (wordcount < 5 || wordcount > 7)
+ goto out;
- volname = (char *)words[2];
+ dict = dict_new();
- GF_ASSERT (volname);
+ if (!dict)
+ goto out;
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ volname = (char *)words[2];
- brick_index = 3;
- w = str_getunamb (words[3], type_opword);
- if (w && !strcmp ("replica", w)) {
- if (wordcount < 6) {
- 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_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "replica-count", count);
- if (ret)
- goto out;
- brick_index = 5;
- } else if (w) {
- GF_ASSERT (!"opword mismatch");
+ if (wordcount == 5) {
+ if (strcmp(words[4], "start")) {
+ cli_err(
+ "Invalid option '%s' for reset-brick. Please "
+ "enter valid reset-brick command",
+ words[4]);
+ ret = -1;
+ goto out;
}
- w = str_getunamb (words[wordcount - 1], opwords);
- if (!w) {
- ret = -1;
- goto out;
- } 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;
- }
- }
-
- ret = dict_set_int32 (dict, "command", command);
+ ret = cli_cmd_brick_op_validate_bricks(words, dict, 3, -1);
if (ret)
- 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);
-
- if (!tmp_brick) {
- gf_log ("",GF_LOG_ERROR,"cli_cmd_volume_remove_brick_parse: "
- "Unable to get memory");
- ret = -1;
- goto out;
- }
+ goto out;
- tmp_brick1 = GF_MALLOC(2048 * sizeof(*tmp_brick1), gf_common_mt_char);
-
- if (!tmp_brick1) {
- gf_log ("",GF_LOG_ERROR,"cli_cmd_volume_remove_brick_parse: "
- "Unable to get memory");
- ret = -1;
- goto out;
- }
-
- while (brick_index < wordcount) {
- 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 {
- delimiter = strrchr(words[brick_index], ':');
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
-
- j = tmp_index;
- strcpy(tmp_brick, words[brick_index]);
- while ( j < brick_index) {
- strcpy(tmp_brick1, words[j]);
- if (!(strcmp (tmp_brick, tmp_brick1))) {
- gf_log("",GF_LOG_ERROR, "Duplicate bricks"
- " found %s", words[brick_index]);
- cli_err("Duplicate bricks found %s",
- words[brick_index]);
- ret = -1;
- goto out;
- }
- j++;
- }
- snprintf (key, 50, "brick%d", ++brick_count);
- ret = dict_set_str (dict, key, (char *)words[brick_index++]);
+ ret = dict_set_str(dict, "operation", "GF_RESET_OP_START");
+ if (ret)
+ goto out;
+ } else if (wordcount == 6) {
+ if (strcmp(words[5], "commit")) {
+ cli_err(
+ "Invalid option '%s' for reset-brick. Please "
+ "enter valid reset-brick command",
+ words[5]);
+ ret = -1;
+ goto out;
+ }
+
+ ret = cli_cmd_brick_op_validate_bricks(words, dict, 3, 4);
+ if (ret)
+ goto out;
- if (ret)
- goto out;
- }
+ ret = dict_set_str(dict, "operation", "GF_RESET_OP_COMMIT");
+ if (ret)
+ goto out;
+ } else if (wordcount == 7) {
+ if (strcmp(words[5], "commit") || strcmp(words[6], "force")) {
+ cli_err(
+ "Invalid option '%s %s' for reset-brick. Please "
+ "enter valid reset-brick command",
+ words[5], words[6]);
+ ret = -1;
+ goto out;
+ }
+
+ ret = cli_cmd_brick_op_validate_bricks(words, dict, 3, 4);
+ if (ret)
+ goto out;
- if (command != GF_OP_CMD_STATUS && command != GF_OP_CMD_STOP) {
- ret = dict_set_int32 (dict, "count", brick_count);
- if (ret)
- goto out;
- }
+ ret = dict_set_str(dict, "operation", "GF_RESET_OP_COMMIT_FORCE");
+ if (ret)
+ goto out;
+ }
- *options = dict;
+ *options = dict;
out:
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to parse remove-brick CLI");
- if (dict)
- dict_destroy (dict);
- }
-
- GF_FREE (tmp_brick);
- GF_FREE (tmp_brick1);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to parse reset-brick CLI");
+ if (dict)
+ dict_unref(dict);
+ }
- return ret;
+ return ret;
}
-
int32_t
-cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
- dict_t **options)
+cli_cmd_volume_replace_brick_parse(const char **words, int wordcount,
+ dict_t **options)
{
- int ret = -1;
- char *volname = NULL;
- char *delimiter = NULL;
- dict_t *dict = NULL;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
+ int ret = -1;
+ char *volname = NULL;
+ dict_t *dict = NULL;
- if (wordcount != 7) {
- ret = -1;
- goto out;
- }
-
- dict = dict_new ();
+ GF_ASSERT(words);
+ GF_ASSERT(options);
- if (!dict) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to allocate dictionary");
- goto out;
- }
-
- volname = (char *)words[2];
+ if (wordcount != 7) {
+ ret = -1;
+ goto out;
+ }
- GF_ASSERT (volname);
+ dict = dict_new();
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ if (!dict) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to allocate dictionary");
+ goto out;
+ }
- 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 {
- delimiter = strrchr ((char *)words[3], ':');
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
+ volname = (char *)words[2];
- ret = dict_set_str (dict, "src-brick", (char *)words[3]);
- if (ret)
- goto out;
+ GF_ASSERT(volname);
- 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 {
- delimiter = strrchr ((char *)words[4], ':');
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- ret = dict_set_str (dict, "dst-brick", (char *)words[4]);
- if (ret)
- goto out;
+ ret = cli_cmd_brick_op_validate_bricks(words, dict, 3, 4);
+ if (ret)
+ goto out;
- /* commit force option */
- if (strcmp ("commit", words[5]) || strcmp ("force", words[6])) {
- cli_err ("Invalid option '%s' '%s' for replace-brick. Please "
- "enter valid replace-brick command", words[5],
- words[6]);
- ret = -1;
- goto out;
- }
+ /* commit force option */
+ if (strcmp("commit", words[5]) || strcmp("force", words[6])) {
+ cli_err(
+ "Invalid option '%s' '%s' for replace-brick. Please "
+ "enter valid replace-brick command",
+ words[5], words[6]);
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_str (dict, "operation", "GF_REPLACE_OP_COMMIT_FORCE");
- if (ret)
- goto out;
+ ret = dict_set_str(dict, "operation", "GF_REPLACE_OP_COMMIT_FORCE");
+ if (ret)
+ goto out;
- *options = dict;
+ *options = dict;
out:
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to parse replace-brick CLI");
- if (dict)
- dict_destroy (dict);
- }
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to parse reset-brick CLI");
+ if (dict)
+ dict_unref(dict);
+ }
- return ret;
+ return ret;
}
int32_t
-cli_cmd_log_filename_parse (const char **words, int wordcount, dict_t **options)
+cli_cmd_log_filename_parse(const char **words, int wordcount, dict_t **options)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- char *str = NULL;
- int ret = -1;
- char *delimiter = NULL;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ char *str = NULL;
+ int ret = -1;
+ char *delimiter = NULL;
- GF_ASSERT (words);
- GF_ASSERT (options);
+ GF_ASSERT(words);
+ GF_ASSERT(options);
- dict = dict_new ();
- if (!dict)
- goto out;
+ dict = dict_new();
+ if (!dict)
+ goto out;
- volname = (char *)words[3];
- GF_ASSERT (volname);
+ volname = (char *)words[3];
+ GF_ASSERT(volname);
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- str = (char *)words[4];
- if (strchr (str, ':')) {
- delimiter = strchr (words[4], ':');
- if (!delimiter || delimiter == words[4]
- || *(delimiter+1) != '/') {
- cli_err ("wrong brick type: %s, use <HOSTNAME>:"
- "<export-dir-abs-path>", words[4]);
- ret = -1;
- goto out;
- } else {
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
- ret = dict_set_str (dict, "brick", str);
- if (ret)
- goto out;
- /* Path */
- str = (char *)words[5];
- ret = dict_set_str (dict, "path", str);
- if (ret)
- goto out;
+ str = (char *)words[4];
+ if (strchr(str, ':')) {
+ delimiter = strchr(words[4], ':');
+ if (!delimiter || delimiter == words[4] || *(delimiter + 1) != '/') {
+ cli_err(
+ "wrong brick type: %s, use <HOSTNAME>:"
+ "<export-dir-abs-path>",
+ words[4]);
+ ret = -1;
+ goto out;
} else {
- ret = dict_set_str (dict, "path", str);
- if (ret)
- goto out;
+ ret = gf_canonicalize_path(delimiter + 1);
+ if (ret)
+ goto out;
}
+ ret = dict_set_str(dict, "brick", str);
+ if (ret)
+ goto out;
+ /* Path */
+ str = (char *)words[5];
+ ret = dict_set_str(dict, "path", str);
+ if (ret)
+ goto out;
+ } else {
+ ret = dict_set_str(dict, "path", str);
+ if (ret)
+ goto out;
+ }
- *options = dict;
+ *options = dict;
out:
- if (ret && dict)
- dict_destroy (dict);
+ if (ret && dict)
+ dict_unref(dict);
- return ret;
+ return ret;
}
int32_t
-cli_cmd_log_level_parse (const char **words, int worcount, dict_t **options)
+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_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;
+ dict = dict_new();
+ if (!dict)
+ goto out;
- GF_ASSERT(words[3]);
- GF_ASSERT(words[4]);
+ 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, "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, "xlator", (char *)words[4]);
+ if (ret)
+ goto out;
- ret = dict_set_str (dict, "loglevel", (char *)words[5]);
- if (ret)
- goto out;
+ ret = dict_set_str(dict, "loglevel", (char *)words[5]);
+ if (ret)
+ goto out;
- *options = dict;
+ *options = dict;
- out:
- if (ret && dict)
- dict_destroy (dict);
+out:
+ if (ret && dict)
+ dict_unref(dict);
- return ret;
+ return ret;
}
int32_t
-cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options)
+cli_cmd_log_locate_parse(const char **words, int wordcount, dict_t **options)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- char *str = NULL;
- int ret = -1;
- char *delimiter = NULL;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ char *str = NULL;
+ int ret = -1;
+ char *delimiter = NULL;
- GF_ASSERT (words);
- GF_ASSERT (options);
+ GF_ASSERT(words);
+ GF_ASSERT(options);
- dict = dict_new ();
- if (!dict)
- goto out;
+ dict = dict_new();
+ if (!dict)
+ goto out;
- volname = (char *)words[3];
- GF_ASSERT (volname);
+ volname = (char *)words[3];
+ GF_ASSERT(volname);
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- if (words[4]) {
- delimiter = strchr (words[4], ':');
- if (!delimiter || delimiter == words[4]
- || *(delimiter+1) != '/') {
- cli_err ("wrong brick type: %s, use <HOSTNAME>:"
- "<export-dir-abs-path>", words[4]);
- ret = -1;
- goto out;
- } else {
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
- str = (char *)words[4];
- ret = dict_set_str (dict, "brick", str);
- if (ret)
- goto out;
+ if (words[4]) {
+ delimiter = strchr(words[4], ':');
+ if (!delimiter || delimiter == words[4] || *(delimiter + 1) != '/') {
+ cli_err(
+ "wrong brick type: %s, use <HOSTNAME>:"
+ "<export-dir-abs-path>",
+ words[4]);
+ ret = -1;
+ goto out;
+ } else {
+ ret = gf_canonicalize_path(delimiter + 1);
+ if (ret)
+ goto out;
}
+ str = (char *)words[4];
+ ret = dict_set_str(dict, "brick", str);
+ if (ret)
+ goto out;
+ }
- *options = dict;
+ *options = dict;
out:
- if (ret && dict)
- dict_destroy (dict);
+ if (ret && dict)
+ dict_unref(dict);
- return ret;
+ return ret;
}
int32_t
-cli_cmd_log_rotate_parse (const char **words, int wordcount, dict_t **options)
+cli_cmd_log_rotate_parse(const char **words, int wordcount, dict_t **options)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- char *str = NULL;
- int ret = -1;
- char *delimiter = NULL;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ char *str = NULL;
+ int ret = -1;
+ char *delimiter = NULL;
- GF_ASSERT (words);
- GF_ASSERT (options);
+ GF_ASSERT(words);
+ GF_ASSERT(options);
- dict = dict_new ();
- if (!dict)
- goto out;
+ dict = dict_new();
+ if (!dict)
+ goto out;
- if (strcmp ("rotate", words[3]) == 0)
- volname = (char *)words[2];
- else if (strcmp ("rotate", words[2]) == 0)
- volname = (char *)words[3];
- GF_ASSERT (volname);
+ if (strcmp("rotate", words[3]) == 0)
+ volname = (char *)words[2];
+ GF_ASSERT(volname);
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- if (words[4]) {
- delimiter = strchr (words[4], ':');
- if (!delimiter || delimiter == words[4]
- || *(delimiter+1) != '/') {
- cli_err ("wrong brick type: %s, use <HOSTNAME>:"
- "<export-dir-abs-path>", words[4]);
- ret = -1;
- goto out;
- } else {
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
- str = (char *)words[4];
- ret = dict_set_str (dict, "brick", str);
- if (ret)
- goto out;
+ if (words[4]) {
+ delimiter = strchr(words[4], ':');
+ if (!delimiter || delimiter == words[4] || *(delimiter + 1) != '/') {
+ cli_err(
+ "wrong brick type: %s, use <HOSTNAME>:"
+ "<export-dir-abs-path>",
+ words[4]);
+ ret = -1;
+ goto out;
+ } else {
+ ret = gf_canonicalize_path(delimiter + 1);
+ if (ret)
+ goto out;
}
+ str = (char *)words[4];
+ ret = dict_set_str(dict, "brick", str);
+ if (ret)
+ goto out;
+ }
- *options = dict;
+ *options = dict;
out:
- if (ret && dict)
- dict_destroy (dict);
+ if (ret && dict)
+ dict_unref(dict);
- return ret;
+ return ret;
}
static gf_boolean_t
-gsyncd_url_check (const char *w)
+gsyncd_url_check(const char *w)
{
- return !!strpbrk (w, ":/");
+ return !!strpbrk(w, ":/");
}
static gf_boolean_t
-gsyncd_glob_check (const char *w)
+valid_slave_gsyncd_url(const char *w)
{
- return !!strpbrk (w, "*?[");
+ if (strstr(w, ":::"))
+ return _gf_false;
+ else if (strstr(w, "::"))
+ return _gf_true;
+ else
+ return _gf_false;
}
-static int
-config_parse (const char **words, int wordcount, dict_t *dict,
- unsigned cmdi, unsigned glob)
+static gf_boolean_t
+gsyncd_glob_check(const char *w)
{
- int32_t ret = -1;
- int32_t i = -1;
- char *append_str = NULL;
- size_t append_len = 0;
- char *subop = NULL;
+ return !!strpbrk(w, "*?[");
+}
- switch ((wordcount - 1) - cmdi) {
+static int
+config_parse(const char **words, int wordcount, dict_t *dict, unsigned cmdi,
+ unsigned glob)
+{
+ int32_t ret = -1;
+ int32_t i = -1;
+ char *append_str = NULL;
+ size_t append_len = 0;
+ char *subop = NULL;
+ char *ret_chkpt = NULL;
+ struct tm checkpoint_time;
+ char chkpt_buf[20] = "";
+
+ switch ((wordcount - 1) - cmdi) {
case 0:
- subop = gf_strdup ("get-all");
- break;
+ subop = gf_strdup("get-all");
+ break;
case 1:
- if (words[cmdi + 1][0] == '!') {
- (words[cmdi + 1])++;
- if (gf_asprintf (&subop, "del%s",
- glob ? "-glob" : "") == -1)
- subop = NULL;
- } else
- subop = gf_strdup ("get");
+ if (words[cmdi + 1][0] == '!') {
+ (words[cmdi + 1])++;
+ if (gf_asprintf(&subop, "del%s", glob ? "-glob" : "") == -1)
+ subop = NULL;
+ } else
+ subop = gf_strdup("get");
- ret = dict_set_str (dict, "op_name", ((char *)words[cmdi + 1]));
- if (ret < 0)
- goto out;
- break;
+ ret = dict_set_str(dict, "op_name", ((char *)words[cmdi + 1]));
+ if (ret < 0)
+ goto out;
+ break;
default:
- if (gf_asprintf (&subop, "set%s", glob ? "-glob" : "") == -1)
- subop = NULL;
+ 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)
- goto out;
+ ret = dict_set_str(dict, "op_name", ((char *)words[cmdi + 1]));
+ if (ret < 0)
+ goto out;
- /* join the varargs by spaces to get the op_value */
+ /* join the varargs by spaces to get the op_value */
- for (i = cmdi + 2; i < wordcount; i++)
- append_len += (strlen (words[i]) + 1);
- /* trailing strcat will add two bytes, make space for that */
- append_len++;
+ for (i = cmdi + 2; i < wordcount; i++)
+ append_len += (strlen(words[i]) + 1);
+ /* trailing strcat will add two bytes, make space for that */
+ append_len++;
- append_str = GF_CALLOC (1, append_len, cli_mt_append_str);
- if (!append_str) {
- ret = -1;
- goto out;
- }
+ /* strcat is used on this allocation and hence expected to be
+ * initiatlized to 0. So GF_CALLOC is used.
+ */
+ append_str = GF_CALLOC(1, append_len, cli_mt_append_str);
+ if (!append_str) {
+ ret = -1;
+ goto out;
+ }
+
+ for (i = cmdi + 2; i < wordcount; i++) {
+ strcat(append_str, words[i]);
+ strcat(append_str, " ");
+ }
+ append_str[append_len - 2] = '\0';
+ /* "checkpoint now" is special: we resolve that "now" */
+ if ((strcmp(words[cmdi + 1], "checkpoint") == 0) &&
+ (strcmp(append_str, "now") == 0)) {
+ struct timeval tv = {
+ 0,
+ };
+
+ ret = gettimeofday(&tv, NULL);
+ if (ret == -1)
+ goto out;
- for (i = cmdi + 2; i < wordcount; i++) {
- strcat (append_str, words[i]);
- strcat (append_str, " ");
- }
- append_str[append_len - 2] = '\0';
- /* "checkpoint now" is special: we resolve that "now" */
- if ((strcmp (words[cmdi + 1], "checkpoint") == 0) &&
- (strcmp (append_str, "now") == 0)) {
- struct timeval tv = {0,};
-
- ret = gettimeofday (&tv, NULL);
- if (ret == -1)
- goto out;
-
- GF_FREE (append_str);
- append_str = GF_CALLOC (1, 300, cli_mt_append_str);
- if (!append_str) {
- ret = -1;
- goto out;
- }
- snprintf (append_str, 300, "%" GF_PRI_SECOND,
- tv.tv_sec);
+ GF_FREE(append_str);
+ append_str = GF_MALLOC(300, cli_mt_append_str);
+ if (!append_str) {
+ ret = -1;
+ goto out;
+ }
+ snprintf(append_str, 300, "%" GF_PRI_SECOND, tv.tv_sec);
+ } else if ((strcmp(words[cmdi + 1], "checkpoint") == 0) &&
+ (strcmp(append_str, "now") != 0)) {
+ memset(&checkpoint_time, 0, sizeof(struct tm));
+ ret_chkpt = strptime(append_str, "%Y-%m-%d %H:%M:%S",
+ &checkpoint_time);
+
+ if (ret_chkpt == NULL || *ret_chkpt != '\0') {
+ ret = -1;
+ cli_err(
+ "Invalid Checkpoint label. Use format "
+ "\"Y-m-d H:M:S\", Example: 2016-10-25 15:30:45");
+ goto out;
+ }
+ GF_FREE(append_str);
+ append_str = GF_MALLOC(300, cli_mt_append_str);
+ if (!append_str) {
+ ret = -1;
+ goto out;
}
+ strftime(chkpt_buf, sizeof(chkpt_buf), "%s", &checkpoint_time);
+ snprintf(append_str, 300, "%s", chkpt_buf);
+ }
- ret = dict_set_dynstr (dict, "op_value", append_str);
- }
+ ret = dict_set_dynstr(dict, "op_value", append_str);
+ if (ret != 0) {
+ goto out;
+ }
+ append_str = NULL;
+ }
- ret = -1;
- if (subop) {
- ret = dict_set_dynstr (dict, "subop", subop);
- if (!ret)
- subop = NULL;
- }
+ ret = -1;
+ if (subop) {
+ ret = dict_set_dynstr(dict, "subop", subop);
+ if (!ret)
+ subop = NULL;
+ }
out:
- if (ret && append_str)
- GF_FREE (append_str);
+ GF_FREE(append_str);
+ GF_FREE(subop);
- GF_FREE (subop);
-
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
+/* ssh_port_parse: Parses and validates when ssh_port is given.
+ * ssh_index refers to index of ssh_port and
+ * type refers to either push-pem or no-verify
+ */
+
static int32_t
-force_push_pem_no_verify_parse (const char **words, int wordcount,
- dict_t *dict, unsigned *cmdi)
+parse_ssh_port(const char **words, int wordcount, dict_t *dict, unsigned *cmdi,
+ int ssh_index, char *type)
{
- int32_t ret = 0;
-
- if (!strcmp ((char *)words[wordcount-1], "force")) {
- if ((strcmp ((char *)words[wordcount-2], "start")) &&
- (strcmp ((char *)words[wordcount-2], "stop")) &&
- (strcmp ((char *)words[wordcount-2], "create")) &&
- (strcmp ((char *)words[wordcount-2], "no-verify")) &&
- (strcmp ((char *)words[wordcount-2], "push-pem")) &&
- (strcmp ((char *)words[wordcount-2], "pause")) &&
- (strcmp ((char *)words[wordcount-2], "resume"))) {
- ret = -1;
- goto out;
- }
- ret = dict_set_uint32 (dict, "force",
- _gf_true);
- if (ret)
- goto out;
- (*cmdi)++;
+ int ret = 0;
+ char *end_ptr = NULL;
+ int64_t limit = 0;
- if (!strcmp ((char *)words[wordcount-2], "push-pem")) {
- if (strcmp ((char *)words[wordcount-3], "create")) {
- ret = -1;
- goto out;
- }
- ret = dict_set_int32 (dict, "push_pem", 1);
- if (ret)
- goto out;
- (*cmdi)++;
- } else if (!strcmp ((char *)words[wordcount-2], "no-verify")) {
- if (strcmp ((char *)words[wordcount-3], "create")) {
- ret = -1;
- goto out;
- }
- ret = dict_set_uint32 (dict, "no_verify",
- _gf_true);
- if (ret)
- goto out;
- (*cmdi)++;
- }
- } else if (!strcmp ((char *)words[wordcount-1], "push-pem")) {
- if (strcmp ((char *)words[wordcount-2], "create")) {
- ret = -1;
- goto out;
- }
- ret = dict_set_int32 (dict, "push_pem", 1);
- if (ret)
- goto out;
- (*cmdi)++;
- } else if (!strcmp ((char *)words[wordcount-1], "no-verify")) {
- if ((strcmp ((char *)words[wordcount-2], "create"))) {
- ret = -1;
- goto out;
- }
- ret = dict_set_uint32 (dict, "no_verify",
- _gf_true);
- if (ret)
- goto out;
- (*cmdi)++;
+ if (!strcmp((char *)words[ssh_index], "ssh-port")) {
+ if (strcmp((char *)words[ssh_index - 1], "create")) {
+ ret = -1;
+ goto out;
+ }
+ (*cmdi)++;
+ limit = strtol(words[ssh_index + 1], &end_ptr, 10);
+ if (errno == ERANGE || errno == EINVAL || limit <= 0 ||
+ strcmp(end_ptr, "") != 0) {
+ ret = -1;
+ cli_err("Please enter an integer value for ssh_port ");
+ goto out;
}
+ ret = dict_set_int32(dict, "ssh_port", limit);
+ if (ret)
+ goto out;
+ (*cmdi)++;
+ } else if (strcmp((char *)words[ssh_index + 1], "create")) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_int32(dict, type, 1);
+ if (ret)
+ goto out;
+ (*cmdi)++;
+
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ return ret;
}
-
-int32_t
-cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)
+static int32_t
+force_push_pem_no_verify_parse(const char **words, int wordcount, dict_t *dict,
+ unsigned *cmdi)
{
- int32_t ret = -1;
- dict_t *dict = NULL;
- gf1_cli_gsync_set type = GF_GSYNC_OPTION_TYPE_NONE;
- int i = 0;
- unsigned masteri = 0;
- unsigned slavei = 0;
- unsigned glob = 0;
- unsigned cmdi = 0;
- char *opwords[] = { "create", "status", "start", "stop",
- "config", "force", "delete", "no-verify"
- "push-pem", "detail", "pause",
- "resume", NULL };
- char *w = NULL;
- char *save_ptr = NULL;
- char *slave_temp = NULL;
- char *token = NULL;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- /* new syntax:
- *
- * volume geo-replication $m $s create [[no-verify] | [push-pem]] [force]
- * volume geo-replication [$m [$s]] status [detail]
- * volume geo-replication [$m] $s config [[!]$opt [$val]]
- * volume geo-replication $m $s start|stop [force]
- * volume geo-replication $m $s delete
- * volume geo-replication $m $s pause [force]
- * volume geo-replication $m $s resume [force]
- */
+ int32_t ret = 0;
+
+ if (!strcmp((char *)words[wordcount - 1], "force")) {
+ if ((strcmp((char *)words[wordcount - 2], "start")) &&
+ (strcmp((char *)words[wordcount - 2], "stop")) &&
+ (strcmp((char *)words[wordcount - 2], "create")) &&
+ (strcmp((char *)words[wordcount - 2], "no-verify")) &&
+ (strcmp((char *)words[wordcount - 2], "push-pem")) &&
+ (strcmp((char *)words[wordcount - 2], "pause")) &&
+ (strcmp((char *)words[wordcount - 2], "resume"))) {
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_int32n(dict, "force", SLEN("force"), 1);
+ if (ret)
+ goto out;
+ (*cmdi)++;
- if (wordcount < 3)
+ if (!strcmp((char *)words[wordcount - 2], "push-pem")) {
+ ret = parse_ssh_port(words, wordcount, dict, cmdi, wordcount - 4,
+ "push_pem");
+ if (ret)
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)
- masteri = 2;
- } else if (i <= 3) {
- if (!strcmp ((char *)words[wordcount-1], "detail")) {
- /* For status detail it is mandatory to provide
- * both master and slave */
- ret = -1;
- goto out;
- }
-
- /* no $s, can only be status cmd
- * (with either a single $m before it or nothing)
- * -- these conditions imply that i <= 3 after
- * the iteration and that i is the successor of
- * the (0 or 1 length) sequence of $m-s.
- */
- cmdi = i;
- if (i == 3)
- masteri = 2;
- } else
+ } else if (!strcmp((char *)words[wordcount - 2], "no-verify")) {
+ ret = parse_ssh_port(words, wordcount, dict, cmdi, wordcount - 4,
+ "no_verify");
+ if (ret)
goto out;
+ }
+ } else if (!strcmp((char *)words[wordcount - 1], "push-pem")) {
+ ret = parse_ssh_port(words, wordcount, dict, cmdi, wordcount - 3,
+ "push_pem");
+ if (ret)
+ goto out;
+ } else if (!strcmp((char *)words[wordcount - 1], "no-verify")) {
+ ret = parse_ssh_port(words, wordcount, dict, cmdi, wordcount - 3,
+ "no_verify");
+ if (ret)
+ goto out;
+ }
- /* now check if input really complies syntax
- * (in a somewhat redundant way, in favor
- * transparent soundness)
- */
-
- if (masteri && gsyncd_url_check (words[masteri]))
- goto out;
- if (slavei && !glob && !gsyncd_url_check (words[slavei]))
- goto out;
+out:
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
- w = str_getunamb (words[cmdi], opwords);
- if (!w)
- goto out;
+int32_t
+cli_cmd_gsync_set_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **errstr)
+{
+ int32_t ret = -1;
+ dict_t *dict = NULL;
+ gf1_cli_gsync_set type = GF_GSYNC_OPTION_TYPE_NONE;
+ int i = 0;
+ unsigned masteri = 0;
+ unsigned slavei = 0;
+ unsigned glob = 0;
+ unsigned cmdi = 0;
+ static char *opwords[] = {"create", "status", "start", "stop",
+ "config", "force", "delete", "ssh-port",
+ "no-verify", "push-pem", "detail", "pause",
+ "resume", NULL};
+ char *w = NULL;
+ char *save_ptr = NULL;
+ char *slave_temp = NULL;
+ char *token = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *question = NULL;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
- if (strcmp (w, "create") == 0) {
- type = GF_GSYNC_OPTION_TYPE_CREATE;
+ /* new syntax:
+ *
+ * volume geo-replication $m $s create [[ssh-port n] [[no-verify] |
+ * [push-pem]]] [force] volume geo-replication [$m [$s]] status [detail]
+ * volume geo-replication [$m] $s config [[!]$opt [$val]]
+ * volume geo-replication $m $s start|stop [force]
+ * volume geo-replication $m $s delete [reset-sync-time]
+ * volume geo-replication $m $s pause [force]
+ * volume geo-replication $m $s resume [force]
+ */
+
+ if (wordcount < 3)
+ goto out;
- if (!masteri || !slavei)
- goto out;
- } else if (strcmp (w, "status") == 0) {
- type = GF_GSYNC_OPTION_TYPE_STATUS;
+ 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 (slavei && !masteri)
- goto out;
- } else if (strcmp (w, "config") == 0) {
- type = GF_GSYNC_OPTION_TYPE_CONFIG;
+ 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)
+ masteri = 2;
+ } else if (i <= 4) {
+ if (strtail("detail", (char *)words[wordcount - 1])) {
+ cmdi = wordcount - 2;
+ if (i == 4)
+ masteri = 2;
+ } else {
+ /* no $s, can only be status cmd
+ * (with either a single $m before it or nothing)
+ * -- these conditions imply that i <= 3 after
+ * the iteration and that i is the successor of
+ * the (0 or 1 length) sequence of $m-s.
+ */
+ cmdi = i;
+ if (i == 3)
+ masteri = 2;
+ }
+ } else
+ goto out;
- if (!slavei)
- goto out;
- } else if (strcmp (w, "start") == 0) {
- type = GF_GSYNC_OPTION_TYPE_START;
+ /* now check if input really complies syntax
+ * (in a somewhat redundant way, in favor
+ * transparent soundness)
+ */
- if (!masteri || !slavei)
- goto out;
- } else if (strcmp (w, "stop") == 0) {
- type = GF_GSYNC_OPTION_TYPE_STOP;
+ if (masteri && gsyncd_url_check(words[masteri]))
+ goto out;
- if (!masteri || !slavei)
- goto out;
- } else if (strcmp (w, "delete") == 0) {
- type = GF_GSYNC_OPTION_TYPE_DELETE;
+ if (slavei && !glob && !valid_slave_gsyncd_url(words[slavei])) {
+ gf_asprintf(errstr, "Invalid slave url: %s", words[slavei]);
+ goto out;
+ }
- if (!masteri || !slavei)
- goto out;
- } else if (strcmp (w, "pause") == 0) {
- type = GF_GSYNC_OPTION_TYPE_PAUSE;
+ w = str_getunamb(words[cmdi], opwords);
+ if (!w)
+ goto out;
- if (!masteri || !slavei)
- goto out;
- } else if (strcmp (w, "resume") == 0) {
- type = GF_GSYNC_OPTION_TYPE_RESUME;
+ if (strcmp(w, "create") == 0) {
+ type = GF_GSYNC_OPTION_TYPE_CREATE;
+
+ if (!masteri || !slavei)
+ goto out;
+ } else if (strcmp(w, "status") == 0) {
+ type = GF_GSYNC_OPTION_TYPE_STATUS;
+
+ if (slavei && !masteri)
+ goto out;
+ } else if (strcmp(w, "config") == 0) {
+ type = GF_GSYNC_OPTION_TYPE_CONFIG;
+
+ if (!slavei)
+ goto out;
+ } else if (strcmp(w, "start") == 0) {
+ type = GF_GSYNC_OPTION_TYPE_START;
+
+ if (!masteri || !slavei)
+ goto out;
+ } else if (strcmp(w, "stop") == 0) {
+ type = GF_GSYNC_OPTION_TYPE_STOP;
+
+ if (!masteri || !slavei)
+ goto out;
+ } else if (strcmp(w, "delete") == 0) {
+ type = GF_GSYNC_OPTION_TYPE_DELETE;
+
+ if (!masteri || !slavei)
+ goto out;
+ } else if (strcmp(w, "pause") == 0) {
+ type = GF_GSYNC_OPTION_TYPE_PAUSE;
+
+ if (!masteri || !slavei)
+ goto out;
+ } else if (strcmp(w, "resume") == 0) {
+ type = GF_GSYNC_OPTION_TYPE_RESUME;
+
+ if (!masteri || !slavei)
+ goto out;
+ } else
+ GF_ASSERT(!"opword mismatch");
+
+ ret = force_push_pem_no_verify_parse(words, wordcount, dict, &cmdi);
+ if (ret)
+ goto out;
- if (!masteri || !slavei)
- goto out;
- } else
- GF_ASSERT (!"opword mismatch");
+ if (strtail("detail", (char *)words[wordcount - 1])) {
+ if (!strtail("status", (char *)words[wordcount - 2])) {
+ ret = -1;
+ goto out;
+ }
- ret = force_push_pem_no_verify_parse (words, wordcount, dict, &cmdi);
+ ret = dict_set_uint32(dict, "status-detail", _gf_true);
if (ret)
- goto out;
+ goto out;
+ cmdi++;
+ }
- if (!strcmp ((char *)words[wordcount-1], "detail")) {
- if (strcmp ((char *)words[wordcount-2], "status")) {
- ret = -1;
- goto out;
- }
- if (!slavei || !masteri) {
- ret = -1;
- goto out;
- }
- ret = dict_set_uint32 (dict, "status-detail", _gf_true);
- if (ret)
- goto out;
- cmdi++;
+ if (type == GF_GSYNC_OPTION_TYPE_DELETE &&
+ !strcmp((char *)words[wordcount - 1], "reset-sync-time")) {
+ if (strcmp((char *)words[wordcount - 2], "delete")) {
+ ret = -1;
+ goto out;
}
+ ret = dict_set_uint32(dict, "reset-sync-time", _gf_true);
+ if (ret)
+ goto out;
+ cmdi++;
+ }
- if (type != GF_GSYNC_OPTION_TYPE_CONFIG &&
- (cmdi < wordcount - 1 || glob))
- goto out;
+ if (type != GF_GSYNC_OPTION_TYPE_CONFIG && (cmdi < wordcount - 1 || glob)) {
+ ret = -1;
+ goto out;
+ }
- /* If got so far, input is valid, assemble the message */
+ /* If got so far, input is valid, assemble the message */
- ret = 0;
+ ret = 0;
- if (masteri) {
- ret = dict_set_str (dict, "master", (char *)words[masteri]);
- if (!ret)
- ret = dict_set_str (dict, "volname",
- (char *)words[masteri]);
- }
- if (!ret && slavei) {
- /* If geo-rep is created with root user using the syntax
- * gluster vol geo-rep <mastervol> root@<slavehost> ...
- * pass down only <slavehost> else pass as it is.
- */
- slave_temp = gf_strdup (words[slavei]);
- token = strtok_r (slave_temp, "@", &save_ptr);
- if (token && !strcmp (token, "root")) {
- ret = dict_set_str (dict, "slave",
- (char *)words[slavei]+5);
- } else {
- ret = dict_set_str (dict, "slave",
- (char *)words[slavei]);
- }
- }
+ if (masteri) {
+ ret = dict_set_str(dict, "master", (char *)words[masteri]);
if (!ret)
- ret = dict_set_int32 (dict, "type", type);
- if (!ret && type == GF_GSYNC_OPTION_TYPE_CONFIG)
- ret = config_parse (words, wordcount, dict, cmdi, glob);
+ ret = dict_set_str(dict, "volname", (char *)words[masteri]);
+ }
+ if (!ret && slavei) {
+ /* If geo-rep is created with root user using the syntax
+ * gluster vol geo-rep <mastervol> root@<slavehost> ...
+ * pass down only <slavehost> else pass as it is.
+ */
+ slave_temp = gf_strdup(words[slavei]);
+ if (slave_temp == NULL) {
+ ret = -1;
+ goto out;
+ }
+ token = strtok_r(slave_temp, "@", &save_ptr);
+ if (token && !strcmp(token, "root")) {
+ ret = dict_set_str(dict, "slave", (char *)words[slavei] + 5);
+ } else {
+ ret = dict_set_str(dict, "slave", (char *)words[slavei]);
+ }
+ }
+ if (!ret)
+ ret = dict_set_int32(dict, "type", type);
+ if (!ret && type == GF_GSYNC_OPTION_TYPE_CONFIG) {
+ if (!strcmp((char *)words[wordcount - 2], "ignore-deletes") &&
+ !strcmp((char *)words[wordcount - 1], "true")) {
+ question =
+ "There exists ~15 seconds delay for the option to take"
+ " effect from stime of the corresponding brick. Please"
+ " check the log for the time, the option is effective."
+ " Proceed";
+
+ answer = cli_cmd_get_confirmation(state, question);
+
+ if (GF_ANSWER_NO == answer) {
+ gf_log("cli", GF_LOG_INFO,
+ "Operation "
+ "cancelled, exiting");
+ *errstr = gf_strdup("Aborted by user.");
+ ret = -1;
+ goto out;
+ }
+ }
-out:
- if (slave_temp)
- GF_FREE (slave_temp);
- if (ret) {
- if (dict)
- dict_destroy (dict);
- } else
- *options = dict;
+ ret = config_parse(words, wordcount, dict, cmdi, glob);
+ }
+out:
+ if (slave_temp)
+ GF_FREE(slave_temp);
+ if (ret && dict)
+ dict_unref(dict);
+ else
+ *options = dict;
- return ret;
+ return ret;
}
int32_t
-cli_cmd_volume_profile_parse (const char **words, int wordcount,
- dict_t **options)
+cli_cmd_volume_profile_parse(const char **words, int wordcount,
+ dict_t **options)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- int ret = -1;
- gf1_cli_stats_op op = GF_CLI_STATS_NONE;
- gf1_cli_info_op info_op = GF_CLI_INFO_NONE;
- gf_boolean_t is_peek = _gf_false;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int ret = -1;
+ gf1_cli_stats_op op = GF_CLI_STATS_NONE;
+ gf1_cli_info_op info_op = GF_CLI_INFO_NONE;
+ gf_boolean_t is_peek = _gf_false;
- char *opwords[] = { "start", "stop", "info", NULL };
- char *w = NULL;
+ static char *opwords[] = {"start", "stop", "info", NULL};
+ char *w = NULL;
- GF_ASSERT (words);
- GF_ASSERT (options);
-
- dict = dict_new ();
- if (!dict)
- goto out;
+ GF_ASSERT(words);
+ GF_ASSERT(options);
- if (wordcount < 4)
- goto out;
+ dict = dict_new();
+ if (!dict)
+ goto out;
- volname = (char *)words[2];
+ if (wordcount < 4)
+ goto out;
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ volname = (char *)words[2];
- w = str_getunamb (words[3], opwords);
- if (!w) {
- ret = -1;
- goto out;
- }
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- if ((strcmp (w, "start") == 0 || strcmp (w, "stop") == 0) &&
- wordcount > 5)
- goto out;
+ w = str_getunamb(words[3], opwords);
+ if (!w) {
+ ret = -1;
+ goto out;
+ }
- if (strcmp (w, "info") == 0 && wordcount > 7)
- goto out;
+ if ((strcmp(w, "start") == 0 || strcmp(w, "stop") == 0) && wordcount > 5) {
+ ret = -1;
+ goto out;
+ }
- if (strcmp (w, "start") == 0) {
- op = GF_CLI_STATS_START;
- } else if (strcmp (w, "stop") == 0) {
- op = GF_CLI_STATS_STOP;
- } else if (strcmp (w, "info") == 0) {
- op = GF_CLI_STATS_INFO;
- info_op = GF_CLI_INFO_ALL;
- if (wordcount > 4) {
- if (strcmp (words[4], "incremental") == 0) {
- info_op = GF_CLI_INFO_INCREMENTAL;
- if (wordcount > 5 &&
- strcmp (words[5], "peek") == 0) {
- is_peek = _gf_true;
- }
- } else if (strcmp (words[4], "cumulative") == 0) {
- info_op = GF_CLI_INFO_CUMULATIVE;
- } else if (strcmp (words[4], "clear") == 0) {
- info_op = GF_CLI_INFO_CLEAR;
- } else if (strcmp (words[4], "peek") == 0) {
- is_peek = _gf_true;
- }
- }
- } else
- GF_ASSERT (!"opword mismatch");
+ if (strcmp(w, "info") == 0 && wordcount > 7) {
+ ret = -1;
+ goto out;
+ }
+
+ if (strcmp(w, "start") == 0) {
+ op = GF_CLI_STATS_START;
+ } else if (strcmp(w, "stop") == 0) {
+ op = GF_CLI_STATS_STOP;
+ } else if (strcmp(w, "info") == 0) {
+ op = GF_CLI_STATS_INFO;
+ info_op = GF_CLI_INFO_ALL;
+ if (wordcount > 4) {
+ if (strcmp(words[4], "incremental") == 0) {
+ info_op = GF_CLI_INFO_INCREMENTAL;
+ if (wordcount > 5 && strcmp(words[5], "peek") == 0) {
+ is_peek = _gf_true;
+ }
+ } else if (strcmp(words[4], "cumulative") == 0) {
+ info_op = GF_CLI_INFO_CUMULATIVE;
+ } else if (strcmp(words[4], "clear") == 0) {
+ info_op = GF_CLI_INFO_CLEAR;
+ } else if (strcmp(words[4], "peek") == 0) {
+ is_peek = _gf_true;
+ }
+ }
+ } else
+ GF_ASSERT(!"opword mismatch");
+
+ ret = dict_set_int32(dict, "op", (int32_t)op);
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "op", (int32_t)op);
- if (ret)
- goto out;
+ ret = dict_set_int32(dict, "info-op", (int32_t)info_op);
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "info-op", (int32_t)info_op);
- if (ret)
- goto out;
+ ret = dict_set_int32(dict, "peek", is_peek);
+ if (ret)
+ goto out;
- ret = dict_set_int32 (dict, "peek", is_peek);
+ if (!strcmp(words[wordcount - 1], "nfs")) {
+ ret = dict_set_int32(dict, "nfs", _gf_true);
if (ret)
- goto out;
-
- if (!strcmp (words[wordcount - 1], "nfs")) {
- ret = dict_set_int32 (dict, "nfs", _gf_true);
- if (ret)
- goto out;
- }
+ goto out;
+ }
- *options = dict;
+ *options = dict;
out:
- if (ret && dict)
- dict_destroy (dict);
- return ret;
+ if (ret && dict)
+ dict_unref(dict);
+ return ret;
}
int32_t
-cli_cmd_volume_top_parse (const char **words, int wordcount,
- dict_t **options)
+cli_cmd_volume_top_parse(const char **words, int wordcount, dict_t **options)
{
- dict_t *dict = NULL;
- char *volname = NULL;
- char *value = NULL;
- char *key = NULL;
- int ret = -1;
- gf1_cli_stats_op op = GF_CLI_STATS_NONE;
- gf1_cli_top_op top_op = GF_CLI_TOP_NONE;
- int32_t list_cnt = -1;
- int index = 0;
- int perf = 0;
- int32_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",
- "clear", NULL };
- char *w = NULL;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- if (wordcount < 4)
- goto out;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ char *value = NULL;
+ char *key = NULL;
+ int ret = -1;
+ gf1_cli_stats_op op = GF_CLI_STATS_NONE;
+ gf1_cli_top_op top_op = GF_CLI_TOP_NONE;
+ int32_t list_cnt = -1;
+ int index = 0;
+ int perf = 0;
+ int32_t blk_size = 0;
+ int count = 0;
+ gf_boolean_t nfs = _gf_false;
+ char *delimiter = NULL;
+ static char *opwords[] = {"open", "read", "write",
+ "opendir", "readdir", "read-perf",
+ "write-perf", "clear", NULL};
+ char *w = NULL;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
- volname = (char *)words[2];
+ if (wordcount < 4)
+ goto out;
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ volname = (char *)words[2];
- op = GF_CLI_STATS_TOP;
- ret = dict_set_int32 (dict, "op", (int32_t)op);
- if (ret)
- goto out;
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret)
+ goto out;
- 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 (w, "read") == 0) {
- top_op = GF_CLI_TOP_READ;
- } else if (strcmp (w, "write") == 0) {
- top_op = GF_CLI_TOP_WRITE;
- } else if (strcmp (w, "opendir") == 0) {
- top_op = GF_CLI_TOP_OPENDIR;
- } else if (strcmp (w, "readdir") == 0) {
- top_op = GF_CLI_TOP_READDIR;
- } else if (strcmp (w, "read-perf") == 0) {
- top_op = GF_CLI_TOP_READ_PERF;
- perf = 1;
- } else if (strcmp (w, "write-perf") == 0) {
- top_op = GF_CLI_TOP_WRITE_PERF;
- perf = 1;
- } else if (strcmp (w, "clear") == 0) {
- ret = dict_set_int32 (dict, "clear-stats", 1);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Could not set clear-stats in dict");
- goto out;
- }
- } else
- GF_ASSERT (!"opword mismatch");
- ret = dict_set_int32 (dict, "top-op", (int32_t)top_op);
- if (ret)
- goto out;
+ op = GF_CLI_STATS_TOP;
+ ret = dict_set_int32(dict, "op", (int32_t)op);
+ if (ret)
+ goto out;
- 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;
+ 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(w, "read") == 0) {
+ top_op = GF_CLI_TOP_READ;
+ } else if (strcmp(w, "write") == 0) {
+ top_op = GF_CLI_TOP_WRITE;
+ } else if (strcmp(w, "opendir") == 0) {
+ top_op = GF_CLI_TOP_OPENDIR;
+ } else if (strcmp(w, "readdir") == 0) {
+ top_op = GF_CLI_TOP_READDIR;
+ } else if (strcmp(w, "read-perf") == 0) {
+ top_op = GF_CLI_TOP_READ_PERF;
+ perf = 1;
+ } else if (strcmp(w, "write-perf") == 0) {
+ top_op = GF_CLI_TOP_WRITE_PERF;
+ perf = 1;
+ } else if (strcmp(w, "clear") == 0) {
+ ret = dict_set_int32(dict, "clear-stats", 1);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not set clear-stats in dict");
+ goto out;
}
+ } else
+ GF_ASSERT(!"opword mismatch");
+ ret = dict_set_int32(dict, "top-op", (int32_t)top_op);
+ if (ret)
+ goto out;
- for (; 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;
+ }
- key = (char *) words[index];
- value = (char *) words[index+1];
+ for (; index < wordcount; index += 2) {
+ key = (char *)words[index];
+ value = (char *)words[index + 1];
- if ( key && !value ) {
- ret = -1;
- goto out;
- }
- if (!strcmp (key, "brick")) {
- delimiter = strchr (value, ':');
- if (!delimiter || delimiter == value
- || *(delimiter+1) != '/') {
- cli_err ("wrong brick type: %s, use <HOSTNAME>:"
- "<export-dir-abs-path>", value);
- ret = -1;
- goto out;
- } else {
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
- ret = dict_set_str (dict, "brick", value);
-
- } else if (!strcmp (key, "list-cnt")) {
- ret = gf_is_str_int (value);
- if (!ret)
- list_cnt = atoi (value);
- if (ret || (list_cnt < 0) || (list_cnt > 100)) {
- cli_err ("list-cnt should be between 0 to 100");
- ret = -1;
- goto out;
- }
- } 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_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_uint32 (dict, "blk-size",
- (uint32_t)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_err ("count is an invalid number");
- else
- cli_err ("count should be an integer "
- "greater than zero");
-
- ret = -1;
- goto out;
- }
- ret = dict_set_uint32 (dict, "blk-cnt", count);
- } else {
- ret = -1;
- goto out;
- }
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "Dict set failed for "
- "key %s", key);
- goto out;
- }
- }
- if (list_cnt == -1)
- list_cnt = 100;
- ret = dict_set_int32 (dict, "list-cnt", list_cnt);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "Dict set failed for list_cnt");
+ if (!key || !value) {
+ ret = -1;
+ goto out;
+ }
+ if (!strcmp(key, "brick")) {
+ delimiter = strchr(value, ':');
+ if (!delimiter || delimiter == value || *(delimiter + 1) != '/') {
+ cli_err(
+ "wrong brick type: %s, use <HOSTNAME>:"
+ "<export-dir-abs-path>",
+ value);
+ ret = -1;
goto out;
- }
-
- if ((blk_size > 0) ^ (count > 0)) {
- cli_err ("Need to give both 'bs' and 'count'");
+ } else {
+ ret = gf_canonicalize_path(delimiter + 1);
+ if (ret)
+ goto out;
+ }
+ ret = dict_set_str(dict, "brick", value);
+
+ } else if (!strcmp(key, "list-cnt")) {
+ ret = gf_is_str_int(value);
+ if (!ret)
+ list_cnt = atoi(value);
+ if (ret || (list_cnt < 0) || (list_cnt > 100)) {
+ cli_err("list-cnt should be between 0 to 100");
+ ret = -1;
+ goto out;
+ }
+ } 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_err(
+ "block size is an invalid"
+ " number");
+ else
+ cli_err(
+ "block size should be an "
+ "integer greater than zero");
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 = dict_set_uint32(dict, "blk-size", (uint32_t)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_err("count is an invalid number");
+ else
+ cli_err(
+ "count should be an integer "
+ "greater than zero");
+
ret = -1;
goto out;
+ }
+ ret = dict_set_uint32(dict, "blk-cnt", count);
+ } else {
+ ret = -1;
+ goto out;
}
+ if (ret) {
+ gf_log("", GF_LOG_WARNING,
+ "Dict set failed for "
+ "key %s",
+ key);
+ goto out;
+ }
+ }
+ if (list_cnt == -1)
+ list_cnt = 100;
+ ret = dict_set_int32(dict, "list-cnt", list_cnt);
+ if (ret) {
+ gf_log("", GF_LOG_WARNING, "Dict set failed for list_cnt");
+ goto out;
+ }
- *options = dict;
+ 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)
- dict_destroy (dict);
- return ret;
+ if (ret && dict)
+ dict_unref(dict);
+ return ret;
}
uint32_t
-cli_cmd_get_statusop (const char *arg)
+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", "tasks", 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 },
- { "tasks", GF_CLI_STATUS_TASKS },
- { NULL }
- };
-
- w = str_getunamb (arg, opwords);
- if (!w) {
- gf_log ("cli", GF_LOG_DEBUG,
- "Not a status op %s", arg);
- goto out;
- }
+ int i = 0;
+ uint32_t ret = GF_CLI_STATUS_NONE;
+ char *w = NULL;
+ static char *opwords[] = {"detail", "mem", "clients", "fd", "inode",
+ "callpool", "tasks", "client-list", NULL};
+ static 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},
+ {"tasks", GF_CLI_STATUS_TASKS},
+ {"client-list", GF_CLI_STATUS_CLIENT_LIST},
+ {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;
- }
+ for (i = 0; optable[i].opname; i++) {
+ if (!strcmp(w, optable[i].opname)) {
+ ret = optable[i].opcode;
+ break;
}
+ }
- out:
- return ret;
+out:
+ return ret;
}
int
-cli_cmd_volume_status_parse (const char **words, int wordcount,
- dict_t **options)
+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_t *dict = NULL;
+ int ret = -1;
+ uint32_t cmd = 0;
- dict = dict_new ();
- if (!dict)
- goto out;
+ GF_ASSERT(options);
- switch (wordcount) {
+ dict = dict_new();
+ if (!dict)
+ goto out;
+ switch (wordcount) {
case 2:
- cmd = GF_CLI_STATUS_ALL;
- ret = 0;
- break;
+ cmd = GF_CLI_STATUS_ALL;
+ ret = 0;
+ break;
case 3:
- if (!strcmp (words[2], "all")) {
- cmd = GF_CLI_STATUS_ALL;
- ret = 0;
+ 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]);
- }
+ } else {
+ cmd = GF_CLI_STATUS_VOL;
+ ret = dict_set_str(dict, "volname", (char *)words[2]);
+ }
- break;
+ 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 if (!strcmp (words[3], "quotad")) {
- cmd |= GF_CLI_STATUS_QUOTAD;
- } else if (!strcmp (words[3], "snapd")) {
- cmd |= GF_CLI_STATUS_SNAPD;
- } else if (!strcmp (words[3], "bitd")) {
- cmd |= GF_CLI_STATUS_BITD;
- } else if (!strcmp (words[3], "scrub")) {
- cmd |= GF_CLI_STATUS_SCRUB;
- } else {
- cmd = GF_CLI_STATUS_BRICK;
- ret = dict_set_str (dict, "brick",
- (char *)words[3]);
- }
-
- } else {
- cmd |= GF_CLI_STATUS_VOL;
- ret = 0;
- }
- }
-
- break;
+ cmd = cli_cmd_get_statusop(words[3]);
- 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 (!strcmp(words[2], "all")) {
if (cmd == GF_CLI_STATUS_NONE) {
- cli_err ("%s is not a valid status option",
- words[4]);
- ret = -1;
- goto out;
+ cli_err("%s is not a valid status option", words[3]);
+ ret = -1;
+ goto out;
}
+ cmd |= GF_CLI_STATUS_ALL;
+ ret = 0;
-
- ret = dict_set_str (dict, "volname", (char *)words[2]);
+ } else {
+ ret = dict_set_str(dict, "volname", (char *)words[2]);
if (ret)
- goto out;
+ goto out;
- if (!strcmp (words[3], "nfs")) {
- if (cmd == GF_CLI_STATUS_FD ||
- cmd == GF_CLI_STATUS_DETAIL ||
- cmd == GF_CLI_STATUS_TASKS) {
- cli_err ("Detail/FD/Tasks status not available"
- " for NFS Servers");
- ret = -1;
- goto out;
- }
+ if (cmd == GF_CLI_STATUS_NONE) {
+ if (!strcmp(words[3], "nfs")) {
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 ||
- cmd == GF_CLI_STATUS_TASKS) {
- cli_err ("Detail/FD/Clients/Tasks status not "
- "available for Self-heal Daemons");
- ret = -1;
- goto out;
- }
+ } else if (!strcmp(words[3], "shd")) {
cmd |= GF_CLI_STATUS_SHD;
- } else if (!strcmp (words[3], "quotad")) {
- if (cmd == GF_CLI_STATUS_FD ||
- cmd == GF_CLI_STATUS_CLIENTS ||
- cmd == GF_CLI_STATUS_DETAIL ||
- cmd == GF_CLI_STATUS_INODE) {
- cli_err ("Detail/FD/Clients/Inode status not "
- "available for Quota Daemon");
- ret = -1;
- goto out;
- }
+ } else if (!strcmp(words[3], "quotad")) {
cmd |= GF_CLI_STATUS_QUOTAD;
- } else if (!strcmp (words[3], "snapd")) {
- if (cmd == GF_CLI_STATUS_FD ||
- cmd == GF_CLI_STATUS_CLIENTS ||
- cmd == GF_CLI_STATUS_DETAIL ||
- cmd == GF_CLI_STATUS_INODE) {
- cli_err ("Detail/FD/Clients/Inode status not "
- "available for snap daemon");
- ret = -1;
- goto out;
- }
+ } else if (!strcmp(words[3], "snapd")) {
cmd |= GF_CLI_STATUS_SNAPD;
+ } else if (!strcmp(words[3], "bitd")) {
+ cmd |= GF_CLI_STATUS_BITD;
+ } else if (!strcmp(words[3], "scrub")) {
+ cmd |= GF_CLI_STATUS_SCRUB;
+ } else {
+ cmd = GF_CLI_STATUS_BRICK;
+ ret = dict_set_str(dict, "brick", (char *)words[3]);
+ }
+
} else {
- if (cmd == GF_CLI_STATUS_TASKS) {
- cli_err ("Tasks status not available for "
- "bricks");
- ret = -1;
- goto out;
- }
- cmd |= GF_CLI_STATUS_BRICK;
- ret = dict_set_str (dict, "brick", (char *)words[3]);
+ cmd |= GF_CLI_STATUS_VOL;
+ ret = 0;
}
- break;
+ }
- default:
- goto out;
- }
+ break;
- if (ret)
+ case 5:
+ if (!strcmp(words[2], "all")) {
+ cli_err("Cannot specify brick/nfs for \"all\"");
+ ret = -1;
goto out;
+ }
- ret = dict_set_int32 (dict, "cmd", cmd);
- if (ret)
+ 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 ||
+ cmd == GF_CLI_STATUS_TASKS) {
+ cli_err(
+ "Detail/FD/Tasks 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 || cmd == GF_CLI_STATUS_TASKS) {
+ cli_err(
+ "Detail/FD/Clients/Tasks status not "
+ "available for Self-heal Daemons");
+ ret = -1;
+ goto out;
+ }
+ cmd |= GF_CLI_STATUS_SHD;
+ } else if (!strcmp(words[3], "quotad")) {
+ if (cmd == GF_CLI_STATUS_FD || cmd == GF_CLI_STATUS_CLIENTS ||
+ cmd == GF_CLI_STATUS_DETAIL || cmd == GF_CLI_STATUS_INODE) {
+ cli_err(
+ "Detail/FD/Clients/Inode status not "
+ "available for Quota Daemon");
+ ret = -1;
+ goto out;
+ }
+ cmd |= GF_CLI_STATUS_QUOTAD;
+ } else if (!strcmp(words[3], "snapd")) {
+ if (cmd == GF_CLI_STATUS_FD || cmd == GF_CLI_STATUS_CLIENTS ||
+ cmd == GF_CLI_STATUS_DETAIL || cmd == GF_CLI_STATUS_INODE) {
+ cli_err(
+ "Detail/FD/Clients/Inode status not "
+ "available for snap daemon");
+ ret = -1;
+ goto out;
+ }
+ cmd |= GF_CLI_STATUS_SNAPD;
+ } else {
+ if (cmd == GF_CLI_STATUS_TASKS) {
+ cli_err(
+ "Tasks status not available for "
+ "bricks");
+ ret = -1;
+ goto out;
+ }
+ cmd |= GF_CLI_STATUS_BRICK;
+ ret = dict_set_str(dict, "brick", (char *)words[3]);
+ }
+ break;
- *options = dict;
+ default:
+ goto out;
+ }
+
+ if (ret)
+ goto out;
+
+ ret = dict_set_int32(dict, "cmd", cmd);
+ if (ret)
+ goto out;
- out:
- if (ret && dict)
- dict_destroy (dict);
+ *options = dict;
- return ret;
+out:
+ if (ret && dict)
+ dict_unref(dict);
+
+ return ret;
}
gf_boolean_t
-cli_cmd_validate_dumpoption (const char *arg, char **option)
+cli_cmd_validate_dumpoption(const char *arg, char **option)
{
- char *opwords[] = {"all", "nfs", "mem", "iobuf", "callpool", "priv",
- "fd", "inode", "history", "inodectx", "fdctx",
- "quotad", 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;
+ static char *opwords[] = {"all", "nfs", "mem", "iobuf", "callpool",
+ "priv", "fd", "inode", "history", "inodectx",
+ "fdctx", "quotad", 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)
+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);
+ int ret = 0;
+ int i = 0;
+ dict_t *dict = NULL;
+ int option_cnt = 0;
+ char *option = NULL;
+ char *option_str = NULL;
+ char *tmp_str = NULL;
+ char *tmp = NULL;
+ char *ip_addr = NULL;
+ char *pid = NULL;
+
+ if ((wordcount >= 5) && ((strcmp(words[3], "client")) == 0)) {
+ tmp = gf_strdup(words[4]);
+ if (!tmp) {
+ ret = -1;
+ goto out;
+ }
+ ip_addr = strtok(tmp, ":");
+ pid = strtok(NULL, ":");
+ if (valid_internet_address(ip_addr, _gf_true, _gf_false) && pid &&
+ gf_valid_pid(pid, strlen(pid))) {
+ ret = gf_asprintf(&option_str, "%s %s %s", words[3], ip_addr, pid);
+ if (ret < 0) {
+ goto out;
+ }
+ option_cnt = 3;
+ } else {
+ ret = -1;
+ goto out;
}
- if((strstr (option_str, "nfs")) && strstr (option_str, "quotad")) {
+ } else {
+ for (i = 3; i < wordcount; i++, option_cnt++) {
+ if (!cli_cmd_validate_dumpoption(words[i], &option)) {
ret = -1;
goto out;
+ }
+ tmp_str = option_str;
+ option_str = NULL;
+ ret = gf_asprintf(&option_str, "%s%s ", tmp_str ? tmp_str : "",
+ option);
+ GF_FREE(tmp_str);
+ if (ret < 0) {
+ goto out;
+ }
}
+ if (option_str && (strstr(option_str, "nfs")) &&
+ strstr(option_str, "quotad")) {
+ ret = -1;
+ goto out;
+ }
+ }
- dict = dict_new ();
- if (!dict)
- goto out;
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_dynstr (dict, "options", gf_strdup (option_str));
- if (ret)
- goto out;
+ /* dynamic string in dict is freed up when dict is freed up, and hence
+ if option_str is NULL pass in an duplicate empty string to the same */
+ ret = dict_set_dynstr(dict, "options",
+ (option_str ? option_str : gf_strdup("")));
+ if (ret)
+ goto out;
+ option_str = NULL;
- ret = dict_set_int32 (dict, "option_cnt", option_cnt);
- if (ret)
- goto out;
+ ret = dict_set_int32(dict, "option_cnt", option_cnt);
+ if (ret)
+ goto out;
- *options = dict;
+ *options = dict;
out:
- if (ret && dict)
- dict_destroy (dict);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR, "Error parsing dumpoptions");
- return ret;
+ GF_FREE(tmp);
+ GF_FREE(option_str);
+ if (ret && dict)
+ dict_unref(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)
+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;
+ 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;
+ 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)
+ 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)
+ 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;
-
- if (wordcount == 8) {
- free_ptr = gf_strdup (words[7]);
- ret = dict_set_dynstr (dict, "opts", free_ptr);
- if (ret)
- goto out;
- free_ptr = NULL;
+ free_ptr = NULL;
+ break;
}
+ }
+ if (i == 3)
+ goto out;
- ret = 0;
- *options = dict;
+ 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);
- }
+ if (ret) {
+ GF_FREE(free_ptr);
+ dict_unref(dict);
+ }
- return ret;
+ return ret;
}
static int
-extract_hostname_path_from_token (const char *tmp_words, char **hostname,
- char **path)
+extract_hostname_path_from_token(const char *tmp_words, char **hostname,
+ char **path)
{
- int ret = 0;
- char *delimiter = NULL;
- char *tmp_host = NULL;
- char *host_name = NULL;
- char *words = NULL;
-
- *hostname = NULL;
- *path = NULL;
-
- words = GF_CALLOC (1, strlen (tmp_words) + 1, gf_common_mt_char);
- if (!words){
- ret = -1;
- goto out;
- }
+ int ret = 0;
+ char *delimiter = NULL;
+ char *tmp_host = NULL;
+ char *host_name = NULL;
+ char *words = NULL;
+ int str_len = 0;
+ *hostname = NULL;
+ *path = NULL;
+
+ str_len = strlen(tmp_words) + 1;
+ words = GF_MALLOC(str_len, gf_common_mt_char);
+ if (!words) {
+ ret = -1;
+ goto out;
+ }
- strncpy (words, tmp_words, strlen (tmp_words) + 1);
+ snprintf(words, str_len, "%s", tmp_words);
- if (validate_brick_name (words)) {
- cli_err ("Wrong brick type: %s, use <HOSTNAME>:"
- "<export-dir-abs-path>", words);
- ret = -1;
- goto out;
+ if (validate_brick_name(words)) {
+ cli_err(
+ "Wrong brick type: %s, use <HOSTNAME>:"
+ "<export-dir-abs-path>",
+ words);
+ ret = -1;
+ goto out;
+ } else {
+ delimiter = strrchr(words, ':');
+ ret = gf_canonicalize_path(delimiter + 1);
+ if (ret) {
+ goto out;
} else {
- delimiter = strrchr (words, ':');
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret) {
- goto out;
- } else {
- *path = GF_CALLOC (1, strlen (delimiter+1) +1,
- gf_common_mt_char);
- if (!*path) {
- ret = -1;
- goto out;
-
- }
- strncpy (*path, delimiter +1,
- strlen(delimiter + 1) + 1);
- }
- }
-
- tmp_host = gf_strdup (words);
- 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 "
- "memory");
- goto out;
- }
- if (!(strcmp (host_name, "localhost") &&
- strcmp (host_name, "127.0.0.1") &&
- strncmp (host_name, "0.", 2))) {
- cli_err ("Please provide a valid hostname/ip other "
- "than localhost, 127.0.0.1 or loopback "
- "address (0.0.0.0 to 0.255.255.255).");
- ret = -1;
- goto out;
- }
- if (!valid_internet_address (host_name, _gf_false)) {
- cli_err ("internet address '%s' does not conform to "
- "standards", host_name);
+ str_len = strlen(delimiter + 1) + 1;
+ *path = GF_MALLOC(str_len, gf_common_mt_char);
+ if (!*path) {
ret = -1;
goto out;
+ }
+ snprintf(*path, str_len, "%s", delimiter + 1);
}
+ }
- *hostname = GF_CALLOC (1, strlen (host_name) + 1,
- gf_common_mt_char);
- if (!*hostname) {
- ret = -1;
- goto out;
- }
- strncpy (*hostname, host_name, strlen (host_name) + 1);
- ret = 0;
+ tmp_host = gf_strdup(words);
+ 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 "
+ "memory");
+ goto out;
+ }
+ if (!(strcmp(host_name, "localhost") && strcmp(host_name, "127.0.0.1") &&
+ strncmp(host_name, "0.", 2))) {
+ cli_err(
+ "Please provide a valid hostname/ip other "
+ "than localhost, 127.0.0.1 or loopback "
+ "address (0.0.0.0 to 0.255.255.255).");
+ ret = -1;
+ goto out;
+ }
+ if (!valid_internet_address(host_name, _gf_false, _gf_false)) {
+ cli_err(
+ "internet address '%s' does not conform to "
+ "standards",
+ host_name);
+ ret = -1;
+ goto out;
+ }
+
+ str_len = strlen(host_name) + 1;
+ *hostname = GF_MALLOC(str_len, gf_common_mt_char);
+ if (!*hostname) {
+ ret = -1;
+ goto out;
+ }
+ snprintf(*hostname, str_len, "%s", host_name);
+ ret = 0;
out:
- GF_FREE (words);
- GF_FREE (tmp_host);
- return ret;
+ GF_FREE(words);
+ GF_FREE(tmp_host);
+ return ret;
}
static int
-set_hostname_path_in_dict (const char *token, dict_t *dict, int heal_op)
+set_hostname_path_in_dict(const char *token, dict_t *dict, int heal_op)
{
- char *hostname = NULL;
- char *path = NULL;
- int ret = 0;
+ char *hostname = NULL;
+ char *path = NULL;
+ int ret = 0;
- ret = extract_hostname_path_from_token (token, &hostname, &path);
- if (ret)
- goto out;
+ ret = extract_hostname_path_from_token(token, &hostname, &path);
+ if (ret)
+ goto out;
- switch (heal_op) {
+ switch (heal_op) {
case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK:
- ret = dict_set_dynstr (dict, "heal-source-hostname",
- hostname);
- if (ret)
- goto out;
- ret = dict_set_dynstr (dict, "heal-source-brickpath",
- path);
- break;
+ ret = dict_set_dynstr(dict, "heal-source-hostname", hostname);
+ if (ret)
+ goto out;
+ hostname = NULL;
+ ret = dict_set_dynstr(dict, "heal-source-brickpath", path);
+ if (ret) {
+ goto out;
+ }
+ path = NULL;
+ break;
case GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA:
- ret = dict_set_dynstr (dict, "per-replica-cmd-hostname",
- hostname);
- if (ret)
- goto out;
- ret = dict_set_dynstr (dict, "per-replica-cmd-path",
- path);
- break;
+ ret = dict_set_dynstr(dict, "per-replica-cmd-hostname", hostname);
+ if (ret)
+ goto out;
+ hostname = NULL;
+ ret = dict_set_dynstr(dict, "per-replica-cmd-path", path);
+ if (ret) {
+ goto out;
+ }
+ path = NULL;
+ break;
default:
- ret = -1;
- break;
- }
+ ret = -1;
+ break;
+ }
out:
- return ret;
+ GF_FREE(hostname);
+ GF_FREE(path);
+ return ret;
}
static int
-heal_command_type_get (const char *command)
+heal_command_type_get(const char *command)
{
- int i = 0;
- /* subcommands are set as NULL */
- char *heal_cmds[GF_SHD_OP_HEAL_DISABLE + 1] = {
- [GF_SHD_OP_INVALID] = NULL,
- [GF_SHD_OP_HEAL_INDEX] = NULL,
- [GF_SHD_OP_HEAL_FULL] = "full",
- [GF_SHD_OP_INDEX_SUMMARY] = "info",
- [GF_SHD_OP_HEALED_FILES] = NULL,
- [GF_SHD_OP_HEAL_FAILED_FILES] = NULL,
- [GF_SHD_OP_SPLIT_BRAIN_FILES] = NULL,
- [GF_SHD_OP_STATISTICS] = "statistics",
- [GF_SHD_OP_STATISTICS_HEAL_COUNT] = NULL,
- [GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA] = NULL,
- [GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE] = NULL,
- [GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK] = NULL,
- [GF_SHD_OP_HEAL_ENABLE] = "enable",
- [GF_SHD_OP_HEAL_DISABLE] = "disable",
- };
-
- for (i = 0; i <= GF_SHD_OP_HEAL_DISABLE; i++) {
- if (heal_cmds[i] && (strcmp (heal_cmds[i], command) == 0))
- return i;
- }
-
- return GF_SHD_OP_INVALID;
+ int i = 0;
+ /* subcommands are set as NULL */
+ char *heal_cmds[GF_SHD_OP_HEAL_DISABLE + 1] = {
+ [GF_SHD_OP_INVALID] = NULL,
+ [GF_SHD_OP_HEAL_INDEX] = NULL,
+ [GF_SHD_OP_HEAL_FULL] = "full",
+ [GF_SHD_OP_INDEX_SUMMARY] = "info",
+ [GF_SHD_OP_SPLIT_BRAIN_FILES] = NULL,
+ [GF_SHD_OP_STATISTICS] = "statistics",
+ [GF_SHD_OP_STATISTICS_HEAL_COUNT] = NULL,
+ [GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA] = NULL,
+ [GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE] = NULL,
+ [GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK] = NULL,
+ [GF_SHD_OP_HEAL_ENABLE] = "enable",
+ [GF_SHD_OP_HEAL_DISABLE] = "disable",
+ };
+
+ for (i = 0; i <= GF_SHD_OP_HEAL_DISABLE; i++) {
+ if (heal_cmds[i] && (strcmp(heal_cmds[i], command) == 0))
+ return i;
+ }
+
+ return GF_SHD_OP_INVALID;
}
int
-cli_cmd_volume_heal_options_parse (const char **words, int wordcount,
- dict_t **options)
+cli_cmd_volume_heal_options_parse(const char **words, int wordcount,
+ dict_t **options)
{
- int ret = 0;
- dict_t *dict = NULL;
- char *hostname = NULL;
- char *path = NULL;
- gf_xl_afr_op_t op = GF_SHD_OP_INVALID;
-
- dict = dict_new ();
- if (!dict)
- goto out;
+ int ret = 0;
+ dict_t *dict = NULL;
+ gf_xl_afr_op_t op = GF_SHD_OP_INVALID;
- ret = dict_set_str (dict, "volname", (char *) words[2]);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to set volname");
- goto out;
- }
+ dict = dict_new();
+ if (!dict) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Failed to create the dict");
+ ret = -1;
+ goto out;
+ }
- if (wordcount == 3) {
- ret = dict_set_int32 (dict, "heal-op", GF_SHD_OP_HEAL_INDEX);
- goto done;
+ 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_SHD_OP_HEAL_INDEX);
+ goto done;
+ }
+
+ if (wordcount == 4) {
+ op = heal_command_type_get(words[3]);
+ if (op == GF_SHD_OP_INVALID) {
+ ret = -1;
+ goto out;
}
- if (wordcount == 4) {
- op = heal_command_type_get (words[3]);
- if (op == GF_SHD_OP_INVALID) {
- ret = -1;
- goto out;
- }
+ ret = dict_set_int32(dict, "heal-op", op);
+ goto done;
+ }
+
+ if (wordcount == 5) {
+ if (strcmp(words[3], "info") && strcmp(words[3], "statistics") &&
+ strcmp(words[3], "granular-entry-heal")) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_int32 (dict, "heal-op", op);
+ if (!strcmp(words[3], "info")) {
+ if (!strcmp(words[4], "split-brain")) {
+ ret = dict_set_int32(dict, "heal-op",
+ GF_SHD_OP_SPLIT_BRAIN_FILES);
+ goto done;
+ }
+ if (!strcmp(words[4], "summary")) {
+ ret = dict_set_int32(dict, "heal-op", GF_SHD_OP_HEAL_SUMMARY);
goto done;
+ }
}
- if (wordcount == 5) {
- if (strcmp (words[3], "info") &&
- strcmp (words[3], "statistics")) {
- ret = -1;
- goto out;
- }
+ if (!strcmp(words[3], "statistics")) {
+ if (!strcmp(words[4], "heal-count")) {
+ ret = dict_set_int32(dict, "heal-op",
+ GF_SHD_OP_STATISTICS_HEAL_COUNT);
+ goto done;
+ }
+ }
- if (!strcmp (words[3], "info")) {
- if (!strcmp (words[4], "healed")) {
- ret = dict_set_int32 (dict, "heal-op",
- GF_SHD_OP_HEALED_FILES);
- goto done;
- }
- if (!strcmp (words[4], "heal-failed")) {
- ret = dict_set_int32 (dict, "heal-op",
- GF_SHD_OP_HEAL_FAILED_FILES);
- goto done;
- }
- if (!strcmp (words[4], "split-brain")) {
- ret = dict_set_int32 (dict, "heal-op",
- GF_SHD_OP_SPLIT_BRAIN_FILES);
- goto done;
- }
- }
+ if (!strcmp(words[3], "granular-entry-heal")) {
+ if (!strcmp(words[4], "enable")) {
+ ret = dict_set_int32(dict, "heal-op",
+ GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE);
+ goto done;
+ } else if (!strcmp(words[4], "disable")) {
+ ret = dict_set_int32(dict, "heal-op",
+ GF_SHD_OP_GRANULAR_ENTRY_HEAL_DISABLE);
+ goto done;
+ }
+ }
- if (!strcmp (words[3], "statistics")) {
- if (!strcmp (words[4], "heal-count")) {
- ret = dict_set_int32 (dict, "heal-op",
- GF_SHD_OP_STATISTICS_HEAL_COUNT);
- goto done;
- }
- }
- ret = -1;
+ ret = -1;
+ goto out;
+ }
+ if (wordcount == 6) {
+ if (strcmp(words[3], "split-brain")) {
+ ret = -1;
+ goto out;
+ }
+ if (!strcmp(words[4], "bigger-file")) {
+ ret = dict_set_int32(dict, "heal-op",
+ GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE);
+ if (ret)
goto out;
+ ret = dict_set_str(dict, "file", (char *)words[5]);
+ if (ret)
+ goto out;
+ goto done;
}
- if (wordcount == 6) {
- if (strcmp (words[3], "split-brain")) {
- ret = -1;
- goto out;
- }
- if (!strcmp (words[4], "bigger-file")) {
- ret = dict_set_int32 (dict, "heal-op",
- GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE);
- if (ret)
- goto out;
- ret = dict_set_str (dict, "file", (char *)words[5]);
- if (ret)
- goto out;
- goto done;
- }
- if (!strcmp (words[4], "source-brick")) {
- ret = dict_set_int32 (dict, "heal-op",
- GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
- if (ret)
- goto out;
- ret = set_hostname_path_in_dict (words[5], dict,
- GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
- if (ret)
- goto out;
- goto done;
- }
- ret = -1;
+ if (!strcmp(words[4], "latest-mtime")) {
+ ret = dict_set_int32(dict, "heal-op",
+ GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME);
+ if (ret)
+ goto out;
+ ret = dict_set_str(dict, "file", (char *)words[5]);
+ if (ret)
goto out;
+ goto done;
}
- if (wordcount == 7) {
- if (!strcmp (words[3], "statistics")
- && !strcmp (words[4], "heal-count")
- && !strcmp (words[5], "replica")) {
-
- ret = dict_set_int32 (dict, "heal-op",
- GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA);
- if (ret)
- goto out;
- ret = set_hostname_path_in_dict (words[6], dict,
- GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA);
- if (ret)
- goto out;
- goto done;
-
- }
- if (!strcmp (words[3], "split-brain") &&
- !strcmp (words[4], "source-brick")) {
- ret = dict_set_int32 (dict, "heal-op",
- GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
- ret = set_hostname_path_in_dict (words[5], dict,
- GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
- if (ret)
- goto out;
- ret = dict_set_str (dict, "file",
- (char *) words[6]);
- if (ret)
- goto out;
- goto done;
- }
+ if (!strcmp(words[4], "source-brick")) {
+ ret = dict_set_int32(dict, "heal-op",
+ GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
+ if (ret)
+ goto out;
+ ret = set_hostname_path_in_dict(words[5], dict,
+ GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
+ if (ret)
+ goto out;
+ goto done;
}
ret = -1;
goto out;
+ }
+ if (wordcount == 7) {
+ if (!strcmp(words[3], "statistics") &&
+ !strcmp(words[4], "heal-count") && !strcmp(words[5], "replica")) {
+ ret = dict_set_int32(dict, "heal-op",
+ GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA);
+ if (ret)
+ goto out;
+ ret = set_hostname_path_in_dict(
+ words[6], dict, GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA);
+ if (ret)
+ goto out;
+ goto done;
+ }
+ if (!strcmp(words[3], "split-brain") &&
+ !strcmp(words[4], "source-brick")) {
+ ret = dict_set_int32(dict, "heal-op",
+ GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
+ ret = set_hostname_path_in_dict(words[5], dict,
+ GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
+ if (ret)
+ goto out;
+ ret = dict_set_str(dict, "file", (char *)words[6]);
+ if (ret)
+ goto out;
+ goto done;
+ }
+ }
+ ret = -1;
+ goto out;
done:
- *options = dict;
+ *options = dict;
out:
- if (ret && dict) {
- dict_unref (dict);
- *options = NULL;
- }
+ if (ret && dict) {
+ dict_unref(dict);
+ *options = NULL;
+ }
- return ret;
+ return ret;
}
int
-cli_cmd_volume_defrag_parse (const char **words, int wordcount,
- dict_t **options)
+cli_cmd_volume_defrag_parse(const char **words, int wordcount, dict_t **options)
{
- dict_t *dict = NULL;
- int ret = -1;
- char *option = NULL;
- char *volname = NULL;
- char *command = NULL;
- gf_cli_defrag_type cmd = 0;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- if (!((wordcount == 4) || (wordcount == 5)))
- goto out;
-
- if (wordcount == 4) {
- if (strcmp (words[3], "start") && strcmp (words[3], "stop") &&
- strcmp (words[3], "status"))
- goto out;
- } else if ((strcmp (words[3], "tier") == 0) &&
- (strcmp (words[4], "start") == 0)) {
- volname = (char *) words[2];
- cmd = GF_DEFRAG_CMD_START_TIER;
- goto done;
- } else if ((strcmp (words[3], "tier") == 0) &&
- (strcmp (words[4], "status") == 0)) {
- volname = (char *) words[2];
- cmd = GF_DEFRAG_CMD_STATUS_TIER;
- goto done;
- } else {
- if (strcmp (words[3], "fix-layout") &&
- strcmp (words[3], "start"))
- goto out;
- }
-
- volname = (char *) words[2];
+ dict_t *dict = NULL;
+ int ret = -1;
+ char *option = NULL;
+ char *volname = NULL;
+ char *command = NULL;
+ gf_cli_defrag_type cmd = 0;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
- if (wordcount == 4) {
- command = (char *) words[3];
- }
- if (wordcount == 5) {
- if ((strcmp (words[3], "fix-layout") ||
- strcmp (words[4], "start")) &&
- (strcmp (words[3], "start") ||
- strcmp (words[4], "force"))) {
- ret = -1;
- goto out;
- }
- command = (char *) words[3];
- option = (char *) words[4];
- }
+ if (!((wordcount == 4) || (wordcount == 5)))
+ goto out;
- if (strcmp (command, "start") == 0) {
- cmd = GF_DEFRAG_CMD_START;
- if (option && strcmp (option, "force") == 0) {
- cmd = GF_DEFRAG_CMD_START_FORCE;
- }
- goto done;
- }
-
- if (strcmp (command, "fix-layout") == 0) {
- cmd = GF_DEFRAG_CMD_START_LAYOUT_FIX;
- goto done;
- }
- if (strcmp (command, "stop") == 0) {
- cmd = GF_DEFRAG_CMD_STOP;
- goto done;
- }
- if (strcmp (command, "status") == 0) {
- cmd = GF_DEFRAG_CMD_STATUS;
- }
+ if (wordcount == 4) {
+ if (strcmp(words[3], "start") && strcmp(words[3], "stop") &&
+ strcmp(words[3], "status"))
+ goto out;
+ } else {
+ if (strcmp(words[3], "fix-layout") && strcmp(words[3], "start"))
+ goto out;
+ }
+
+ volname = (char *)words[2];
+
+ if (wordcount == 4) {
+ command = (char *)words[3];
+ }
+ if (wordcount == 5) {
+ if ((strcmp(words[3], "fix-layout") || strcmp(words[4], "start")) &&
+ (strcmp(words[3], "start") || strcmp(words[4], "force"))) {
+ ret = -1;
+ goto out;
+ }
+ command = (char *)words[3];
+ option = (char *)words[4];
+ }
+
+ if (strcmp(command, "start") == 0) {
+ cmd = GF_DEFRAG_CMD_START;
+ if (option && strcmp(option, "force") == 0) {
+ cmd = GF_DEFRAG_CMD_START_FORCE;
+ }
+ goto done;
+ }
+
+ if (strcmp(command, "fix-layout") == 0) {
+ cmd = GF_DEFRAG_CMD_START_LAYOUT_FIX;
+ goto done;
+ }
+ if (strcmp(command, "stop") == 0) {
+ cmd = GF_DEFRAG_CMD_STOP;
+ goto done;
+ }
+ if (strcmp(command, "status") == 0) {
+ cmd = GF_DEFRAG_CMD_STATUS;
+ }
done:
- ret = dict_set_str (dict, "volname", volname);
+ ret = dict_set_str(dict, "volname", volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to set dict");
- goto out;
- }
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to set dict");
+ goto out;
+ }
- ret = dict_set_int32 (dict, "rebalance-command", (int32_t) cmd);
+ ret = dict_set_int32(dict, "rebalance-command", (int32_t)cmd);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to set dict");
- goto out;
- }
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to set dict");
+ goto out;
+ }
- *options = dict;
+ *options = dict;
out:
- if (ret && dict)
- dict_destroy (dict);
+ if (ret && dict)
+ dict_unref(dict);
- return ret;
+ return ret;
}
int32_t
-cli_snap_create_desc_parse (dict_t *dict, const char **words,
- size_t wordcount, int32_t desc_opt_loc)
+cli_snap_create_desc_parse(dict_t *dict, const char **words, size_t wordcount,
+ int32_t desc_opt_loc)
{
- int32_t ret = -1;
- char *desc = NULL;
- int32_t desc_len = 0;
+ int32_t ret = -1;
+ char *desc = NULL;
+ int32_t desc_len = 0;
+ int len;
- desc = GF_CALLOC (MAX_SNAP_DESCRIPTION_LEN + 1, sizeof(char),
- gf_common_mt_char);
- if (!desc) {
- ret = -1;
- goto out;
- }
-
-
- if (strlen (words[desc_opt_loc]) >= MAX_SNAP_DESCRIPTION_LEN) {
- cli_out ("snapshot create: description truncated: "
- "Description provided is longer than 1024 characters");
- desc_len = MAX_SNAP_DESCRIPTION_LEN;
- } else {
- desc_len = strlen (words[desc_opt_loc]);
- }
-
- strncpy (desc, words[desc_opt_loc], desc_len);
- desc[desc_len] = '\0';
- /* Calculating the size of the description as given by the user */
-
- ret = dict_set_dynstr (dict, "description", desc);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to save snap "
- "description");
- goto out;
- }
+ desc = GF_MALLOC(MAX_SNAP_DESCRIPTION_LEN + 1, gf_common_mt_char);
+ if (!desc) {
+ ret = -1;
+ goto out;
+ }
+
+ len = strlen(words[desc_opt_loc]);
+ if (len >= MAX_SNAP_DESCRIPTION_LEN) {
+ cli_out(
+ "snapshot create: description truncated: "
+ "Description provided is longer than 1024 characters");
+ desc_len = MAX_SNAP_DESCRIPTION_LEN;
+ } else {
+ desc_len = len;
+ }
+
+ snprintf(desc, desc_len + 1, "%s", words[desc_opt_loc]);
+ /* Calculating the size of the description as given by the user */
+
+ ret = dict_set_dynstr(dict, "description", desc);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Unable to save snap "
+ "description");
+ goto out;
+ }
- ret = 0;
+ ret = 0;
out:
- if (ret && desc)
- GF_FREE (desc);
+ if (ret && desc)
+ GF_FREE(desc);
- return ret;
+ return ret;
}
/* Function to check whether the Volume name is repeated */
int
-cli_check_if_volname_repeated (const char **words, unsigned int start_index,
- uint64_t cur_index) {
- uint64_t i = -1;
- int ret = 0;
+cli_check_if_volname_repeated(const char **words, unsigned int start_index,
+ uint64_t cur_index)
+{
+ uint64_t i = -1;
+ int ret = 0;
- GF_ASSERT (words);
+ GF_ASSERT(words);
- for (i = start_index ; i < cur_index ; i++) {
- if (strcmp (words[i], words[cur_index]) == 0) {
- ret = -1;
- goto out;
- }
+ for (i = start_index; i < cur_index; i++) {
+ if (strcmp(words[i], words[cur_index]) == 0) {
+ ret = -1;
+ goto out;
}
+ }
out:
- return ret;
+ return ret;
}
/* snapshot clone <clonename> <snapname>
@@ -3785,74 +4243,77 @@ out:
* 0 on success
*/
int
-cli_snap_clone_parse (dict_t *dict, const char **words, int wordcount) {
- uint64_t i = 0;
- int ret = -1;
- char key[PATH_MAX] = "";
- char *clonename = NULL;
- unsigned int cmdi = 2;
- int flags = 0;
- /* cmdi is command index, here cmdi is "2" (gluster snapshot clone)*/
-
- GF_ASSERT (words);
- GF_ASSERT (dict);
-
- if (wordcount == cmdi + 1) {
- cli_err ("Invalid Syntax.");
- gf_log ("cli", GF_LOG_ERROR,
- "Invalid number of words for snap clone command");
- goto out;
- }
-
- if (strlen(words[cmdi]) >= GLUSTERD_MAX_SNAP_NAME) {
- cli_err ("snapshot clone: failed: clonename cannot exceed "
- "255 characters.");
- gf_log ("cli", GF_LOG_ERROR, "Clone name too long");
-
- goto out;
- }
-
- clonename = (char *) words[cmdi];
- for (i = 0 ; i < strlen (clonename); i++) {
- /* Following volume name convention */
- if (!isalnum (clonename[i]) && (clonename[i] != '_'
- && (clonename[i] != '-'))) {
- /* TODO : Is this message enough?? */
- cli_err ("Clonename can contain only alphanumeric, "
- "\"-\" and \"_\" characters");
- goto out;
- }
- }
-
- ret = dict_set_int32 (dict, "volcount", 1);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save volcount");
- goto out;
- }
+cli_snap_clone_parse(dict_t *dict, const char **words, int wordcount)
+{
+ uint64_t i = 0;
+ int ret = -1;
+ char *clonename = NULL;
+ unsigned int cmdi = 2;
+ /* cmdi is command index, here cmdi is "2" (gluster snapshot clone)*/
+
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
+
+ if (wordcount == cmdi + 1) {
+ cli_err("Invalid Syntax.");
+ gf_log("cli", GF_LOG_ERROR,
+ "Invalid number of words for snap clone command");
+ goto out;
+ }
- ret = dict_set_str (dict, "clonename", (char *)words[cmdi]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save clone "
- "name(%s)", (char *)words[cmdi]);
- goto out;
- }
+ if (strlen(words[cmdi]) >= GLUSTERD_MAX_SNAP_NAME) {
+ cli_err(
+ "snapshot clone: failed: clonename cannot exceed "
+ "255 characters.");
+ gf_log("cli", GF_LOG_ERROR, "Clone name too long");
- /* Filling snap name in the dictionary */
- ret = dict_set_str (dict, "snapname", (char *)words[cmdi+1]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not "
- "save snap name(%s)", (char *)words[cmdi+1]);
- goto out;
- }
+ goto out;
+ }
+
+ clonename = (char *)words[cmdi];
+ for (i = 0; i < strlen(clonename); i++) {
+ /* Following volume name convention */
+ if (!isalnum(clonename[i]) &&
+ (clonename[i] != '_' && (clonename[i] != '-'))) {
+ /* TODO : Is this message enough?? */
+ cli_err(
+ "Clonename can contain only alphanumeric, "
+ "\"-\" and \"_\" characters");
+ goto out;
+ }
+ }
+
+ ret = dict_set_int32(dict, "volcount", 1);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not save volcount");
+ goto out;
+ }
+
+ ret = dict_set_str(dict, "clonename", (char *)words[cmdi]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save clone "
+ "name(%s)",
+ (char *)words[cmdi]);
+ goto out;
+ }
+
+ /* Filling snap name in the dictionary */
+ ret = dict_set_str(dict, "snapname", (char *)words[cmdi + 1]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not "
+ "save snap name(%s)",
+ (char *)words[cmdi + 1]);
+ goto out;
+ }
-
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
/* snapshot create <snapname> <vol-name(s)> [description <description>]
* [force]
* @arg-0, dict : Request Dictionary to be sent to server side.
@@ -3863,172 +4324,181 @@ out:
* 0 on success
*/
int
-cli_snap_create_parse (dict_t *dict, const char **words, int wordcount) {
- uint64_t i = 0;
- int ret = -1;
- uint64_t volcount = 0;
- char key[PATH_MAX] = "";
- char *snapname = NULL;
- unsigned int cmdi = 2;
- int flags = 0;
- /* cmdi is command index, here cmdi is "2" (gluster snapshot create)*/
-
- GF_ASSERT (words);
- GF_ASSERT (dict);
-
- if (wordcount <= cmdi + 1) {
- cli_err ("Invalid Syntax.");
- gf_log ("cli", GF_LOG_ERROR,
- "Too less words for snap create command");
- goto out;
- }
+cli_snap_create_parse(dict_t *dict, const char **words, int wordcount)
+{
+ uint64_t i = 0;
+ int ret = -1;
+ uint64_t volcount = 0;
+ char key[PATH_MAX] = "";
+ char *snapname = NULL;
+ unsigned int cmdi = 2;
+ int flags = 0;
+ /* cmdi is command index, here cmdi is "2" (gluster snapshot create)*/
+
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
+
+ if (wordcount <= cmdi + 1) {
+ cli_err("Invalid Syntax.");
+ gf_log("cli", GF_LOG_ERROR, "Too less words for snap create command");
+ goto out;
+ }
- if (strlen(words[cmdi]) >= GLUSTERD_MAX_SNAP_NAME) {
- cli_err ("snapshot create: failed: snapname cannot exceed "
- "255 characters.");
- gf_log ("cli", GF_LOG_ERROR, "Snapname too long");
+ if (strlen(words[cmdi]) >= GLUSTERD_MAX_SNAP_NAME) {
+ cli_err(
+ "snapshot create: failed: snapname cannot exceed "
+ "255 characters.");
+ gf_log("cli", GF_LOG_ERROR, "Snapname too long");
- goto out;
+ goto out;
+ }
+
+ snapname = (char *)words[cmdi];
+ for (i = 0; i < strlen(snapname); i++) {
+ /* Following volume name convention */
+ if (!isalnum(snapname[i]) &&
+ (snapname[i] != '_' && (snapname[i] != '-'))) {
+ /* TODO : Is this message enough?? */
+ cli_err(
+ "Snapname can contain only alphanumeric, "
+ "\"-\" and \"_\" characters");
+ goto out;
+ }
+ }
+
+ ret = dict_set_str(dict, "snapname", (char *)words[cmdi]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save snap "
+ "name(%s)",
+ (char *)words[cmdi]);
+ goto out;
+ }
+
+ /* Filling volume name in the dictionary */
+ for (i = cmdi + 1;
+ i < wordcount && (strcmp(words[i], "description")) != 0 &&
+ (strcmp(words[i], "force") != 0) &&
+ (strcmp(words[i], "no-timestamp") != 0);
+ i++) {
+ volcount++;
+ /* volume index starts from 1 */
+ ret = snprintf(key, sizeof(key), "volname%" PRIu64, volcount);
+ if (ret < 0) {
+ goto out;
}
- snapname = (char *) words[cmdi];
- for (i = 0 ; i < strlen (snapname); i++) {
- /* Following volume name convention */
- if (!isalnum (snapname[i]) && (snapname[i] != '_'
- && (snapname[i] != '-'))) {
- /* TODO : Is this message enough?? */
- cli_err ("Snapname can contain only alphanumeric, "
- "\"-\" and \"_\" characters");
- goto out;
- }
+ ret = dict_set_str(dict, key, (char *)words[i]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not "
+ "save volume name(%s)",
+ (char *)words[i]);
+ goto out;
}
- ret = dict_set_str (dict, "snapname", (char *)words[cmdi]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save snap "
- "name(%s)", (char *)words[cmdi]);
- goto out;
+ if (i >= cmdi + 2) {
+ ret = -1;
+ cli_err(
+ "Creating multiple volume snapshot is not "
+ "supported as of now");
+ goto out;
}
+ /* TODO : remove this above condition check once
+ * multiple volume snapshot is supported */
+ }
- /* Filling volume name in the dictionary */
- for (i = cmdi + 1 ; i < wordcount
- && (strcmp (words[i], "description")) != 0
- && (strcmp (words[i], "force") != 0)
- && (strcmp (words[i], "no-timestamp") != 0);
- i++) {
- volcount++;
- /* volume index starts from 1 */
- ret = snprintf (key, sizeof (key), "volname%"PRIu64, volcount);
- if (ret < 0) {
- goto out;
- }
+ if (volcount == 0) {
+ ret = -1;
+ cli_err("Please provide the volume name");
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- ret = dict_set_str (dict, key, (char *)words[i]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not "
- "save volume name(%s)", (char *)words[i]);
- goto out;
- }
+ ret = dict_set_int32(dict, "volcount", volcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not save volcount");
+ goto out;
+ }
+
+ /* Verify how we got out of "for" loop,
+ * if it is by reaching wordcount limit then goto "out",
+ * because we need not parse for "description","force" and
+ * "no-timestamp" after this.
+ */
+ if (i == wordcount) {
+ goto out;
+ }
- if (i >= cmdi + 2) {
- ret = -1;
- cli_err("Creating multiple volume snapshot is not "
- "supported as of now");
- goto out;
- }
- /* TODO : remove this above condition check once
- * multiple volume snapshot is supported */
+ if (strcmp(words[i], "no-timestamp") == 0) {
+ ret = dict_set_int32n(dict, "no-timestamp", SLEN("no-timestamp"), 1);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save "
+ "time-stamp option");
}
+ if (i == (wordcount - 1))
+ goto out;
+ i++;
+ }
- if (volcount == 0) {
- ret = -1;
- cli_err ("Please provide the volume name");
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
+ if ((strcmp(words[i], "description")) == 0) {
+ ++i;
+ if (i > (wordcount - 1)) {
+ ret = -1;
+ cli_err("Please provide a description");
+ gf_log("cli", GF_LOG_ERROR, "Description not provided");
+ goto out;
}
- ret = dict_set_int32 (dict, "volcount", volcount);
+ ret = cli_snap_create_desc_parse(dict, words, wordcount, i);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save volcount");
- goto out;
- }
-
- /* Verify how we got out of "for" loop,
- * if it is by reaching wordcount limit then goto "out",
- * because we need not parse for "description","force" and
- * "no-timestamp" after this.
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save snap "
+ "description");
+ goto out;
+ }
+
+ if (i == (wordcount - 1))
+ goto out;
+ i++;
+ /* point the index to next word.
+ * As description might be follwed by force option.
+ * Before that, check if wordcount limit is reached
*/
- if (i == wordcount) {
- goto out;
- }
-
- if (strcmp (words[i], "no-timestamp") == 0) {
- ret = dict_set_str (dict, "no-timestamp", "true");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save "
- "time-stamp option");
- }
- if (i == (wordcount-1))
- goto out;
- i++;
- }
+ }
- if ((strcmp (words[i], "description")) == 0) {
- ++i;
- if (i > (wordcount - 1)) {
- ret = -1;
- cli_err ("Please provide a description");
- gf_log ("cli", GF_LOG_ERROR,
- "Description not provided");
- goto out;
- }
+ if (strcmp(words[i], "force") == 0) {
+ flags = GF_CLI_FLAG_OP_FORCE;
- ret = cli_snap_create_desc_parse(dict, words, wordcount, i);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save snap "
- "description");
- goto out;
- }
-
- if (i == (wordcount - 1))
- goto out;
- i++;
- /* point the index to next word.
- * As description might be follwed by force option.
- * Before that, check if wordcount limit is reached
- */
- }
-
- if (strcmp (words[i], "force") == 0) {
- flags = GF_CLI_FLAG_OP_FORCE;
-
- } else {
- ret = -1;
- cli_err ("Invalid Syntax.");
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ } else {
+ ret = -1;
+ cli_err("Invalid Syntax.");
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- /* Check if the command has anything after "force" keyword */
- if (++i < wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ /* Check if the command has anything after "force" keyword */
+ if (++i < wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- ret = 0;
+ ret = 0;
out:
- if(ret == 0) {
- /*Adding force flag in either of the case i.e force set
- * or unset*/
- ret = dict_set_int32 (dict, "flags", flags);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save "
- "snap force option");
- }
+ if (ret == 0) {
+ /*Adding force flag in either of the case i.e force set
+ * or unset*/
+ ret = dict_set_int32(dict, "flags", flags);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save "
+ "snap force option");
}
- return ret;
+ }
+ return ret;
}
/* snapshot list [volname]
@@ -4040,30 +4510,30 @@ out:
* 0 on success
*/
int
-cli_snap_list_parse (dict_t *dict, const char **words, int wordcount) {
- int ret = -1;
+cli_snap_list_parse(dict_t *dict, const char **words, int wordcount)
+{
+ int ret = -1;
- GF_ASSERT (words);
- GF_ASSERT (dict);
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
- if (wordcount < 2 || wordcount > 3) {
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ if (wordcount < 2 || wordcount > 3) {
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- if (wordcount == 2) {
- ret = 0;
- goto out;
- }
+ if (wordcount == 2) {
+ ret = 0;
+ goto out;
+ }
- ret = dict_set_str (dict, "volname", (char *)words[2]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to save volname in dictionary");
- goto out;
- }
+ ret = dict_set_str(dict, "volname", (char *)words[2]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to save volname in dictionary");
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
/* snapshot info [(snapname | volume <volname>)]
@@ -4075,87 +4545,88 @@ out:
* 0 on success
*/
int
-cli_snap_info_parse (dict_t *dict, const char **words, int wordcount)
+cli_snap_info_parse(dict_t *dict, const char **words, int wordcount)
{
+ int ret = -1;
+ int32_t cmd = GF_SNAP_INFO_TYPE_ALL;
+ unsigned int cmdi = 2;
+ /* cmdi is command index, here cmdi is "2" (gluster snapshot info)*/
- int ret = -1;
- int32_t cmd = GF_SNAP_INFO_TYPE_ALL;
- unsigned int cmdi = 2;
- /* cmdi is command index, here cmdi is "2" (gluster snapshot info)*/
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
- GF_ASSERT (words);
- GF_ASSERT (dict);
+ if (wordcount > 4 || wordcount < cmdi) {
+ gf_log("cli", GF_LOG_ERROR, "Invalid syntax");
+ goto out;
+ }
- if (wordcount > 4 || wordcount < cmdi) {
- gf_log ("cli", GF_LOG_ERROR, "Invalid syntax");
- goto out;
- }
+ if (wordcount == cmdi) {
+ ret = 0;
+ goto out;
+ }
- if (wordcount == cmdi) {
- ret = 0;
- goto out;
+ /* If 3rd word is not "volume", then it must
+ * be snapname.
+ */
+ if (strcmp(words[cmdi], "volume") != 0) {
+ ret = dict_set_str(dict, "snapname", (char *)words[cmdi]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Unable to save "
+ "snapname %s",
+ words[cmdi]);
+ goto out;
}
- /* If 3rd word is not "volume", then it must
- * be snapname.
+ /* Once snap name is parsed, if we encounter any other
+ * word then fail it. Invalid Syntax.
+ * example : snapshot info <snapname> word
*/
- if (strcmp (words[cmdi], "volume") != 0) {
- ret = dict_set_str (dict, "snapname",
- (char *)words[cmdi]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to save "
- "snapname %s", words[cmdi]);
- goto out;
- }
-
- /* Once snap name is parsed, if we encounter any other
- * word then fail it. Invalid Syntax.
- * example : snapshot info <snapname> word
- */
- if ((cmdi + 1) != wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
-
- cmd = GF_SNAP_INFO_TYPE_SNAP;
- ret = 0;
- goto out;
- /* No need to continue the parsing once we
- * get the snapname
- */
+ if ((cmdi + 1) != wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
}
- /* If 3rd word is "volume", then check if next word
- * is present. As, "snapshot info volume" is an
- * invalid command.
+ cmd = GF_SNAP_INFO_TYPE_SNAP;
+ ret = 0;
+ goto out;
+ /* No need to continue the parsing once we
+ * get the snapname
*/
- if ((cmdi + 1) == wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ }
- ret = dict_set_str (dict, "volname", (char *)words[wordcount - 1]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save "
- "volume name %s", words[wordcount - 1]);
- goto out;
- }
- cmd = GF_SNAP_INFO_TYPE_VOL;
+ /* If 3rd word is "volume", then check if next word
+ * is present. As, "snapshot info volume" is an
+ * invalid command.
+ */
+ if ((cmdi + 1) == wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+
+ ret = dict_set_str(dict, "volname", (char *)words[wordcount - 1]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save "
+ "volume name %s",
+ words[wordcount - 1]);
+ goto out;
+ }
+ cmd = GF_SNAP_INFO_TYPE_VOL;
out:
- if (ret == 0) {
- ret = dict_set_int32 (dict, "cmd", cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save "
- "type of snapshot info");
- }
+ if (ret == 0) {
+ ret = dict_set_int32(dict, "sub-cmd", cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save "
+ "type of snapshot info");
}
- return ret;
+ }
+ return ret;
}
-
-
/* snapshot restore <snapname>
* @arg-0, dict : Request Dictionary to be sent to server side.
* @arg-1, words : Contains individual words of CLI command.
@@ -4165,42 +4636,43 @@ out:
* 0 on success
*/
int
-cli_snap_restore_parse (dict_t *dict, const char **words, int wordcount,
- struct cli_state *state)
+cli_snap_restore_parse(dict_t *dict, const char **words, int wordcount,
+ struct cli_state *state)
{
+ int ret = -1;
+ const char *question = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
- int ret = -1;
- const char *question = NULL;
- gf_answer_t answer = GF_ANSWER_NO;
-
- GF_ASSERT (words);
- GF_ASSERT (dict);
-
- if (wordcount != 3) {
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
-
- ret = dict_set_str (dict, "snapname", (char *)words[2]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to save snap-name %s",
- words[2]);
- goto out;
- }
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
- question = "Restore operation will replace the "
- "original volume with the snapshotted volume. "
- "Do you still want to continue?";
+ if (wordcount != 3) {
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- answer = cli_cmd_get_confirmation (state, question);
- if (GF_ANSWER_NO == answer) {
- ret = 1;
- gf_log ("cli", GF_LOG_ERROR, "User cancelled a snapshot "
- "restore operation for snap %s", (char *)words[2]);
- goto out;
- }
+ ret = dict_set_str(dict, "snapname", (char *)words[2]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to save snap-name %s", words[2]);
+ goto out;
+ }
+
+ question =
+ "Restore operation will replace the "
+ "original volume with the snapshotted volume. "
+ "Do you still want to continue?";
+
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 1;
+ gf_log("cli", GF_LOG_ERROR,
+ "User cancelled a snapshot "
+ "restore operation for snap %s",
+ (char *)words[2]);
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
/* snapshot activate <snapname> [force]
@@ -4212,43 +4684,41 @@ out:
* 0 on success
*/
int
-cli_snap_activate_parse (dict_t *dict, const char **words, int wordcount)
+cli_snap_activate_parse(dict_t *dict, const char **words, int wordcount)
{
+ int ret = -1;
+ int flags = 0;
- int ret = -1;
- int flags = 0;
-
- GF_ASSERT (words);
- GF_ASSERT (dict);
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
- if ((wordcount < 3) || (wordcount > 4)) {
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ if ((wordcount < 3) || (wordcount > 4)) {
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- ret = dict_set_str (dict, "snapname", (char *)words[2]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to save snap-name %s",
- words[2]);
- goto out;
- }
+ ret = dict_set_str(dict, "snapname", (char *)words[2]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to save snap-name %s", words[2]);
+ goto out;
+ }
- if (wordcount == 4) {
- if (!strcmp("force", (char *)words[3])) {
- flags = GF_CLI_FLAG_OP_FORCE;
- } else {
- gf_log ("cli", GF_LOG_ERROR, "Invalid option");
- ret = -1;
- goto out;
- }
- }
- ret = dict_set_int32 (dict, "flags", flags);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to save force option");
- goto out;
- }
+ if (wordcount == 4) {
+ if (!strcmp("force", (char *)words[3])) {
+ flags = GF_CLI_FLAG_OP_FORCE;
+ } else {
+ gf_log("cli", GF_LOG_ERROR, "Invalid option");
+ ret = -1;
+ goto out;
+ }
+ }
+ ret = dict_set_int32(dict, "flags", flags);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to save force option");
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
/* snapshot deactivate <snapname>
@@ -4261,42 +4731,41 @@ out:
* 1 if user cancelled the request
*/
int
-cli_snap_deactivate_parse (dict_t *dict, const char **words, int wordcount,
- struct cli_state *state)
+cli_snap_deactivate_parse(dict_t *dict, const char **words, int wordcount,
+ struct cli_state *state)
{
+ int ret = -1;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *question =
+ "Deactivating snap will make its "
+ "data inaccessible. Do you want to "
+ "continue?";
+
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
+
+ if ((wordcount != 3)) {
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- int ret = -1;
- gf_answer_t answer = GF_ANSWER_NO;
- const char *question = "Deactivating snap will make its "
- "data inaccessible. Do you want to "
- "continue?";
-
-
- GF_ASSERT (words);
- GF_ASSERT (dict);
-
- if ((wordcount != 3)) {
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
-
- ret = dict_set_str (dict, "snapname", (char *)words[2]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to save snap-name %s",
- words[2]);
- goto out;
- }
-
- answer = cli_cmd_get_confirmation (state, question);
- if (GF_ANSWER_NO == answer) {
- ret = 1;
- gf_log ("cli", GF_LOG_DEBUG, "User cancelled "
- "snapshot deactivate operation");
- goto out;
- }
+ ret = dict_set_str(dict, "snapname", (char *)words[2]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to save snap-name %s", words[2]);
+ goto out;
+ }
+
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 1;
+ gf_log("cli", GF_LOG_DEBUG,
+ "User cancelled "
+ "snapshot deactivate operation");
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
/* snapshot delete (all | snapname | volume <volname>)
@@ -4309,78 +4778,84 @@ out:
* 1 if user cancel the operation
*/
int
-cli_snap_delete_parse (dict_t *dict, const char **words, int wordcount,
- struct cli_state *state) {
-
- int ret = -1;
- const char *question = NULL;
- int32_t cmd = -1;
- unsigned int cmdi = 2;
- gf_answer_t answer = GF_ANSWER_NO;
-
- GF_ASSERT (words);
- GF_ASSERT (dict);
+cli_snap_delete_parse(dict_t *dict, const char **words, int wordcount,
+ struct cli_state *state)
+{
+ int ret = -1;
+ const char *question = NULL;
+ int32_t cmd = -1;
+ unsigned int cmdi = 2;
+ gf_answer_t answer = GF_ANSWER_NO;
- if (wordcount > 4 || wordcount <= cmdi) {
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
- question = "Deleting snap will erase all the information about "
- "the snap. Do you still want to continue?";
+ if (wordcount > 4 || wordcount <= cmdi) {
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- if (strcmp (words [cmdi], "all") == 0) {
- ret = 0;
- cmd = GF_SNAP_DELETE_TYPE_ALL;
- } else if (strcmp (words [cmdi], "volume") == 0) {
- if (++cmdi == wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ question =
+ "Deleting snap will erase all the information about "
+ "the snap. Do you still want to continue?";
- ret = dict_set_str (dict, "volname",
- (char *)words[cmdi]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save "
- "volume name %s", words[wordcount - 1]);
- goto out;
- }
- cmd = GF_SNAP_DELETE_TYPE_VOL;
- } else {
- ret = dict_set_str (dict, "snapname", (char *)words[cmdi]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to save "
- "snapname %s", words[2]);
- goto out;
- }
- cmd = GF_SNAP_DELETE_TYPE_SNAP;
+ if (strcmp(words[cmdi], "all") == 0) {
+ ret = 0;
+ cmd = GF_SNAP_DELETE_TYPE_ALL;
+ } else if (strcmp(words[cmdi], "volume") == 0) {
+ if (++cmdi == wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
}
- if ((cmdi + 1) != wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
+ ret = dict_set_str(dict, "volname", (char *)words[cmdi]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save "
+ "volume name %s",
+ words[wordcount - 1]);
+ goto out;
+ }
+ cmd = GF_SNAP_DELETE_TYPE_VOL;
+ } else {
+ ret = dict_set_str(dict, "snapname", (char *)words[cmdi]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Unable to save "
+ "snapname %s",
+ words[2]);
+ goto out;
}
+ cmd = GF_SNAP_DELETE_TYPE_SNAP;
+ }
- if (cmd == GF_SNAP_DELETE_TYPE_SNAP) {
- answer = cli_cmd_get_confirmation (state, question);
- if (GF_ANSWER_NO == answer) {
- ret = 1;
- gf_log ("cli", GF_LOG_DEBUG, "User cancelled "
- "snapshot delete operation for snap %s",
- (char *)words[2]);
- goto out;
- }
- }
+ if ((cmdi + 1) != wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- ret = dict_set_int32 (dict, "sub-cmd", cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save "
- "type of snapshot delete");
- }
+ if (cmd == GF_SNAP_DELETE_TYPE_SNAP) {
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 1;
+ gf_log("cli", GF_LOG_DEBUG,
+ "User cancelled "
+ "snapshot delete operation for snap %s",
+ (char *)words[2]);
+ goto out;
+ }
+ }
+
+ ret = dict_set_int32(dict, "sub-cmd", cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save "
+ "type of snapshot delete");
+ }
out:
- return ret;
+ return ret;
}
/* snapshot status [(snapname | volume <volname>)]
@@ -4392,132 +4867,138 @@ out:
* 0 on success
*/
int
-cli_snap_status_parse (dict_t *dict, const char **words, int wordcount)
+cli_snap_status_parse(dict_t *dict, const char **words, int wordcount)
{
+ int ret = -1;
+ int32_t cmd = GF_SNAP_STATUS_TYPE_ALL;
+ unsigned int cmdi = 2;
+ /* cmdi is command index, here cmdi is "2" (gluster snapshot status)*/
- int ret = -1;
- int32_t cmd = GF_SNAP_STATUS_TYPE_ALL;
- unsigned int cmdi = 2;
- /* cmdi is command index, here cmdi is "2" (gluster snapshot status)*/
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
- GF_ASSERT (words);
- GF_ASSERT (dict);
+ if (wordcount > 4 || wordcount < cmdi) {
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- if (wordcount > 4 || wordcount < cmdi) {
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ if (wordcount == cmdi) {
+ ret = 0;
+ goto out;
+ }
- if (wordcount == cmdi) {
- ret = 0;
- goto out;
+ /* if 3rd word is not "volume", then it must be "snapname"
+ */
+ if (strcmp(words[cmdi], "volume") != 0) {
+ ret = dict_set_str(dict, "snapname", (char *)words[cmdi]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Count not save "
+ "snap name %s",
+ words[cmdi]);
+ goto out;
}
- /* if 3rd word is not "volume", then it must be "snapname"
- */
- if (strcmp (words[cmdi], "volume") != 0) {
- ret = dict_set_str (dict, "snapname",
- (char *)words[cmdi]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Count not save "
- "snap name %s", words[cmdi]);
- goto out;
- }
-
- if ((cmdi + 1) != wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
-
- ret = 0;
- cmd = GF_SNAP_STATUS_TYPE_SNAP;
- goto out;
+ if ((cmdi + 1) != wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
}
- /* If 3rd word is "volume", then check if next word is present.
- * As, "snapshot info volume" is an invalid command
- */
- if ((cmdi + 1) == wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ ret = 0;
+ cmd = GF_SNAP_STATUS_TYPE_SNAP;
+ goto out;
+ }
- ret = dict_set_str (dict, "volname", (char *)words [wordcount - 1]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Count not save "
- "volume name %s", words[wordcount - 1]);
- goto out;
- }
- cmd = GF_SNAP_STATUS_TYPE_VOL;
+ /* If 3rd word is "volume", then check if next word is present.
+ * As, "snapshot info volume" is an invalid command
+ */
+ if ((cmdi + 1) == wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+
+ ret = dict_set_str(dict, "volname", (char *)words[wordcount - 1]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Count not save "
+ "volume name %s",
+ words[wordcount - 1]);
+ goto out;
+ }
+ cmd = GF_SNAP_STATUS_TYPE_VOL;
out:
- if (ret == 0) {
- ret = dict_set_int32 (dict, "sub-cmd", cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save cmd "
- "of snapshot status");
- }
+ if (ret == 0) {
+ ret = dict_set_int32(dict, "sub-cmd", cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save cmd "
+ "of snapshot status");
}
+ }
- return ret;
+ return ret;
}
-
/* return value:
* -1 in case of failure.
* 0 in case of success.
*/
int32_t
-cli_snap_config_limit_parse (const char **words, dict_t *dict,
- unsigned int wordcount, unsigned int index,
- char *key)
+cli_snap_config_limit_parse(const char **words, dict_t *dict,
+ unsigned int wordcount, unsigned int index,
+ char *key)
{
- int ret = -1;
- int limit = 0;
- char *end_ptr = NULL;
+ int ret = -1;
+ int limit = 0;
+ char *end_ptr = NULL;
- GF_ASSERT (words);
- GF_ASSERT (dict);
- GF_ASSERT (key);
-
- if (index >= wordcount) {
- ret = -1;
- cli_err ("Please provide a value for %s.", key);
- gf_log ("cli", GF_LOG_ERROR, "Value not provided for %s", key);
- goto out;
- }
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
+ GF_ASSERT(key);
- limit = strtol (words[index], &end_ptr, 10);
+ if (index >= wordcount) {
+ ret = -1;
+ cli_err("Please provide a value for %s.", key);
+ gf_log("cli", GF_LOG_ERROR, "Value not provided for %s", key);
+ goto out;
+ }
- if (limit <= 0 || strcmp (end_ptr, "") != 0) {
- ret = -1;
- cli_err("Please enter an integer value "
- "greater than zero for %s", key);
- goto out;
- }
+ limit = strtol(words[index], &end_ptr, 10);
- ret = dict_set_int32 (dict, key, limit);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not set "
- "%s in dictionary", key);
- goto out;
- }
+ if (limit <= 0 || strcmp(end_ptr, "") != 0) {
+ ret = -1;
+ cli_err(
+ "Please enter an integer value "
+ "greater than zero for %s",
+ key);
+ goto out;
+ }
+
+ ret = dict_set_int32(dict, key, limit);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not set "
+ "%s in dictionary",
+ key);
+ goto out;
+ }
- ret = dict_set_dynstr_with_alloc (dict, "globalname", "All");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not set global key");
- goto out;
- }
- ret = dict_set_int32 (dict, "hold_global_locks", _gf_true);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not set global locks");
- goto out;
- }
+ ret = dict_set_dynstr_with_alloc(dict, "globalname", "All");
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not set global key");
+ goto out;
+ }
+ ret = dict_set_int32(dict, "hold_global_locks", _gf_true);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not set global locks");
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
/* function cli_snap_config_parse
@@ -4533,759 +5014,933 @@ out:
NOTE : snap-max-soft-limit can only be set for system.
*/
int32_t
-cli_snap_config_parse (const char **words, int wordcount, dict_t *dict,
- struct cli_state *state)
+cli_snap_config_parse(const char **words, int wordcount, dict_t *dict,
+ struct cli_state *state)
{
- int ret = -1;
- gf_answer_t answer = GF_ANSWER_NO;
- gf_boolean_t vol_presence = _gf_false;
- struct snap_config_opt_vals_ *conf_vals = NULL;
- int8_t hard_limit = 0;
- int8_t soft_limit = 0;
- int8_t config_type = -1;
- const char *question = NULL;
- unsigned int cmdi = 2;
- /* cmdi is command index, here cmdi is "2" (gluster snapshot config)*/
-
- GF_ASSERT (words);
- GF_ASSERT (dict);
- GF_ASSERT (state);
-
- if ((wordcount < 2) || (wordcount > 7)) {
- gf_log ("cli", GF_LOG_ERROR,
- "Invalid wordcount(%d)", wordcount);
- goto out;
- }
+ int ret = -1;
+ gf_answer_t answer = GF_ANSWER_NO;
+ gf_boolean_t vol_presence = _gf_false;
+ struct snap_config_opt_vals_ *conf_vals = NULL;
+ int8_t hard_limit = 0;
+ int8_t soft_limit = 0;
+ int8_t config_type = -1;
+ const char *question = NULL;
+ unsigned int cmdi = 2;
+ /* cmdi is command index, here cmdi is "2" (gluster snapshot config)*/
+
+ GF_ASSERT(words);
+ GF_ASSERT(dict);
+ GF_ASSERT(state);
+
+ if ((wordcount < 2) || (wordcount > 7)) {
+ gf_log("cli", GF_LOG_ERROR, "Invalid wordcount(%d)", wordcount);
+ goto out;
+ }
- if (wordcount == 2) {
- config_type = GF_SNAP_CONFIG_DISPLAY;
- ret = 0;
- goto set;
+ if (wordcount == 2) {
+ config_type = GF_SNAP_CONFIG_DISPLAY;
+ ret = 0;
+ goto set;
+ }
+
+ /* auto-delete cannot be a volume name */
+ /* Check whether the 3rd word is volname */
+ if (strcmp(words[cmdi], "snap-max-hard-limit") != 0 &&
+ strcmp(words[cmdi], "snap-max-soft-limit") != 0 &&
+ strcmp(words[cmdi], "auto-delete") != 0 &&
+ strcmp(words[cmdi], "activate-on-create") != 0) {
+ ret = dict_set_str(dict, "volname", (char *)words[cmdi]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to set volname");
+ goto out;
}
+ cmdi++;
+ vol_presence = _gf_true;
- /* auto-delete cannot be a volume name */
- /* Check whether the 3rd word is volname */
- if (strcmp (words[cmdi], "snap-max-hard-limit") != 0
- && strcmp (words[cmdi], "snap-max-soft-limit") != 0
- && strcmp (words[cmdi], "auto-delete") != 0
- && strcmp (words[cmdi], "activate-on-create") != 0) {
- ret = dict_set_str (dict, "volname", (char *)words[cmdi]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set volname");
- goto out;
- }
- cmdi++;
- vol_presence = _gf_true;
-
- if (cmdi == wordcount) {
- config_type = GF_SNAP_CONFIG_DISPLAY;
- ret = 0;
- goto set;
- }
+ if (cmdi == wordcount) {
+ config_type = GF_SNAP_CONFIG_DISPLAY;
+ ret = 0;
+ goto set;
}
+ }
- config_type = GF_SNAP_CONFIG_TYPE_SET;
+ config_type = GF_SNAP_CONFIG_TYPE_SET;
- if (strcmp (words[cmdi], "snap-max-hard-limit") == 0) {
- ret = cli_snap_config_limit_parse (words, dict, wordcount,
- ++cmdi, "snap-max-hard-limit");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse snap "
- "config hard limit");
- goto out;
- }
- hard_limit = 1;
-
- if (++cmdi == wordcount) {
- ret = 0;
- goto set;
- }
+ if (strcmp(words[cmdi], "snap-max-hard-limit") == 0) {
+ ret = cli_snap_config_limit_parse(words, dict, wordcount, ++cmdi,
+ "snap-max-hard-limit");
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to parse snap "
+ "config hard limit");
+ goto out;
}
+ hard_limit = 1;
- if (strcmp (words[cmdi], "snap-max-soft-limit") == 0) {
- if (vol_presence == 1) {
- ret = -1;
- cli_err ("Soft limit cannot be set to individual "
- "volumes.");
- gf_log ("cli", GF_LOG_ERROR, "Soft limit cannot be "
- "set to volumes");
- goto out;
- }
-
- ret = cli_snap_config_limit_parse (words, dict, wordcount,
- ++cmdi, "snap-max-soft-limit");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse snap "
- "config soft limit");
- goto out;
- }
-
- if (++cmdi != wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
- soft_limit = 1;
+ if (++cmdi == wordcount) {
+ ret = 0;
+ goto set;
}
+ }
- if (hard_limit || soft_limit)
- goto set;
+ if (strcmp(words[cmdi], "snap-max-soft-limit") == 0) {
+ if (vol_presence == 1) {
+ ret = -1;
+ cli_err(
+ "Soft limit cannot be set to individual "
+ "volumes.");
+ gf_log("cli", GF_LOG_ERROR,
+ "Soft limit cannot be "
+ "set to volumes");
+ goto out;
+ }
- if (strcmp(words[cmdi], "auto-delete") == 0) {
- if (vol_presence == 1) {
- ret = -1;
- cli_err ("As of now, auto-delete option cannot be set "
- "to volumes");
- gf_log ("cli", GF_LOG_ERROR, "auto-delete option "
- "cannot be set to volumes");
- goto out;
- }
+ ret = cli_snap_config_limit_parse(words, dict, wordcount, ++cmdi,
+ "snap-max-soft-limit");
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to parse snap "
+ "config soft limit");
+ goto out;
+ }
- if (++cmdi >= wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ if (++cmdi != wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+ soft_limit = 1;
+ }
- ret = dict_set_str (dict, "auto-delete", (char *)words[cmdi]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set "
- "value of auto-delete in request "
- "dictionary");
- goto out;
- }
+ if (hard_limit || soft_limit)
+ goto set;
- if (++cmdi != wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
- } else if (strcmp(words[cmdi], "activate-on-create") == 0) {
- if (vol_presence == 1) {
- ret = -1;
- cli_err ("As of now, activate-on-create option "
- "cannot be set to volumes");
- gf_log ("cli", GF_LOG_ERROR, "activate-on-create "
- "option cannot be set to volumes");
- goto out;
- }
+ if (strcmp(words[cmdi], "auto-delete") == 0) {
+ if (vol_presence == 1) {
+ ret = -1;
+ cli_err(
+ "As of now, auto-delete option cannot be set "
+ "to volumes");
+ gf_log("cli", GF_LOG_ERROR,
+ "auto-delete option "
+ "cannot be set to volumes");
+ goto out;
+ }
- if (++cmdi >= wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ if (++cmdi >= wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- ret = dict_set_str (dict, "snap-activate-on-create",
- (char *)words[cmdi]);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set value "
- "of activate-on-create in request dictionary");
- goto out;
- }
+ ret = dict_set_str(dict, "auto-delete", (char *)words[cmdi]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to set "
+ "value of auto-delete in request "
+ "dictionary");
+ goto out;
+ }
+
+ if (++cmdi != wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+ } else if (strcmp(words[cmdi], "activate-on-create") == 0) {
+ if (vol_presence == 1) {
+ ret = -1;
+ cli_err(
+ "As of now, activate-on-create option "
+ "cannot be set to volumes");
+ gf_log("cli", GF_LOG_ERROR,
+ "activate-on-create "
+ "option cannot be set to volumes");
+ goto out;
+ }
+
+ if (++cmdi >= wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
+
+ ret = dict_set_str(dict, "snap-activate-on-create",
+ (char *)words[cmdi]);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to set value "
+ "of activate-on-create in request dictionary");
+ goto out;
+ }
- if (++cmdi != wordcount) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
- } else {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
+ if (++cmdi != wordcount) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
}
+ } else {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- ret = 0; /* Success */
+ ret = 0; /* Success */
set:
- ret = dict_set_int32 (dict, "config-command", config_type);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to set "
- "config-command");
- goto out;
- }
+ ret = dict_set_int32(dict, "config-command", config_type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Unable to set "
+ "config-command");
+ goto out;
+ }
- if (config_type == GF_SNAP_CONFIG_TYPE_SET &&
- (hard_limit || soft_limit)) {
- conf_vals = snap_confopt_vals;
- if (hard_limit && soft_limit) {
- question = conf_vals[GF_SNAP_CONFIG_SET_BOTH].question;
- } else if (soft_limit) {
- question = conf_vals[GF_SNAP_CONFIG_SET_SOFT].question;
- } else if (hard_limit) {
- question = conf_vals[GF_SNAP_CONFIG_SET_HARD].question;
- }
+ if (config_type == GF_SNAP_CONFIG_TYPE_SET && (hard_limit || soft_limit)) {
+ conf_vals = snap_confopt_vals;
+ if (hard_limit && soft_limit) {
+ question = conf_vals[GF_SNAP_CONFIG_SET_BOTH].question;
+ } else if (soft_limit) {
+ question = conf_vals[GF_SNAP_CONFIG_SET_SOFT].question;
+ } else if (hard_limit) {
+ question = conf_vals[GF_SNAP_CONFIG_SET_HARD].question;
+ }
- answer = cli_cmd_get_confirmation (state, question);
- if (GF_ANSWER_NO == answer) {
- ret = 1;
- gf_log ("cli", GF_LOG_DEBUG, "User cancelled "
- "snapshot config operation");
- }
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 1;
+ gf_log("cli", GF_LOG_DEBUG,
+ "User cancelled "
+ "snapshot config operation");
}
+ }
out:
- return ret;
+ return ret;
}
int
-validate_op_name (const char *op, const char *opname, char **opwords) {
- int ret = -1;
- int i = 0;
+validate_op_name(const char *op, const char *opname, char **opwords)
+{
+ int ret = -1;
+ int i = 0;
- GF_ASSERT (opname);
- GF_ASSERT (opwords);
+ GF_ASSERT(opname);
+ GF_ASSERT(opwords);
- for (i = 0 ; opwords[i] != NULL; i++) {
- if (strcmp (opwords[i], opname) == 0) {
- cli_out ("\"%s\" cannot be a %s", opname, op);
- goto out;
- }
+ for (i = 0; opwords[i] != NULL; i++) {
+ if (strcmp(opwords[i], opname) == 0) {
+ cli_out("\"%s\" cannot be a %s", opname, op);
+ goto out;
}
- ret = 0;
+ }
+ ret = 0;
out:
- return ret;
+ return ret;
}
int32_t
-cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
- struct cli_state *state)
+cli_cmd_snapshot_parse(const char **words, int wordcount, dict_t **options,
+ struct cli_state *state)
{
- int32_t ret = -1;
- dict_t *dict = NULL;
- gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE;
- char *w = NULL;
- char *opwords[] = {"create", "delete", "restore",
- "activate", "deactivate", "list",
- "status", "config", "info", "clone",
+ int32_t ret = -1;
+ dict_t *dict = NULL;
+ gf1_cli_snapshot type = GF_SNAP_OPTION_TYPE_NONE;
+ char *w = NULL;
+ static char *opwords[] = {"create", "delete", "restore", "activate",
+ "deactivate", "list", "status", "config",
+ "info", "clone", NULL};
+ static char *invalid_snapnames[] = {"description", "force", "volume", "all",
NULL};
- char *invalid_snapnames[] = {"description", "force",
- "volume", "all", NULL};
- char *invalid_volnames[] = {"volume", "type",
- "subvolumes", "option",
- "end-volume", "all",
- "volume_not_in_ring",
- "description", "force",
- "snap-max-hard-limit",
- "snap-max-soft-limit",
- "auto-delete",
- "activate-on-create", NULL};
-
- GF_ASSERT (words);
- GF_ASSERT (options);
- GF_ASSERT (state);
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- /* Lowest wordcount possible */
- if (wordcount < 2) {
- gf_log ("", GF_LOG_ERROR,
- "Invalid command: Not enough arguments");
- goto out;
- }
-
- w = str_getunamb (words[1], opwords);
- if (!w) {
- /* Checks if the operation is a valid operation */
- gf_log ("", GF_LOG_ERROR, "Opword Mismatch");
- goto out;
- }
+ static char *invalid_volnames[] = {"volume",
+ "type",
+ "subvolumes",
+ "option",
+ "end-volume",
+ "all",
+ "volume_not_in_ring",
+ "description",
+ "force",
+ "snap-max-hard-limit",
+ "snap-max-soft-limit",
+ "auto-delete",
+ "activate-on-create",
+ NULL};
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+ GF_ASSERT(state);
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
- if (!strcmp (w, "create")) {
- type = GF_SNAP_OPTION_TYPE_CREATE;
- } else if (!strcmp (w, "list")) {
- type = GF_SNAP_OPTION_TYPE_LIST;
- } else if (!strcmp (w, "info")) {
- type = GF_SNAP_OPTION_TYPE_INFO;
- } else if (!strcmp (w, "delete")) {
- type = GF_SNAP_OPTION_TYPE_DELETE;
- } else if (!strcmp (w, "config")) {
- type = GF_SNAP_OPTION_TYPE_CONFIG;
- } else if (!strcmp (w, "restore")) {
- type = GF_SNAP_OPTION_TYPE_RESTORE;
- } else if (!strcmp (w, "status")) {
- type = GF_SNAP_OPTION_TYPE_STATUS;
- } else if (!strcmp (w, "activate")) {
- type = GF_SNAP_OPTION_TYPE_ACTIVATE;
- } else if (!strcmp (w, "deactivate")) {
- type = GF_SNAP_OPTION_TYPE_DEACTIVATE;
- } else if (!strcmp(w, "clone")) {
- type = GF_SNAP_OPTION_TYPE_CLONE;
- }
-
- if (type != GF_SNAP_OPTION_TYPE_CONFIG &&
- type != GF_SNAP_OPTION_TYPE_STATUS) {
- ret = dict_set_int32 (dict, "hold_snap_locks", _gf_true);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Unable to set hold-snap-locks value "
- "as _gf_true");
- goto out;
- }
- }
+ /* Lowest wordcount possible */
+ if (wordcount < 2) {
+ gf_log("", GF_LOG_ERROR, "Invalid command: Not enough arguments");
+ goto out;
+ }
- /* Following commands does not require volume locks */
- if (type == GF_SNAP_OPTION_TYPE_STATUS ||
- type == GF_SNAP_OPTION_TYPE_ACTIVATE ||
- type == GF_SNAP_OPTION_TYPE_DEACTIVATE) {
- ret = dict_set_int32 (dict, "hold_vol_locks", _gf_false);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Setting volume lock "
- "flag failed");
- goto out;
- }
+ w = str_getunamb(words[1], opwords);
+ if (!w) {
+ /* Checks if the operation is a valid operation */
+ gf_log("", GF_LOG_ERROR, "Opword Mismatch");
+ goto out;
+ }
+
+ if (!strcmp(w, "create")) {
+ type = GF_SNAP_OPTION_TYPE_CREATE;
+ } else if (!strcmp(w, "list")) {
+ type = GF_SNAP_OPTION_TYPE_LIST;
+ } else if (!strcmp(w, "info")) {
+ type = GF_SNAP_OPTION_TYPE_INFO;
+ } else if (!strcmp(w, "delete")) {
+ type = GF_SNAP_OPTION_TYPE_DELETE;
+ } else if (!strcmp(w, "config")) {
+ type = GF_SNAP_OPTION_TYPE_CONFIG;
+ } else if (!strcmp(w, "restore")) {
+ type = GF_SNAP_OPTION_TYPE_RESTORE;
+ } else if (!strcmp(w, "status")) {
+ type = GF_SNAP_OPTION_TYPE_STATUS;
+ } else if (!strcmp(w, "activate")) {
+ type = GF_SNAP_OPTION_TYPE_ACTIVATE;
+ } else if (!strcmp(w, "deactivate")) {
+ type = GF_SNAP_OPTION_TYPE_DEACTIVATE;
+ } else if (!strcmp(w, "clone")) {
+ type = GF_SNAP_OPTION_TYPE_CLONE;
+ }
+
+ if (type != GF_SNAP_OPTION_TYPE_CONFIG &&
+ type != GF_SNAP_OPTION_TYPE_STATUS) {
+ ret = dict_set_int32(dict, "hold_snap_locks", _gf_true);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Unable to set hold-snap-locks value "
+ "as _gf_true");
+ goto out;
+ }
+ }
+
+ /* Following commands does not require volume locks */
+ if (type == GF_SNAP_OPTION_TYPE_STATUS ||
+ type == GF_SNAP_OPTION_TYPE_ACTIVATE ||
+ type == GF_SNAP_OPTION_TYPE_DEACTIVATE) {
+ ret = dict_set_int32(dict, "hold_vol_locks", _gf_false);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Setting volume lock "
+ "flag failed");
+ goto out;
}
+ }
- /* Check which op is intended */
- switch (type) {
+ /* Check which op is intended */
+ switch (type) {
case GF_SNAP_OPTION_TYPE_CREATE:
- /* Syntax :
- * gluster snapshot create <snapname> <vol-name(s)>
- * [no-timestamp]
- * [description <description>]
- * [force]
- */
- /* In cases where the snapname is not given then
- * parsing fails & snapname cannot be "description",
- * "force" and "volume", that check is made here
- */
- if (wordcount == 2){
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
+ /* Syntax :
+ * gluster snapshot create <snapname> <vol-name(s)>
+ * [no-timestamp]
+ * [description <description>]
+ * [force]
+ */
+ /* In cases where the snapname is not given then
+ * parsing fails & snapname cannot be "description",
+ * "force" and "volume", that check is made here
+ */
+ if (wordcount == 2) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- ret = validate_op_name ("snapname", words[2],
- invalid_snapnames);
- if (ret) {
- goto out;
- }
+ ret = validate_op_name("snapname", words[2], invalid_snapnames);
+ if (ret) {
+ goto out;
+ }
- ret = cli_snap_create_parse (dict, words, wordcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "create command parsing failed.");
- goto out;
- }
- break;
+ ret = cli_snap_create_parse(dict, words, wordcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "create command parsing failed.");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_CLONE:
- /* Syntax :
- * gluster snapshot clone <clonename> <snapname>
- */
- /* In cases where the clonename is not given then
- * parsing fails & snapname cannot be "description",
- * "force" and "volume", that check is made here
- */
- if (wordcount == 2) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid Syntax");
- goto out;
- }
-
- ret = validate_op_name ("clonename", words[2],
- invalid_volnames);
- if (ret) {
- goto out;
- }
+ /* Syntax :
+ * gluster snapshot clone <clonename> <snapname>
+ */
+ /* In cases where the clonename is not given then
+ * parsing fails & snapname cannot be "description",
+ * "force" and "volume", that check is made here
+ */
+ if (wordcount == 2) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid Syntax");
+ goto out;
+ }
- ret = cli_snap_clone_parse (dict, words, wordcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "clone command parsing failed.");
- goto out;
- }
- break;
+ ret = validate_op_name("clonename", words[2], invalid_volnames);
+ if (ret) {
+ goto out;
+ }
+ ret = cli_snap_clone_parse(dict, words, wordcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "clone command parsing failed.");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_INFO:
- /* Syntax :
- * gluster snapshot info [(snapname] | [vol <volname>)]
- */
- ret = cli_snap_info_parse (dict, words, wordcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
- "snapshot info command");
- goto out;
- }
- break;
+ /* Syntax :
+ * gluster snapshot info [(snapname] | [vol <volname>)]
+ */
+ ret = cli_snap_info_parse(dict, words, wordcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to parse "
+ "snapshot info command");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_LIST:
- /* Syntax :
- * gluster snaphsot list [volname]
- */
+ /* Syntax :
+ * gluster snaphsot list [volname]
+ */
- ret = cli_snap_list_parse (dict, words, wordcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
- "snapshot list command");
- goto out;
- }
- break;
+ ret = cli_snap_list_parse(dict, words, wordcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to parse "
+ "snapshot list command");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_DELETE:
- /* Syntax :
- * snapshot delete (all | snapname | volume <volname>)
- */
- ret = cli_snap_delete_parse (dict, words, wordcount, state);
- if (ret) {
- /* A positive ret value means user cancelled
- * the command */
- if (ret < 0) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
- "snapshot delete command");
- }
- goto out;
+ /* Syntax :
+ * snapshot delete (all | snapname | volume <volname>)
+ */
+ ret = cli_snap_delete_parse(dict, words, wordcount, state);
+ if (ret) {
+ /* A positive ret value means user cancelled
+ * the command */
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to parse "
+ "snapshot delete command");
}
- break;
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_CONFIG:
- /* snapshot config [volname] [snap-max-hard-limit <count>]
- * [snap-max-soft-limit <percent>] */
- ret = cli_snap_config_parse (words, wordcount, dict, state);
- if (ret) {
- if (ret < 0)
- gf_log ("cli", GF_LOG_ERROR,
- "config command parsing failed.");
- goto out;
- }
-
- ret = dict_set_int32 (dict, "type", GF_SNAP_OPTION_TYPE_CONFIG);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to set "
- "config type");
- ret = -1;
- goto out;
- }
- break;
-
- case GF_SNAP_OPTION_TYPE_STATUS:
- {
- /* Syntax :
- * gluster snapshot status [(snapname |
- * volume <volname>)]
- */
- ret = cli_snap_status_parse (dict, words, wordcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
- "snapshot status command");
- goto out;
- }
- break;
- }
+ /* snapshot config [volname] [snap-max-hard-limit <count>]
+ * [snap-max-soft-limit <percent>] */
+ ret = cli_snap_config_parse(words, wordcount, dict, state);
+ if (ret) {
+ if (ret < 0)
+ gf_log("cli", GF_LOG_ERROR,
+ "config command parsing failed.");
+ goto out;
+ }
- case GF_SNAP_OPTION_TYPE_RESTORE:
- /* Syntax:
- * snapshot restore <snapname>
- */
- ret = cli_snap_restore_parse (dict, words, wordcount, state);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
- "restore command");
- goto out;
- }
- break;
-
- case GF_SNAP_OPTION_TYPE_ACTIVATE:
- /* Syntax:
- * snapshot activate <snapname> [force]
- */
- ret = cli_snap_activate_parse (dict, words, wordcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse "
- "start command");
- goto out;
- }
- break;
- case GF_SNAP_OPTION_TYPE_DEACTIVATE:
- /* Syntax:
- * snapshot deactivate <snapname>
- */
- ret = cli_snap_deactivate_parse (dict, words, wordcount,
- state);
- if (ret) {
- /* A positive ret value means user cancelled
- * the command */
- if (ret < 0) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to parse deactivate "
- "command");
- }
- goto out;
- }
- break;
+ ret = dict_set_int32(dict, "type", GF_SNAP_OPTION_TYPE_CONFIG);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Unable to set "
+ "config type");
+ ret = -1;
+ goto out;
+ }
+ break;
- default:
- gf_log ("", GF_LOG_ERROR, "Opword Mismatch");
+ case GF_SNAP_OPTION_TYPE_STATUS: {
+ /* Syntax :
+ * gluster snapshot status [(snapname |
+ * volume <volname>)]
+ */
+ ret = cli_snap_status_parse(dict, words, wordcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to parse "
+ "snapshot status command");
goto out;
+ }
+ break;
}
- ret = dict_set_int32 (dict, "type", type);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to set type.");
+ case GF_SNAP_OPTION_TYPE_RESTORE:
+ /* Syntax:
+ * snapshot restore <snapname>
+ */
+ ret = cli_snap_restore_parse(dict, words, wordcount, state);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to parse "
+ "restore command");
+ goto out;
+ }
+ break;
+
+ case GF_SNAP_OPTION_TYPE_ACTIVATE:
+ /* Syntax:
+ * snapshot activate <snapname> [force]
+ */
+ ret = cli_snap_activate_parse(dict, words, wordcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to parse "
+ "start command");
+ goto out;
+ }
+ break;
+ case GF_SNAP_OPTION_TYPE_DEACTIVATE:
+ /* Syntax:
+ * snapshot deactivate <snapname>
+ */
+ ret = cli_snap_deactivate_parse(dict, words, wordcount, state);
+ if (ret) {
+ /* A positive ret value means user cancelled
+ * the command */
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to parse deactivate "
+ "command");
+ }
goto out;
- }
- /* If you got so far, input is valid */
- ret = 0;
+ }
+ break;
+
+ default:
+ ret = -1;
+ gf_log("", GF_LOG_ERROR, "Opword Mismatch");
+ goto out;
+ }
+
+ ret = dict_set_int32(dict, "type", type);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "Failed to set type.");
+ goto out;
+ }
+ /* If you got so far, input is valid */
+ ret = 0;
out:
- if (ret) {
- if (dict)
- dict_destroy (dict);
- } else
- *options = dict;
+ if (ret) {
+ if (dict)
+ dict_unref(dict);
+ } else
+ *options = dict;
- return ret;
+ return ret;
}
int
-cli_cmd_validate_volume (char *volname)
+cli_cmd_validate_volume(char *volname)
{
- int i = 0;
- int ret = -1;
+ int i = 0;
+ int ret = -1;
+ int volname_len;
+ if (volname[0] == '-')
+ return ret;
- if (volname[0] == '-')
- return ret;
+ if (!strcmp(volname, "all")) {
+ cli_err("\"all\" cannot be the name of a volume.");
+ return ret;
+ }
- if (!strcmp (volname, "all")) {
- cli_err ("\"all\" cannot be the name of a volume.");
- return ret;
- }
+ if (strchr(volname, '/')) {
+ cli_err("Volume name should not contain \"/\" character.");
+ return ret;
+ }
- if (strchr (volname, '/')) {
- cli_err ("Volume name should not contain \"/\" character.");
- return ret;
- }
+ volname_len = strlen(volname);
+ if (volname_len > GD_VOLUME_NAME_MAX) {
+ cli_err("Volname can not exceed %d characters.", GD_VOLUME_NAME_MAX);
+ return ret;
+ }
- if (strlen (volname) > GD_VOLUME_NAME_MAX) {
- cli_err ("Volname can not exceed %d characters.",
- GD_VOLUME_NAME_MAX);
- return ret;
+ for (i = 0; i < volname_len; i++)
+ if (!isalnum(volname[i]) && (volname[i] != '_') &&
+ (volname[i] != '-')) {
+ cli_err(
+ "Volume name should not contain \"%c\""
+ " character.\nVolume names can only"
+ "contain alphanumeric, '-' and '_' "
+ "characters.",
+ volname[i]);
+ return ret;
}
- for (i = 0; i < strlen (volname); i++)
- if (!isalnum (volname[i]) && (volname[i] != '_') &&
- (volname[i] != '-')) {
- cli_err ("Volume name should not contain \"%c\""
- " character.\nVolume names can only"
- "contain alphanumeric, '-' and '_' "
- "characters.", volname[i]);
- return ret;
- }
-
- ret = 0;
+ ret = 0;
- return ret;
+ return ret;
}
int32_t
-cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **options)
+cli_cmd_bitrot_parse(const char **words, int wordcount, dict_t **options)
{
- int32_t ret = -1;
- char *w = NULL;
- char *volname = NULL;
- char *opwords[] = {"enable", "disable",
- "scrub-throttle",
- "scrub-frequency", "scrub",
- "signing-time", NULL};
- char *scrub_throt_values[] = {"lazy", "normal",
- "aggressive", NULL};
- char *scrub_freq_values[] = {"hourly",
- "daily", "weekly",
- "biweekly", "monthly",
- NULL};
- char *scrub_values[] = {"pause", "resume",
- NULL};
- dict_t *dict = NULL;
- gf_bitrot_type type = GF_BITROT_OPTION_TYPE_NONE;
- int32_t expiry_time = 0;
-
- GF_ASSERT (words);
- GF_ASSERT (options);
-
- dict = dict_new ();
- if (!dict)
- goto out;
+ int32_t ret = -1;
+ char *w = NULL;
+ char *volname = NULL;
+ static char *opwords[] = {"enable", "disable", "scrub-throttle",
+ "scrub-frequency", "scrub", "signing-time",
+ "signer-threads", NULL};
+ static char *scrub_throt_values[] = {"lazy", "normal", "aggressive", NULL};
+ static char *scrub_freq_values[] = {
+ "hourly", "daily", "weekly", "biweekly", "monthly", "minute", NULL};
+ static char *scrub_values[] = {"pause", "resume", "status", "ondemand",
+ NULL};
+ dict_t *dict = NULL;
+ gf_bitrot_type type = GF_BITROT_OPTION_TYPE_NONE;
+ int32_t expiry_time = 0;
+ int32_t signer_th_count = 0;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ /* Hack to print out bitrot help properly */
+ if ((wordcount == 3) && !(strcmp(words[2], "help"))) {
+ ret = 1;
+ return ret;
+ }
- if (wordcount < 4 || wordcount > 5) {
- gf_log ("cli", GF_LOG_ERROR, "Invalid syntax");
- goto out;
- }
+ if (wordcount < 4 || wordcount > 5) {
+ gf_log("cli", GF_LOG_ERROR, "Invalid syntax");
+ goto out;
+ }
- volname = (char *)words[2];
- if (!volname) {
- ret = -1;
- goto out;
- }
+ dict = dict_new();
+ if (!dict)
+ goto out;
- ret = cli_cmd_validate_volume (volname);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to validate volume name");
- goto out;
- }
+ volname = (char *)words[2];
+ if (!volname) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_str (dict, "volname", volname);
- if (ret) {
- cli_out ("Failed to set volume name in dictionary ");
- goto out;
+ ret = cli_cmd_validate_volume(volname);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to validate volume name");
+ goto out;
+ }
+
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret) {
+ cli_out("Failed to set volume name in dictionary ");
+ goto out;
+ }
+
+ w = str_getunamb(words[3], opwords);
+ if (!w) {
+ cli_out("Invalid bit rot option : %s", words[3]);
+ ret = -1;
+ goto out;
+ }
+
+ if (strcmp(w, "enable") == 0) {
+ if (wordcount == 4) {
+ type = GF_BITROT_OPTION_TYPE_ENABLE;
+ ret = 0;
+ goto set_type;
+ } else {
+ ret = -1;
+ goto out;
}
+ }
- w = str_getunamb (words[3], opwords);
- if (!w) {
- cli_out ("Invalid bit rot option : %s", words[3]);
+ if (strcmp(w, "disable") == 0) {
+ if (wordcount == 4) {
+ type = GF_BITROT_OPTION_TYPE_DISABLE;
+ ret = 0;
+ goto set_type;
+ } else {
+ ret = -1;
+ goto out;
+ }
+ }
+
+ if (!strcmp(w, "scrub-throttle")) {
+ if (!words[4]) {
+ cli_err(
+ "Missing scrub-throttle value for bitrot "
+ "option");
+ ret = -1;
+ goto out;
+ } else {
+ w = str_getunamb(words[4], scrub_throt_values);
+ if (!w) {
+ cli_err(
+ "Invalid scrub-throttle option for "
+ "bitrot");
ret = -1;
goto out;
- }
-
- if (strcmp (w, "enable") == 0) {
- if (wordcount == 4) {
- type = GF_BITROT_OPTION_TYPE_ENABLE;
- ret = 0;
- goto set_type;
- } else {
- ret = -1;
- goto out;
+ } else {
+ type = GF_BITROT_OPTION_TYPE_SCRUB_THROTTLE;
+ ret = dict_set_str(dict, "scrub-throttle-value",
+ (char *)words[4]);
+ if (ret) {
+ cli_out(
+ "Failed to set scrub-throttle "
+ "value in the dict");
+ goto out;
}
+ goto set_type;
+ }
}
+ }
- if (strcmp (w, "disable") == 0) {
- if (wordcount == 4) {
- type = GF_BITROT_OPTION_TYPE_DISABLE;
- ret = 0;
- goto set_type;
- } else {
- ret = -1;
- goto out;
+ if (!strcmp(words[3], "scrub-frequency")) {
+ if (!words[4]) {
+ cli_err("Missing scrub-frequency value");
+ ret = -1;
+ goto out;
+ } else {
+ w = str_getunamb(words[4], scrub_freq_values);
+ if (!w) {
+ cli_err("Invalid frequency option for bitrot");
+ ret = -1;
+ goto out;
+ } else {
+ type = GF_BITROT_OPTION_TYPE_SCRUB_FREQ;
+ ret = dict_set_str(dict, "scrub-frequency-value",
+ (char *)words[4]);
+ if (ret) {
+ cli_out(
+ "Failed to set dict for "
+ "bitrot");
+ goto out;
}
+ goto set_type;
+ }
}
+ }
- if (!strcmp (w, "scrub-throttle")) {
- if (!words[4]) {
- cli_err ("Missing scrub-throttle value for bitrot "
- "option");
- ret = -1;
- goto out;
+ if (!strcmp(words[3], "scrub")) {
+ if (!words[4]) {
+ cli_err("Missing scrub value for bitrot option");
+ ret = -1;
+ goto out;
+ } else {
+ w = str_getunamb(words[4], scrub_values);
+ if (!w) {
+ cli_err("Invalid scrub option for bitrot");
+ ret = -1;
+ goto out;
+ } else {
+ if (strcmp(words[4], "status") == 0) {
+ type = GF_BITROT_CMD_SCRUB_STATUS;
+ } else if (strcmp(words[4], "ondemand") == 0) {
+ type = GF_BITROT_CMD_SCRUB_ONDEMAND;
} else {
- w = str_getunamb (words[4], scrub_throt_values);
- if (!w) {
- cli_err ("Invalid scrub-throttle option for "
- "bitrot");
- ret = -1;
- goto out;
- } else {
- type = GF_BITROT_OPTION_TYPE_SCRUB_THROTTLE;
- ret = dict_set_str (dict,
- "scrub-throttle-value",
- (char *) words[4]);
- if (ret) {
- cli_out ("Failed to set scrub-throttle "
- "value in the dict");
- goto out;
- }
- goto set_type;
- }
+ type = GF_BITROT_OPTION_TYPE_SCRUB;
}
- }
-
- if (!strcmp (words[3], "scrub-frequency")) {
- if (!words[4]) {
- cli_err ("Missing scrub-frequency value");
- ret = -1;
- goto out;
- } else {
- w = str_getunamb (words[4], scrub_freq_values);
- if (!w) {
- cli_err ("Invalid frequency option for bitrot");
- ret = -1;
- goto out;
- } else {
- type = GF_BITROT_OPTION_TYPE_SCRUB_FREQ;
- ret = dict_set_str (dict,
- "scrub-frequency-value",
- (char *) words[4]);
- if (ret) {
- cli_out ("Failed to set dict for "
- "bitrot");
- goto out;
- }
- goto set_type;
- }
+ ret = dict_set_str(dict, "scrub-value", (char *)words[4]);
+ if (ret) {
+ cli_out(
+ "Failed to set dict for "
+ "bitrot");
+ goto out;
}
+ goto set_type;
+ }
}
+ }
- if (!strcmp (words[3], "scrub")) {
- if (!words[4]) {
- cli_err ("Missing scrub value for bitrot option");
- ret = -1;
- goto out;
- } else {
- w = str_getunamb (words[4], scrub_values);
- if (!w) {
- cli_err ("Invalid scrub option for bitrot");
- ret = -1;
- goto out;
- } else {
- type = GF_BITROT_OPTION_TYPE_SCRUB;
- ret = dict_set_str (dict, "scrub-value",
- (char *) words[4]);
- if (ret) {
- cli_out ("Failed to set dict for "
- "bitrot");
- goto out;
- }
- goto set_type;
- }
- }
- }
+ if (!strcmp(words[3], "signing-time")) {
+ if (!words[4]) {
+ cli_err(
+ "Missing signing-time value for bitrot "
+ "option");
+ ret = -1;
+ goto out;
+ } else {
+ type = GF_BITROT_OPTION_TYPE_EXPIRY_TIME;
- if (!strcmp (words[3], "signing-time")) {
- if (!words[4]) {
- cli_err ("Missing signing-time value for bitrot "
- "option");
- ret = -1;
- goto out;
- } else {
- type = GF_BITROT_OPTION_TYPE_EXPIRY_TIME;
-
- expiry_time = strtol (words[4], NULL, 0);
- if (expiry_time < 1) {
- cli_err ("Expiry time value should not be less"
- " than 1");
- ret = -1;
- goto out;
- }
+ expiry_time = strtol(words[4], NULL, 0);
+ if (expiry_time < 1) {
+ cli_err(
+ "Expiry time value should not be less"
+ " than 1");
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_uint32 (dict, "expiry-time",
- (unsigned int) expiry_time);
- if (ret) {
- cli_out ("Failed to set dict for bitrot");
- goto out;
- }
- goto set_type;
- }
+ ret = dict_set_uint32(dict, "expiry-time",
+ (unsigned int)expiry_time);
+ if (ret) {
+ cli_out("Failed to set dict for bitrot");
+ goto out;
+ }
+ goto set_type;
+ }
+ } else if (!strcmp(words[3], "signer-threads")) {
+ if (!words[4]) {
+ cli_err(
+ "Missing signer-thread value for bitrot "
+ "option");
+ ret = -1;
+ goto out;
} else {
- cli_err ("Invalid option %s for bitrot. Please enter valid "
- "bitrot option", words[3]);
+ type = GF_BITROT_OPTION_TYPE_SIGNER_THREADS;
+
+ signer_th_count = strtol(words[4], NULL, 0);
+ if (signer_th_count < 1) {
+ cli_err("signer-thread count should not be less than 1");
ret = -1;
goto out;
- }
+ }
-set_type:
- ret = dict_set_int32 (dict, "type", type);
- if (ret < 0)
+ ret = dict_set_uint32(dict, "signer-threads",
+ (unsigned int)signer_th_count);
+ if (ret) {
+ cli_out("Failed to set dict for bitrot");
goto out;
+ }
+ goto set_type;
+ }
+ } else {
+ cli_err(
+ "Invalid option %s for bitrot. Please enter valid "
+ "bitrot option",
+ words[3]);
+ ret = -1;
+ goto out;
+ }
+set_type:
+ ret = dict_set_int32(dict, "type", type);
+ if (ret < 0)
+ goto out;
- *options = dict;
+ *options = dict;
out:
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to parse bitrot command");
- if (dict)
- dict_destroy (dict);
- }
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to parse bitrot command");
+ if (dict)
+ dict_unref(dict);
+ }
- return ret;
+ return ret;
+}
+
+/* Parsing global option for NFS-Ganesha config
+ * gluster nfs-ganesha enable/disable */
+
+int32_t
+cli_cmd_ganesha_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **op_errstr)
+{
+ dict_t *dict = NULL;
+ int ret = -1;
+ char *key = NULL;
+ char *value = NULL;
+ char *w = NULL;
+ static char *opwords[] = {"enable", "disable", NULL};
+ const char *question = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+
+ GF_ASSERT(words);
+ GF_ASSERT(options);
+
+ dict = dict_new();
+
+ if (!dict)
+ goto out;
+
+ if (wordcount != 2)
+ goto out;
+
+ key = (char *)words[0];
+ value = (char *)words[1];
+
+ if (!key || !value) {
+ cli_out("Usage : nfs-ganesha <enable/disable>");
+ ret = -1;
+ goto out;
+ }
+
+ ret = gf_strip_whitespace(value, strlen(value));
+ if (ret == -1)
+ goto out;
+
+ if (strcmp(key, "nfs-ganesha")) {
+ gf_asprintf(op_errstr,
+ "Global option: error: ' %s '"
+ "is not a valid global option.",
+ key);
+ ret = -1;
+ goto out;
+ }
+
+ w = str_getunamb(value, opwords);
+ if (!w) {
+ cli_out(
+ "Invalid global option \n"
+ "Usage : nfs-ganesha <enable/disable>");
+ ret = -1;
+ goto out;
+ }
+
+ if (strcmp(value, "enable") == 0) {
+ question =
+ "Enabling NFS-Ganesha requires Gluster-NFS to be "
+ "disabled across the trusted pool. Do you "
+ "still want to continue?\n";
+ } else if (strcmp(value, "disable") == 0) {
+ question =
+ "Disabling NFS-Ganesha will tear down the entire "
+ "ganesha cluster across the trusted pool. Do you "
+ "still want to continue?\n";
+ } else {
+ ret = -1;
+ goto out;
+ }
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Global operation "
+ "cancelled, exiting");
+ ret = -1;
+ goto out;
+ }
+ cli_out("This will take a few minutes to complete. Please wait ..");
+
+ ret = dict_set_str(dict, "key", key);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "dict set on key failed");
+ goto out;
+ }
+
+ ret = dict_set_str(dict, "value", value);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "dict set on value failed");
+ goto out;
+ }
+
+ ret = dict_set_str(dict, "globalname", "All");
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "dict set on global"
+ " key failed.");
+ goto out;
+ }
+
+ ret = dict_set_int32(dict, "hold_global_locks", _gf_true);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "dict set on global key "
+ "failed.");
+ goto out;
+ }
+
+ *options = dict;
+out:
+ if (ret)
+ dict_unref(dict);
+
+ return ret;
}
diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c
index 0ca31028211..084998701d8 100644
--- a/cli/src/cli-cmd-peer.c
+++ b/cli/src/cli-cmd-peer.c
@@ -18,278 +18,300 @@
#include "cli-mem-types.h"
#include "cli1-xdr.h"
#include "protocol-common.h"
+#include <glusterfs/events.h>
-extern struct rpc_clnt *global_rpc;
-
-extern rpc_clnt_prog_t *cli_rpc_prog;
-
-int cli_cmd_peer_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
+int
+cli_cmd_peer_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount);
int
-cli_cmd_peer_probe_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_peer_probe_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;
- int sent = 0;
- int parse_error = 0;
- cli_local_t *local = NULL;
-
- if (!(wordcount == 3)) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PROBE];
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_set_str (dict, "hostname", (char *)words[2]);
- if (ret)
- goto out;
-
- ret = valid_internet_address ((char *) words[2], _gf_false);
- if (ret == 1) {
- ret = 0;
- } else {
- cli_out ("%s is an invalid address", words[2]);
- cli_usage_out (word->pattern);
- parse_error = 1;
- ret = -1;
- goto out;
- }
-/* if (words[3]) {
- ret = dict_set_str (dict, "port", (char *)words[3]);
- if (ret)
- goto out;
- }
-*/
-
- CLI_LOCAL_INIT (local, words, frame, dict);
-
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ int sent = 0;
+ int parse_error = 0;
+ cli_local_t *local = NULL;
+
+ if (!(wordcount == 3)) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PROBE];
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
+
+ ret = dict_set_str(dict, "hostname", (char *)words[2]);
+ if (ret)
+ goto out;
+
+ ret = valid_internet_address((char *)words[2], _gf_false, _gf_false);
+ if (ret == 1) {
+ ret = 0;
+ } else {
+ cli_out("%s is an invalid address", words[2]);
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ ret = -1;
+ goto out;
+ }
+ /* if (words[3]) {
+ ret = dict_set_str (dict, "port", (char *)words[3]);
+ if (ret)
+ goto out;
+ }
+ */
+
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ CLI_LOCAL_INIT(local, words, frame, dict);
+
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, dict);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Peer probe failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Peer probe failed");
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
-}
+ if (ret == 0) {
+ gf_event(EVENT_PEER_ATTACH, "host=%s", (char *)words[2]);
+ }
+ return ret;
+}
int
-cli_cmd_peer_deprobe_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_peer_deprobe_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;
- int flags = 0;
- int sent = 0;
- int parse_error = 0;
- cli_local_t *local = NULL;
-
- if ((wordcount < 3) || (wordcount > 4)) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DEPROBE];
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- dict = dict_new ();
-
- ret = dict_set_str (dict, "hostname", (char *)words[2]);
- if (ret)
- goto out;
-
-/* if (words[3]) {
- ret = dict_set_str (dict, "port", (char *)words[3]);
- if (ret)
- 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;
-
- CLI_LOCAL_INIT (local, words, frame, dict);
-
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
+ int ret = -1;
+ 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;
+ cli_local_t *local = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *question = NULL;
+
+ if ((wordcount < 3) || (wordcount > 4)) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+ question =
+ "All clients mounted through the peer which is getting detached need "
+ "to be remounted using one of the other active peers in the trusted "
+ "storage pool to ensure client gets notification on any changes done "
+ "on the gluster configuration and if the same has been done do you "
+ "want to proceed?";
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DEPROBE];
+
+ dict = dict_new();
+
+ ret = dict_set_str(dict, "hostname", (char *)words[2]);
+ if (ret)
+ goto out;
+
+ /* if (words[3]) {
+ ret = dict_set_str (dict, "port", (char *)words[3]);
+ if (ret)
+ 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;
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ goto out;
+ }
+
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ CLI_LOCAL_INIT(local, words, frame, dict);
+
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, dict);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Peer detach failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Peer detach failed");
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ if (ret == 0) {
+ gf_event(EVENT_PEER_DETACH, "host=%s", (char *)words[2]);
+ }
+
+ return ret;
}
int
-cli_cmd_peer_status_cbk (struct cli_state *state, struct cli_cmd_word *word,
+cli_cmd_peer_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;
- int sent = 0;
- int parse_error = 0;
-
- if (wordcount != 2) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ int sent = 0;
+ int parse_error = 0;
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_FRIENDS];
+ if (wordcount != 2) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_FRIENDS];
- if (proc->fn) {
- ret = proc->fn (frame, THIS, (void *)GF_CLI_LIST_PEERS);
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, (void *)GF_CLI_LIST_PEERS);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Peer status failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Peer status failed");
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
int
-cli_cmd_pool_list_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_pool_list_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;
-
- if (wordcount != 2) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ int sent = 0;
+ int parse_error = 0;
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_FRIENDS];
+ if (wordcount != 2) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_FRIENDS];
- if (proc->fn) {
- ret = proc->fn (frame, THIS,
- (void *)GF_CLI_LIST_POOL_NODES);
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, (void *)GF_CLI_LIST_POOL_NODES);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_err ("pool list: command execution failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_err("pool list: command execution failed");
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
struct cli_cmd cli_probe_cmds[] = {
- { "peer probe { <HOSTNAME> | <IP-address> }",
- cli_cmd_peer_probe_cbk,
- "probe peer specified by <HOSTNAME>"},
+ {"peer probe { <HOSTNAME> | <IP-address> }", cli_cmd_peer_probe_cbk,
+ "probe peer specified by <HOSTNAME>"},
- { "peer detach { <HOSTNAME> | <IP-address> } [force]",
- cli_cmd_peer_deprobe_cbk,
- "detach peer specified by <HOSTNAME>"},
+ {"peer detach { <HOSTNAME> | <IP-address> } [force]",
+ cli_cmd_peer_deprobe_cbk, "detach peer specified by <HOSTNAME>"},
- { "peer status",
- cli_cmd_peer_status_cbk,
- "list status of peers"},
+ {"peer status", cli_cmd_peer_status_cbk, "list status of peers"},
- { "peer help",
- cli_cmd_peer_help_cbk,
- "Help command for peer "},
+ {"peer help", cli_cmd_peer_help_cbk, "display help for peer commands"},
- { "pool list",
- cli_cmd_pool_list_cbk,
- "list all the nodes in the pool (including localhost)"},
+ {"pool list", cli_cmd_pool_list_cbk,
+ "list all the nodes in the pool (including localhost)"},
- { NULL, NULL, NULL }
-};
+ {NULL, NULL, NULL}};
int
-cli_cmd_peer_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
+cli_cmd_peer_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
const char **words, int wordcount)
{
- struct cli_cmd *cmd = NULL;
+ struct cli_cmd *cmd = NULL;
+ struct cli_cmd *probe_cmd = NULL;
+ int count = 0;
+
+ cli_out("\ngluster peer commands");
+ cli_out("======================\n");
+ cmd = GF_MALLOC(sizeof(cli_probe_cmds), cli_mt_cli_cmd);
+ memcpy(cmd, cli_probe_cmds, sizeof(cli_probe_cmds));
+ count = (sizeof(cli_probe_cmds) / sizeof(struct cli_cmd));
+ cli_cmd_sort(cmd, count);
+ for (probe_cmd = cmd; probe_cmd->pattern; probe_cmd++)
+ cli_out("%s - %s", probe_cmd->pattern, probe_cmd->desc);
- for (cmd = cli_probe_cmds; cmd->pattern; cmd++)
- cli_out ("%s - %s", cmd->pattern, cmd->desc);
+ GF_FREE(cmd);
- return 0;
+ cli_out("\n");
+ return 0;
}
int
-cli_cmd_probe_register (struct cli_state *state)
+cli_cmd_probe_register(struct cli_state *state)
{
- int ret = 0;
- struct cli_cmd *cmd = NULL;
+ int ret = 0;
+ struct cli_cmd *cmd = NULL;
- for (cmd = cli_probe_cmds; cmd->pattern; cmd++) {
-
- ret = cli_cmd_register (&state->tree, cmd);
- if (ret)
- goto out;
- }
+ for (cmd = cli_probe_cmds; cmd->pattern; cmd++) {
+ ret = cli_cmd_register(&state->tree, cmd);
+ if (ret)
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
diff --git a/cli/src/cli-cmd-snapshot.c b/cli/src/cli-cmd-snapshot.c
index 80ab2b0f211..859d6b2e40d 100644
--- a/cli/src/cli-cmd-snapshot.c
+++ b/cli/src/cli-cmd-snapshot.c
@@ -15,142 +15,121 @@
#include "cli.h"
#include "cli-cmd.h"
-
-extern rpc_clnt_prog_t *cli_rpc_prog;
+#include "cli-mem-types.h"
int
-cli_cmd_snapshot_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
- const char **words, int wordcount);
+cli_cmd_snapshot_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount);
int
-cli_cmd_snapshot_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_snapshot_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- int ret = 0;
- int parse_err = 0;
- dict_t *options = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- cli_local_t *local = NULL;
-
- proc = &cli_rpc_prog->proctable [GLUSTER_CLI_SNAP];
- if (proc == NULL) {
- ret = -1;
- goto out;
+ int ret = 0;
+ int parse_err = 0;
+ dict_t *options = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ cli_local_t *local = NULL;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SNAP];
+
+ /* Parses the command entered by the user */
+ ret = cli_cmd_snapshot_parse(words, wordcount, &options, state);
+ if (ret) {
+ if (ret < 0) {
+ cli_usage_out(word->pattern);
+ parse_err = 1;
+ } else {
+ /* User might have cancelled the snapshot operation */
+ ret = 0;
}
+ goto out;
+ }
- frame = create_frame (THIS, THIS->ctx->pool);
- if (frame == NULL) {
- ret = -1;
- goto out;
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (frame == NULL) {
+ ret = -1;
+ goto out;
+ }
- /* Parses the command entered by the user */
- ret = cli_cmd_snapshot_parse (words, wordcount, &options, state);
- if (ret) {
- if (ret < 0) {
- cli_usage_out (word->pattern);
- parse_err = 1;
- } else {
- /* User might have cancelled the snapshot operation */
- ret = 0;
- }
- goto out;
- }
+ CLI_LOCAL_INIT(local, words, frame, options);
- CLI_LOCAL_INIT (local, words, frame, options);
-
- if (proc->fn)
- ret = proc->fn (frame, THIS, options);
+ if (proc->fn)
+ ret = proc->fn(frame, THIS, options);
out:
- if (ret && parse_err == 0)
- cli_out ("Snapshot command failed");
+ if (ret && parse_err == 0)
+ cli_out("Snapshot command failed");
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
struct cli_cmd snapshot_cmds[] = {
- { "snapshot help",
- cli_cmd_snapshot_help_cbk,
- "display help for snapshot commands"
- },
- { "snapshot create <snapname> <volname> [no-timestamp] "
- "[description <description>] [force]",
- cli_cmd_snapshot_cbk,
- "Snapshot Create."
- },
- { "snapshot clone <clonename> <snapname>",
- cli_cmd_snapshot_cbk,
- "Snapshot Clone."
- },
- { "snapshot restore <snapname>",
- cli_cmd_snapshot_cbk,
- "Snapshot Restore."
- },
- { "snapshot status [(snapname | volume <volname>)]",
- cli_cmd_snapshot_cbk,
- "Snapshot Status."
- },
- { "snapshot info [(snapname | volume <volname>)]",
- cli_cmd_snapshot_cbk,
- "Snapshot Info."
- },
- { "snapshot list [volname]",
- cli_cmd_snapshot_cbk,
- "Snapshot List."
- },
- {"snapshot config [volname] ([snap-max-hard-limit <count>] "
- "[snap-max-soft-limit <percent>]) "
- "| ([auto-delete <enable|disable>])"
- "| ([activate-on-create <enable|disable>])",
- cli_cmd_snapshot_cbk,
- "Snapshot Config."
- },
- {"snapshot delete (all | snapname | volume <volname>)",
- cli_cmd_snapshot_cbk,
- "Snapshot Delete."
- },
- {"snapshot activate <snapname> [force]",
- cli_cmd_snapshot_cbk,
- "Activate snapshot volume."
- },
- {"snapshot deactivate <snapname>",
- cli_cmd_snapshot_cbk,
- "Deactivate snapshot volume."
- },
- { NULL, NULL, NULL }
-};
+ {"snapshot help", cli_cmd_snapshot_help_cbk,
+ "display help for snapshot commands"},
+ {"snapshot create <snapname> <volname> [no-timestamp] "
+ "[description <description>] [force]",
+ cli_cmd_snapshot_cbk, "Snapshot Create."},
+ {"snapshot clone <clonename> <snapname>", cli_cmd_snapshot_cbk,
+ "Snapshot Clone."},
+ {"snapshot restore <snapname>", cli_cmd_snapshot_cbk, "Snapshot Restore."},
+ {"snapshot status [(snapname | volume <volname>)]", cli_cmd_snapshot_cbk,
+ "Snapshot Status."},
+ {"snapshot info [(snapname | volume <volname>)]", cli_cmd_snapshot_cbk,
+ "Snapshot Info."},
+ {"snapshot list [volname]", cli_cmd_snapshot_cbk, "Snapshot List."},
+ {"snapshot config [volname] ([snap-max-hard-limit <count>] "
+ "[snap-max-soft-limit <percent>]) "
+ "| ([auto-delete <enable|disable>])"
+ "| ([activate-on-create <enable|disable>])",
+ cli_cmd_snapshot_cbk, "Snapshot Config."},
+ {"snapshot delete (all | snapname | volume <volname>)",
+ cli_cmd_snapshot_cbk, "Snapshot Delete."},
+ {"snapshot activate <snapname> [force]", cli_cmd_snapshot_cbk,
+ "Activate snapshot volume."},
+ {"snapshot deactivate <snapname>", cli_cmd_snapshot_cbk,
+ "Deactivate snapshot volume."},
+ {NULL, NULL, NULL}};
int
-cli_cmd_snapshot_help_cbk (struct cli_state *state,
- struct cli_cmd_word *in_word,
- const char **words,
- int wordcount)
+cli_cmd_snapshot_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount)
{
- struct cli_cmd *cmd = NULL;
+ struct cli_cmd *cmd = NULL;
+ struct cli_cmd *snap_cmd = NULL;
+ int count = 0;
+
+ cmd = GF_MALLOC(sizeof(snapshot_cmds), cli_mt_cli_cmd);
+ memcpy(cmd, snapshot_cmds, sizeof(snapshot_cmds));
+ count = (sizeof(snapshot_cmds) / sizeof(struct cli_cmd));
+ cli_cmd_sort(cmd, count);
- for (cmd = snapshot_cmds; cmd->pattern; cmd++)
- if (_gf_false == cmd->disable)
- cli_out ("%s - %s", cmd->pattern, cmd->desc);
+ cli_out("\ngluster snapshot commands");
+ cli_out("=========================\n");
- return 0;
+ for (snap_cmd = cmd; snap_cmd->pattern; snap_cmd++)
+ if (_gf_false == snap_cmd->disable)
+ cli_out("%s - %s", snap_cmd->pattern, snap_cmd->desc);
+ cli_out("\n");
+
+ GF_FREE(cmd);
+ return 0;
}
int
-cli_cmd_snapshot_register (struct cli_state *state)
+cli_cmd_snapshot_register(struct cli_state *state)
{
- int ret = 0;
- struct cli_cmd *cmd = NULL;
-
- for (cmd = snapshot_cmds; cmd->pattern; cmd++) {
-
- ret = cli_cmd_register (&state->tree, cmd);
- if (ret)
- goto out;
- }
+ int ret = 0;
+ struct cli_cmd *cmd = NULL;
+
+ for (cmd = snapshot_cmds; cmd->pattern; cmd++) {
+ ret = cli_cmd_register(&state->tree, cmd);
+ if (ret)
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
diff --git a/cli/src/cli-cmd-system.c b/cli/src/cli-cmd-system.c
index d71f622ba11..801e8f4efed 100644
--- a/cli/src/cli-cmd-system.c
+++ b/cli/src/cli-cmd-system.c
@@ -18,580 +18,607 @@
#include "cli-mem-types.h"
#include "protocol-common.h"
+int
+cli_cmd_system_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount);
-extern struct rpc_clnt *global_rpc;
-
-extern rpc_clnt_prog_t *cli_rpc_prog;
-
-int cli_cmd_system_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
- const char **words, int wordcount);
-
-int cli_cmd_copy_file_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount);
+int
+cli_cmd_copy_file_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount);
-int cli_cmd_sys_exec_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount);
+int
+cli_cmd_sys_exec_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount);
int
-cli_cmd_getspec_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_getspec_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;
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- if (wordcount != 3) {
- cli_usage_out (word->pattern);
- goto out;
- }
-
- ret = dict_set_str (dict, "volid", (char *)words[2]);
- if (ret)
- goto out;
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GETSPEC];
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+
+ if (wordcount != 3) {
+ cli_usage_out(word->pattern);
+ goto out;
+ }
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
+
+ ret = dict_set_str(dict, "volid", (char *)words[2]);
+ if (ret)
+ goto out;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GETSPEC];
+ if (proc->fn) {
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+ ret = proc->fn(frame, THIS, dict);
+ }
out:
- if (!proc && ret) {
- if (dict)
- dict_destroy (dict);
- if (wordcount > 1)
- cli_out ("Fetching spec for volume %s failed",
- (char *)words[2]);
- }
+ if (!proc && ret) {
+ if (wordcount > 1)
+ cli_out("Fetching spec for volume %s failed", (char *)words[2]);
+ }
- return ret;
+ if (dict)
+ dict_unref(dict);
+
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
int
-cli_cmd_pmap_b2p_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_pmap_b2p_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;
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- if (wordcount != 4) {
- cli_usage_out (word->pattern);
- goto out;
- }
-
- ret = dict_set_str (dict, "brick", (char *)words[3]);
- if (ret)
- goto out;
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PMAP_PORTBYBRICK];
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+
+ if (wordcount != 4) {
+ cli_usage_out(word->pattern);
+ goto out;
+ }
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
+
+ ret = dict_set_str(dict, "brick", (char *)words[3]);
+ if (ret)
+ goto out;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PMAP_PORTBYBRICK];
+ if (proc->fn) {
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+ ret = proc->fn(frame, THIS, dict);
+ }
out:
- if (!proc && ret) {
- if (dict)
- dict_destroy (dict);
- if (wordcount > 1)
- cli_out ("Fetching spec for volume %s failed",
- (char *)words[3]);
- }
+ if (!proc && ret) {
+ if (wordcount > 1)
+ cli_out("Fetching spec for volume %s failed", (char *)words[3]);
+ }
+
+ if (dict)
+ dict_unref(dict);
- return ret;
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
int
-cli_cmd_fsm_log_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_fsm_log_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;
- char *name = "";
-
- if ((wordcount != 4) && (wordcount != 3)) {
- cli_usage_out (word->pattern);
- goto out;
- }
-
- if (wordcount == 4)
- name = (char*)words[3];
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_FSM_LOG];
- if (proc && proc->fn) {
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
- ret = proc->fn (frame, THIS, (void*)name);
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ char *name = "";
+
+ if ((wordcount != 4) && (wordcount != 3)) {
+ cli_usage_out(word->pattern);
+ goto out;
+ }
+
+ if (wordcount == 4)
+ name = (char *)words[3];
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_FSM_LOG];
+ if (proc && proc->fn) {
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+ ret = proc->fn(frame, THIS, (void *)name);
+ }
out:
- return ret;
+ return ret;
}
int
-cli_cmd_getwd_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_getwd_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;
-
- if (wordcount != 2) {
- cli_usage_out (word->pattern);
- goto out;
- }
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GETWD];
- if (proc && proc->fn) {
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
- ret = proc->fn (frame, THIS, NULL);
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+
+ if (wordcount != 2) {
+ cli_usage_out(word->pattern);
+ goto out;
+ }
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GETWD];
+ if (proc && proc->fn) {
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
+ ret = proc->fn(frame, THIS, NULL);
+ }
out:
- return ret;
+ return ret;
}
static dict_t *
-make_seq_dict (int argc, char **argv)
+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;
+ char index[] = "4294967296"; // 1<<32
+ int i = 0;
+ int len;
+ int ret = 0;
+ dict_t *dict = dict_new();
+
+ if (!dict)
+ return NULL;
+
+ for (i = 0; i < argc; i++) {
+ len = snprintf(index, sizeof(index), "%d", i);
+ ret = dict_set_strn(dict, index, len, argv[i]);
+ if (ret == -1)
+ break;
+ }
+
+ if (ret) {
+ dict_unref(dict);
+ dict = NULL;
+ }
+
+ return dict;
}
int
-cli_cmd_mount_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+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);
- }
+ 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);
+out:
+ if (dict)
+ dict_unref(dict);
- if (!proc && ret)
- cli_out ("Mount command failed");
+ if (!proc && ret)
+ cli_out("Mount command failed");
- return ret;
+ return ret;
}
int
-cli_cmd_umount_cbk (struct cli_state *state, struct cli_cmd_word *word,
+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;
+ 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) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame");
+ ret = -1;
+ goto out;
+ }
+ ret = proc->fn(frame, THIS, dict);
+ }
- 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);
+out:
+ if (dict)
+ dict_unref(dict);
- if (!proc && ret)
- cli_out ("Umount command failed");
+ if (!proc && ret)
+ cli_out("Umount command failed");
- return ret;
+ return ret;
}
int
-cli_cmd_uuid_get_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_uuid_get_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- int ret = -1;
- int sent = 0;
- int parse_error = 0;
- dict_t *dict = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- cli_local_t *local = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- if (wordcount != 3) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_UUID_GET];
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- goto out;
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- CLI_LOCAL_INIT (local, words, frame, dict);
- if (proc->fn)
- ret = proc->fn (frame, this, dict);
+ int ret = -1;
+ int sent = 0;
+ int parse_error = 0;
+ dict_t *dict = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ cli_local_t *local = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ if (wordcount != 3) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_UUID_GET];
+ frame = create_frame(this, this->ctx->pool);
+ if (!frame)
+ goto out;
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
+
+ CLI_LOCAL_INIT(local, words, frame, dict);
+ if (proc->fn)
+ ret = proc->fn(frame, this, dict);
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("uuid get failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("uuid get failed");
+ }
- if (dict)
- dict_unref (dict);
+ if (dict)
+ dict_unref(dict);
- CLI_STACK_DESTROY (frame);
- return ret;
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
int
-cli_cmd_uuid_reset_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_uuid_reset_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;
- gf_answer_t answer = GF_ANSWER_NO;
- char *question = NULL;
- cli_local_t *local = NULL;
- dict_t *dict = NULL;
- xlator_t *this = NULL;
-
- question = "Resetting uuid changes the uuid of local glusterd. "
- "Do you want to continue?";
-
- if (wordcount != 3) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_UUID_RESET];
-
- this = THIS;
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- goto out;
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
- CLI_LOCAL_INIT (local, words, frame, dict);
- answer = cli_cmd_get_confirmation (state, question);
-
- if (GF_ANSWER_NO == answer) {
- ret = 0;
- goto out;
- }
-
- //send NULL as argument since no dictionary is sent to glusterd
- if (proc->fn) {
- ret = proc->fn (frame, this, dict);
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ int sent = 0;
+ int parse_error = 0;
+ gf_answer_t answer = GF_ANSWER_NO;
+ char *question = NULL;
+ cli_local_t *local = NULL;
+ dict_t *dict = NULL;
+ xlator_t *this = NULL;
+
+ question =
+ "Resetting uuid changes the uuid of local glusterd. "
+ "Do you want to continue?";
+
+ if (wordcount != 3) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_UUID_RESET];
+
+ this = THIS;
+ frame = create_frame(this, this->ctx->pool);
+ if (!frame)
+ goto out;
+
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+ CLI_LOCAL_INIT(local, words, frame, dict);
+ answer = cli_cmd_get_confirmation(state, question);
+
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ goto out;
+ }
+
+ // send NULL as argument since no dictionary is sent to glusterd
+ if (proc->fn) {
+ ret = proc->fn(frame, this, dict);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("uuid reset failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("uuid reset failed");
+ }
+
+ if (dict)
+ dict_unref(dict);
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
-struct cli_cmd cli_system_cmds[] = {
- { "system:: getspec <VOLNAME>",
- cli_cmd_getspec_cbk,
- "fetch the volume file for the volume <VOLNAME>"},
+static struct cli_cmd cli_system_cmds[] = {
+ {"system:: getspec <VOLNAME>", cli_cmd_getspec_cbk,
+ "fetch the volume file for the volume <VOLNAME>"},
- { "system:: portmap brick2port <BRICK>",
- cli_cmd_pmap_b2p_cbk,
- "query which port <BRICK> listens on"},
+ {"system:: portmap brick2port <BRICK>", cli_cmd_pmap_b2p_cbk,
+ "query which port <BRICK> listens on"},
- { "system:: fsm log [<peer-name>]",
- cli_cmd_fsm_log_cbk,
- "display fsm transitions"},
+ {"system:: fsm log [<peer-name>]", cli_cmd_fsm_log_cbk,
+ "display fsm transitions"},
- { "system:: getwd",
- cli_cmd_getwd_cbk,
- "query glusterd work directory"},
+ {"system:: getwd", cli_cmd_getwd_cbk, "query glusterd work directory"},
- { "system:: mount <label> <args...>",
- cli_cmd_mount_cbk,
- "request a mount"},
+ {"system:: mount <label> <args...>", cli_cmd_mount_cbk, "request a mount"},
- { "system:: umount <path> [lazy]",
- cli_cmd_umount_cbk,
- "request an umount"},
+ {"system:: umount <path> [lazy]", cli_cmd_umount_cbk, "request an umount"},
- { "system:: uuid get",
- cli_cmd_uuid_get_cbk,
- "get uuid of glusterd"},
+ {"system:: uuid get", cli_cmd_uuid_get_cbk, "get uuid of glusterd"},
- { "system:: uuid reset",
- cli_cmd_uuid_reset_cbk,
- "reset the uuid of glusterd"},
+ {"system:: uuid reset", cli_cmd_uuid_reset_cbk,
+ "reset the uuid of glusterd"},
- { "system:: help",
- cli_cmd_system_help_cbk,
- "display help for system commands"},
+ {"system:: help", cli_cmd_system_help_cbk,
+ "display help for system commands"},
- { "system:: copy file [<filename>]",
- cli_cmd_copy_file_cbk,
- "Copy file from current node's $working_dir to "
- "$working_dir of all cluster nodes"},
+ {"system:: copy file [<filename>]", cli_cmd_copy_file_cbk,
+ "Copy file from current node's $working_dir to "
+ "$working_dir of all cluster nodes"},
- { "system:: execute <command> <args>",
- cli_cmd_sys_exec_cbk,
- "Execute the command on all the nodes "
- "in the cluster and display their output."},
+ {"system:: execute <command> <args>", cli_cmd_sys_exec_cbk,
+ "Execute the command on all the nodes "
+ "in the cluster and display their output."},
- { NULL, NULL, NULL }
-};
+ {NULL, NULL, NULL}};
int
-cli_cmd_sys_exec_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_sys_exec_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- char cmd_arg_name[PATH_MAX] = "";
- char *command = NULL;
- char *saveptr = NULL;
- char *tmp = NULL;
- int ret = -1;
- int i = -1;
- int cmd_args_count = 0;
- int in_cmd_args_count = 0;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- dict_t *dict = NULL;
- cli_local_t *local = NULL;
-
- if (wordcount < 3) {
- cli_usage_out (word->pattern);
- goto out;
- }
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- command = strtok_r ((char *)words[2], " ", &saveptr);
- do {
- tmp = strtok_r (NULL, " ", &saveptr);
- if (tmp) {
- in_cmd_args_count++;
- memset (cmd_arg_name, '\0', sizeof(cmd_arg_name));
- snprintf (cmd_arg_name, sizeof(cmd_arg_name),
- "cmd_arg_%d", in_cmd_args_count);
- ret = dict_set_str (dict, cmd_arg_name, tmp);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set "
- "%s in dict", cmd_arg_name);
- goto out;
- }
- }
- } while (tmp);
-
- cmd_args_count = wordcount - 3;
-
- ret = dict_set_str (dict, "command", command);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set command in dict");
+ char cmd_arg_name[PATH_MAX] = "";
+ char *command = NULL;
+ char *saveptr = NULL;
+ char *tmp = NULL;
+ int ret = -1;
+ int i = -1;
+ int len;
+ int cmd_args_count = 0;
+ int in_cmd_args_count = 0;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ cli_local_t *local = NULL;
+
+ if ((wordcount < 3) || (words[2] == NULL)) {
+ cli_usage_out(word->pattern);
+ goto out;
+ }
+
+ command = strtok_r((char *)words[2], " ", &saveptr);
+ if (command == NULL) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to parse command");
+ goto out;
+ }
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
+
+ do {
+ tmp = strtok_r(NULL, " ", &saveptr);
+ if (tmp) {
+ in_cmd_args_count++;
+ snprintf(cmd_arg_name, sizeof(cmd_arg_name), "cmd_arg_%d",
+ in_cmd_args_count);
+ ret = dict_set_str(dict, cmd_arg_name, tmp);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR,
+ "Unable to set "
+ "%s in dict",
+ cmd_arg_name);
goto out;
+ }
}
+ } while (tmp);
- for (i=1; i <= cmd_args_count; i++) {
- in_cmd_args_count++;
- memset (cmd_arg_name, '\0', sizeof(cmd_arg_name));
- snprintf (cmd_arg_name, sizeof(cmd_arg_name),
- "cmd_arg_%d", in_cmd_args_count);
- ret = dict_set_str (dict, cmd_arg_name,
- (char *)words[2+i]);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set %s in dict",
- cmd_arg_name);
- goto out;
- }
- }
+ cmd_args_count = wordcount - 3;
- ret = dict_set_int32 (dict, "cmd_args_count", in_cmd_args_count);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to set cmd_args_count in dict");
- goto out;
- }
+ ret = dict_set_str(dict, "command", command);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "Unable to set command in dict");
+ goto out;
+ }
- ret = dict_set_str (dict, "volname", "N/A");
+ for (i = 1; i <= cmd_args_count; i++) {
+ in_cmd_args_count++;
+ len = snprintf(cmd_arg_name, sizeof(cmd_arg_name), "cmd_arg_%d",
+ in_cmd_args_count);
+ ret = dict_set_strn(dict, cmd_arg_name, len, (char *)words[2 + i]);
if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set volname in dict");
- goto out;
- }
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SYS_EXEC];
- if (proc && proc->fn) {
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
- CLI_LOCAL_INIT (local, words, frame, dict);
- ret = proc->fn (frame, THIS, (void*)dict);
- }
+ gf_log("", GF_LOG_ERROR, "Unable to set %s in dict", cmd_arg_name);
+ goto out;
+ }
+ }
+
+ ret = dict_set_int32(dict, "cmd_args_count", in_cmd_args_count);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "Unable to set cmd_args_count in dict");
+ goto out;
+ }
+
+ ret = dict_set_str(dict, "volname", "N/A");
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "Unable to set volname in dict");
+ goto out;
+ }
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SYS_EXEC];
+ if (proc->fn) {
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame");
+ ret = -1;
+ goto out;
+ }
+ CLI_LOCAL_INIT(local, words, frame, dict);
+ ret = proc->fn(frame, THIS, (void *)dict);
+
+ /* proc->fn is processed synchronously, which means that the
+ * execution flow won't return here until the operation is
+ * fully processed, including any related callback. For this
+ * reason, it's safe to destroy the stack here, since no one
+ * can still be using it. Additionally, it's not easy to move
+ * the stack destroy to the callback executed after completion
+ * of the operation because there are multiple things than can
+ * fail even before having queued the callback, so we would
+ * still need to destroy the stack if proc->fn returns an
+ * error. */
+ CLI_STACK_DESTROY(frame);
+ dict = NULL;
+ }
out:
- return ret;
+ if (dict != NULL) {
+ dict_unref(dict);
+ }
+
+ return ret;
}
int
-cli_cmd_copy_file_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_copy_file_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;
- char *filename = "";
- dict_t *dict = NULL;
- cli_local_t *local = NULL;
-
- if (wordcount != 4) {
- cli_usage_out (word->pattern);
- goto out;
- }
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- filename = (char*)words[3];
- ret = dict_set_str (dict, "source", filename);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "Unable to set filename in dict");
-
- ret = dict_set_str (dict, "volname", "N/A");
- if (ret)
- gf_log ("", GF_LOG_ERROR, "Unable to set volname in dict");
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_COPY_FILE];
- if (proc && proc->fn) {
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
- CLI_LOCAL_INIT (local, words, frame, dict);
- ret = proc->fn (frame, THIS, (void*)dict);
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ char *filename = "";
+ dict_t *dict = NULL;
+ cli_local_t *local = NULL;
+
+ if (wordcount != 4) {
+ cli_usage_out(word->pattern);
+ goto out;
+ }
+
+ dict = dict_new();
+ if (!dict)
+ goto out;
+
+ filename = (char *)words[3];
+ ret = dict_set_str(dict, "source", filename);
+ if (ret)
+ gf_log("", GF_LOG_ERROR, "Unable to set filename in dict");
+
+ ret = dict_set_str(dict, "volname", "N/A");
+ if (ret)
+ gf_log("", GF_LOG_ERROR, "Unable to set volname in dict");
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_COPY_FILE];
+ if (proc && proc->fn) {
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame");
+ ret = -1;
+ goto out;
+ }
+ CLI_LOCAL_INIT(local, words, frame, dict);
+ ret = proc->fn(frame, THIS, (void *)dict);
+ }
out:
- return ret;
+ return ret;
}
int
-cli_cmd_system_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
- const char **words, int wordcount)
+cli_cmd_system_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount)
{
- struct cli_cmd *cmd = NULL;
+ struct cli_cmd *cmd = NULL;
+ struct cli_cmd *system_cmd = NULL;
+ int count = 0;
- for (cmd = cli_system_cmds; cmd->pattern; cmd++)
- cli_out ("%s - %s", cmd->pattern, cmd->desc);
+ cmd = GF_MALLOC(sizeof(cli_system_cmds), cli_mt_cli_cmd);
+ memcpy(cmd, cli_system_cmds, sizeof(cli_system_cmds));
+ count = (sizeof(cli_system_cmds) / sizeof(struct cli_cmd));
+ cli_cmd_sort(cmd, count);
- return 0;
+ for (system_cmd = cmd; system_cmd->pattern; system_cmd++)
+ cli_out("%s - %s", system_cmd->pattern, system_cmd->desc);
+
+ GF_FREE(cmd);
+ return 0;
}
int
-cli_cmd_system_register (struct cli_state *state)
+cli_cmd_system_register(struct cli_state *state)
{
- int ret = 0;
- struct cli_cmd *cmd = NULL;
-
- for (cmd = cli_system_cmds; cmd->pattern; cmd++) {
+ int ret = 0;
+ struct cli_cmd *cmd = NULL;
- ret = cli_cmd_register (&state->tree, cmd);
- if (ret)
- goto out;
- }
+ for (cmd = cli_system_cmds; cmd->pattern; cmd++) {
+ ret = cli_cmd_register(&state->tree, cmd);
+ if (ret)
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index ee9a09af4ba..f238851586e 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -23,1223 +23,1156 @@
#include "cli-cmd.h"
#include "cli-mem-types.h"
#include "cli1-xdr.h"
-#include "run.h"
-#include "syscall.h"
-#include "common-utils.h"
+#include <glusterfs/run.h>
+#include <glusterfs/syscall.h>
+#include <glusterfs/common-utils.h>
+#include <glusterfs/events.h>
-extern struct rpc_clnt *global_rpc;
-extern struct rpc_clnt *global_quotad_rpc;
-
-extern rpc_clnt_prog_t *cli_rpc_prog;
extern rpc_clnt_prog_t cli_quotad_clnt;
-int
-cli_cmd_volume_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
- const char **words, int wordcount);
+static int
+gf_asprintf_append(char **string_ptr, const char *format, ...);
int
-cli_cmd_volume_info_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;
- cli_cmd_volume_get_ctx_t ctx = {0,};
- cli_local_t *local = NULL;
- int sent = 0;
- int parse_error = 0;
+cli_cmd_volume_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount);
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_VOLUME];
+int
+cli_cmd_bitrot_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount);
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+int
+cli_cmd_quota_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount);
- if ((wordcount == 2) || (wordcount == 3 &&
- !strcmp (words[2], "all"))) {
- ctx.flags = GF_CLI_GET_NEXT_VOLUME;
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_NEXT_VOLUME];
- } else if (wordcount == 3) {
- ctx.flags = GF_CLI_GET_VOLUME;
- ctx.volname = (char *)words[2];
- if (strlen (ctx.volname) > GD_VOLUME_NAME_MAX) {
- cli_out ("Invalid volume name");
- goto out;
- }
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_VOLUME];
- } else {
- cli_usage_out (word->pattern);
- parse_error = 1;
- return -1;
+int
+cli_cmd_volume_info_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;
+ cli_cmd_volume_get_ctx_t ctx = {
+ 0,
+ };
+ cli_local_t *local = NULL;
+ int sent = 0;
+ int parse_error = 0;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_VOLUME];
+
+ if ((wordcount == 2) || (wordcount == 3 && !strcmp(words[2], "all"))) {
+ ctx.flags = GF_CLI_GET_NEXT_VOLUME;
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_NEXT_VOLUME];
+ } else if (wordcount == 3) {
+ ctx.flags = GF_CLI_GET_VOLUME;
+ ctx.volname = (char *)words[2];
+ if (strlen(ctx.volname) > GD_VOLUME_NAME_MAX) {
+ cli_out("Invalid volume name");
+ goto out;
}
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_VOLUME];
+ } else {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ return -1;
+ }
- local = cli_local_get ();
+ local = cli_local_get();
- if (!local)
- goto out;
+ if (!local)
+ goto out;
- local->get_vol.flags = ctx.flags;
- if (ctx.volname)
- local->get_vol.volname = gf_strdup (ctx.volname);
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame)
+ goto out;
- frame->local = local;
+ local->get_vol.flags = ctx.flags;
+ if (ctx.volname)
+ local->get_vol.volname = gf_strdup(ctx.volname);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, &ctx);
- }
+ frame->local = local;
-out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Getting Volume information failed!");
- }
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, &ctx);
+ }
- CLI_STACK_DESTROY (frame);
+out:
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Getting Volume information failed!");
+ }
- return ret;
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
int
-cli_cmd_sync_volume_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_sync_volume_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 *dict = NULL;
- cli_local_t *local = NULL;
- gf_answer_t answer = GF_ANSWER_NO;
- const char *question = "Sync volume may make data "
- "inaccessible while the sync "
- "is in progress. Do you want "
- "to continue?";
-
- if ((wordcount < 3) || (wordcount > 4)) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ int sent = 0;
+ int parse_error = 0;
+ dict_t *dict = NULL;
+ cli_local_t *local = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *question =
+ "Sync volume may make data "
+ "inaccessible while the sync "
+ "is in progress. Do you want "
+ "to continue?";
+
+ if ((wordcount < 3) || (wordcount > 4)) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- dict = dict_new ();
- if (!dict)
- goto out;
+ dict = dict_new();
+ if (!dict)
+ goto out;
- if ((wordcount == 3) || !strcmp(words[3], "all")) {
- 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 {
- ret = dict_set_str (dict, "volname", (char *) words[3]);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to set "
- "volume");
- goto out;
- }
+ if ((wordcount == 3) || !strcmp(words[3], "all")) {
+ 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;
}
-
- ret = dict_set_str (dict, "hostname", (char *) words[2]);
+ } else {
+ ret = dict_set_str(dict, "volname", (char *)words[3]);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to set hostname");
- goto out;
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "failed to set "
+ "volume");
+ goto out;
}
+ }
- if (!(state->mode & GLUSTER_MODE_SCRIPT)) {
- answer = cli_cmd_get_confirmation (state, question);
- if (GF_ANSWER_NO == answer) {
- ret = 0;
- goto out;
- }
+ ret = dict_set_str(dict, "hostname", (char *)words[2]);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to set hostname");
+ goto out;
+ }
+
+ if (!(state->mode & GLUSTER_MODE_SCRIPT)) {
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ goto out;
}
+ }
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SYNC_VOLUME];
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SYNC_VOLUME];
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame");
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, dict);
+ CLI_LOCAL_INIT(local, words, frame, dict);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
- }
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, dict);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume sync failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume sync failed");
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
int
-cli_cmd_volume_create_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_create_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;
- char *brick_list = NULL;
- int32_t brick_count = 0;
- int32_t sub_count = 0;
- int32_t type = GF_CLUSTER_TYPE_NONE;
- cli_local_t *local = NULL;
- char *trans_type = NULL;
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_CREATE_VOLUME];
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- ret = cli_cmd_volume_create_parse (state, words, wordcount, &options);
+ 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;
+ cli_local_t *local = NULL;
+ char *trans_type = NULL;
+ char *bricks = NULL;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_CREATE_VOLUME];
+
+ ret = cli_cmd_volume_create_parse(state, words, wordcount, &options,
+ &bricks);
+
+ if (ret) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ ret = dict_get_str(options, "transport", &trans_type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get transport type");
+ goto out;
+ }
- ret = dict_get_str (options, "transport", &trans_type);
+ if (state->mode & GLUSTER_MODE_WIGNORE) {
+ ret = dict_set_int32(options, "force", _gf_true);
if (ret) {
- gf_log("cli", GF_LOG_ERROR, "Unable to get transport type");
- goto out;
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to set force "
+ "option");
+ goto out;
}
+ }
- if (state->mode & GLUSTER_MODE_WIGNORE) {
- ret = dict_set_int32 (options, "force", _gf_true);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set force "
- "option");
- goto out;
- }
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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 create failed");
- }
-
- CLI_STACK_DESTROY (frame);
-
- return ret;
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume create failed");
+ }
+
+ if (ret == 0) {
+ gf_event(EVENT_VOLUME_CREATE, "name=%s;bricks=%s", (char *)words[2],
+ bricks);
+ }
+
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
-
int
-cli_cmd_volume_delete_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_delete_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;
- char *volname = NULL;
- gf_answer_t answer = GF_ANSWER_NO;
- const char *question = NULL;
- int sent = 0;
- int parse_error = 0;
- cli_local_t *local = NULL;
- dict_t *dict = NULL;
-
- question = "Deleting volume will erase all information about the volume. "
- "Do you want to continue?";
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DELETE_VOLUME];
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- if (wordcount != 3) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ char *volname = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+ const char *question = NULL;
+ int sent = 0;
+ int parse_error = 0;
+ cli_local_t *local = NULL;
+ dict_t *dict = NULL;
+
+ question =
+ "Deleting volume will erase all information about the volume. "
+ "Do you want to continue?";
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DELETE_VOLUME];
+
+ if (wordcount != 3) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- volname = (char *)words[2];
+ volname = (char *)words[2];
- ret = dict_set_str (dict, "volname", volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING, "dict set failed");
- goto out;
- }
+ dict = dict_new();
+ if (!dict)
+ goto out;
- if (!strcmp (volname, GLUSTER_SHARED_STORAGE)) {
- question = "Deleting the shared storage volume"
- "(gluster_shared_storage), will affect features "
- "like snapshot scheduler, geo-replication "
- "and NFS-Ganesha. Do you still want to "
- "continue?";
- }
+ ret = dict_set_str(dict, "volname", volname);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_WARNING, "dict set failed");
+ goto out;
+ }
+
+ if (!strcmp(volname, GLUSTER_SHARED_STORAGE)) {
+ question =
+ "Deleting the shared storage volume"
+ "(gluster_shared_storage), will affect features "
+ "like snapshot scheduler, geo-replication "
+ "and NFS-Ganesha. Do you still want to "
+ "continue?";
+ }
+
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ goto out;
+ }
- answer = cli_cmd_get_confirmation (state, question);
- if (GF_ANSWER_NO == answer) {
- ret = 0;
- goto out;
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, dict);
+ CLI_LOCAL_INIT(local, words, frame, dict);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
- }
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, dict);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume delete failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume delete failed");
+ }
+
+ CLI_STACK_DESTROY(frame);
- CLI_STACK_DESTROY (frame);
+ if (ret == 0 && GF_ANSWER_YES == answer) {
+ gf_event(EVENT_VOLUME_DELETE, "name=%s", (char *)words[2]);
+ }
- return ret;
+ return ret;
}
int
-cli_cmd_volume_start_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_start_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 *dict = NULL;
- int flags = 0;
- cli_local_t *local = NULL;
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ int sent = 0;
+ int parse_error = 0;
+ dict_t *dict = NULL;
+ int flags = 0;
+ cli_local_t *local = NULL;
+
+ if (wordcount < 3 || wordcount > 4) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- if (wordcount < 3 || wordcount > 4) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ if (!words[2])
+ goto out;
- dict = dict_new ();
- if (!dict) {
- 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;
}
+ }
- if (!words[2])
- goto out;
+ 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, "dict set failed");
- 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])) {
- 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) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "dict set failed");
- goto out;
- }
+ ret = dict_set_int32(dict, "flags", flags);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "dict set failed");
+ goto out;
+ }
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_START_VOLUME];
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_START_VOLUME];
- CLI_LOCAL_INIT (local, words, frame, dict);
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
- }
+ CLI_LOCAL_INIT(local, words, frame, dict);
+
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, dict);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume start failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume start failed");
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ if (ret == 0) {
+ gf_event(EVENT_VOLUME_START, "name=%s;force=%d", (char *)words[2],
+ (flags & GF_CLI_FLAG_OP_FORCE));
+ }
+
+ return ret;
}
gf_answer_t
-cli_cmd_get_confirmation (struct cli_state *state, const char *question)
+cli_cmd_get_confirmation(struct cli_state *state, const char *question)
{
- char answer[5] = {'\0', };
- char flush = '\0';
- size_t len;
+ char answer[5] = {
+ '\0',
+ };
+ int flush = '\0';
+ size_t len;
- if (state->mode & GLUSTER_MODE_SCRIPT)
- return GF_ANSWER_YES;
+ if (state->mode & GLUSTER_MODE_SCRIPT)
+ return GF_ANSWER_YES;
- printf ("%s (y/n) ", question);
+ printf("%s (y/n) ", question);
- if (fgets (answer, 4, stdin) == NULL) {
- cli_out("gluster cli read error");
- goto out;
- }
+ if (fgets(answer, 4, stdin) == NULL) {
+ cli_out("gluster cli read error");
+ goto out;
+ }
- len = strlen (answer);
+ len = strlen(answer);
- if (len && answer [len - 1] == '\n'){
- answer [--len] = '\0';
- } else {
- do{
- flush = getchar ();
- }while (flush != '\n');
- }
+ if (len && answer[len - 1] == '\n') {
+ answer[--len] = '\0';
+ } else {
+ do {
+ flush = getchar();
+ } while (flush != '\n');
+ }
- if (len > 3)
- goto out;
+ if (len > 3)
+ goto out;
- if (!strcasecmp (answer, "y") || !strcasecmp (answer, "yes"))
- return GF_ANSWER_YES;
+ if (!strcasecmp(answer, "y") || !strcasecmp(answer, "yes"))
+ return GF_ANSWER_YES;
- else if (!strcasecmp (answer, "n") || !strcasecmp (answer, "no"))
- return GF_ANSWER_NO;
+ else if (!strcasecmp(answer, "n") || !strcasecmp(answer, "no"))
+ return GF_ANSWER_NO;
out:
- cli_out ("Invalid input, please enter y/n");
+ cli_out("Invalid input, please enter y/n");
- return GF_ANSWER_NO;
+ return GF_ANSWER_NO;
}
int
-cli_cmd_volume_stop_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_stop_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 flags = 0;
- gf_answer_t answer = GF_ANSWER_NO;
- int sent = 0;
- int parse_error = 0;
- dict_t *dict = NULL;
- char *volname = NULL;
- cli_local_t *local = NULL;
-
- const char *question = "Stopping volume will make its data inaccessible. "
- "Do you want to continue?";
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- if (wordcount < 3 || wordcount > 4) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- volname = (char*) words[2];
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ int flags = 0;
+ gf_answer_t answer = GF_ANSWER_NO;
+ int sent = 0;
+ int parse_error = 0;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ cli_local_t *local = NULL;
+
+ const char *question =
+ "Stopping volume will make its data inaccessible. "
+ "Do you want to continue?";
+
+ if (wordcount < 3 || wordcount > 4) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- dict = dict_new ();
- ret = dict_set_str (dict, "volname", volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "dict set failed");
- goto out;
- }
+ volname = (char *)words[2];
- if (!strcmp (volname, GLUSTER_SHARED_STORAGE)) {
- question = "Stopping the shared storage volume"
- "(gluster_shared_storage), will affect features "
- "like snapshot scheduler, geo-replication "
- "and NFS-Ganesha. Do you still want to "
- "continue?";
+ 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 (!strcmp(volname, GLUSTER_SHARED_STORAGE)) {
+ question =
+ "Stopping the shared storage volume"
+ "(gluster_shared_storage), will affect features "
+ "like snapshot scheduler, geo-replication "
+ "and NFS-Ganesha. Do you still want to "
+ "continue?";
+ }
+
+ 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;
}
+ }
- 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) {
+ gf_log(THIS->name, GF_LOG_ERROR, "dict set failed");
+ 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);
- answer = cli_cmd_get_confirmation (state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ goto out;
+ }
- if (GF_ANSWER_NO == answer) {
- ret = 0;
- goto out;
- }
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STOP_VOLUME];
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STOP_VOLUME];
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, dict);
+ CLI_LOCAL_INIT(local, words, frame, dict);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
- }
+ if (proc->fn) {
+ 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 on '%s' failed", volname);
- }
-
- CLI_STACK_DESTROY (frame);
-
- return ret;
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume stop on '%s' failed", volname);
+ }
+
+ CLI_STACK_DESTROY(frame);
+ if (dict)
+ dict_unref(dict);
+
+ if (ret == 0 && GF_ANSWER_YES == answer) {
+ gf_event(EVENT_VOLUME_STOP, "name=%s;force=%d", (char *)words[2],
+ (flags & GF_CLI_FLAG_OP_FORCE));
+ }
+
+ return ret;
}
-
int
-cli_cmd_volume_rename_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_rename_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;
- int sent = 0;
- int parse_error = 0;
-
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- dict = dict_new ();
- if (!dict)
- goto out;
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ int sent = 0;
+ int parse_error = 0;
+
+ if (wordcount != 4) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- if (wordcount != 4) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ dict = dict_new();
+ if (!dict)
+ goto out;
- ret = dict_set_str (dict, "old-volname", (char *)words[2]);
+ ret = dict_set_str(dict, "old-volname", (char *)words[2]);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- ret = dict_set_str (dict, "new-volname", (char *)words[3]);
+ ret = dict_set_str(dict, "new-volname", (char *)words[3]);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RENAME_VOLUME];
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RENAME_VOLUME];
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
+ if (proc->fn) {
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
}
+ ret = proc->fn(frame, THIS, dict);
+ }
out:
- if (dict)
- dict_destroy (dict);
+ if (dict)
+ dict_unref(dict);
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume rename on '%s' failed", (char *)words[2]);
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume rename on '%s' failed", (char *)words[2]);
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
int
-cli_cmd_volume_defrag_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_defrag_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;
- int sent = 0;
- int parse_error = 0;
- cli_local_t *local = NULL;
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ int sent = 0;
+ int parse_error = 0;
+ cli_local_t *local = NULL;
+#if (USE_EVENTS)
+ eventtypes_t event = EVENT_LAST;
+#endif
+
#ifdef GF_SOLARIS_HOST_OS
- cli_out ("Command not supported on Solaris");
- goto out;
+ cli_out("Command not supported on Solaris");
+ goto out;
#endif
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ ret = cli_cmd_volume_defrag_parse(words, wordcount, &dict);
- ret = cli_cmd_volume_defrag_parse (words, wordcount, &dict);
+ if (ret) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ }
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- }
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DEFRAG_VOLUME];
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_DEFRAG_VOLUME];
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, dict);
+ CLI_LOCAL_INIT(local, words, frame, dict);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, dict);
- }
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, dict);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume rebalance failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume rebalance failed");
+ } else {
+#if (USE_EVENTS)
+ if (!(strcmp(words[wordcount - 1], "start")) ||
+ !(strcmp(words[wordcount - 1], "force"))) {
+ event = EVENT_VOLUME_REBALANCE_START;
+ } else if (!strcmp(words[wordcount - 1], "stop")) {
+ event = EVENT_VOLUME_REBALANCE_STOP;
+ }
+
+ if (event != EVENT_LAST)
+ gf_event(event, "volume=%s", (char *)words[2]);
+#endif
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
int
-cli_cmd_volume_reset_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_reset_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- int sent = 0;
- int parse_error = 0;
- int ret = -1;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- dict_t *options = NULL;
- cli_local_t *local = NULL;
+ int sent = 0;
+ int parse_error = 0;
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+ cli_local_t *local = NULL;
+#if (USE_EVENTS)
+ int ret1 = -1;
+ char *tmp_opt = NULL;
+#endif
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RESET_VOLUME];
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RESET_VOLUME];
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ ret = cli_cmd_volume_reset_parse(words, wordcount, &options);
+ if (ret) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- ret = cli_cmd_volume_reset_parse (words, wordcount, &options);
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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 reset failed");
- }
-
- CLI_STACK_DESTROY (frame);
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume reset failed");
+ }
+
+#if (USE_EVENTS)
+ if (ret == 0) {
+ ret1 = dict_get_str(options, "key", &tmp_opt);
+ if (ret1)
+ tmp_opt = "";
+
+ gf_event(EVENT_VOLUME_RESET, "name=%s;option=%s", (char *)words[2],
+ tmp_opt);
+ }
+#endif
- return ret;
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
int
-cli_cmd_volume_profile_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_profile_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- int sent = 0;
- int parse_error = 0;
+ int sent = 0;
+ int parse_error = 0;
- int ret = -1;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- dict_t *options = NULL;
- cli_local_t *local = NULL;
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+ cli_local_t *local = NULL;
- ret = cli_cmd_volume_profile_parse (words, wordcount, &options);
+ ret = cli_cmd_volume_profile_parse(words, wordcount, &options);
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ if (ret) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PROFILE_VOLUME];
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_PROFILE_VOLUME];
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame");
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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 profile failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume profile failed");
+ }
- CLI_STACK_DESTROY (frame);
-
- return ret;
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
int
-cli_cmd_volume_set_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_set_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- int sent = 0;
- int parse_error = 0;
+ int sent = 0;
+ int parse_error = 0;
+
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+ cli_local_t *local = NULL;
+ char *op_errstr = NULL;
+
+#if (USE_EVENTS)
+ int ret1 = -1;
+ int i = 1;
+ char dict_key[50] = {
+ 0,
+ };
+ char *tmp_opt = NULL;
+ char *opts_str = NULL;
+ int num_options = 0;
+#endif
- int ret = -1;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- dict_t *options = NULL;
- cli_local_t *local = NULL;
- char *op_errstr = NULL;
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SET_VOLUME];
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_SET_VOLUME];
+ ret = cli_cmd_volume_set_parse(state, words, wordcount, &options,
+ &op_errstr);
+ if (ret) {
+ if (op_errstr) {
+ cli_err("%s", op_errstr);
+ GF_FREE(op_errstr);
+ } else
+ cli_usage_out(word->pattern);
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- ret = cli_cmd_volume_set_parse (state, words, wordcount,
- &options, &op_errstr);
- if (ret) {
- if (op_errstr) {
- cli_err ("%s", op_errstr);
- GF_FREE (op_errstr);
- } else
- cli_usage_out (word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- parse_error = 1;
- goto out;
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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 set failed");
- }
-
- CLI_STACK_DESTROY (frame);
-
- return ret;
-
-}
-
-int
-cli_cmd_volume_add_brick_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;
- gf_answer_t answer = GF_ANSWER_NO;
- cli_local_t *local = NULL;
-
- 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)
- goto out;
-
- ret = cli_cmd_volume_add_brick_parse (words, wordcount, &options, 0);
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- /* TODO: there are challenges in supporting changing of
- stripe-count, until 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;
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume set failed");
+ }
+
+#if (USE_EVENTS)
+ if (ret == 0 && strcmp(words[2], "help") != 0) {
+ ret1 = dict_get_int32(options, "count", &num_options);
+ if (ret1) {
+ num_options = 0;
+ goto end;
+ } else {
+ num_options = num_options / 2;
}
- if (state->mode & GLUSTER_MODE_WIGNORE) {
- ret = dict_set_int32 (options, "force", _gf_true);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set force "
- "option");
- goto out;
- }
+ char *free_list_key[num_options];
+ char *free_list_val[num_options];
+ for (i = 0; i < num_options; i++) {
+ free_list_key[i] = NULL;
+ free_list_val[i] = NULL;
}
+ /* Initialize opts_str */
+ opts_str = "";
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_ADD_BRICK];
+ /* Prepare String in format options=KEY1,VALUE1,KEY2,VALUE2 */
+ for (i = 1; i <= num_options; i++) {
+ sprintf(dict_key, "key%d", i);
+ ret1 = dict_get_str(options, dict_key, &tmp_opt);
+ if (ret1)
+ tmp_opt = "";
- CLI_LOCAL_INIT (local, words, frame, options);
+ gf_asprintf(&opts_str, "%s,%s", opts_str, tmp_opt);
+ free_list_key[i - 1] = opts_str;
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ sprintf(dict_key, "value%d", i);
+ ret1 = dict_get_str(options, dict_key, &tmp_opt);
+ if (ret1)
+ tmp_opt = "";
-out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume add-brick failed");
+ gf_asprintf(&opts_str, "%s,%s", opts_str, tmp_opt);
+ free_list_val[i - 1] = opts_str;
}
- CLI_STACK_DESTROY (frame);
-
- return ret;
-}
-
-int
-cli_tier_validate_replica_type (dict_t *dict, int type)
-{
-
- int brick_count = -1;
- int replica_count = 1;
- int ret = -1;
+ gf_event(EVENT_VOLUME_SET, "name=%s;options=%s", (char *)words[2],
+ opts_str);
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get brick count");
- goto out;
+ /* Allocated by gf_strdup and gf_asprintf */
+ for (i = 0; i < num_options; i++) {
+ GF_FREE(free_list_key[i]);
+ GF_FREE(free_list_val[i]);
}
+ }
+#endif
- ret = dict_get_int32 (dict, "replica-count", &replica_count);
- if (ret) {
- gf_log ("cli", GF_LOG_DEBUG, "Failed to get replica count. "
- "Defaulting to one");
- replica_count = 1;
- }
+end:
+ CLI_STACK_DESTROY(frame);
- /*
- * Change the calculation of sub_count once attach-tier support
- * disperse volume.
- * sub_count = disperse_count for disperse volume
- * */
-
-
- if (brick_count % replica_count) {
- if (type == GF_CLUSTER_TYPE_REPLICATE)
- cli_err ("number of bricks is not a multiple of "
- "replica count");
- else if (type == GF_CLUSTER_TYPE_DISPERSE)
- cli_err ("number of bricks is not a multiple of "
- "disperse count");
- else
- cli_err ("number of bricks given doesn't match "
- "required count");
-
- ret = -1;
- goto out;
- }
- ret = 0;
-out:
- return ret;
+ return ret;
}
-int
-do_cli_cmd_volume_attach_tier (struct cli_state *state,
- struct cli_cmd_word *word, const char **words,
- int wordcount)
+static int
+cli_event_remove_brick_str(dict_t *options, char **event_str,
+ eventtypes_t *event)
{
- 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;
- cli_local_t *local = NULL;
- int type = 0;
- char *question = "Attach tier is recommended only "
- "for testing purposes in this "
- "release. Do you want to continue?";
- gf_answer_t answer = GF_ANSWER_NO;
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- answer = cli_cmd_get_confirmation (state, question);
- if (GF_ANSWER_NO == answer) {
- ret = 0;
- goto out;
- }
-
- ret = cli_cmd_volume_add_brick_parse (words, wordcount, &options, &type);
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- /*
- * Merge this check when attach-tier has it's own cli parse function.
- */
- ret = cli_tier_validate_replica_type (options, type);
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- if (state->mode & GLUSTER_MODE_WIGNORE) {
- ret = dict_set_int32 (options, "force", _gf_true);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set force "
- "option");
- goto out;
- }
- }
-
- ret = dict_set_int32 (options, "attach-tier", 1);
- if (ret)
- goto out;
-
- ret = dict_set_int32 (options, "hot-type", type);
- if (ret)
- goto out;
+ int ret = -1;
+ char *bricklist = NULL;
+ char *brick = NULL;
+ char *volname = NULL;
+ char key[256] = {
+ 0,
+ };
+ const char *eventstrformat = "volume=%s;bricks=%s";
+ int32_t command = 0;
+ int32_t i = 1;
+ int32_t count = 0;
+ int32_t eventstrlen = 1;
+ int bricklen = 0;
+ char *tmp_ptr = NULL;
+
+ if (!options || !event_str || !event)
+ goto out;
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_ATTACH_TIER];
+ ret = dict_get_str(options, "volname", &volname);
+ if (ret || !volname) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to fetch volname");
+ ret = -1;
+ goto out;
+ }
+ /* Get the list of bricks for the event */
+ ret = dict_get_int32(options, "command", &command);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to fetch command");
+ ret = -1;
+ goto out;
+ }
+
+ switch (command) {
+ case GF_OP_CMD_START:
+ *event = EVENT_VOLUME_REMOVE_BRICK_START;
+ break;
+ case GF_OP_CMD_COMMIT:
+ *event = EVENT_VOLUME_REMOVE_BRICK_COMMIT;
+ break;
+ case GF_OP_CMD_COMMIT_FORCE:
+ *event = EVENT_VOLUME_REMOVE_BRICK_FORCE;
+ break;
+ case GF_OP_CMD_STOP:
+ *event = EVENT_VOLUME_REMOVE_BRICK_STOP;
+ break;
+ default:
+ *event = EVENT_LAST;
+ break;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ ret = -1;
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ if (*event == EVENT_LAST) {
+ goto out;
+ }
-out:
+ /* I could just get this from words[] but this is cleaner in case the
+ * format changes */
+ while (i) {
+ snprintf(key, sizeof(key), "brick%d", i);
+ ret = dict_get_str(options, key, &brick);
if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("attach-tier failed");
+ break;
}
+ eventstrlen += strlen(brick) + 1;
+ i++;
+ }
- CLI_STACK_DESTROY (frame);
+ count = --i;
- return ret;
-}
+ eventstrlen += 1;
-int
-do_cli_cmd_volume_detach_tier (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;
- gf_answer_t answer = GF_ANSWER_NO;
- cli_local_t *local = NULL;
- int need_question = 0;
-
- const char *question = "Removing tier can result in data loss. "
- "Do you want to Continue?";
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- ret = cli_cmd_volume_detach_tier_parse(words, wordcount, &options);
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
-
- ret = dict_set_int32 (options, "force", 1);
- if (ret)
- goto out;
-
- ret = dict_set_int32 (options, "count", 0);
- if (ret)
- 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_DETACH_TIER];
-
- CLI_LOCAL_INIT (local, words, frame, options);
+ bricklist = GF_CALLOC(eventstrlen, sizeof(char), gf_common_mt_char);
+ if (!bricklist) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "memory allocation failed for"
+ "bricklist");
+ ret = -1;
+ goto out;
+ }
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ tmp_ptr = bricklist;
-out:
+ i = 1;
+ while (i <= count) {
+ snprintf(key, sizeof(key), "brick%d", i);
+ ret = dict_get_str(options, key, &brick);
if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_error == 0))
- cli_out ("Volume detach-tier failed");
+ break;
}
+ snprintf(tmp_ptr, eventstrlen, "%s ", brick);
+ bricklen = strlen(brick);
+ eventstrlen -= (bricklen + 1);
+ tmp_ptr += (bricklen + 1);
+ i++;
+ }
- CLI_STACK_DESTROY (frame);
+ if (!ret) {
+ gf_asprintf(event_str, eventstrformat, volname, bricklist);
+ } else {
+ gf_asprintf(event_str, eventstrformat, volname, "<unavailable>");
+ }
- return ret;
+ ret = 0;
+out:
+ GF_FREE(bricklist);
+ return ret;
}
int
-cli_cmd_volume_tier_cbk (struct cli_state *state,
- struct cli_cmd_word *word, const char **words,
- int wordcount)
+cli_cmd_volume_add_brick_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- int ret = -1;
- call_frame_t *frame = NULL;
- dict_t *options = NULL;
- char *volname = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- cli_local_t *local = NULL;
- int i = 0;
-
- if (wordcount < 4) {
- cli_usage_out (word->pattern);
- goto out;
- }
-
- if (!strcmp(words[1], "detach-tier")) {
- ret = do_cli_cmd_volume_detach_tier (state, word,
- words, wordcount);
- goto out;
- } else if (!strcmp(words[3], "detach")) {
- for (i = 3; i < wordcount; i++)
- words[i] = words[i+1];
-
- ret = do_cli_cmd_volume_detach_tier (state, word,
- words, wordcount-1);
- goto out;
+ 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;
+ gf_answer_t answer = GF_ANSWER_NO;
+ cli_local_t *local = NULL;
+
+#if (USE_EVENTS)
+ char *event_str = NULL;
+ char *bricks = NULL;
+ const char *eventstrformat = "volume=%s;bricks=%s";
+#endif
- } else if (!strcmp(words[1], "attach-tier")) {
- ret = do_cli_cmd_volume_attach_tier (state, word,
- words, wordcount);
- goto out;
- } else if (!strcmp(words[3], "attach")) {
- for (i = 3; i < wordcount; i++)
- words[i] = words[i+1];
+ 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 ? ";
+
+ ret = cli_cmd_volume_add_brick_parse(state, words, wordcount, &options, 0);
+ if (ret) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- ret = do_cli_cmd_volume_attach_tier (state, word,
- words, wordcount-1);
- goto out;
- }
+ /* TODO: there are challenges in supporting changing of
+ stripe-count, until it is properly supported give warning to user */
+ if (dict_get(options, "stripe-count")) {
+ answer = cli_cmd_get_confirmation(state, question);
- ret = cli_cmd_volume_tier_parse (words, wordcount, &options);
- if (ret) {
- cli_usage_out (word->pattern);
- goto out;
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ goto out;
}
+ }
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_TIER];
+#if (USE_EVENTS)
+ /* Get the list of bricks for the event */
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ ret = dict_get_str(options, "bricks", &bricks);
- CLI_LOCAL_INIT (local, words, frame, options);
-
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ if (!ret) {
+ gf_asprintf(&event_str, eventstrformat, (char *)words[2],
+ &bricks[1] /*Skip leading space*/);
+ } else {
+ gf_asprintf(&event_str, eventstrformat, (char *)words[2],
+ "<unavailable>");
+ }
+#endif
-out:
+ if (state->mode & GLUSTER_MODE_WIGNORE) {
+ ret = dict_set_int32(options, "force", _gf_true);
if (ret) {
- cli_out ("Tier command failed");
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to set force "
+ "option");
+ goto out;
}
- if (options)
- dict_unref (options);
-
- return ret;
-}
+ }
-static int
-gf_cli_create_auxiliary_mount (char *volname)
-{
- int ret = -1;
- char mountdir[PATH_MAX] = {0,};
- char pidfile_path[PATH_MAX] = {0,};
- char logfile[PATH_MAX] = {0,};
- char qpid [16] = {0,};
-
- GLUSTERFS_GET_AUX_MOUNT_PIDFILE (pidfile_path, volname);
-
- if (gf_is_service_running (pidfile_path, NULL)) {
- gf_log ("cli", GF_LOG_DEBUG, "Aux mount of volume %s is running"
- " already", volname);
- ret = 0;
- goto out;
- }
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_ADD_BRICK];
- GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, "/");
- ret = mkdir (mountdir, 0777);
- if (ret && errno != EEXIST) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create auxiliary mount "
- "directory %s. Reason : %s", mountdir,
- strerror (errno));
- goto out;
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- snprintf (logfile, PATH_MAX-1, "%s/quota-mount-%s.log",
- DEFAULT_LOG_FILE_DIRECTORY, volname);
- snprintf(qpid, 15, "%d", GF_CLIENT_PID_QUOTA_MOUNT);
+ CLI_LOCAL_INIT(local, words, frame, options);
- ret = runcmd (SBIN_DIR"/glusterfs",
- "-s", "localhost",
- "--volfile-id", volname,
- "-l", logfile,
- "-p", pidfile_path,
- "--client-pid", qpid,
- mountdir,
- NULL);
-
- if (ret) {
- gf_log ("cli", GF_LOG_WARNING, "failed to mount glusterfs "
- "client. Please check the log file %s for more details",
- logfile);
- ret = -1;
- goto out;
- }
-
- ret = 0;
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, options);
+ }
out:
- return ret;
-}
-
-static int
-cli_stage_quota_op (char *volname, int op_code)
-{
- int ret = -1;
-
- switch (op_code) {
- case GF_QUOTA_OPTION_TYPE_ENABLE:
- case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE:
- case GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS:
- case GF_QUOTA_OPTION_TYPE_REMOVE:
- case GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS:
- case GF_QUOTA_OPTION_TYPE_LIST:
- ret = gf_cli_create_auxiliary_mount (volname);
- if (ret) {
- cli_err ("quota: Could not start quota "
- "auxiliary mount");
- goto out;
- }
- ret = 0;
- break;
-
- default:
- ret = 0;
- break;
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume add-brick failed");
+ } else {
+#if (USE_EVENTS)
+ gf_event(EVENT_VOLUME_ADD_BRICK, "%s", event_str);
+#endif
+ }
+#if (USE_EVENTS)
+ GF_FREE(event_str);
+#endif
-out:
- return ret;
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
int
-cli_get_soft_limit (dict_t *options, const char **words, dict_t *xdata)
+cli_get_soft_limit(dict_t *options, const char **words, dict_t *xdata)
{
- call_frame_t *frame = NULL;
- cli_local_t *local = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- char *default_sl = NULL;
- char *default_sl_dup = NULL;
- int ret = -1;
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame) {
- ret = -1;
- goto out;
- }
-
- //We need a ref on @options to prevent CLI_STACK_DESTROY
- //from destroying it prematurely.
- dict_ref (options);
- CLI_LOCAL_INIT (local, words, frame, options);
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_QUOTA];
- ret = proc->fn (frame, THIS, options);
-
- ret = dict_get_str (options, "default-soft-limit", &default_sl);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get default soft limit");
- goto out;
- }
+ call_frame_t *frame = NULL;
+ cli_local_t *local = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ char *default_sl = NULL;
+ char *default_sl_dup = NULL;
+ int ret = -1;
+
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ // We need a ref on @options to prevent CLI_STACK_DESTROY
+ // from destroying it prematurely.
+ dict_ref(options);
+ CLI_LOCAL_INIT(local, words, frame, options);
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_QUOTA];
+ ret = proc->fn(frame, THIS, options);
+
+ ret = dict_get_str(options, "default-soft-limit", &default_sl);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get default soft limit");
+ goto out;
+ }
- default_sl_dup = gf_strdup (default_sl);
- if (!default_sl_dup) {
- ret = -1;
- goto out;
- }
+ default_sl_dup = gf_strdup(default_sl);
+ if (!default_sl_dup) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_set_dynstr (xdata, "default-soft-limit", default_sl_dup);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set default soft limit");
- GF_FREE (default_sl_dup);
- goto out;
- }
+ ret = dict_set_dynstr(xdata, "default-soft-limit", default_sl_dup);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to set default soft limit");
+ GF_FREE(default_sl_dup);
+ goto out;
+ }
out:
- CLI_STACK_DESTROY (frame);
- return ret;
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
/* Checks if at least one limit has been set on the volume
@@ -1247,1582 +1180,2099 @@ out:
* Returns true if at least one limit is set. Returns false otherwise.
*/
gf_boolean_t
-_limits_set_on_volume (char *volname, int type) {
- gf_boolean_t limits_set = _gf_false;
- int ret = -1;
- char quota_conf_file[PATH_MAX] = {0,};
- int fd = -1;
- char buf[16] = {0,};
- float version = 0.0f;
- char gfid_type_stored = 0;
- char gfid_type = 0;
-
- /* TODO: fix hardcoding; Need to perform an RPC call to glusterd
- * to fetch working directory
- */
- sprintf (quota_conf_file, "%s/vols/%s/quota.conf",
- GLUSTERD_DEFAULT_WORKDIR,
- volname);
- fd = open (quota_conf_file, O_RDONLY);
- if (fd == -1)
- goto out;
+_limits_set_on_volume(char *volname, int type)
+{
+ gf_boolean_t limits_set = _gf_false;
+ int ret = -1;
+ char quota_conf_file[PATH_MAX] = {
+ 0,
+ };
+ int fd = -1;
+ char buf[16] = {
+ 0,
+ };
+ float version = 0.0f;
+ char gfid_type_stored = 0;
+ char gfid_type = 0;
+
+ /* TODO: fix hardcoding; Need to perform an RPC call to glusterd
+ * to fetch working directory
+ */
+ snprintf(quota_conf_file, sizeof quota_conf_file, "%s/vols/%s/quota.conf",
+ GLUSTERD_DEFAULT_WORKDIR, volname);
+ fd = open(quota_conf_file, O_RDONLY);
+ if (fd == -1)
+ goto out;
- ret = quota_conf_read_version (fd, &version);
- if (ret)
- goto out;
+ ret = quota_conf_read_version(fd, &version);
+ if (ret)
+ goto out;
- if (type == GF_QUOTA_OPTION_TYPE_LIST)
- gfid_type = GF_QUOTA_CONF_TYPE_USAGE;
- else
- gfid_type = GF_QUOTA_CONF_TYPE_OBJECTS;
-
- /* Try to read atleast one gfid of type 'gfid_type' */
- while (1) {
- ret = quota_conf_read_gfid (fd, buf, &gfid_type_stored,
- version);
- if (ret <= 0)
- break;
-
- if (gfid_type_stored == gfid_type) {
- limits_set = _gf_true;
- break;
- }
+ if (type == GF_QUOTA_OPTION_TYPE_LIST)
+ gfid_type = GF_QUOTA_CONF_TYPE_USAGE;
+ else
+ gfid_type = GF_QUOTA_CONF_TYPE_OBJECTS;
+
+ /* Try to read at least one gfid of type 'gfid_type' */
+ while (1) {
+ ret = quota_conf_read_gfid(fd, buf, &gfid_type_stored, version);
+ if (ret <= 0)
+ break;
+
+ if (gfid_type_stored == gfid_type) {
+ limits_set = _gf_true;
+ break;
}
+ }
out:
- if (fd != -1)
- close (fd);
+ if (fd != -1)
+ sys_close(fd);
- return limits_set;
+ return limits_set;
}
-/* Checks if the mount is connected to the bricks
- *
- * Returns true if connected and false if not
- */
-gf_boolean_t
-_quota_aux_mount_online (char *volname)
+int
+cli_cmd_quota_handle_list_all(const char **words, dict_t *options)
{
- int ret = 0;
- char mount_path[PATH_MAX + 1] = {0,};
- struct stat buf = {0,};
+ int all_failed = 1;
+ int count = 0;
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ cli_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *xdata = NULL;
+ char gfid_str[UUID_CANONICAL_FORM_LEN + 1];
+ char *volname = NULL;
+ char *volname_dup = NULL;
+ unsigned char buf[16] = {0};
+ int fd = -1;
+ char quota_conf_file[PATH_MAX] = {0};
+ gf_boolean_t xml_err_flag = _gf_false;
+ char err_str[NAME_MAX] = {
+ 0,
+ };
+ int32_t type = 0;
+ char gfid_type = 0;
+ float version = 0.0f;
+ int32_t max_count = 0;
+
+ xdata = dict_new();
+ if (!xdata) {
+ ret = -1;
+ goto out;
+ }
- GF_ASSERT (volname);
+ ret = dict_get_str(options, "volname", &volname);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get volume name");
+ goto out;
+ }
- /* Try to create the aux mount before checking if bricks are online */
- ret = gf_cli_create_auxiliary_mount (volname);
- if (ret) {
- cli_err ("quota: Could not start quota auxiliary mount");
- return _gf_false;
- }
+ ret = dict_get_int32(options, "type", &type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get quota option type");
+ goto out;
+ }
- GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mount_path, volname, "/");
+ ret = dict_set_int32(xdata, "type", type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to set type in xdata");
+ goto out;
+ }
- ret = sys_stat (mount_path, &buf);
- if (ret) {
- if (ENOTCONN == errno) {
- cli_err ("quota: Cannot connect to bricks. Check if "
- "bricks are online.");
- } else {
- cli_err ("quota: Error on quota auxiliary mount (%s).",
- strerror (errno));
- }
- return _gf_false;
+ ret = cli_get_soft_limit(options, words, xdata);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to fetch default "
+ "soft-limit");
+ goto out;
+ }
+
+ /* Check if at least one limit is set on volume. No need to check for
+ * quota enabled as cli_get_soft_limit() handles that
+ */
+ if (!_limits_set_on_volume(volname, type)) {
+ snprintf(err_str, sizeof(err_str),
+ "No%s quota configured on"
+ " volume %s",
+ (type == GF_QUOTA_OPTION_TYPE_LIST) ? "" : " inode", volname);
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ xml_err_flag = _gf_true;
+ } else {
+ cli_out("quota: %s", err_str);
}
- return _gf_true;
-}
+ ret = 0;
+ goto out;
+ }
-int
-cli_cmd_quota_handle_list_all (const char **words, dict_t *options)
-{
- int all_failed = 1;
- int count = 0;
- int ret = -1;
- rpc_clnt_procedure_t *proc = NULL;
- cli_local_t *local = NULL;
- call_frame_t *frame = NULL;
- dict_t *xdata = NULL;
- char *gfid_str = NULL;
- char *volname = NULL;
- char *volname_dup = NULL;
- unsigned char buf[16] = {0};
- int fd = -1;
- char quota_conf_file[PATH_MAX] = {0};
- gf_boolean_t xml_err_flag = _gf_false;
- char err_str[NAME_MAX] = {0,};
- int32_t type = 0;
- char gfid_type = 0;
- float version = 0.0f;
-
- xdata = dict_new ();
- if (!xdata) {
- ret = -1;
- goto out;
- }
+ volname_dup = gf_strdup(volname);
+ if (!volname_dup) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_get_str (options, "volname", &volname);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get volume name");
- goto out;
- }
+ ret = dict_set_dynstr(xdata, "volume-uuid", volname_dup);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to set volume-uuid");
+ GF_FREE(volname_dup);
+ goto out;
+ }
+
+ // TODO: fix hardcoding; Need to perform an RPC call to glusterd
+ // to fetch working directory
+ snprintf(quota_conf_file, sizeof quota_conf_file, "%s/vols/%s/quota.conf",
+ GLUSTERD_DEFAULT_WORKDIR, volname);
+ fd = open(quota_conf_file, O_RDONLY);
+ if (fd == -1) {
+ // This may because no limits were yet set on the volume
+ gf_log("cli", GF_LOG_TRACE,
+ "Unable to open "
+ "quota.conf");
+ ret = 0;
+ goto out;
+ }
- ret = dict_get_int32 (options, "type", &type);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get quota option type");
- goto out;
- }
+ ret = quota_conf_read_version(fd, &version);
+ if (ret)
+ goto out;
- ret = dict_set_int32 (xdata, "type", type);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set type in xdata");
- goto out;
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ CLI_LOCAL_INIT(local, words, frame, xdata);
+ proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT];
+
+ for (count = 0;; count++) {
+ ret = quota_conf_read_gfid(fd, buf, &gfid_type, version);
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ gf_log(THIS->name, GF_LOG_CRITICAL,
+ "Quota "
+ "configuration store may be corrupt.");
+ goto out;
+ }
+
+ if ((type == GF_QUOTA_OPTION_TYPE_LIST &&
+ gfid_type == GF_QUOTA_CONF_TYPE_OBJECTS) ||
+ (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS &&
+ gfid_type == GF_QUOTA_CONF_TYPE_USAGE))
+ continue;
+
+ max_count++;
+ }
+ ret = dict_set_int32(xdata, "max_count", max_count);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to set max_count");
+ goto out;
+ }
+
+ ret = sys_lseek(fd, 0L, SEEK_SET);
+ if (ret < 0) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "failed to move offset to "
+ "the beginning: %s",
+ strerror(errno));
+ goto out;
+ }
+ ret = quota_conf_read_version(fd, &version);
+ if (ret)
+ goto out;
- ret = cli_get_soft_limit (options, words, xdata);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to fetch default "
- "soft-limit");
- goto out;
+ for (count = 0;; count++) {
+ ret = quota_conf_read_gfid(fd, buf, &gfid_type, version);
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ gf_log(THIS->name, GF_LOG_CRITICAL,
+ "Quota "
+ "configuration store may be corrupt.");
+ goto out;
}
- /* Check if at least one limit is set on volume. No need to check for
- * quota enabled as cli_get_soft_limit() handles that
- */
- if (!_limits_set_on_volume (volname, type)) {
- snprintf (err_str, sizeof (err_str), "No%s quota configured on"
- " volume %s",
- (type == GF_QUOTA_OPTION_TYPE_LIST) ? "" : " inode",
- volname);
- if (global_state->mode & GLUSTER_MODE_XML) {
- xml_err_flag = _gf_true;
- } else {
- cli_out ("quota: %s", err_str);
- }
- ret = 0;
- goto out;
- }
+ if ((type == GF_QUOTA_OPTION_TYPE_LIST &&
+ gfid_type == GF_QUOTA_CONF_TYPE_OBJECTS) ||
+ (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS &&
+ gfid_type == GF_QUOTA_CONF_TYPE_USAGE))
+ continue;
- /* Check if the mount is online before doing any listing */
- if (!_quota_aux_mount_online (volname)) {
- ret = -1;
- goto out;
+ uuid_utoa_r(buf, gfid_str);
+ ret = dict_set_str(xdata, "gfid", gfid_str);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to set gfid");
+ goto out;
}
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame) {
- ret = -1;
- goto out;
+ ret = proc->fn(frame, THIS, xdata);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to get quota "
+ "limits for %s",
+ uuid_utoa((unsigned char *)buf));
}
- volname_dup = gf_strdup (volname);
- if (!volname_dup) {
- ret = -1;
- goto out;
- }
+ dict_del(xdata, "gfid");
+ all_failed = all_failed && ret;
+ }
- ret = dict_set_dynstr (xdata, "volume-uuid", volname_dup);
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_quota_limit_list_end(local);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set volume-uuid");
- GF_FREE (volname_dup);
- goto out;
+ gf_log("cli", GF_LOG_ERROR,
+ "Error in printing "
+ "xml output");
+ goto out;
}
+ }
- //TODO: fix hardcoding; Need to perform an RPC call to glusterd
- //to fetch working directory
- sprintf (quota_conf_file, "%s/vols/%s/quota.conf",
- GLUSTERD_DEFAULT_WORKDIR,
- volname);
- fd = open (quota_conf_file, O_RDONLY);
- if (fd == -1) {
- //This may because no limits were yet set on the volume
- gf_log ("cli", GF_LOG_TRACE, "Unable to open "
- "quota.conf");
- ret = 0;
- goto out;
- }
-
- ret = quota_conf_read_version (fd, &version);
- if (ret)
- goto out;
+ if (count > 0) {
+ ret = all_failed ? -1 : 0;
+ } else {
+ ret = 0;
+ }
- CLI_LOCAL_INIT (local, words, frame, xdata);
- proc = &cli_quotad_clnt.proctable[GF_AGGREGATOR_GETLIMIT];
+out:
+ if (xml_err_flag) {
+ ret = cli_xml_output_str("volQuota", NULL, -1, 0, err_str);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Error outputting in "
+ "xml format");
+ }
+ }
+ if (xdata)
+ dict_unref(xdata);
+
+ if (fd != -1) {
+ sys_close(fd);
+ }
+
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not fetch and display quota"
+ " limits");
+ }
+ CLI_STACK_DESTROY(frame);
+ return ret;
+}
- gfid_str = GF_CALLOC (1, gf_common_mt_char, 64);
- if (!gfid_str) {
- ret = -1;
- goto out;
- }
- for (count = 0;; count++) {
- ret = quota_conf_read_gfid (fd, buf, &gfid_type, version);
- if (ret == 0) {
- break;
- } else if (ret < 0) {
- gf_log (THIS->name, GF_LOG_CRITICAL, "Quota "
- "configuration store may be corrupt.");
- goto out;
- }
+int
+cli_cmd_bitrot_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
+{
+ int ret = -1;
+ int parse_err = 0;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+ cli_local_t *local = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ int sent = 0;
+#if (USE_EVENTS)
+ int cmd_type = -1;
+ int ret1 = -1;
+ int event_type = -1;
+ char *tmp = NULL;
+ char *events_str = NULL;
+ char *volname = NULL;
+#endif
- if ((type == GF_QUOTA_OPTION_TYPE_LIST &&
- gfid_type == GF_QUOTA_CONF_TYPE_OBJECTS) ||
- (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS &&
- gfid_type == GF_QUOTA_CONF_TYPE_USAGE))
- continue;
-
- uuid_utoa_r (buf, gfid_str);
- ret = dict_set_str (xdata, "gfid", gfid_str);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set gfid");
- goto out;
- }
+ ret = cli_cmd_bitrot_parse(words, wordcount, &options);
+ if (ret < 0) {
+ cli_usage_out(word->pattern);
+ parse_err = 1;
+ goto out;
+ }
- ret = proc->fn (frame, THIS, xdata);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get quota "
- "limits for %s", uuid_utoa ((unsigned char*)buf));
- }
+ if (ret == 1) {
+ /* this is 'volume bitrot help' */
+ cli_cmd_bitrot_help_cbk(state, word, words, wordcount);
+ ret = 0;
+ goto out2;
+ }
- dict_del (xdata, "gfid");
- all_failed = all_failed && ret;
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_quota_limit_list_end (local);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Error in printing "
- "xml output");
- goto out;
- }
- }
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_BITROT];
- if (count > 0) {
- ret = all_failed? -1: 0;
- } else {
- ret = 0;
- }
+ CLI_LOCAL_INIT(local, words, frame, options);
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, options);
+ }
out:
- if (xml_err_flag) {
- ret = cli_xml_output_str ("volQuota", NULL, -1, 0, err_str);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Error outputting in "
- "xml format");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_err == 0))
+ cli_err(
+ "Bit rot command failed. Please check the cli "
+ "logs for more details");
+ }
+
+#if (USE_EVENTS)
+ if (ret == 0) {
+ ret1 = dict_get_int32(options, "type", &cmd_type);
+ if (ret1)
+ cmd_type = -1;
+ else {
+ ret1 = dict_get_str(options, "volname", &volname);
+ if (ret1)
+ volname = "";
}
- if (fd != -1) {
- close (fd);
+ switch (cmd_type) {
+ case GF_BITROT_OPTION_TYPE_ENABLE:
+ event_type = EVENT_BITROT_ENABLE;
+ break;
+ case GF_BITROT_OPTION_TYPE_DISABLE:
+ event_type = EVENT_BITROT_DISABLE;
+ break;
+ case GF_BITROT_CMD_SCRUB_ONDEMAND:
+ event_type = EVENT_BITROT_SCRUB_ONDEMAND;
+ break;
+ case GF_BITROT_OPTION_TYPE_SCRUB_THROTTLE:
+ event_type = EVENT_BITROT_SCRUB_THROTTLE;
+ ret1 = dict_get_str(options, "scrub-throttle-value", &tmp);
+ if (ret1)
+ tmp = "";
+ gf_asprintf(&events_str, "name=%s;value=%s", volname, tmp);
+ break;
+ case GF_BITROT_OPTION_TYPE_SCRUB_FREQ:
+ event_type = EVENT_BITROT_SCRUB_FREQ;
+ ret1 = dict_get_str(options, "scrub-frequency-value", &tmp);
+ if (ret1)
+ tmp = "";
+ gf_asprintf(&events_str, "name=%s;value=%s", volname, tmp);
+ break;
+ case GF_BITROT_OPTION_TYPE_SCRUB:
+ event_type = EVENT_BITROT_SCRUB_OPTION;
+ ret1 = dict_get_str(options, "scrub-value", &tmp);
+ if (ret1)
+ tmp = "";
+ gf_asprintf(&events_str, "name=%s;value=%s", volname, tmp);
+ break;
+ default:
+ break;
}
- GF_FREE (gfid_str);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch and display quota"
- " limits");
- }
- CLI_STACK_DESTROY (frame);
- return ret;
+ if (event_type > -1)
+ gf_event(event_type, "%s", events_str);
+
+ if (events_str)
+ GF_FREE(events_str);
+ }
+#endif
+
+ CLI_STACK_DESTROY(frame);
+out2:
+ return ret;
}
int
-cli_cmd_bitrot_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_quota_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
-
- int ret = -1;
- int parse_err = 0;
- call_frame_t *frame = NULL;
- dict_t *options = NULL;
- cli_local_t *local = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- int sent = 0;
-
- ret = cli_cmd_bitrot_parse (words, wordcount, &options);
+ 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;
+ cli_local_t *local = NULL;
+ int sent = 0;
+ char *volname = NULL;
+ const char *question =
+ "Disabling quota will delete all the quota "
+ "configuration. Do you want to continue?";
+
+ // parse **words into options dictionary
+ if (strcmp(words[1], "inode-quota") == 0) {
+ ret = cli_cmd_inode_quota_parse(words, wordcount, &options);
if (ret < 0) {
- cli_usage_out (word->pattern);
- parse_err = 1;
- goto out;
+ cli_usage_out(word->pattern);
+ parse_err = 1;
+ goto out;
}
+ } else {
+ ret = cli_cmd_quota_parse(words, wordcount, &options);
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame) {
- ret = -1;
- goto out;
+ if (ret == 1) {
+ cli_cmd_quota_help_cbk(state, word, words, wordcount);
+ ret = 0;
+ goto out;
+ }
+ if (ret < 0) {
+ cli_usage_out(word->pattern);
+ parse_err = 1;
+ goto out;
}
+ }
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_BITROT];
- if (proc == NULL) {
- ret = -1;
+ ret = dict_get_int32(options, "type", &type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get opcode");
+ goto out;
+ }
+
+ // handle quota-disable and quota-list-all different from others
+ switch (type) {
+ case GF_QUOTA_OPTION_TYPE_DISABLE:
+ answer = cli_cmd_get_confirmation(state, question);
+ if (answer == GF_ANSWER_NO)
goto out;
- }
+ break;
+ case GF_QUOTA_OPTION_TYPE_LIST:
+ case GF_QUOTA_OPTION_TYPE_LIST_OBJECTS:
+ if (wordcount != 4)
+ break;
+ ret = cli_cmd_quota_handle_list_all(words, options);
+ goto out;
+ default:
+ break;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ ret = dict_get_str(options, "volname", &volname);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get volume name");
+ goto out;
+ }
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
-out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_err == 0))
- cli_err ("Bit rot command failed. Please check the cli "
- "logs for more details");
+ CLI_LOCAL_INIT(local, words, frame, options);
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_QUOTA];
- }
+ if (proc->fn)
+ ret = proc->fn(frame, THIS, options);
- CLI_STACK_DESTROY (frame);
+out:
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if (sent == 0 && parse_err == 0)
+ cli_out(
+ "Quota command failed. Please check the cli "
+ "logs for more details");
+ }
+ if (options)
+ dict_unref(options);
+
+ /* Events for Quota */
+ if (ret == 0) {
+ switch (type) {
+ case GF_QUOTA_OPTION_TYPE_ENABLE:
+ gf_event(EVENT_QUOTA_ENABLE, "volume=%s", volname);
+ break;
+ case GF_QUOTA_OPTION_TYPE_DISABLE:
+ gf_event(EVENT_QUOTA_DISABLE, "volume=%s", volname);
+ break;
+ case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE:
+ gf_event(EVENT_QUOTA_SET_USAGE_LIMIT,
+ "volume=%s;"
+ "path=%s;limit=%s",
+ volname, words[4], words[5]);
+ break;
+ case GF_QUOTA_OPTION_TYPE_LIMIT_OBJECTS:
+ gf_event(EVENT_QUOTA_SET_OBJECTS_LIMIT,
+ "volume=%s;"
+ "path=%s;limit=%s",
+ volname, words[4], words[5]);
+ break;
+ case GF_QUOTA_OPTION_TYPE_REMOVE:
+ gf_event(EVENT_QUOTA_REMOVE_USAGE_LIMIT,
+ "volume=%s;"
+ "path=%s",
+ volname, words[4]);
+ break;
+ case GF_QUOTA_OPTION_TYPE_REMOVE_OBJECTS:
+ gf_event(EVENT_QUOTA_REMOVE_OBJECTS_LIMIT,
+ "volume=%s;"
+ "path=%s",
+ volname, words[4]);
+ break;
+ case GF_QUOTA_OPTION_TYPE_ALERT_TIME:
+ gf_event(EVENT_QUOTA_ALERT_TIME, "volume=%s;time=%s", volname,
+ words[4]);
+ break;
+ case GF_QUOTA_OPTION_TYPE_SOFT_TIMEOUT:
+ gf_event(EVENT_QUOTA_SOFT_TIMEOUT,
+ "volume=%s;"
+ "soft-timeout=%s",
+ volname, words[4]);
+ break;
+ case GF_QUOTA_OPTION_TYPE_HARD_TIMEOUT:
+ gf_event(EVENT_QUOTA_HARD_TIMEOUT,
+ "volume=%s;"
+ "hard-timeout=%s",
+ volname, words[4]);
+ break;
+ case GF_QUOTA_OPTION_TYPE_DEFAULT_SOFT_LIMIT:
+ gf_event(EVENT_QUOTA_DEFAULT_SOFT_LIMIT,
+ "volume=%s;"
+ "default-soft-limit=%s",
+ volname, words[4]);
+ break;
+ }
+ }
- return ret;
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
int
-cli_cmd_quota_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_remove_brick_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;
+ gf_answer_t answer = GF_ANSWER_NO;
+ int brick_count = 0;
+ int sent = 0;
+ int parse_error = 0;
+ int need_question = 0;
+ cli_local_t *local = NULL;
+ char *volname = NULL;
+#if (USE_EVENTS)
+ eventtypes_t event = EVENT_LAST;
+ char *event_str = NULL;
+ int event_ret = -1;
+#endif
+ int32_t command = GF_OP_CMD_NONE;
+ char *question = NULL;
+
+ ret = cli_cmd_volume_remove_brick_parse(state, words, wordcount, &options,
+ &need_question, &brick_count,
+ &command);
+ if (ret) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+
+ if (command == GF_OP_CMD_COMMIT_FORCE) {
+ question =
+ "Remove-brick force will not migrate files from the "
+ "removed bricks, so they will no longer be available"
+ " on the volume.\nDo you want to continue?";
+ } else if (command == GF_OP_CMD_START) {
+ question =
+ "It is recommended that remove-brick be run with"
+ " cluster.force-migration option disabled to prevent"
+ " possible data corruption. Doing so will ensure that"
+ " files that receive writes during migration will not"
+ " be migrated and will need to be manually copied"
+ " after the remove-brick commit operation. Please"
+ " check the value of the option and update accordingly."
+ " \nDo you want to continue with your current"
+ " cluster.force-migration settings?";
+ }
+
+ if (!brick_count) {
+ cli_err("No bricks specified");
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ ret = -1;
+ goto out;
+ }
+ ret = dict_get_str(options, "volname", &volname);
+ if (ret || !volname) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to fetch volname");
+ ret = -1;
+ goto out;
+ }
- 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;
- cli_local_t *local = NULL;
- int sent = 0;
- char *volname = NULL;
- const char *question = "Disabling quota will delete all the quota "
- "configuration. Do you want to continue?";
-
- //parse **words into options dictionary
- if (strcmp (words[1], "inode-quota") == 0) {
- ret = cli_cmd_inode_quota_parse (words, wordcount, &options);
- if (ret < 0) {
- cli_usage_out (word->pattern);
- parse_err = 1;
- goto out;
- }
- } else {
- ret = cli_cmd_quota_parse (words, wordcount, &options);
- if (ret < 0) {
- cli_usage_out (word->pattern);
- parse_err = 1;
- goto out;
- }
- }
+#if (USE_EVENTS)
+ event_ret = cli_event_remove_brick_str(options, &event_str, &event);
+#endif
- ret = dict_get_int32 (options, "type", &type);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get opcode");
- goto out;
+ if (!strcmp(volname, GLUSTER_SHARED_STORAGE)) {
+ question =
+ "Removing brick from the shared storage volume"
+ "(gluster_shared_storage), will affect features "
+ "like snapshot scheduler, geo-replication "
+ "and NFS-Ganesha. Do you still want to "
+ "continue?";
+ need_question = _gf_true;
+ }
+
+ if (!(state->mode & GLUSTER_MODE_SCRIPT) && need_question) {
+ answer = cli_cmd_get_confirmation(state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ goto out;
}
+ }
- //handle quota-disable and quota-list-all different from others
- switch (type) {
- case GF_QUOTA_OPTION_TYPE_DISABLE:
- answer = cli_cmd_get_confirmation (state, question);
- if (answer == GF_ANSWER_NO)
- goto out;
- break;
- case GF_QUOTA_OPTION_TYPE_LIST:
- case GF_QUOTA_OPTION_TYPE_LIST_OBJECTS:
- if (wordcount != 4)
- break;
- ret = cli_cmd_quota_handle_list_all (words, options);
- goto out;
- default:
- break;
- }
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_REMOVE_BRICK];
- ret = dict_get_str (options, "volname", &volname);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get volume name");
- goto out;
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- //create auxiliary mount need for quota commands that operate on path
- ret = cli_stage_quota_op (volname, type);
- if (ret)
- goto out;
+ CLI_LOCAL_INIT(local, words, frame, options);
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame) {
- ret = -1;
- goto out;
- }
+ if (proc->fn) {
+ ret = proc->fn(frame, THIS, options);
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_QUOTA];
+out:
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume remove-brick failed");
+ }
+#if (USE_EVENTS)
+ if (!ret && !event_ret)
+ gf_event(event, "%s", event_str);
+ if (event_str)
+ GF_FREE(event_str);
- if (proc->fn)
- ret = proc->fn (frame, THIS, options);
+#endif
-out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if (sent == 0 && parse_err == 0)
- cli_out ("Quota command failed. Please check the cli "
- "logs for more details");
- }
+ CLI_STACK_DESTROY(frame);
+ if (options)
+ dict_unref(options);
- CLI_STACK_DESTROY (frame);
- return ret;
+ return ret;
}
int
-cli_cmd_volume_remove_brick_cbk (struct cli_state *state,
- struct cli_cmd_word *word, const char **words,
- int wordcount)
+cli_cmd_volume_reset_brick_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;
- gf_answer_t answer = GF_ANSWER_NO;
- int sent = 0;
- int parse_error = 0;
- int need_question = 0;
- cli_local_t *local = NULL;
- char *volname = NULL;
-
- const char *question = "Removing brick(s) can result in data loss. "
- "Do you want to Continue?";
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ 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;
+ cli_local_t *local = NULL;
- ret = cli_cmd_volume_remove_brick_parse (words, wordcount, &options,
- &need_question);
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+#ifdef GF_SOLARIS_HOST_OS
+ cli_out("Command not supported on Solaris");
+ goto out;
+#endif
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RESET_BRICK];
- ret = dict_get_str (options, "volname", &volname);
- if (ret || !volname) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to fetch volname");
- ret = -1;
- goto out;
- }
+ ret = cli_cmd_volume_reset_brick_parse(words, wordcount, &options);
- if (!strcmp (volname, GLUSTER_SHARED_STORAGE)) {
- question = "Removing brick from the shared storage volume"
- "(gluster_shared_storage), will affect features "
- "like snapshot scheduler, geo-replication "
- "and NFS-Ganesha. Do you still want to "
- "continue?";
- need_question = _gf_true;
- }
+ if (ret) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ 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;
- }
+ if (state->mode & GLUSTER_MODE_WIGNORE_PARTITION) {
+ ret = dict_set_int32(options, "ignore-partition", _gf_true);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to set ignore-"
+ "partition option");
+ goto out;
}
+ }
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_REMOVE_BRICK];
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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 remove-brick failed");
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume reset-brick failed");
+ } else {
+ if (wordcount > 5) {
+ gf_event(EVENT_BRICK_RESET_COMMIT,
+ "Volume=%s;source-brick=%s;"
+ "destination-brick=%s",
+ (char *)words[2], (char *)words[3], (char *)words[4]);
+ } else {
+ gf_event(EVENT_BRICK_RESET_START, "Volume=%s;source-brick=%s",
+ (char *)words[2], (char *)words[3]);
}
+ }
+ CLI_STACK_DESTROY(frame);
- CLI_STACK_DESTROY (frame);
-
- return ret;
-
+ return ret;
}
int
-cli_cmd_volume_replace_brick_cbk (struct cli_state *state,
- struct cli_cmd_word *word,
- const char **words,
- int wordcount)
+cli_cmd_volume_replace_brick_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;
- cli_local_t *local = NULL;
+ 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;
+ cli_local_t *local = NULL;
#ifdef GF_SOLARIS_HOST_OS
- cli_out ("Command not supported on Solaris");
- goto out;
+ cli_out("Command not supported on Solaris");
+ goto out;
#endif
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_REPLACE_BRICK];
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_REPLACE_BRICK];
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ ret = cli_cmd_volume_replace_brick_parse(words, wordcount, &options);
- ret = cli_cmd_volume_replace_brick_parse (words, wordcount, &options);
+ if (ret) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- if (ret) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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 replace-brick failed");
- }
-
- CLI_STACK_DESTROY (frame);
-
- return ret;
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume replace-brick failed");
+ } else {
+ gf_event(EVENT_BRICK_REPLACE,
+ "Volume=%s;source-brick=%s;destination-brick=%s",
+ (char *)words[2], (char *)words[3], (char *)words[4]);
+ }
+ CLI_STACK_DESTROY(frame);
+
+ return ret;
}
-
int
-cli_cmd_volume_set_transport_cbk (struct cli_state *state,
- struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_set_transport_cbk(struct cli_state *state,
+ struct cli_cmd_word *word, const char **words,
+ int wordcount)
{
- cli_cmd_broadcast_response (0);
- return 0;
+ cli_cmd_broadcast_response(0);
+ return 0;
}
int
-cli_cmd_volume_top_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_top_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;
+ cli_local_t *local = NULL;
+
+ ret = cli_cmd_volume_top_parse(words, wordcount, &options);
+
+ if (ret) {
+ parse_error = 1;
+ cli_usage_out(word->pattern);
+ goto out;
+ }
- 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;
- cli_local_t *local = NULL;
-
- ret = cli_cmd_volume_top_parse (words, wordcount, &options);
-
- if (ret) {
- parse_error = 1;
- cli_usage_out (word->pattern);
- goto out;
- }
-
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_TOP_VOLUME];
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_TOP_VOLUME];
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame");
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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 top failed");
- }
-
- CLI_STACK_DESTROY (frame);
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume top failed");
+ }
- return ret;
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
-
int
-cli_cmd_log_rotate_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_log_rotate_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;
- cli_local_t *local = NULL;
-
- if (!((wordcount == 4) || (wordcount == 5))) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ 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;
+ cli_local_t *local = NULL;
+
+ if (!((wordcount == 4) || (wordcount == 5))) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- if (!((strcmp ("rotate", words[2]) == 0) ||
- (strcmp ("rotate", words[3]) == 0))) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ if (!(strcmp("rotate", words[3]) == 0)) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LOG_ROTATE];
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LOG_ROTATE];
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ ret = cli_cmd_log_rotate_parse(words, wordcount, &options);
+ if (ret)
+ goto out;
- ret = cli_cmd_log_rotate_parse (words, wordcount, &options);
- if (ret)
- goto out;
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame");
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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 log rotate failed");
- }
- CLI_STACK_DESTROY (frame);
-
- return ret;
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume log rotate failed");
+ }
+ CLI_STACK_DESTROY(frame);
+
+ return ret;
}
#if (SYNCDAEMON_COMPILE)
static int
-cli_check_gsync_present ()
+cli_check_gsync_present()
{
- char buff[PATH_MAX] = {0, };
- runner_t runner = {0,};
- char *ptr = NULL;
- int ret = 0;
-
- ret = setenv ("_GLUSTERD_CALLED_", "1", 1);
- if (-1 == ret) {
- gf_log ("", GF_LOG_WARNING, "setenv syscall failed, hence could"
- "not assert if geo-replication is installed");
- goto out;
- }
-
- 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;
- }
+ char buff[PATH_MAX] = {
+ 0,
+ };
+ runner_t runner = {
+ 0,
+ };
+ char *ptr = NULL;
+ int ret = 0;
+
+ ret = setenv("_GLUSTERD_CALLED_", "1", 1);
+ if (-1 == ret) {
+ gf_log("", GF_LOG_WARNING,
+ "setenv syscall failed, hence could"
+ "not assert if geo-replication is installed");
+ goto out;
+ }
+
+ 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), runner_chio (&runner, STDOUT_FILENO));
- if (ptr) {
- if (!strstr (buff, "gsyncd")) {
- ret = -1;
- goto out;
- }
- } else {
- ret = -1;
- goto out;
+ ptr = fgets(buff, sizeof(buff), runner_chio(&runner, STDOUT_FILENO));
+ if (ptr) {
+ if (!strstr(buff, "gsyncd")) {
+ ret = -1;
+ goto out;
}
+ } else {
+ ret = -1;
+ goto out;
+ }
- ret = runner_end (&runner);
+ ret = runner_end(&runner);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "geo-replication not installed");
+ if (ret)
+ gf_log("", GF_LOG_ERROR, "geo-replication not installed");
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret ? -1 : 0;
-
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret ? -1 : 0;
}
void
-cli_cmd_check_gsync_exists_cbk (struct cli_cmd *this)
+cli_cmd_check_gsync_exists_cbk(struct cli_cmd *this)
{
+ int ret = 0;
- int ret = 0;
-
- ret = cli_check_gsync_present ();
- if (ret)
- this->disable = _gf_true;
-
+ ret = cli_check_gsync_present();
+ if (ret)
+ this->disable = _gf_true;
}
#endif
int
-cli_cmd_volume_gsync_set_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_gsync_set_cbk(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount)
{
- int ret = 0;
- int parse_err = 0;
- dict_t *options = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- call_frame_t *frame = NULL;
- cli_local_t *local = NULL;
-
- proc = &cli_rpc_prog->proctable [GLUSTER_CLI_GSYNC_SET];
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (frame == NULL) {
- ret = -1;
- goto out;
- }
+ int ret = 0;
+ int parse_err = 0;
+ dict_t *options = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ cli_local_t *local = NULL;
+ char *errstr = NULL;
+#if (USE_EVENTS)
+ int ret1 = -1;
+ int cmd_type = -1;
+ int tmpi = 0;
+ char *tmp = NULL;
+ char *events_str = NULL;
+ int event_type = -1;
+#endif
- ret = cli_cmd_gsync_set_parse (words, wordcount, &options);
- if (ret) {
- cli_usage_out (word->pattern);
- parse_err = 1;
- goto out;
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GSYNC_SET];
+
+ ret = cli_cmd_gsync_set_parse(state, words, wordcount, &options, &errstr);
+ if (ret) {
+ if (errstr) {
+ cli_err("%s", errstr);
+ GF_FREE(errstr);
+ } else {
+ cli_usage_out(word->pattern);
}
+ parse_err = 1;
+ goto out;
+ }
+
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (frame == NULL) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn)
- ret = proc->fn (frame, THIS, options);
+ if (proc->fn)
+ ret = proc->fn(frame, THIS, options);
out:
- if (ret && parse_err == 0)
- cli_out (GEOREP" command failed");
+ if (ret && parse_err == 0)
+ cli_out(GEOREP " command failed");
+
+#if (USE_EVENTS)
+ if (ret == 0) {
+ events_str = gf_strdup("");
+
+ /* Type of Geo-rep Action - Create, Start etc */
+ ret1 = dict_get_int32(options, "type", &cmd_type);
+ if (ret1)
+ cmd_type = -1;
+
+ /* Only capture Events for modification commands */
+ switch (cmd_type) {
+ case GF_GSYNC_OPTION_TYPE_CREATE:
+ event_type = EVENT_GEOREP_CREATE;
+ break;
+ case GF_GSYNC_OPTION_TYPE_START:
+ event_type = EVENT_GEOREP_START;
+ break;
+ case GF_GSYNC_OPTION_TYPE_STOP:
+ event_type = EVENT_GEOREP_STOP;
+ break;
+ case GF_GSYNC_OPTION_TYPE_PAUSE:
+ event_type = EVENT_GEOREP_PAUSE;
+ break;
+ case GF_GSYNC_OPTION_TYPE_RESUME:
+ event_type = EVENT_GEOREP_RESUME;
+ break;
+ case GF_GSYNC_OPTION_TYPE_DELETE:
+ event_type = EVENT_GEOREP_DELETE;
+ break;
+ case GF_GSYNC_OPTION_TYPE_CONFIG:
+ ret1 = dict_get_str(options, "subop", &tmp);
+ if (ret1)
+ tmp = "";
+
+ /* For Config Set additionally capture key and value */
+ /* For Config Reset capture key */
+ if (strcmp(tmp, "set") == 0) {
+ event_type = EVENT_GEOREP_CONFIG_SET;
+
+ ret1 = dict_get_str(options, "op_name", &tmp);
+ if (ret1)
+ tmp = "";
+
+ gf_asprintf_append(&events_str, "%soption=%s;", events_str,
+ tmp);
+
+ ret1 = dict_get_str(options, "op_value", &tmp);
+ if (ret1)
+ tmp = "";
+
+ gf_asprintf_append(&events_str, "%svalue=%s;", events_str,
+ tmp);
+ } else if (strcmp(tmp, "del") == 0) {
+ event_type = EVENT_GEOREP_CONFIG_RESET;
+
+ ret1 = dict_get_str(options, "op_name", &tmp);
+ if (ret1)
+ tmp = "";
+
+ gf_asprintf_append(&events_str, "%soption=%s;", events_str,
+ tmp);
+ }
+ break;
+ default:
+ break;
+ }
- CLI_STACK_DESTROY (frame);
+ if (event_type > -1) {
+ /* Capture all optional arguments used */
+ ret1 = dict_get_int32(options, "force", &tmpi);
+ if (ret1 == 0) {
+ gf_asprintf_append(&events_str, "%sforce=%d;", events_str,
+ tmpi);
+ }
+ ret1 = dict_get_int32(options, "push_pem", &tmpi);
+ if (ret1 == 0) {
+ gf_asprintf_append(&events_str, "%spush_pem=%d;", events_str,
+ tmpi);
+ }
+ ret1 = dict_get_int32(options, "no_verify", &tmpi);
+ if (ret1 == 0) {
+ gf_asprintf_append(&events_str, "%sno_verify=%d;", events_str,
+ tmpi);
+ }
+
+ ret1 = dict_get_int32(options, "ssh_port", &tmpi);
+ if (ret1 == 0) {
+ gf_asprintf_append(&events_str, "%sssh_port=%d;", events_str,
+ tmpi);
+ }
+
+ ret1 = dict_get_int32(options, "reset-sync-time", &tmpi);
+ if (ret1 == 0) {
+ gf_asprintf_append(&events_str, "%sreset_sync_time=%d;",
+ events_str, tmpi);
+ }
+ /* Capture Master and Slave Info */
+ ret1 = dict_get_str(options, "master", &tmp);
+ if (ret1)
+ tmp = "";
+ gf_asprintf_append(&events_str, "%smaster=%s;", events_str, tmp);
+
+ ret1 = dict_get_str(options, "slave", &tmp);
+ if (ret1)
+ tmp = "";
+ gf_asprintf_append(&events_str, "%sslave=%s", events_str, tmp);
+
+ gf_event(event_type, "%s", events_str);
+ }
+
+ /* Allocated by gf_strdup and gf_asprintf */
+ if (events_str)
+ GF_FREE(events_str);
+ }
+#endif
- return ret;
+ 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)
+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;
- cli_local_t *local = NULL;
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ uint32_t cmd = 0;
+ cli_local_t *local = NULL;
- ret = cli_cmd_volume_status_parse (words, wordcount, &dict);
+ ret = cli_cmd_volume_status_parse(words, wordcount, &dict);
- if (ret) {
- cli_usage_out (word->pattern);
- goto out;
- }
+ if (ret) {
+ cli_usage_out(word->pattern);
+ goto out;
+ }
- ret = dict_get_uint32 (dict, "cmd", &cmd);
- if (ret)
- 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 (!(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;
+ if (!proc->fn) {
+ ret = -1;
+ goto out;
+ }
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ gf_log(THIS->name, GF_LOG_ERROR, "failed to create frame");
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, dict);
+ CLI_LOCAL_INIT(local, words, frame, dict);
- ret = proc->fn (frame, THIS, dict);
+ ret = proc->fn(frame, THIS, dict);
out:
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
-
int
-cli_get_detail_status (dict_t *dict, int i, cli_volume_status_t *status)
+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;
+ 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.total", i);
- ret = dict_get_uint64 (dict, key, &total);
+ snprintf(key, sizeof(key), "brick%d.free", i);
+ ret = dict_get_uint64(dict, key, &free);
- 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
+ status->free = gf_uint64_2human_readable(free);
+ if (!status->free)
+ goto out;
- 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;
- }
+ snprintf(key, sizeof(key), "brick%d.total", i);
+ ret = dict_get_uint64(dict, key, &total);
-#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;
- }
+ status->total = gf_uint64_2human_readable(total);
+ if (!status->total)
+ goto out;
- 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 */
+ snprintf(key, sizeof(key), "brick%d.device", i);
+ ret = dict_get_str(dict, key, &(status->device));
+ if (ret)
+ status->device = NULL;
- 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;
+ 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;
+ }
- 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;
- }
+ snprintf(key, sizeof(key), "brick%d.mnt_options", i);
+ ret = dict_get_str(dict, key, &(status->mount_options));
+ if (ret)
+ status->mount_options = NULL;
+ 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;
+ }
+
+ snprintf(key, sizeof(key), "brick%d.inode_size", i);
+ ret = dict_get_str(dict, key, &(status->inode_size));
+ if (ret)
+ status->inode_size = NULL;
+
+ snprintf(key, sizeof(key), "brick%d.total_inodes", i);
+ ret = dict_get_uint64(dict, key, &(status->total_inodes));
+ if (ret)
+ status->total_inodes = 0;
+
+ 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;
+out:
+ return ret;
}
void
-cli_print_detailed_status (cli_volume_status_t *status)
+cli_print_detailed_status(cli_volume_status_t *status)
{
- cli_out ("%-20s : %-20s", "Brick", status->brick);
-
- if (status->online) {
- cli_out ("%-20s : %-20d", "TCP Port", status->port);
- cli_out ("%-20s : %-20d", "RDMA Port", status->rdma_port);
- } else {
- cli_out ("%-20s : %-20s", "TCP Port", "N/A");
- cli_out ("%-20s : %-20s", "RDMA Port", "N/A");
- }
-
- 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 : %-20"GF_PRI_INODE, "Inode Count",
- status->total_inodes);
- } else {
- cli_out ("%-20s : %-20s", "Inode Count", "N/A");
- }
-
- if (status->free_inodes) {
- cli_out ("%-20s : %-20"GF_PRI_INODE, "Free Inodes",
- status->free_inodes);
- } else {
- cli_out ("%-20s : %-20s", "Free Inodes", "N/A");
- }
+ cli_out("%-20s : %-20s", "Brick", status->brick);
+
+ if (status->online) {
+ cli_out("%-20s : %-20d", "TCP Port", status->port);
+ cli_out("%-20s : %-20d", "RDMA Port", status->rdma_port);
+ } else {
+ cli_out("%-20s : %-20s", "TCP Port", "N/A");
+ cli_out("%-20s : %-20s", "RDMA Port", "N/A");
+ }
+
+ cli_out("%-20s : %-20c", "Online", (status->online) ? 'Y' : 'N');
+ cli_out("%-20s : %-20s", "Pid", status->pid_str);
+
+ 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");
+ }
+ 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 : %-20" GF_PRI_INODE, "Inode Count",
+ status->total_inodes);
+ } else {
+ cli_out("%-20s : %-20s", "Inode Count", "N/A");
+ }
+
+ if (status->free_inodes) {
+ cli_out("%-20s : %-20" GF_PRI_INODE, "Free Inodes",
+ status->free_inodes);
+ } else {
+ cli_out("%-20s : %-20s", "Free Inodes", "N/A");
+ }
}
int
-cli_print_brick_status (cli_volume_status_t *status)
+cli_print_brick_status(cli_volume_status_t *status)
{
- int fieldlen = CLI_VOL_STATUS_BRICK_LEN;
- int bricklen = 0;
- char *p = NULL;
- int num_spaces = 0;
-
- p = status->brick;
- bricklen = strlen (p);
- while (bricklen > 0) {
- if (bricklen > fieldlen) {
- cli_out ("%.*s", fieldlen, p);
- p += fieldlen;
- bricklen -= fieldlen;
- } else {
- num_spaces = (fieldlen - bricklen) + 1;
- printf ("%s", p);
- while (num_spaces-- != 0)
- printf (" ");
- if (status->port || status->rdma_port) {
- if (status->online)
- cli_out ("%-10d%-11d%-8c%-5s",
- status->port,
- status->rdma_port,
- status->online?'Y':'N',
- status->pid_str);
- else
- cli_out ("%-10s%-11s%-8c%-5s",
- "N/A",
- "N/A",
- status->online?'Y':'N',
- status->pid_str);
- }
- else
- cli_out ("%-10s%-11s%-8c%-5s",
- "N/A", "N/A", status->online?'Y':'N',
- status->pid_str);
- bricklen = 0;
- }
- }
-
- return 0;
+ int fieldlen = CLI_VOL_STATUS_BRICK_LEN;
+ int bricklen = 0;
+ char *p = NULL;
+ int num_spaces = 0;
+
+ p = status->brick;
+ bricklen = strlen(p);
+ while (bricklen > 0) {
+ if (bricklen > fieldlen) {
+ cli_out("%.*s", fieldlen, p);
+ p += fieldlen;
+ bricklen -= fieldlen;
+ } else {
+ num_spaces = (fieldlen - bricklen) + 1;
+ printf("%s", p);
+ while (num_spaces-- != 0)
+ printf(" ");
+ if (status->port || status->rdma_port) {
+ if (status->online)
+ cli_out("%-10d%-11d%-8c%-5s", status->port,
+ status->rdma_port, status->online ? 'Y' : 'N',
+ status->pid_str);
+ else
+ cli_out("%-10s%-11s%-8c%-5s", "N/A", "N/A",
+ status->online ? 'Y' : 'N', status->pid_str);
+ } else
+ cli_out("%-10s%-11s%-8c%-5s", "N/A", "N/A",
+ status->online ? 'Y' : 'N', status->pid_str);
+ bricklen = 0;
+ }
+ }
+
+ return 0;
}
-#define NEEDS_GLFS_HEAL(op) ((op == GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE) || \
- (op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) || \
- (op == GF_SHD_OP_INDEX_SUMMARY) || \
- (op == GF_SHD_OP_SPLIT_BRAIN_FILES))
+#define NEEDS_GLFS_HEAL(op) \
+ ((op == GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE) || \
+ (op == GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME) || \
+ (op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) || \
+ (op == GF_SHD_OP_INDEX_SUMMARY) || (op == GF_SHD_OP_SPLIT_BRAIN_FILES) || \
+ (op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) || \
+ (op == GF_SHD_OP_HEAL_SUMMARY))
int
-cli_launch_glfs_heal (int heal_op, dict_t *options)
+cli_launch_glfs_heal(int heal_op, dict_t *options)
{
- char buff[PATH_MAX] = {0};
- runner_t runner = {0};
- char *filename = NULL;
- char *hostname = NULL;
- char *path = NULL;
- char *volname = NULL;
- char *out = NULL;
- int ret = 0;
-
- runinit (&runner);
- ret = dict_get_str (options, "volname", &volname);
- runner_add_args (&runner, SBIN_DIR"/glfsheal", volname, NULL);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
-
- switch (heal_op) {
+ char buff[PATH_MAX] = {0};
+ runner_t runner = {0};
+ char *filename = NULL;
+ char *hostname = NULL;
+ char *path = NULL;
+ char *volname = NULL;
+ char *out = NULL;
+ int ret = 0;
+
+ runinit(&runner);
+ ret = dict_get_str(options, "volname", &volname);
+ runner_add_args(&runner, GLFSHEAL_PREFIX "/glfsheal", volname, NULL);
+ runner_redir(&runner, STDOUT_FILENO, RUN_PIPE);
+
+ switch (heal_op) {
case GF_SHD_OP_INDEX_SUMMARY:
- break;
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ runner_add_args(&runner, "--xml", NULL);
+ }
+ break;
case GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE:
- ret = dict_get_str (options, "file", &filename);
- runner_add_args (&runner, "bigger-file", filename, NULL);
- break;
+ ret = dict_get_str(options, "file", &filename);
+ runner_add_args(&runner, "bigger-file", filename, NULL);
+ break;
+ case GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME:
+ ret = dict_get_str(options, "file", &filename);
+ runner_add_args(&runner, "latest-mtime", filename, NULL);
+ break;
case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK:
- ret = dict_get_str (options, "heal-source-hostname",
- &hostname);
- ret = dict_get_str (options, "heal-source-brickpath",
- &path);
- runner_add_args (&runner, "source-brick", NULL);
- runner_argprintf (&runner, "%s:%s", hostname, path);
- if (dict_get_str (options, "file", &filename) == 0)
- runner_argprintf (&runner, filename);
- break;
+ ret = dict_get_str(options, "heal-source-hostname", &hostname);
+ ret = dict_get_str(options, "heal-source-brickpath", &path);
+ runner_add_args(&runner, "source-brick", NULL);
+ runner_argprintf(&runner, "%s:%s", hostname, path);
+ if (dict_get_str(options, "file", &filename) == 0)
+ runner_argprintf(&runner, "%s", filename);
+ break;
case GF_SHD_OP_SPLIT_BRAIN_FILES:
- runner_add_args (&runner, "split-brain-info", NULL);
- break;
+ runner_add_args(&runner, "split-brain-info", NULL);
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ runner_add_args(&runner, "--xml", NULL);
+ }
+ break;
+ case GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE:
+ case GF_SHD_OP_GRANULAR_ENTRY_HEAL_DISABLE:
+ runner_add_args(&runner, "granular-entry-heal-op", NULL);
+ break;
+ case GF_SHD_OP_HEAL_SUMMARY:
+ runner_add_args(&runner, "info-summary", NULL);
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ runner_add_args(&runner, "--xml", NULL);
+ }
+ break;
default:
- ret = -1;
- }
- ret = runner_start (&runner);
- if (ret == -1)
- goto out;
- while ((out = fgets (buff, sizeof(buff),
- runner_chio (&runner, STDOUT_FILENO)))) {
- printf ("%s", out);
- }
- ret = runner_end (&runner);
- ret = WEXITSTATUS (ret);
+ ret = -1;
+ goto out;
+ }
+ if (global_state->mode & GLUSTER_MODE_GLFSHEAL_NOLOG)
+ runner_add_args(&runner, "--nolog", NULL);
+ ret = runner_start(&runner);
+ if (ret == -1)
+ goto out;
+ while ((
+ out = fgets(buff, sizeof(buff), runner_chio(&runner, STDOUT_FILENO)))) {
+ printf("%s", out);
+ }
+ ret = runner_end(&runner);
out:
- return ret;
+ return ret;
}
+
int
-cli_cmd_volume_heal_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+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;
- cli_local_t *local = NULL;
- int heal_op = 0;
-
- 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;
- }
+ 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;
+ cli_local_t *local = NULL;
+ int heal_op = 0;
+
+ this = THIS;
+
+ 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;
- }
- ret = dict_get_int32 (options, "heal-op", &heal_op);
+ ret = cli_cmd_volume_heal_options_parse(words, wordcount, &options);
+ if (ret) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
+ ret = dict_get_int32(options, "heal-op", &heal_op);
+ if (ret < 0)
+ goto out;
+ if (NEEDS_GLFS_HEAL(heal_op)) {
+ ret = cli_launch_glfs_heal(heal_op, options);
if (ret < 0)
- goto out;
- if (NEEDS_GLFS_HEAL (heal_op)) {
- ret = cli_launch_glfs_heal (heal_op, options);
- if (ret == -1)
- goto out;
- }
- else {
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_HEAL_VOLUME];
+ goto out;
+ if (heal_op != GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE)
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_HEAL_VOLUME];
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
- }
+ frame = create_frame(this, this->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ CLI_LOCAL_INIT(local, words, frame, options);
+ 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 (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0) &&
+ !(global_state->mode & GLUSTER_MODE_XML)) {
+ cli_out("Volume heal failed.");
}
+ }
+
+ if (options)
+ dict_unref(options);
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
int
-cli_cmd_volume_statedump_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+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;
- cli_local_t *local = NULL;
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ 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;
+ cli_local_t *local = NULL;
+
+ if (wordcount < 3) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ 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);
}
+ }
- 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;
- ret = dict_set_str (options, "volname", (char *)words[2]);
- if (ret)
- goto out;
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATEDUMP_VOLUME];
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_STATEDUMP_VOLUME];
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume statedump failed");
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
int
-cli_cmd_volume_list_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+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);
+ int ret = -1;
+ call_frame_t *frame = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ int sent = 0;
+
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_LIST_VOLUME];
+ if (proc->fn) {
+ 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);
- }
+ goto out;
+ ret = proc->fn(frame, THIS, NULL);
+ }
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if (sent == 0)
- cli_out ("Volume list failed");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if (sent == 0)
+ cli_out("Volume list failed");
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
int
-cli_cmd_volume_clearlocks_cbk (struct cli_state *state,
- struct cli_cmd_word *word,
- const char **words, int wordcount)
+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;
- cli_local_t *local = NULL;
-
- 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);
- }
+ 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;
+ cli_local_t *local = NULL;
+
+ 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, "volname", (char *)words[2]);
- if (ret)
- goto out;
+ ret = dict_set_str(options, "path", (char *)words[3]);
+ 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];
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_CLRLOCKS_VOLUME];
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn) {
- ret = proc->fn (frame, THIS, options);
- }
+ 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");
- }
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_out("Volume clear-locks failed");
+ }
- CLI_STACK_DESTROY (frame);
+ CLI_STACK_DESTROY(frame);
- return ret;
+ return ret;
}
int
-cli_cmd_volume_barrier_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_barrier_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;
- cli_local_t *local = NULL;
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ 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;
+ cli_local_t *local = NULL;
+
+ if (wordcount != 4) {
+ cli_usage_out(word->pattern);
+ parse_error = 1;
+ goto out;
+ }
- if (wordcount != 4) {
- cli_usage_out (word->pattern);
- parse_error = 1;
- goto out;
- }
+ options = dict_new();
+ if (!options) {
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_str(options, "volname", (char *)words[2]);
+ if (ret)
+ goto out;
- options = dict_new();
- if (!options) {
- ret = -1;
- goto out;
- }
- ret = dict_set_str(options, "volname", (char *)words[2]);
- if (ret)
- goto out;
+ ret = dict_set_str(options, "barrier", (char *)words[3]);
+ if (ret)
+ goto out;
- ret = dict_set_str (options, "barrier", (char *)words[3]);
- if (ret)
- goto out;
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_BARRIER_VOLUME];
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_BARRIER_VOLUME];
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn)
- ret = proc->fn (frame, THIS, options);
+ 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_err ("Volume barrier failed");
- }
- CLI_STACK_DESTROY (frame);
- if (options)
- dict_unref (options);
-
- return ret;
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_error == 0))
+ cli_err("Volume barrier failed");
+ }
+ CLI_STACK_DESTROY(frame);
+
+ return ret;
}
int
-cli_cmd_volume_getopt_cbk (struct cli_state *state, struct cli_cmd_word *word,
- const char **words, int wordcount)
+cli_cmd_volume_getopt_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_err = 0;
- cli_local_t *local = NULL;
-
- if (wordcount != 4) {
- cli_usage_out (word->pattern);
- parse_err = 1;
- goto out;
- }
+ int ret = -1;
+ rpc_clnt_procedure_t *proc = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *options = NULL;
+ int sent = 0;
+ int parse_err = 0;
+ cli_local_t *local = NULL;
+
+ if (wordcount != 4) {
+ cli_usage_out(word->pattern);
+ parse_err = 1;
+ goto out;
+ }
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
+ options = dict_new();
+ if (!options)
+ goto out;
- options = dict_new ();
- if (!options)
- goto out;
+ ret = dict_set_str(options, "volname", (char *)words[2]);
+ if (ret)
+ goto out;
- ret = dict_set_str (options, "volname", (char *)words[2]);
- if (ret)
- goto out;
+ ret = dict_set_str(options, "key", (char *)words[3]);
+ if (ret)
+ goto out;
- ret = dict_set_str (options, "key", (char *)words[3]);
- if (ret)
- goto out;
+ proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_VOL_OPT];
- proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GET_VOL_OPT];
+ frame = create_frame(THIS, THIS->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
- CLI_LOCAL_INIT (local, words, frame, options);
+ CLI_LOCAL_INIT(local, words, frame, options);
- if (proc->fn)
- ret = proc->fn (frame, THIS, options);
+ if (proc->fn)
+ ret = proc->fn(frame, THIS, options);
out:
- if (ret) {
- cli_cmd_sent_status_get (&sent);
- if ((sent == 0) && (parse_err == 0))
- cli_err ("Volume get option failed");
- }
- CLI_STACK_DESTROY (frame);
- if (options)
- dict_unref (options);
- return ret;
+ if (ret) {
+ cli_cmd_sent_status_get(&sent);
+ if ((sent == 0) && (parse_err == 0))
+ cli_err("Volume get option failed");
+ }
+ CLI_STACK_DESTROY(frame);
+ return ret;
}
+/* This is a bit of a hack to display the help. The current bitrot cmd
+ * format does not work well when registering the cmds.
+ * Ideally the should have been of the form
+ * gluster volume bitrot <subcommand> <volumename> ...
+ */
+
+struct cli_cmd bitrot_cmds[] = {
+
+ {"volume bitrot help", cli_cmd_bitrot_help_cbk,
+ "display help for volume bitrot commands"},
+
+ {"volume bitrot <VOLNAME> {enable|disable}", NULL, /*cli_cmd_bitrot_cbk,*/
+ "Enable/disable bitrot for volume <VOLNAME>"},
+
+ {"volume bitrot <VOLNAME> signing-time <time-in-secs>",
+ NULL, /*cli_cmd_bitrot_cbk,*/
+ "Waiting time for an object after last fd is closed to start signing "
+ "process"},
+
+ {"volume bitrot <VOLNAME> signer-threads <count>",
+ NULL, /*cli_cmd_bitrot_cbk,*/
+ "Number of signing process threads. Usually set to number of available "
+ "cores"},
+
+ {"volume bitrot <VOLNAME> scrub-throttle {lazy|normal|aggressive}",
+ NULL, /*cli_cmd_bitrot_cbk,*/
+ "Set the speed of the scrubber for volume <VOLNAME>"},
+
+ {"volume bitrot <VOLNAME> scrub-frequency {hourly|daily|weekly|biweekly"
+ "|monthly}",
+ NULL, /*cli_cmd_bitrot_cbk,*/
+ "Set the frequency of the scrubber for volume <VOLNAME>"},
+
+ {"volume bitrot <VOLNAME> scrub {pause|resume|status|ondemand}",
+ NULL, /*cli_cmd_bitrot_cbk,*/
+ "Pause/resume the scrubber for <VOLNAME>. Status displays the status of "
+ "the scrubber. ondemand starts the scrubber immediately."},
+
+ {"volume bitrot <VOLNAME> {enable|disable}\n"
+ "volume bitrot <VOLNAME> signing-time <time-in-secs>\n"
+ "volume bitrot <VOLNAME> signer-threads <count>\n"
+ "volume bitrot <volname> scrub-throttle {lazy|normal|aggressive}\n"
+ "volume bitrot <volname> scrub-frequency {hourly|daily|weekly|biweekly"
+ "|monthly}\n"
+ "volume bitrot <volname> scrub {pause|resume|status|ondemand}",
+ cli_cmd_bitrot_cbk, NULL},
+
+ {NULL, NULL, NULL}};
+
+struct cli_cmd quota_cmds[] = {
+
+ /* Quota commands */
+ {"volume quota help", cli_cmd_quota_help_cbk,
+ "display help for volume quota commands"},
+
+ {"volume quota <VOLNAME> {enable|disable|list [<path> ...]| "
+ "list-objects [<path> ...] | remove <path>| remove-objects <path> | "
+ "default-soft-limit <percent>}",
+ cli_cmd_quota_cbk, "Enable/disable and configure quota for <VOLNAME>"},
+
+ {"volume quota <VOLNAME> {limit-usage <path> <size> [<percent>]}",
+ cli_cmd_quota_cbk, "Set maximum size for <path> for <VOLNAME>"},
+
+ {"volume quota <VOLNAME> {limit-objects <path> <number> [<percent>]}",
+ cli_cmd_quota_cbk,
+ "Set the maximum number of entries allowed in <path> for <VOLNAME>"},
+
+ {"volume quota <VOLNAME> {alert-time|soft-timeout|hard-timeout} {<time>}",
+ cli_cmd_quota_cbk, "Set quota timeout for <VOLNAME>"},
+
+ {"volume inode-quota <VOLNAME> enable", cli_cmd_quota_cbk,
+ "Enable/disable inode-quota for <VOLNAME>"},
+
+ {"volume quota <VOLNAME> {enable|disable|list [<path> ...]| "
+ "list-objects [<path> ...] | remove <path>| remove-objects <path> | "
+ "default-soft-limit <percent>}\n"
+ "volume quota <VOLNAME> {limit-usage <path> <size> [<percent>]}\n"
+ "volume quota <VOLNAME> {limit-objects <path> <number> [<percent>]}\n"
+ "volume quota <VOLNAME> {alert-time|soft-timeout|hard-timeout} {<time>}",
+ cli_cmd_quota_cbk, NULL},
+
+ {NULL, NULL, NULL}};
+
struct cli_cmd volume_cmds[] = {
- { "volume info [all|<VOLNAME>]",
- cli_cmd_volume_info_cbk,
- "list information of all volumes"},
-
- { "volume create <NEW-VOLNAME> [stripe <COUNT>] "
- "[replica <COUNT> [arbiter <COUNT>]] "
- "[disperse [<COUNT>]] [disperse-data <COUNT>] [redundancy <COUNT>] "
- "[transport <tcp|rdma|tcp,rdma>] <NEW-BRICK>"
-#ifdef HAVE_BD_XLATOR
- "?<vg_name>"
-#endif
- "... [force]",
-
- cli_cmd_volume_create_cbk,
- "create a new volume of specified type with mentioned bricks"},
-
- { "volume delete <VOLNAME>",
- cli_cmd_volume_delete_cbk,
- "delete volume specified by <VOLNAME>"},
-
- { "volume start <VOLNAME> [force]",
- cli_cmd_volume_start_cbk,
- "start volume specified by <VOLNAME>"},
-
- { "volume stop <VOLNAME> [force]",
- cli_cmd_volume_stop_cbk,
- "stop volume specified by <VOLNAME>"},
-
- /*{ "volume rename <VOLNAME> <NEW-VOLNAME>",
- cli_cmd_volume_rename_cbk,
- "rename volume <VOLNAME> to <NEW-VOLNAME>"},*/
-
- { "volume tier <VOLNAME> status\n"
- "volume tier <VOLNAME> attach [<replica COUNT>] <NEW-BRICK>...\n"
- "volume tier <VOLNAME> detach <start|stop|status|commit|[force]>\n",
- cli_cmd_volume_tier_cbk,
- "Tier translator specific operations."},
-
- { "volume attach-tier <VOLNAME> [<replica COUNT>] <NEW-BRICK>...",
- cli_cmd_volume_tier_cbk,
- "NOTE: this is old syntax, will be depreciated in next release. "
- "Please use gluster volume tier <vol> attach "
- "[<replica COUNT>] <NEW-BRICK>..."},
-
- { "volume detach-tier <VOLNAME> "
- " <start|stop|status|commit|[force]>",
- cli_cmd_volume_tier_cbk,
- "NOTE: this is old syntax, will be depreciated in next release. "
- "Please use gluster volume tier <vol> detach "
- "{start|stop|commit} [force]"},
-
- { "volume add-brick <VOLNAME> [<stripe|replica> <COUNT>] <NEW-BRICK> ... [force]",
- cli_cmd_volume_add_brick_cbk,
- "add brick to volume <VOLNAME>"},
-
- { "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 start} | {start [force]|stop|status}}",
- cli_cmd_volume_defrag_cbk,
- "rebalance operations"},
-
- { "volume replace-brick <VOLNAME> <SOURCE-BRICK> <NEW-BRICK> "
- "{commit force}",
- cli_cmd_volume_replace_brick_cbk,
- "replace-brick operations"},
-
- /*{ "volume set-transport <VOLNAME> <TRANSPORT-TYPE> [<TRANSPORT-TYPE>] ...",
- cli_cmd_volume_set_transport_cbk,
- "set transport type for volume <VOLNAME>"},*/
-
- { "volume set <VOLNAME> <KEY> <VALUE>",
- cli_cmd_volume_set_cbk,
- "set options for volume <VOLNAME>"},
-
- { "volume help",
- cli_cmd_volume_help_cbk,
- "display help for the volume command"},
-
- { "volume log <VOLNAME> rotate [BRICK]",
- cli_cmd_log_rotate_cbk,
- "rotate 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"
- " NOTE: This is an old syntax, will be deprecated from next release."},
-
- { "volume sync <HOSTNAME> [all|<VOLNAME>]",
- cli_cmd_sync_volume_cbk,
- "sync the volume information from a peer"},
-
- { "volume reset <VOLNAME> [option] [force]",
- cli_cmd_volume_reset_cbk,
- "reset all the reconfigured options"},
+ {"volume help", cli_cmd_volume_help_cbk,
+ "display help for volume commands"},
+
+ {"volume info [all|<VOLNAME>]", cli_cmd_volume_info_cbk,
+ "list information of all volumes"},
+
+ {"volume create <NEW-VOLNAME> [stripe <COUNT>] "
+ "[[replica <COUNT> [arbiter <COUNT>]]|[replica 2 thin-arbiter 1]] "
+ "[disperse [<COUNT>]] [disperse-data <COUNT>] [redundancy <COUNT>] "
+ "[transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> <TA-BRICK>"
+ "... [force]",
+
+ cli_cmd_volume_create_cbk,
+ "create a new volume of specified type with mentioned bricks"},
+
+ {"volume delete <VOLNAME>", cli_cmd_volume_delete_cbk,
+ "delete volume specified by <VOLNAME>"},
+
+ {"volume start <VOLNAME> [force]", cli_cmd_volume_start_cbk,
+ "start volume specified by <VOLNAME>"},
+
+ {"volume stop <VOLNAME> [force]", cli_cmd_volume_stop_cbk,
+ "stop volume specified by <VOLNAME>"},
+
+ /*{ "volume rename <VOLNAME> <NEW-VOLNAME>",
+ cli_cmd_volume_rename_cbk,
+ "rename volume <VOLNAME> to <NEW-VOLNAME>"},*/
+
+ {"volume add-brick <VOLNAME> [<stripe|replica> <COUNT> "
+ "[arbiter <COUNT>]] <NEW-BRICK> ... [force]",
+ cli_cmd_volume_add_brick_cbk, "add brick to volume <VOLNAME>"},
+
+ {"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 start} | {start "
+ "[force]|stop|status}}",
+ cli_cmd_volume_defrag_cbk, "rebalance operations"},
+
+ {"volume replace-brick <VOLNAME> <SOURCE-BRICK> <NEW-BRICK> "
+ "{commit force}",
+ cli_cmd_volume_replace_brick_cbk, "replace-brick operations"},
+
+ /*{ "volume set-transport <VOLNAME> <TRANSPORT-TYPE> [<TRANSPORT-TYPE>]
+ ...", cli_cmd_volume_set_transport_cbk, "set transport type for volume
+ <VOLNAME>"},*/
+
+ {"volume set <VOLNAME> <KEY> <VALUE>", cli_cmd_volume_set_cbk,
+ "set options for volume <VOLNAME>"},
+
+ {"volume set <VOLNAME> group <GROUP>", cli_cmd_volume_set_cbk,
+ "This option can be used for setting multiple pre-defined volume options "
+ "where group_name is a file under /var/lib/glusterd/groups containing one "
+ "key value pair per line"},
+
+ {"volume log <VOLNAME> rotate [BRICK]", cli_cmd_log_rotate_cbk,
+ "rotate the log file for corresponding volume/brick"},
+
+ {"volume sync <HOSTNAME> [all|<VOLNAME>]", cli_cmd_sync_volume_cbk,
+ "sync the volume information from a peer"},
+
+ {"volume reset <VOLNAME> [option] [force]", cli_cmd_volume_reset_cbk,
+ "reset all the reconfigured options"},
#if (SYNCDAEMON_COMPILE)
- {"volume "GEOREP" [<VOLNAME>] [<SLAVE-URL>] {create [[no-verify]|[push-pem]] [force]"
- "|start [force]|stop [force]|pause [force]|resume [force]|config|status [detail]|delete} [options...]",
- cli_cmd_volume_gsync_set_cbk,
- "Geo-sync operations",
- cli_cmd_check_gsync_exists_cbk},
+ {"volume " GEOREP " [<MASTER-VOLNAME>] [<SLAVE-IP>]::[<SLAVE-VOLNAME>] {"
+ "\\\n create [[ssh-port n] [[no-verify] \\\n | [push-pem]]] [force] \\\n"
+ " | start [force] \\\n | stop [force] \\\n | pause [force] \\\n | resume "
+ "[force] \\\n"
+ " | config [[[\\!]<option>] [<value>]] \\\n | status "
+ "[detail] \\\n | delete [reset-sync-time]} ",
+ cli_cmd_volume_gsync_set_cbk, "Geo-sync operations",
+ cli_cmd_check_gsync_exists_cbk},
#endif
- { "volume profile <VOLNAME> {start|info [peek|incremental [peek]|cumulative|clear]|stop} [nfs]",
- cli_cmd_volume_profile_cbk,
- "volume profile operations"},
-
- { "volume quota <VOLNAME> {enable|disable|list [<path> ...]| "
- "list-objects [<path> ...] | remove <path>| remove-objects <path> | "
- "default-soft-limit <percent>} |\n"
- "volume quota <VOLNAME> {limit-usage <path> <size> [<percent>]} |\n"
- "volume quota <VOLNAME> {limit-objects <path> <number> [<percent>]} |\n"
- "volume quota <VOLNAME> {alert-time|soft-timeout|hard-timeout} {<time>}",
- cli_cmd_quota_cbk,
- "quota translator specific operations"},
-
- { "volume inode-quota <VOLNAME> enable",
- cli_cmd_quota_cbk,
- "quota translator specific operations"},
-
- { "volume top <VOLNAME> {open|read|write|opendir|readdir|clear} [nfs|brick <brick>] [list-cnt <value>] |\n"
- "volume top <VOLNAME> {read-perf|write-perf} [bs <size> count <count>] [brick <brick>] [list-cnt <value>]",
- cli_cmd_volume_top_cbk,
- "volume top operations"},
-
- { "volume status [all | <VOLNAME> [nfs|shd|<BRICK>|quotad]]"
- " [detail|clients|mem|inode|fd|callpool|tasks]",
- cli_cmd_volume_status_cbk,
- "display status of all or specified volume(s)/brick"},
-
- { "volume heal <VOLNAME> [enable | disable | full |"
- "statistics [heal-count [replica <HOSTNAME:BRICKNAME>]] |"
- "info [healed | heal-failed | split-brain] |"
- "split-brain {bigger-file <FILE> |"
- "source-brick <HOSTNAME:BRICKNAME> [<FILE>]}]",
- cli_cmd_volume_heal_cbk,
- "self-heal commands on volume specified by <VOLNAME>"},
-
- {"volume statedump <VOLNAME> [nfs|quotad] [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"
- },
- {"volume barrier <VOLNAME> {enable|disable}",
- cli_cmd_volume_barrier_cbk,
- "Barrier/unbarrier file operations on a volume"
- },
- {"volume get <VOLNAME> <key|all>",
- cli_cmd_volume_getopt_cbk,
- "Get the value of the all options or given option for volume <VOLNAME>"
- },
- {"volume bitrot <VOLNAME> {enable|disable} |\n"
- "volume bitrot <volname> scrub-throttle {lazy|normal|aggressive} |\n"
- "volume bitrot <volname> scrub-frequency {hourly|daily|weekly|biweekly"
- "|monthly} |\n"
- "volume bitrot <volname> scrub {pause|resume}",
- cli_cmd_bitrot_cbk,
- "Bitrot translator specific operation. For more information about "
- "bitrot command type 'man gluster'"
- },
- { NULL, NULL, NULL }
-};
+ {"volume profile <VOLNAME> {start|info [peek|incremental "
+ "[peek]|cumulative|clear]|stop} [nfs]",
+ cli_cmd_volume_profile_cbk, "volume profile operations"},
+
+ {"volume top <VOLNAME> {open|read|write|opendir|readdir|clear} [nfs|brick "
+ "<brick>] [list-cnt <value>] | "
+ "{read-perf|write-perf} [bs <size> count <count>] "
+ "[brick <brick>] [list-cnt <value>]",
+ cli_cmd_volume_top_cbk, "volume top operations"},
+
+ {"volume status [all | <VOLNAME> [nfs|shd|<BRICK>|quotad]]"
+ " [detail|clients|mem|inode|fd|callpool|tasks|client-list]",
+ cli_cmd_volume_status_cbk,
+ "display status of all or specified volume(s)/brick"},
+
+ {"volume heal <VOLNAME> [enable | disable | full |"
+ "statistics [heal-count [replica <HOSTNAME:BRICKNAME>]] |"
+ "info [summary | split-brain] |"
+ "split-brain {bigger-file <FILE> | latest-mtime <FILE> |"
+ "source-brick <HOSTNAME:BRICKNAME> [<FILE>]} |"
+ "granular-entry-heal {enable | disable}]",
+ cli_cmd_volume_heal_cbk,
+ "self-heal commands on volume specified by <VOLNAME>"},
+
+ {"volume statedump <VOLNAME> [[nfs|quotad] [all|mem|iobuf|callpool|"
+ "priv|fd|inode|history]... | [client <hostname:process-id>]]",
+ 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"},
+ {"volume barrier <VOLNAME> {enable|disable}", cli_cmd_volume_barrier_cbk,
+ "Barrier/unbarrier file operations on a volume"},
+ {"volume get <VOLNAME|all> <key|all>", cli_cmd_volume_getopt_cbk,
+ "Get the value of the all options or given option for volume <VOLNAME>"
+ " or all option. gluster volume get all all is to get all global "
+ "options"},
+
+ {"volume reset-brick <VOLNAME> <SOURCE-BRICK> {{start} |"
+ " {<NEW-BRICK> commit}}",
+ cli_cmd_volume_reset_brick_cbk, "reset-brick operations"},
+
+ {NULL, NULL, NULL}};
int
-cli_cmd_volume_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
- const char **words, int wordcount)
+cli_cmd_quota_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount)
{
- struct cli_cmd *cmd = NULL;
+ struct cli_cmd *cmd = NULL;
+ struct cli_cmd *quota_cmd = NULL;
+ int count = 0;
- for (cmd = volume_cmds; cmd->pattern; cmd++)
- if (_gf_false == cmd->disable)
- cli_out ("%s - %s", cmd->pattern, cmd->desc);
+ cmd = GF_MALLOC(sizeof(quota_cmds), cli_mt_cli_cmd);
+ memcpy(cmd, quota_cmds, sizeof(quota_cmds));
+ count = (sizeof(quota_cmds) / sizeof(struct cli_cmd));
+ cli_cmd_sort(cmd, count);
- return 0;
+ cli_out("\ngluster quota commands");
+ cli_out("=======================\n");
+
+ for (quota_cmd = cmd; quota_cmd->pattern; quota_cmd++)
+ if ((_gf_false == quota_cmd->disable) && (quota_cmd->desc))
+ cli_out("%s - %s", quota_cmd->pattern, quota_cmd->desc);
+
+ cli_out("\n");
+ GF_FREE(cmd);
+
+ return 0;
}
int
-cli_cmd_volume_register (struct cli_state *state)
+cli_cmd_bitrot_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount)
{
- int ret = 0;
- struct cli_cmd *cmd = NULL;
+ struct cli_cmd *cmd = NULL;
+ struct cli_cmd *bitrot_cmd = NULL;
+ int count = 0;
- for (cmd = volume_cmds; cmd->pattern; cmd++) {
+ cmd = GF_MALLOC(sizeof(bitrot_cmds), cli_mt_cli_cmd);
+ memcpy(cmd, bitrot_cmds, sizeof(bitrot_cmds));
+ count = (sizeof(bitrot_cmds) / sizeof(struct cli_cmd));
+ cli_cmd_sort(cmd, count);
+
+ cli_out("\ngluster bitrot commands");
+ cli_out("========================\n");
+
+ for (bitrot_cmd = cmd; bitrot_cmd->pattern; bitrot_cmd++)
+ if ((_gf_false == bitrot_cmd->disable) && (bitrot_cmd->desc))
+ cli_out("%s - %s", bitrot_cmd->pattern, bitrot_cmd->desc);
+
+ cli_out("\n");
+ GF_FREE(cmd);
+
+ return 0;
+}
+
+int
+cli_cmd_volume_help_cbk(struct cli_state *state, struct cli_cmd_word *in_word,
+ const char **words, int wordcount)
+{
+ struct cli_cmd *cmd = NULL;
+ struct cli_cmd *vol_cmd = NULL;
+ int count = 0;
+
+ cmd = GF_MALLOC(sizeof(volume_cmds), cli_mt_cli_cmd);
+ memcpy(cmd, volume_cmds, sizeof(volume_cmds));
+ count = (sizeof(volume_cmds) / sizeof(struct cli_cmd));
+ cli_cmd_sort(cmd, count);
+
+ cli_out("\ngluster volume commands");
+ cli_out("========================\n");
+
+ for (vol_cmd = cmd; vol_cmd->pattern; vol_cmd++)
+ if (_gf_false == vol_cmd->disable)
+ cli_out("%s - %s", vol_cmd->pattern, vol_cmd->desc);
+
+ cli_out("\n");
+ GF_FREE(cmd);
+ return 0;
+}
+
+int
+cli_cmd_volume_register(struct cli_state *state)
+{
+ int ret = 0;
+ struct cli_cmd *cmd = NULL;
+
+ for (cmd = volume_cmds; cmd->pattern; cmd++) {
+ ret = cli_cmd_register(&state->tree, cmd);
+ if (ret)
+ goto out;
+ }
+
+ for (cmd = bitrot_cmds; cmd->pattern; cmd++) {
+ ret = cli_cmd_register(&state->tree, cmd);
+ if (ret)
+ goto out;
+ }
+
+ for (cmd = quota_cmds; cmd->pattern; cmd++) {
+ ret = cli_cmd_register(&state->tree, cmd);
+ if (ret)
+ goto out;
+ }
- ret = cli_cmd_register (&state->tree, cmd);
- if (ret)
- goto out;
- }
out:
- return ret;
+ return ret;
+}
+
+static int
+gf_asprintf_append(char **string_ptr, const char *format, ...)
+{
+ va_list arg;
+ int rv = 0;
+ char *tmp = *string_ptr;
+
+ va_start(arg, format);
+ rv = gf_vasprintf(string_ptr, format, arg);
+ va_end(arg);
+
+ if (tmp)
+ GF_FREE(tmp);
+
+ return rv;
}
diff --git a/cli/src/cli-cmd.c b/cli/src/cli-cmd.c
index 99448fcae56..2d458b16a56 100644
--- a/cli/src/cli-cmd.c
+++ b/cli/src/cli-cmd.c
@@ -22,371 +22,390 @@
static int cmd_done;
static int cmd_sent;
-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t conn = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t conn = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
-int cli_op_ret = 0;
-int connected = 0;
-
-int cli_cmd_log_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word,
- const char **words, int wordcount);
+int cli_op_ret = 0;
+static gf_boolean_t connected = _gf_false;
static unsigned
-cli_cmd_needs_connection (struct cli_cmd_word *word)
+cli_cmd_needs_connection(struct cli_cmd_word *word)
{
- if (!strcasecmp ("quit", word->word))
- return 0;
+ if (!strcasecmp("quit", word->word))
+ return 0;
- if (!strcasecmp ("help", word->word))
- return 0;
+ if (!strcasecmp("help", word->word))
+ return 0;
- if (!strcasecmp ("getwd", word->word))
- return 1;
+ if (!strcasecmp("getwd", word->word))
+ return 1;
- if (!strcasecmp ("exit", word->word))
- return 0;
+ if (!strcasecmp("exit", word->word))
+ return 0;
- return CLI_DEFAULT_CONN_TIMEOUT;
+ return cli_default_conn_timeout;
}
int
-cli_cmd_status_reset (void)
+cli_cmd_status_reset(void)
{
- int ret = 0;
-
- ret = cli_cmd_lock ();
- {
- if (ret == 0) {
- cmd_sent = 0;
- cmd_done = 0;
- }
- }
- ret = cli_cmd_unlock ();
- return ret;
+ int ret = 0;
+ ret = cli_cmd_lock();
+ {
+ if (ret == 0) {
+ cmd_sent = 0;
+ cmd_done = 0;
+ }
+ }
+ ret = cli_cmd_unlock();
+ return ret;
}
int
-cli_cmd_sent_status_get (int *status)
+cli_cmd_sent_status_get(int *status)
{
- int ret = 0;
- GF_ASSERT (status);
-
- ret = cli_cmd_lock ();
- {
- if (ret == 0)
- *status = cmd_sent;
- }
- ret = cli_cmd_unlock ();
- return ret;
+ int ret = 0;
+ GF_ASSERT(status);
+
+ ret = cli_cmd_lock();
+ {
+ if (ret == 0)
+ *status = cmd_sent;
+ }
+ ret = cli_cmd_unlock();
+ return ret;
}
int
-cli_cmd_process (struct cli_state *state, int argc, char **argv)
+cli_cmd_process(struct cli_state *state, int argc, char **argv)
{
- int ret = 0;
- struct cli_cmd_word *word = NULL;
- struct cli_cmd_word *next = NULL;
- int i = 0;
+ int ret = 0;
+ struct cli_cmd_word *word = NULL;
+ struct cli_cmd_word *next = NULL;
+ int i = 0;
- word = &state->tree.root;
+ word = &state->tree.root;
- if (!argc)
- return 0;
+ if (!argc)
+ return 0;
- for (i = 0; i < argc; i++) {
- next = cli_cmd_nextword (word, argv[i]);
+ for (i = 0; i < argc; i++) {
+ next = cli_cmd_nextword(word, argv[i]);
- word = next;
- if (!word)
- break;
+ word = next;
+ if (!word)
+ break;
- if (word->cbkfn)
- break;
- }
+ if (word->cbkfn)
+ break;
+ }
- if (!word) {
- cli_out ("unrecognized word: %s (position %d)",
- argv[i], i);
- return -1;
- }
+ if (!word) {
+ cli_out("unrecognized word: %s (position %d)\n", argv[i], i);
+ usage();
+ return -1;
+ }
- if (!word->cbkfn) {
- cli_out ("unrecognized command");
- return -1;
- }
+ if (!word->cbkfn) {
+ cli_out("unrecognized command\n");
+ usage();
+ return -1;
+ }
- if ( strcmp (word->word,"help")==0 )
- goto callback;
+ if (strcmp(word->word, "help") == 0)
+ goto callback;
- state->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.");
- gf_log ("", GF_LOG_INFO, "Exiting with: %d", ret);
- exit (ret);
- }
+ ret = cli_cmd_await_connected(state->await_connected);
+ if (ret) {
+ cli_out(
+ "Connection failed. Please check if gluster "
+ "daemon is operational.");
+ gf_log("", GF_LOG_INFO, "Exiting with: %d", ret);
+ exit(ret);
+ }
callback:
- ret = word->cbkfn (state, word, (const char **)argv, argc);
- (void) cli_cmd_status_reset ();
- return ret;
+ ret = word->cbkfn(state, word, (const char **)argv, argc);
+ (void)cli_cmd_status_reset();
+ return ret;
}
int
-cli_cmd_input_token_count (const char *text)
+cli_cmd_input_token_count(const char *text)
{
- int count = 0;
- const char *trav = NULL;
- int is_spc = 1;
-
- for (trav = text; *trav; trav++) {
- if (*trav == ' ') {
- is_spc = 1;
- } else {
- if (is_spc) {
- count++;
- is_spc = 0;
- }
- }
+ int count = 0;
+ const char *trav = NULL;
+ int is_spc = 1;
+
+ for (trav = text; *trav; trav++) {
+ if (*trav == ' ') {
+ is_spc = 1;
+ } else {
+ if (is_spc) {
+ count++;
+ is_spc = 0;
+ }
}
+ }
- return count;
+ return count;
}
-
int
-cli_cmd_process_line (struct cli_state *state, const char *text)
+cli_cmd_process_line(struct cli_state *state, const char *text)
{
- int count = 0;
- char **tokens = NULL;
- char **tokenp = NULL;
- char *token = NULL;
- char *copy = NULL;
- char *saveptr = NULL;
- int i = 0;
- int ret = -1;
-
- count = cli_cmd_input_token_count (text);
-
- tokens = calloc (count + 1, sizeof (*tokens));
- if (!tokens)
- return -1;
-
- copy = strdup (text);
- if (!copy)
- goto out;
-
- tokenp = tokens;
-
- for (token = strtok_r (copy, " \t\r\n", &saveptr); token;
- token = strtok_r (NULL, " \t\r\n", &saveptr)) {
- *tokenp = strdup (token);
-
- if (!*tokenp)
- goto out;
- tokenp++;
- i++;
-
- }
-
- ret = cli_cmd_process (state, count, tokens);
+ int count = 0;
+ char **tokens = NULL;
+ char **tokenp = NULL;
+ char *token = NULL;
+ char *copy = NULL;
+ char *saveptr = NULL;
+ int i = 0;
+ int ret = -1;
+
+ count = cli_cmd_input_token_count(text);
+
+ tokens = calloc(count + 1, sizeof(*tokens));
+ if (!tokens)
+ return -1;
+
+ copy = strdup(text);
+ if (!copy)
+ goto out;
+
+ tokenp = tokens;
+
+ for (token = strtok_r(copy, " \t\r\n", &saveptr); token;
+ token = strtok_r(NULL, " \t\r\n", &saveptr)) {
+ *tokenp = strdup(token);
+
+ if (!*tokenp)
+ goto out;
+ tokenp++;
+ i++;
+ }
+
+ ret = cli_cmd_process(state, count, tokens);
out:
- free (copy);
+ free(copy);
- if (tokens)
- cli_cmd_tokens_destroy (tokens);
+ if (tokens)
+ cli_cmd_tokens_destroy(tokens);
- return ret;
+ return ret;
}
-
int
-cli_cmds_register (struct cli_state *state)
+cli_cmds_register(struct cli_state *state)
{
- int ret = 0;
-
- ret = cli_cmd_volume_register (state);
- if (ret)
- goto out;
-
- ret = cli_cmd_probe_register (state);
- if (ret)
- goto out;
-
- ret = cli_cmd_system_register (state);
- if (ret)
- goto out;
-
- ret = cli_cmd_misc_register (state);
- if (ret)
- goto out;
-
- ret = cli_cmd_snapshot_register (state);
- if (ret)
- goto out;
- ret = cli_cmd_global_register (state);
- if (ret)
- goto out;
+ int ret = 0;
+
+ ret = cli_cmd_volume_register(state);
+ if (ret)
+ goto out;
+
+ ret = cli_cmd_probe_register(state);
+ if (ret)
+ goto out;
+
+ ret = cli_cmd_system_register(state);
+ if (ret)
+ goto out;
+
+ ret = cli_cmd_misc_register(state);
+ if (ret)
+ goto out;
+
+ ret = cli_cmd_snapshot_register(state);
+ if (ret)
+ goto out;
+ ret = cli_cmd_global_register(state);
+ if (ret)
+ goto out;
out:
- return ret;
-}
-
-int
-cli_cmd_cond_init ()
-{
-
- pthread_mutex_init (&cond_mutex, NULL);
- pthread_cond_init (&cond, NULL);
-
- pthread_mutex_init (&conn_mutex, NULL);
- pthread_cond_init (&conn, NULL);
-
- return 0;
+ return ret;
}
int
-cli_cmd_lock ()
+cli_cmd_lock()
{
- pthread_mutex_lock (&cond_mutex);
- return 0;
+ pthread_mutex_lock(&cond_mutex);
+ return 0;
}
int
-cli_cmd_unlock ()
+cli_cmd_unlock()
{
- pthread_mutex_unlock (&cond_mutex);
- return 0;
+ pthread_mutex_unlock(&cond_mutex);
+ return 0;
}
static void
-seconds_from_now (unsigned secs, struct timespec *ts)
+seconds_from_now(unsigned secs, struct timespec *ts)
{
- struct timeval tv = {0,};
+ struct timeval tv = {
+ 0,
+ };
- gettimeofday (&tv, NULL);
+ gettimeofday(&tv, NULL);
- ts->tv_sec = tv.tv_sec + secs;
- ts->tv_nsec = tv.tv_usec * 1000;
+ ts->tv_sec = tv.tv_sec + secs;
+ ts->tv_nsec = tv.tv_usec * 1000;
}
int
-cli_cmd_await_response (unsigned time)
+cli_cmd_await_response(unsigned time)
{
- struct timespec ts = {0,};
- int ret = 0;
+ struct timespec ts = {
+ 0,
+ };
+ int ret = 0;
- cli_op_ret = -1;
+ cli_op_ret = -1;
- seconds_from_now (time, &ts);
- while (!cmd_done && !ret) {
- ret = pthread_cond_timedwait (&cond, &cond_mutex,
- &ts);
- }
+ seconds_from_now(time, &ts);
+ while (!cmd_done && !ret) {
+ ret = pthread_cond_timedwait(&cond, &cond_mutex, &ts);
+ }
- if (!cmd_done) {
- if (ret == ETIMEDOUT)
- cli_out ("Error : Request timed out");
- else
- cli_out ("Error : Command returned with error code:%d",
- ret);
- }
- cmd_done = 0;
+ if (!cmd_done) {
+ if (ret == ETIMEDOUT)
+ cli_out("Error : Request timed out");
+ else
+ cli_out("Error : Command returned with error code:%d", ret);
+ }
+ cmd_done = 0;
- return cli_op_ret;
+ return cli_op_ret;
}
/* This function must be called _only_ after all actions associated with
* command processing is complete. Otherwise, gluster process may exit before
* reporting results to stdout/stderr. */
int
-cli_cmd_broadcast_response (int32_t status)
+cli_cmd_broadcast_response(int32_t status)
{
-
- pthread_mutex_lock (&cond_mutex);
- {
- if (!cmd_sent)
- goto out;
- cmd_done = 1;
- cli_op_ret = status;
- pthread_cond_broadcast (&cond);
- }
-
+ pthread_mutex_lock(&cond_mutex);
+ {
+ if (!cmd_sent)
+ goto out;
+ cmd_done = 1;
+ cli_op_ret = status;
+ pthread_cond_broadcast(&cond);
+ }
out:
- pthread_mutex_unlock (&cond_mutex);
- return 0;
+ pthread_mutex_unlock(&cond_mutex);
+ return 0;
}
int32_t
-cli_cmd_await_connected (unsigned conn_timo)
+cli_cmd_await_connected(unsigned conn_timo)
{
- int32_t ret = 0;
- struct timespec ts = {0,};
-
- if (!conn_timo)
- return 0;
-
- pthread_mutex_lock (&conn_mutex);
- {
- seconds_from_now (conn_timo, &ts);
- while (!connected && !ret) {
- ret = pthread_cond_timedwait (&conn, &conn_mutex,
- &ts);
- }
- }
- pthread_mutex_unlock (&conn_mutex);
+ int32_t ret = 0;
+ struct timespec ts = {
+ 0,
+ };
+ if (!conn_timo)
+ return 0;
- return ret;
+ pthread_mutex_lock(&conn_mutex);
+ {
+ seconds_from_now(conn_timo, &ts);
+ while (!connected && !ret) {
+ ret = pthread_cond_timedwait(&conn, &conn_mutex, &ts);
+ }
+ }
+ pthread_mutex_unlock(&conn_mutex);
+
+ return ret;
}
int32_t
-cli_cmd_broadcast_connected ()
+cli_cmd_broadcast_connected(gf_boolean_t status)
{
- pthread_mutex_lock (&conn_mutex);
- {
- connected = 1;
- pthread_cond_broadcast (&conn);
- }
-
- pthread_mutex_unlock (&conn_mutex);
-
- return 0;
+ pthread_mutex_lock(&conn_mutex);
+ {
+ connected = status;
+ pthread_cond_broadcast(&conn);
+ }
+ pthread_mutex_unlock(&conn_mutex);
+
+ return 0;
}
-int
-cli_cmd_submit (struct rpc_clnt* rpc, void *req, call_frame_t *frame,
- rpc_clnt_prog_t *prog,
- int procnum, struct iobref *iobref,
- xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
+gf_boolean_t
+cli_cmd_connected(void)
{
- int ret = -1;
- unsigned timeout = 0;
+ gf_boolean_t status;
- if ((GLUSTER_CLI_PROFILE_VOLUME == procnum) ||
- (GLUSTER_CLI_HEAL_VOLUME == procnum) ||
- (GLUSTER_CLI_GANESHA == procnum))
- timeout = CLI_TEN_MINUTES_TIMEOUT;
- else
- timeout = CLI_DEFAULT_CMD_TIMEOUT;
+ pthread_mutex_lock(&conn_mutex);
+ {
+ status = connected;
+ }
+ pthread_mutex_unlock(&conn_mutex);
- cli_cmd_lock ();
- cmd_sent = 0;
- ret = cli_submit_request (rpc, req, frame, prog,
- procnum, NULL, this, cbkfn, xdrproc);
+ return status;
+}
- if (!ret) {
- cmd_sent = 1;
- ret = cli_cmd_await_response (timeout);
- }
+int
+cli_cmd_submit(struct rpc_clnt *rpc, void *req, call_frame_t *frame,
+ rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref,
+ xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
+{
+ int ret = -1;
+ unsigned timeout = 0;
+
+ if ((GLUSTER_CLI_PROFILE_VOLUME == procnum) ||
+ (GLUSTER_CLI_HEAL_VOLUME == procnum) ||
+ (GLUSTER_CLI_GANESHA == procnum))
+ timeout = cli_ten_minutes_timeout;
+ else
+ timeout = cli_default_conn_timeout;
+
+ cli_cmd_lock();
+ cmd_sent = 0;
+ ret = cli_submit_request(rpc, req, frame, prog, procnum, NULL, this, cbkfn,
+ xdrproc);
+
+ if (!ret) {
+ cmd_sent = 1;
+ ret = cli_cmd_await_response(timeout);
+ }
+
+ cli_cmd_unlock();
+
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
- cli_cmd_unlock ();
+int
+cli_cmd_pattern_cmp(void *a, void *b)
+{
+ struct cli_cmd *ia = NULL;
+ struct cli_cmd *ib = NULL;
+ int ret = 0;
+
+ ia = a;
+ ib = b;
+ if (strcmp(ia->pattern, ib->pattern) > 0)
+ ret = 1;
+ else if (strcmp(ia->pattern, ib->pattern) < 0)
+ ret = -1;
+ else
+ ret = 0;
+ return ret;
+}
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+void
+cli_cmd_sort(struct cli_cmd *cmd, int count)
+{
+ gf_array_insertionsort(cmd, 1, count - 2, sizeof(struct cli_cmd),
+ cli_cmd_pattern_cmp);
}
diff --git a/cli/src/cli-cmd.h b/cli/src/cli-cmd.h
index 27f385fab85..c1c068c7085 100644
--- a/cli/src/cli-cmd.h
+++ b/cli/src/cli-cmd.h
@@ -13,106 +13,117 @@
#include <netdb.h>
#include "cli.h"
-#include "list.h"
-
-#define GLUSTER_SHARED_STORAGE "gluster_shared_storage"
-
-#define CLI_LOCAL_INIT(local, words, frame, dictionary) \
- do { \
- local = cli_local_get (); \
- \
- if (local) { \
- local->words = words; \
- if (dictionary) \
- local->dict = dictionary; \
- if (frame) \
- frame->local = local; \
- } \
- } while (0)
-
-#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,
- GF_ANSWER_NO = 2
-} gf_answer_t;
+#include <glusterfs/list.h>
+
+#define GLUSTER_SHARED_STORAGE "gluster_shared_storage"
+
+#define CLI_LOCAL_INIT(local, words, frame, dictionary) \
+ do { \
+ local = cli_local_get(); \
+ \
+ if (local) { \
+ local->words = words; \
+ if (dictionary) \
+ local->dict = dictionary; \
+ if (frame) \
+ frame->local = local; \
+ } \
+ } while (0)
+
+#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, GF_ANSWER_NO = 2 } gf_answer_t;
struct cli_cmd {
- const char *pattern;
- cli_cmd_cbk_t *cbk;
- const char *desc;
- cli_cmd_reg_cbk_t *reg_cbk; /* callback to check in runtime if the *
- * command should be enabled or disabled */
- gf_boolean_t disable;
+ const char *pattern;
+ cli_cmd_cbk_t *cbk;
+ const char *desc;
+ cli_cmd_reg_cbk_t *reg_cbk; /* callback to check in runtime if the *
+ * command should be enabled or disabled */
+ gf_boolean_t disable;
};
struct cli_cmd_volume_get_ctx_ {
- char *volname;
- int flags;
+ char *volname;
+ int flags;
};
typedef struct cli_profile_info_ {
- uint64_t fop_hits;
- double min_latency;
- double max_latency;
- double avg_latency;
- char *fop_name;
- double percentage_avg_latency;
+ uint64_t fop_hits;
+ double min_latency;
+ double max_latency;
+ double avg_latency;
+ char *fop_name;
+ double percentage_avg_latency;
} cli_profile_info_t;
typedef struct cli_cmd_volume_get_ctx_ cli_cmd_volume_get_ctx_t;
-int cli_cmd_volume_register (struct cli_state *state);
+int
+cli_cmd_volume_register(struct cli_state *state);
-int cli_cmd_probe_register (struct cli_state *state);
+int
+cli_cmd_probe_register(struct cli_state *state);
-int cli_cmd_system_register (struct cli_state *state);
+int
+cli_cmd_system_register(struct cli_state *state);
-int cli_cmd_snapshot_register (struct cli_state *state);
+int
+cli_cmd_snapshot_register(struct cli_state *state);
-int cli_cmd_global_register (struct cli_state *state);
+int
+cli_cmd_global_register(struct cli_state *state);
-int cli_cmd_misc_register (struct cli_state *state);
+int
+cli_cmd_misc_register(struct cli_state *state);
-struct cli_cmd_word *cli_cmd_nextword (struct cli_cmd_word *word,
- const char *text);
-void cli_cmd_tokens_destroy (char **tokens);
+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 (unsigned time);
+int
+cli_cmd_await_response(unsigned time);
-int cli_cmd_broadcast_response (int32_t status);
+int
+cli_cmd_broadcast_response(int32_t status);
-int cli_cmd_cond_init ();
+int
+cli_cmd_lock();
-int cli_cmd_lock ();
+int
+cli_cmd_unlock();
-int cli_cmd_unlock ();
+int
+cli_cmd_submit(struct rpc_clnt *rpc, void *req, call_frame_t *frame,
+ rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref,
+ xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
int
-cli_cmd_submit (struct rpc_clnt *rpc, void *req, call_frame_t *frame,
- rpc_clnt_prog_t *prog,
- int procnum, struct iobref *iobref,
- xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
+cli_cmd_pattern_cmp(void *a, void *b);
-gf_answer_t
-cli_cmd_get_confirmation (struct cli_state *state, const char *question);
-int cli_cmd_sent_status_get (int *status);
+void
+cli_cmd_sort(struct cli_cmd *cmd, int count);
-gf_boolean_t
-_limits_set_on_volume (char *volname, int type);
+gf_answer_t
+cli_cmd_get_confirmation(struct cli_state *state, const char *question);
+int
+cli_cmd_sent_status_get(int *status);
gf_boolean_t
-_quota_aux_mount_online (char *volname);
+_limits_set_on_volume(char *volname, int type);
#endif /* __CLI_CMD_H__ */
diff --git a/cli/src/cli-mem-types.h b/cli/src/cli-mem-types.h
index 09fcb639bd0..b42b4dd86c2 100644
--- a/cli/src/cli-mem-types.h
+++ b/cli/src/cli-mem-types.h
@@ -10,20 +10,21 @@
#ifndef __CLI_MEM_TYPES_H__
#define __CLI_MEM_TYPES_H__
-#include "mem-types.h"
+#include <glusterfs/mem-types.h>
#define CLI_MEM_TYPE_START (gf_common_mt_end + 1)
enum cli_mem_types_ {
- cli_mt_xlator_list_t = CLI_MEM_TYPE_START,
- cli_mt_xlator_t,
- cli_mt_xlator_cmdline_option_t,
- cli_mt_char,
- cli_mt_call_pool_t,
- cli_mt_cli_local_t,
- cli_mt_cli_get_vol_ctx_t,
- cli_mt_append_str,
- cli_mt_end
+ cli_mt_xlator_list_t = CLI_MEM_TYPE_START,
+ cli_mt_xlator_t,
+ cli_mt_xlator_cmdline_option_t,
+ cli_mt_char,
+ cli_mt_call_pool_t,
+ cli_mt_cli_local_t,
+ cli_mt_cli_get_vol_ctx_t,
+ cli_mt_append_str,
+ cli_mt_cli_cmd,
+ cli_mt_end
};
diff --git a/cli/src/cli-quotad-client.c b/cli/src/cli-quotad-client.c
index 5be9c80c858..772b8f75bd9 100644
--- a/cli/src/cli-quotad-client.c
+++ b/cli/src/cli-quotad-client.c
@@ -10,140 +10,137 @@
#include "cli-quotad-client.h"
-extern struct rpc_clnt global_quotad_rpc;
-extern struct rpc_clnt_program cli_quotad_clnt;
-
int
-cli_quotad_submit_request (void *req, call_frame_t *frame,
- rpc_clnt_prog_t *prog,
- int procnum, struct iobref *iobref,
- xlator_t *this, fop_cbk_fn_t cbkfn,
- xdrproc_t xdrproc)
+cli_quotad_submit_request(void *req, call_frame_t *frame, rpc_clnt_prog_t *prog,
+ int procnum, struct iobref *iobref, xlator_t *this,
+ fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
{
- int ret = -1;
- int count = 0;
- struct iovec iov = {0, };
- struct iobuf *iobuf = NULL;
- char new_iobref = 0;
- ssize_t xdr_size = 0;
-
- GF_ASSERT (this);
-
- 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;
- }
-
- new_iobref = 1;
- }
-
- iobref_add (iobref, iobuf);
-
- iov.iov_base = iobuf->ptr;
- iov.iov_len = iobuf_size (iobuf);
-
- /* Create the xdr payload */
- ret = xdr_serialize_generic (iov, req, xdrproc);
- if (ret == -1) {
- goto out;
- }
- iov.iov_len = ret;
- count = 1;
+ int ret = -1;
+ int count = 0;
+ struct iovec iov = {
+ 0,
+ };
+ struct iobuf *iobuf = NULL;
+ char new_iobref = 0;
+ ssize_t xdr_size = 0;
+
+ GF_ASSERT(this);
+
+ 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;
+ }
+
+ new_iobref = 1;
+ }
+
+ iobref_add(iobref, iobuf);
+
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = iobuf_size(iobuf);
+
+ /* Create the xdr payload */
+ ret = xdr_serialize_generic(iov, req, xdrproc);
+ if (ret == -1) {
+ goto out;
}
+ iov.iov_len = ret;
+ count = 1;
+ }
- /* Send the msg */
- ret = rpc_clnt_submit (&global_quotad_rpc, prog, procnum, cbkfn,
- &iov, count,
- NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
- ret = 0;
+ /* Send the msg */
+ ret = rpc_clnt_submit(global_quotad_rpc, prog, procnum, cbkfn, &iov, count,
+ NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
+ ret = 0;
out:
- if (new_iobref)
- iobref_unref (iobref);
- if (iobuf)
- iobuf_unref (iobuf);
+ if (new_iobref)
+ iobref_unref(iobref);
+ if (iobuf)
+ iobuf_unref(iobuf);
- return ret;
+ return ret;
}
int
-cli_quotad_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
+cli_quotad_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
+ void *data)
{
- xlator_t *this = NULL;
- int ret = 0;
+ xlator_t *this = NULL;
+ int ret = 0;
- this = mydata;
+ this = mydata;
- switch (event) {
- case RPC_CLNT_CONNECT:
- {
- gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
- break;
+ switch (event) {
+ case RPC_CLNT_CONNECT: {
+ gf_log(this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
+ break;
}
- case RPC_CLNT_DISCONNECT:
- {
- gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
- break;
+ case RPC_CLNT_DISCONNECT: {
+ gf_log(this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
+ break;
}
default:
- gf_log (this->name, GF_LOG_TRACE,
- "got some other RPC event %d", event);
- ret = 0;
- break;
- }
+ gf_log(this->name, GF_LOG_TRACE, "got some other RPC event %d",
+ event);
+ ret = 0;
+ break;
+ }
- return ret;
+ return ret;
}
struct rpc_clnt *
-cli_quotad_clnt_init (xlator_t *this, dict_t *options)
+cli_quotad_clnt_init(xlator_t *this, dict_t *options)
{
- struct rpc_clnt *rpc = NULL;
- int ret = -1;
-
-
- ret = dict_set_str (options, "transport.address-family", "unix");
- if (ret)
- goto out;
-
- ret = dict_set_str (options, "transport-type", "socket");
- if (ret)
- goto out;
-
- ret = dict_set_str (options, "transport.socket.connect-path",
- "/var/run/gluster/quotad.socket");
- if (ret)
- goto out;
-
- rpc = rpc_clnt_new (options, this, this->name, 16);
- if (!rpc)
- goto out;
-
- ret = rpc_clnt_register_notify (rpc, cli_quotad_notify, this);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "failed to register notify");
- goto out;
- }
-
- rpc_clnt_start (rpc);
+ struct rpc_clnt *rpc = NULL;
+ int ret = -1;
+
+ ret = dict_set_nstrn(options, "transport.address-family",
+ SLEN("transport.address-family"), "unix",
+ SLEN("unix"));
+ if (ret)
+ goto out;
+
+ ret = dict_set_nstrn(options, "transport-type", SLEN("transport-type"),
+ "socket", SLEN("socket"));
+ if (ret)
+ goto out;
+
+ ret = dict_set_nstrn(options, "transport.socket.connect-path",
+ SLEN("transport.socket.connect-path"),
+ "/var/run/gluster/quotad.socket",
+ SLEN("/var/run/gluster/quotad.socket"));
+ if (ret)
+ goto out;
+
+ rpc = rpc_clnt_new(options, this, this->name, 16);
+ if (!rpc)
+ goto out;
+
+ ret = rpc_clnt_register_notify(rpc, cli_quotad_notify, this);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "failed to register notify");
+ goto out;
+ }
+
+ rpc_clnt_start(rpc);
out:
- if (ret) {
- if (rpc)
- rpc_clnt_unref (rpc);
- rpc = NULL;
- }
+ if (ret) {
+ if (rpc)
+ rpc_clnt_unref(rpc);
+ rpc = NULL;
+ }
- return rpc;
+ return rpc;
}
-
diff --git a/cli/src/cli-quotad-client.h b/cli/src/cli-quotad-client.h
index aa0b42af38d..71a44e5916b 100644
--- a/cli/src/cli-quotad-client.h
+++ b/cli/src/cli-quotad-client.h
@@ -8,26 +8,22 @@
cases as published by the Free Software Foundation.
*/
#include "cli.h"
-#include "compat-errno.h"
-#include "compat.h"
+#include <glusterfs/compat-errno.h>
+#include <glusterfs/compat.h>
#include "cli-cmd.h"
#include "cli1-xdr.h"
#include "xdr-generic.h"
#include "protocol-common.h"
#include "cli-mem-types.h"
-
int
-cli_quotad_submit_request (void *req, call_frame_t *frame,
- rpc_clnt_prog_t *prog,
- int procnum, struct iobref *iobref,
- xlator_t *this, fop_cbk_fn_t cbkfn,
- xdrproc_t xdrproc);
+cli_quotad_submit_request(void *req, call_frame_t *frame, rpc_clnt_prog_t *prog,
+ int procnum, struct iobref *iobref, xlator_t *this,
+ fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
struct rpc_clnt *
-cli_quotad_clnt_init (xlator_t *this, dict_t *options);
+cli_quotad_clnt_init(xlator_t *this, dict_t *options);
int
-cli_quotad_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data);
-
+cli_quotad_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
+ void *data);
diff --git a/cli/src/cli-rl.c b/cli/src/cli-rl.c
index bca37d9c509..7a38a0b882a 100644
--- a/cli/src/cli-rl.c
+++ b/cli/src/cli-rl.c
@@ -17,7 +17,7 @@
#include "cli-cmd.h"
#include "cli-mem-types.h"
-#include "event.h"
+#include <glusterfs/gf-event.h>
#include <fnmatch.h>
@@ -27,384 +27,376 @@
#include <readline/readline.h>
#include <readline/history.h>
-
int
-cli_rl_out (struct cli_state *state, const char *fmt, va_list ap)
+cli_rl_out(struct cli_state *state, const char *fmt, va_list ap)
{
- int tmp_rl_point = rl_point;
- int n = rl_end;
- int ret = 0;
+ 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 ();
- }
+ if (rl_end >= 0) {
+ rl_kill_text(0, rl_end);
+ rl_redisplay();
+ }
- printf ("\r%*s\r", (int)strlen (state->prompt), "");
+ printf("\r%*s\r", (int)strlen(state->prompt), "");
- ret = vprintf (fmt, ap);
+ ret = vprintf(fmt, ap);
- printf ("\n");
- fflush(stdout);
+ printf("\n");
+ fflush(stdout);
- if (n) {
- rl_do_undo ();
- rl_point = tmp_rl_point;
- rl_reset_line_state ();
- }
+ if (n) {
+ rl_do_undo();
+ rl_point = tmp_rl_point;
+ rl_reset_line_state();
+ }
- return ret;
+ return ret;
}
int
-cli_rl_err (struct cli_state *state, const char *fmt, va_list ap)
+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;
+ 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 ();
- }
+ if (rl_end >= 0) {
+ rl_kill_text(0, rl_end);
+ rl_redisplay();
+ }
- fprintf (stderr, "\r%*s\r", (int)strlen (state->prompt), "");
+ fprintf(stderr, "\r%*s\r", (int)strlen(state->prompt), "");
- ret = vfprintf (stderr, fmt, ap);
+ ret = vfprintf(stderr, fmt, ap);
- fprintf (stderr, "\n");
- fflush(stderr);
+ fprintf(stderr, "\n");
+ fflush(stderr);
- if (n) {
- rl_do_undo ();
- rl_point = tmp_rl_point;
- rl_reset_line_state ();
- }
+ if (n) {
+ rl_do_undo();
+ rl_point = tmp_rl_point;
+ rl_reset_line_state();
+ }
- return ret;
+ return ret;
}
-
void
-cli_rl_process_line (char *line)
+cli_rl_process_line(char *line)
{
- struct cli_state *state = NULL;
- int ret = 0;
-
- state = global_state;
+ struct cli_state *state = NULL;
+ int ret = 0;
- state->rl_processing = 1;
- {
- ret = cli_cmd_process_line (state, line);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to process line");
+ state = global_state;
- add_history (line);
- }
- state->rl_processing = 0;
+ 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;
}
-
-int
-cli_rl_stdin (int fd, int idx, void *data,
- int poll_out, int poll_in, int poll_err)
+void
+cli_rl_stdin(int fd, int idx, int gen, void *data, int poll_out, int poll_in,
+ int poll_err, char event_thread_died)
{
- rl_callback_read_char ();
+ struct cli_state *state = NULL;
- return 0;
-}
+ state = data;
+
+ rl_callback_read_char();
+ gf_event_handled(state->ctx->event_pool, fd, idx, gen);
+
+ return;
+}
char *
-cli_rl_autocomplete_entry (const char *text, int times)
+cli_rl_autocomplete_entry(const char *text, int times)
{
- struct cli_state *state = NULL;
- char *retp = NULL;
+ struct cli_state *state = NULL;
+ char *retp = NULL;
- state = global_state;
+ state = global_state;
- if (!state->matchesp)
- return NULL;
+ if (!state->matchesp)
+ return NULL;
- retp = *state->matchesp;
+ retp = *state->matchesp;
- state->matchesp++;
+ state->matchesp++;
- return retp ? strdup (retp) : NULL;
+ return retp ? strdup(retp) : NULL;
}
-
int
-cli_rl_token_count (const char *text)
+cli_rl_token_count(const char *text)
{
- int count = 0;
- const char *trav = NULL;
- int is_spc = 1;
-
- for (trav = text; *trav; trav++) {
- if (*trav == ' ') {
- is_spc = 1;
- } else {
- if (is_spc) {
- count++;
- is_spc = 0;
- }
- }
+ int count = 0;
+ const char *trav = NULL;
+ int is_spc = 1;
+
+ for (trav = text; *trav; trav++) {
+ if (*trav == ' ') {
+ is_spc = 1;
+ } else {
+ if (is_spc) {
+ count++;
+ is_spc = 0;
+ }
}
+ }
- if (is_spc)
- /* what needs to be autocompleted is a full
- new word, and not extend the last word
- */
- count++;
+ if (is_spc)
+ /* what needs to be autocompleted is a full
+ new word, and not extend the last word
+ */
+ count++;
- return count;
+ return count;
}
-
char **
-cli_rl_tokenize (const char *text)
+cli_rl_tokenize(const char *text)
{
- int count = 0;
- char **tokens = NULL;
- char **tokenp = NULL;
- char *token = NULL;
- char *copy = NULL;
- char *saveptr = NULL;
- int i = 0;
-
- count = cli_rl_token_count (text);
-
- tokens = calloc (count + 1, sizeof (*tokens));
- if (!tokens)
- return NULL;
-
- copy = strdup (text);
- if (!copy)
- goto out;
-
- tokenp = tokens;
-
- for (token = strtok_r (copy, " \t\r\n", &saveptr); token;
- token = strtok_r (NULL, " \t\r\n", &saveptr)) {
- *tokenp = strdup (token);
-
- if (!*tokenp)
- goto out;
- tokenp++;
- i++;
-
- }
+ int count = 0;
+ char **tokens = NULL;
+ char **tokenp = NULL;
+ char *token = NULL;
+ char *copy = NULL;
+ char *saveptr = NULL;
+ int i = 0;
+
+ count = cli_rl_token_count(text);
+
+ tokens = calloc(count + 1, sizeof(*tokens));
+ if (!tokens)
+ return NULL;
- if (i < count) {
- /* symbolize that what needs to be autocompleted is
- the full set of possible nextwords, and not extend
- the last word
- */
- *tokenp = strdup ("");
- if (!*tokenp)
- goto out;
- tokenp++;
- i++;
- }
+ copy = strdup(text);
+ if (!copy)
+ goto out;
+
+ tokenp = tokens;
+
+ for (token = strtok_r(copy, " \t\r\n", &saveptr); token;
+ token = strtok_r(NULL, " \t\r\n", &saveptr)) {
+ *tokenp = strdup(token);
+
+ if (!*tokenp)
+ goto out;
+ tokenp++;
+ i++;
+ }
+
+ if (i < count) {
+ /* symbolize that what needs to be autocompleted is
+ the full set of possible nextwords, and not extend
+ the last word
+ */
+ *tokenp = strdup("");
+ if (!*tokenp)
+ goto out;
+ tokenp++;
+ i++;
+ }
out:
- free (copy);
+ free(copy);
- if (i < count) {
- cli_cmd_tokens_destroy (tokens);
- tokens = NULL;
- }
+ if (i < count) {
+ cli_cmd_tokens_destroy(tokens);
+ tokens = NULL;
+ }
- return tokens;
+ return tokens;
}
-
char **
-cli_rl_get_matches (struct cli_state *state, struct cli_cmd_word *word,
- const char *text)
+cli_rl_get_matches(struct cli_state *state, struct cli_cmd_word *word,
+ const char *text)
{
- char **matches = NULL;
- char **matchesp = NULL;
- struct cli_cmd_word **next = NULL;
- int count = 0;
- int len = 0;
+ char **matches = NULL;
+ char **matchesp = NULL;
+ struct cli_cmd_word **next = NULL;
+ int count = 0;
+ int len = 0;
- len = strlen (text);
+ len = strlen(text);
- if (!word->nextwords)
- return NULL;
+ if (!word->nextwords)
+ return NULL;
- for (next = word->nextwords; *next; next++)
- count++;
+ for (next = word->nextwords; *next; next++)
+ count++;
- matches = calloc (count + 1, sizeof (*matches));
- matchesp = matches;
+ matches = calloc(count + 1, sizeof(*matches));
+ matchesp = matches;
- for (next = word->nextwords; *next; next++) {
- if ((*next)->match) {
- continue;
- }
+ for (next = word->nextwords; *next; next++) {
+ if ((*next)->match) {
+ continue;
+ }
- if (strncmp ((*next)->word, text, len) == 0) {
- *matchesp = strdup ((*next)->word);
- matchesp++;
- }
+ if (strncmp((*next)->word, text, len) == 0) {
+ *matchesp = strdup((*next)->word);
+ matchesp++;
}
+ }
- return matches;
+ return matches;
}
-
int
-cli_rl_autocomplete_prepare (struct cli_state *state, const char *text)
+cli_rl_autocomplete_prepare(struct cli_state *state, const char *text)
{
- struct cli_cmd_word *word = NULL;
- struct cli_cmd_word *next = NULL;
- char **tokens = NULL;
- char **tokenp = NULL;
- char *token = NULL;
- char **matches = NULL;
-
- tokens = cli_rl_tokenize (text);
- if (!tokens)
- return 0;
-
- word = &state->tree.root;
-
- for (tokenp = tokens; (token = *tokenp); tokenp++) {
- if (!*(tokenp+1)) {
- /* last word */
- break;
- }
-
- next = cli_cmd_nextword (word, token);
- word = next;
- if (!word)
- break;
+ struct cli_cmd_word *word = NULL;
+ struct cli_cmd_word *next = NULL;
+ char **tokens = NULL;
+ char **tokenp = NULL;
+ char *token = NULL;
+ char **matches = NULL;
+
+ tokens = cli_rl_tokenize(text);
+ if (!tokens)
+ return 0;
+
+ word = &state->tree.root;
+
+ for (tokenp = tokens; (token = *tokenp); tokenp++) {
+ if (!*(tokenp + 1)) {
+ /* last word */
+ break;
}
+ next = cli_cmd_nextword(word, token);
+ word = next;
if (!word)
- goto out;
+ break;
+ }
+
+ if (!word || !token)
+ goto out;
- matches = cli_rl_get_matches (state, word, token);
+ matches = cli_rl_get_matches(state, word, token);
- state->matches = matches;
- state->matchesp = matches;
+ state->matches = matches;
+ state->matchesp = matches;
out:
- cli_cmd_tokens_destroy (tokens);
- return 0;
+ cli_cmd_tokens_destroy(tokens);
+ return 0;
}
-
int
-cli_rl_autocomplete_cleanup (struct cli_state *state)
+cli_rl_autocomplete_cleanup(struct cli_state *state)
{
- if (state->matches)
- cli_cmd_tokens_destroy (state->matches);
+ if (state->matches)
+ cli_cmd_tokens_destroy(state->matches);
- state->matches = NULL;
- state->matchesp = NULL;
+ state->matches = NULL;
+ state->matchesp = NULL;
- return 0;
+ return 0;
}
-
char **
-cli_rl_autocomplete (const char *text, int start, int end)
+cli_rl_autocomplete(const char *text, int start, int end)
{
- struct cli_state *state = NULL;
- char **matches = NULL;
- char save = 0;
+ struct cli_state *state = NULL;
+ char **matches = NULL;
+ char save = 0;
- state = global_state;
+ state = global_state;
- /* hack to make the autocompletion code neater */
- /* fake it as though the cursor is at the end of line */
+ /* hack to make the autocompletion code neater */
+ /* fake it as though the cursor is at the end of line */
- save = rl_line_buffer[rl_point];
- rl_line_buffer[rl_point] = 0;
+ save = rl_line_buffer[rl_point];
+ rl_line_buffer[rl_point] = 0;
- cli_rl_autocomplete_prepare (state, rl_line_buffer);
+ cli_rl_autocomplete_prepare(state, rl_line_buffer);
- matches = rl_completion_matches (text, cli_rl_autocomplete_entry);
+ matches = rl_completion_matches(text, cli_rl_autocomplete_entry);
- cli_rl_autocomplete_cleanup (state);
+ cli_rl_autocomplete_cleanup(state);
- rl_line_buffer[rl_point] = save;
+ rl_line_buffer[rl_point] = save;
- return matches;
+ return matches;
}
-
static char *
-complete_none (const char *txt, int times)
+complete_none(const char *txt, int times)
{
- return NULL;
+ return NULL;
}
-
void *
-cli_rl_input (void *_data)
+cli_rl_input(void *_data)
{
- struct cli_state *state = NULL;
- char *line = NULL;
+ struct cli_state *state = NULL;
+ char *line = NULL;
- state = _data;
+ state = _data;
- for (;;) {
- line = readline (state->prompt);
- if (!line)
- exit(0); //break;
+ fprintf(stderr,
+ "Welcome to gluster prompt, type 'help' to see the available "
+ "commands.\n");
+ for (;;) {
+ line = readline(state->prompt);
+ if (!line)
+ exit(0); // break;
- if (*line)
- cli_rl_process_line (line);
+ if (*line)
+ cli_rl_process_line(line);
- free (line);
- }
+ free(line);
+ }
- return NULL;
+ return NULL;
}
-
int
-cli_rl_enable (struct cli_state *state)
+cli_rl_enable(struct cli_state *state)
{
- int ret = 0;
-
- rl_pre_input_hook = NULL;
- rl_attempted_completion_function = cli_rl_autocomplete;
- rl_completion_entry_function = complete_none;
-
- if (!state->rl_async) {
- ret = pthread_create (&state->input, NULL,
- cli_rl_input, state);
- if (ret == 0)
- state->rl_enabled = 1;
- goto out;
- }
+ int ret = 0;
- ret = event_register (state->ctx->event_pool, 0, cli_rl_stdin, state,
- 1, 0);
- if (ret == -1)
- goto out;
+ rl_pre_input_hook = NULL;
+ rl_attempted_completion_function = cli_rl_autocomplete;
+ rl_completion_entry_function = complete_none;
- state->rl_enabled = 1;
- rl_callback_handler_install (state->prompt, cli_rl_process_line);
+ if (!state->rl_async) {
+ ret = pthread_create(&state->input, NULL, cli_rl_input, state);
+ if (ret == 0)
+ state->rl_enabled = 1;
+ goto out;
+ }
+
+ ret = gf_event_register(state->ctx->event_pool, 0, cli_rl_stdin, state, 1,
+ 0, 0);
+ if (ret == -1)
+ goto out;
+
+ state->rl_enabled = 1;
+ rl_callback_handler_install(state->prompt, cli_rl_process_line);
out:
- return state->rl_enabled;
+ return state->rl_enabled;
}
#else /* HAVE_READLINE */
int
-cli_rl_enable (struct cli_state *state)
+cli_rl_enable(struct cli_state *state)
{
- return 0;
+ return 0;
}
#endif /* HAVE_READLINE */
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
index c160339cb12..9b6b0c7fa50 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -14,63 +14,49 @@
*/
#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
+#define VOL_TOP_PERF_SPEED_WIDTH 4
+#define VOL_TOP_PERF_TIME_WIDTH 26
#define INDENT_MAIN_HEAD "%-25s %s "
+#define RETURNING "Returning %d"
+#define XML_ERROR "Error outputting to xml"
+#define XDR_DECODE_FAIL "Failed to decode xdr response"
+#define DICT_SERIALIZE_FAIL "Failed to serialize to data to dictionary"
+#define DICT_UNSERIALIZE_FAIL "Failed to unserialize the dictionary"
+
+/* Do not show estimates if greater than this number */
+#define REBAL_ESTIMATE_SEC_UPPER_LIMIT (60 * 24 * 3600)
+#define REBAL_ESTIMATE_START_TIME 600
+
#include "cli.h"
-#include "compat-errno.h"
+#include <glusterfs/compat-errno.h>
#include "cli-cmd.h"
#include <sys/uio.h>
#include <stdlib.h>
#include <sys/mount.h>
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-#include "protocol-common.h"
+#include <glusterfs/compat.h>
#include "cli-mem-types.h"
-#include "compat.h"
-
-#include "syscall.h"
+#include <glusterfs/syscall.h>
#include "glusterfs3.h"
#include "portmap-xdr.h"
-#include "byte-order.h"
+#include <glusterfs/byte-order.h>
-#include "cli-quotad-client.h"
-#include "run.h"
-#include "quota-common-utils.h"
+#include <glusterfs/run.h>
+#include <glusterfs/events.h>
-enum gf_task_types {
- GF_TASK_TYPE_REBALANCE,
- GF_TASK_TYPE_REMOVE_BRICK
-};
+enum gf_task_types { GF_TASK_TYPE_REBALANCE, GF_TASK_TYPE_REMOVE_BRICK };
-extern struct rpc_clnt *global_quotad_rpc;
-extern rpc_clnt_prog_t cli_quotad_clnt;
-extern rpc_clnt_prog_t *cli_rpc_prog;
-extern int cli_op_ret;
-extern int connected;
+rpc_clnt_prog_t cli_quotad_clnt;
-int32_t
-gf_cli_remove_brick (call_frame_t *frame, xlator_t *this,
- void *data);
-
-char *cli_vol_type_str[] = {"Distribute",
- "Stripe",
- "Replicate",
- "Striped-Replicate",
- "Disperse",
- "Tier",
- "Distributed-Stripe",
- "Distributed-Replicate",
- "Distributed-Striped-Replicate",
- "Distributed-Disperse",
- };
-
-char *cli_vol_status_str[] = {"Created",
- "Started",
- "Stopped",
- };
+static int32_t
+gf_cli_remove_brick(call_frame_t *frame, xlator_t *this, void *data);
+
+char *cli_vol_status_str[] = {
+ "Created",
+ "Started",
+ "Stopped",
+};
char *cli_vol_task_status_str[] = {"not started",
"in progress",
@@ -81,8906 +67,8582 @@ char *cli_vol_task_status_str[] = {"not started",
"fix-layout stopped",
"fix-layout completed",
"fix-layout failed",
- "unknown"
-};
+ "unknown"};
-int32_t
-gf_cli_snapshot (call_frame_t *frame, xlator_t *this, void *data);
+static int32_t
+gf_cli_snapshot(call_frame_t *frame, xlator_t *this, void *data);
-int32_t
-gf_cli_get_volume (call_frame_t *frame, xlator_t *this,
- void *data);
+static int32_t
+gf_cli_get_volume(call_frame_t *frame, xlator_t *this, void *data);
-int
-cli_to_glusterd (gf_cli_req *req, call_frame_t *frame, fop_cbk_fn_t cbkfn,
- xdrproc_t xdrproc, dict_t *dict, int procnum, xlator_t *this,
- rpc_clnt_prog_t *prog, struct iobref *iobref);
-
-rpc_clnt_prog_t cli_handshake_prog = {
- .progname = "cli handshake",
- .prognum = GLUSTER_HNDSK_PROGRAM,
- .progver = GLUSTER_HNDSK_VERSION,
+static int
+cli_to_glusterd(gf_cli_req *req, call_frame_t *frame, fop_cbk_fn_t cbkfn,
+ xdrproc_t xdrproc, dict_t *dict, int procnum, xlator_t *this,
+ rpc_clnt_prog_t *prog, struct iobref *iobref);
+
+static int
+add_cli_cmd_timeout_to_dict(dict_t *dict);
+
+static rpc_clnt_prog_t cli_handshake_prog = {
+ .progname = "cli handshake",
+ .prognum = GLUSTER_HNDSK_PROGRAM,
+ .progver = GLUSTER_HNDSK_VERSION,
};
-rpc_clnt_prog_t cli_pmap_prog = {
- .progname = "cli portmap",
- .prognum = GLUSTER_PMAP_PROGRAM,
- .progver = GLUSTER_PMAP_VERSION,
+static rpc_clnt_prog_t cli_pmap_prog = {
+ .progname = "cli portmap",
+ .prognum = GLUSTER_PMAP_PROGRAM,
+ .progver = GLUSTER_PMAP_VERSION,
};
-int
-gf_cli_probe_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static void
+gf_free_xdr_cli_rsp(gf_cli_rsp rsp)
{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- char msg[1024] = {0,};
-
- if (-1 == req->rpc_status) {
- goto out;
- }
+ if (rsp.dict.dict_val) {
+ free(rsp.dict.dict_val);
+ }
+ if (rsp.op_errstr) {
+ free(rsp.op_errstr);
+ }
+}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- //rsp.op_ret = -1;
- //rsp.op_errno = EINVAL;
- goto out;
- }
+static void
+gf_free_xdr_getspec_rsp(gf_getspec_rsp rsp)
+{
+ if (rsp.spec) {
+ free(rsp.spec);
+ }
+ if (rsp.xdata.xdata_val) {
+ free(rsp.xdata.xdata_val);
+ }
+}
- gf_log ("cli", GF_LOG_INFO, "Received resp to probe");
+static void
+gf_free_xdr_fsm_log_rsp(gf1_cli_fsm_log_rsp rsp)
+{
+ if (rsp.op_errstr) {
+ free(rsp.op_errstr);
+ }
+ if (rsp.fsm_log.fsm_log_val) {
+ free(rsp.fsm_log.fsm_log_val);
+ }
+}
- if (rsp.op_errstr && (strlen (rsp.op_errstr) > 0)) {
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
- if (rsp.op_ret)
- gf_log ("cli", GF_LOG_ERROR, "%s", msg);
+static int
+gf_cli_probe_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ char msg[1024] = "success";
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ // rsp.op_ret = -1;
+ // rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to probe");
+
+ if (rsp.op_errstr && rsp.op_errstr[0] != '\0') {
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ if (rsp.op_ret) {
+ gf_log("cli", GF_LOG_ERROR, "%s", msg);
}
+ }
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_str (NULL,
- (rsp.op_ret)? NULL : msg,
- rsp.op_ret, rsp.op_errno,
- (rsp.op_ret)? msg : NULL);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str(NULL, (rsp.op_ret) ? NULL : msg, rsp.op_ret,
+ rsp.op_errno, (rsp.op_ret) ? msg : NULL);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if (!rsp.op_ret)
- cli_out ("peer probe: success. %s", msg);
- else
- cli_err ("peer probe: failed: %s", msg);
+ if (!rsp.op_ret)
+ cli_out("peer probe: %s", msg);
+ else
+ cli_err("peer probe: failed: %s", msg);
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int
-gf_cli_deprobe_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- char msg[1024] = {0,};
+static int
+gf_cli_deprobe_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ char msg[1024] = "success";
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ // rsp.op_ret = -1;
+ // rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to deprobe");
+
+ if (rsp.op_ret) {
+ if (rsp.op_errstr[0] != '\0') {
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ gf_log("cli", GF_LOG_ERROR, "%s", rsp.op_errstr);
+ }
+ }
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str(NULL, (rsp.op_ret) ? NULL : msg, rsp.op_ret,
+ rsp.op_errno, (rsp.op_ret) ? msg : NULL);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if (-1 == req->rpc_status) {
- goto out;
- }
+ if (!rsp.op_ret)
+ cli_out("peer detach: %s", msg);
+ else
+ cli_err("peer detach: failed: %s", msg);
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- //rsp.op_ret = -1;
- //rsp.op_errno = EINVAL;
- goto out;
- }
+ ret = rsp.op_ret;
- gf_log ("cli", GF_LOG_INFO, "Received resp to deprobe");
+out:
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
+}
- if (rsp.op_ret) {
- if (strlen (rsp.op_errstr) > 0) {
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
- gf_log ("cli", GF_LOG_ERROR, "%s", rsp.op_errstr);
- }
- } else {
- snprintf (msg, sizeof (msg), "success");
- }
+static int
+gf_cli_output_peer_hostnames(dict_t *dict, int count, const char *prefix)
+{
+ int ret = -1;
+ char key[512] = {
+ 0,
+ };
+ int i = 0;
+ char *hostname = NULL;
+
+ cli_out("Other names:");
+ /* Starting from friend.hostname1, as friend.hostname0 will be the same
+ * as friend.hostname
+ */
+ for (i = 1; i < count; i++) {
+ ret = snprintf(key, sizeof(key), "%s.hostname%d", prefix, i);
+ ret = dict_get_strn(dict, key, ret, &hostname);
+ if (ret)
+ break;
+ cli_out("%s", hostname);
+ hostname = NULL;
+ }
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_str (NULL,
- (rsp.op_ret)? NULL : msg,
- rsp.op_ret, rsp.op_errno,
- (rsp.op_ret)? msg : NULL);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ return ret;
+}
- if (!rsp.op_ret)
- cli_out ("peer detach: %s", msg);
- else
- cli_err ("peer detach: failed: %s", msg);
+static int
+gf_cli_output_peer_status(dict_t *dict, int count)
+{
+ int ret = -1;
+ char *uuid_buf = NULL;
+ char *hostname_buf = NULL;
+ int32_t i = 1;
+ char key[256] = {
+ 0,
+ };
+ int keylen;
+ char *state = NULL;
+ int32_t connected = 0;
+ const char *connected_str = NULL;
+ int hostname_count = 0;
+
+ cli_out("Number of Peers: %d", count);
+ i = 1;
+ while (i <= count) {
+ keylen = snprintf(key, sizeof(key), "friend%d.uuid", i);
+ ret = dict_get_strn(dict, key, keylen, &uuid_buf);
+ if (ret)
+ goto out;
- ret = rsp.op_ret;
+ keylen = snprintf(key, sizeof(key), "friend%d.hostname", i);
+ ret = dict_get_strn(dict, key, keylen, &hostname_buf);
+ if (ret)
+ goto out;
-out:
- cli_cmd_broadcast_response (ret);
- return ret;
-}
+ keylen = snprintf(key, sizeof(key), "friend%d.connected", i);
+ ret = dict_get_int32n(dict, key, keylen, &connected);
+ if (ret)
+ goto out;
+ if (connected)
+ connected_str = "Connected";
+ else
+ connected_str = "Disconnected";
-int
-gf_cli_output_peer_hostnames (dict_t *dict, int count, char *prefix)
-{
- int ret = -1;
- char key[256] = {0,};
- int i = 0;
- char *hostname = NULL;
+ keylen = snprintf(key, sizeof(key), "friend%d.state", i);
+ ret = dict_get_strn(dict, key, keylen, &state);
+ if (ret)
+ goto out;
+
+ cli_out("\nHostname: %s\nUuid: %s\nState: %s (%s)", hostname_buf,
+ uuid_buf, state, connected_str);
- cli_out ("Other names:");
- /* Starting from friend.hostname1, as friend.hostname0 will be the same
- * as friend.hostname
+ keylen = snprintf(key, sizeof(key), "friend%d.hostname_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &hostname_count);
+ /* Print other addresses only if there are more than 1.
*/
- for (i = 1; i < count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.hostname%d", prefix, i);
- ret = dict_get_str (dict, key, &hostname);
- if (ret)
- break;
- cli_out ("%s", hostname);
- hostname = NULL;
+ if ((ret == 0) && (hostname_count > 1)) {
+ snprintf(key, sizeof(key), "friend%d", i);
+ ret = gf_cli_output_peer_hostnames(dict, hostname_count, key);
+ if (ret) {
+ gf_log("cli", GF_LOG_WARNING,
+ "error outputting peer other names");
+ goto out;
+ }
}
+ i++;
+ }
- return ret;
+ ret = 0;
+out:
+ return ret;
}
-int
-gf_cli_output_peer_status (dict_t *dict, int count)
-{
- int ret = -1;
- char *uuid_buf = NULL;
- char *hostname_buf = NULL;
- int32_t i = 1;
- char key[256] = {0,};
- char *state = NULL;
- int32_t connected = 0;
- char *connected_str = NULL;
- int hostname_count = 0;
-
- cli_out ("Number of Peers: %d", count);
- i = 1;
- while ( i <= count) {
- snprintf (key, 256, "friend%d.uuid", i);
- ret = dict_get_str (dict, key, &uuid_buf);
- if (ret)
- goto out;
+static int
+gf_cli_output_pool_list(dict_t *dict, int count)
+{
+ int ret = -1;
+ char *uuid_buf = NULL;
+ char *hostname_buf = NULL;
+ int32_t hostname_len = 8; /*min len 8 chars*/
+ int32_t i = 1;
+ char key[64] = {
+ 0,
+ };
+ int keylen;
+ int32_t connected = 0;
+ const char *connected_str = NULL;
+
+ if (count <= 0)
+ goto out;
+
+ while (i <= count) {
+ keylen = snprintf(key, sizeof(key), "friend%d.hostname", i);
+ ret = dict_get_strn(dict, key, keylen, &hostname_buf);
+ if (ret)
+ goto out;
- snprintf (key, 256, "friend%d.hostname", i);
- ret = dict_get_str (dict, key, &hostname_buf);
- if (ret)
- goto out;
+ ret = strlen(hostname_buf);
+ if (ret > hostname_len)
+ hostname_len = ret;
- snprintf (key, 256, "friend%d.connected", i);
- ret = dict_get_int32 (dict, key, &connected);
- if (ret)
- goto out;
- if (connected)
- connected_str = "Connected";
- else
- connected_str = "Disconnected";
+ i++;
+ }
+ cli_out("UUID\t\t\t\t\t%-*s\tState", hostname_len, "Hostname");
- snprintf (key, 256, "friend%d.state", i);
- ret = dict_get_str (dict, key, &state);
- if (ret)
- goto out;
+ i = 1;
+ while (i <= count) {
+ keylen = snprintf(key, sizeof(key), "friend%d.uuid", i);
+ ret = dict_get_strn(dict, key, keylen, &uuid_buf);
+ if (ret)
+ goto out;
- cli_out ("\nHostname: %s\nUuid: %s\nState: %s (%s)",
- hostname_buf, uuid_buf, state, connected_str);
+ keylen = snprintf(key, sizeof(key), "friend%d.hostname", i);
+ ret = dict_get_strn(dict, key, keylen, &hostname_buf);
+ if (ret)
+ goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d.hostname_count", i);
- ret = dict_get_int32 (dict, key, &hostname_count);
- /* Print other addresses only if there are more than 1.
- */
- if ((ret == 0) && (hostname_count > 1)) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d", i);
- ret = gf_cli_output_peer_hostnames (dict,
- hostname_count,
- key);
- }
- i++;
- }
+ keylen = snprintf(key, sizeof(key), "friend%d.connected", i);
+ ret = dict_get_int32n(dict, key, keylen, &connected);
+ if (ret)
+ goto out;
+ if (connected)
+ connected_str = "Connected";
+ else
+ connected_str = "Disconnected";
- ret = 0;
+ cli_out("%s\t%-*s\t%s ", uuid_buf, hostname_len, hostname_buf,
+ connected_str);
+ i++;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
-int
-gf_cli_output_pool_list (dict_t *dict, int count)
-{
- int ret = -1;
- char *uuid_buf = NULL;
- char *hostname_buf = NULL;
- int32_t hostname_len = 8; /*min len 8 chars*/
- int32_t i = 1;
- char key[256] = {0,};
- int32_t connected = 0;
- char *connected_str = NULL;
-
- if (count <= 0)
- goto out;
-
- while (i <= count) {
- snprintf (key, 256, "friend%d.hostname", i);
- ret = dict_get_str (dict, key, &hostname_buf);
- if (ret)
- goto out;
+/* function pointer for gf_cli_output_{pool_list,peer_status} */
+typedef int (*cli_friend_output_fn)(dict_t *, int);
- ret = strlen(hostname_buf);
- if (ret > hostname_len)
- hostname_len = ret;
+static int
+gf_cli_list_friends_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf1_cli_peer_list_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ char msg[1024] = {
+ 0,
+ };
+ const char *cmd = NULL;
+ cli_friend_output_fn friend_output_fn;
+ call_frame_t *frame = NULL;
+ unsigned long flags = 0;
- i++;
- }
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- cli_out ("UUID\t\t\t\t\t%-*s\tState", hostname_len, "Hostname");
+ GF_ASSERT(myframe);
- i = 1;
- while ( i <= count) {
- snprintf (key, 256, "friend%d.uuid", i);
- ret = dict_get_str (dict, key, &uuid_buf);
- if (ret)
- goto out;
+ frame = myframe;
- snprintf (key, 256, "friend%d.hostname", i);
- ret = dict_get_str (dict, key, &hostname_buf);
- if (ret)
- goto out;
+ flags = (long)frame->local;
- snprintf (key, 256, "friend%d.connected", i);
- ret = dict_get_int32 (dict, key, &connected);
- if (ret)
- goto out;
- if (connected)
- connected_str = "Connected";
- else
- connected_str = "Disconnected";
+ if (flags == GF_CLI_LIST_POOL_NODES) {
+ cmd = "pool list";
+ friend_output_fn = &gf_cli_output_pool_list;
+ } else {
+ cmd = "peer status";
+ friend_output_fn = &gf_cli_output_peer_status;
+ }
- cli_out ("%s\t%-*s\t%s ", uuid_buf, hostname_len, hostname_buf,
- connected_str);
- i++;
- }
+ /* 'free' the flags set by gf_cli_list_friends */
+ frame->local = NULL;
- ret = 0;
-out:
- return ret;
-}
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf1_cli_peer_list_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ // rsp.op_ret = -1;
+ // rsp.op_errno = EINVAL;
+ goto out;
+ }
-/* function pointer for gf_cli_output_{pool_list,peer_status} */
-typedef int (*cli_friend_output_fn) (dict_t*, int);
+ gf_log("cli", GF_LOG_DEBUG, "Received resp to list: %d", rsp.op_ret);
-int
-gf_cli_list_friends_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf1_cli_peer_list_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- char msg[1024] = {0,};
- char *cmd = NULL;
- cli_friend_output_fn friend_output_fn;
- call_frame_t *frame = NULL;
- unsigned long flags = 0;
-
- frame = myframe;
- flags = (long)frame->local;
-
- if (flags == GF_CLI_LIST_POOL_NODES) {
- cmd = "pool list";
- friend_output_fn = &gf_cli_output_pool_list;
- } else {
- cmd = "peer status";
- friend_output_fn = &gf_cli_output_peer_status;
+ if (!rsp.op_ret) {
+ if (!rsp.friends.friends_len) {
+ snprintf(msg, sizeof(msg), "%s: No peers present", cmd);
+ 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, XML_ERROR);
+ goto out;
+ }
+ cli_err("%s", msg);
+ ret = 0;
+ goto out;
}
- /* 'free' the flags set by gf_cli_list_friends */
- frame->local = NULL;
+ dict = dict_new();
- if (-1 == req->rpc_status) {
- goto out;
+ if (!dict) {
+ ret = -1;
+ goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_peer_list_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- //rsp.op_ret = -1;
- //rsp.op_errno = EINVAL;
- goto out;
+ ret = dict_unserialize(rsp.friends.friends_val, rsp.friends.friends_len,
+ &dict);
+
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
}
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to list: %d",
- rsp.op_ret);
+ 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, XML_ERROR);
+ goto out;
+ }
- ret = rsp.op_ret;
+ ret = dict_get_int32_sizen(dict, "count", &count);
+ if (ret) {
+ goto out;
+ }
- if (!rsp.op_ret) {
-
- if (!rsp.friends.friends_len) {
- snprintf (msg, sizeof (msg),
- "%s: No peers present", cmd);
- 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;
- }
- cli_err ("%s", msg);
- ret = 0;
- goto out;
- }
+ ret = friend_output_fn(dict, count);
+ if (ret) {
+ goto out;
+ }
+ } else {
+ 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, XML_ERROR);
+ } else {
+ ret = -1;
+ }
+ goto out;
+ }
- dict = dict_new ();
+ ret = 0;
- if (!dict) {
- ret = -1;
- goto out;
- }
+out:
+ if (ret)
+ cli_err("%s: failed", cmd);
- ret = dict_unserialize (rsp.friends.friends_val,
- rsp.friends.friends_len,
- &dict);
+ cli_cmd_broadcast_response(ret);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to allocate memory");
- goto out;
- }
+ if (dict)
+ dict_unref(dict);
- 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;
- }
+ if (rsp.friends.friends_val) {
+ free(rsp.friends.friends_val);
+ }
+ return ret;
+}
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- goto out;
- }
+static int
+gf_cli_get_state_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *daemon_name = NULL;
+ char *ofilepath = NULL;
+
+ GF_VALIDATE_OR_GOTO("cli", myframe, out);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ 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)
+ goto out;
+
+ if (rsp.op_ret) {
+ if (strcmp(rsp.op_errstr, ""))
+ cli_err("Failed to get daemon state: %s", rsp.op_errstr);
+ else
+ cli_err(
+ "Failed to get daemon state. Check glusterd"
+ " log file for more details");
+ } else {
+ ret = dict_get_str_sizen(dict, "daemon", &daemon_name);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, "Couldn't get daemon name");
- ret = friend_output_fn (dict, count);
- if (ret) {
- goto out;
- }
- } else {
- 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 {
- ret = -1;
- }
- goto out;
- }
+ ret = dict_get_str_sizen(dict, "ofilepath", &ofilepath);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, "Couldn't get filepath");
+ if (daemon_name && ofilepath)
+ cli_out("%s state dumped to %s", daemon_name, ofilepath);
+ }
- ret = 0;
+ ret = rsp.op_ret;
out:
- if (ret)
- cli_err ("%s: failed", cmd);
+ if (dict)
+ dict_unref(dict);
- cli_cmd_broadcast_response (ret);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
- if (dict)
- dict_destroy (dict);
-
- return ret;
+ return ret;
}
-void
-cli_out_options ( char *substr, char *optstr, char *valstr)
+static void
+cli_out_options(char *substr, char *optstr, char *valstr)
{
- char *ptr1 = NULL;
- char *ptr2 = NULL;
+ char *ptr1 = NULL;
+ char *ptr2 = NULL;
- ptr1 = substr;
- ptr2 = optstr;
+ ptr1 = substr;
+ ptr2 = optstr;
- while (ptr1)
- {
- /* Avoiding segmentation fault. */
- if (!ptr2)
- return;
- if (*ptr1 != *ptr2)
- break;
- ptr1++;
- ptr2++;
- }
+ while (ptr1) {
+ /* Avoiding segmentation fault. */
+ if (!ptr2)
+ return;
+ if (*ptr1 != *ptr2)
+ break;
+ ptr1++;
+ ptr2++;
+ }
- if (*ptr2 == '\0')
- return;
- cli_out ("%s: %s",ptr2 , valstr);
+ if (*ptr2 == '\0')
+ return;
+ cli_out("%s: %s", ptr2, valstr);
}
static int
-_gf_cli_output_volinfo_opts (dict_t *d, char *k,
- data_t *v, void *tmp)
-{
- int ret = 0;
- char *key = NULL;
- char *ptr = NULL;
- data_t *value = NULL;
-
- key = tmp;
-
- ptr = strstr (k, "option.");
- if (ptr) {
- value = v;
- if (!value) {
- ret = -1;
- goto out;
- }
- cli_out_options (key, k, v->data);
+_gf_cli_output_volinfo_opts(dict_t *d, char *k, data_t *v, void *tmp)
+{
+ int ret = 0;
+ char *key = NULL;
+ char *ptr = NULL;
+ data_t *value = NULL;
+
+ key = tmp;
+
+ ptr = strstr(k, "option.");
+ if (ptr) {
+ value = v;
+ if (!value) {
+ ret = -1;
+ goto out;
}
+ cli_out_options(key, k, v->data);
+ }
out:
- return ret;
+ return ret;
}
static int
-print_brick_details (dict_t *dict, int volcount, int start_index,
- int end_index)
-{
- char key[1024] = {0,};
- int index = start_index;
- int ret = -1;
- char *brick = NULL;
-#ifdef HAVE_BD_XLATOR
- char *caps = NULL;
-#endif
-
- while (index <= end_index) {
- snprintf (key, 1024, "volume%d.brick%d", volcount, index);
- ret = dict_get_str (dict, key, &brick);
- if (ret)
- goto out;
+print_brick_details(dict_t *dict, int volcount, int start_index, int end_index,
+ int replica_count)
+{
+ char key[64] = {
+ 0,
+ };
+ int keylen;
+ int index = start_index;
+ int isArbiter = 0;
+ int ret = -1;
+ char *brick = NULL;
+
+ while (index <= end_index) {
+ keylen = snprintf(key, sizeof(key), "volume%d.brick%d", volcount,
+ index);
+ ret = dict_get_strn(dict, key, keylen, &brick);
+ if (ret)
+ goto out;
+ keylen = snprintf(key, sizeof(key), "volume%d.brick%d.isArbiter",
+ volcount, index);
+ if (dict_getn(dict, key, keylen))
+ isArbiter = 1;
+ else
+ isArbiter = 0;
- cli_out ("Brick%d: %s", index, brick);
-#ifdef HAVE_BD_XLATOR
- snprintf (key, 1024, "volume%d.vg%d", volcount, index);
- ret = dict_get_str (dict, key, &caps);
- if (!ret)
- cli_out ("Brick%d VG: %s", index, caps);
-#endif
- index++;
- }
- ret = 0;
+ if (isArbiter)
+ cli_out("Brick%d: %s (arbiter)", index, brick);
+ else
+ cli_out("Brick%d: %s", index, brick);
+ index++;
+ }
+ ret = 0;
out:
- return ret;
+ return ret;
}
-void
-gf_cli_print_number_of_bricks (int type, int brick_count, int dist_count,
- int stripe_count, int replica_count,
- int disperse_count, int redundancy_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 ||
- type == GF_CLUSTER_TYPE_TIER) {
- cli_out ("Number of Bricks: %d", brick_count);
- } else if (type == GF_CLUSTER_TYPE_DISPERSE) {
- cli_out ("Number of Bricks: %d x (%d + %d) = %d",
- (brick_count / dist_count),
- disperse_count - redundancy_count,
- redundancy_count, 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);
- }
+static void
+gf_cli_print_number_of_bricks(int type, int brick_count, int dist_count,
+ int stripe_count, int replica_count,
+ int disperse_count, int redundancy_count,
+ int arbiter_count)
+{
+ if (type == GF_CLUSTER_TYPE_NONE) {
+ cli_out("Number of Bricks: %d", brick_count);
+ } else if (type == GF_CLUSTER_TYPE_DISPERSE) {
+ cli_out("Number of Bricks: %d x (%d + %d) = %d",
+ (brick_count / dist_count), disperse_count - redundancy_count,
+ redundancy_count, brick_count);
+ } else {
+ /* For both replicate and stripe, dist_count is
+ good enough */
+ if (arbiter_count == 0) {
+ cli_out("Number of Bricks: %d x %d = %d",
+ (brick_count / dist_count), dist_count, brick_count);
+ } else {
+ cli_out("Number of Bricks: %d x (%d + %d) = %d",
+ (brick_count / dist_count), dist_count - arbiter_count,
+ arbiter_count, brick_count);
+ }
+ }
}
-int
-gf_cli_print_tier_info (dict_t *dict, int i, int brick_count)
-{
+static int
+gf_cli_get_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ int ret = -1;
+ int opt_count = 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 disperse_count = 0;
+ int32_t redundancy_count = 0;
+ int32_t arbiter_count = 0;
+ int32_t snap_count = 0;
+ int32_t thin_arbiter_count = 0;
+ int32_t vol_type = 0;
+ int32_t transport = 0;
+ char *volume_id_str = NULL;
+ char *volname = NULL;
+ char *ta_brick = NULL;
+ dict_t *dict = NULL;
+ cli_local_t *local = NULL;
+ char key[64] = {0};
+ int keylen;
+ char err_str[2048] = {0};
+ gf_cli_rsp rsp = {0};
+ char *caps __attribute__((unused)) = NULL;
+ int k __attribute__((unused)) = 0;
+ call_frame_t *frame = NULL;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status)
+ goto out;
+
+ frame = myframe;
+
+ GF_ASSERT(frame->local);
+
+ local = frame->local;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to get vol: %d", rsp.op_ret);
+
+ if (!rsp.dict.dict_len) {
+ if (global_state->mode & GLUSTER_MODE_XML)
+ goto xml_output;
+ cli_err("No volumes present");
+ ret = 0;
+ goto out;
+ }
- int hot_brick_count = -1;
- int cold_type = 0;
- int cold_brick_count = 0;
- int cold_replica_count = 0;
- int cold_disperse_count = 0;
- int cold_redundancy_count = 0;
- int cold_dist_count = 0;
- int hot_type = 0;
- int hot_replica_count = 0;
- int hot_dist_count = 0;
- int ret = -1;
- int vol_type = -1;
- char key[256] = {0,};
+ dict = dict_new();
- GF_ASSERT (dict);
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.cold_brick_count", i);
- ret = dict_get_int32 (dict, key, &cold_brick_count);
- if (ret)
- goto out;
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.cold_type", i);
- ret = dict_get_int32 (dict, key, &cold_type);
- if (ret)
- goto out;
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.cold_dist_count", i);
- ret = dict_get_int32 (dict, key, &cold_dist_count);
- if (ret)
+ ret = dict_get_int32_sizen(dict, "count", &count);
+ if (ret)
+ goto out;
+
+ if (!count) {
+ switch (local->get_vol.flags) {
+ case GF_CLI_GET_NEXT_VOLUME:
+ GF_FREE(local->get_vol.volname);
+ local->get_vol.volname = NULL;
+ ret = 0;
goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.cold_replica_count", i);
- ret = dict_get_int32 (dict, key, &cold_replica_count);
- if (ret)
+ case GF_CLI_GET_VOLUME:
+ snprintf(err_str, sizeof(err_str), "Volume %s does not exist",
+ local->get_vol.volname);
+ ret = -1;
+ if (!(global_state->mode & GLUSTER_MODE_XML))
+ goto out;
+ }
+ }
+
+ if (rsp.op_ret) {
+ if (global_state->mode & GLUSTER_MODE_XML)
+ goto xml_output;
+ ret = -1;
+ goto out;
+ }
+
+xml_output:
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ /* For GET_NEXT_VOLUME output is already begun in
+ * and will also end in gf_cli_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, XML_ERROR);
goto out;
+ }
+ }
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.cold_disperse_count", i);
- ret = dict_get_int32 (dict, key, &cold_disperse_count);
- if (ret)
+ if (dict) {
+ ret = cli_xml_output_vol_info(local, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
goto out;
+ }
+ }
+
+ if (local->get_vol.flags == GF_CLI_GET_VOLUME) {
+ ret = cli_xml_output_vol_info_end(local);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ }
+ goto out;
+ }
- memset (key, 0, sizeof (key));
- snprintf (key, 256,
- "volume%d.cold_redundancy_count", i);
- ret = dict_get_int32 (dict, key,
- &cold_redundancy_count);
+ while (i < count) {
+ cli_out(" ");
+ keylen = snprintf(key, sizeof(key), "volume%d.name", i);
+ ret = dict_get_strn(dict, key, keylen, &volname);
if (ret)
- goto out;
+ goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.hot_brick_count", i);
- ret = dict_get_int32 (dict, key, &hot_brick_count);
+ keylen = snprintf(key, sizeof(key), "volume%d.type", i);
+ ret = dict_get_int32n(dict, key, keylen, &type);
if (ret)
- goto out;
+ goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.hot_type", i);
- ret = dict_get_int32 (dict, key, &hot_type);
+ keylen = snprintf(key, sizeof(key), "volume%d.status", i);
+ ret = dict_get_int32n(dict, key, keylen, &status);
if (ret)
- goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.hot_replica_count", i);
- ret = dict_get_int32 (dict, key, &hot_replica_count);
+ goto out;
+
+ keylen = snprintf(key, sizeof(key), "volume%d.brick_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &brick_count);
if (ret)
- goto out;
+ goto out;
- cli_out ("Hot Tier :");
- vol_type = hot_type;
- hot_dist_count = (hot_replica_count ?
- hot_replica_count : 1);
- if ((hot_type != GF_CLUSTER_TYPE_TIER) &&
- (hot_type > 0) &&
- (hot_dist_count < hot_brick_count))
- vol_type = hot_type + GF_CLUSTER_TYPE_MAX - 1;
+ keylen = snprintf(key, sizeof(key), "volume%d.dist_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &dist_count);
+ if (ret)
+ goto out;
- cli_out ("Hot Tier Type : %s",
- cli_vol_type_str[vol_type]);
- gf_cli_print_number_of_bricks (hot_type,
- hot_brick_count, hot_dist_count, 0,
- hot_replica_count, 0, 0);
+ keylen = snprintf(key, sizeof(key), "volume%d.stripe_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &stripe_count);
+ if (ret)
+ goto out;
- ret = print_brick_details (dict, i, 1, hot_brick_count);
+ keylen = snprintf(key, sizeof(key), "volume%d.replica_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &replica_count);
if (ret)
- goto out;
+ goto out;
- cli_out ("Cold Tier:");
- vol_type = cold_type;
- if ((cold_type != GF_CLUSTER_TYPE_TIER) &&
- (cold_type > 0) &&
- (cold_dist_count < cold_brick_count))
- vol_type = cold_type + GF_CLUSTER_TYPE_MAX - 1;
+ keylen = snprintf(key, sizeof(key), "volume%d.disperse_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &disperse_count);
+ if (ret)
+ goto out;
- cli_out ("Cold Tier Type : %s",
- cli_vol_type_str[vol_type]);
- gf_cli_print_number_of_bricks (cold_type,
- cold_brick_count,
- cold_dist_count, 0, cold_replica_count,
- cold_disperse_count, cold_redundancy_count);
+ keylen = snprintf(key, sizeof(key), "volume%d.redundancy_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &redundancy_count);
+ if (ret)
+ goto out;
- ret = print_brick_details (dict, i, hot_brick_count+1,
- brick_count);
+ keylen = snprintf(key, sizeof(key), "volume%d.arbiter_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &arbiter_count);
if (ret)
- goto out;
-out:
- return ret;
-}
+ goto out;
-int
-gf_cli_get_volume_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- int opt_count = 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 disperse_count = 0;
- int32_t redundancy_count = 0;
- int32_t vol_type = 0;
- int32_t transport = 0;
- char *volume_id_str = NULL;
- char *brick = NULL;
- char *volname = NULL;
- dict_t *dict = NULL;
- cli_local_t *local = NULL;
- char key[1024] = {0};
- char err_str[2048] = {0};
- gf_cli_rsp rsp = {0};
- char *caps = NULL;
- int k __attribute__((unused)) = 0;
-
- if (-1 == req->rpc_status)
- goto out;
+ keylen = snprintf(key, sizeof(key), "volume%d.transport", i);
+ ret = dict_get_int32n(dict, key, keylen, &transport);
+ if (ret)
+ goto out;
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ keylen = snprintf(key, sizeof(key), "volume%d.volume_id", i);
+ ret = dict_get_strn(dict, key, keylen, &volume_id_str);
+ if (ret)
+ goto out;
- gf_log ("cli", GF_LOG_INFO, "Received resp to get vol: %d",
- rsp.op_ret);
+ keylen = snprintf(key, sizeof(key), "volume%d.snap_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &snap_count);
+ if (ret)
+ goto out;
- if (rsp.op_ret) {
- ret = -1;
- goto out;
- }
+ keylen = snprintf(key, sizeof(key), "volume%d.thin_arbiter_count", i);
+ ret = dict_get_int32n(dict, key, keylen, &thin_arbiter_count);
+ if (ret)
+ goto out;
- if (!rsp.dict.dict_len) {
- if (global_state->mode & GLUSTER_MODE_XML)
- goto xml_output;
- cli_err ("No volumes present");
- ret = 0;
- goto out;
- }
+ // Distributed (stripe/replicate/stripe-replica) setups
+ vol_type = get_vol_type(type, dist_count, brick_count);
- dict = dict_new ();
+ cli_out("Volume Name: %s", volname);
+ cli_out("Type: %s", vol_type_str[vol_type]);
+ cli_out("Volume ID: %s", volume_id_str);
+ cli_out("Status: %s", cli_vol_status_str[status]);
+ cli_out("Snapshot Count: %d", snap_count);
- if (!dict) {
- ret = -1;
- goto out;
- }
+ gf_cli_print_number_of_bricks(
+ type, brick_count, dist_count, stripe_count, replica_count,
+ disperse_count, redundancy_count, arbiter_count);
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &dict);
+ cli_out("Transport-type: %s",
+ ((transport == 0) ? "tcp"
+ : (transport == 1) ? "rdma" : "tcp,rdma"));
+ j = 1;
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Unable to allocate memory");
- goto out;
- }
+ GF_FREE(local->get_vol.volname);
+ local->get_vol.volname = gf_strdup(volname);
- ret = dict_get_int32 (dict, "count", &count);
+ cli_out("Bricks:");
+ ret = print_brick_details(dict, i, j, brick_count, replica_count);
if (ret)
- goto out;
-
- local = ((call_frame_t *)myframe)->local;
-
- if (!count) {
- switch (local->get_vol.flags) {
-
- case GF_CLI_GET_NEXT_VOLUME:
- GF_FREE (local->get_vol.volname);
- local->get_vol.volname = NULL;
- ret = 0;
- goto out;
-
- case GF_CLI_GET_VOLUME:
- memset (err_str, 0, sizeof (err_str));
- snprintf (err_str, sizeof (err_str),
- "Volume %s does not exist",
- local->get_vol.volname);
- ret = -1;
- if (!(global_state->mode & GLUSTER_MODE_XML))
- goto out;
- }
- }
-
-xml_output:
- if (global_state->mode & GLUSTER_MODE_XML) {
- /* For GET_NEXT_VOLUME output is already begun in
- * and will also end in gf_cli_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;
- }
- }
-
- if (dict) {
- ret = cli_xml_output_vol_info (local, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
- }
+ goto out;
- if (local->get_vol.flags == GF_CLI_GET_VOLUME) {
- ret = cli_xml_output_vol_info_end (local);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- }
+ if (thin_arbiter_count) {
+ snprintf(key, sizeof(key), "volume%d.thin_arbiter_brick", i);
+ ret = dict_get_str(dict, key, &ta_brick);
+ if (ret)
goto out;
+ cli_out("Thin-arbiter-path: %s", ta_brick);
}
- 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, sizeof(key), "volume%d.opt_count", i);
+ ret = dict_get_int32(dict, key, &opt_count);
+ if (ret)
+ goto out;
- snprintf (key, 256, "volume%d.type", i);
- ret = dict_get_int32 (dict, key, &type);
- if (ret)
- goto out;
+ if (!opt_count)
+ goto out;
- snprintf (key, 256, "volume%d.status", i);
- ret = dict_get_int32 (dict, key, &status);
- if (ret)
- goto out;
+ cli_out("Options Reconfigured:");
- snprintf (key, 256, "volume%d.brick_count", i);
- ret = dict_get_int32 (dict, key, &brick_count);
- if (ret)
- goto out;
+ snprintf(key, sizeof(key), "volume%d.option.", i);
- snprintf (key, 256, "volume%d.dist_count", i);
- ret = dict_get_int32 (dict, key, &dist_count);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.stripe_count", i);
- ret = dict_get_int32 (dict, key, &stripe_count);
- if (ret)
- goto out;
+ ret = dict_foreach(dict, _gf_cli_output_volinfo_opts, key);
+ if (ret)
+ goto out;
- snprintf (key, 256, "volume%d.replica_count", i);
- ret = dict_get_int32 (dict, key, &replica_count);
- if (ret)
- goto out;
+ i++;
+ }
- snprintf (key, 256, "volume%d.disperse_count", i);
- ret = dict_get_int32 (dict, key, &disperse_count);
- if (ret)
- goto out;
+ ret = 0;
+out:
+ if (ret)
+ cli_err("%s", err_str);
- snprintf (key, 256, "volume%d.redundancy_count", i);
- ret = dict_get_int32 (dict, key, &redundancy_count);
- if (ret)
- goto out;
+ cli_cmd_broadcast_response(ret);
- snprintf (key, 256, "volume%d.transport", i);
- ret = dict_get_int32 (dict, key, &transport);
- if (ret)
- goto out;
+ if (dict)
+ dict_unref(dict);
- snprintf (key, 256, "volume%d.volume_id", i);
- ret = dict_get_str (dict, key, &volume_id_str);
- if (ret)
- goto out;
+ gf_free_xdr_cli_rsp(rsp);
- vol_type = type;
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
+}
- // Distributed (stripe/replicate/stripe-replica) setups
- if ((type != GF_CLUSTER_TYPE_TIER) && (type > 0) &&
- (dist_count < brick_count))
- vol_type = type + GF_CLUSTER_TYPE_MAX - 1;
+static int
+gf_cli_create_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;
+ dict_t *rsp_dict = NULL;
+ call_frame_t *frame = NULL;
- cli_out ("Volume Name: %s", volname);
- cli_out ("Type: %s", cli_vol_type_str[vol_type]);
- cli_out ("Volume ID: %s", volume_id_str);
- cli_out ("Status: %s", cli_vol_status_str[status]);
+ GF_ASSERT(myframe);
-#ifdef HAVE_BD_XLATOR
- k = 0;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.xlator%d", i, k);
- ret = dict_get_str (dict, key, &caps);
- if (ret)
- goto next;
- do {
- j = 0;
- cli_out ("Xlator %d: %s", k + 1, caps);
- do {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key),
- "volume%d.xlator%d.caps%d",
- i, k, j++);
- ret = dict_get_str (dict, key, &caps);
- if (ret)
- break;
- cli_out ("Capability %d: %s", j, caps);
- } while (1);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key),
- "volume%d.xlator%d", i, ++k);
- ret = dict_get_str (dict, key, &caps);
- if (ret)
- break;
- } while (1);
-
-next:
-#else
- caps = 0; /* Avoid compiler warnings when BD not enabled */
-#endif
- gf_cli_print_number_of_bricks (type, brick_count,
- dist_count, stripe_count, replica_count,
- disperse_count, redundancy_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 (type == GF_CLUSTER_TYPE_TIER) {
- ret = gf_cli_print_tier_info (dict, i, brick_count);
- if (ret)
- goto out;
-
- } else {
- cli_out ("Bricks:");
- ret = print_brick_details (dict, i, j, brick_count);
- if (ret)
- goto out;
- }
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- snprintf (key, 256, "volume%d.opt_count",i);
- ret = dict_get_int32 (dict, key, &opt_count);
- if (ret)
- goto out;
+ frame = myframe;
- if (!opt_count)
- goto out;
+ GF_ASSERT(frame->local);
- cli_out ("Options Reconfigured:");
+ local = frame->local;
- snprintf (key, 256, "volume%d.option.",i);
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
- ret = dict_foreach (dict, _gf_cli_output_volinfo_opts, key);
- if (ret)
- goto out;
+ gf_log("cli", GF_LOG_INFO, "Received resp to create volume");
- i++;
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ if (rsp.op_ret == 0) {
+ rsp_dict = dict_new();
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len,
+ &rsp_dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
}
-
- ret = 0;
-out:
+ ret = cli_xml_output_vol_create(rsp_dict, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
if (ret)
- cli_err ("%s", err_str);
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- cli_cmd_broadcast_response (ret);
+ ret = dict_get_str_sizen(local->dict, "volname", &volname);
+ if (ret)
+ goto out;
- if (dict)
- dict_destroy (dict);
+ if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
+ cli_err("volume create: %s: failed: %s", volname, rsp.op_errstr);
+ else if (rsp.op_ret)
+ cli_err("volume create: %s: failed", volname);
+ else
+ cli_out(
+ "volume create: %s: success: "
+ "please start the volume to access data",
+ volname);
- free (rsp.dict.dict_val);
+ ret = rsp.op_ret;
- free (rsp.op_errstr);
+out:
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
- gf_log ("cli", GF_LOG_DEBUG, "Returning: %d", ret);
- return ret;
+ if (rsp_dict)
+ dict_unref(rsp_dict);
+ return ret;
}
-int
-gf_cli_create_volume_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+gf_cli_delete_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;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- local = ((call_frame_t *) (myframe))->local;
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- gf_log ("cli", GF_LOG_INFO, "Received resp to create volume");
-
- dict = local->dict;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- if (rsp.op_ret == 0) {
- rsp_dict = dict_new ();
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &rsp_dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed rsp_dict unserialization");
- goto out;
- }
- }
-
- ret = cli_xml_output_vol_create (rsp_dict, rsp.op_ret,
- rsp.op_errno, rsp.op_errstr);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ cli_local_t *local = NULL;
+ char *volname = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *rsp_dict = NULL;
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_err ("volume create: %s: failed: %s", volname,
- rsp.op_errstr);
- else if (rsp.op_ret)
- cli_err ("volume create: %s: failed", volname);
- else
- cli_out ("volume create: %s: success: "
- "please start the volume to access data", volname);
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- ret = rsp.op_ret;
+ GF_ASSERT(myframe);
+ frame = myframe;
-out:
- cli_cmd_broadcast_response (ret);
- free (rsp.dict.dict_val);
- free (rsp.op_errstr);
- return ret;
-}
+ GF_ASSERT(frame->local);
-int
-gf_cli_delete_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 *dict = NULL;
- dict_t *rsp_dict = NULL;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
+ local = frame->local;
- frame = myframe;
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
- local = frame->local;
+ gf_log("cli", GF_LOG_INFO, "Received resp to delete volume");
- if (local)
- dict = local->dict;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "dict get failed");
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ if (rsp.op_ret == 0) {
+ rsp_dict = dict_new();
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len,
+ &rsp_dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
goto out;
+ }
}
- gf_log ("cli", GF_LOG_INFO, "Received resp to delete volume");
+ ret = cli_xml_output_generic_volume("volDelete", rsp_dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if (global_state->mode & GLUSTER_MODE_XML) {
- if (rsp.op_ret == 0) {
- rsp_dict = dict_new ();
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &rsp_dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed rsp_dict unserialization");
- goto out;
- }
- }
+ ret = dict_get_str_sizen(local->dict, "volname", &volname);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR, "dict get failed");
+ goto out;
+ }
- ret = cli_xml_output_generic_volume ("volDelete", rsp_dict,
- rsp.op_ret, rsp.op_errno,
- rsp.op_errstr);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
-
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_err ("volume delete: %s: failed: %s", volname,
- rsp.op_errstr);
- else if (rsp.op_ret)
- cli_err ("volume delete: %s: failed", volname);
- else
- cli_out ("volume delete: %s: success", volname);
+ if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
+ cli_err("volume delete: %s: failed: %s", volname, rsp.op_errstr);
+ else if (rsp.op_ret)
+ cli_err("volume delete: %s: failed", volname);
+ else
+ cli_out("volume delete: %s: success", volname);
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- free (rsp.dict.dict_val);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
+ if (rsp_dict)
+ dict_unref(rsp_dict);
+ gf_log("", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-int
-gf_cli3_1_uuid_get_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+gf_cli3_1_uuid_get_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- char *uuid_str = NULL;
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- cli_local_t *local = NULL;
- call_frame_t *frame = NULL;
- dict_t *dict = NULL;
+ char *uuid_str = NULL;
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ cli_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
- if (-1 == req->rpc_status)
- goto out;
+ GF_ASSERT(myframe);
- frame = myframe;
+ if (-1 == req->rpc_status)
+ goto out;
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ frame = myframe;
- local = frame->local;
- frame->local = NULL;
+ GF_ASSERT(frame->local);
- gf_log ("cli", GF_LOG_INFO, "Received resp to uuid get");
+ local = frame->local;
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
- ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len,
- &dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to unserialize "
- "response for uuid get");
- goto out;
- }
+ frame->local = NULL;
- ret = dict_get_str (dict, "uuid", &uuid_str);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get uuid "
- "from dictionary");
- goto out;
- }
+ gf_log("cli", GF_LOG_INFO, "Received resp to uuid get");
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_dict ("uuidGenerate", dict, rsp.op_ret,
- rsp.op_errno, rsp.op_errstr);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
- if (rsp.op_ret) {
- if (strcmp (rsp.op_errstr, "") == 0)
- cli_err ("Get uuid was unsuccessful");
- else
- cli_err ("%s", rsp.op_errstr);
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
- } else {
- cli_out ("UUID: %s", uuid_str);
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_dict("uuidGenerate", dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
+
+ if (rsp.op_ret) {
+ if (strcmp(rsp.op_errstr, "") == 0)
+ cli_err("Get uuid was unsuccessful");
+ else
+ cli_err("%s", rsp.op_errstr);
+ } else {
+ ret = dict_get_str_sizen(dict, "uuid", &uuid_str);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get uuid from dictionary");
+ goto out;
}
- ret = rsp.op_ret;
+ cli_out("UUID: %s", uuid_str);
+ }
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- cli_local_wipe (local);
- if (rsp.dict.dict_val)
- free (rsp.dict.dict_val);
+ cli_cmd_broadcast_response(ret);
+ cli_local_wipe(local);
+ gf_free_xdr_cli_rsp(rsp);
+
+ if (dict)
+ dict_unref(dict);
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
+ gf_log("", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-int
-gf_cli3_1_uuid_reset_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+gf_cli3_1_uuid_reset_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;
- call_frame_t *frame = NULL;
- dict_t *dict = NULL;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- frame = myframe;
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ cli_local_t *local = NULL;
+ call_frame_t *frame = NULL;
- local = frame->local;
- frame->local = NULL;
+ GF_ASSERT(myframe);
- gf_log ("cli", GF_LOG_INFO, "Received resp to uuid reset");
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_dict ("uuidReset", dict, rsp.op_ret,
- rsp.op_errno, rsp.op_errstr);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ frame = myframe;
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_err ("%s", rsp.op_errstr);
- else
- cli_out ("resetting the peer uuid has been %s",
- (rsp.op_ret) ? "unsuccessful": "successful");
- ret = rsp.op_ret;
+ GF_ASSERT(frame->local);
-out:
- cli_cmd_broadcast_response (ret);
- cli_local_wipe (local);
- if (rsp.dict.dict_val)
- free (rsp.dict.dict_val);
- if (dict)
- dict_unref (dict);
+ local = frame->local;
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
-int
-gf_cli_start_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 *dict = NULL;
- dict_t *rsp_dict = NULL;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
+ frame->local = NULL;
- frame = myframe;
+ gf_log("cli", GF_LOG_INFO, "Received resp to uuid reset");
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_dict("uuidReset", NULL, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if (frame)
- local = frame->local;
+ if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
+ cli_err("%s", rsp.op_errstr);
+ else
+ cli_out("resetting the peer uuid has been %s",
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+ ret = rsp.op_ret;
- if (local)
- dict = local->dict;
+out:
+ cli_cmd_broadcast_response(ret);
+ cli_local_wipe(local);
+ gf_free_xdr_cli_rsp(rsp);
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "dict get failed");
- goto out;
- }
+ gf_log("", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
+}
- gf_log ("cli", GF_LOG_INFO, "Received resp to start volume");
+static int
+gf_cli_start_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 *rsp_dict = NULL;
- if (global_state->mode & GLUSTER_MODE_XML) {
- if (rsp.op_ret == 0) {
- rsp_dict = dict_new ();
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &rsp_dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed rsp_dict unserialization");
- goto out;
- }
- }
+ GF_ASSERT(myframe);
- ret = cli_xml_output_generic_volume ("volStart", rsp_dict,
- rsp.op_ret, rsp.op_errno,
- rsp.op_errstr);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_err ("volume start: %s: failed: %s", volname,
- rsp.op_errstr);
- else if (rsp.op_ret)
- cli_err ("volume start: %s: failed", volname);
- else
- cli_out ("volume start: %s: success", volname);
+ frame = myframe;
- ret = rsp.op_ret;
+ GF_ASSERT(frame->local);
-out:
- cli_cmd_broadcast_response (ret);
- free (rsp.dict.dict_val);
- free (rsp.op_errstr);
- return ret;
-}
+ local = frame->local;
-int
-gf_cli_stop_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 *dict = NULL;
- dict_t *rsp_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(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
- frame = myframe;
+ gf_log("cli", GF_LOG_INFO, "Received resp to start volume");
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ if (rsp.op_ret == 0) {
+ rsp_dict = dict_new();
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len,
+ &rsp_dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
goto out;
+ }
}
- if (frame)
- local = frame->local;
-
- if (local) {
- dict = local->dict;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (frame->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 (global_state->mode & GLUSTER_MODE_XML) {
- if (rsp.op_ret == 0) {
- rsp_dict = dict_new ();
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &rsp_dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed rsp_dict unserialization");
- goto out;
- }
- }
+ ret = cli_xml_output_generic_volume("volStart", rsp_dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- ret = cli_xml_output_generic_volume ("volStop", rsp_dict,
- rsp.op_ret, rsp.op_errno,
- rsp.op_errstr);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ ret = dict_get_str_sizen(local->dict, "volname", &volname);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "dict get failed");
+ goto out;
+ }
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- cli_err ("volume stop: %s: failed: %s", volname, rsp.op_errstr);
- else if (rsp.op_ret)
- cli_err ("volume stop: %s: failed", volname);
- else
- cli_out ("volume stop: %s: success", volname);
+ if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
+ cli_err("volume start: %s: failed: %s", volname, rsp.op_errstr);
+ else if (rsp.op_ret)
+ cli_err("volume start: %s: failed", volname);
+ else
+ cli_out("volume start: %s: success", volname);
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- free (rsp.op_errstr);
- free (rsp.dict.dict_val);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
- return ret;
+ if (rsp_dict)
+ dict_unref(rsp_dict);
+ return ret;
}
-int
-gf_cli_print_rebalance_status (dict_t *dict, enum gf_task_types task_type)
-{
- int ret = -1;
- int count = 0;
- int i = 1;
- char key[256] = {0,};
- gf_defrag_status_t status_rcd = GF_DEFRAG_STATUS_NOT_STARTED;
- uint64_t files = 0;
- uint64_t size = 0;
- uint64_t lookup = 0;
- char *node_name = NULL;
- uint64_t failures = 0;
- uint64_t skipped = 0;
- double elapsed = 0;
- char *status_str = NULL;
- char *size_str = NULL;
-
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "count not set");
- goto out;
- }
-
-
- cli_out ("%40s %16s %13s %13s %13s %13s %20s %18s", "Node",
- "Rebalanced-files", "size", "scanned", "failures", "skipped",
- "status", "run time in secs");
- cli_out ("%40s %16s %13s %13s %13s %13s %20s %18s", "---------",
- "-----------", "-----------", "-----------", "-----------",
- "-----------", "------------", "--------------");
- for (i = 1; i <= count; i++) {
- /* Reset the variables to prevent carryover of values */
- node_name = NULL;
- files = 0;
- size = 0;
- lookup = 0;
- skipped = 0;
- status_str = NULL;
- elapsed = 0;
-
- /* Check if status is NOT_STARTED, and continue early */
- memset (key, 0, 256);
- snprintf (key, 256, "status-%d", i);
-
- ret = dict_get_int32 (dict, key, (int32_t *)&status_rcd);
- if (ret) {
- gf_log ("cli", GF_LOG_TRACE, "count %d %d", count, i);
- gf_log ("cli", GF_LOG_TRACE, "failed to get status");
- goto out;
- }
-
- if (GF_DEFRAG_STATUS_NOT_STARTED == status_rcd)
- continue;
-
+static int
+gf_cli_stop_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 *rsp_dict = NULL;
- snprintf (key, 256, "node-name-%d", i);
- ret = dict_get_str (dict, key, &node_name);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE, "failed to get node-name");
+ GF_ASSERT(myframe);
- memset (key, 0, 256);
- snprintf (key, 256, "files-%d", i);
- ret = dict_get_uint64 (dict, key, &files);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE,
- "failed to get file count");
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- memset (key, 0, 256);
- snprintf (key, 256, "size-%d", i);
- ret = dict_get_uint64 (dict, key, &size);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE,
- "failed to get size of xfer");
+ frame = myframe;
- memset (key, 0, 256);
- snprintf (key, 256, "lookups-%d", i);
- ret = dict_get_uint64 (dict, key, &lookup);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE,
- "failed to get lookedup file count");
+ GF_ASSERT(frame->local);
- memset (key, 0, 256);
- snprintf (key, 256, "failures-%d", i);
- ret = dict_get_uint64 (dict, key, &failures);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE,
- "failed to get failures count");
+ local = frame->local;
- memset (key, 0, 256);
- snprintf (key, 256, "skipped-%d", i);
- ret = dict_get_uint64 (dict, key, &skipped);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE,
- "failed to get skipped count");
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
- /* For remove-brick include skipped count into failure count*/
- if (task_type != GF_TASK_TYPE_REBALANCE) {
- failures += skipped;
- skipped = 0;
- }
+ gf_log("cli", GF_LOG_INFO, "Received resp to stop volume");
- memset (key, 0, 256);
- snprintf (key, 256, "run-time-%d", i);
- ret = dict_get_double (dict, key, &elapsed);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE, "failed to get run-time");
-
- /* Check for array bound */
- if (status_rcd >= GF_DEFRAG_STATUS_MAX)
- status_rcd = GF_DEFRAG_STATUS_MAX;
-
- status_str = cli_vol_task_status_str[status_rcd];
- size_str = gf_uint64_2human_readable(size);
- if (size_str) {
- cli_out ("%40s %16"PRIu64 " %13s" " %13"PRIu64 " %13"
- PRIu64" %13"PRIu64 " %20s %18.2f", node_name,
- files, size_str, lookup, failures, skipped,
- status_str, elapsed);
- } else {
- cli_out ("%40s %16"PRIu64 " %13"PRIu64 " %13"PRIu64
- " %13"PRIu64" %13"PRIu64 " %20s %18.2f",
- node_name, files, size, lookup, failures,
- skipped, status_str, elapsed);
- }
- GF_FREE(size_str);
- }
-out:
- return ret;
-}
-
-int
-gf_cli_print_tier_status (dict_t *dict, enum gf_task_types task_type)
-{
- int ret = -1;
- int count = 0;
- int i = 1;
- uint64_t promoted = 0;
- uint64_t demoted = 0;
- char key[256] = {0,};
- char *node_name = NULL;
- gf_defrag_status_t status_rcd = GF_DEFRAG_STATUS_NOT_STARTED;
- char *status_str = NULL;
- char *size_str = NULL;
-
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "count not set");
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ if (rsp.op_ret == 0) {
+ rsp_dict = dict_new();
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len,
+ &rsp_dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
goto out;
+ }
}
- cli_out ("%-20s %-20s %-20s %-20s", "Node", "Promoted files",
- "Demoted files", "Status");
- cli_out ("%-20s %-20s %-20s %-20s", "---------", "---------",
- "---------", "---------");
-
- for (i = 1; i <= count; i++) {
- /* Reset the variables to prevent carryover of values */
- node_name = NULL;
- promoted = 0;
- demoted = 0;
-
- memset (key, 0, 256);
- snprintf (key, 256, "node-name-%d", i);
- ret = dict_get_str (dict, key, &node_name);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE, "failed to get node-name");
+ ret = cli_xml_output_generic_volume("volStop", rsp_dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- memset (key, 0, 256);
- snprintf (key, 256, "promoted-%d", i);
- ret = dict_get_uint64 (dict, key, &promoted);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE,
- "failed to get promoted count");
+ ret = dict_get_str_sizen(local->dict, "volname", &volname);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR,
+ "Unable to get volname from dict");
+ goto out;
+ }
- memset (key, 0, 256);
- snprintf (key, 256, "demoted-%d", i);
- ret = dict_get_uint64 (dict, key, &demoted);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE,
- "failed to get demoted count");
+ if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
+ cli_err("volume stop: %s: failed: %s", volname, rsp.op_errstr);
+ else if (rsp.op_ret)
+ cli_err("volume stop: %s: failed", volname);
+ else
+ cli_out("volume stop: %s: success", volname);
- memset (key, 0, 256);
- snprintf (key, 256, "status-%d", i);
- ret = dict_get_int32 (dict, key, (int32_t *)&status_rcd);
- if (ret)
- gf_log ("cli", GF_LOG_TRACE,
- "failed to get status");
+ ret = rsp.op_ret;
- /* Check for array bound */
- if (status_rcd >= GF_DEFRAG_STATUS_MAX)
- status_rcd = GF_DEFRAG_STATUS_MAX;
+out:
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
- status_str = cli_vol_task_status_str[status_rcd];
- cli_out ("%-20s %-20"PRIu64" %-20"PRIu64" %-20s",
- node_name, promoted, demoted, status_str);
+ if (rsp_dict)
+ dict_unref(rsp_dict);
- }
-out:
- return ret;
+ return ret;
}
-int
-gf_cli_defrag_volume_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- cli_local_t *local = NULL;
- char *volname = NULL;
- call_frame_t *frame = NULL;
- int cmd = 0;
- int ret = -1;
- dict_t *dict = NULL;
- dict_t *local_dict = NULL;
- char msg[1024] = {0,};
- char *task_id_str = NULL;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
+static int
+gf_cli_print_rebalance_status(dict_t *dict, enum gf_task_types task_type)
+{
+ int ret = -1;
+ int count = 0;
+ int i = 1;
+ char key[64] = {
+ 0,
+ };
+ int keylen;
+ gf_defrag_status_t status_rcd = GF_DEFRAG_STATUS_NOT_STARTED;
+ uint64_t files = 0;
+ uint64_t size = 0;
+ uint64_t lookup = 0;
+ char *node_name = NULL;
+ uint64_t failures = 0;
+ uint64_t skipped = 0;
+ double elapsed = 0;
+ char *status_str = NULL;
+ char *size_str = NULL;
+ int32_t hrs = 0;
+ uint32_t min = 0;
+ uint32_t sec = 0;
+ gf_boolean_t fix_layout = _gf_false;
+ uint64_t max_time = 0;
+ uint64_t max_elapsed = 0;
+ uint64_t time_left = 0;
+ gf_boolean_t show_estimates = _gf_false;
+
+ ret = dict_get_int32_sizen(dict, "count", &count);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "count not set");
+ goto out;
+ }
+
+ for (i = 1; i <= count; i++) {
+ keylen = snprintf(key, sizeof(key), "status-%d", i);
+ ret = dict_get_int32n(dict, key, keylen, (int32_t *)&status_rcd);
+ /* If information from a node is missing we should skip
+ * the node and try to fetch information of other nodes.
+ * If information is not found for all nodes, we should
+ * error out.
+ */
+ if (!ret)
+ break;
+ if (ret && i == count) {
+ gf_log("cli", GF_LOG_TRACE, "failed to get status");
+ goto out;
+ }
+ }
+
+ /* Fix layout will be sent to all nodes for the volume
+ so every status should be of type
+ GF_DEFRAG_STATUS_LAYOUT_FIX*
+ */
+
+ if ((task_type == GF_TASK_TYPE_REBALANCE) &&
+ (status_rcd >= GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED)) {
+ fix_layout = _gf_true;
+ }
+
+ if (fix_layout) {
+ cli_out("%35s %41s %27s", "Node", "status", "run time in h:m:s");
+ cli_out("%35s %41s %27s", "---------", "-----------", "------------");
+ } else {
+ cli_out("%40s %16s %13s %13s %13s %13s %20s %18s", "Node",
+ "Rebalanced-files", "size", "scanned", "failures", "skipped",
+ "status",
+ "run time in"
+ " h:m:s");
+ cli_out("%40s %16s %13s %13s %13s %13s %20s %18s", "---------",
+ "-----------", "-----------", "-----------", "-----------",
+ "-----------", "------------", "--------------");
+ }
+
+ for (i = 1; i <= count; i++) {
+ /* Reset the variables to prevent carryover of values */
+ node_name = NULL;
+ files = 0;
+ size = 0;
+ lookup = 0;
+ skipped = 0;
+ status_str = NULL;
+ elapsed = 0;
+ time_left = 0;
+
+ /* Check if status is NOT_STARTED, and continue early */
+ keylen = snprintf(key, sizeof(key), "status-%d", i);
+
+ ret = dict_get_int32n(dict, key, keylen, (int32_t *)&status_rcd);
+ if (ret == -ENOENT) {
+ gf_log("cli", GF_LOG_TRACE, "count %d %d", count, i);
+ gf_log("cli", GF_LOG_TRACE, "failed to get status");
+ gf_log("cli", GF_LOG_ERROR, "node down and has failed to set dict");
+ continue;
+ /* skip this node if value not available*/
+ } else if (ret) {
+ gf_log("cli", GF_LOG_TRACE, "count %d %d", count, i);
+ gf_log("cli", GF_LOG_TRACE, "failed to get status");
+ continue;
+ /* skip this node if value not available*/
+ }
+
+ if (GF_DEFRAG_STATUS_NOT_STARTED == status_rcd)
+ continue;
+
+ if (GF_DEFRAG_STATUS_STARTED == status_rcd)
+ show_estimates = _gf_true;
+
+ keylen = snprintf(key, sizeof(key), "node-name-%d", i);
+ ret = dict_get_strn(dict, key, keylen, &node_name);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get node-name");
- frame = myframe;
+ snprintf(key, sizeof(key), "files-%d", i);
+ ret = dict_get_uint64(dict, key, &files);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get file count");
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ snprintf(key, sizeof(key), "size-%d", i);
+ ret = dict_get_uint64(dict, key, &size);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get size of xfer");
- if (frame)
- local = frame->local;
+ snprintf(key, sizeof(key), "lookups-%d", i);
+ ret = dict_get_uint64(dict, key, &lookup);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get lookedup file count");
- if (local)
- local_dict = local->dict;
+ snprintf(key, sizeof(key), "failures-%d", i);
+ ret = dict_get_uint64(dict, key, &failures);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get failures count");
- ret = dict_get_str (local_dict, "volname", &volname);
- if (ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to get volname");
- goto out;
- }
+ snprintf(key, sizeof(key), "skipped-%d", i);
+ ret = dict_get_uint64(dict, key, &skipped);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get skipped count");
- ret = dict_get_int32 (local_dict, "rebalance-command", (int32_t*)&cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to get command");
- goto out;
+ /* For remove-brick include skipped count into failure count*/
+ if (task_type != GF_TASK_TYPE_REBALANCE) {
+ failures += skipped;
+ skipped = 0;
}
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
+ snprintf(key, sizeof(key), "run-time-%d", i);
+ ret = dict_get_double(dict, key, &elapsed);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get run-time");
- 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;
- }
- }
+ snprintf(key, sizeof(key), "time-left-%d", i);
+ ret = dict_get_uint64(dict, key, &time_left);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get time left");
- if (!((cmd == GF_DEFRAG_CMD_STOP) ||
- (cmd == GF_DEFRAG_CMD_STATUS) ||
- (cmd == GF_DEFRAG_CMD_STATUS_TIER)) &&
- !(global_state->mode & GLUSTER_MODE_XML)) {
- /* All other possibilites are about starting a rebalance */
- ret = dict_get_str (dict, GF_REBALANCE_TID_KEY, &task_id_str);
- if (rsp.op_ret && strcmp (rsp.op_errstr, "")) {
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
- } else {
- if (!rsp.op_ret) {
- /* append errstr in the cli msg for successful
- * case since unlock failures can be highlighted
- * event though rebalance command was successful
- */
- snprintf (msg, sizeof (msg),
- "Rebalance on %s has been started "
- "successfully. Use rebalance status "
- "command to check status of the "
- "rebalance process.\nID: %s\n%s",
- volname, task_id_str, rsp.op_errstr);
- } else {
- snprintf (msg, sizeof (msg),
- "Starting rebalance on volume %s has "
- "been unsuccessful.", volname);
- }
- }
- goto done;
- }
-
- if (cmd == GF_DEFRAG_CMD_STOP) {
- if (rsp.op_ret == -1) {
- if (strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg),
- "%s", rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg),
- "rebalance volume %s stop failed",
- volname);
- goto done;
- } else {
- /* append errstr in the cli msg for successful case
- * since unlock failures can be highlighted event though
- * rebalance command was successful */
- snprintf (msg, sizeof (msg),
- "rebalance process may be in the middle of a "
- "file migration.\nThe process will be fully "
- "stopped once the migration of the file is "
- "complete.\nPlease check rebalance process "
- "for completion before doing any further "
- "brick related tasks on the volume.\n%s",
- rsp.op_errstr);
- }
- }
- if (cmd == GF_DEFRAG_CMD_STATUS || cmd == GF_DEFRAG_CMD_STATUS_TIER) {
- if (rsp.op_ret == -1) {
- if (strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg),
- "%s", rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg),
- "Failed to get the status of "
- "rebalance process");
- goto done;
- } else {
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
- }
- }
+ if (elapsed > max_elapsed)
+ max_elapsed = elapsed;
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_rebalance (cmd, dict, rsp.op_ret,
- rsp.op_errno,
- rsp.op_errstr);
- goto out;
- }
+ if (time_left > max_time)
+ max_time = time_left;
- if (cmd == GF_DEFRAG_CMD_STATUS_TIER)
- ret = gf_cli_print_tier_status (dict, GF_TASK_TYPE_REBALANCE);
- else
- ret = gf_cli_print_rebalance_status (dict,
- GF_TASK_TYPE_REBALANCE);
+ /* Check for array bound */
+ if (status_rcd >= GF_DEFRAG_STATUS_MAX)
+ status_rcd = GF_DEFRAG_STATUS_MAX;
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to print rebalance status");
+ status_str = cli_vol_task_status_str[status_rcd];
+ size_str = gf_uint64_2human_readable(size);
+ hrs = elapsed / 3600;
+ min = ((uint64_t)elapsed % 3600) / 60;
+ sec = ((uint64_t)elapsed % 3600) % 60;
-done:
- if (global_state->mode & GLUSTER_MODE_XML)
- cli_xml_output_str ("volRebalance", msg,
- rsp.op_ret, rsp.op_errno,
- rsp.op_errstr);
- else {
- if (rsp.op_ret)
- cli_err ("volume rebalance: %s: failed%s%s",
- volname, strlen (msg) ? ": " : "", msg);
- else
- cli_out ("volume rebalance: %s: success%s%s",
- volname, strlen (msg) ? ": " : "", msg);
+ if (fix_layout) {
+ cli_out("%35s %50s %8d:%d:%d", node_name, status_str, hrs, min,
+ sec);
+ } else {
+ if (size_str) {
+ cli_out("%40s %16" PRIu64
+ " %13s"
+ " %13" PRIu64 " %13" PRIu64 " %13" PRIu64
+ " %20s "
+ "%8d:%02d:%02d",
+ node_name, files, size_str, lookup, failures, skipped,
+ status_str, hrs, min, sec);
+ } else {
+ cli_out("%40s %16" PRIu64 " %13" PRIu64 " %13" PRIu64
+ " %13" PRIu64 " %13" PRIu64
+ " %20s"
+ " %8d:%02d:%02d",
+ node_name, files, size, lookup, failures, skipped,
+ status_str, hrs, min, sec);
+ }
+ }
+ GF_FREE(size_str);
+ }
+
+ /* Max time will be non-zero if rebalance is still running */
+ if (max_time) {
+ hrs = max_time / 3600;
+ min = (max_time % 3600) / 60;
+ sec = (max_time % 3600) % 60;
+
+ if (hrs < REBAL_ESTIMATE_SEC_UPPER_LIMIT) {
+ cli_out(
+ "Estimated time left for rebalance to "
+ "complete : %8d:%02d:%02d",
+ hrs, min, sec);
+ } else {
+ cli_out(
+ "Estimated time left for rebalance to "
+ "complete : > 2 months. Please try again "
+ "later.");
+ }
+ } else {
+ /* Rebalance will return 0 if it could not calculate the
+ * estimates or if it is complete.
+ */
+ if (!show_estimates) {
+ goto out;
+ }
+ if (max_elapsed <= REBAL_ESTIMATE_START_TIME) {
+ cli_out(
+ "The estimated time for rebalance to complete "
+ "will be unavailable for the first 10 "
+ "minutes.");
+ } else {
+ cli_out(
+ "Rebalance estimated time unavailable. Please "
+ "try again later.");
}
- ret = rsp.op_ret;
-
+ }
out:
- free (rsp.op_errstr); //malloced by xdr
- free (rsp.dict.dict_val); //malloced by xdr
- if (dict)
- dict_unref (dict);
- cli_cmd_broadcast_response (ret);
- return ret;
+ return ret;
}
-int
-gf_cli_rename_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);
+static int
+gf_cli_defrag_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ cli_local_t *local = NULL;
+ char *volname = NULL;
+ call_frame_t *frame = NULL;
+ int cmd = 0;
+ int ret = -1;
+ dict_t *dict = NULL;
+ char msg[1024] = {
+ 0,
+ };
+ char *task_id_str = NULL;
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ GF_ASSERT(myframe);
+
+ frame = myframe;
+
+ GF_ASSERT(frame->local);
+
+ local = frame->local;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(local->dict, "volname", &volname);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR, "Failed to get volname");
+ goto out;
+ }
+
+ ret = dict_get_int32_sizen(local->dict, "rebalance-command",
+ (int32_t *)&cmd);
+ if (ret) {
+ gf_log("cli", 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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
+ gf_log("glusterd", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
}
+ }
+ if (!((cmd == GF_DEFRAG_CMD_STOP) || (cmd == GF_DEFRAG_CMD_STATUS)) &&
+ !(global_state->mode & GLUSTER_MODE_XML)) {
+ ret = dict_get_str_sizen(dict, GF_REBALANCE_TID_KEY, &task_id_str);
+ if (ret) {
+ gf_log("cli", GF_LOG_WARNING, "failed to get %s from dict",
+ GF_REBALANCE_TID_KEY);
+ }
+ if (rsp.op_ret && strcmp(rsp.op_errstr, "")) {
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ } else {
+ if (!rsp.op_ret) {
+ /* append errstr in the cli msg for successful
+ * case since unlock failures can be highlighted
+ * event though rebalance command was successful
+ */
+ snprintf(msg, sizeof(msg),
+ "Rebalance on %s has been "
+ "started successfully. Use "
+ "rebalance status command to"
+ " check status of the "
+ "rebalance process.\nID: %s",
+ volname, task_id_str);
+ } else {
+ snprintf(msg, sizeof(msg),
+ "Starting rebalance on volume %s has "
+ "been unsuccessful.",
+ volname);
+ }
+ }
+ goto done;
+ }
+
+ if (cmd == GF_DEFRAG_CMD_STOP) {
+ if (rsp.op_ret == -1) {
+ if (strcmp(rsp.op_errstr, ""))
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ else
+ snprintf(msg, sizeof(msg), "rebalance volume %s stop failed",
+ volname);
+ goto done;
+ } else {
+ /* append errstr in the cli msg for successful case
+ * since unlock failures can be highlighted event though
+ * rebalance command was successful */
+ snprintf(msg, sizeof(msg),
+ "rebalance process may be in the middle of a "
+ "file migration.\nThe process will be fully "
+ "stopped once the migration of the file is "
+ "complete.\nPlease check rebalance process "
+ "for completion before doing any further "
+ "brick related tasks on the volume.\n%s",
+ rsp.op_errstr);
+ }
+ }
+ if (cmd == GF_DEFRAG_CMD_STATUS) {
+ if (rsp.op_ret == -1) {
+ if (strcmp(rsp.op_errstr, ""))
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ else
+ snprintf(msg, sizeof(msg),
+ "Failed to get the status of rebalance process");
+ goto done;
+ } else {
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ }
+ }
- gf_log ("cli", GF_LOG_INFO, "Received resp to probe");
- snprintf (msg, sizeof (msg), "Rename volume %s",
- (rsp.op_ret) ? "unsuccessful": "successful");
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_rebalance(cmd, dict, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
+ goto out;
+ }
- 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;
- }
+ ret = gf_cli_print_rebalance_status(dict, GF_TASK_TYPE_REBALANCE);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, "Failed to print rebalance status");
+done:
+ if (global_state->mode & GLUSTER_MODE_XML)
+ cli_xml_output_str("volRebalance", msg, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
+ else {
if (rsp.op_ret)
- cli_err ("volume rename: failed");
+ cli_err("volume rebalance: %s: failed%s%s", volname,
+ strlen(msg) ? ": " : "", msg);
else
- cli_out ("volume rename: success");
-
- ret = rsp.op_ret;
+ cli_out("volume rebalance: %s: success%s%s", volname,
+ strlen(msg) ? ": " : "", msg);
+ }
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- return ret;
+ gf_free_xdr_cli_rsp(rsp);
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
+ return ret;
}
-int
-gf_cli_reset_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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- gf_log ("cli", GF_LOG_INFO, "Received resp to reset");
-
- if (strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg), "reset volume %s",
- (rsp.op_ret) ? "unsuccessful": "successful");
-
- 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;
- }
+static int
+gf_cli_rename_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,
+ };
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to probe");
+ snprintf(msg, sizeof(msg), "Rename volume %s",
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+
+ 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, XML_ERROR);
+ goto out;
+ }
- if (rsp.op_ret)
- cli_err ("volume reset: failed: %s", msg);
- else
- cli_out ("volume reset: success: %s", msg);
+ if (rsp.op_ret)
+ cli_err("volume rename: failed");
+ else
+ cli_out("volume rename: success");
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int
-gf_cli_ganesha_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+gf_cli_reset_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- char *help_str = NULL;
- char msg[1024] = {0,};
- char tmp_str[512] = {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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to ganesha");
-
- dict = dict_new ();
-
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ char msg[1024] = {
+ 0,
+ };
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to reset");
+
+ if (strcmp(rsp.op_errstr, ""))
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ else
+ snprintf(msg, sizeof(msg), "reset volume %s",
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+
+ 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)
- goto out;
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if (rsp.op_ret) {
- if (strcmp (rsp.op_errstr, ""))
- cli_err ("nfs-ganesha: failed: %s", rsp.op_errstr);
- else
- cli_err ("nfs-ganesha: failed");
- }
+ if (rsp.op_ret)
+ cli_err("volume reset: failed: %s", msg);
+ else
+ cli_out("volume reset: success: %s", msg);
- else {
- cli_out("nfs-ganesha : success ");
- }
-
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- if (dict)
- dict_unref (dict);
- cli_cmd_broadcast_response (ret);
- return ret;
-}
-
-char *
-is_server_debug_xlator (void *myframe)
-{
- call_frame_t *frame = NULL;
- cli_local_t *local = NULL;
- char **words = NULL;
- char *key = NULL;
- char *value = NULL;
- char *debug_xlator = NULL;
-
- frame = myframe;
- local = frame->local;
- words = (char **)local->words;
-
- while (*words != NULL) {
- if (strstr (*words, "trace") == NULL &&
- strstr (*words, "error-gen") == NULL) {
- words++;
- continue;
- }
-
- key = *words;
- words++;
- value = *words;
- if (value == NULL)
- break;
- if (strstr (value, "client")) {
- words++;
- continue;
- } else {
- if (!(strstr (value, "posix") || strstr (value, "acl")
- || strstr (value, "locks") ||
- strstr (value, "io-threads") ||
- strstr (value, "marker") ||
- strstr (value, "index"))) {
- words++;
- continue;
- } else {
- debug_xlator = gf_strdup (key);
- break;
- }
- }
- }
-
- return debug_xlator;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int
-gf_cli_set_volume_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- char *help_str = NULL;
- char msg[1024] = {0,};
- char *debug_xlator = NULL;
- char tmp_str[512] = {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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- 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);
-
- /* For brick processes graph change does not happen on the fly.
- * The process has to be restarted. So this is a check from the
- * volume set option such that if debug xlators such as trace/errorgen
- * are provided in the set command, warn the user.
- */
- debug_xlator = is_server_debug_xlator (myframe);
-
- if (dict_get_str (dict, "help-str", &help_str) && !msg[0])
- snprintf (msg, sizeof (msg), "Set volume %s",
- (rsp.op_ret) ? "unsuccessful": "successful");
- if (rsp.op_ret == 0 && debug_xlator) {
- snprintf (tmp_str, sizeof (tmp_str), "\n%s translator has been "
- "added to the server volume file. Please restart the"
- " volume for enabling the translator", debug_xlator);
- }
-
- 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;
- }
-
- if (rsp.op_ret) {
- if (strcmp (rsp.op_errstr, ""))
- cli_err ("volume set: failed: %s", rsp.op_errstr);
- else
- cli_err ("volume set: failed");
- } else {
- if (help_str == NULL) {
- if (debug_xlator == NULL)
- cli_out ("volume set: success");
- else
- cli_out ("volume set: success%s", tmp_str);
- }else {
- cli_out ("%s", help_str);
- }
- }
+static int
+gf_cli_ganesha_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
- ret = rsp.op_ret;
+ GF_ASSERT(myframe);
-out:
- if (dict)
- dict_unref (dict);
- GF_FREE (debug_xlator);
- cli_cmd_broadcast_response (ret);
- return ret;
-}
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
-int
-gf_cli_attach_tier_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- char msg[1024] = {0,};
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
- if (-1 == req->rpc_status) {
- goto out;
- }
+ gf_log("cli", GF_LOG_DEBUG, "Received resp to ganesha");
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
- gf_log ("cli", GF_LOG_INFO, "Received resp to attach tier");
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+ if (ret)
+ goto out;
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
+ if (rsp.op_ret) {
+ if (strcmp(rsp.op_errstr, ""))
+ cli_err("nfs-ganesha: failed: %s", rsp.op_errstr);
else
- snprintf (msg, sizeof (msg), "Attach tier %s",
- (rsp.op_ret) ? "unsuccessful" : "successful");
+ cli_err("nfs-ganesha: failed");
+ }
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_str ("volAttachTier", msg, rsp.op_ret,
- rsp.op_errno, rsp.op_errstr);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ else {
+ cli_out("nfs-ganesha : success ");
+ }
- if (rsp.op_ret)
- cli_err ("volume attach-tier: failed: %s", msg);
- else
- cli_out ("volume attach-tier: success");
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- free (rsp.dict.dict_val);
- free (rsp.op_errstr);
- return ret;
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
+ return ret;
}
-int
-gf_cli_detach_tier_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static char *
+is_server_debug_xlator(void *myframe)
{
+ call_frame_t *frame = NULL;
+ cli_local_t *local = NULL;
+ char **words = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ char *debug_xlator = NULL;
- 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;
- char *task_id_str = NULL;
- dict_t *rsp_dict = NULL;
+ frame = myframe;
+ local = frame->local;
+ words = (char **)local->words;
- if (-1 == req->rpc_status) {
- goto out;
+ while (*words != NULL) {
+ if (strstr(*words, "trace") == NULL &&
+ strstr(*words, "error-gen") == NULL) {
+ words++;
+ continue;
}
- frame = myframe;
- local = frame->local;
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- 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;
- }
-
- if (rsp.dict.dict_len) {
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len,
- &rsp_dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to unserialize rsp_dict");
- goto out;
- }
- }
-
- switch (cmd) {
- case GF_OP_CMD_DETACH_START:
- cmd_str = "start";
-
- ret = dict_get_str (rsp_dict, GF_REMOVE_BRICK_TID_KEY,
- &task_id_str);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "remove-brick-id is not present in dict");
- }
- break;
- case GF_OP_CMD_DETACH_COMMIT:
- cmd_str = "commit";
- break;
- case GF_OP_CMD_DETACH_COMMIT_FORCE:
- cmd_str = "commit force";
- break;
- default:
- cmd_str = "unknown";
+ key = *words;
+ words++;
+ value = *words;
+ if (value == NULL)
+ break;
+ if (strstr(value, "client")) {
+ words++;
+ continue;
+ } else {
+ if (!(strstr(value, "posix") || strstr(value, "acl") ||
+ strstr(value, "locks") || strstr(value, "io-threads") ||
+ strstr(value, "marker") || strstr(value, "index"))) {
+ words++;
+ continue;
+ } else {
+ debug_xlator = gf_strdup(key);
break;
+ }
}
+ }
- gf_log ("cli", GF_LOG_INFO, "Received resp to detach-tier");
-
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg), "Detach tier %s %s", cmd_str,
- (rsp.op_ret) ? "unsuccessful" : "successful");
-
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_remove_brick_detach_tier (
- _gf_false, rsp_dict,
- rsp.op_ret, rsp.op_errno,
- msg, "volDetachTier");
+ return debug_xlator;
+}
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+static int
+gf_cli_set_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *help_str = NULL;
+ char msg[1024] = {
+ 0,
+ };
+ char *debug_xlator = NULL;
+ char tmp_str[512] = {
+ 0,
+ };
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ 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) {
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
+
+ /* For brick processes graph change does not happen on the fly.
+ * The process has to be restarted. So this is a check from the
+ * volume set option such that if debug xlators such as trace/errorgen
+ * are provided in the set command, warn the user.
+ */
+ debug_xlator = is_server_debug_xlator(myframe);
+
+ if (dict_get_str_sizen(dict, "help-str", &help_str) && !msg[0])
+ snprintf(msg, sizeof(msg), "Set volume %s",
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+ if (rsp.op_ret == 0 && debug_xlator) {
+ snprintf(tmp_str, sizeof(tmp_str),
+ "\n%s translator has been "
+ "added to the server volume file. Please restart the"
+ " volume for enabling the translator",
+ debug_xlator);
+ }
+
+ 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, XML_ERROR);
+ goto out;
+ }
- if (rsp.op_ret) {
- cli_err ("volume detach-tier %s: failed: %s", cmd_str,
- msg);
+ if (rsp.op_ret) {
+ if (strcmp(rsp.op_errstr, ""))
+ cli_err("volume set: failed: %s", rsp.op_errstr);
+ else
+ cli_err("volume set: failed");
+ } else {
+ if (help_str == NULL) {
+ if (debug_xlator == NULL)
+ cli_out("volume set: success");
+ else
+ cli_out("volume set: success%s", tmp_str);
} else {
- cli_out ("volume detach-tier %s: success", cmd_str);
- if (GF_OP_CMD_DETACH_START == cmd && task_id_str != NULL)
- cli_out ("ID: %s", task_id_str);
- if (GF_OP_CMD_DETACH_COMMIT == cmd)
- cli_out ("Check the detached bricks to ensure all files"
- " are migrated.\nIf files with data are "
- "found on the brick path, copy them via a "
- "gluster mount point before re-purposing the "
- "removed brick. ");
+ cli_out("%s", help_str);
}
+ }
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- free (rsp.dict.dict_val);
- free (rsp.op_errstr);
-
- return ret;
+ if (dict)
+ dict_unref(dict);
+ GF_FREE(debug_xlator);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
int
-gf_cli_detach_tier_status_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- char msg[1024] = {0,};
- int32_t command = 0;
- gf1_op_commands cmd = GF_OP_CMD_NONE;
- cli_local_t *local = NULL;
- call_frame_t *frame = NULL;
- char *cmd_str = "unknown";
-
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- frame = myframe;
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- if (frame)
- local = frame->local;
- ret = dict_get_int32 (local->dict, "command", &command);
+gf_cli_add_brick_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ char msg[1024] = {
+ 0,
+ };
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to add brick");
+
+ if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ else
+ snprintf(msg, sizeof(msg), "Add Brick %s",
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+
+ 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)
- goto out;
- cmd = command;
-
- switch (cmd) {
- case GF_OP_CMD_STOP_DETACH_TIER:
- cmd_str = "stop";
- break;
- case GF_OP_CMD_STATUS:
- cmd_str = "status";
- break;
- default:
- break;
- }
-
- ret = rsp.op_ret;
- if (rsp.op_ret == -1) {
- if (strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg), "volume detach-tier %s: "
- "failed: %s", cmd_str, rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg), "volume detach-tier %s: "
- "failed", cmd_str);
-
- if (global_state->mode & GLUSTER_MODE_XML)
- goto xml_output;
-
- cli_err ("%s", msg);
- 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) {
- strncpy (msg, "failed to unserialize req-buffer to "
- "dictionary", sizeof (msg));
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- rsp.op_ret = -1;
- goto xml_output;
- }
-
- gf_log ("cli", GF_LOG_ERROR, "%s", msg);
- goto out;
- }
- }
-xml_output:
- if (global_state->mode & GLUSTER_MODE_XML) {
- if (strcmp (rsp.op_errstr, "")) {
- ret = cli_xml_output_vol_remove_brick_detach_tier (
- _gf_true, dict,
- rsp.op_ret,
- rsp.op_errno,
- rsp.op_errstr,
- "volDetachTier");
- } else {
- ret = cli_xml_output_vol_remove_brick_detach_tier
- (_gf_true, dict,
- rsp.op_ret,
- rsp.op_errno,
- msg,
- "volDetachTier");
- }
- goto out;
- }
-
- ret = gf_cli_print_rebalance_status (dict, GF_TASK_TYPE_REMOVE_BRICK);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to print remove-brick "
- "rebalance status");
- goto out;
- }
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if ((cmd == GF_OP_CMD_STOP_DETACH_TIER) && (rsp.op_ret == 0)) {
- cli_out ("'detach-tier' process may be in the middle of a "
- "file migration.\nThe process will be fully stopped "
- "once the migration of the file is complete.\nPlease "
- "check detach-tier process for completion before "
- "doing any further brick related tasks on the "
- "volume.");
- }
+ if (rsp.op_ret)
+ cli_err("volume add-brick: failed: %s", rsp.op_errstr);
+ else
+ cli_out("volume add-brick: success");
+ ret = rsp.op_ret;
out:
- free (rsp.dict.dict_val); /* malloced by xdr */
- if (dict)
- dict_unref (dict);
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-
-int
-gf_cli_add_brick_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+gf_cli3_remove_brick_status_cbk(struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- char msg[1024] = {0,};
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ char msg[1024] = {
+ 0,
+ };
+ int32_t command = 0;
+ gf1_op_commands cmd = GF_OP_CMD_NONE;
+ cli_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ const char *cmd_str;
- if (-1 == req->rpc_status) {
- goto out;
- }
+ GF_ASSERT(myframe);
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+ frame = myframe;
- gf_log ("cli", GF_LOG_INFO, "Received resp to add brick");
+ GF_ASSERT(frame->local);
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg), "Add Brick %s",
- (rsp.op_ret) ? "unsuccessful": "successful");
+ local = frame->local;
- 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;
- }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
- if (rsp.op_ret)
- cli_err ("volume add-brick: failed: %s", rsp.op_errstr);
- else
- cli_out ("volume add-brick: success");
- ret = rsp.op_ret;
+ ret = dict_get_int32_sizen(local->dict, "command", &command);
+ if (ret)
+ goto out;
-out:
- cli_cmd_broadcast_response (ret);
- free (rsp.dict.dict_val);
- free (rsp.op_errstr);
- return ret;
-}
+ cmd = command;
-int
-gf_cli3_remove_brick_status_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- char msg[1024] = {0,};
- int32_t command = 0;
- gf1_op_commands cmd = GF_OP_CMD_NONE;
- cli_local_t *local = NULL;
- call_frame_t *frame = NULL;
- char *cmd_str = "unknown";
-
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- frame = myframe;
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- if (frame)
- local = frame->local;
- ret = dict_get_int32 (local->dict, "command", &command);
- if (ret)
- goto out;
- cmd = command;
-
- switch (cmd) {
+ switch (cmd) {
case GF_OP_CMD_STOP:
- cmd_str = "stop";
- break;
+ cmd_str = "stop";
+ break;
case GF_OP_CMD_STATUS:
- cmd_str = "status";
- break;
+ cmd_str = "status";
+ break;
default:
- break;
- }
-
- ret = rsp.op_ret;
- if (rsp.op_ret == -1) {
- if (strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg), "volume remove-brick %s: "
- "failed: %s", cmd_str, rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg), "volume remove-brick %s: "
- "failed", cmd_str);
+ cmd_str = "unknown";
+ break;
+ }
+
+ ret = rsp.op_ret;
+ if (rsp.op_ret == -1) {
+ if (strcmp(rsp.op_errstr, ""))
+ snprintf(msg, sizeof(msg), "volume remove-brick %s: failed: %s",
+ cmd_str, rsp.op_errstr);
+ else
+ snprintf(msg, sizeof(msg), "volume remove-brick %s: failed",
+ cmd_str);
- if (global_state->mode & GLUSTER_MODE_XML)
- goto xml_output;
+ if (global_state->mode & GLUSTER_MODE_XML)
+ goto xml_output;
- cli_err ("%s", msg);
- goto out;
- }
+ cli_err("%s", msg);
+ goto out;
+ }
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
+ 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) {
- strncpy (msg, "failed to unserialize req-buffer to "
- "dictionary", sizeof (msg));
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+ if (ret < 0) {
+ strncpy(msg, DICT_UNSERIALIZE_FAIL, sizeof(msg));
- if (global_state->mode & GLUSTER_MODE_XML) {
- rsp.op_ret = -1;
- goto xml_output;
- }
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ rsp.op_ret = -1;
+ goto xml_output;
+ }
- gf_log ("cli", GF_LOG_ERROR, "%s", msg);
- goto out;
- }
+ gf_log("cli", GF_LOG_ERROR, "%s", msg);
+ goto out;
}
+ }
xml_output:
- if (global_state->mode & GLUSTER_MODE_XML) {
- if (strcmp (rsp.op_errstr, "")) {
- ret = cli_xml_output_vol_remove_brick_detach_tier (
- _gf_true, dict,
- rsp.op_ret,
- rsp.op_errno,
- rsp.op_errstr,
- "volRemoveBrick");
- } else {
- ret = cli_xml_output_vol_remove_brick_detach_tier (
- _gf_true, dict,
- rsp.op_ret,
- rsp.op_errno,
- msg,
- "volRemoveBrick");
- }
- goto out;
- }
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ if (strcmp(rsp.op_errstr, "")) {
+ ret = cli_xml_output_vol_remove_brick(_gf_true, dict, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr,
+ "volRemoveBrick");
+ } else {
+ ret = cli_xml_output_vol_remove_brick(_gf_true, dict, rsp.op_ret,
+ rsp.op_errno, msg,
+ "volRemoveBrick");
+ }
+ goto out;
+ }
+
+ ret = gf_cli_print_rebalance_status(dict, GF_TASK_TYPE_REMOVE_BRICK);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to print remove-brick rebalance status");
+ goto out;
+ }
+
+ if ((cmd == GF_OP_CMD_STOP) && (rsp.op_ret == 0)) {
+ cli_out(
+ "'remove-brick' process may be in the middle of a "
+ "file migration.\nThe process will be fully stopped "
+ "once the migration of the file is complete.\nPlease "
+ "check remove-brick process for completion before "
+ "doing any further brick related tasks on the "
+ "volume.");
+ }
+
+out:
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
+}
- ret = gf_cli_print_rebalance_status (dict, GF_TASK_TYPE_REMOVE_BRICK);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to print remove-brick "
- "rebalance status");
- goto out;
- }
+static int
+gf_cli_remove_brick_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ 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;
+ char *task_id_str = NULL;
+ dict_t *rsp_dict = NULL;
- if ((cmd == GF_OP_CMD_STOP) && (rsp.op_ret == 0)) {
- cli_out ("'remove-brick' process may be in the middle of a "
- "file migration.\nThe process will be fully stopped "
- "once the migration of the file is complete.\nPlease "
- "check remove-brick process for completion before "
- "doing any further brick related tasks on the "
- "volume.");
- }
+ GF_ASSERT(myframe);
-out:
- free (rsp.dict.dict_val); //malloced by xdr
- if (dict)
- dict_unref (dict);
- cli_cmd_broadcast_response (ret);
- return ret;
-}
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+ frame = myframe;
-int
-gf_cli_remove_brick_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- 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;
- char *task_id_str = NULL;
- dict_t *rsp_dict = NULL;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
+ GF_ASSERT(frame->local);
- frame = myframe;
- local = frame->local;
+ local = frame->local;
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ 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;
- }
+ ret = dict_get_int32_sizen(local->dict, "command", (int32_t *)&cmd);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "failed to get command");
+ goto out;
+ }
- if (rsp.dict.dict_len) {
- rsp_dict = dict_new ();
- if (!rsp_dict) {
- ret = -1;
- goto out;
- }
+ if (rsp.dict.dict_len) {
+ rsp_dict = dict_new();
+ if (!rsp_dict) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len,
- &rsp_dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to unserialize rsp_dict");
- goto out;
- }
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &rsp_dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
}
+ }
- switch (cmd) {
+ switch (cmd) {
case GF_OP_CMD_DETACH_START:
case GF_OP_CMD_START:
- cmd_str = "start";
-
- ret = dict_get_str (rsp_dict, GF_REMOVE_BRICK_TID_KEY, &task_id_str);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "remove-brick-id is not present in dict");
- }
- break;
+ cmd_str = "start";
+
+ ret = dict_get_str_sizen(rsp_dict, GF_REMOVE_BRICK_TID_KEY,
+ &task_id_str);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "remove-brick-id is not present in dict");
+ }
+ break;
case GF_OP_CMD_COMMIT:
- cmd_str = "commit";
- break;
+ cmd_str = "commit";
+ break;
case GF_OP_CMD_COMMIT_FORCE:
- cmd_str = "commit force";
- break;
+ 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, ""))
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg), "Remove Brick %s %s", cmd_str,
- (rsp.op_ret) ? "unsuccessful": "successful");
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_remove_brick_detach_tier (
- _gf_false, rsp_dict,
- rsp.op_ret, rsp.op_errno,
- msg, "volRemoveBrick");
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ cmd_str = "unknown";
+ break;
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to remove brick");
+
+ if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ else
+ snprintf(msg, sizeof(msg), "Remove Brick %s %s", cmd_str,
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_remove_brick(_gf_false, rsp_dict, rsp.op_ret,
+ rsp.op_errno, msg,
+ "volRemoveBrick");
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if (rsp.op_ret) {
- cli_err ("volume remove-brick %s: failed: %s", cmd_str,
- msg);
- } else {
- cli_out ("volume remove-brick %s: success", cmd_str);
- if (GF_OP_CMD_START == cmd && task_id_str != NULL)
- cli_out ("ID: %s", task_id_str);
- if (GF_OP_CMD_COMMIT == cmd)
- cli_out ("Check the removed bricks to ensure all files "
- "are migrated.\nIf files with data are "
- "found on the brick path, copy them via a "
- "gluster mount point before re-purposing the "
- "removed brick. ");
- }
+ if (rsp.op_ret) {
+ cli_err("volume remove-brick %s: failed: %s", cmd_str, msg);
+ } else {
+ cli_out("volume remove-brick %s: success", cmd_str);
+ if (GF_OP_CMD_START == cmd && task_id_str != NULL)
+ cli_out("ID: %s", task_id_str);
+ if (GF_OP_CMD_COMMIT == cmd)
+ cli_out(
+ "Check the removed bricks to ensure all files "
+ "are migrated.\nIf files with data are "
+ "found on the brick path, copy them via a "
+ "gluster mount point before re-purposing the "
+ "removed brick. ");
+ }
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- free (rsp.dict.dict_val);
- free (rsp.op_errstr);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
- return ret;
-}
+ if (rsp_dict)
+ dict_unref(rsp_dict);
-int
-gf_cli_replace_brick_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;
- call_frame_t *frame = NULL;
- dict_t *dict = NULL;
- char *src_brick = NULL;
- char *dst_brick = NULL;
- char *status_reply = NULL;
- char *rb_operation_str = NULL;
- dict_t *rsp_dict = NULL;
- char msg[1024] = {0,};
- char *task_id_str = NULL;
- char *replace_op = 0;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- frame = (call_frame_t *) myframe;
+ return ret;
+}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+static int
+gf_cli_reset_brick_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;
+ call_frame_t *frame = NULL;
+ const char *rb_operation_str = NULL;
+ dict_t *rsp_dict = NULL;
+ char msg[1024] = {
+ 0,
+ };
+ char *reset_op = NULL;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ frame = myframe;
+
+ GF_ASSERT(frame->local);
+
+ local = frame->local;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(local->dict, "operation", &reset_op);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR, "dict_get on operation failed");
+ goto out;
+ }
+
+ if (strcmp(reset_op, "GF_RESET_OP_START") &&
+ strcmp(reset_op, "GF_RESET_OP_COMMIT") &&
+ strcmp(reset_op, "GF_RESET_OP_COMMIT_FORCE")) {
+ ret = -1;
+ goto out;
+ }
+
+ 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 (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- local = frame->local;
- GF_ASSERT (local);
- dict = local->dict;
-
- ret = dict_get_str (dict, "operation", &replace_op);
- if (ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "dict_get on operation failed");
- goto out;
- }
-
- 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 (frame->this->name, GF_LOG_ERROR, "failed to "
- "unserialize rsp buffer to dictionary");
- goto out;
- }
- }
-
- if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
-
- if (rsp.op_ret || ret)
- rb_operation_str = gf_strdup ("replace-brick commit "
- "force operation failed");
- else
- rb_operation_str = gf_strdup ("replace-brick commit "
- "force operation "
- "successful");
- } else {
- gf_log (frame->this->name, GF_LOG_DEBUG, "Unknown operation");
- }
-
- if (rsp.op_ret && (strcmp (rsp.op_errstr, ""))) {
- rb_operation_str = gf_strdup (rsp.op_errstr);
- }
-
- gf_log ("cli", GF_LOG_INFO, "Received resp to replace brick");
- snprintf (msg, sizeof (msg), "%s",
- rb_operation_str ? rb_operation_str : "Unknown operation");
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_replace_brick (replace_op, rsp_dict,
- rsp.op_ret,
- rsp.op_errno, msg);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ gf_log(frame->this->name, GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
+ }
+
+ if (rsp.op_ret && (strcmp(rsp.op_errstr, ""))) {
+ rb_operation_str = rsp.op_errstr;
+ } else {
+ if (!strcmp(reset_op, "GF_RESET_OP_START")) {
+ if (rsp.op_ret)
+ rb_operation_str = "reset-brick start operation failed";
+ else
+ rb_operation_str = "reset-brick start operation successful";
+ } else if (!strcmp(reset_op, "GF_RESET_OP_COMMIT")) {
+ if (rsp.op_ret)
+ rb_operation_str = "reset-brick commit operation failed";
+ else
+ rb_operation_str = "reset-brick commit operation successful";
+ } else if (!strcmp(reset_op, "GF_RESET_OP_COMMIT_FORCE")) {
+ if (rsp.op_ret)
+ rb_operation_str = "reset-brick commit force operation failed";
+ else
+ rb_operation_str =
+ "reset-brick commit force operation successful";
+ }
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to reset brick");
+ snprintf(msg, sizeof(msg), "%s",
+ rb_operation_str ? rb_operation_str : "Unknown operation");
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_replace_brick(rsp_dict, rsp.op_ret,
+ rsp.op_errno, msg);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if (rsp.op_ret)
- cli_err ("volume replace-brick: failed: %s", msg);
- else
- cli_out ("volume replace-brick: success: %s", msg);
- ret = rsp.op_ret;
+ if (rsp.op_ret)
+ cli_err("volume reset-brick: failed: %s", msg);
+ else
+ cli_out("volume reset-brick: success: %s", msg);
+ ret = rsp.op_ret;
out:
- if (frame)
- frame->local = NULL;
-
- if (local) {
- dict_unref (local->dict);
- cli_local_wipe (local);
- }
+ if (frame)
+ frame->local = NULL;
- if (rb_operation_str)
- GF_FREE (rb_operation_str);
+ if (local)
+ cli_local_wipe(local);
- cli_cmd_broadcast_response (ret);
- free (rsp.dict.dict_val);
- if (rsp_dict)
- dict_unref (rsp_dict);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ if (rsp_dict)
+ dict_unref(rsp_dict);
- return ret;
+ return ret;
}
-
-
static int
-gf_cli_log_rotate_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);
+gf_cli_replace_brick_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;
+ call_frame_t *frame = NULL;
+ const char *rb_operation_str = NULL;
+ dict_t *rsp_dict = NULL;
+ char msg[1024] = {
+ 0,
+ };
+ char *replace_op = NULL;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ frame = myframe;
+
+ GF_ASSERT(frame->local);
+
+ local = frame->local;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(local->dict, "operation", &replace_op);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR, "dict_get on operation failed");
+ goto out;
+ }
+
+ 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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
+ gf_log(frame->this->name, GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
}
+ }
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to log rotate");
-
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg), "%s", rsp.op_errstr);
+ if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
+ if (rsp.op_ret || ret)
+ rb_operation_str = "replace-brick commit force operation failed";
else
- snprintf (msg, sizeof (msg), "log rotate %s",
- (rsp.op_ret) ? "unsuccessful": "successful");
-
- 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;
- }
+ rb_operation_str =
+ "replace-brick commit force operation successful";
+ } else {
+ gf_log(frame->this->name, GF_LOG_DEBUG, "Unknown operation");
+ }
+
+ if (rsp.op_ret && (strcmp(rsp.op_errstr, ""))) {
+ rb_operation_str = rsp.op_errstr;
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to replace brick");
+ snprintf(msg, sizeof(msg), "%s",
+ rb_operation_str ? rb_operation_str : "Unknown operation");
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_replace_brick(rsp_dict, rsp.op_ret,
+ rsp.op_errno, msg);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if (rsp.op_ret)
- cli_err ("volume log-rotate: failed: %s", msg);
- else
- cli_out ("volume log-rotate: success");
- ret = rsp.op_ret;
+ if (rsp.op_ret)
+ cli_err("volume replace-brick: failed: %s", msg);
+ else
+ cli_out("volume replace-brick: success: %s", msg);
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- free (rsp.dict.dict_val);
+ if (frame)
+ frame->local = NULL;
+
+ if (local)
+ cli_local_wipe(local);
+
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ if (rsp_dict)
+ dict_unref(rsp_dict);
- return ret;
+ return ret;
}
static int
-gf_cli_sync_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;
- }
+gf_cli_log_rotate_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ char msg[1024] = {
+ 0,
+ };
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_DEBUG, "Received resp to log rotate");
+
+ if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+ else
+ snprintf(msg, sizeof(msg), "log rotate %s",
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+
+ 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, XML_ERROR);
+ goto out;
+ }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ if (rsp.op_ret)
+ cli_err("volume log-rotate: failed: %s", msg);
+ else
+ cli_out("volume log-rotate: success");
+ ret = rsp.op_ret;
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to sync");
+out:
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
- if (rsp.op_ret && strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg), "volume sync: failed: %s",
- rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg), "volume sync: %s",
- (rsp.op_ret) ? "failed": "success");
+ return ret;
+}
- 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;
- }
+static int
+gf_cli_sync_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,
+ };
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_DEBUG, "Received resp to sync");
+
+ if (rsp.op_ret && strcmp(rsp.op_errstr, ""))
+ snprintf(msg, sizeof(msg), "volume sync: failed: %s", rsp.op_errstr);
+ else
+ snprintf(msg, sizeof(msg), "volume sync: %s",
+ (rsp.op_ret) ? "failed" : "success");
+
+ 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, XML_ERROR);
+ goto out;
+ }
- if (rsp.op_ret)
- cli_err ("%s", msg);
- else
- cli_out ("%s", msg);
- ret = rsp.op_ret;
+ 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;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
static int
-print_quota_list_usage_output (cli_local_t *local, char *path, int64_t avail,
- char *sl_str, quota_limits_t *limits,
- quota_meta_t *used_space, gf_boolean_t sl,
- gf_boolean_t hl, double sl_num)
-{
- int32_t ret = -1;
- char *used_str = NULL;
- char *avail_str = NULL;
- char *hl_str = NULL;
- char *sl_val = NULL;
+print_quota_list_usage_output(cli_local_t *local, char *path, int64_t avail,
+ char *sl_str, quota_limits_t *limits,
+ quota_meta_t *used_space, gf_boolean_t sl,
+ gf_boolean_t hl, double sl_num,
+ gf_boolean_t limit_set)
+{
+ int32_t ret = -1;
+ char *used_str = NULL;
+ char *avail_str = NULL;
+ char *hl_str = NULL;
+ char *sl_val = NULL;
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_quota_xml_output(local, path, limits->hl, sl_str, sl_num,
+ used_space->size, avail, sl ? "Yes" : "No",
+ hl ? "Yes" : "No", limit_set);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to output in xml format for quota list command");
+ }
+ goto out;
+ }
- hl_str = gf_uint64_2human_readable (limits->hl);
- used_str = gf_uint64_2human_readable (used_space->size);
- avail_str = gf_uint64_2human_readable (avail);
+ used_str = gf_uint64_2human_readable(used_space->size);
- sl_val = gf_uint64_2human_readable (sl_num);
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_quota_xml_output (local, path, hl_str,
- sl_str, used_str,
- avail_str, sl ? "Yes" : "No",
- hl ? "Yes" : "No");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to "
- "output in xml format for quota "
- "list command");
- }
- goto out;
- }
+ if (limit_set) {
+ hl_str = gf_uint64_2human_readable(limits->hl);
+ sl_val = gf_uint64_2human_readable(sl_num);
if (!used_str) {
- cli_out ("%-40s %7s %7s(%s) %8"PRIu64 "%9"PRIu64" %15s %18s",
- path, hl_str, sl_str, sl_val, used_space->size, avail,
- sl ? "Yes" : "No", hl ? "Yes" : "No");
+ cli_out("%-40s %7s %7s(%s) %8" PRIu64 "%9" PRIu64
+ ""
+ "%15s %18s",
+ path, hl_str, sl_str, sl_val, used_space->size, avail,
+ sl ? "Yes" : "No", hl ? "Yes" : "No");
} else {
- cli_out ("%-40s %7s %7s(%s) %8s %7s %15s %20s", path, hl_str,
- sl_str, sl_val, used_str, avail_str, sl ? "Yes" : "No",
- hl ? "Yes" : "No");
+ avail_str = gf_uint64_2human_readable(avail);
+ cli_out("%-40s %7s %7s(%s) %8s %7s %15s %20s", path, hl_str, sl_str,
+ sl_val, used_str, avail_str, sl ? "Yes" : "No",
+ hl ? "Yes" : "No");
}
+ } else {
+ cli_out("%-36s %10s %10s %14s %9s %15s %18s", path, "N/A", "N/A",
+ used_str, "N/A", "N/A", "N/A");
+ }
- ret = 0;
+ ret = 0;
out:
- GF_FREE (hl_str);
- GF_FREE (used_str);
- GF_FREE (avail_str);
+ GF_FREE(hl_str);
+ GF_FREE(used_str);
+ GF_FREE(avail_str);
+ GF_FREE(sl_val);
- return ret;
+ return ret;
}
static int
-print_quota_list_object_output (cli_local_t *local, char *path, int64_t avail,
+print_quota_list_object_output(cli_local_t *local, char *path, int64_t avail,
char *sl_str, quota_limits_t *limits,
quota_meta_t *used_space, gf_boolean_t sl,
- gf_boolean_t hl, double sl_num)
+ gf_boolean_t hl, double sl_num,
+ gf_boolean_t limit_set)
{
- int32_t ret = -1;
- int64_t sl_val = sl_num;
+ int32_t ret = -1;
+ int64_t sl_val = sl_num;
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_quota_object_xml_output (local, path, sl_str, limits,
- used_space, avail,
- sl ? "Yes" : "No",
- hl ? "Yes" : "No");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to "
- "output in xml format for quota "
- "list command");
- }
- goto out;
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_quota_object_xml_output(local, path, sl_str, sl_val, limits,
+ used_space, avail, sl ? "Yes" : "No",
+ hl ? "Yes" : "No", limit_set);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to output in xml format for quota list command");
}
+ goto out;
+ }
- cli_out ("%-40s %9"PRIu64" %9s(%"PRId64") %10"PRIu64" %10"PRIu64
- "%11"PRIu64" %15s %20s", path, limits->hl, sl_str, sl_val,
- used_space->file_count, used_space->dir_count,
- avail, sl ? "Yes" : "No", hl ? "Yes" : "No");
-
- ret = 0;
+ if (limit_set) {
+ cli_out("%-40s %9" PRIu64 " %9s(%" PRId64 ") %10" PRIu64
+ ""
+ "%10" PRIu64 " %11" PRIu64 " %15s %20s",
+ path, limits->hl, sl_str, sl_val, used_space->file_count,
+ used_space->dir_count, avail, sl ? "Yes" : "No",
+ hl ? "Yes" : "No");
+ } else {
+ cli_out("%-40s %9s %9s %10" PRIu64 " %10" PRIu64 " %11s %15s %20s",
+ path, "N/A", "N/A", used_space->file_count,
+ used_space->dir_count, "N/A", "N/A", "N/A");
+ }
+ ret = 0;
out:
- return ret;
+ return ret;
}
static int
-print_quota_list_output (cli_local_t *local, char *path, char *default_sl,
- quota_limits_t *limits, quota_meta_t *used_space,
- int type)
-{
- int64_t avail = 0;
- char percent_str[20] = {0};
- char *sl_final = NULL;
- int ret = -1;
- double sl_num = 0;
- gf_boolean_t sl = _gf_false;
- gf_boolean_t hl = _gf_false;
- int64_t used_size = 0;
-
- GF_ASSERT (local);
- GF_ASSERT (path);
-
+print_quota_list_output(cli_local_t *local, char *path, char *default_sl,
+ quota_limits_t *limits, quota_meta_t *used_space,
+ int type, gf_boolean_t limit_set)
+{
+ int64_t avail = 0;
+ char percent_str[20] = {0};
+ char *sl_final = NULL;
+ int ret = -1;
+ double sl_num = 0;
+ gf_boolean_t sl = _gf_false;
+ gf_boolean_t hl = _gf_false;
+ int64_t used_size = 0;
+
+ GF_ASSERT(local);
+ GF_ASSERT(path);
+
+ if (limit_set) {
if (limits->sl < 0) {
- ret = gf_string2percent (default_sl, &sl_num);
- sl_num = (sl_num * limits->hl) / 100;
- sl_final = default_sl;
+ ret = gf_string2percent(default_sl, &sl_num);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "could not convert default soft limit to percent");
+ goto out;
+ }
+ sl_num = (sl_num * limits->hl) / 100;
+ sl_final = default_sl;
} else {
- sl_num = (limits->sl * limits->hl) / 100;
- snprintf (percent_str, sizeof (percent_str), "%"PRIu64"%%",
- limits->sl);
- sl_final = percent_str;
+ sl_num = (limits->sl * limits->hl) / 100;
+ ret = snprintf(percent_str, sizeof(percent_str), "%" PRIu64 "%%",
+ limits->sl);
+ if (ret < 0)
+ goto out;
+ sl_final = percent_str;
}
if (type == GF_QUOTA_OPTION_TYPE_LIST)
- used_size = used_space->size;
+ used_size = used_space->size;
else
- used_size = used_space->file_count + used_space->dir_count;
+ used_size = used_space->file_count + used_space->dir_count;
if (limits->hl > used_size) {
- avail = limits->hl - used_size;
- hl = _gf_false;
- if (used_size > sl_num)
- sl = _gf_true;
- else
- sl = _gf_false;
+ avail = limits->hl - used_size;
+ hl = _gf_false;
+ if (used_size > sl_num)
+ sl = _gf_true;
+ else
+ sl = _gf_false;
} else {
- avail = 0;
- hl = sl = _gf_true;
+ avail = 0;
+ hl = sl = _gf_true;
}
+ }
- if (type == GF_QUOTA_OPTION_TYPE_LIST)
- ret = print_quota_list_usage_output (local, path, avail,
- sl_final, limits,
- used_space, sl, hl,
- sl_num);
- else
- ret = print_quota_list_object_output (local, path, avail,
- sl_final, limits,
- used_space, sl, hl,
- sl_num);
-
- return ret;
+ if (type == GF_QUOTA_OPTION_TYPE_LIST)
+ ret = print_quota_list_usage_output(local, path, avail, sl_final,
+ limits, used_space, sl, hl, sl_num,
+ limit_set);
+ else
+ ret = print_quota_list_object_output(local, path, avail, sl_final,
+ limits, used_space, sl, hl, sl_num,
+ limit_set);
+out:
+ return ret;
}
static int
-print_quota_list_from_mountdir (cli_local_t *local, char *mountdir,
- char *default_sl, char *path, int type)
-{
- int ret = -1;
- ssize_t xattr_size = 0;
- quota_limits_t limits = {0,};
- quota_meta_t used_space = {0,};
- char *key = NULL;
-
- GF_ASSERT (local);
- GF_ASSERT (mountdir);
- GF_ASSERT (path);
-
- if (type == GF_QUOTA_OPTION_TYPE_LIST)
- key = "trusted.glusterfs.quota.limit-set";
- else
- key = "trusted.glusterfs.quota.limit-objects";
-
-
- ret = sys_lgetxattr (mountdir, key, (void *)&limits, sizeof (limits));
- if (ret < 0) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get the xattr %s "
- "on %s. Reason : %s", key, mountdir, strerror (errno));
-
- switch (errno) {
+print_quota_list_from_mountdir(cli_local_t *local, char *mountdir,
+ char *default_sl, char *path, int type)
+{
+ int ret = -1;
+ ssize_t xattr_size = 0;
+ quota_limits_t limits = {
+ 0,
+ };
+ quota_meta_t used_space = {
+ 0,
+ };
+ char *key = NULL;
+ gf_boolean_t limit_set = _gf_true;
+
+ GF_ASSERT(local);
+ GF_ASSERT(mountdir);
+ GF_ASSERT(path);
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIST)
+ key = QUOTA_LIMIT_KEY;
+ else
+ key = QUOTA_LIMIT_OBJECTS_KEY;
+
+ ret = sys_lgetxattr(mountdir, key, (void *)&limits, sizeof(limits));
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to get the xattr %s on %s. Reason : %s", key, mountdir,
+ strerror(errno));
+
+ switch (errno) {
#if defined(ENODATA)
- case ENODATA:
+ case ENODATA:
#endif
#if defined(ENOATTR) && (ENOATTR != ENODATA)
- case ENOATTR:
+ case ENOATTR:
#endif
- cli_err ("%-40s %s", path, "Limit not set");
- break;
- default:
- cli_err ("%-40s %s", path, strerror (errno));
- break;
- }
+ /* If it's an ENOATTR, quota/inode-quota is
+ * configured(limit is set at least for one directory).
+ * The user is trying to issue 'list/list-objects'
+ * command for a directory on which quota limit is
+ * not set and we are showing the used-space in case
+ * of list-usage and showing (dir_count, file_count)
+ * in case of list-objects. Other labels are
+ * shown "N/A".
+ */
- goto out;
+ limit_set = _gf_false;
+ goto enoattr;
+ break;
+
+ default:
+ cli_err("%-40s %s", path, strerror(errno));
+ break;
}
- limits.hl = ntoh64 (limits.hl);
- limits.sl = ntoh64 (limits.sl);
+ goto out;
+ }
- xattr_size = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size",
- NULL, 0);
- if (xattr_size < (sizeof (int64_t) * 2) &&
- type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS) {
- ret = -1;
+ limits.hl = ntoh64(limits.hl);
+ limits.sl = ntoh64(limits.sl);
- /* This can happen when glusterfs is upgraded from 3.6 to 3.7
- * and the xattr healing is not completed.
- */
- } else if (xattr_size > (sizeof (int64_t) * 2)) {
- ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size",
- &used_space, sizeof (used_space));
- } else if (xattr_size > 0) {
- /* This is for compatibility.
- * Older version had only file usage
- */
- ret = sys_lgetxattr (mountdir, "trusted.glusterfs.quota.size",
- &(used_space.size), sizeof (used_space.size));
- used_space.file_count = 0;
- used_space.dir_count = 0;
- } else {
- ret = -1;
- }
+enoattr:
+ xattr_size = sys_lgetxattr(mountdir, QUOTA_SIZE_KEY, NULL, 0);
+ if (xattr_size < (sizeof(int64_t) * 2) &&
+ type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS) {
+ ret = -1;
- if (ret < 0) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get quota size "
- "on path %s: %s", mountdir, strerror (errno));
- print_quota_list_empty (path, type);
- goto out;
- }
+ /* This can happen when glusterfs is upgraded from 3.6 to 3.7
+ * and the xattr healing is not completed.
+ */
+ } else if (xattr_size > (sizeof(int64_t) * 2)) {
+ ret = sys_lgetxattr(mountdir, QUOTA_SIZE_KEY, &used_space,
+ sizeof(used_space));
+ } else if (xattr_size > 0) {
+ /* This is for compatibility.
+ * Older version had only file usage
+ */
+ ret = sys_lgetxattr(mountdir, QUOTA_SIZE_KEY, &(used_space.size),
+ sizeof(used_space.size));
+ used_space.file_count = 0;
+ used_space.dir_count = 0;
+ } else {
+ ret = -1;
+ }
+
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get quota size on path %s: %s",
+ mountdir, strerror(errno));
+ print_quota_list_empty(path, type);
+ goto out;
+ }
- used_space.size = ntoh64 (used_space.size);
- used_space.file_count = ntoh64 (used_space.file_count);
- used_space.dir_count = ntoh64 (used_space.dir_count);
+ used_space.size = ntoh64(used_space.size);
+ used_space.file_count = ntoh64(used_space.file_count);
+ used_space.dir_count = ntoh64(used_space.dir_count);
- ret = print_quota_list_output (local, path, default_sl, &limits,
- &used_space, type);
+ ret = print_quota_list_output(local, path, default_sl, &limits, &used_space,
+ type, limit_set);
out:
- return ret;
+ return ret;
}
-int
-gf_cli_print_limit_list_from_dict (cli_local_t *local, char *volname,
- dict_t *dict, char *default_sl, int count,
- int op_ret, int op_errno, char *op_errstr)
-{
- int ret = -1;
- int i = 0;
- char key[1024] = {0,};
- char mountdir[PATH_MAX] = {0,};
- char *path = NULL;
- gf_boolean_t xml_err_flag = _gf_false;
- char err_str[NAME_MAX] = {0,};
- int type = -1;
-
- if (!dict|| count <= 0)
- goto out;
+static int
+gluster_remove_auxiliary_mount(char *volname)
+{
+ int ret = -1;
+ char mountdir[PATH_MAX] = {
+ 0,
+ };
+ xlator_t *this = NULL;
- ret = dict_get_int32 (dict, "type", &type);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get quota type");
- goto out;
- }
+ this = THIS;
+ GF_ASSERT(this);
- /* Need to check if any quota limits are set on the volume before trying
- * to list them
- */
- if (!_limits_set_on_volume (volname, type)) {
- snprintf (err_str, sizeof (err_str), "No%s quota configured on "
- "volume %s",
- (type == GF_QUOTA_OPTION_TYPE_LIST) ? "" : " inode",
- volname);
- if (global_state->mode & GLUSTER_MODE_XML) {
- xml_err_flag = _gf_true;
- } else {
- cli_out ("quota: %s", err_str);
- }
- ret = 0;
- goto out;
- }
+ GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(mountdir, volname, "/");
+ ret = gf_umount_lazy(this->name, mountdir, 1);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "umount on %s failed, reason : %s",
+ mountdir, strerror(errno));
+ }
- /* Check if the mount is online before doing any listing */
- if (!_quota_aux_mount_online (volname)) {
- ret = -1;
- goto out;
- }
+ return ret;
+}
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_quota_limit_list_begin
- (local, op_ret, op_errno, op_errstr);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting xml begin");
- goto out;
- }
- } else {
- print_quota_list_header (type);
+static int
+gf_cli_print_limit_list_from_dict(cli_local_t *local, char *volname,
+ dict_t *dict, char *default_sl, int count,
+ int op_ret, int op_errno, char *op_errstr)
+{
+ int ret = -1;
+ int i = 0;
+ char key[32] = {
+ 0,
+ };
+ int keylen;
+ char mountdir[PATH_MAX] = {
+ 0,
+ };
+ char *path = NULL;
+ int type = -1;
+
+ if (!dict || count <= 0)
+ goto out;
+
+ ret = dict_get_int32_sizen(dict, "type", &type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get quota type");
+ goto out;
+ }
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_quota_limit_list_begin(local, op_ret, op_errno,
+ op_errstr);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
}
+ } else {
+ print_quota_list_header(type);
+ }
- while (count--) {
- snprintf (key, sizeof (key), "path%d", i++);
-
- ret = dict_get_str (dict, key, &path);
- if (ret < 0) {
- gf_log ("cli", GF_LOG_DEBUG, "Path not present in limit"
- " list");
- continue;
- }
+ while (count--) {
+ keylen = snprintf(key, sizeof(key), "path%d", i++);
- ret = gf_canonicalize_path (path);
- if (ret)
- goto out;
- GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH (mountdir, volname, path);
- ret = print_quota_list_from_mountdir (local, mountdir,
- default_sl, path, type);
+ ret = dict_get_strn(dict, key, keylen, &path);
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_DEBUG, "Path not present in limit list");
+ continue;
}
+ ret = gf_canonicalize_path(path);
+ if (ret)
+ goto out;
+ GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(mountdir, volname, path);
+ ret = print_quota_list_from_mountdir(local, mountdir, default_sl, path,
+ type);
+ }
+
out:
- if (xml_err_flag) {
- ret = cli_xml_output_str ("volQuota", NULL, -1, 0, err_str);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Error outputting in xml "
- "format");
- }
- }
- return ret;
+ return ret;
}
-int
-print_quota_list_from_quotad (call_frame_t *frame, dict_t *rsp_dict,
- int32_t list_count)
-{
- char *path = NULL;
- char *default_sl = NULL;
- int ret = -1;
- cli_local_t *local = NULL;
- dict_t *gd_rsp_dict = NULL;
- quota_meta_t used_space = {0, };
- quota_limits_t limits = {0, };
- quota_limits_t *size_limits = NULL;
- int32_t type = 0;
-
- GF_ASSERT (frame);
-
- local = frame->local;
- gd_rsp_dict = local->dict;
-
- ret = dict_get_int32 (rsp_dict, "type", &type);
+static int
+print_quota_list_from_quotad(call_frame_t *frame, dict_t *rsp_dict)
+{
+ char *path = NULL;
+ char *default_sl = NULL;
+ int ret = -1;
+ cli_local_t *local = NULL;
+ dict_t *gd_rsp_dict = NULL;
+ quota_meta_t used_space = {
+ 0,
+ };
+ quota_limits_t limits = {
+ 0,
+ };
+ quota_limits_t *size_limits = NULL;
+ int32_t type = 0;
+ int32_t success_count = 0;
+
+ GF_ASSERT(frame);
+
+ local = frame->local;
+ gd_rsp_dict = local->dict;
+
+ ret = dict_get_int32_sizen(rsp_dict, "type", &type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get type");
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(rsp_dict, GET_ANCESTRY_PATH_KEY, &path);
+ if (ret) {
+ gf_log("cli", GF_LOG_WARNING, "path key is not present in dict");
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(gd_rsp_dict, "default-soft-limit", &default_sl);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR,
+ "failed to get default soft limit");
+ goto out;
+ }
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIST) {
+ ret = dict_get_bin(rsp_dict, QUOTA_LIMIT_KEY, (void **)&size_limits);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get type");
- goto out;
+ gf_log("cli", GF_LOG_WARNING, "limit key not present in dict on %s",
+ path);
+ goto out;
}
-
- ret = dict_get_str (rsp_dict, GET_ANCESTRY_PATH_KEY, &path);
+ } else {
+ ret = dict_get_bin(rsp_dict, QUOTA_LIMIT_OBJECTS_KEY,
+ (void **)&size_limits);
if (ret) {
- gf_log ("cli", GF_LOG_WARNING, "path key is not present "
- "in dict");
+ gf_log("cli", GF_LOG_WARNING,
+ "object limit key not present in dict on %s", path);
+ goto out;
+ }
+ }
+
+ limits.hl = ntoh64(size_limits->hl);
+ limits.sl = ntoh64(size_limits->sl);
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIST)
+ ret = quota_dict_get_meta(rsp_dict, QUOTA_SIZE_KEY,
+ SLEN(QUOTA_SIZE_KEY), &used_space);
+ else
+ ret = quota_dict_get_inode_meta(rsp_dict, QUOTA_SIZE_KEY,
+ SLEN(QUOTA_SIZE_KEY), &used_space);
+
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_WARNING, "size key not present in dict");
+ print_quota_list_empty(path, type);
+ goto out;
+ }
+
+ LOCK(&local->lock);
+ {
+ ret = dict_get_int32_sizen(gd_rsp_dict, "quota-list-success-count",
+ &success_count);
+ if (ret)
+ success_count = 0;
+
+ ret = dict_set_int32_sizen(gd_rsp_dict, "quota-list-success-count",
+ success_count + 1);
+ }
+ UNLOCK(&local->lock);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to set quota-list-success-count in dict");
+ goto out;
+ }
+
+ if (success_count == 0) {
+ if (!(global_state->mode & GLUSTER_MODE_XML)) {
+ print_quota_list_header(type);
+ } else {
+ ret = cli_xml_output_vol_quota_limit_list_begin(local, 0, 0, NULL);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
goto out;
+ }
}
+ }
- ret = dict_get_str (gd_rsp_dict, "default-soft-limit", &default_sl);
- if (ret) {
- gf_log (frame->this->name, GF_LOG_ERROR, "failed to "
- "get default soft limit");
- goto out;
- }
+ ret = print_quota_list_output(local, path, default_sl, &limits, &used_space,
+ type, _gf_true);
+out:
+ return ret;
+}
- if (type == GF_QUOTA_OPTION_TYPE_LIST) {
- ret = dict_get_bin (rsp_dict, QUOTA_LIMIT_KEY,
- (void **)&size_limits);
- if (ret) {
- gf_log ("cli", GF_LOG_WARNING,
- "limit key not present in dict on %s",
- path);
- goto out;
- }
- } else {
- ret = dict_get_bin (rsp_dict, QUOTA_LIMIT_OBJECTS_KEY,
- (void **)&size_limits);
- if (ret) {
- gf_log ("cli", GF_LOG_WARNING,
- "object limit key not present in dict on %s",
- path);
- goto out;
- }
- }
+static void *
+cli_cmd_broadcast_response_detached(void *opaque)
+{
+ int32_t ret = 0;
- limits.hl = ntoh64 (size_limits->hl);
- limits.sl = ntoh64 (size_limits->sl);
+ ret = (intptr_t)opaque;
+ cli_cmd_broadcast_response(ret);
- if (type == GF_QUOTA_OPTION_TYPE_LIST)
- ret = quota_dict_get_meta (rsp_dict, QUOTA_SIZE_KEY,
- &used_space);
- else
- ret = quota_dict_get_inode_meta (rsp_dict, QUOTA_SIZE_KEY,
- &used_space);
+ return NULL;
+}
- if (ret < 0) {
- gf_log ("cli", GF_LOG_WARNING,
- "size key not present in dict");
- print_quota_list_empty (path, type);
- goto out;
- }
+static int32_t
+cli_quota_compare_path(struct list_head *list1, struct list_head *list2)
+{
+ struct list_node *node1 = NULL;
+ struct list_node *node2 = NULL;
+ dict_t *dict1 = NULL;
+ dict_t *dict2 = NULL;
+ char *path1 = NULL;
+ char *path2 = NULL;
+ int ret = 0;
- if (list_count == 0) {
- if (!(global_state->mode & GLUSTER_MODE_XML)) {
- print_quota_list_header (type);
- } else {
- ret = cli_xml_output_vol_quota_limit_list_begin
- (local, 0, 0, NULL);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Error in "
- "printing xml output");
- goto out;
- }
- }
- }
+ node1 = list_entry(list1, struct list_node, list);
+ node2 = list_entry(list2, struct list_node, list);
- ret = print_quota_list_output (local, path, default_sl, &limits,
- &used_space, type);
-out:
- return ret;
-}
+ dict1 = node1->ptr;
+ dict2 = node2->ptr;
-void*
-cli_cmd_broadcast_response_detached (void *opaque)
-{
- int32_t ret = 0;
+ ret = dict_get_str_sizen(dict1, GET_ANCESTRY_PATH_KEY, &path1);
+ if (ret < 0)
+ return 0;
- ret = (intptr_t) opaque;
- cli_cmd_broadcast_response (ret);
+ ret = dict_get_str_sizen(dict2, GET_ANCESTRY_PATH_KEY, &path2);
+ if (ret < 0)
+ return 0;
- return NULL;
+ return strcmp(path1, path2);
}
-int
-cli_quotad_getlimit_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+cli_quotad_getlimit_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
/*TODO: we need to gather the path, hard-limit, soft-limit and used space*/
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- call_frame_t *frame = NULL;
- cli_local_t *local = NULL;
- dict_t *gd_rsp_dict = NULL;
- int32_t list_count = 0;
- pthread_t th_id = {0, };
-
- frame = myframe;
- GF_ASSERT (frame);
-
- local = frame->local;
- gd_rsp_dict = local->dict;
-
- LOCK (&local->lock);
- {
- ret = dict_get_int32 (gd_rsp_dict, "quota-list-count",
- &list_count);
- if (ret)
- list_count = 0;
- ret = dict_set_int32 (gd_rsp_dict, "quota-list-count",
- list_count + 1);
- }
- UNLOCK (&local->lock);
-
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set "
- "quota-list-count in dict");
- goto out;
- }
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ struct list_node *node = NULL;
+ struct list_node *tmpnode = NULL;
+ call_frame_t *frame = NULL;
+ cli_local_t *local = NULL;
+ int32_t list_count = 0;
+ pthread_t th_id = {
+ 0,
+ };
+ int32_t max_count = 0;
+
+ GF_ASSERT(myframe);
+
+ frame = myframe;
+
+ GF_ASSERT(frame->local);
+
+ local = frame->local;
+
+ LOCK(&local->lock);
+ {
+ ret = dict_get_int32_sizen(local->dict, "quota-list-count",
+ &list_count);
+ if (ret)
+ list_count = 0;
+
+ list_count++;
+ ret = dict_set_int32_sizen(local->dict, "quota-list-count", list_count);
+ }
+ UNLOCK(&local->lock);
+
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to set quota-list-count in dict");
+ goto out;
+ }
+
+ if (-1 == req->rpc_status) {
+ if (list_count == 0)
+ cli_err(
+ "Connection failed. Please check if quota "
+ "daemon is operational.");
+ ret = -1;
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ if (rsp.op_ret) {
+ ret = -1;
+ if (strcmp(rsp.op_errstr, ""))
+ cli_err("quota command failed : %s", rsp.op_errstr);
+ else
+ cli_err("quota command : failed");
+ goto out;
+ }
- if (-1 == req->rpc_status) {
- if (list_count == 0)
- cli_err ("Connection failed. Please check if quota "
- "daemon is operational.");
- ret = -1;
- goto out;
- }
+ if (rsp.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new();
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- if (rsp.op_ret) {
- ret = -1;
- if (strcmp (rsp.op_errstr, ""))
- cli_err ("quota command failed : %s", rsp.op_errstr);
- else
- cli_err ("quota command : failed");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ 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 ("cli", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
- print_quota_list_from_quotad (frame, dict, list_count);
+ node = list_node_add_order(dict, &local->dict_list,
+ cli_quota_compare_path);
+ if (node == NULL) {
+ gf_log("cli", GF_LOG_ERROR, "failed to add node to the list");
+ dict_unref(dict);
+ ret = -1;
+ goto out;
}
+ }
-out:
- /* Bad Fix: CLI holds the lock to process a command.
- * When processing quota list command, below sequence of steps executed
- * in the same thread and causing deadlock
- *
- * 1) CLI holds the lock
- * 2) Send rpc_clnt_submit request to quotad for quota usage
- * 3) If quotad is down, rpc_clnt_submit invokes cbk function with error
- * 4) cbk function cli_quotad_getlimit_cbk invokes
- * cli_cmd_broadcast_response which tries to hold lock to broadcast
- * the results and hangs, because same thread has already holding
- * the lock
- *
- * Broadcasting response in a seperate thread which is not a
- * good fix. This needs to be re-visted with better solution
- */
- if (ret == -1) {
- ret = pthread_create (&th_id, NULL,
- cli_cmd_broadcast_response_detached,
- (void *)-1);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR, "pthread_create failed: "
- "%s", strerror (errno));
- } else {
- cli_cmd_broadcast_response (ret);
- }
+ ret = dict_get_int32_sizen(local->dict, "max_count", &max_count);
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_ERROR, "failed to get max_count");
+ goto out;
+ }
- if (dict)
- dict_unref (dict);
+ if (list_count == max_count) {
+ list_for_each_entry_safe(node, tmpnode, &local->dict_list, list)
+ {
+ dict = node->ptr;
+ print_quota_list_from_quotad(frame, dict);
+ list_node_del(node);
+ dict_unref(dict);
+ }
+ }
+
+out:
+ /* Bad Fix: CLI holds the lock to process a command.
+ * When processing quota list command, below sequence of steps executed
+ * in the same thread and causing deadlock
+ *
+ * 1) CLI holds the lock
+ * 2) Send rpc_clnt_submit request to quotad for quota usage
+ * 3) If quotad is down, rpc_clnt_submit invokes cbk function with error
+ * 4) cbk function cli_quotad_getlimit_cbk invokes
+ * cli_cmd_broadcast_response which tries to hold lock to broadcast
+ * the results and hangs, because same thread has already holding
+ * the lock
+ *
+ * Broadcasting response in a separate thread which is not a
+ * good fix. This needs to be re-visted with better solution
+ */
+ if (ret == -1) {
+ ret = pthread_create(&th_id, NULL, cli_cmd_broadcast_response_detached,
+ (void *)-1);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, "pthread_create failed: %s",
+ strerror(errno));
+ } else {
+ cli_cmd_broadcast_response(ret);
+ }
+ gf_free_xdr_cli_rsp(rsp);
- free (rsp.dict.dict_val);
- return ret;
+ return ret;
}
-int
-cli_quotad_getlimit (call_frame_t *frame, xlator_t *this, void *data)
+static int
+cli_quotad_getlimit(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
- 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 the data");
+ dict = data;
+ ret = add_cli_cmd_timeout_to_dict(dict);
- goto out;
- }
+ ret = dict_allocate_and_serialize(dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log(this->name, GF_LOG_ERROR, DICT_SERIALIZE_FAIL);
- ret = cli_cmd_submit (global_quotad_rpc, &req, frame, &cli_quotad_clnt,
- GF_AGGREGATOR_GETLIMIT, NULL,
- this, cli_quotad_getlimit_cbk,
- (xdrproc_t) xdr_gf_cli_req);
+ goto out;
+ }
+
+ ret = cli_cmd_submit(global_quotad_rpc, &req, frame, &cli_quotad_clnt,
+ GF_AGGREGATOR_GETLIMIT, NULL, this,
+ cli_quotad_getlimit_cbk, (xdrproc_t)xdr_gf_cli_req);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-void
-gf_cli_quota_list (cli_local_t *local, char *volname, dict_t *dict,
- char *default_sl, int count, int op_ret,
- int op_errno, char *op_errstr)
+static void
+gf_cli_quota_list(cli_local_t *local, char *volname, dict_t *dict,
+ char *default_sl, int count, int op_ret, int op_errno,
+ char *op_errstr)
{
- GF_VALIDATE_OR_GOTO ("cli", volname, out);
+ if (!cli_cmd_connected())
+ goto out;
- if (!connected)
- goto out;
+ if (count > 0) {
+ GF_VALIDATE_OR_GOTO("cli", volname, out);
- if (count > 0)
- gf_cli_print_limit_list_from_dict (local, volname, dict,
- default_sl, count, op_ret,
- op_errno, op_errstr);
+ gf_cli_print_limit_list_from_dict(local, volname, dict, default_sl,
+ count, op_ret, op_errno, op_errstr);
+ }
out:
- return;
+ return;
}
-int
-gf_cli_quota_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- char *volname = NULL;
- int32_t type = 0;
- call_frame_t *frame = NULL;
- char *default_sl = NULL;
- char *limit_list = NULL;
- cli_local_t *local = NULL;
- dict_t *aggr = NULL;
- char *default_sl_dup = NULL;
- int32_t entry_count = 0;
- if (-1 == req->rpc_status) {
- goto out;
+static int
+gf_cli_quota_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *volname = NULL;
+ int32_t type = 0;
+ call_frame_t *frame = NULL;
+ char *default_sl = NULL;
+ cli_local_t *local = NULL;
+ char *default_sl_dup = NULL;
+ int32_t entry_count = 0;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ frame = myframe;
+
+ GF_ASSERT(frame->local);
+
+ local = frame->local;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ if (rsp.op_ret) {
+ ret = -1;
+ if (global_state->mode & GLUSTER_MODE_XML)
+ goto xml_output;
+
+ if (strcmp(rsp.op_errstr, "")) {
+ cli_err("quota command failed : %s", rsp.op_errstr);
+ if (rsp.op_ret == -ENOENT)
+ cli_err("please enter the path relative to the volume");
+ } else {
+ cli_err("quota command : failed");
}
- frame = myframe;
- local = frame->local;
- aggr = local->dict;
+ goto out;
+ }
+
+ if (rsp.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new();
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
}
+ }
- if (rsp.op_ret) {
- ret = -1;
- if (global_state->mode & GLUSTER_MODE_XML)
- goto xml_output;
-
- if (strcmp (rsp.op_errstr, "")) {
- cli_err ("quota command failed : %s", rsp.op_errstr);
- if (rsp.op_ret == -ENOENT)
- cli_err ("please enter the path relative to "
- "the volume");
- } else {
- cli_err ("quota command : failed");
- }
-
- goto out;
- }
+ gf_log("cli", GF_LOG_DEBUG, "Received resp to quota command");
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
+ ret = dict_get_str_sizen(dict, "default-soft-limit", &default_sl);
+ if (ret)
+ gf_log(frame->this->name, GF_LOG_TRACE,
+ "failed to get default soft limit");
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("cli", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
+ // default-soft-limit is part of rsp_dict only iff we sent
+ // GLUSTER_CLI_QUOTA with type being GF_QUOTA_OPTION_TYPE_LIST
+ if (default_sl) {
+ default_sl_dup = gf_strdup(default_sl);
+ if (!default_sl_dup) {
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_dynstr_sizen(local->dict, "default-soft-limit",
+ default_sl_dup);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_TRACE,
+ "failed to set default soft limit");
+ GF_FREE(default_sl_dup);
}
+ }
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to quota command");
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ gf_log(frame->this->name, GF_LOG_ERROR, "failed to get volname");
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- gf_log (frame->this->name, GF_LOG_ERROR,
- "failed to get volname");
+ ret = dict_get_int32_sizen(dict, "type", &type);
+ if (ret)
+ gf_log(frame->this->name, GF_LOG_TRACE, "failed to get type");
- ret = dict_get_str (dict, "default-soft-limit", &default_sl);
- if (ret)
- gf_log (frame->this->name, GF_LOG_TRACE, "failed to get "
- "default soft limit");
+ ret = dict_get_int32_sizen(dict, "count", &entry_count);
+ if (ret)
+ gf_log(frame->this->name, GF_LOG_TRACE, "failed to get count");
- // default-soft-limit is part of rsp_dict only iff we sent
- // GLUSTER_CLI_QUOTA with type being GF_QUOTA_OPTION_TYPE_LIST
- if (default_sl) {
- default_sl_dup = gf_strdup (default_sl);
- if (!default_sl_dup) {
- ret = -1;
- goto out;
- }
- ret = dict_set_dynstr (aggr, "default-soft-limit",
- default_sl_dup);
- if (ret) {
- gf_log (frame->this->name, GF_LOG_TRACE,
- "failed to set default soft limit");
- GF_FREE (default_sl_dup);
- }
+ if ((type == GF_QUOTA_OPTION_TYPE_LIST) ||
+ (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)) {
+ gf_cli_quota_list(local, volname, dict, default_sl, entry_count,
+ rsp.op_ret, rsp.op_errno, rsp.op_errstr);
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_quota_limit_list_end(local);
+ if (ret < 0) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ }
+ goto out;
}
+ }
- ret = dict_get_int32 (dict, "type", &type);
- if (ret)
- gf_log (frame->this->name, GF_LOG_TRACE,
- "failed to get type");
+xml_output:
- ret = dict_get_int32 (dict, "count", &entry_count);
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_str("volQuota", NULL, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
if (ret)
- gf_log (frame->this->name, GF_LOG_TRACE, "failed to get count");
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- if ((type == GF_QUOTA_OPTION_TYPE_LIST)
- || (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)) {
- gf_cli_quota_list (local, volname, dict, default_sl,
- entry_count, rsp.op_ret,
- rsp.op_errno, rsp.op_errstr);
+ if (!rsp.op_ret && type != GF_QUOTA_OPTION_TYPE_LIST &&
+ type != GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)
+ cli_out("volume quota : success");
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_quota_limit_list_end (local);
- if (ret < 0) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Error in printing"
- " xml output");
- }
- goto out;
- }
- }
-
-xml_output:
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_str ("volQuota", NULL, rsp.op_ret,
- rsp.op_errno, rsp.op_errstr);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
+ ret = rsp.op_ret;
+out:
- if (!rsp.op_ret && type != GF_QUOTA_OPTION_TYPE_LIST
- && type != GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)
- cli_out ("volume quota : success");
+ if ((type == GF_QUOTA_OPTION_TYPE_LIST) ||
+ (type == GF_QUOTA_OPTION_TYPE_LIST_OBJECTS)) {
+ gluster_remove_auxiliary_mount(volname);
+ }
- ret = rsp.op_ret;
-out:
- cli_cmd_broadcast_response (ret);
- if (dict)
- dict_unref (dict);
+ cli_cmd_broadcast_response(ret);
+ if (dict)
+ dict_unref(dict);
- free (rsp.dict.dict_val);
+ gf_free_xdr_cli_rsp(rsp);
- return ret;
+ return ret;
}
-int
-gf_cli_getspec_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+gf_cli_getspec_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- gf_getspec_rsp rsp = {0,};
- int ret = -1;
- char *spec = NULL;
- call_frame_t *frame = NULL;
+ gf_getspec_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ char *spec = NULL;
- if (-1 == req->rpc_status) {
- goto out;
- }
+ GF_ASSERT(myframe);
- frame = myframe;
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
- if (rsp.op_ret == -1) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "getspec failed");
- goto out;
- }
+ if (rsp.op_ret == -1) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ "getspec failed");
+ ret = -1;
+ goto out;
+ }
- gf_log ("cli", GF_LOG_INFO, "Received resp to getspec");
+ gf_log("cli", GF_LOG_INFO, "Received resp to getspec");
- spec = GF_MALLOC (rsp.op_ret + 1, cli_mt_char);
- if (!spec) {
- gf_log("", GF_LOG_ERROR, "out of memory");
- goto out;
- }
- memcpy (spec, rsp.spec, rsp.op_ret);
- spec[rsp.op_ret] = '\0';
- cli_out ("%s", spec);
- GF_FREE (spec);
+ spec = GF_MALLOC(rsp.op_ret + 1, cli_mt_char);
+ if (!spec) {
+ gf_log("", GF_LOG_ERROR, "out of memory");
+ ret = -1;
+ goto out;
+ }
+ memcpy(spec, rsp.spec, rsp.op_ret);
+ spec[rsp.op_ret] = '\0';
+ cli_out("%s", spec);
+ GF_FREE(spec);
- ret = 0;
+ ret = 0;
out:
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_getspec_rsp(rsp);
+ return ret;
}
-int
-gf_cli_pmap_b2p_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+gf_cli_pmap_b2p_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- pmap_port_by_brick_rsp rsp = {0,};
- int ret = -1;
- char *spec = NULL;
- call_frame_t *frame = NULL;
+ pmap_port_by_brick_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ char *spec = NULL;
- if (-1 == req->rpc_status) {
- goto out;
- }
+ GF_ASSERT(myframe);
- frame = myframe;
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
- if (rsp.op_ret == -1) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "pump_b2p failed");
- goto out;
- }
+ if (rsp.op_ret == -1) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ "pump_b2p failed");
+ ret = -1;
+ goto out;
+ }
- gf_log ("cli", GF_LOG_INFO, "Received resp to pmap b2p");
+ gf_log("cli", GF_LOG_INFO, "Received resp to pmap b2p");
- cli_out ("%d", rsp.port);
- GF_FREE (spec);
+ cli_out("%d", rsp.port);
+ GF_FREE(spec);
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ return ret;
}
-
-int32_t
-gf_cli_probe (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_probe(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,},};
- int ret = 0;
- dict_t *dict = NULL;
- int port = 0;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
-
- ret = dict_get_int32 (dict, "port", &port);
- if (ret) {
- ret = dict_set_int32 (dict, "port", CLI_GLUSTERD_PORT);
- if (ret)
- goto out;
- }
+ gf_cli_req req = {
+ {
+ 0,
+ },
+ };
+ int ret = 0;
+ dict_t *dict = NULL;
+ int port = 0;
+
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
+
+ dict = data;
+
+ ret = dict_get_int32_sizen(dict, "port", &port);
+ if (ret) {
+ ret = dict_set_int32_sizen(dict, "port", CLI_GLUSTERD_PORT);
+ if (ret)
+ goto out;
+ }
- ret = cli_to_glusterd (&req, frame, gf_cli_probe_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_PROBE, this, cli_rpc_prog, NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_probe_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_PROBE,
+ this, cli_rpc_prog, NULL);
out:
- GF_FREE (req.dict.dict_val);
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ GF_FREE(req.dict.dict_val);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_deprobe (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_deprobe(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,},};
- int ret = 0;
- dict_t *dict = NULL;
- int port = 0;
- int flags = 0;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
- ret = dict_get_int32 (dict, "port", &port);
- if (ret) {
- ret = dict_set_int32 (dict, "port", CLI_GLUSTERD_PORT);
- if (ret)
- goto out;
- }
+ gf_cli_req req = {
+ {
+ 0,
+ },
+ };
+ int ret = 0;
+ dict_t *dict = NULL;
+ int port = 0;
+ int flags = 0;
+
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
+
+ dict = data;
+ ret = dict_get_int32_sizen(dict, "port", &port);
+ if (ret) {
+ ret = dict_set_int32_sizen(dict, "port", CLI_GLUSTERD_PORT);
+ if (ret)
+ goto out;
+ }
- ret = dict_get_int32 (dict, "flags", &flags);
- if (ret) {
- ret = dict_set_int32 (dict, "flags", 0);
- if (ret)
- goto out;
- }
+ ret = dict_get_int32_sizen(dict, "flags", &flags);
+ if (ret) {
+ ret = dict_set_int32_sizen(dict, "flags", 0);
+ if (ret)
+ goto out;
+ }
- ret = cli_to_glusterd (&req, frame, gf_cli_deprobe_cbk,
- (xdrproc_t)xdr_gf_cli_req, dict,
- GLUSTER_CLI_DEPROBE, this, cli_rpc_prog, NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_deprobe_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_DEPROBE,
+ this, cli_rpc_prog, NULL);
out:
- GF_FREE (req.dict.dict_val);
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ GF_FREE(req.dict.dict_val);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_list_friends (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_list_friends(call_frame_t *frame, xlator_t *this, void *data)
{
- gf1_cli_peer_list_req req = {0,};
- int ret = 0;
- unsigned long flags = 0;
+ gf1_cli_peer_list_req req = {
+ 0,
+ };
+ int ret = 0;
+ unsigned long flags = 0;
- if (!frame || !this) {
- ret = -1;
- goto out;
- }
+ if (!frame || !this) {
+ ret = -1;
+ goto out;
+ }
- GF_ASSERT (frame->local == NULL);
+ GF_ASSERT(frame->local == NULL);
- flags = (long)data;
- req.flags = flags;
- frame->local = (void*)flags;
- ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog,
- GLUSTER_CLI_LIST_FRIENDS, NULL,
- this, gf_cli_list_friends_cbk,
- (xdrproc_t) xdr_gf1_cli_peer_list_req);
+ flags = (long)data;
+ req.flags = flags;
+ frame->local = (void *)flags;
+ ret = cli_cmd_submit(
+ NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_LIST_FRIENDS, NULL, this,
+ gf_cli_list_friends_cbk, (xdrproc_t)xdr_gf1_cli_peer_list_req);
out:
- if (ret) {
- /*
- * If everything goes fine, gf_cli_list_friends_cbk()
- * [invoked through cli_cmd_submit()]resets the
- * frame->local to NULL. In case cli_cmd_submit()
- * fails in between, RESET frame->local here.
- */
- frame->local = NULL;
- }
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ if (ret && frame) {
+ /*
+ * If everything goes fine, gf_cli_list_friends_cbk()
+ * [invoked through cli_cmd_submit()]resets the
+ * frame->local to NULL. In case cli_cmd_submit()
+ * fails in between, RESET frame->local here.
+ */
+ frame->local = NULL;
+ }
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-int32_t
-gf_cli_get_next_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_get_state(call_frame_t *frame, xlator_t *this, void *data)
{
+ gf_cli_req req = {
+ {
+ 0,
+ },
+ };
+ int ret = 0;
+ dict_t *dict = NULL;
- int ret = 0;
- cli_cmd_volume_get_ctx_t *ctx = NULL;
- cli_local_t *local = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ dict = data;
- ctx = data;
- local = frame->local;
+ ret = cli_to_glusterd(&req, frame, gf_cli_get_state_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_GET_STATE, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
- 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;
- }
- }
+ return ret;
+}
- ret = gf_cli_get_volume (frame, this, data);
+static int32_t
+gf_cli_get_next_volume(call_frame_t *frame, xlator_t *this, void *data)
+{
+ int ret = 0;
+ cli_cmd_volume_get_ctx_t *ctx = NULL;
+ cli_local_t *local = NULL;
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
- if (!local || !local->get_vol.volname) {
- if ((global_state->mode & GLUSTER_MODE_XML))
- goto end_xml;
+ ctx = data;
+ local = frame->local;
- cli_err ("No volumes present");
- goto out;
+ 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, XML_ERROR);
+ goto out;
}
+ }
+ ret = gf_cli_get_volume(frame, this, data);
- ctx->volname = local->get_vol.volname;
+ if (!local || !local->get_vol.volname) {
+ if ((global_state->mode & GLUSTER_MODE_XML))
+ goto end_xml;
- while (ctx->volname) {
- ret = gf_cli_get_volume (frame, this, ctx);
- if (ret)
- goto out;
- ctx->volname = local->get_vol.volname;
- }
+ cli_err("No volumes present");
+ goto out;
+ }
+
+ ctx->volname = local->get_vol.volname;
+
+ while (ctx->volname) {
+ ret = gf_cli_get_volume(frame, this, ctx);
+ if (ret)
+ goto out;
+ ctx->volname = local->get_vol.volname;
+ }
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");
- }
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_info_end(local);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ }
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-int32_t
-gf_cli_get_volume (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- 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;
- goto out;
- }
-
- ctx = data;
-
- dict = dict_new ();
- if (!dict)
- goto out;
+static int32_t
+gf_cli_get_volume(call_frame_t *frame, xlator_t *this, void *data)
+{
+ 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 (!this || !data) {
+ ret = -1;
+ goto out;
+ }
+
+ ctx = data;
+
+ dict = dict_new();
+ if (!dict) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Failed to create the dict");
+ ret = -1;
+ goto out;
+ }
+
+ if (ctx->volname) {
+ ret = dict_set_str_sizen(dict, "volname", ctx->volname);
+ if (ret)
+ goto out;
+ }
- if (ctx->volname) {
- ret = dict_set_str (dict, "volname", ctx->volname);
- if (ret)
- goto out;
- }
+ flags = ctx->flags;
+ ret = dict_set_int32_sizen(dict, "flags", flags);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR, "failed to set flags");
+ goto out;
+ }
- flags = ctx->flags;
- ret = dict_set_int32 (dict, "flags", flags);
- if (ret) {
- gf_log (frame->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 = dict_allocate_and_serialize(dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR, DICT_SERIALIZE_FAIL);
+ goto out;
+ }
- ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog,
- GLUSTER_CLI_GET_VOLUME, NULL,
- this, gf_cli_get_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req);
+ ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog,
+ GLUSTER_CLI_GET_VOLUME, NULL, this,
+ gf_cli_get_volume_cbk, (xdrproc_t)xdr_gf_cli_req);
out:
- if (dict)
- dict_unref (dict);
+ if (dict)
+ dict_unref(dict);
- GF_FREE (req.dict.dict_val);
+ GF_FREE(req.dict.dict_val);
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-int32_t
-gf_cli3_1_uuid_get (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli3_1_uuid_get(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli3_1_uuid_get_cbk,
- (xdrproc_t)xdr_gf_cli_req, dict,
- GLUSTER_CLI_UUID_GET, this, cli_rpc_prog,
- NULL);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ dict = data;
+ ret = cli_to_glusterd(&req, frame, gf_cli3_1_uuid_get_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_UUID_GET,
+ this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-gf_cli3_1_uuid_reset (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli3_1_uuid_reset(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli3_1_uuid_reset_cbk,
- (xdrproc_t)xdr_gf_cli_req, dict,
- GLUSTER_CLI_UUID_RESET, this, cli_rpc_prog,
- NULL);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ dict = data;
+ ret = cli_to_glusterd(&req, frame, gf_cli3_1_uuid_reset_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_UUID_RESET, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-gf_cli_create_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_create_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ dict = data;
- dict = data;
+ ret = cli_to_glusterd(&req, frame, gf_cli_create_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_CREATE_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- ret = cli_to_glusterd (&req, frame, gf_cli_create_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_CREATE_VOLUME, this, cli_rpc_prog,
- NULL);
+ GF_FREE(req.dict.dict_val);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- GF_FREE (req.dict.dict_val);
-
- return ret;
+ return ret;
}
-int32_t
-gf_cli_delete_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_delete_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_delete_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_DELETE_VOLUME, this, cli_rpc_prog,
- NULL);
-
-out:
- GF_FREE (req.dict.dict_val);
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ ret = cli_to_glusterd(&req, frame, gf_cli_delete_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_DELETE_VOLUME, this, cli_rpc_prog, NULL);
+ GF_FREE(req.dict.dict_val);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_start_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_start_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_start_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_START_VOLUME, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_start_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_START_VOLUME, this, cli_rpc_prog, NULL);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_stop_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_stop_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = data;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = data;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_stop_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_STOP_VOLUME, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_stop_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_STOP_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
+ return ret;
}
-int32_t
-gf_cli_defrag_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_defrag_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_defrag_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_DEFRAG_VOLUME, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_defrag_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_DEFRAG_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
+ return ret;
}
-int32_t
-gf_cli_rename_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_rename_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- dict = data;
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
- 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");
+ dict = data;
- goto out;
- }
+ ret = dict_allocate_and_serialize(dict, &req.dict.dict_val,
+ &req.dict.dict_len);
+ if (ret < 0) {
+ gf_log(this->name, GF_LOG_ERROR, DICT_SERIALIZE_FAIL);
+ goto out;
+ }
- ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog,
- GLUSTER_CLI_RENAME_VOLUME, NULL,
- this, gf_cli_rename_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req);
+ ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog,
+ GLUSTER_CLI_RENAME_VOLUME, NULL, this,
+ gf_cli_rename_volume_cbk, (xdrproc_t)xdr_gf_cli_req);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ GF_FREE(req.dict.dict_val);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_reset_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_reset_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,} };
- int ret = 0;
- dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_reset_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_RESET_VOLUME, this, cli_rpc_prog,
- NULL);
-
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ ret = cli_to_glusterd(&req, frame, gf_cli_reset_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_RESET_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-gf_cli_ganesha (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_ganesha(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = { {0,} } ;
- int ret = 0;
- dict_t *dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_ganesha_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_GANESHA, this, cli_rpc_prog,
- NULL);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ ret = cli_to_glusterd(&req, frame, gf_cli_ganesha_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_GANESHA,
+ this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_set_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_set_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,} };
- int ret = 0;
- dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_set_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_SET_VOLUME, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_set_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_SET_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
+ return ret;
}
int32_t
-gf_cli_add_brick (call_frame_t *frame, xlator_t *this,
- void *data)
+gf_cli_add_brick(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,} };
- int ret = 0;
- dict_t *dict = NULL;
- char *volname = NULL;
- int32_t count = 0;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ dict = data;
- dict = data;
+ ret = cli_to_glusterd(&req, frame, gf_cli_add_brick_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_ADD_BRICK, this, cli_rpc_prog, NULL);
- ret = dict_get_str (dict, "volname", &volname);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- if (ret)
- goto out;
+ GF_FREE(req.dict.dict_val);
- ret = dict_get_int32 (dict, "count", &count);
- if (ret)
- goto out;
-
- ret = cli_to_glusterd (&req, frame, gf_cli_add_brick_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_ADD_BRICK, this, cli_rpc_prog, NULL);
-
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- GF_FREE (req.dict.dict_val);
-
- return ret;
+ return ret;
}
-int32_t
-gf_cli_attach_tier (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gf_cli_req req = {{0,} };
- int ret = 0;
- dict_t *dict = NULL;
- dict_t *newdict = NULL;
- char *tierwords[] = {"volume", "rebalance", "",
- "tier", "start", NULL};
- const char **words = (const char **)tierwords;
- int wordcount = 5;
- char *volname = NULL;
- cli_local_t *local = NULL;
- cli_local_t *oldlocal = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
-
- if (ret)
- goto out;
-
- ret = cli_to_glusterd (&req, frame, gf_cli_attach_tier_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_ATTACH_TIER, this,
- cli_rpc_prog, NULL);
- if (ret)
- goto out;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get volume name");
- goto notify_cli;
- }
-
- words[2] = volname;
- ret = cli_cmd_volume_defrag_parse ((const char **)words,
- wordcount, &newdict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to parse tier start "
- "command");
- goto notify_cli;
- }
-
- gf_log ("cli", GF_LOG_DEBUG, "Sending tier start");
-
- oldlocal = frame->local;
- CLI_LOCAL_INIT (local, words, frame, newdict);
- ret = gf_cli_defrag_volume (frame, this, newdict);
- frame->local = oldlocal;
- cli_local_wipe (local);
+static int32_t
+gf_cli_remove_brick(call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf_cli_req req = {{
+ 0,
+ }};
+ ;
+ gf_cli_req status_req = {{
+ 0,
+ }};
+ ;
+ int ret = 0;
+ dict_t *dict = NULL;
+ int32_t command = 0;
+ int32_t cmd = 0;
+
+ if (!frame || !this) {
+ ret = -1;
+ goto out;
+ }
+
+ dict = data;
+
+ ret = dict_get_int32_sizen(dict, "command", &command);
+ if (ret)
+ goto out;
+
+ if ((command != GF_OP_CMD_STATUS) && (command != GF_OP_CMD_STOP)) {
+ ret = cli_to_glusterd(
+ &req, frame, gf_cli_remove_brick_cbk, (xdrproc_t)xdr_gf_cli_req,
+ dict, GLUSTER_CLI_REMOVE_BRICK, this, cli_rpc_prog, NULL);
+ } else {
+ /* Need rebalance status to be sent :-) */
+ if (command == GF_OP_CMD_STATUS)
+ cmd |= GF_DEFRAG_CMD_STATUS;
+ else
+ cmd |= GF_DEFRAG_CMD_STOP;
-notify_cli:
+ ret = dict_set_int32_sizen(dict, "rebalance-command", (int32_t)cmd);
if (ret) {
- cli_out ("Failed to run tier start. Please execute tier start "
- "command explictly");
- cli_out ("Usage : gluster volume rebalance <volname> tier "
- "start");
+ gf_log(this->name, GF_LOG_ERROR, "Failed to set dict");
+ goto out;
}
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- GF_FREE (req.dict.dict_val);
- return ret;
-}
-
-int32_t
-gf_cli_tier (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- int ret = 0;
- int32_t command = 0;
- int32_t cmd = 0;
- gf_cli_req req = { {0,} };
- gf_cli_req status_req = { {0,} };
- dict_t *dict = NULL;
- char *volname = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
- dict = data;
-
- ret = cli_to_glusterd (&req, frame, gf_cli_defrag_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_DEFRAG_VOLUME, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(
+ &status_req, frame, gf_cli3_remove_brick_status_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_DEFRAG_VOLUME, this,
+ cli_rpc_prog, NULL);
+ }
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- GF_FREE (req.dict.dict_val);
+ GF_FREE(req.dict.dict_val);
- GF_FREE (status_req.dict.dict_val);
+ GF_FREE(status_req.dict.dict_val);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_detach_tier (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gf_cli_req req = { {0,} };
- gf_cli_req status_req = { {0,} };
- int ret = 0;
- dict_t *dict = NULL;
- int32_t command = 0;
- char *volname = NULL;
- int32_t cmd = 0;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
-
- ret = dict_get_int32 (dict, "command", &command);
- if (ret)
- goto out;
-
- if ((command != GF_OP_CMD_STATUS) &&
- (command != GF_OP_CMD_STOP_DETACH_TIER)) {
-
-
- ret = cli_to_glusterd (&req, frame, gf_cli_detach_tier_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_REMOVE_BRICK, this,
- cli_rpc_prog, NULL);
- } else {
- /* Need rebalance status to be sent :-) */
- if (command == GF_OP_CMD_STATUS)
- cmd |= GF_DEFRAG_CMD_STATUS;
- else
- cmd |= GF_DEFRAG_CMD_STOP_DETACH_TIER;
-
- ret = dict_set_int32 (dict, "rebalance-command", (int32_t) cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set dict");
- goto out;
- }
-
- ret = cli_to_glusterd (&status_req, frame,
- gf_cli_detach_tier_status_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_DEFRAG_VOLUME, this,
- cli_rpc_prog, NULL);
-
- }
-
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- GF_FREE (req.dict.dict_val);
-
- GF_FREE (status_req.dict.dict_val);
-
- return ret;
-}
-
-
-
-int32_t
-gf_cli_remove_brick (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gf_cli_req req = {{0,}};;
- gf_cli_req status_req = {{0,}};;
- int ret = 0;
- dict_t *dict = NULL;
- int32_t command = 0;
- char *volname = NULL;
- int32_t cmd = 0;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
+static int32_t
+gf_cli_reset_brick(call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
+ char *dst_brick = NULL;
+ char *op = NULL;
+
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
+
+ dict = data;
+
+ ret = dict_get_str_sizen(dict, "operation", &op);
+ if (ret) {
+ gf_log(this->name, GF_LOG_DEBUG, "dict_get on operation failed");
+ goto out;
+ }
+
+ if (!strcmp(op, "GF_RESET_OP_COMMIT") ||
+ !strcmp(op, "GF_RESET_OP_COMMIT_FORCE")) {
+ ret = dict_get_str_sizen(dict, "dst-brick", &dst_brick);
+ if (ret) {
+ gf_log(this->name, GF_LOG_DEBUG, "dict_get on dst-brick failed");
+ goto out;
}
+ }
- dict = data;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
-
- ret = dict_get_int32 (dict, "command", &command);
- if (ret)
- goto out;
-
- if ((command != GF_OP_CMD_STATUS) &&
- (command != GF_OP_CMD_STOP)) {
-
-
- ret = cli_to_glusterd (&req, frame, gf_cli_remove_brick_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_REMOVE_BRICK, this,
- cli_rpc_prog, NULL);
- } else {
- /* Need rebalance status to be sent :-) */
- if (command == GF_OP_CMD_STATUS)
- cmd |= GF_DEFRAG_CMD_STATUS;
- else
- cmd |= GF_DEFRAG_CMD_STOP;
-
- ret = dict_set_int32 (dict, "rebalance-command", (int32_t) cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set dict");
- goto out;
- }
-
- ret = cli_to_glusterd (&status_req, frame,
- gf_cli3_remove_brick_status_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_DEFRAG_VOLUME, this,
- cli_rpc_prog, NULL);
-
- }
+ ret = cli_to_glusterd(&req, frame, gf_cli_reset_brick_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_RESET_BRICK, this, cli_rpc_prog, NULL);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- GF_FREE (req.dict.dict_val);
+ GF_FREE(req.dict.dict_val);
- GF_FREE (status_req.dict.dict_val);
-
- return ret;
+ return ret;
}
-int32_t
-gf_cli_replace_brick (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gf_cli_req req = {{0,}};
- int ret = 0;
- 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;
-
- 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", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "dict_get on volname failed");
- goto out;
- }
+static int32_t
+gf_cli_replace_brick(call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
+ int32_t op = 0;
- ret = dict_get_str (dict, "src-brick", &src_brick);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "dict_get on src-brick failed");
- goto out;
- }
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_get_str (dict, "dst-brick", &dst_brick);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "dict_get on dst-brick failed");
- goto out;
- }
+ dict = data;
- gf_log (this->name, GF_LOG_DEBUG,
- "Received command replace-brick %s with "
- "%s with operation=%d", src_brick,
- dst_brick, op);
+ ret = dict_get_int32_sizen(dict, "operation", &op);
+ if (ret) {
+ gf_log(this->name, GF_LOG_DEBUG, "dict_get on operation failed");
+ goto out;
+ }
- ret = cli_to_glusterd (&req, frame, gf_cli_replace_brick_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_REPLACE_BRICK, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_replace_brick_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_REPLACE_BRICK, this, cli_rpc_prog, NULL);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- GF_FREE (req.dict.dict_val);
+ GF_FREE(req.dict.dict_val);
- return ret;
+ return ret;
}
-
-int32_t
-gf_cli_log_rotate (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_log_rotate(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
-
- ret = cli_to_glusterd (&req, frame, gf_cli_log_rotate_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_LOG_ROTATE, this, cli_rpc_prog,
- NULL);
+ dict = data;
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ ret = cli_to_glusterd(&req, frame, gf_cli_log_rotate_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_LOG_ROTATE, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- GF_FREE (req.dict.dict_val);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-gf_cli_sync_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_sync_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- int ret = 0;
- gf_cli_req req = {{0,}};
- dict_t *dict = NULL;
+ int ret = 0;
+ gf_cli_req req = {{
+ 0,
+ }};
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_sync_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_SYNC_VOLUME, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_sync_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_SYNC_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- GF_FREE (req.dict.dict_val);
-
- return ret;
+ return ret;
}
-int32_t
-gf_cli_getspec (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gf_getspec_req req = {0,};
- int ret = 0;
- dict_t *dict = NULL;
- dict_t *op_dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
-
- ret = dict_get_str (dict, "volid", &req.key);
- if (ret)
- goto out;
-
- op_dict = dict_new ();
- if (!op_dict) {
- ret = -1;
- goto out;
- }
-
- // Set the supported min and max op-versions, so glusterd can make a
- // decision
- ret = dict_set_int32 (op_dict, "min-op-version", GD_OP_VERSION_MIN);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to set min-op-version"
- " in request dict");
- goto out;
- }
-
- ret = dict_set_int32 (op_dict, "max-op-version", GD_OP_VERSION_MAX);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to set max-op-version"
- " in request dict");
- goto out;
- }
-
- ret = dict_allocate_and_serialize (op_dict, &req.xdata.xdata_val,
- &req.xdata.xdata_len);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to serialize dictionary");
- goto out;
- }
-
- ret = cli_cmd_submit (NULL, &req, frame, &cli_handshake_prog,
- GF_HNDSK_GETSPEC, NULL,
- this, gf_cli_getspec_cbk,
- (xdrproc_t) xdr_gf_getspec_req);
-
-out:
- if (op_dict) {
- dict_unref(op_dict);
- }
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
+static int32_t
+gf_cli_getspec(call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf_getspec_req req = {
+ 0,
+ };
+ int ret = 0;
+ dict_t *dict = NULL;
+ dict_t *op_dict = NULL;
+
+ if (!frame || !this) {
+ ret = -1;
+ goto out;
+ }
+
+ dict = data;
+
+ ret = dict_get_str_sizen(dict, "volid", &req.key);
+ if (ret)
+ goto out;
+
+ op_dict = dict_new();
+ if (!op_dict) {
+ ret = -1;
+ goto out;
+ }
+
+ // Set the supported min and max op-versions, so glusterd can make a
+ // decision
+ ret = dict_set_int32_sizen(op_dict, "min-op-version", GD_OP_VERSION_MIN);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "Failed to set min-op-version in request dict");
+ goto out;
+ }
+
+ ret = dict_set_int32_sizen(op_dict, "max-op-version", GD_OP_VERSION_MAX);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "Failed to set max-op-version in request dict");
+ goto out;
+ }
+
+ ret = dict_allocate_and_serialize(op_dict, &req.xdata.xdata_val,
+ &req.xdata.xdata_len);
+ if (ret < 0) {
+ gf_log(THIS->name, GF_LOG_ERROR, DICT_SERIALIZE_FAIL);
+ goto out;
+ }
+
+ ret = cli_cmd_submit(NULL, &req, frame, &cli_handshake_prog,
+ GF_HNDSK_GETSPEC, NULL, this, gf_cli_getspec_cbk,
+ (xdrproc_t)xdr_gf_getspec_req);
+
+out:
+ if (op_dict) {
+ dict_unref(op_dict);
+ }
+ GF_FREE(req.xdata.xdata_val);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+
+ return ret;
}
-int32_t
-gf_cli_quota (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_quota(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
-
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_quota_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_QUOTA, this, cli_rpc_prog, NULL);
-
-out:
- GF_FREE (req.dict.dict_val);
-
- return ret;
+ ret = cli_to_glusterd(&req, frame, gf_cli_quota_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_QUOTA,
+ this, cli_rpc_prog, NULL);
+ GF_FREE(req.dict.dict_val);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-int32_t
-gf_cli_pmap_b2p (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_pmap_b2p(call_frame_t *frame, xlator_t *this, void *data)
{
- pmap_port_by_brick_req req = {0,};
- int ret = 0;
- dict_t *dict = NULL;
+ pmap_port_by_brick_req req = {
+ 0,
+ };
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
+ if (!frame || !this) {
+ ret = -1;
+ goto out;
+ }
- dict = data;
+ dict = data;
- ret = dict_get_str (dict, "brick", &req.brick);
- if (ret)
- goto out;
+ ret = dict_get_str_sizen(dict, "brick", &req.brick);
+ if (ret)
+ goto out;
- ret = cli_cmd_submit (NULL, &req, frame, &cli_pmap_prog,
- GF_PMAP_PORTBYBRICK, NULL,
- this, gf_cli_pmap_b2p_cbk,
- (xdrproc_t) xdr_pmap_port_by_brick_req);
+ ret = cli_cmd_submit(NULL, &req, frame, &cli_pmap_prog, GF_PMAP_PORTBYBRICK,
+ NULL, this, gf_cli_pmap_b2p_cbk,
+ (xdrproc_t)xdr_pmap_port_by_brick_req);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- return ret;
+ return ret;
}
static int
-gf_cli_fsm_log_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf1_cli_fsm_log_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- int tr_count = 0;
- char key[256] = {0};
- int i = 0;
- char *old_state = NULL;
- char *new_state = NULL;
- char *event = NULL;
- char *time = NULL;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_fsm_log_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- if (rsp.op_ret) {
- if (strcmp (rsp.op_errstr, ""))
- cli_err ("%s", rsp.op_errstr);
- cli_err ("fsm log unsuccessful");
- ret = rsp.op_ret;
- goto out;
- }
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (rsp.fsm_log.fsm_log_val,
- rsp.fsm_log.fsm_log_len,
- &dict);
-
- if (ret) {
- cli_err ("bad response");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &tr_count);
- if (tr_count)
- cli_out("number of transitions: %d", tr_count);
- else
- cli_err("No transitions");
- for (i = 0; i < tr_count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "log%d-old-state", i);
- ret = dict_get_str (dict, key, &old_state);
- if (ret)
- goto out;
+gf_cli_fsm_log_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf1_cli_fsm_log_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ int tr_count = 0;
+ char key[64] = {0};
+ int keylen;
+ int i = 0;
+ char *old_state = NULL;
+ char *new_state = NULL;
+ char *event = NULL;
+ char *time = NULL;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf1_cli_fsm_log_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ if (rsp.op_ret) {
+ if (strcmp(rsp.op_errstr, ""))
+ cli_err("%s", rsp.op_errstr);
+ cli_err("fsm log unsuccessful");
+ ret = rsp.op_ret;
+ goto out;
+ }
+
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize(rsp.fsm_log.fsm_log_val, rsp.fsm_log.fsm_log_len,
+ &dict);
+
+ if (ret) {
+ cli_err(DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
+
+ ret = dict_get_int32_sizen(dict, "count", &tr_count);
+ if (!ret && tr_count)
+ cli_out("number of transitions: %d", tr_count);
+ else
+ cli_err("No transitions");
+ for (i = 0; i < tr_count; i++) {
+ keylen = snprintf(key, sizeof(key), "log%d-old-state", i);
+ ret = dict_get_strn(dict, key, keylen, &old_state);
+ if (ret)
+ goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "log%d-event", i);
- ret = dict_get_str (dict, key, &event);
- if (ret)
- goto out;
+ keylen = snprintf(key, sizeof(key), "log%d-event", i);
+ ret = dict_get_strn(dict, key, keylen, &event);
+ if (ret)
+ goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "log%d-new-state", i);
- ret = dict_get_str (dict, key, &new_state);
- if (ret)
- goto out;
+ keylen = snprintf(key, sizeof(key), "log%d-new-state", i);
+ ret = dict_get_strn(dict, key, keylen, &new_state);
+ if (ret)
+ goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "log%d-time", i);
- ret = dict_get_str (dict, key, &time);
- if (ret)
- goto out;
- cli_out ("Old State: [%s]\n"
- "New State: [%s]\n"
- "Event : [%s]\n"
- "timestamp: [%s]\n", old_state, new_state, event, time);
- }
+ keylen = snprintf(key, sizeof(key), "log%d-time", i);
+ ret = dict_get_strn(dict, key, keylen, &time);
+ if (ret)
+ goto out;
+ cli_out(
+ "Old State: [%s]\n"
+ "New State: [%s]\n"
+ "Event : [%s]\n"
+ "timestamp: [%s]\n",
+ old_state, new_state, event, time);
+ }
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ if (dict) {
+ dict_unref(dict);
+ }
+ gf_free_xdr_fsm_log_rsp(rsp);
+
+ return ret;
}
-int32_t
-gf_cli_fsm_log (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_fsm_log(call_frame_t *frame, xlator_t *this, void *data)
{
- int ret = -1;
- gf1_cli_fsm_log_req req = {0,};
+ int ret = -1;
+ gf1_cli_fsm_log_req req = {
+ 0,
+ };
- GF_ASSERT (frame);
- GF_ASSERT (this);
- GF_ASSERT (data);
+ GF_ASSERT(frame);
+ GF_ASSERT(this);
+ GF_ASSERT(data);
- if (!frame || !this || !data)
- goto out;
- req.name = data;
- ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog,
- GLUSTER_CLI_FSM_LOG, NULL,
- this, gf_cli_fsm_log_cbk,
- (xdrproc_t) xdr_gf1_cli_fsm_log_req);
+ if (!frame || !this || !data)
+ goto out;
+ req.name = data;
+ ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_FSM_LOG,
+ NULL, this, gf_cli_fsm_log_cbk,
+ (xdrproc_t)xdr_gf1_cli_fsm_log_req);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- return ret;
+ return ret;
}
-int
-gf_cli_gsync_config_command (dict_t *dict)
-{
- runner_t runner = {0,};
- char *subop = NULL;
- char *gwd = NULL;
- char *slave = NULL;
- char *confpath = NULL;
- char *master = NULL;
- char *op_name = NULL;
- int ret = -1;
- char conf_path[PATH_MAX] = "";
-
- if (dict_get_str (dict, "subop", &subop) != 0)
- return -1;
-
- if (strcmp (subop, "get") != 0 && strcmp (subop, "get-all") != 0) {
- cli_out (GEOREP" config updated successfully");
- return 0;
- }
-
- if (dict_get_str (dict, "glusterd_workdir", &gwd) != 0 ||
- dict_get_str (dict, "slave", &slave) != 0)
- return -1;
-
- if (dict_get_str (dict, "master", &master) != 0)
- master = NULL;
- if (dict_get_str (dict, "op_name", &op_name) != 0)
- op_name = NULL;
-
- ret = dict_get_str (dict, "conf_path", &confpath);
- if (!confpath) {
- ret = snprintf (conf_path, sizeof(conf_path) - 1,
- "%s/"GEOREP"/gsyncd_template.conf", gwd);
- conf_path[ret] = '\0';
- confpath = conf_path;
- }
-
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s", confpath);
- runner_argprintf (&runner, "--iprefix=%s", DATADIR);
- 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);
-}
-
-char*
-get_struct_variable (int mem_num, gf_gsync_status_t *sts_val)
-{
- switch (mem_num) {
- case 0: return (sts_val->node);
- case 1: return (sts_val->master);
- case 2: return (sts_val->brick);
- case 3: return (sts_val->slave_user);
- case 4: return (sts_val->slave);
- case 5: return (sts_val->slave_node);
- case 6: return (sts_val->worker_status);
- case 7: return (sts_val->crawl_status);
- case 8: return (sts_val->last_synced);
- case 9: return (sts_val->entry);
- case 10: return (sts_val->data);
- case 11: return (sts_val->meta);
- case 12: return (sts_val->failures);
- case 13: return (sts_val->checkpoint_time);
- case 14: return (sts_val->checkpoint_completed);
- case 15: return (sts_val->checkpoint_completion_time);
- case 16: return (sts_val->brick_host_uuid);
- case 17: return (sts_val->last_synced_utc);
- case 18: return (sts_val->checkpoint_time_utc);
- case 19: return (sts_val->checkpoint_completion_time_utc);
- case 20: return (sts_val->slavekey);
- case 21: return (sts_val->session_slave);
- default:
- goto out;
- }
-
-out:
- return NULL;
+static int
+gf_cli_gsync_config_command(dict_t *dict)
+{
+ runner_t runner = {
+ 0,
+ };
+ char *subop = NULL;
+ char *gwd = NULL;
+ char *slave = NULL;
+ char *confpath = NULL;
+ char *master = NULL;
+ char *op_name = NULL;
+ int ret = -1;
+ char conf_path[PATH_MAX] = "";
+
+ if (dict_get_str_sizen(dict, "subop", &subop) != 0)
+ return -1;
+
+ if (strcmp(subop, "get") != 0 && strcmp(subop, "get-all") != 0) {
+ cli_out(GEOREP " config updated successfully");
+ return 0;
+ }
+
+ if (dict_get_str_sizen(dict, "glusterd_workdir", &gwd) != 0 ||
+ dict_get_str_sizen(dict, "slave", &slave) != 0)
+ return -1;
+
+ if (dict_get_str_sizen(dict, "master", &master) != 0)
+ master = NULL;
+ if (dict_get_str_sizen(dict, "op_name", &op_name) != 0)
+ op_name = NULL;
+
+ ret = dict_get_str_sizen(dict, "conf_path", &confpath);
+ if (ret || !confpath) {
+ ret = snprintf(conf_path, sizeof(conf_path) - 1,
+ "%s/" GEOREP "/gsyncd_template.conf", gwd);
+ conf_path[ret] = '\0';
+ confpath = conf_path;
+ }
+
+ runinit(&runner);
+ runner_add_args(&runner, GSYNCD_PREFIX "/gsyncd", "-c", NULL);
+ runner_argprintf(&runner, "%s", confpath);
+ runner_argprintf(&runner, "--iprefix=%s", DATADIR);
+ 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
-gf_cli_print_status (char **title_values,
- gf_gsync_status_t **sts_vals,
- int *spacing, int gsync_count,
- int number_of_fields, int is_detail)
-{
- int i = 0;
- int j = 0;
- int ret = 0;
- int status_fields = 8; /* Indexed at 0 */
- int total_spacing = 0;
- char **output_values = NULL;
- char *tmp = NULL;
- char *hyphens = NULL;
-
- /* calculating spacing for hyphens */
- for (i = 0; i < number_of_fields; i++) {
- /* Suppressing detail output for status */
- if ((!is_detail) && (i > status_fields)) {
- /* Suppressing detailed output for
- * status */
- continue;
- }
- spacing[i] += 3; /* Adding extra space to
- distinguish between fields */
- total_spacing += spacing[i];
- }
- total_spacing += 4; /* For the spacing between the fields */
-
- /* char pointers for each field */
- output_values = GF_CALLOC (number_of_fields, sizeof (char *),
- gf_common_mt_char);
- if (!output_values) {
- ret = -1;
- goto out;
- }
- for (i = 0; i < number_of_fields; i++) {
- output_values[i] = GF_CALLOC (spacing[i] + 1, sizeof (char),
- gf_common_mt_char);
- if (!output_values[i]) {
- ret = -1;
- goto out;
- }
- }
-
- hyphens = GF_CALLOC (total_spacing + 1, sizeof (char),
- gf_common_mt_char);
- if (!hyphens) {
+static int
+gf_cli_print_status(char **title_values, gf_gsync_status_t **sts_vals,
+ int *spacing, int gsync_count, int number_of_fields,
+ int is_detail)
+{
+ int i = 0;
+ int j = 0;
+ int ret = 0;
+ int status_fields = 8; /* Indexed at 0 */
+ int total_spacing = 0;
+ char **output_values = NULL;
+ char *tmp = NULL;
+ char *hyphens = NULL;
+
+ /* calculating spacing for hyphens */
+ for (i = 0; i < number_of_fields; i++) {
+ /* Suppressing detail output for status */
+ if ((!is_detail) && (i > status_fields)) {
+ /* Suppressing detailed output for
+ * status */
+ continue;
+ }
+ spacing[i] += 3; /* Adding extra space to
+ distinguish between fields */
+ total_spacing += spacing[i];
+ }
+ total_spacing += 4; /* For the spacing between the fields */
+
+ /* char pointers for each field */
+ output_values = GF_MALLOC(number_of_fields * sizeof(char *),
+ gf_common_mt_char);
+ if (!output_values) {
+ ret = -1;
+ goto out;
+ }
+ for (i = 0; i < number_of_fields; i++) {
+ output_values[i] = GF_CALLOC(spacing[i] + 1, sizeof(char),
+ gf_common_mt_char);
+ if (!output_values[i]) {
+ ret = -1;
+ goto out;
+ }
+ }
+
+ cli_out(" ");
+
+ /* setting the title "NODE", "MASTER", etc. from title_values[]
+ and printing the same */
+ for (j = 0; j < number_of_fields; j++) {
+ if ((!is_detail) && (j > status_fields)) {
+ /* Suppressing detailed output for
+ * status */
+ output_values[j][0] = '\0';
+ continue;
+ }
+ memset(output_values[j], ' ', spacing[j]);
+ memcpy(output_values[j], title_values[j], strlen(title_values[j]));
+ output_values[j][spacing[j]] = '\0';
+ }
+ cli_out("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", output_values[0],
+ output_values[1], output_values[2], output_values[3],
+ output_values[4], output_values[5], output_values[6],
+ output_values[7], output_values[8], output_values[9],
+ output_values[10], output_values[11], output_values[12],
+ output_values[13], output_values[14], output_values[15]);
+
+ hyphens = GF_MALLOC((total_spacing + 1) * sizeof(char), gf_common_mt_char);
+ if (!hyphens) {
+ ret = -1;
+ goto out;
+ }
+
+ /* setting and printing the hyphens */
+ memset(hyphens, '-', total_spacing);
+ hyphens[total_spacing] = '\0';
+ cli_out("%s", hyphens);
+
+ for (i = 0; i < gsync_count; i++) {
+ for (j = 0; j < number_of_fields; j++) {
+ if ((!is_detail) && (j > status_fields)) {
+ /* Suppressing detailed output for
+ * status */
+ output_values[j][0] = '\0';
+ continue;
+ }
+ tmp = get_struct_variable(j, sts_vals[i]);
+ if (!tmp) {
+ gf_log("", GF_LOG_ERROR, "struct member empty.");
ret = -1;
goto out;
+ }
+ memset(output_values[j], ' ', spacing[j]);
+ memcpy(output_values[j], tmp, strlen(tmp));
+ output_values[j][spacing[j]] = '\0';
}
- cli_out (" ");
-
- /* setting the title "NODE", "MASTER", etc. from title_values[]
- and printing the same */
- for (j = 0; j < number_of_fields; j++) {
- if ((!is_detail) && (j > status_fields)) {
- /* Suppressing detailed output for
- * status */
- output_values[j][0] = '\0';
- continue;
- }
- memset (output_values[j], ' ', spacing[j]);
- memcpy (output_values[j], title_values[j],
- strlen(title_values[j]));
- output_values[j][spacing[j]] = '\0';
- }
- cli_out ("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
- output_values[0], output_values[1],
- output_values[2], output_values[3],
- output_values[4], output_values[5],
- output_values[6], output_values[7],
- output_values[8], output_values[9],
- output_values[10], output_values[11],
- output_values[12], output_values[13],
- output_values[14], output_values[15]);
-
- /* setting and printing the hyphens */
- memset (hyphens, '-', total_spacing);
- hyphens[total_spacing] = '\0';
- cli_out ("%s", hyphens);
-
- for (i = 0; i < gsync_count; i++) {
- for (j = 0; j < number_of_fields; j++) {
- if ((!is_detail) && (j > status_fields)) {
- /* Suppressing detailed output for
- * status */
- output_values[j][0] = '\0';
- continue;
- }
- tmp = get_struct_variable(j, sts_vals[i]);
- if (!tmp) {
- gf_log ("", GF_LOG_ERROR,
- "struct member empty.");
- ret = -1;
- goto out;
- }
- memset (output_values[j], ' ', spacing[j]);
- memcpy (output_values[j], tmp, strlen (tmp));
- output_values[j][spacing[j]] = '\0';
- }
-
- cli_out ("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
- output_values[0], output_values[1],
- output_values[2], output_values[3],
- output_values[4], output_values[5],
- output_values[6], output_values[7],
- output_values[8], output_values[9],
- output_values[10], output_values[11],
- output_values[12], output_values[13],
- output_values[14], output_values[15]);
- }
+ cli_out("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
+ output_values[0], output_values[1], output_values[2],
+ output_values[3], output_values[4], output_values[5],
+ output_values[6], output_values[7], output_values[8],
+ output_values[9], output_values[10], output_values[11],
+ output_values[12], output_values[13], output_values[14],
+ output_values[15]);
+ }
out:
- if (output_values) {
- for (i = 0; i < number_of_fields; i++) {
- if (output_values[i])
- GF_FREE (output_values[i]);
- }
- GF_FREE (output_values);
+ if (output_values) {
+ for (i = 0; i < number_of_fields; i++) {
+ if (output_values[i])
+ GF_FREE(output_values[i]);
}
+ GF_FREE(output_values);
+ }
- if (hyphens)
- GF_FREE (hyphens);
+ if (hyphens)
+ GF_FREE(hyphens);
- return ret;
+ return ret;
}
int
-gf_gsync_status_t_comparator (const void *p, const void *q)
+gf_gsync_status_t_comparator(const void *p, const void *q)
{
- char *slavekey1 = NULL;
- char *slavekey2 = NULL;
+ char *slavekey1 = NULL;
+ char *slavekey2 = NULL;
- slavekey1 = get_struct_variable (20, (*(gf_gsync_status_t **)p));
- slavekey2 = get_struct_variable (20, (*(gf_gsync_status_t **)q));
- if (!slavekey1 || !slavekey2) {
- gf_log ("cli", GF_LOG_ERROR,
- "struct member empty.");
- return 0;
- }
+ slavekey1 = get_struct_variable(20, (*(gf_gsync_status_t **)p));
+ slavekey2 = get_struct_variable(20, (*(gf_gsync_status_t **)q));
+ if (!slavekey1 || !slavekey2) {
+ gf_log("cli", GF_LOG_ERROR, "struct member empty.");
+ return 0;
+ }
- return strcmp (slavekey1, slavekey2);
+ return strcmp(slavekey1, slavekey2);
}
-int
-gf_cli_read_status_data (dict_t *dict,
- gf_gsync_status_t **sts_vals,
- int *spacing, int gsync_count,
- int number_of_fields)
-{
- char *tmp = NULL;
- char sts_val_name[PATH_MAX] = "";
- int ret = 0;
- int i = 0;
- int j = 0;
-
- /* Storing per node status info in each object */
- for (i = 0; i < gsync_count; i++) {
- snprintf (sts_val_name, sizeof(sts_val_name), "status_value%d", i);
-
- /* Fetching the values from dict, and calculating
- the max length for each field */
- ret = dict_get_bin (dict, sts_val_name, (void **)&(sts_vals[i]));
- if (ret)
- goto out;
-
- for (j = 0; j < number_of_fields; j++) {
- tmp = get_struct_variable(j, sts_vals[i]);
- if (!tmp) {
- gf_log ("", GF_LOG_ERROR,
- "struct member empty.");
- ret = -1;
- goto out;
- }
- if (strlen (tmp) > spacing[j])
- spacing[j] = strlen (tmp);
- }
+static int
+gf_cli_read_status_data(dict_t *dict, gf_gsync_status_t **sts_vals,
+ int *spacing, int gsync_count, int number_of_fields)
+{
+ char *tmp = NULL;
+ char sts_val_name[PATH_MAX] = "";
+ int ret = 0;
+ int i = 0;
+ int j = 0;
+
+ /* Storing per node status info in each object */
+ for (i = 0; i < gsync_count; i++) {
+ snprintf(sts_val_name, sizeof(sts_val_name), "status_value%d", i);
+
+ /* Fetching the values from dict, and calculating
+ the max length for each field */
+ ret = dict_get_bin(dict, sts_val_name, (void **)&(sts_vals[i]));
+ if (ret)
+ goto out;
+
+ for (j = 0; j < number_of_fields; j++) {
+ tmp = get_struct_variable(j, sts_vals[i]);
+ if (!tmp) {
+ gf_log("", GF_LOG_ERROR, "struct member empty.");
+ ret = -1;
+ goto out;
+ }
+ if (strlen(tmp) > spacing[j])
+ spacing[j] = strlen(tmp);
}
+ }
- /* Sort based on Session Slave */
- qsort(sts_vals, gsync_count,
- sizeof(gf_gsync_status_t *),
- gf_gsync_status_t_comparator);
+ /* Sort based on Session Slave */
+ qsort(sts_vals, gsync_count, sizeof(gf_gsync_status_t *),
+ gf_gsync_status_t_comparator);
out:
- return ret;
+ return ret;
}
-int
-gf_cli_gsync_status_output (dict_t *dict, gf_boolean_t is_detail)
-{
- int gsync_count = 0;
- int i = 0;
- int ret = 0;
- int spacing[16] = {0};
- int num_of_fields = 16;
- char errmsg[1024] = "";
- char *master = NULL;
- char *slave = NULL;
- char *title_values[] = {"MASTER NODE", "MASTER VOL",
- "MASTER BRICK", "SLAVE USER",
- "SLAVE", "SLAVE NODE",
- "STATUS", "CRAWL STATUS",
- "LAST_SYNCED", "ENTRY",
- "DATA", "META", "FAILURES",
- "CHECKPOINT TIME",
- "CHECKPOINT COMPLETED",
- "CHECKPOINT COMPLETION TIME"};
- gf_gsync_status_t **sts_vals = NULL;
-
- /* Checks if any session is active or not */
- ret = dict_get_int32 (dict, "gsync-count", &gsync_count);
- if (ret) {
- ret = dict_get_str (dict, "master", &master);
-
- ret = dict_get_str (dict, "slave", &slave);
-
- if (master) {
- if (slave)
- snprintf (errmsg, sizeof(errmsg), "No active "
- "geo-replication sessions between %s"
- " and %s", master, slave);
- else
- snprintf (errmsg, sizeof(errmsg), "No active "
- "geo-replication sessions for %s",
- master);
- } else
- snprintf (errmsg, sizeof(errmsg), "No active "
- "geo-replication sessions");
-
- gf_log ("cli", GF_LOG_INFO, "%s", errmsg);
- cli_out ("%s", errmsg);
- ret = 0;
- goto out;
- }
+static int
+gf_cli_gsync_status_output(dict_t *dict, gf_boolean_t is_detail)
+{
+ int gsync_count = 0;
+ int i = 0;
+ int ret = 0;
+ int spacing[16] = {0};
+ int num_of_fields = 16;
+ char errmsg[1024] = "";
+ char *master = NULL;
+ char *slave = NULL;
+ static char *title_values[] = {"MASTER NODE",
+ "MASTER VOL",
+ "MASTER BRICK",
+ "SLAVE USER",
+ "SLAVE",
+ "SLAVE NODE",
+ "STATUS",
+ "CRAWL STATUS",
+ "LAST_SYNCED",
+ "ENTRY",
+ "DATA",
+ "META",
+ "FAILURES",
+ "CHECKPOINT TIME",
+ "CHECKPOINT COMPLETED",
+ "CHECKPOINT COMPLETION TIME"};
+ gf_gsync_status_t **sts_vals = NULL;
+
+ /* Checks if any session is active or not */
+ ret = dict_get_int32_sizen(dict, "gsync-count", &gsync_count);
+ if (ret) {
+ ret = dict_get_str_sizen(dict, "master", &master);
+
+ ret = dict_get_str_sizen(dict, "slave", &slave);
+
+ if (master) {
+ if (slave)
+ snprintf(errmsg, sizeof(errmsg),
+ "No active geo-replication sessions between %s"
+ " and %s",
+ master, slave);
+ else
+ snprintf(errmsg, sizeof(errmsg),
+ "No active geo-replication sessions for %s", master);
+ } else
+ snprintf(errmsg, sizeof(errmsg),
+ "No active geo-replication sessions");
- for (i = 0; i < num_of_fields; i++)
- spacing[i] = strlen(title_values[i]);
+ gf_log("cli", GF_LOG_INFO, "%s", errmsg);
+ cli_out("%s", errmsg);
+ ret = -1;
+ goto out;
+ }
- /* gsync_count = number of nodes reporting output.
- each sts_val object will store output of each
- node */
- sts_vals = GF_CALLOC (gsync_count, sizeof (gf_gsync_status_t *),
- gf_common_mt_char);
- if (!sts_vals) {
- ret = -1;
- goto out;
- }
- for (i = 0; i < gsync_count; i++) {
- sts_vals[i] = GF_CALLOC (1, sizeof (gf_gsync_status_t),
- gf_common_mt_char);
- if (!sts_vals[i]) {
- ret = -1;
- goto out;
- }
- }
+ for (i = 0; i < num_of_fields; i++)
+ spacing[i] = strlen(title_values[i]);
- ret = gf_cli_read_status_data (dict, sts_vals, spacing,
- gsync_count, num_of_fields);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to read status data");
- goto out;
- }
+ /* gsync_count = number of nodes reporting output.
+ each sts_val object will store output of each
+ node */
+ sts_vals = GF_MALLOC(gsync_count * sizeof(gf_gsync_status_t *),
+ gf_common_mt_char);
+ if (!sts_vals) {
+ ret = -1;
+ goto out;
+ }
- ret = gf_cli_print_status (title_values, sts_vals, spacing, gsync_count,
- num_of_fields, is_detail);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to print status output");
- goto out;
- }
+ ret = gf_cli_read_status_data(dict, sts_vals, spacing, gsync_count,
+ num_of_fields);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "Unable to read status data");
+ goto out;
+ }
+
+ ret = gf_cli_print_status(title_values, sts_vals, spacing, gsync_count,
+ num_of_fields, is_detail);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "Unable to print status output");
+ goto out;
+ }
out:
- if (sts_vals)
- GF_FREE (sts_vals);
+ if (sts_vals)
+ GF_FREE(sts_vals);
- return ret;
+ return ret;
}
static int32_t
-write_contents_to_common_pem_file (dict_t *dict, int output_count)
-{
- char *workdir = NULL;
- char common_pem_file[PATH_MAX] = "";
- char *output = NULL;
- char output_name[PATH_MAX] = "";
- int bytes_written = 0;
- int fd = -1;
- int ret = -1;
- int i = -1;
-
- ret = dict_get_str (dict, "glusterd_workdir", &workdir);
- if (ret || !workdir) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch workdir");
+write_contents_to_common_pem_file(dict_t *dict, int output_count)
+{
+ char *workdir = NULL;
+ char common_pem_file[PATH_MAX] = "";
+ char *output = NULL;
+ char output_name[32] = "";
+ int bytes_written = 0;
+ int fd = -1;
+ int ret = -1;
+ int i = -1;
+
+ ret = dict_get_str_sizen(dict, "glusterd_workdir", &workdir);
+ if (ret || !workdir) {
+ gf_log("", GF_LOG_ERROR, "Unable to fetch workdir");
+ ret = -1;
+ goto out;
+ }
+
+ snprintf(common_pem_file, sizeof(common_pem_file),
+ "%s/geo-replication/common_secret.pem.pub", workdir);
+
+ sys_unlink(common_pem_file);
+
+ fd = open(common_pem_file, O_WRONLY | O_CREAT, 0600);
+ if (fd == -1) {
+ gf_log("", GF_LOG_ERROR, "Failed to open %s Error : %s",
+ common_pem_file, strerror(errno));
+ ret = -1;
+ goto out;
+ }
+
+ for (i = 1; i <= output_count; i++) {
+ ret = snprintf(output_name, sizeof(output_name), "output_%d", i);
+ ret = dict_get_strn(dict, output_name, ret, &output);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "Failed to get %s.", output_name);
+ cli_out("Unable to fetch output.");
+ }
+ if (output) {
+ bytes_written = sys_write(fd, output, strlen(output));
+ if (bytes_written != strlen(output)) {
+ gf_log("", GF_LOG_ERROR, "Failed to write to %s",
+ common_pem_file);
ret = -1;
goto out;
- }
-
- snprintf (common_pem_file, sizeof(common_pem_file),
- "%s/geo-replication/common_secret.pem.pub",
- workdir);
-
- unlink (common_pem_file);
-
- fd = open (common_pem_file, O_WRONLY | O_CREAT, 0600);
- if (fd == -1) {
- gf_log ("", GF_LOG_ERROR, "Failed to open %s"
- " Error : %s", common_pem_file,
- strerror (errno));
+ }
+ /* Adding the new line character */
+ bytes_written = sys_write(fd, "\n", 1);
+ if (bytes_written != 1) {
+ gf_log("", GF_LOG_ERROR, "Failed to add new line char");
ret = -1;
goto out;
+ }
+ output = NULL;
}
+ }
- for (i = 1; i <= output_count; i++) {
- memset (output_name, '\0', sizeof (output_name));
- snprintf (output_name, sizeof (output_name),
- "output_%d", i);
- ret = dict_get_str (dict, output_name, &output);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Failed to get %s.",
- output_name);
- cli_out ("Unable to fetch output.");
- }
- if (output) {
- bytes_written = write (fd, output, strlen(output));
- if (bytes_written != strlen(output)) {
- gf_log ("", GF_LOG_ERROR, "Failed to write "
- "to %s", common_pem_file);
- ret = -1;
- goto out;
- }
- /* Adding the new line character */
- bytes_written = write (fd, "\n", strlen("\n"));
- if (bytes_written != strlen("\n")) {
- gf_log ("", GF_LOG_ERROR,
- "Failed to add new line char");
- ret = -1;
- goto out;
- }
- output = NULL;
- }
- }
-
- cli_out ("Common secret pub file present at %s", common_pem_file);
- ret = 0;
+ cli_out("Common secret pub file present at %s", common_pem_file);
+ ret = 0;
out:
- if (fd >= 0)
- close (fd);
+ if (fd >= 0)
+ sys_close(fd);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-int
-gf_cli_sys_exec_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- int output_count = -1;
- int i = -1;
- char *output = NULL;
- char *command = NULL;
- char output_name[PATH_MAX] = "";
- gf_cli_rsp rsp = {0, };
- dict_t *dict = NULL;
- call_frame_t *frame = NULL;
-
- if (req->rpc_status == -1) {
- ret = -1;
- goto out;
- }
-
- frame = myframe;
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- dict = dict_new ();
-
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+static int
+gf_cli_sys_exec_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ int ret = -1;
+ int output_count = -1;
+ int i = -1;
+ char *output = NULL;
+ char *command = NULL;
+ char output_name[32] = "";
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ dict_t *dict = NULL;
+
+ GF_ASSERT(myframe);
+
+ if (req->rpc_status == -1) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ 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)
+ goto out;
+
+ if (rsp.op_ret) {
+ cli_err("%s", rsp.op_errstr ? rsp.op_errstr : "Command failed.");
+ ret = rsp.op_ret;
+ goto out;
+ }
- if (ret)
- goto out;
+ ret = dict_get_int32_sizen(dict, "output_count", &output_count);
+ if (ret) {
+ cli_out("Command executed successfully.");
+ ret = 0;
+ goto out;
+ }
- if (rsp.op_ret) {
- cli_err ("%s", rsp.op_errstr ? rsp.op_errstr :
- "Command failed.");
- ret = rsp.op_ret;
- goto out;
- }
+ ret = dict_get_str_sizen(dict, "command", &command);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "Unable to get command from dict");
+ goto out;
+ }
- ret = dict_get_int32 (dict, "output_count", &output_count);
- if (ret) {
- cli_out ("Command executed successfully.");
- ret = 0;
- goto out;
- }
+ if (!strcmp(command, "gsec_create")) {
+ ret = write_contents_to_common_pem_file(dict, output_count);
+ if (!ret)
+ goto out;
+ }
- ret = dict_get_str (dict, "command", &command);
+ for (i = 1; i <= output_count; i++) {
+ ret = snprintf(output_name, sizeof(output_name), "output_%d", i);
+ ret = dict_get_strn(dict, output_name, ret, &output);
if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to get command from dict");
- goto out;
+ gf_log("", GF_LOG_ERROR, "Failed to get %s.", output_name);
+ cli_out("Unable to fetch output.");
}
-
- if (!strcmp (command, "gsec_create")) {
- ret = write_contents_to_common_pem_file (dict, output_count);
- if (!ret)
- goto out;
+ if (output) {
+ cli_out("%s", output);
+ output = NULL;
}
+ }
- for (i = 1; i <= output_count; i++) {
- memset (output_name, '\0', sizeof (output_name));
- snprintf (output_name, sizeof (output_name),
- "output_%d", i);
- ret = dict_get_str (dict, output_name, &output);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Failed to get %s.",
- output_name);
- cli_out ("Unable to fetch output.");
- }
- if (output) {
- cli_out ("%s", output);
- output = NULL;
- }
- }
-
- ret = 0;
+ ret = 0;
out:
- if (dict)
- dict_unref (dict);
- cli_cmd_broadcast_response (ret);
-
- free (rsp.dict.dict_val);
-
- return ret;
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int
-gf_cli_copy_file_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+gf_cli_copy_file_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- int ret = -1;
- gf_cli_rsp rsp = {0, };
- dict_t *dict = NULL;
- call_frame_t *frame = NULL;
+ int ret = -1;
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ dict_t *dict = NULL;
- if (req->rpc_status == -1) {
- ret = -1;
- goto out;
- }
+ GF_ASSERT(myframe);
- frame = myframe;
+ if (req->rpc_status == -1) {
+ goto out;
+ }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
- dict = dict_new ();
+ dict = dict_new();
- if (!dict) {
- ret = -1;
- goto out;
- }
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
- ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
- if (ret)
- goto out;
+ if (ret)
+ goto out;
- if (rsp.op_ret) {
- cli_err ("%s", rsp.op_errstr ? rsp.op_errstr :
- "Copy unsuccessful");
- ret = rsp.op_ret;
- goto out;
- }
+ if (rsp.op_ret) {
+ cli_err("%s", rsp.op_errstr ? rsp.op_errstr : "Copy unsuccessful");
+ ret = rsp.op_ret;
+ goto out;
+ }
- cli_out ("Successfully copied file.");
+ cli_out("Successfully copied file.");
out:
- if (dict)
- dict_unref (dict);
- cli_cmd_broadcast_response (ret);
-
- free (rsp.dict.dict_val);
-
- return ret;
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int
-gf_cli_gsync_set_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- 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;
- call_frame_t *frame = NULL;
- gf_boolean_t status_detail = _gf_false;
-
-
- if (req->rpc_status == -1) {
- ret = -1;
- goto out;
- }
-
- frame = myframe;
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- dict = dict_new ();
-
- if (!dict) {
- ret = -1;
- goto out;
- }
-
- ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
-
+static int
+gf_cli_gsync_set_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ 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;
+ gf_boolean_t status_detail = _gf_false;
+
+ GF_ASSERT(myframe);
+
+ if (req->rpc_status == -1) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ 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)
+ goto out;
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_gsync(dict, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
if (ret)
- goto out;
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_gsync (dict, rsp.op_ret, rsp.op_errno,
- rsp.op_errstr);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
-
- if (rsp.op_ret) {
- cli_err ("%s", rsp.op_errstr ? rsp.op_errstr :
- GEOREP" command unsuccessful");
- ret = rsp.op_ret;
- goto out;
- }
-
- 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 (frame->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:
- 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_PAUSE:
- case GF_GSYNC_OPTION_TYPE_RESUME:
- 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_PAUSE ?
- "Pausing" : "Resuming",
- master, slave);
- break;
-
- case GF_GSYNC_OPTION_TYPE_CONFIG:
- ret = gf_cli_gsync_config_command (dict);
- break;
-
- case GF_GSYNC_OPTION_TYPE_STATUS:
- status_detail = dict_get_str_boolean (dict,
- "status-detail",
- _gf_false);
- if (status_detail)
- ret = gf_cli_gsync_status_output (dict, status_detail);
- else
- ret = gf_cli_gsync_status_output (dict, status_detail);
- break;
-
- case GF_GSYNC_OPTION_TYPE_DELETE:
- if (dict_get_str (dict, "master", &master) != 0)
- master = "???";
- if (dict_get_str (dict, "slave", &slave) != 0)
- slave = "???";
- cli_out ("Deleting " GEOREP " session between %s & %s"
- " has been successful", master, slave);
- break;
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
- case GF_GSYNC_OPTION_TYPE_CREATE:
- if (dict_get_str (dict, "master", &master) != 0)
- master = "???";
- if (dict_get_str (dict, "slave", &slave) != 0)
- slave = "???";
- cli_out ("Creating " GEOREP " session between %s & %s"
- " has been successful", master, slave);
- break;
+ if (rsp.op_ret) {
+ cli_err("%s",
+ rsp.op_errstr ? rsp.op_errstr : GEOREP " command unsuccessful");
+ ret = rsp.op_ret;
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(dict, "gsync-status", &gsync_status);
+ if (!ret)
+ cli_out("%s", gsync_status);
+
+ ret = dict_get_int32_sizen(dict, "type", &type);
+ if (ret) {
+ gf_log(((call_frame_t *)myframe)->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:
+ if (dict_get_str_sizen(dict, "master", &master) != 0)
+ master = "???";
+ if (dict_get_str_sizen(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_PAUSE:
+ case GF_GSYNC_OPTION_TYPE_RESUME:
+ if (dict_get_str_sizen(dict, "master", &master) != 0)
+ master = "???";
+ if (dict_get_str_sizen(dict, "slave", &slave) != 0)
+ slave = "???";
+
+ cli_out("%s " GEOREP " session between %s & %s has been successful",
+ type == GF_GSYNC_OPTION_TYPE_PAUSE ? "Pausing" : "Resuming",
+ master, slave);
+ break;
+
+ case GF_GSYNC_OPTION_TYPE_CONFIG:
+ ret = gf_cli_gsync_config_command(dict);
+ break;
+
+ case GF_GSYNC_OPTION_TYPE_STATUS:
+ status_detail = dict_get_str_boolean(dict, "status-detail",
+ _gf_false);
+ ret = gf_cli_gsync_status_output(dict, status_detail);
+ break;
+
+ case GF_GSYNC_OPTION_TYPE_DELETE:
+ if (dict_get_str_sizen(dict, "master", &master) != 0)
+ master = "???";
+ if (dict_get_str_sizen(dict, "slave", &slave) != 0)
+ slave = "???";
+ cli_out("Deleting " GEOREP
+ " session between %s & %s has been successful",
+ master, slave);
+ break;
+
+ case GF_GSYNC_OPTION_TYPE_CREATE:
+ if (dict_get_str_sizen(dict, "master", &master) != 0)
+ master = "???";
+ if (dict_get_str_sizen(dict, "slave", &slave) != 0)
+ slave = "???";
+ cli_out("Creating " GEOREP
+ " session between %s & %s has been successful",
+ master, slave);
+ break;
- default:
- cli_out (GEOREP" command executed successfully");
- }
+ default:
+ cli_out(GEOREP " command executed successfully");
+ }
out:
- if (dict)
- dict_unref (dict);
- cli_cmd_broadcast_response (ret);
-
- free (rsp.dict.dict_val);
-
- return ret;
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int32_t
-gf_cli_sys_exec (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_sys_exec(call_frame_t *frame, xlator_t *this, void *data)
{
- int ret = 0;
- dict_t *dict = NULL;
- gf_cli_req req = {{0,}};
+ int ret = 0;
+ dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+
+ dict = data;
+ ret = cli_to_glusterd(&req, frame, gf_cli_sys_exec_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict, GLUSTER_CLI_SYS_EXEC,
+ this, cli_rpc_prog, NULL);
+ if (ret)
if (!frame || !this || !data) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid data");
- goto out;
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid data");
}
- dict = data;
-
- ret = cli_to_glusterd (&req, frame, gf_cli_sys_exec_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_SYS_EXEC, this, cli_rpc_prog,
- NULL);
-out:
- GF_FREE (req.dict.dict_val);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-gf_cli_copy_file (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_copy_file(call_frame_t *frame, xlator_t *this, void *data)
{
- int ret = 0;
- dict_t *dict = NULL;
- gf_cli_req req = {{0,}};
+ int ret = 0;
+ dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+
+ dict = data;
+ ret = cli_to_glusterd(&req, frame, gf_cli_copy_file_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_COPY_FILE, this, cli_rpc_prog, NULL);
+ if (ret)
if (!frame || !this || !data) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Invalid data");
- goto out;
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Invalid data");
}
- dict = data;
-
- ret = cli_to_glusterd (&req, frame, gf_cli_copy_file_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_COPY_FILE, this, cli_rpc_prog,
- NULL);
-out:
- GF_FREE (req.dict.dict_val);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-gf_cli_gsync_set (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_gsync_set(call_frame_t *frame, xlator_t *this, void *data)
{
- int ret = 0;
- dict_t *dict = NULL;
- gf_cli_req req = {{0,}};
+ int ret = 0;
+ dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
-
- ret = cli_to_glusterd (&req, frame, gf_cli_gsync_set_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_GSYNC_SET, this, cli_rpc_prog,
- NULL);
+ dict = data;
-out:
- GF_FREE (req.dict.dict_val);
+ ret = cli_to_glusterd(&req, frame, gf_cli_gsync_set_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_GSYNC_SET, this, cli_rpc_prog, NULL);
+ GF_FREE(req.dict.dict_val);
- return ret;
+ return ret;
}
-
int
-cli_profile_info_percentage_cmp (void *a, void *b)
+cli_profile_info_percentage_cmp(void *a, void *b)
{
- cli_profile_info_t *ia = NULL;
- cli_profile_info_t *ib = NULL;
- int ret = 0;
-
- ia = a;
- ib = b;
- if (ia->percentage_avg_latency < ib->percentage_avg_latency)
- ret = -1;
- else if (ia->percentage_avg_latency > ib->percentage_avg_latency)
- ret = 1;
- else
- ret = 0;
- return ret;
-}
-
-
-void
-cmd_profile_volume_brick_out (dict_t *dict, int count, int interval)
-{
- char key[256] = {0};
- int i = 0;
- uint64_t sec = 0;
- uint64_t r_count = 0;
- uint64_t w_count = 0;
- uint64_t rb_counts[32] = {0};
- uint64_t wb_counts[32] = {0};
- cli_profile_info_t profile_info[GF_FOP_MAXVALUE] = {{0}};
- char output[128] = {0};
- int per_line = 0;
- char read_blocks[128] = {0};
- char write_blocks[128] = {0};
- int index = 0;
- int is_header_printed = 0;
- int ret = 0;
- double total_percentage_latency = 0;
-
- for (i = 0; i < 32; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-%d-read-%d", count,
- interval, (1 << i));
- ret = dict_get_uint64 (dict, key, &rb_counts[i]);
- }
-
- for (i = 0; i < 32; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-%d-write-%d", count, interval,
- (1<<i));
- ret = dict_get_uint64 (dict, key, &wb_counts[i]);
- }
+ cli_profile_info_t *ia = NULL;
+ cli_profile_info_t *ib = NULL;
- for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-%d-%d-hits", count,
- interval, i);
- ret = dict_get_uint64 (dict, key, &profile_info[i].fop_hits);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-%d-%d-avglatency", count,
- interval, i);
- ret = dict_get_double (dict, key, &profile_info[i].avg_latency);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-%d-%d-minlatency", count,
- interval, i);
- ret = dict_get_double (dict, key, &profile_info[i].min_latency);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-%d-%d-maxlatency", count,
- interval, i);
- ret = dict_get_double (dict, key, &profile_info[i].max_latency);
- profile_info[i].fop_name = (char *)gf_fop_list[i];
-
- total_percentage_latency +=
- (profile_info[i].fop_hits * profile_info[i].avg_latency);
- }
- if (total_percentage_latency) {
- for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- profile_info[i].percentage_avg_latency = 100 * (
- (profile_info[i].avg_latency* profile_info[i].fop_hits) /
- total_percentage_latency);
- }
- gf_array_insertionsort (profile_info, 1, GF_FOP_MAXVALUE - 1,
- sizeof (cli_profile_info_t),
- cli_profile_info_percentage_cmp);
- }
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-%d-duration", count, interval);
- ret = dict_get_uint64 (dict, key, &sec);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-%d-total-read", count, interval);
- ret = dict_get_uint64 (dict, key, &r_count);
+ ia = a;
+ ib = b;
+ if (ia->percentage_avg_latency < ib->percentage_avg_latency)
+ return -1;
+ else if (ia->percentage_avg_latency > ib->percentage_avg_latency)
+ return 1;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-%d-total-write", count, interval);
- ret = dict_get_uint64 (dict, key, &w_count);
+ return 0;
+}
- if (ret == 0) {
+static void
+cmd_profile_volume_brick_out(dict_t *dict, int count, int interval)
+{
+ char key[256] = {0};
+ int i = 0;
+ uint64_t sec = 0;
+ uint64_t r_count = 0;
+ uint64_t w_count = 0;
+ uint64_t rb_counts[32] = {0};
+ uint64_t wb_counts[32] = {0};
+ cli_profile_info_t profile_info[GF_FOP_MAXVALUE] = {{0}};
+ cli_profile_info_t upcall_info[GF_UPCALL_FLAGS_MAXVALUE] = {
+ {0},
+ };
+ char output[128] = {0};
+ int per_line = 0;
+ char read_blocks[128] = {0};
+ char write_blocks[128] = {0};
+ int index = 0;
+ int is_header_printed = 0;
+ int ret = 0;
+ double total_percentage_latency = 0;
+
+ for (i = 0; i < 32; i++) {
+ snprintf(key, sizeof(key), "%d-%d-read-%" PRIu32, count, interval,
+ (1U << i));
+ ret = dict_get_uint64(dict, key, &rb_counts[i]);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
}
+ }
- if (interval == -1)
- cli_out ("Cumulative Stats:");
- else
- cli_out ("Interval %d Stats:", interval);
- 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;
- per_line++;
- snprintf (output+index, sizeof (output)-index, "%19db+ ", (1<<i));
- if (rb_counts[i]) {
- snprintf (read_blocks+index, sizeof (read_blocks)-index,
- "%21"PRId64" ", rb_counts[i]);
- } else {
- snprintf (read_blocks+index, sizeof (read_blocks)-index,
- "%21s ", "0");
- }
- if (wb_counts[i]) {
- snprintf (write_blocks+index, sizeof (write_blocks)-index,
- "%21"PRId64" ", wb_counts[i]);
- } else {
- snprintf (write_blocks+index, sizeof (write_blocks)-index,
- "%21s ", "0");
- }
- index += 22;
- if (per_line == 3) {
- 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), "%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++) {
+ snprintf(key, sizeof(key), "%d-%d-write-%" PRIu32, count, interval,
+ (1U << i));
+ ret = dict_get_uint64(dict, key, &wb_counts[i]);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
}
+ }
- if (per_line != 0) {
- 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 ("%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 ("%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,
- profile_info[i].max_latency,
- profile_info[i].fop_hits,
- profile_info[i].fop_name);
- }
+ for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++) {
+ snprintf(key, sizeof(key), "%d-%d-%d-upcall-hits", count, interval, i);
+ ret = dict_get_uint64(dict, key, &upcall_info[i].fop_hits);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
}
- 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 (" ");
-}
+ upcall_info[i].fop_name = (char *)gf_upcall_list[i];
+ }
-int32_t
-gf_cli_profile_volume_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- 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,};
- int stats_cleared = 0;
- gf1_cli_info_op info_op = GF_CLI_INFO_NONE;
-
- if (-1 == req->rpc_status) {
- goto out;
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ snprintf(key, sizeof(key), "%d-%d-%d-hits", count, interval, i);
+ ret = dict_get_uint64(dict, key, &profile_info[i].fop_hits);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
}
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to profile");
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
+ snprintf(key, sizeof(key), "%d-%d-%d-avglatency", count, interval, i);
+ ret = dict_get_double(dict, key, &profile_info[i].avg_latency);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
}
- dict = dict_new ();
-
- if (!dict) {
- ret = -1;
- goto out;
+ snprintf(key, sizeof(key), "%d-%d-%d-minlatency", count, interval, i);
+ ret = dict_get_double(dict, key, &profile_info[i].min_latency);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
}
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &dict);
-
+ snprintf(key, sizeof(key), "%d-%d-%d-maxlatency", count, interval, i);
+ ret = dict_get_double(dict, key, &profile_info[i].max_latency);
if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to allocate memory");
- goto out;
- } else {
- dict->extra_stdfree = rsp.dict.dict_val;
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
}
+ profile_info[i].fop_name = (char *)gf_fop_list[i];
- 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;
+ total_percentage_latency += (profile_info[i].fop_hits *
+ profile_info[i].avg_latency);
+ }
+ if (total_percentage_latency) {
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ profile_info[i]
+ .percentage_avg_latency = 100 * ((profile_info[i].avg_latency *
+ profile_info[i].fop_hits) /
+ total_percentage_latency);
+ }
+ gf_array_insertionsort(profile_info, 1, GF_FOP_MAXVALUE - 1,
+ sizeof(cli_profile_info_t),
+ cli_profile_info_percentage_cmp);
+ }
+ snprintf(key, sizeof(key), "%d-%d-duration", count, interval);
+ ret = dict_get_uint64(dict, key, &sec);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
+ }
+
+ snprintf(key, sizeof(key), "%d-%d-total-read", count, interval);
+ ret = dict_get_uint64(dict, key, &r_count);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
+ }
+
+ snprintf(key, sizeof(key), "%d-%d-total-write", count, interval);
+ ret = dict_get_uint64(dict, key, &w_count);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get %s from dict", key);
+ }
+
+ if (interval == -1)
+ cli_out("Cumulative Stats:");
+ else
+ cli_out("Interval %d Stats:", interval);
+ 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;
+ per_line++;
+ snprintf(output + index, sizeof(output) - index, "%19" PRIu32 "b+ ",
+ (1U << i));
+ if (rb_counts[i]) {
+ snprintf(read_blocks + index, sizeof(read_blocks) - index,
+ "%21" PRId64 " ", rb_counts[i]);
+ } else {
+ snprintf(read_blocks + index, sizeof(read_blocks) - index, "%21s ",
+ "0");
}
+ if (wb_counts[i]) {
+ snprintf(write_blocks + index, sizeof(write_blocks) - index,
+ "%21" PRId64 " ", wb_counts[i]);
+ } else {
+ snprintf(write_blocks + index, sizeof(write_blocks) - index,
+ "%21s ", "0");
+ }
+ index += 22;
+ if (per_line == 3) {
+ cli_out("%s", output);
+ cli_out("%s", read_blocks);
+ cli_out("%s", write_blocks);
+ cli_out(" ");
+ per_line = 0;
+ 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("%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("%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(
+ "%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,
+ profile_info[i].max_latency, profile_info[i].fop_hits,
+ profile_info[i].fop_name);
+ }
+ }
+
+ for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++) {
+ if (upcall_info[i].fop_hits == 0)
+ continue;
+ if (upcall_info[i].fop_hits) {
+ cli_out(
+ "%10.2lf %10.2lf us %10.2lf us %10.2lf us"
+ " %14" PRId64 " %11s",
+ upcall_info[i].percentage_avg_latency,
+ upcall_info[i].avg_latency, upcall_info[i].min_latency,
+ upcall_info[i].max_latency, upcall_info[i].fop_hits,
+ upcall_info[i].fop_name);
+ }
+ }
+
+ 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(" ");
+}
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
-
- ret = dict_get_int32 (dict, "op", (int32_t*)&op);
+static int32_t
+gf_cli_profile_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ gf1_cli_stats_op op = GF_CLI_STATS_NONE;
+ char key[64] = {0};
+ int len;
+ int interval = 0;
+ int i = 1;
+ int32_t brick_count = 0;
+ char *volname = NULL;
+ char *brick = NULL;
+ char str[1024] = {
+ 0,
+ };
+ int stats_cleared = 0;
+ gf1_cli_info_op info_op = GF_CLI_INFO_NONE;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_DEBUG, "Received resp to profile");
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ 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, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
+
+ 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)
- goto out;
-
- if (rsp.op_ret && strcmp (rsp.op_errstr, "")) {
- cli_err ("%s", rsp.op_errstr);
- } else {
- switch (op) {
- case GF_CLI_STATS_START:
- cli_out ("Starting volume profile on %s has been %s ",
- volname,
- (rsp.op_ret) ? "unsuccessful": "successful");
- break;
- case GF_CLI_STATS_STOP:
- cli_out ("Stopping volume profile on %s has been %s ",
- volname,
- (rsp.op_ret) ? "unsuccessful": "successful");
- break;
- case GF_CLI_STATS_INFO:
- break;
- default:
- cli_out ("volume profile on %s has been %s ",
- volname,
- (rsp.op_ret) ? "unsuccessful": "successful");
- break;
- }
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto out;
+ }
+
+ ret = dict_get_int32_sizen(dict, "op", (int32_t *)&op);
+ if (ret)
+ goto out;
+
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ goto out;
+
+ if (rsp.op_ret && strcmp(rsp.op_errstr, "")) {
+ cli_err("%s", rsp.op_errstr);
+ } else {
+ switch (op) {
+ case GF_CLI_STATS_START:
+ cli_out("Starting volume profile on %s has been %s ", volname,
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+ break;
+ case GF_CLI_STATS_STOP:
+ cli_out("Stopping volume profile on %s has been %s ", volname,
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+ break;
+ case GF_CLI_STATS_INFO:
+ break;
+ default:
+ cli_out("volume profile on %s has been %s ", volname,
+ (rsp.op_ret) ? "unsuccessful" : "successful");
+ break;
}
+ }
- if (rsp.op_ret) {
- ret = rsp.op_ret;
- goto out;
- }
+ if (rsp.op_ret) {
+ ret = rsp.op_ret;
+ goto out;
+ }
- if (GF_CLI_STATS_INFO != op) {
- ret = 0;
- goto out;
- }
+ if (GF_CLI_STATS_INFO != op) {
+ ret = 0;
+ goto out;
+ }
- ret = dict_get_int32 (dict, "info-op", (int32_t*)&info_op);
- if (ret)
- goto out;
+ ret = dict_get_int32_sizen(dict, "count", &brick_count);
+ if (ret)
+ goto out;
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret)
- goto out;
+ if (!brick_count) {
+ cli_err("All bricks of volume %s are down.", volname);
+ goto out;
+ }
- if (!brick_count) {
- cli_err ("All bricks of volume %s are down.", volname);
- goto out;
+ ret = dict_get_int32_sizen(dict, "info-op", (int32_t *)&info_op);
+ if (ret)
+ goto out;
+
+ while (i <= brick_count) {
+ len = snprintf(key, sizeof(key), "%d-brick", i);
+ ret = dict_get_strn(dict, key, len, &brick);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Couldn't get brick name");
+ 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);
- ret = dict_get_str_boolean (dict, "nfs", _gf_false);
+ if (ret)
+ len = snprintf(str, sizeof(str), "NFS Server : %s", brick);
+ else
+ len = snprintf(str, sizeof(str), "Brick: %s", brick);
+ cli_out("%s", str);
+ memset(str, '-', len);
+ cli_out("%s", str);
+
+ if (GF_CLI_INFO_CLEAR == info_op) {
+ len = snprintf(key, sizeof(key), "%d-stats-cleared", i);
+ ret = dict_get_int32n(dict, key, len, &stats_cleared);
+ if (ret)
+ goto out;
+ cli_out(stats_cleared ? "Cleared stats."
+ : "Failed to clear stats.");
+ } else {
+ len = snprintf(key, sizeof(key), "%d-cumulative", i);
+ ret = dict_get_int32n(dict, key, len, &interval);
+ if (ret == 0)
+ cmd_profile_volume_brick_out(dict, i, interval);
- 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);
-
- if (GF_CLI_INFO_CLEAR == info_op) {
- snprintf (key, sizeof (key), "%d-stats-cleared", i);
- ret = dict_get_int32 (dict, key, &stats_cleared);
- if (ret)
- goto out;
- cli_out (stats_cleared ? "Cleared stats." :
- "Failed to clear stats.");
- } else {
- snprintf (key, sizeof (key), "%d-cumulative", i);
- ret = dict_get_int32 (dict, key, &interval);
- if (ret == 0)
- cmd_profile_volume_brick_out (dict, i,
- interval);
-
- snprintf (key, sizeof (key), "%d-interval", i);
- ret = dict_get_int32 (dict, key, &interval);
- if (ret == 0)
- cmd_profile_volume_brick_out (dict, i,
- interval);
- }
- i++;
+ len = snprintf(key, sizeof(key), "%d-interval", i);
+ ret = dict_get_int32n(dict, key, len, &interval);
+ if (ret == 0)
+ cmd_profile_volume_brick_out(dict, i, interval);
}
- ret = rsp.op_ret;
+ i++;
+ }
+ ret = rsp.op_ret;
out:
- if (dict)
- dict_unref (dict);
- free (rsp.op_errstr);
- cli_cmd_broadcast_response (ret);
- return ret;
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int32_t
-gf_cli_profile_volume (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_profile_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- int ret = -1;
- gf_cli_req req = {{0,}};
- dict_t *dict = NULL;
+ int ret = -1;
+ gf_cli_req req = {{
+ 0,
+ }};
+ dict_t *dict = NULL;
- GF_ASSERT (frame);
- GF_ASSERT (this);
- GF_ASSERT (data);
+ GF_ASSERT(frame);
+ GF_ASSERT(this);
+ GF_ASSERT(data);
- if (!frame || !this || !data)
- goto out;
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_profile_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_PROFILE_VOLUME, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_profile_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_PROFILE_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- GF_FREE (req.dict.dict_val);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-gf_cli_top_volume_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- 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;
- int32_t j = 0;
- gf1_cli_top_op top_op = GF_CLI_TOP_NONE;
- uint64_t nr_open = 0;
- uint64_t max_nr_open = 0;
- double throughput = 0;
- double time = 0;
- int32_t time_sec = 0;
- long int time_usec = 0;
- char timestr[256] = {0, };
- char *openfd_str = NULL;
- gf_boolean_t nfs = _gf_false;
- gf_boolean_t clear_stats = _gf_false;
- int stats_cleared = 0;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
+static int32_t
+gf_cli_top_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ gf1_cli_stats_op op = GF_CLI_STATS_NONE;
+ char key[256] = {0};
+ int keylen;
+ int i = 0;
+ int32_t brick_count = 0;
+ char brick[1024];
+ int32_t members = 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;
+ uint64_t max_nr_open = 0;
+ double throughput = 0;
+ double time = 0;
+ int32_t time_sec = 0;
+ long int time_usec = 0;
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ char *openfd_str = NULL;
+ gf_boolean_t nfs = _gf_false;
+ gf_boolean_t clear_stats = _gf_false;
+ int stats_cleared = 0;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_DEBUG, "Received resp to top");
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ 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;
+ }
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to top");
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ dict = dict_new();
- 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;
- }
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
- dict = dict_new ();
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
- if (!dict) {
- ret = -1;
- goto out;
- }
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &dict);
+ ret = dict_get_int32_sizen(dict, "op", (int32_t *)&op);
+ if (op != GF_CLI_STATS_TOP) {
+ ret = 0;
+ goto out;
+ }
+
+ 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 ("", GF_LOG_ERROR,
- "Unable to allocate memory");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
}
+ goto out;
+ }
- ret = dict_get_int32 (dict, "op", (int32_t*)&op);
+ ret = dict_get_int32_sizen(dict, "count", &brick_count);
+ if (ret)
+ goto out;
+ keylen = snprintf(key, sizeof(key), "%d-top-op", 1);
+ ret = dict_get_int32n(dict, key, keylen, (int32_t *)&top_op);
+ if (ret)
+ goto out;
- if (op != GF_CLI_STATS_TOP) {
- ret = 0;
+ clear_stats = dict_get_str_boolean(dict, "clear-stats", _gf_false);
+
+ while (i < brick_count) {
+ i++;
+ keylen = snprintf(brick, sizeof(brick), "%d-brick", i);
+ ret = dict_get_strn(dict, brick, keylen, &bricks);
+ if (ret)
+ goto out;
+
+ nfs = dict_get_str_boolean(dict, "nfs", _gf_false);
+
+ if (clear_stats) {
+ keylen = snprintf(key, sizeof(key), "%d-stats-cleared", i);
+ ret = dict_get_int32n(dict, key, keylen, &stats_cleared);
+ if (ret)
goto out;
+ cli_out(stats_cleared ? "Cleared stats for %s %s"
+ : "Failed to clear stats for %s %s",
+ nfs ? "NFS server on" : "brick", bricks);
+ continue;
}
- 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");
+ if (nfs)
+ cli_out("NFS Server : %s", bricks);
+ else
+ cli_out("Brick: %s", bricks);
+
+ keylen = snprintf(key, sizeof(key), "%d-members", i);
+ ret = dict_get_int32n(dict, key, keylen, &members);
+
+ switch (top_op) {
+ case GF_CLI_TOP_OPEN:
+ snprintf(key, sizeof(key), "%d-current-open", i);
+ ret = dict_get_uint64(dict, key, &nr_open);
+ if (ret)
+ break;
+ snprintf(key, sizeof(key), "%d-max-open", i);
+ ret = dict_get_uint64(dict, key, &max_nr_open);
+ if (ret)
+ goto out;
+ keylen = snprintf(key, sizeof(key), "%d-max-openfd-time", i);
+ ret = dict_get_strn(dict, key, keylen, &openfd_str);
+ if (ret)
+ goto out;
+ cli_out("Current open fds: %" PRIu64 ", Max 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) {
+ continue;
+ }
+ cli_out("Count\t\tfilename\n=======================");
+ break;
+ case GF_CLI_TOP_READ_PERF:
+ case GF_CLI_TOP_WRITE_PERF:
+ snprintf(key, sizeof(key), "%d-throughput", i);
+ ret = dict_get_double(dict, key, &throughput);
+ if (!ret) {
+ snprintf(key, sizeof(key), "%d-time", i);
+ ret = dict_get_double(dict, key, &time);
}
+ if (!ret)
+ cli_out("Throughput %.2f MBps time %.4f secs", throughput,
+ time / 1e6);
+
+ if (!members) {
+ continue;
+ }
+ 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;
}
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret)
- goto out;
- snprintf (key, sizeof (key), "%d-top-op", 1);
- ret = dict_get_int32 (dict, key, (int32_t*)&top_op);
- if (ret)
- goto out;
-
- clear_stats = dict_get_str_boolean (dict, "clear-stats", _gf_false);
-
- while (i < brick_count) {
- i++;
- snprintf (brick, sizeof (brick), "%d-brick", i);
- ret = dict_get_str (dict, brick, &bricks);
- if (ret)
- goto out;
-
- nfs = dict_get_str_boolean (dict, "nfs", _gf_false);
-
- if (clear_stats) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%d-stats-cleared", i);
- ret = dict_get_int32 (dict, key, &stats_cleared);
- if (ret)
- goto out;
- cli_out (stats_cleared ? "Cleared stats for %s %s" :
- "Failed to clear stats for %s %s",
- nfs ? "NFS server on" : "brick", bricks);
- continue;
- }
-
- if (nfs)
- cli_out ("NFS Server : %s", bricks);
+ for (j = 1; j <= members; j++) {
+ keylen = snprintf(key, sizeof(key), "%d-filename-%d", i, j);
+ ret = dict_get_strn(dict, key, keylen, &filename);
+ if (ret)
+ break;
+ snprintf(key, sizeof(key), "%d-value-%d", i, j);
+ ret = dict_get_uint64(dict, key, &value);
+ if (ret)
+ goto out;
+ if (top_op == GF_CLI_TOP_READ_PERF ||
+ top_op == GF_CLI_TOP_WRITE_PERF) {
+ keylen = snprintf(key, sizeof(key), "%d-time-sec-%d", i, j);
+ ret = dict_get_int32n(dict, key, keylen, (int32_t *)&time_sec);
+ if (ret)
+ goto out;
+ keylen = snprintf(key, sizeof(key), "%d-time-usec-%d", i, j);
+ ret = dict_get_int32n(dict, key, keylen, (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), ".%ld", time_usec);
+ 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 ("Brick: %s", bricks);
-
- snprintf(key, sizeof (key), "%d-members", i);
- ret = dict_get_int32 (dict, key, &members);
-
- switch (top_op) {
- case GF_CLI_TOP_OPEN:
- snprintf (key, sizeof (key), "%d-current-open", i);
- ret = dict_get_uint64 (dict, key, &nr_open);
- if (ret)
- break;
- snprintf (key, sizeof (key), "%d-max-open", i);
- 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", 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) {
- continue;
- }
- cli_out ("Count\t\tfilename\n=======================");
- break;
- case GF_CLI_TOP_READ_PERF:
- case GF_CLI_TOP_WRITE_PERF:
- snprintf (key, sizeof (key), "%d-throughput", i);
- ret = dict_get_double (dict, key, &throughput);
- if (!ret) {
- snprintf (key, sizeof (key), "%d-time", i);
- ret = dict_get_double (dict, key, &time);
- }
- if (!ret)
- cli_out ("Throughput %.2f MBps time %.4f secs", throughput,
- time / 1e6);
-
- if (!members) {
- continue;
- }
- 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;
- }
-
- for (j = 1; j <= members; j++) {
- snprintf (key, sizeof (key), "%d-filename-%d", i, j);
- ret = dict_get_str (dict, key, &filename);
- if (ret)
- break;
- snprintf (key, sizeof (key), "%d-value-%d", i, j);
- ret = dict_get_uint64 (dict, key, &value);
- if (ret)
- goto out;
- if ( top_op == GF_CLI_TOP_READ_PERF ||
- top_op == GF_CLI_TOP_WRITE_PERF) {
- snprintf (key, sizeof (key), "%d-time-sec-%d", i, j);
- ret = dict_get_int32 (dict, key, (int32_t *)&time_sec);
- if (ret)
- goto out;
- snprintf (key, sizeof (key), "%d-time-usec-%d", i, j);
- 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),
- ".%ld", time_usec);
- 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);
- }
- }
+ 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);
+ }
}
- ret = rsp.op_ret;
+ }
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
+ cli_cmd_broadcast_response(ret);
- if (dict)
- dict_unref (dict);
+ if (dict)
+ dict_unref(dict);
- free (rsp.dict.dict_val);
- return ret;
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int32_t
-gf_cli_top_volume (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_top_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- int ret = -1;
- gf_cli_req req = {{0,}};
- dict_t *dict = NULL;
-
- GF_ASSERT (frame);
- GF_ASSERT (this);
- GF_ASSERT (data);
+ int ret = -1;
+ gf_cli_req req = {{
+ 0,
+ }};
+ dict_t *dict = NULL;
- if (!frame || !this || !data)
- goto out;
- dict = data;
+ GF_ASSERT(frame);
+ GF_ASSERT(this);
+ GF_ASSERT(data);
- ret = cli_to_glusterd (&req, frame, gf_cli_top_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_PROFILE_VOLUME, this, cli_rpc_prog,
- NULL);
+ dict = data;
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- GF_FREE (req.dict.dict_val);
- return ret;
+ ret = cli_to_glusterd(&req, frame, gf_cli_top_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_PROFILE_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-
-int
-gf_cli_getwd_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+static int
+gf_cli_getwd_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- gf1_cli_getwd_rsp rsp = {0,};
- int ret = -1;
+ gf1_cli_getwd_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
- if (-1 == req->rpc_status) {
- goto out;
- }
+ GF_ASSERT(myframe);
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_getwd_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- if (rsp.op_ret == -1) {
- cli_err ("getwd failed");
- ret = rsp.op_ret;
- goto out;
- }
-
- gf_log ("cli", GF_LOG_INFO, "Received resp to getwd");
-
- cli_out ("%s", rsp.wd);
-
- ret = 0;
-
-out:
- cli_cmd_broadcast_response (ret);
- return ret;
-}
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf1_cli_getwd_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
-int32_t
-gf_cli_getwd (call_frame_t *frame, xlator_t *this, void *data)
-{
- int ret = -1;
- gf1_cli_getwd_req req = {0,};
+ if (rsp.op_ret == -1) {
+ cli_err("getwd failed");
+ ret = rsp.op_ret;
+ goto out;
+ }
- GF_ASSERT (frame);
- GF_ASSERT (this);
+ gf_log("cli", GF_LOG_INFO, "Received resp to getwd");
- if (!frame || !this)
- goto out;
+ cli_out("%s", rsp.wd);
- ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog,
- GLUSTER_CLI_GETWD, NULL,
- this, gf_cli_getwd_cbk,
- (xdrproc_t) xdr_gf1_cli_getwd_req);
+ ret = 0;
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ cli_cmd_broadcast_response(ret);
+ if (rsp.wd) {
+ free(rsp.wd);
+ }
- return ret;
+ 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;
+static int32_t
+gf_cli_getwd(call_frame_t *frame, xlator_t *this, void *data)
+{
+ int ret = -1;
+ gf1_cli_getwd_req req = {
+ 0,
+ };
- 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;
+ GF_ASSERT(frame);
+ GF_ASSERT(this);
- 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;
+ if (!frame || !this)
+ 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);
- }
+ ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_GETWD,
+ NULL, this, gf_cli_getwd_cbk,
+ (xdrproc_t)xdr_gf1_cli_getwd_req);
out:
- return;
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-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);
+static 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[128] = {
+ /* prefix is really small 'brick%d' really */
+ 0,
+ };
+ int keylen;
+ int i = 0;
+
+ GF_ASSERT(dict);
+ GF_ASSERT(prefix);
+
+ keylen = snprintf(key, sizeof(key), "%s.mempool-count", prefix);
+ ret = dict_get_int32n(dict, key, keylen, &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++) {
+ keylen = snprintf(key, sizeof(key), "%s.pool%d.name", prefix, i);
+ ret = dict_get_strn(dict, key, keylen, &name);
if (ret)
- goto out;
- cli_out ("Memory status for volume : %s", volname);
+ goto out;
- ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
+ keylen = snprintf(key, sizeof(key), "%s.pool%d.hotcount", prefix, i);
+ ret = dict_get_int32n(dict, key, keylen, &hotcount);
if (ret)
- goto out;
- ret = dict_get_int32 (dict, "other-count", &other_count);
- if (ret)
- goto out;
-
- index_max = brick_index_max + other_count;
+ goto out;
- 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--------");
+ keylen = snprintf(key, sizeof(key), "%s.pool%d.coldcount", prefix, i);
+ ret = dict_get_int32n(dict, key, keylen, &coldcount);
+ if (ret)
+ goto out;
- 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);
+ 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), "brick%d.mallinfo.usmblks", i);
- ret = dict_get_int32 (dict, key, &val);
- if (ret)
- goto out;
- cli_out ("%-8s : %d", "Usmblks", val);
+ 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), "brick%d.mallinfo.fsmblks", i);
- ret = dict_get_int32 (dict, key, &val);
- if (ret)
- goto out;
- cli_out ("%-8s : %d", "Fsmblks", val);
+ keylen = snprintf(key, sizeof(key), "%s.pool%d.max_alloc", prefix, i);
+ ret = dict_get_int32n(dict, key, keylen, &maxalloc);
+ if (ret)
+ goto out;
- 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);
+ keylen = snprintf(key, sizeof(key), "%s.pool%d.max-stdalloc", prefix,
+ i);
+ ret = dict_get_int32n(dict, key, keylen, &maxstdalloc);
+ if (ret)
+ goto out;
- 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);
+ snprintf(key, sizeof(key), "%s.pool%d.pool-misses", prefix, i);
+ ret = dict_get_uint64(dict, key, &pool_misses);
+ if (ret)
+ goto out;
- 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("%-30s %9d %9d %12" PRIu64 " %10" PRIu64 " %8d %8" PRIu64
+ " %12d",
+ name, hotcount, coldcount, paddedsizeof, alloccount, maxalloc,
+ pool_misses, maxstdalloc);
+ }
- 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;
+ 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);
+static 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[64] = {
+ 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_sizen(dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out("Memory status for volume : %s", volname);
+
+ ret = dict_get_int32_sizen(dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32_sizen(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("----------------------------------------------");
+
+ snprintf(key, sizeof(key), "brick%d.hostname", i);
+ ret = dict_get_str(dict, key, &hostname);
if (ret)
- goto out;
- ret = dict_get_int32 (dict, "other-count", &other_count);
+ continue;
+ snprintf(key, sizeof(key), "brick%d.path", i);
+ ret = dict_get_str(dict, key, &path);
if (ret)
- goto out;
+ continue;
+ if (notbrick)
+ cli_out("%s : %s", hostname, path);
+ else
+ cli_out("Brick : %s:%s", hostname, path);
- index_max = brick_index_max + other_count;
+ 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;
+ }
- for (i = 0; i <= index_max; i++) {
- cli_out ("----------------------------------------------");
+ cli_out("Mallinfo\n--------");
- 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;
+ 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);
- if (notbrick)
- cli_out ("%s : %s", hostname, path);
- else
- cli_out ("Brick : %s:%s", hostname, path);
+ 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.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;
- }
+ 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.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;
-}
+ 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);
-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;
+ 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);
- GF_ASSERT (dict);
- GF_ASSERT (prefix);
+ 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), "%s.gfid", prefix);
- ret = dict_get_str (dict, key, &gfid);
+ snprintf(key, sizeof(key), "brick%d.mallinfo.fsmblks", i);
+ ret = dict_get_int32(dict, key, &val);
if (ret)
- goto out;
+ goto out;
+ cli_out("%-8s : %d", "Fsmblks", val);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.nlookup", prefix);
- ret = dict_get_uint64 (dict, key, &nlookup);
+ snprintf(key, sizeof(key), "brick%d.mallinfo.uordblks", i);
+ ret = dict_get_int32(dict, key, &val);
if (ret)
- goto out;
+ goto out;
+ cli_out("%-8s : %d", "Uordblks", val);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.ref", prefix);
- ret = dict_get_uint32 (dict, key, &ref);
+ snprintf(key, sizeof(key), "brick%d.mallinfo.fordblks", i);
+ ret = dict_get_int32(dict, key, &val);
if (ret)
- goto out;
+ goto out;
+ cli_out("%-8s : %d", "Fordblks", val);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.ia_type", prefix);
- ret = dict_get_int32 (dict, key, &ia_type);
+ snprintf(key, sizeof(key), "brick%d.mallinfo.keepcost", i);
+ ret = dict_get_int32(dict, key, &val);
if (ret)
- goto out;
+ goto out;
+ cli_out("%-8s : %d", "Keepcost", val);
- switch (ia_type) {
+ cli_out(" ");
+ snprintf(key, sizeof(key), "brick%d", i);
+ cli_print_volume_status_mempool(dict, key);
+ }
+out:
+ cli_out("----------------------------------------------\n");
+ return;
+}
+
+static void
+cli_print_volume_status_client_list(dict_t *dict, gf_boolean_t notbrick)
+{
+ int ret = -1;
+ char *volname = NULL;
+ int client_count = 0;
+ int current_count = 0;
+ char key[64] = {
+ 0,
+ };
+ int i = 0;
+ int total = 0;
+ char *name = NULL;
+ gf_boolean_t is_fuse_done = _gf_false;
+ gf_boolean_t is_gfapi_done = _gf_false;
+ gf_boolean_t is_rebalance_done = _gf_false;
+ gf_boolean_t is_glustershd_done = _gf_false;
+ gf_boolean_t is_quotad_done = _gf_false;
+ gf_boolean_t is_snapd_done = _gf_false;
+
+ GF_ASSERT(dict);
+
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out("Client connections for volume %s", volname);
+
+ ret = dict_get_int32_sizen(dict, "client-count", &client_count);
+ if (ret)
+ goto out;
+
+ cli_out("%-48s %15s", "Name", "count");
+ cli_out("%-48s %15s", "-----", "------");
+ for (i = 0; i < client_count; i++) {
+ name = NULL;
+ snprintf(key, sizeof(key), "client%d.name", i);
+ ret = dict_get_str(dict, key, &name);
+
+ if (!strncmp(name, "fuse", 4)) {
+ if (!is_fuse_done) {
+ is_fuse_done = _gf_true;
+ ret = dict_get_int32_sizen(dict, "fuse-count", &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strncmp(name, "gfapi", 5)) {
+ if (!is_gfapi_done) {
+ is_gfapi_done = _gf_true;
+ ret = dict_get_int32_sizen(dict, "gfapi-count", &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strcmp(name, "rebalance")) {
+ if (!is_rebalance_done) {
+ is_rebalance_done = _gf_true;
+ ret = dict_get_int32_sizen(dict, "rebalance-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strcmp(name, "glustershd")) {
+ if (!is_glustershd_done) {
+ is_glustershd_done = _gf_true;
+ ret = dict_get_int32_sizen(dict, "glustershd-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strcmp(name, "quotad")) {
+ if (!is_quotad_done) {
+ is_quotad_done = _gf_true;
+ ret = dict_get_int32_sizen(dict, "quotad-count",
+ &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ } else if (!strcmp(name, "snapd")) {
+ if (!is_snapd_done) {
+ is_snapd_done = _gf_true;
+ ret = dict_get_int32_sizen(dict, "snapd-count", &current_count);
+ if (ret)
+ goto out;
+ total = total + current_count;
+ goto print;
+ }
+ continue;
+ }
+
+ print:
+ cli_out("%-48s %15d", name, current_count);
+ }
+out:
+ cli_out("\ntotal clients for volume %s : %d ", volname, total);
+ cli_out(
+ "-----------------------------------------------------------------\n");
+ return;
+}
+
+static 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;
+ uint32_t opversion = 0;
+ char key[128] = {
+ 0,
+ };
+ int i = 0;
+ int j = 0;
+
+ GF_ASSERT(dict);
+
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out("Client connections for volume %s", volname);
+
+ ret = dict_get_int32_sizen(dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32_sizen(dict, "other-count", &other_count);
+ if (ret)
+ goto out;
+
+ index_max = brick_index_max + other_count;
+
+ for (i = 0; i <= index_max; i++) {
+ hostname = NULL;
+ path = NULL;
+ online = -1;
+ client_count = 0;
+ clientname = NULL;
+ bytesread = 0;
+ byteswrite = 0;
+
+ cli_out("----------------------------------------------");
+
+ snprintf(key, sizeof(key), "brick%d.hostname", i);
+ ret = dict_get_str(dict, key, &hostname);
+
+ snprintf(key, sizeof(key), "brick%d.path", i);
+ ret = dict_get_str(dict, key, &path);
+
+ if (hostname && path) {
+ if (notbrick)
+ cli_out("%s : %s", hostname, path);
+ else
+ cli_out("Brick : %s:%s", hostname, path);
+ }
+ snprintf(key, sizeof(key), "brick%d.status", i);
+ ret = dict_get_int32(dict, key, &online);
+ if (!online) {
+ if (notbrick)
+ cli_out("%s is offline", hostname);
+ else
+ cli_out("Brick is offline");
+ continue;
+ }
+
+ snprintf(key, sizeof(key), "brick%d.clientcount", i);
+ ret = dict_get_int32(dict, key, &client_count);
+
+ if (hostname && path)
+ cli_out("Clients connected : %d", client_count);
+ if (client_count == 0)
+ continue;
+
+ cli_out("%-48s %15s %15s %15s", "Hostname", "BytesRead", "BytesWritten",
+ "OpVersion");
+ cli_out("%-48s %15s %15s %15s", "--------", "---------", "------------",
+ "---------");
+ for (j = 0; j < client_count; j++) {
+ snprintf(key, sizeof(key), "brick%d.client%d.hostname", i, j);
+ ret = dict_get_str(dict, key, &clientname);
+
+ snprintf(key, sizeof(key), "brick%d.client%d.bytesread", i, j);
+ ret = dict_get_uint64(dict, key, &bytesread);
+
+ snprintf(key, sizeof(key), "brick%d.client%d.byteswrite", i, j);
+ ret = dict_get_uint64(dict, key, &byteswrite);
+
+ snprintf(key, sizeof(key), "brick%d.client%d.opversion", i, j);
+ ret = dict_get_uint32(dict, key, &opversion);
+
+ cli_out("%-48s %15" PRIu64 " %15" PRIu64 " %15" PRIu32, clientname,
+ bytesread, byteswrite, opversion);
+ }
+ }
+out:
+ cli_out("----------------------------------------------\n");
+ return;
+}
+
+#ifdef DEBUG /* this function is only used in debug */
+static 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);
+
+ snprintf(key, sizeof(key), "%s.gfid", prefix);
+ ret = dict_get_str(dict, key, &gfid);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%s.nlookup", prefix);
+ ret = dict_get_uint64(dict, key, &nlookup);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%s.ref", prefix);
+ ret = dict_get_uint32(dict, key, &ref);
+ if (ret)
+ goto out;
+
+ 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;
+ inode_type = 'R';
+ break;
case IA_IFDIR:
- inode_type = 'D';
- break;
+ inode_type = 'D';
+ break;
case IA_IFLNK:
- inode_type = 'L';
- break;
+ inode_type = 'L';
+ break;
case IA_IFBLK:
- inode_type = 'B';
- break;
+ inode_type = 'B';
+ break;
case IA_IFCHR:
- inode_type = 'C';
- break;
+ inode_type = 'C';
+ break;
case IA_IFIFO:
- inode_type = 'F';
- break;
+ inode_type = 'F';
+ break;
case IA_IFSOCK:
- inode_type = 'S';
- break;
+ inode_type = 'S';
+ break;
default:
- inode_type = 'I';
- break;
- }
+ inode_type = 'I';
+ break;
+ }
- cli_out ("%-40s %14"PRIu64" %14"PRIu32" %9c",
- gfid, nlookup, ref, inode_type);
+ cli_out("%-40s %14" PRIu64 " %14" PRIu32 " %9c", gfid, nlookup, ref,
+ inode_type);
out:
- return;
-
+ return;
}
+#endif
-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);
+static 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;
+ uint32_t lru_limit = 0;
+#ifdef DEBUG
+ int i = 0;
+#endif
+ GF_ASSERT(dict);
+ GF_ASSERT(prefix);
+
+ snprintf(key, sizeof(key), "%s.lru_limit", prefix);
+ ret = dict_get_uint32(dict, key, &lru_limit);
+ if (ret)
+ goto out;
+ cli_out("LRU limit : %u", lru_limit);
+
+ snprintf(key, sizeof(key), "%s.active_size", prefix);
+ ret = dict_get_uint32(dict, key, &active_size);
+ if (ret)
+ goto out;
+
+#ifdef DEBUG
+ 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++) {
+ snprintf(key, sizeof(key), "%s.active%d", prefix, i);
+ cli_print_volume_status_inode_entry(dict, key);
+ }
+ cli_out(" ");
+#else
+ cli_out("Active Inodes : %u", active_size);
- 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 (" ");
+#endif
- 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 (" ");
+ snprintf(key, sizeof(key), "%s.lru_size", prefix);
+ ret = dict_get_uint32(dict, key, &lru_size);
+ if (ret)
+ goto out;
+
+#ifdef DEBUG
+ 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++) {
+ snprintf(key, sizeof(key), "%s.lru%d", prefix, i);
+ cli_print_volume_status_inode_entry(dict, key);
+ }
+ cli_out(" ");
+#else
+ cli_out("LRU Inodes : %u", lru_size);
+#endif
- 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);
- }
+ snprintf(key, sizeof(key), "%s.purge_size", prefix);
+ ret = dict_get_uint32(dict, key, &purge_size);
+ if (ret)
+ goto out;
+#ifdef DEBUG
+ 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++) {
+ snprintf(key, sizeof(key), "%s.purge%d", prefix, i);
+ cli_print_volume_status_inode_entry(dict, key);
+ }
+#else
+ cli_out("Purge Inodes : %u", purge_size);
+#endif
out:
- return;
+ 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);
+static 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[64] = {
+ 0,
+ };
+ int i = 0;
+ int j = 0;
+
+ GF_ASSERT(dict);
+
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out("Inode tables for volume %s", volname);
+
+ ret = dict_get_int32_sizen(dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32_sizen(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("----------------------------------------------");
+
+ snprintf(key, sizeof(key), "brick%d.hostname", i);
+ ret = dict_get_str(dict, key, &hostname);
if (ret)
- goto out;
- cli_out ("Inode tables for volume %s", volname);
-
- ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
+ goto out;
+ snprintf(key, sizeof(key), "brick%d.path", i);
+ ret = dict_get_str(dict, key, &path);
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);
+ 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;
- }
+ 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;
+ 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);
+ 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 (" ");
- }
+ snprintf(key, sizeof(key), "brick%d.conn%d.itable", i, j);
+ cli_print_volume_status_itables(dict, key);
+ cli_out(" ");
}
+ }
out:
- cli_out ("----------------------------------------------");
- return;
+ 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);
+cli_print_volume_status_fdtable(dict_t *dict, char *prefix)
+{
+ int ret = -1;
+ char key[256] = {
+ 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);
+
+ snprintf(key, sizeof(key), "%s.refcount", prefix);
+ ret = dict_get_int32(dict, key, &refcount);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%s.maxfds", prefix);
+ ret = dict_get_uint32(dict, key, &maxfds);
+ if (ret)
+ goto out;
+
+ 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);
+
+ snprintf(key, sizeof(key), "%s.openfds", prefix);
+ ret = dict_get_int32(dict, key, &openfds);
+ if (ret)
+ goto out;
+ if (0 == openfds) {
+ cli_err("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++) {
+ snprintf(key, sizeof(key), "%s.fdentry%d.pid", prefix, i);
+ ret = dict_get_int32(dict, key, &fd_pid);
if (ret)
- goto out;
+ continue;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.maxfds", prefix);
- ret = dict_get_uint32 (dict, key, &maxfds);
+ snprintf(key, sizeof(key), "%s.fdentry%d.refcount", prefix, i);
+ ret = dict_get_int32(dict, key, &fd_refcount);
if (ret)
- goto out;
+ continue;
- memset (key, 0 ,sizeof (key));
- snprintf (key, sizeof (key), "%s.firstfree", prefix);
- ret = dict_get_int32 (dict, key, &firstfree);
+ snprintf(key, sizeof(key), "%s.fdentry%d.flags", prefix, i);
+ ret = dict_get_int32(dict, key, &fd_flags);
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_err ("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;
+ 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);
- }
+ cli_out("%-19d %-19d %-19d %-19d", i, fd_pid, fd_refcount, fd_flags);
+ }
out:
- return;
+ 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);
+static 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[64] = {
+ 0,
+ };
+ int i = 0;
+ int j = 0;
+
+ GF_ASSERT(dict);
+
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out("FD tables for volume %s", volname);
+
+ ret = dict_get_int32_sizen(dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32_sizen(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("----------------------------------------------");
+
+ snprintf(key, sizeof(key), "brick%d.hostname", i);
+ ret = dict_get_str(dict, key, &hostname);
if (ret)
- goto out;
- ret = dict_get_int32 (dict, "other-count", &other_count);
+ goto out;
+ snprintf(key, sizeof(key), "brick%d.path", i);
+ ret = dict_get_str(dict, key, &path);
if (ret)
- goto out;
+ 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);
+ 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;
- }
+ 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;
+ 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);
+ 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 (" ");
- }
+ snprintf(key, sizeof(key), "brick%d.conn%d.fdtable", i, j);
+ cli_print_volume_status_fdtable(dict, key);
+ cli_out(" ");
}
+ }
out:
- cli_out ("----------------------------------------------");
- return;
+ 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;
+static 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;
+ 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;
+ 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;
+ 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"));
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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;
+static void
+cli_print_volume_status_call_stack(dict_t *dict, char *prefix)
+{
+ int ret = -1;
+ char key[256] = {
+ 0,
+ };
+ int uid = 0;
+ int gid = 0;
+ int pid = 0;
+ uint64_t unique = 0;
+ // char *op = NULL;
+ int count = 0;
+ int i = 0;
+
+ if (!prefix)
+ return;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.gid", prefix);
- ret = dict_get_int32 (dict, key, &gid);
- if (ret)
- return;
+ 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.pid", prefix);
- ret = dict_get_int32 (dict, key, &pid);
- if (ret)
- return;
+ 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.unique", prefix);
- ret = dict_get_uint64 (dict, key, &unique);
- if (ret)
- return;
+ 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.op", prefix);
- ret = dict_get_str (dict, key, &op);
- if (ret)
- return;
- */
+ snprintf(key, sizeof(key), "%s.unique", prefix);
+ ret = dict_get_uint64(dict, key, &unique);
+ if (ret)
+ return;
+ /*
+ 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;
+ 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);
+ 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);
+ 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);
- }
+ snprintf(key, sizeof(key), "%s.frame%d", prefix, i);
+ cli_print_volume_status_call_frame(dict, key);
+ }
- cli_out (" ");
+ 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);
+static 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[64] = {
+ 0,
+ };
+ int i = 0;
+ int j = 0;
+
+ GF_ASSERT(dict);
+
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ goto out;
+ cli_out("Pending calls for volume %s", volname);
+
+ ret = dict_get_int32_sizen(dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
+ ret = dict_get_int32_sizen(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("----------------------------------------------");
+
+ snprintf(key, sizeof(key), "brick%d.hostname", i);
+ ret = dict_get_str(dict, key, &hostname);
if (ret)
- goto out;
- ret = dict_get_int32 (dict, "other-count", &other_count);
+ goto out;
+ snprintf(key, sizeof(key), "brick%d.path", i);
+ ret = dict_get_str(dict, key, &path);
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;
+ goto out;
- if (notbrick)
- cli_out ("%s : %s", hostname, path);
- else
- cli_out ("Brick : %s:%s", hostname, path);
+ 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;
- }
+ 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);
+ 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;
+ if (0 == call_count)
+ continue;
- for (j = 0; j < call_count; j++) {
- cli_out ("Call Stack%d", j+1);
+ 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);
- }
+ snprintf(key, sizeof(key), "brick%d.callpool.stack%d", i, j);
+ cli_print_volume_status_call_stack(dict, key);
}
+ }
out:
- cli_out ("----------------------------------------------");
- return;
+ cli_out("----------------------------------------------");
+ return;
}
static void
-cli_print_volume_status_tasks (dict_t *dict)
-{
- int ret = -1;
- int i = 0;
- int j = 0;
- int count = 0;
- int task_count = 0;
- int status = 0;
- char *op = NULL;
- char *task_id_str = NULL;
- char *volname = NULL;
- char key[1024] = {0,};
- char task[1024] = {0,};
- char *brick = NULL;
- char *src_brick = NULL;
- char *dest_brick = NULL;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
+cli_print_volume_status_tasks(dict_t *dict)
+{
+ int ret = -1;
+ int i = 0;
+ int j = 0;
+ int count = 0;
+ int task_count = 0;
+ int status = 0;
+ char *op = NULL;
+ char *task_id_str = NULL;
+ char *volname = NULL;
+ char key[64] = {
+ 0,
+ };
+ char task[32] = {
+ 0,
+ };
+ char *brick = NULL;
+
+ ret = dict_get_int32_sizen(dict, "tasks", &task_count);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get tasks count");
+ return;
+ }
- ret = dict_get_int32 (dict, "tasks", &task_count);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get tasks count");
- return;
- }
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ goto out;
- cli_out ("Task Status of Volume %s", volname);
- cli_print_line (CLI_BRICK_STATUS_LINE_LEN);
+ cli_out("Task Status of Volume %s", volname);
+ cli_print_line(CLI_BRICK_STATUS_LINE_LEN);
- if (task_count == 0) {
- cli_out ("There are no active volume tasks");
- cli_out (" ");
- return;
- }
+ if (task_count == 0) {
+ cli_out("There are no active volume tasks");
+ cli_out(" ");
+ return;
+ }
- for (i = 0; i < task_count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.type", i);
- ret = dict_get_str(dict, key, &op);
- if (ret)
- return;
- cli_out ("%-20s : %-20s", "Task", op);
+ for (i = 0; i < task_count; i++) {
+ snprintf(key, sizeof(key), "task%d.type", i);
+ ret = dict_get_str(dict, key, &op);
+ if (ret)
+ return;
+ cli_out("%-20s : %-20s", "Task", op);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.id", i);
- ret = dict_get_str (dict, key, &task_id_str);
- if (ret)
- return;
- cli_out ("%-20s : %-20s", "ID", task_id_str);
+ snprintf(key, sizeof(key), "task%d.id", i);
+ ret = dict_get_str(dict, key, &task_id_str);
+ if (ret)
+ return;
+ cli_out("%-20s : %-20s", "ID", task_id_str);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.status", i);
- ret = dict_get_int32 (dict, key, &status);
- if (ret)
- return;
+ snprintf(key, sizeof(key), "task%d.status", i);
+ ret = dict_get_int32(dict, key, &status);
+ if (ret)
+ return;
- snprintf (task, sizeof (task), "task%d", i);
+ snprintf(task, sizeof(task), "task%d", i);
- if (!strcmp (op, "Remove brick")) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.count", task);
- ret = dict_get_int32 (dict, key, &count);
- if (ret)
- goto out;
+ if (!strcmp(op, "Remove brick")) {
+ snprintf(key, sizeof(key), "%s.count", task);
+ ret = dict_get_int32(dict, key, &count);
+ if (ret)
+ goto out;
- cli_out ("%-20s", "Removed bricks:");
+ cli_out("%-20s", "Removed bricks:");
- for (j = 1; j <= count; j++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key),"%s.brick%d",
- task, j);
- ret = dict_get_str (dict, key, &brick);
- if (ret)
- goto out;
+ for (j = 1; j <= count; j++) {
+ snprintf(key, sizeof(key), "%s.brick%d", task, j);
+ ret = dict_get_str(dict, key, &brick);
+ if (ret)
+ goto out;
- cli_out ("%-20s", brick);
- }
- }
- cli_out ("%-20s : %-20s", "Status",
- cli_vol_task_status_str[status]);
- cli_out (" ");
+ cli_out("%-20s", brick);
+ }
}
+ cli_out("%-20s : %-20s", "Status", cli_vol_task_status_str[status]);
+ cli_out(" ");
+ }
out:
- return;
+ return;
}
static int
-gf_cli_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 type = -1;
- int hot_brick_count = -1;
- 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;
- gf_boolean_t wipe_local = _gf_false;
- 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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- gf_log ("cli", GF_LOG_DEBUG, "Received response to status cmd");
-
- local = ((call_frame_t *)myframe)->local;
+gf_cli_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 type = -1;
+ int hot_brick_count = -1;
+ int pid = -1;
+ uint32_t cmd = 0;
+ gf_boolean_t notbrick = _gf_false;
+ char key[64] = {
+ 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;
+ gf_boolean_t wipe_local = _gf_false;
+ char msg[1024] = {
+ 0,
+ };
+
+ GF_ASSERT(myframe);
+
+ if (req->rpc_status == -1)
+ goto out;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_DEBUG, "Received response to status cmd");
+
+ local = ((call_frame_t *)myframe)->local;
+ if (!local) {
+ local = cli_local_get();
if (!local) {
- local = cli_local_get ();
- if (!local) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "Failed to get local");
- goto out;
- }
- wipe_local = _gf_true;
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Failed to get local");
+ goto out;
}
+ wipe_local = _gf_true;
+ }
- 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 (global_state->mode & GLUSTER_MODE_XML) {
- if (!local->all)
- cli_xml_output_str ("volStatus", msg,
- rsp.op_ret, rsp.op_errno,
- rsp.op_errstr);
- ret = 0;
- goto out;
- }
-
- cli_err ("%s", msg);
- if (local && local->all) {
- ret = 0;
- cli_out (" ");
- } else
- ret = -1;
+ 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.");
- goto out;
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ if (!local->all)
+ cli_xml_output_str("volStatus", msg, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
+ ret = 0;
+ goto out;
}
- dict = dict_new ();
- if (!dict)
- goto out;
+ cli_err("%s", msg);
+ if (local && local->all) {
+ ret = 0;
+ cli_out(" ");
+ } else
+ ret = -1;
+
+ goto out;
+ }
+
+ dict = dict_new();
+ if (!dict) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Failed to create the dict");
+ ret = -1;
+ 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_ref(dict);
+ ret = dict_set_static_ptr(local->dict, "rsp-dict", dict);
+ ret = 0;
+ } else {
+ gf_log("cli", GF_LOG_ERROR, "local not found");
+ ret = -1;
+ }
+ goto out;
+ }
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ if (!local->all) {
+ ret = cli_xml_output_vol_status_begin(local, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto xml_end;
+ }
+ }
+ if (cmd & GF_CLI_STATUS_TASKS) {
+ ret = cli_xml_output_vol_status_tasks_detail(local, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Error outputting to xml");
+ goto xml_end;
+ }
+ } else {
+ ret = cli_xml_output_vol_status(local, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto xml_end;
+ }
+ }
+
+ xml_end:
+ if (!local->all) {
+ ret = cli_xml_output_vol_status_end(local);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ }
+ }
+ goto out;
+ }
+
+ if ((cmd & GF_CLI_STATUS_NFS) || (cmd & GF_CLI_STATUS_SHD) ||
+ (cmd & GF_CLI_STATUS_QUOTAD) || (cmd & GF_CLI_STATUS_SNAPD) ||
+ (cmd & GF_CLI_STATUS_BITD) || (cmd & GF_CLI_STATUS_SCRUB))
+ notbrick = _gf_true;
+
+ 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_CLIENT_LIST:
+ cli_print_volume_status_client_list(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;
+ case GF_CLI_STATUS_TASKS:
+ cli_print_volume_status_tasks(dict);
+ goto cont;
+ break;
+ default:
+ break;
+ }
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &dict);
- if (ret)
- goto out;
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ goto out;
- ret = dict_get_uint32 (dict, "cmd", &cmd);
- if (ret)
- goto out;
+ ret = dict_get_int32_sizen(dict, "brick-index-max", &brick_index_max);
+ if (ret)
+ goto out;
- if ((cmd & GF_CLI_STATUS_ALL)) {
- if (local && local->dict) {
- dict_ref (dict);
- ret = dict_set_static_ptr (local->dict, "rsp-dict", dict);
- ret = 0;
- } else {
- gf_log ("cli", GF_LOG_ERROR, "local not found");
- ret = -1;
- }
- goto out;
- }
+ ret = dict_get_int32_sizen(dict, "other-count", &other_count);
+ if (ret)
+ goto out;
- if ((cmd & GF_CLI_STATUS_NFS) || (cmd & GF_CLI_STATUS_SHD) ||
- (cmd & GF_CLI_STATUS_QUOTAD) || (cmd & GF_CLI_STATUS_SNAPD) ||
- (cmd & GF_CLI_STATUS_BITD) || (cmd & GF_CLI_STATUS_SCRUB))
- notbrick = _gf_true;
+ index_max = brick_index_max + other_count;
- if (global_state->mode & GLUSTER_MODE_XML) {
- if (!local->all) {
- ret = cli_xml_output_vol_status_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;
- }
- }
- if (cmd & GF_CLI_STATUS_TASKS) {
- ret = cli_xml_output_vol_status_tasks_detail (local,
- dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,"Error outputting "
- "to xml");
- goto out;
- }
- } else {
- ret = cli_xml_output_vol_status (local, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
- }
+ ret = dict_get_int32_sizen(dict, "type", &type);
+ if (ret)
+ goto out;
- if (!local->all) {
- ret = cli_xml_output_vol_status_end (local);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- }
- }
- goto out;
- }
+ ret = dict_get_int32_sizen(dict, "hot_brick_count", &hot_brick_count);
+ if (ret)
+ goto out;
- status.brick = GF_CALLOC (1, PATH_MAX + 256, gf_common_mt_strdup);
- if (!status.brick) {
- errno = ENOMEM;
- ret = -1;
- goto out;
- }
- 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;
- case GF_CLI_STATUS_TASKS:
- cli_print_volume_status_tasks (dict);
- goto cont;
- break;
- default:
- break;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
+ cli_out("Status of volume: %s", volname);
- ret = dict_get_int32 (dict, "brick-index-max", &brick_index_max);
- if (ret)
- goto out;
+ if ((cmd & GF_CLI_STATUS_DETAIL) == 0) {
+ cli_out("%-*s %s %s %s %s", CLI_VOL_STATUS_BRICK_LEN,
+ "Gluster process", "TCP Port", "RDMA Port", "Online", "Pid");
+ cli_print_line(CLI_BRICK_STATUS_LINE_LEN);
+ }
- ret = dict_get_int32 (dict, "other-count", &other_count);
- if (ret)
- goto out;
+ status.brick = GF_MALLOC(PATH_MAX + 256, gf_common_mt_strdup);
+ if (!status.brick) {
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
- index_max = brick_index_max + other_count;
+ for (i = 0; i <= index_max; i++) {
+ status.rdma_port = 0;
- ret = dict_get_int32 (dict, "type", &type);
+ snprintf(key, sizeof(key), "brick%d.hostname", i);
+ ret = dict_get_str(dict, key, &hostname);
if (ret)
- goto out;
+ continue;
- ret = dict_get_int32 (dict, "hot_brick_count", &hot_brick_count);
+ snprintf(key, sizeof(key), "brick%d.path", i);
+ ret = dict_get_str(dict, key, &path);
if (ret)
- goto out;
-
- cli_out ("Status of volume: %s", volname);
+ continue;
- if ((cmd & GF_CLI_STATUS_DETAIL) == 0) {
- cli_out ("%-*s %s %s %s %s", CLI_VOL_STATUS_BRICK_LEN,
- "Gluster process", "TCP Port", "RDMA Port",
- "Online", "Pid");
- cli_print_line (CLI_BRICK_STATUS_LINE_LEN);
- }
- if (type == GF_CLUSTER_TYPE_TIER) {
- cli_out ("Hot Bricks:");
+ /* Brick/not-brick is handled separately here as all
+ * types of nodes are contained in the default output
+ */
+ status.brick[0] = '\0';
+ if (!strcmp(hostname, "NFS Server") ||
+ !strcmp(hostname, "Self-heal Daemon") ||
+ !strcmp(hostname, "Quota Daemon") ||
+ !strcmp(hostname, "Snapshot Daemon") ||
+ !strcmp(hostname, "Scrubber Daemon") ||
+ !strcmp(hostname, "Bitrot Daemon"))
+ snprintf(status.brick, PATH_MAX + 255, "%s on %s", hostname, path);
+ else {
+ snprintf(key, sizeof(key), "brick%d.rdma_port", i);
+ ret = dict_get_int32(dict, key, &(status.rdma_port));
+ if (ret)
+ continue;
+ snprintf(status.brick, PATH_MAX + 255, "Brick %s:%s", hostname,
+ path);
}
- for (i = 0; i <= index_max; i++) {
-
- if (type == GF_CLUSTER_TYPE_TIER && i == hot_brick_count) {
- cli_out ("Cold Bricks:");
- }
- status.rdma_port = 0;
-
- 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 separately 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") ||
- !strcmp (hostname, "Quota Daemon") ||
- !strcmp (hostname, "Snapshot Daemon") ||
- !strcmp (hostname, "Scrubber Daemon") ||
- !strcmp (hostname, "Bitrot Daemon"))
- snprintf (status.brick, PATH_MAX + 255, "%s on %s",
- hostname, path);
- else {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.rdma_port", i);
- ret = dict_get_int32 (dict, key, &(status.rdma_port));
- if (ret)
- continue;
- snprintf (status.brick, PATH_MAX + 255, "Brick %s:%s",
- hostname, path);
- }
+ 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.port", i);
- ret = dict_get_int32 (dict, key, &(status.port));
- if (ret)
- continue;
+ 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.status", i);
- ret = dict_get_int32 (dict, key, &(status.online));
- if (ret)
- continue;
+ 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);
- 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);
- }
+ 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 (" ");
- if ((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE)
- cli_print_volume_status_tasks (dict);
+ /* Allocatated memory using gf_asprintf*/
+ GF_FREE(status.pid_str);
+ }
+ cli_out(" ");
+
+ if ((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE)
+ cli_print_volume_status_tasks(dict);
cont:
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- if (dict)
- dict_unref (dict);
- GF_FREE (status.brick);
- if (local && wipe_local) {
- cli_local_wipe (local);
- }
+ if (dict)
+ dict_unref(dict);
+ GF_FREE(status.brick);
+ if (local && wipe_local) {
+ cli_local_wipe(local);
+ }
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int32_t
-gf_cli_status_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_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;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = -1;
+ dict_t *dict = NULL;
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_status_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_STATUS_VOLUME, this, cli_rpc_prog,
- NULL);
- out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning: %d", ret);
- return ret;
+ ret = cli_to_glusterd(&req, frame, gf_cli_status_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_STATUS_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ GF_FREE(req.dict.dict_val);
+ 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;
- void *vol_dict = NULL;
- dict_t *dict = NULL;
- cli_local_t *local = NULL;
-
- if (frame->local) {
- local = frame->local;
- local->all = _gf_true;
- } else
- goto out;
+static 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;
+ void *vol_dict = NULL;
+ dict_t *dict = NULL;
+ cli_local_t *local = NULL;
- ret = dict_get_uint32 (local->dict, "cmd", &cmd);
- if (ret)
- goto out;
+ if (!frame)
+ goto out;
+ if (!frame->local)
+ goto out;
- ret = gf_cli_status_volume (frame, this, data);
- if (ret)
- goto out;
+ local = frame->local;
- ret = dict_get_ptr (local->dict, "rsp-dict", &vol_dict);
- if (ret)
- goto out;
+ ret = dict_get_uint32(local->dict, "cmd", &cmd);
+ if (ret)
+ goto out;
- ret = dict_get_int32 ((dict_t *)vol_dict, "vol_count", &vol_count);
- if (ret) {
- cli_err ("Failed to get names of volumes");
- goto out;
- }
+ local->all = _gf_true;
- /* remove the "all" flag in cmd */
- cmd &= ~GF_CLI_STATUS_ALL;
- cmd |= GF_CLI_STATUS_VOL;
+ ret = gf_cli_status_volume(frame, this, data);
- if (global_state->mode & GLUSTER_MODE_XML) {
- //TODO: Pass proper op_* values
- ret = cli_xml_output_vol_status_begin (local, 0,0, NULL);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- goto out;
- }
- }
+ if (ret)
+ goto out;
- if (vol_count == 0 && !(global_state->mode & GLUSTER_MODE_XML)) {
- cli_err ("No volumes present");
- ret = 0;
- goto out;
- }
+ ret = dict_get_ptr(local->dict, "rsp-dict", &vol_dict);
+ if (ret)
+ goto out;
- for (i = 0; i < vol_count; i++) {
+ ret = dict_get_int32_sizen((dict_t *)vol_dict, "vol_count", &vol_count);
+ if (ret) {
+ cli_err("Failed to get names of volumes");
+ goto out;
+ }
- dict = dict_new ();
- if (!dict)
- goto out;
+ /* remove the "all" flag in cmd */
+ cmd &= ~GF_CLI_STATUS_ALL;
+ cmd |= GF_CLI_STATUS_VOL;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "vol%d", i);
- ret = dict_get_str (vol_dict, key, &volname);
- if (ret)
- goto out;
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ // TODO: Pass proper op_* values
+ ret = cli_xml_output_vol_status_begin(local, 0, 0, NULL);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ goto xml_end;
+ }
+ }
- ret = dict_set_str (dict, "volname", volname);
- if (ret)
- goto out;
+ if (vol_count == 0 && !(global_state->mode & GLUSTER_MODE_XML)) {
+ cli_err("No volumes present");
+ ret = 0;
+ goto out;
+ }
- ret = dict_set_uint32 (dict, "cmd", cmd);
- if (ret)
- goto out;
+ for (i = 0; i < vol_count; i++) {
+ dict = dict_new();
+ if (!dict)
+ goto out;
- ret = gf_cli_status_volume (frame, this, dict);
- if (ret)
- goto out;
+ ret = snprintf(key, sizeof(key), "vol%d", i);
+ ret = dict_get_strn(vol_dict, key, ret, &volname);
+ if (ret)
+ goto out;
- dict_unref (dict);
- }
+ ret = dict_set_str_sizen(dict, "volname", volname);
+ if (ret)
+ goto out;
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_status_end (local);
- }
+ ret = dict_set_uint32(dict, "cmd", cmd);
+ if (ret)
+ goto out;
- out:
+ ret = gf_cli_status_volume(frame, this, dict);
if (ret)
- gf_log ("cli", GF_LOG_ERROR, "status all failed");
+ goto out;
+
+ dict_unref(dict);
+ }
- if (vol_dict)
- dict_unref (vol_dict);
+xml_end:
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_status_end(local);
+ }
- if (ret && dict)
- dict_unref (dict);
+out:
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, "status all failed");
- if (local)
- cli_local_wipe (local);
+ if (vol_dict)
+ dict_unref(vol_dict);
- if (frame)
- frame->local = NULL;
+ if (ret && dict)
+ dict_unref(dict);
- return ret;
+ if (local)
+ cli_local_wipe(local);
+
+ if (frame)
+ frame->local = NULL;
+
+ return ret;
}
static int
-gf_cli_mount_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+gf_cli_mount_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- gf1_cli_mount_rsp rsp = {0,};
- int ret = -1;
+ gf1_cli_mount_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
- if (-1 == req->rpc_status) {
- goto out;
- }
+ GF_ASSERT(myframe);
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_mount_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- gf_log ("cli", GF_LOG_INFO, "Received resp to mount");
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf1_cli_mount_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
- 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;
- }
+ 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;
+ cli_cmd_broadcast_response(ret);
+ if (rsp.path) {
+ free(rsp.path);
+ }
+ return ret;
}
-int32_t
-gf_cli_mount (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_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;
+ 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;
+ if (!frame || !this || !data)
+ goto out;
- label = dataa[0];
- dict = dataa[1];
+ 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;
- }
+ 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 (NULL, &req, frame, cli_rpc_prog,
- GLUSTER_CLI_MOUNT, NULL,
- this, gf_cli_mount_cbk,
- (xdrproc_t)xdr_gf1_cli_mount_req);
+ ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_MOUNT,
+ NULL, this, gf_cli_mount_cbk,
+ (xdrproc_t)xdr_gf1_cli_mount_req);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
static int
-gf_cli_umount_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
+gf_cli_umount_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- gf1_cli_umount_rsp rsp = {0,};
- int ret = -1;
+ gf1_cli_umount_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
- if (-1 == req->rpc_status) {
- goto out;
- }
+ GF_ASSERT(myframe);
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf1_cli_umount_rsp);
- if (ret < 0) {
- gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
- gf_log ("cli", GF_LOG_INFO, "Received resp to mount");
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf1_cli_umount_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
- if (rsp.op_ret == 0)
- ret = 0;
- else {
- cli_err ("umount failed");
- ret = -1;
- }
+ 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;
+ cli_cmd_broadcast_response(ret);
+ return ret;
}
-int32_t
-gf_cli_umount (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_umount(call_frame_t *frame, xlator_t *this, void *data)
{
- gf1_cli_umount_req req = {0,};
- int ret = -1;
- dict_t *dict = NULL;
+ gf1_cli_umount_req req = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
- if (!frame || !this || !data)
- goto out;
+ if (!frame || !this || !data)
+ goto out;
- dict = data;
+ dict = data;
- ret = dict_get_str (dict, "path", &req.path);
- if (ret == 0)
- ret = dict_get_int32 (dict, "lazy", &req.lazy);
+ ret = dict_get_str_sizen(dict, "path", &req.path);
+ if (ret == 0)
+ ret = dict_get_int32_sizen(dict, "lazy", &req.lazy);
- if (ret) {
- ret = -1;
- goto out;
- }
+ if (ret) {
+ ret = -1;
+ goto out;
+ }
- ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog,
- GLUSTER_CLI_UMOUNT, NULL,
- this, gf_cli_umount_cbk,
- (xdrproc_t)xdr_gf1_cli_umount_req);
+ ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog, GLUSTER_CLI_UMOUNT,
+ NULL, this, gf_cli_umount_cbk,
+ (xdrproc_t)xdr_gf1_cli_umount_req);
- out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+out:
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-void
-cmd_heal_volume_statistics_out (dict_t *dict, int brick)
-{
-
- uint64_t num_entries = 0;
- int ret = 0;
- char key[256] = {0};
- char *hostname = NULL;
- uint64_t i = 0;
- uint64_t healed_count = 0;
- uint64_t split_brain_count = 0;
- uint64_t heal_failed_count = 0;
- char *start_time_str = NULL;
- char *end_time_str = NULL;
- char *crawl_type = NULL;
- int progress = -1;
-
- snprintf (key, sizeof key, "%d-hostname", brick);
- ret = dict_get_str (dict, key, &hostname);
+static void
+cmd_heal_volume_statistics_out(dict_t *dict, int brick)
+{
+ uint64_t num_entries = 0;
+ int ret = 0;
+ char key[256] = {0};
+ char *hostname = NULL;
+ uint64_t i = 0;
+ uint64_t healed_count = 0;
+ uint64_t split_brain_count = 0;
+ uint64_t heal_failed_count = 0;
+ char *start_time_str = NULL;
+ char *end_time_str = NULL;
+ char *crawl_type = NULL;
+ int progress = -1;
+
+ snprintf(key, sizeof key, "%d-hostname", brick);
+ ret = dict_get_str(dict, key, &hostname);
+ if (ret)
+ goto out;
+ cli_out("------------------------------------------------");
+ cli_out("\nCrawl statistics for brick no %d", brick);
+ cli_out("Hostname of brick %s", hostname);
+
+ snprintf(key, sizeof key, "statistics-%d-count", brick);
+ ret = dict_get_uint64(dict, key, &num_entries);
+ if (ret)
+ goto out;
+
+ for (i = 0; i < num_entries; i++) {
+ snprintf(key, sizeof key, "statistics_crawl_type-%d-%" PRIu64, brick,
+ i);
+ ret = dict_get_str(dict, key, &crawl_type);
if (ret)
- goto out;
- cli_out ("------------------------------------------------");
- cli_out ("\nCrawl statistics for brick no %d", brick);
- cli_out ("Hostname of brick %s", hostname);
+ goto out;
- snprintf (key, sizeof key, "statistics-%d-count", brick);
- ret = dict_get_uint64 (dict, key, &num_entries);
+ snprintf(key, sizeof key, "statistics_healed_cnt-%d-%" PRIu64, brick,
+ i);
+ ret = dict_get_uint64(dict, key, &healed_count);
if (ret)
- goto out;
-
- for (i = 0; i < num_entries; i++)
- {
- snprintf (key, sizeof key, "statistics_crawl_type-%d-%"PRIu64,
- brick, i);
- ret = dict_get_str (dict, key, &crawl_type);
- if (ret)
- goto out;
-
- snprintf (key, sizeof key, "statistics_healed_cnt-%d-%"PRIu64,
- brick,i);
- ret = dict_get_uint64 (dict, key, &healed_count);
- if (ret)
- goto out;
-
- snprintf (key, sizeof key, "statistics_sb_cnt-%d-%"PRIu64,
- brick, i);
- ret = dict_get_uint64 (dict, key, &split_brain_count);
- if (ret)
- goto out;
- snprintf (key, sizeof key, "statistics_heal_failed_cnt-%d-%"PRIu64,
- brick, i);
- ret = dict_get_uint64 (dict, key, &heal_failed_count);
- if (ret)
- goto out;
- snprintf (key, sizeof key, "statistics_strt_time-%d-%"PRIu64,
- brick, i);
- ret = dict_get_str (dict, key, &start_time_str);
- if (ret)
- goto out;
- snprintf (key, sizeof key, "statistics_end_time-%d-%"PRIu64,
- brick, i);
- ret = dict_get_str (dict, key, &end_time_str);
- if (ret)
- goto out;
- snprintf (key, sizeof key, "statistics_inprogress-%d-%"PRIu64,
- brick, i);
- ret = dict_get_int32 (dict, key, &progress);
- if (ret)
- goto out;
-
- cli_out ("\nStarting time of crawl: %s", start_time_str);
- if (progress == 1)
- cli_out ("Crawl is in progress");
- else
- cli_out ("Ending time of crawl: %s", end_time_str);
-
- cli_out ("Type of crawl: %s", crawl_type);
- cli_out ("No. of entries healed: %"PRIu64,
- healed_count);
- cli_out ("No. of entries in split-brain: %"PRIu64,
- split_brain_count);
- cli_out ("No. of heal failed entries: %"PRIu64,
- heal_failed_count);
-
- }
-
-
-out:
- return;
-}
+ goto out;
-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};
- char *shd_status = NULL;
-
- snprintf (key, sizeof key, "%d-hostname", brick);
- ret = dict_get_str (dict, key, &hostname);
+ snprintf(key, sizeof key, "statistics_sb_cnt-%d-%" PRIu64, brick, i);
+ ret = dict_get_uint64(dict, key, &split_brain_count);
if (ret)
- goto out;
- snprintf (key, sizeof key, "%d-path", brick);
- ret = dict_get_str (dict, key, &path);
+ goto out;
+ snprintf(key, sizeof key, "statistics_heal_failed_cnt-%d-%" PRIu64,
+ brick, i);
+ ret = dict_get_uint64(dict, key, &heal_failed_count);
if (ret)
- goto out;
- cli_out ("\nBrick %s:%s", hostname, path);
-
- snprintf (key, sizeof key, "%d-status", brick);
- ret = dict_get_str (dict, key, &status);
- if (status && strlen (status))
- cli_out ("Status: %s", status);
+ goto out;
+ snprintf(key, sizeof key, "statistics_strt_time-%d-%" PRIu64, brick, i);
+ ret = dict_get_str(dict, key, &start_time_str);
+ if (ret)
+ goto out;
+ snprintf(key, sizeof key, "statistics_end_time-%d-%" PRIu64, brick, i);
+ ret = dict_get_str(dict, key, &end_time_str);
+ if (ret)
+ goto out;
+ snprintf(key, sizeof key, "statistics_inprogress-%d-%" PRIu64, brick,
+ i);
+ ret = dict_get_int32(dict, key, &progress);
+ if (ret)
+ goto out;
- snprintf (key, sizeof key, "%d-shd-status",brick);
- ret = dict_get_str (dict, key, &shd_status);
+ cli_out("\nStarting time of crawl: %s", start_time_str);
+ if (progress == 1)
+ cli_out("Crawl is in progress");
+ else
+ cli_out("Ending time of crawl: %s", end_time_str);
- if(!shd_status)
- {
- snprintf (key, sizeof key, "%d-count", brick);
- ret = dict_get_uint64 (dict, key, &num_entries);
- cli_out ("Number of entries: %"PRIu64, num_entries);
-
-
- 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);
- }
- }
- }
+ cli_out("Type of crawl: %s", crawl_type);
+ cli_out("No. of entries healed: %" PRIu64, healed_count);
+ cli_out("No. of entries in split-brain: %" PRIu64, split_brain_count);
+ cli_out("No. of heal failed entries: %" PRIu64, heal_failed_count);
+ }
out:
- return;
+ return;
}
+static void
+cmd_heal_volume_brick_out(dict_t *dict, int brick)
+{
+ uint64_t num_entries = 0;
+ int ret = 0;
+ char key[64] = {0};
+ char *hostname = NULL;
+ char *path = NULL;
+ char *status = NULL;
+ uint64_t i = 0;
+ uint32_t time = 0;
+ char timestr[GF_TIMESTR_SIZE] = {0};
+ char *shd_status = NULL;
+
+ 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-status", brick);
+ ret = dict_get_str(dict, key, &status);
+ if (status && status[0] != '\0')
+ cli_out("Status: %s", status);
+
+ snprintf(key, sizeof key, "%d-shd-status", brick);
+ ret = dict_get_str(dict, key, &shd_status);
+
+ if (!shd_status) {
+ snprintf(key, sizeof key, "%d-count", brick);
+ ret = dict_get_uint64(dict, key, &num_entries);
+ cli_out("Number of entries: %" PRIu64, num_entries);
+
+ 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 (ret || !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;
+}
-void
-cmd_heal_volume_statistics_heal_count_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;
- char *shd_status = NULL;
-
- 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);
+static void
+cmd_heal_volume_statistics_heal_count_out(dict_t *dict, int brick)
+{
+ uint64_t num_entries = 0;
+ int ret = 0;
+ char key[64] = {0};
+ char *hostname = NULL;
+ char *path = NULL;
+ char *status = NULL;
+ char *shd_status = NULL;
+
+ 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-status", brick);
+ ret = dict_get_str(dict, key, &status);
+ if (status && strlen(status))
+ cli_out("Status: %s", status);
+
+ snprintf(key, sizeof key, "%d-shd-status", brick);
+ ret = dict_get_str(dict, key, &shd_status);
+
+ if (!shd_status) {
+ snprintf(key, sizeof key, "%d-hardlinks", brick);
+ ret = dict_get_uint64(dict, key, &num_entries);
if (ret)
- goto out;
- cli_out ("\nBrick %s:%s", hostname, path);
-
- snprintf (key, sizeof key, "%d-status", brick);
- ret = dict_get_str (dict, key, &status);
- if (status && strlen (status))
- cli_out ("Status: %s", status);
-
- snprintf (key, sizeof key, "%d-shd-status",brick);
- ret = dict_get_str (dict, key, &shd_status);
-
- if(!shd_status)
- {
- snprintf (key, sizeof key, "%d-hardlinks", brick);
- ret = dict_get_uint64 (dict, key, &num_entries);
- if (ret)
- cli_out ("No gathered input for this brick");
- else
- cli_out ("Number of entries: %"PRIu64, num_entries);
-
-
- }
+ cli_out("No gathered input for this brick");
+ else
+ cli_out("Number of entries: %" PRIu64, num_entries);
+ }
out:
- return;
+ return;
}
-int
-gf_is_cli_heal_get_command (gf_xl_afr_op_t heal_op)
-{
- /* If the command is get command value is 1 otherwise 0, for
- invalid commands -1 */
- int get_cmds[GF_SHD_OP_HEAL_DISABLE + 1] = {
- [GF_SHD_OP_INVALID] = -1,
- [GF_SHD_OP_HEAL_INDEX] = 0,
- [GF_SHD_OP_HEAL_FULL] = 0,
- [GF_SHD_OP_INDEX_SUMMARY] = 1,
- [GF_SHD_OP_HEALED_FILES] = 1,
- [GF_SHD_OP_HEAL_FAILED_FILES] = 1,
- [GF_SHD_OP_SPLIT_BRAIN_FILES] = 1,
- [GF_SHD_OP_STATISTICS] = 1,
- [GF_SHD_OP_STATISTICS_HEAL_COUNT] = 1,
- [GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA] = 1,
- [GF_SHD_OP_HEAL_ENABLE] = 0,
- [GF_SHD_OP_HEAL_DISABLE] = 0,
- };
-
- if (heal_op > GF_SHD_OP_INVALID && heal_op <= GF_SHD_OP_HEAL_DISABLE)
- return get_cmds[heal_op] == 1;
- return _gf_false;
+static int
+gf_is_cli_heal_get_command(gf_xl_afr_op_t heal_op)
+{
+ /* If the command is get command value is 1 otherwise 0, for
+ invalid commands -1 */
+ static int get_cmds[GF_SHD_OP_HEAL_DISABLE + 1] = {
+ [GF_SHD_OP_INVALID] = -1,
+ [GF_SHD_OP_HEAL_INDEX] = 0,
+ [GF_SHD_OP_HEAL_FULL] = 0,
+ [GF_SHD_OP_INDEX_SUMMARY] = 1,
+ [GF_SHD_OP_SPLIT_BRAIN_FILES] = 1,
+ [GF_SHD_OP_STATISTICS] = 1,
+ [GF_SHD_OP_STATISTICS_HEAL_COUNT] = 1,
+ [GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA] = 1,
+ [GF_SHD_OP_HEAL_ENABLE] = 0,
+ [GF_SHD_OP_HEAL_DISABLE] = 0,
+ };
+
+ if (heal_op > GF_SHD_OP_INVALID && heal_op <= GF_SHD_OP_HEAL_DISABLE)
+ return get_cmds[heal_op] == 1;
+ return _gf_false;
}
int
-gf_cli_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_SHD_OP_INVALID;
- char *operation = NULL;
- char *substr = NULL;
- char *heal_op_str = NULL;
-
- if (-1 == req->rpc_status) {
- goto out;
- }
-
- frame = myframe;
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- if (frame)
- local = frame->local;
-
- 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 (frame->this->name, GF_LOG_ERROR, "failed to get volname");
- goto out;
- }
-
- gf_log ("cli", GF_LOG_INFO, "Received resp to heal volume");
-
- operation = "Gathering ";
- substr = "";
- switch (heal_op) {
- case GF_SHD_OP_HEAL_INDEX:
- operation = "Launching heal operation ";
- heal_op_str = "to perform index self heal";
- substr = "\nUse heal info commands to check"
- " status";
- break;
- case GF_SHD_OP_HEAL_FULL:
- operation = "Launching heal operation ";
- heal_op_str = "to perform full self heal";
- substr = "\nUse heal info commands to check"
- " status";
- break;
- case GF_SHD_OP_INDEX_SUMMARY:
- heal_op_str = "list of entries to be healed";
- break;
- case GF_SHD_OP_HEALED_FILES:
- heal_op_str = "list of healed entries";
- break;
- case GF_SHD_OP_HEAL_FAILED_FILES:
- heal_op_str = "list of heal failed entries";
- break;
- case GF_SHD_OP_SPLIT_BRAIN_FILES:
- heal_op_str = "list of split brain entries";
- break;
- case GF_SHD_OP_STATISTICS:
- heal_op_str = "crawl statistics";
- break;
- case GF_SHD_OP_STATISTICS_HEAL_COUNT:
- heal_op_str = "count of entries to be healed";
- break;
- case GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA:
- heal_op_str = "count of entries to be healed per replica";
- break;
- /* The below 2 cases are never hit; they're coded only to make
- * compiler warnings go away.*/
- case GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE:
- case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK:
- break;
-
- case GF_SHD_OP_INVALID:
- heal_op_str = "invalid heal op";
- break;
- case GF_SHD_OP_HEAL_ENABLE:
- operation = "";
- heal_op_str = "Enable heal";
- break;
- case GF_SHD_OP_HEAL_DISABLE:
- operation = "";
- heal_op_str = "Disable heal";
- break;
- }
-
- if (rsp.op_ret) {
- if (strcmp (rsp.op_errstr, "")) {
- cli_err ("%s", rsp.op_errstr);
- } else {
- cli_err ("%s%s on volume %s has been unsuccessful",
- operation, heal_op_str, volname);
- }
-
- ret = rsp.op_ret;
- goto out;
- } else {
- cli_out ("%s%s on volume %s has been successful %s", operation,
- heal_op_str, volname, substr);
+gf_cli_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 *dict = NULL;
+ int brick_count = 0;
+ int i = 0;
+ gf_xl_afr_op_t heal_op = GF_SHD_OP_INVALID;
+ const char *operation = NULL;
+ const char *substr = NULL;
+ const char *heal_op_str = NULL;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ frame = myframe;
+
+ GF_ASSERT(frame->local);
+
+ local = frame->local;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ ret = dict_get_int32_sizen(local->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, XML_ERROR);
+ // goto out;
+ // }
+ //#endif
+
+ ret = dict_get_str_sizen(local->dict, "volname", &volname);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR, "failed to get volname");
+ goto out;
+ }
+
+ gf_log("cli", GF_LOG_INFO, "Received resp to heal volume");
+
+ operation = "Gathering ";
+ substr = "";
+ switch (heal_op) {
+ case GF_SHD_OP_HEAL_INDEX:
+ operation = "Launching heal operation ";
+ heal_op_str = "to perform index self heal";
+ substr = "\nUse heal info commands to check status.";
+ break;
+ case GF_SHD_OP_HEAL_FULL:
+ operation = "Launching heal operation ";
+ heal_op_str = "to perform full self heal";
+ substr = "\nUse heal info commands to check status.";
+ break;
+ case GF_SHD_OP_INDEX_SUMMARY:
+ heal_op_str = "list of entries to be healed";
+ break;
+ case GF_SHD_OP_SPLIT_BRAIN_FILES:
+ heal_op_str = "list of split brain entries";
+ break;
+ case GF_SHD_OP_STATISTICS:
+ heal_op_str = "crawl statistics";
+ break;
+ case GF_SHD_OP_STATISTICS_HEAL_COUNT:
+ heal_op_str = "count of entries to be healed";
+ break;
+ case GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA:
+ heal_op_str = "count of entries to be healed per replica";
+ break;
+ case GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE:
+ case GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME:
+ case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK:
+ case GF_SHD_OP_HEAL_SUMMARY:
+ case GF_SHD_OP_HEALED_FILES:
+ case GF_SHD_OP_HEAL_FAILED_FILES:
+ /* These cases are never hit; they're coded just to silence the
+ * compiler warnings.*/
+ break;
+
+ case GF_SHD_OP_INVALID:
+ heal_op_str = "invalid heal op";
+ break;
+ case GF_SHD_OP_HEAL_ENABLE:
+ operation = "";
+ heal_op_str = "Enable heal";
+ break;
+ case GF_SHD_OP_HEAL_DISABLE:
+ operation = "";
+ heal_op_str = "Disable heal";
+ break;
+ case GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE:
+ operation = "";
+ heal_op_str = "Enable granular entry heal";
+ break;
+ case GF_SHD_OP_GRANULAR_ENTRY_HEAL_DISABLE:
+ operation = "";
+ heal_op_str = "Disable granular entry heal";
+ break;
+ }
+
+ if (rsp.op_ret) {
+ if (strcmp(rsp.op_errstr, "")) {
+ cli_err("%s%s on volume %s has been unsuccessful:", operation,
+ heal_op_str, volname);
+ cli_err("%s", rsp.op_errstr);
}
-
ret = rsp.op_ret;
- if (!gf_is_cli_heal_get_command (heal_op))
- 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_err ("All bricks of volume %s are down.", volname);
- goto out;
- }
-
- switch (heal_op) {
+ goto out;
+ } else {
+ cli_out("%s%s on volume %s has been successful %s", operation,
+ heal_op_str, volname, substr);
+ }
+
+ ret = rsp.op_ret;
+ if (!gf_is_cli_heal_get_command(heal_op))
+ 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, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
+
+ ret = dict_get_int32_sizen(dict, "count", &brick_count);
+ if (ret)
+ goto out;
+
+ if (!brick_count) {
+ cli_err("All bricks of volume %s are down.", volname);
+ ret = -1;
+ goto out;
+ }
+
+ switch (heal_op) {
case GF_SHD_OP_STATISTICS:
- for (i = 0; i < brick_count; i++)
- cmd_heal_volume_statistics_out (dict, i);
- break;
+ for (i = 0; i < brick_count; i++)
+ cmd_heal_volume_statistics_out(dict, i);
+ break;
case GF_SHD_OP_STATISTICS_HEAL_COUNT:
case GF_SHD_OP_STATISTICS_HEAL_COUNT_PER_REPLICA:
- for (i = 0; i < brick_count; i++)
- cmd_heal_volume_statistics_heal_count_out (dict,
- i);
- break;
+ for (i = 0; i < brick_count; i++)
+ cmd_heal_volume_statistics_heal_count_out(dict, i);
+ break;
case GF_SHD_OP_INDEX_SUMMARY:
- case GF_SHD_OP_HEALED_FILES:
- case GF_SHD_OP_HEAL_FAILED_FILES:
case GF_SHD_OP_SPLIT_BRAIN_FILES:
- for (i = 0; i < brick_count; i++)
- cmd_heal_volume_brick_out (dict, i);
- break;
+ for (i = 0; i < brick_count; i++)
+ cmd_heal_volume_brick_out(dict, i);
+ break;
default:
- break;
- }
+ break;
+ }
- ret = rsp.op_ret;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- free (rsp.op_errstr);
- if (dict)
- dict_unref (dict);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ if (dict)
+ dict_unref(dict);
+ return ret;
}
-int32_t
-gf_cli_heal_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_heal_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- int ret = 0;
- dict_t *dict = NULL;
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = 0;
+ dict_t *dict = NULL;
- if (!frame || !this || !data) {
- ret = -1;
- goto out;
- }
-
- dict = data;
+ dict = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_heal_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, dict,
- GLUSTER_CLI_HEAL_VOLUME, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(&req, frame, gf_cli_heal_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, dict,
+ GLUSTER_CLI_HEAL_VOLUME, this, cli_rpc_prog, NULL);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- GF_FREE (req.dict.dict_val);
+ GF_FREE(req.dict.dict_val);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- 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 (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;
- }
+static int32_t
+gf_cli_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] = "Volume statedump successful";
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status)
+ goto out;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+ gf_log("cli", GF_LOG_DEBUG, "Received response to statedump");
+ if (rsp.op_ret)
+ snprintf(msg, sizeof(msg), "%s", rsp.op_errstr);
+
+ 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, XML_ERROR);
+ goto out;
+ }
- if (rsp.op_ret)
- cli_err ("volume statedump: failed: %s", msg);
- else
- cli_out ("volume statedump: success");
- ret = rsp.op_ret;
+ if (rsp.op_ret)
+ cli_err("volume statedump: failed: %s", msg);
+ else
+ cli_out("volume statedump: success");
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int32_t
-gf_cli_statedump_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_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;
+ gf_cli_req req = {{
+ 0,
+ }};
+ dict_t *options = NULL;
+ int ret = -1;
- options = data;
+ options = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_statedump_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, options,
- GLUSTER_CLI_STATEDUMP_VOLUME, this, cli_rpc_prog,
- NULL);
+ ret = cli_to_glusterd(
+ &req, frame, gf_cli_statedump_volume_cbk, (xdrproc_t)xdr_gf_cli_req,
+ options, GLUSTER_CLI_STATEDUMP_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- GF_FREE (req.dict.dict_val);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-gf_cli_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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
+static int32_t
+gf_cli_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;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status)
+ goto out;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ 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, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
+
+ 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, XML_ERROR);
+ goto out;
+ }
+
+ if (rsp.op_ret)
+ cli_err("%s", rsp.op_errstr);
+ else {
+ ret = dict_get_int32_sizen(dict, "count", &vol_count);
+ if (ret)
+ 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 (vol_count == 0) {
+ cli_err("No volumes present in cluster");
+ goto out;
}
-
- 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");
+ for (i = 0; i < vol_count; i++) {
+ ret = snprintf(key, sizeof(key), "volume%d", i);
+ ret = dict_get_strn(dict, key, ret, &volname);
+ if (ret)
goto out;
+ cli_out("%s", volname);
}
+ }
- 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_err ("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;
+ ret = rsp.op_ret;
out:
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+
+ if (dict)
+ dict_unref(dict);
+ return ret;
}
-int32_t
-gf_cli_list_volume (call_frame_t *frame, xlator_t *this, void *data)
+static int32_t
+gf_cli_list_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- int ret = -1;
- gf_cli_req req = {{0,}};
-
- if (!frame || !this)
- goto out;
+ int ret = -1;
+ gf_cli_req req = {{
+ 0,
+ }};
- ret = cli_cmd_submit (NULL, &req, frame, cli_rpc_prog,
- GLUSTER_CLI_LIST_VOLUME, NULL,
- this, gf_cli_list_volume_cbk,
- (xdrproc_t)xdr_gf_cli_req);
-
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ ret = cli_cmd_submit(NULL, &req, frame, cli_rpc_prog,
+ GLUSTER_CLI_LIST_VOLUME, NULL, this,
+ gf_cli_list_volume_cbk, (xdrproc_t)xdr_gf_cli_req);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+ return ret;
}
-int32_t
-gf_cli_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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
+static int32_t
+gf_cli_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;
+ dict_t *dict = NULL;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status)
+ goto out;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ 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_err("Possibly no locks cleared");
+ ret = 0;
+ 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_err ("Possibly no locks cleared");
- ret = 0;
- goto out;
- }
-
- dict = dict_new ();
+ 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;
- }
+ if (!dict) {
+ ret = -1;
+ 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_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
- 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);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ 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;
+ ret = rsp.op_ret;
out:
- if (dict)
- dict_unref (dict);
- cli_cmd_broadcast_response (ret);
- return ret;
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int32_t
-gf_cli_clearlocks_volume (call_frame_t *frame, xlator_t *this,
- void *data)
+static int32_t
+gf_cli_clearlocks_volume(call_frame_t *frame, xlator_t *this, void *data)
{
- gf_cli_req req = {{0,}};
- dict_t *options = NULL;
- int ret = -1;
+ gf_cli_req req = {{
+ 0,
+ }};
+ dict_t *options = NULL;
+ int ret = -1;
- if (!frame || !this || !data)
- goto out;
-
- options = data;
+ options = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_clearlocks_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, options,
- GLUSTER_CLI_CLRLOCKS_VOLUME, this, cli_rpc_prog,
- NULL);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ ret = cli_to_glusterd(
+ &req, frame, gf_cli_clearlocks_volume_cbk, (xdrproc_t)xdr_gf_cli_req,
+ options, GLUSTER_CLI_CLRLOCKS_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- GF_FREE (req.dict.dict_val);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-cli_snapshot_remove_reply (gf_cli_rsp *rsp, dict_t *dict, call_frame_t *frame)
+static int32_t
+cli_snapshot_remove_reply(gf_cli_rsp *rsp, dict_t *dict, call_frame_t *frame)
{
- int32_t ret = -1;
- char *snap_name = NULL;
- int32_t delete_cmd = -1;
- cli_local_t *local = NULL;
+ int32_t ret = -1;
+ char *snap_name = NULL;
+ int32_t delete_cmd = -1;
+ cli_local_t *local = NULL;
- GF_ASSERT (frame);
- GF_ASSERT (rsp);
- GF_ASSERT (dict);
+ GF_ASSERT(frame);
+ GF_ASSERT(rsp);
+ GF_ASSERT(dict);
- local = frame->local;
+ local = frame->local;
- ret = dict_get_int32 (dict, "sub-cmd", &delete_cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not get sub-cmd");
- goto end;
- }
+ ret = dict_get_int32_sizen(dict, "sub-cmd", &delete_cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not get sub-cmd");
+ goto end;
+ }
- if ((global_state->mode & GLUSTER_MODE_XML) &&
- (delete_cmd == GF_SNAP_DELETE_TYPE_SNAP)) {
- ret = cli_xml_output_snap_delete_begin (local, rsp->op_ret,
- rsp->op_errno,
- rsp->op_errstr);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for delete");
- goto end;
- }
+ if ((global_state->mode & GLUSTER_MODE_XML) &&
+ (delete_cmd == GF_SNAP_DELETE_TYPE_SNAP)) {
+ ret = cli_xml_output_snap_delete_begin(local, rsp->op_ret,
+ rsp->op_errno, rsp->op_errstr);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create xml output for delete");
+ goto end;
+ }
+ }
+
+ if (rsp->op_ret && !(global_state->mode & GLUSTER_MODE_XML)) {
+ cli_err("snapshot delete: failed: %s",
+ rsp->op_errstr ? rsp->op_errstr
+ : "Please check log file for details");
+ ret = rsp->op_ret;
+ goto out;
+ }
+
+ if (delete_cmd == GF_SNAP_DELETE_TYPE_ALL ||
+ delete_cmd == GF_SNAP_DELETE_TYPE_VOL) {
+ local = ((call_frame_t *)frame)->local;
+ if (!local) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "frame->local is NULL");
+ goto out;
}
+ /* During first call back of snapshot delete of type
+ * ALL and VOL, We will get the snapcount and snapnames.
+ * Hence to make the subsequent rpc calls for individual
+ * snapshot delete, We need to save it in local dictionary.
+ */
+ dict_copy(dict, local->dict);
+ ret = 0;
+ goto out;
+ }
- if (rsp->op_ret && !(global_state->mode & GLUSTER_MODE_XML)) {
- cli_err ("snapshot delete: failed: %s",
- rsp->op_errstr ? rsp->op_errstr :
- "Please check log file for details");
- ret = rsp->op_ret;
- goto out;
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_snapshot_delete(local, dict, rsp);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create xml output for snapshot delete command");
+ goto out;
}
-
- if (delete_cmd == GF_SNAP_DELETE_TYPE_ALL ||
- delete_cmd == GF_SNAP_DELETE_TYPE_VOL) {
- local = ((call_frame_t *) frame) -> local;
- if (!local) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "frame->local is NULL");
- goto out;
- }
-
- /* During first call back of snapshot delete of type
- * ALL and VOL, We will get the snapcount and snapnames.
- * Hence to make the subsequent rpc calls for individual
- * snapshot delete, We need to save it in local dictionary.
- */
- dict_copy (dict, local->dict);
- ret = 0;
- goto out;
+ /* Error out in case of the op already failed */
+ if (rsp->op_ret) {
+ ret = rsp->op_ret;
+ goto out;
}
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_snapshot_delete (local->writer, local->doc,
- dict, rsp);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot delete command");
- goto out;
- }
- /* Error out in case of the op already failed */
- if (rsp->op_ret) {
- ret = rsp->op_ret;
- goto out;
- }
- } else {
- ret = dict_get_str (dict, "snapname", &snap_name);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snapname");
- goto out;
- }
-
- cli_out ("snapshot delete: %s: snap removed successfully",
- snap_name);
+ } else {
+ ret = dict_get_str_sizen(dict, "snapname", &snap_name);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snapname");
+ goto out;
}
- ret = 0;
+
+ cli_out("snapshot delete: %s: snap removed successfully", snap_name);
+ }
+ ret = 0;
out:
- if ((global_state->mode & GLUSTER_MODE_XML) &&
- (delete_cmd == GF_SNAP_DELETE_TYPE_SNAP)) {
- ret = cli_xml_output_snap_delete_end (local);
- }
+ if ((global_state->mode & GLUSTER_MODE_XML) &&
+ (delete_cmd == GF_SNAP_DELETE_TYPE_SNAP)) {
+ ret = cli_xml_output_snap_delete_end(local);
+ }
end:
- return ret;
+ return ret;
}
-int
-cli_snapshot_config_display (dict_t *dict, gf_cli_rsp *rsp)
-{
- char buf[PATH_MAX] = "";
- char *volname = NULL;
- int ret = -1;
- int config_command = 0;
- uint64_t value = 0;
- uint64_t hard_limit = 0;
- uint64_t soft_limit = 0;
- uint64_t i = 0;
- uint64_t voldisplaycount = 0;
- char *auto_delete = NULL;
- char *snap_activate = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (rsp);
+static int
+cli_snapshot_config_display(dict_t *dict, gf_cli_rsp *rsp)
+{
+ char buf[PATH_MAX] = "";
+ char *volname = NULL;
+ int ret = -1;
+ int config_command = 0;
+ uint64_t value = 0;
+ uint64_t hard_limit = 0;
+ uint64_t soft_limit = 0;
+ uint64_t i = 0;
+ uint64_t voldisplaycount = 0;
+ char *auto_delete = NULL;
+ char *snap_activate = NULL;
+
+ GF_ASSERT(dict);
+ GF_ASSERT(rsp);
+
+ if (rsp->op_ret) {
+ cli_err("Snapshot Config : failed: %s",
+ rsp->op_errstr ? rsp->op_errstr
+ : "Please check log file for details");
+ ret = rsp->op_ret;
+ goto out;
+ }
+
+ ret = dict_get_int32_sizen(dict, "config-command", &config_command);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch config type");
+ goto out;
+ }
+
+ ret = dict_get_uint64(dict, "snap-max-hard-limit", &hard_limit);
+ /* Ignore the error, as the key specified is optional */
+ ret = dict_get_uint64(dict, "snap-max-soft-limit", &soft_limit);
+
+ ret = dict_get_str_sizen(dict, "auto-delete", &auto_delete);
+
+ ret = dict_get_str_sizen(dict, "snap-activate-on-create", &snap_activate);
+
+ if (!hard_limit && !soft_limit &&
+ config_command != GF_SNAP_CONFIG_DISPLAY && !auto_delete &&
+ !snap_activate) {
+ ret = -1;
+ gf_log(THIS->name, GF_LOG_ERROR, "Could not fetch config-key");
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ /* Ignore the error, as volname is optional */
+
+ if (!volname) {
+ volname = "System";
+ }
+
+ switch (config_command) {
+ case GF_SNAP_CONFIG_TYPE_SET:
+ if (hard_limit && soft_limit) {
+ cli_out(
+ "snapshot config: snap-max-hard-limit "
+ "& snap-max-soft-limit for system set successfully");
+ } else if (hard_limit) {
+ cli_out(
+ "snapshot config: snap-max-hard-limit "
+ "for %s set successfully",
+ volname);
+ } else if (soft_limit) {
+ cli_out(
+ "snapshot config: snap-max-soft-limit "
+ "for %s set successfully",
+ volname);
+ } else if (auto_delete) {
+ cli_out("snapshot config: auto-delete successfully set");
+ } else if (snap_activate) {
+ cli_out("snapshot config: activate-on-create successfully set");
+ }
+ break;
- if (rsp->op_ret) {
- cli_err ("Snapshot Config : failed: %s",
- rsp->op_errstr ? rsp->op_errstr :
- "Please check log file for details");
- ret = rsp->op_ret;
+ case GF_SNAP_CONFIG_DISPLAY:
+ cli_out("\nSnapshot System Configuration:");
+ ret = dict_get_uint64(dict, "snap-max-hard-limit", &value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not fetch snap_max_hard_limit for %s", volname);
+ ret = -1;
goto out;
- }
+ }
+ cli_out("snap-max-hard-limit : %" PRIu64, value);
- ret = dict_get_int32 (dict, "config-command", &config_command);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch config type");
+ ret = dict_get_uint64(dict, "snap-max-soft-limit", &soft_limit);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not fetch snap-max-soft-limit for %s", volname);
+ ret = -1;
goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- /* Ignore the error, as volname is optional */
-
- if (!volname) {
- volname = "System";
- }
+ }
+ cli_out("snap-max-soft-limit : %" PRIu64 "%%", soft_limit);
- ret = dict_get_uint64 (dict, "snap-max-hard-limit", &hard_limit);
- /* Ignore the error, as the key specified is optional */
- ret = dict_get_uint64 (dict, "snap-max-soft-limit", &soft_limit);
+ cli_out("auto-delete : %s", auto_delete);
- ret = dict_get_str (dict, "auto-delete", &auto_delete);
+ cli_out("activate-on-create : %s\n", snap_activate);
- ret = dict_get_str (dict, "snap-activate-on-create", &snap_activate);
+ cli_out("Snapshot Volume Configuration:");
- if (!hard_limit && !soft_limit
- && config_command != GF_SNAP_CONFIG_DISPLAY
- && !auto_delete && !snap_activate) {
+ ret = dict_get_uint64(dict, "voldisplaycount", &voldisplaycount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch voldisplaycount");
ret = -1;
- gf_log(THIS->name, GF_LOG_ERROR,
- "Could not fetch config-key");
goto out;
- }
+ }
- switch (config_command) {
- case GF_SNAP_CONFIG_TYPE_SET:
- if (hard_limit && soft_limit) {
- cli_out ("snapshot config: snap-max-hard-limit "
- "& snap-max-soft-limit for system set "
- "successfully");
- } else if (hard_limit) {
- cli_out ("snapshot config: snap-max-hard-limit "
- "for %s set successfully",
- volname);
- } else if (soft_limit) {
- cli_out ("snapshot config: snap-max-soft-limit "
- "for %s set successfully",
- volname);
- } else if (auto_delete) {
- cli_out ("snapshot config: auto-delete "
- "successfully set");
- } else if (snap_activate) {
- cli_out ("snapshot config: activate-on-create "
- "successfully set");
- }
- break;
-
- case GF_SNAP_CONFIG_DISPLAY:
- cli_out ("\nSnapshot System Configuration:");
- ret = dict_get_uint64 (dict, "snap-max-hard-limit",
- &value);
+ for (i = 0; i < voldisplaycount; i++) {
+ ret = snprintf(buf, sizeof(buf), "volume%" PRIu64 "-volname",
+ i);
+ ret = dict_get_strn(dict, buf, ret, &volname);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
- "snap_max_hard_limit for %s", volname);
- ret = -1;
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch %s", buf);
+ ret = -1;
+ goto out;
}
- cli_out ("snap-max-hard-limit : %"PRIu64, value);
+ cli_out("\nVolume : %s", volname);
- ret = dict_get_uint64 (dict, "snap-max-soft-limit",
- &soft_limit);
+ snprintf(buf, sizeof(buf),
+ "volume%" PRIu64 "-snap-max-hard-limit", i);
+ ret = dict_get_uint64(dict, buf, &value);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
- "snap-max-soft-limit for %s", volname);
- ret = -1;
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch %s", buf);
+ ret = -1;
+ goto out;
}
- cli_out ("snap-max-soft-limit : %"PRIu64"%%",
- soft_limit);
+ cli_out("snap-max-hard-limit : %" PRIu64, value);
- cli_out ("auto-delete : %s", auto_delete);
-
- cli_out ("activate-on-create : %s\n", snap_activate);
-
- cli_out ("Snapshot Volume Configuration:");
-
- ret = dict_get_uint64 (dict, "voldisplaycount",
- &voldisplaycount);
+ snprintf(buf, sizeof(buf),
+ "volume%" PRIu64 "-active-hard-limit", i);
+ ret = dict_get_uint64(dict, buf, &value);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Could not fetch voldisplaycount");
- ret = -1;
- goto out;
- }
-
- for (i = 0; i < voldisplaycount; i++) {
- snprintf (buf, sizeof(buf), "volume%"PRIu64"-volname", i);
- ret = dict_get_str (dict, buf, &volname);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
- " %s", buf);
- ret = -1;
- goto out;
- }
- cli_out ("\nVolume : %s", volname);
-
- snprintf (buf, sizeof(buf),
- "volume%"PRIu64"-snap-max-hard-limit", i);
- ret = dict_get_uint64 (dict, buf, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
- " %s", buf);
- ret = -1;
- goto out;
- }
- cli_out ("snap-max-hard-limit : %"PRIu64, value);
-
- snprintf (buf, sizeof(buf),
- "volume%"PRIu64"-active-hard-limit", i);
- ret = dict_get_uint64 (dict, buf, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch"
- " effective snap_max_hard_limit for "
- "%s", volname);
- ret = -1;
- goto out;
- }
- cli_out ("Effective snap-max-hard-limit : %"PRIu64,
- value);
-
- snprintf (buf, sizeof(buf),
- "volume%"PRIu64"-snap-max-soft-limit", i);
- ret = dict_get_uint64 (dict, buf, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
- " %s", buf);
- ret = -1;
- goto out;
- }
- cli_out ("Effective snap-max-soft-limit : %"PRIu64" "
- "(%"PRIu64"%%)", value, soft_limit);
- }
- break;
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not fetch"
+ " effective snap_max_hard_limit for %s",
+ volname);
+ ret = -1;
+ goto out;
+ }
+ cli_out("Effective snap-max-hard-limit : %" PRIu64, value);
+
+ snprintf(buf, sizeof(buf),
+ "volume%" PRIu64 "-snap-max-soft-limit", i);
+ ret = dict_get_uint64(dict, buf, &value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch %s", buf);
+ ret = -1;
+ goto out;
+ }
+ cli_out("Effective snap-max-soft-limit : %" PRIu64
+ " "
+ "(%" PRIu64 "%%)",
+ value, soft_limit);
+ }
+ break;
default:
- break;
- }
+ break;
+ }
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function is used to print the volume related information
@@ -8989,1798 +8651,2299 @@ out:
* arg - 0, dict : Response Dictionary.
* arg - 1, prefix str : snaplist.snap{0..}.vol{0..}.*
*/
-int
-cli_get_each_volinfo_in_snap (dict_t *dict, char *keyprefix,
- gf_boolean_t snap_driven) {
- char key[PATH_MAX] = "";
- char *get_buffer = NULL;
- int value = 0;
- int ret = -1;
- char indent[5] = "\t";
- char *volname = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
-
- if (snap_driven) {
- ret = snprintf (key, sizeof (key), "%s.volname", keyprefix);
- if (ret < 0) {
- goto out;
- }
-
- ret = dict_get_str (dict, key, &get_buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
- goto out;
- }
- cli_out ("%s" INDENT_MAIN_HEAD "%s", indent,
- "Snap Volume Name", ":", get_buffer);
-
- ret = snprintf (key, sizeof (key),
- "%s.origin-volname", keyprefix);
- if (ret < 0) {
- goto out;
- }
+static int
+cli_get_each_volinfo_in_snap(dict_t *dict, char *keyprefix,
+ gf_boolean_t snap_driven)
+{
+ char key[PATH_MAX] = "";
+ char *get_buffer = NULL;
+ int value = 0;
+ int ret = -1;
+ char indent[5] = "\t";
+ char *volname = NULL;
- ret = dict_get_str (dict, key, &volname);
- if (ret) {
- gf_log ("cli", GF_LOG_WARNING, "Failed to get %s", key);
- cli_out ("%-12s", "Origin:");
- }
- cli_out ("%s" INDENT_MAIN_HEAD "%s", indent,
- "Origin Volume name", ":", volname);
+ GF_ASSERT(dict);
+ GF_ASSERT(keyprefix);
+ if (snap_driven) {
+ ret = snprintf(key, sizeof(key), "%s.volname", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
- ret = snprintf (key, sizeof (key), "%s.snapcount",
- keyprefix);
- if (ret < 0) {
- goto out;
- }
+ ret = dict_get_str(dict, key, &get_buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
+ cli_out("%s" INDENT_MAIN_HEAD "%s", indent, "Snap Volume Name", ":",
+ get_buffer);
- ret = dict_get_int32 (dict, key, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
- goto out;
- }
- cli_out ("%s%s %s %s %d", indent, "Snaps taken for",
- volname, ":", value);
+ ret = snprintf(key, sizeof(key), "%s.origin-volname", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
- ret = snprintf (key, sizeof (key), "%s.snaps-available",
- keyprefix);
- if (ret < 0) {
- goto out;
- }
+ ret = dict_get_str(dict, key, &volname);
+ if (ret) {
+ gf_log("cli", GF_LOG_WARNING, "Failed to get %s", key);
+ cli_out("%-12s", "Origin:");
+ }
+ cli_out("%s" INDENT_MAIN_HEAD "%s", indent, "Origin Volume name", ":",
+ volname);
- ret = dict_get_int32 (dict, key, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
- goto out;
- }
- cli_out ("%s%s %s %s %d", indent, "Snaps available for",
- volname, ":", value);
+ ret = snprintf(key, sizeof(key), "%s.snapcount", keyprefix);
+ if (ret < 0) {
+ goto out;
}
+ ret = dict_get_int32(dict, key, &value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
+ cli_out("%s%s %s %s %d", indent, "Snaps taken for", volname, ":",
+ value);
- ret = snprintf (key, sizeof (key), "%s.vol-status", keyprefix);
+ ret = snprintf(key, sizeof(key), "%s.snaps-available", keyprefix);
if (ret < 0) {
- goto out;
+ goto out;
}
- ret = dict_get_str (dict, key, &get_buffer);
+ ret = dict_get_int32(dict, key, &value);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
}
- cli_out ("%s" INDENT_MAIN_HEAD "%s", indent, "Status",
- ":", get_buffer);
+ cli_out("%s%s %s %s %d", indent, "Snaps available for", volname, ":",
+ value);
+ }
+
+ ret = snprintf(key, sizeof(key), "%s.vol-status", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str(dict, key, &get_buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
+ cli_out("%s" INDENT_MAIN_HEAD "%s", indent, "Status", ":", get_buffer);
out:
- return ret;
+ return ret;
}
/* This function is used to print snap related information
* arg - 0, dict : Response dictionary.
* arg - 1, prefix_str : snaplist.snap{0..}.*
*/
-int
-cli_get_volinfo_in_snap (dict_t *dict, char *keyprefix) {
+static int
+cli_get_volinfo_in_snap(dict_t *dict, char *keyprefix)
+{
+ char key[PATH_MAX] = "";
+ int i = 0;
+ int volcount = 0;
+ int ret = -1;
- char key[PATH_MAX] = "";
- int i = 0;
- int volcount = 0;
- int ret = -1;
+ GF_ASSERT(dict);
+ GF_ASSERT(keyprefix);
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
+ ret = snprintf(key, sizeof(key), "%s.vol-count", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
- ret = snprintf (key, sizeof (key), "%s.vol-count", keyprefix);
+ ret = dict_get_int32(dict, key, &volcount);
+ for (i = 1; i <= volcount; i++) {
+ ret = snprintf(key, sizeof(key), "%s.vol%d", keyprefix, i);
if (ret < 0) {
- goto out;
+ goto out;
}
-
- ret = dict_get_int32 (dict, key, &volcount);
- for (i = 1 ; i <= volcount ; i++) {
- ret = snprintf (key, sizeof (key),
- "%s.vol%d", keyprefix, i);
- if (ret < 0) {
- goto out;
- }
- ret = cli_get_each_volinfo_in_snap (dict, key, _gf_true);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not list "
- "details of volume in a snap");
- goto out;
- }
- cli_out (" ");
+ ret = cli_get_each_volinfo_in_snap(dict, key, _gf_true);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not list details of volume in a snap");
+ goto out;
}
+ cli_out(" ");
+ }
out:
- return ret;
+ return ret;
}
-int
-cli_get_each_snap_info (dict_t *dict, char *prefix_str,
- gf_boolean_t snap_driven) {
- char key_buffer[PATH_MAX] = "";
- char *get_buffer = NULL;
- int ret = -1;
- char indent[5] = "";
+static int
+cli_get_each_snap_info(dict_t *dict, char *prefix_str, gf_boolean_t snap_driven)
+{
+ char key_buffer[PATH_MAX] = "";
+ char *get_buffer = NULL;
+ int ret = -1;
+ char indent[5] = "";
+
+ GF_ASSERT(dict);
+ GF_ASSERT(prefix_str);
+
+ if (!snap_driven)
+ strcat(indent, "\t");
+
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.snapname", prefix_str);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str(dict, key_buffer, &get_buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to fetch snapname %s ", key_buffer);
+ goto out;
+ }
+ cli_out("%s" INDENT_MAIN_HEAD "%s", indent, "Snapshot", ":", get_buffer);
+
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.snap-id", prefix_str);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str(dict, key_buffer, &get_buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to fetch snap-id %s ", key_buffer);
+ goto out;
+ }
+ cli_out("%s" INDENT_MAIN_HEAD "%s", indent, "Snap UUID", ":", get_buffer);
+
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.snap-desc", prefix_str);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str(dict, key_buffer, &get_buffer);
+ if (!ret) {
+ /* Ignore error for description */
+ cli_out("%s" INDENT_MAIN_HEAD "%s", indent, "Description", ":",
+ get_buffer);
+ }
+
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.snap-time", prefix_str);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str(dict, key_buffer, &get_buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to fetch snap-time %s ",
+ prefix_str);
+ goto out;
+ }
+ cli_out("%s" INDENT_MAIN_HEAD "%s", indent, "Created", ":", get_buffer);
+
+ if (snap_driven) {
+ cli_out("%-12s", "Snap Volumes:\n");
+ ret = cli_get_volinfo_in_snap(dict, prefix_str);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to list details of the snaps");
+ goto out;
+ }
+ }
+out:
+ return ret;
+}
- GF_ASSERT (dict);
- GF_ASSERT (prefix_str);
+/* This is a generic function to print snap related information.
+ * arg - 0, dict : Response Dictionary
+ */
+static int
+cli_call_snapshot_info(dict_t *dict, gf_boolean_t bool_snap_driven)
+{
+ int snap_count = 0;
+ char key[32] = "";
+ int ret = -1;
+ int i = 0;
- if (!snap_driven)
- strcat (indent, "\t");
+ GF_ASSERT(dict);
- ret = snprintf (key_buffer, sizeof (key_buffer), "%s.snapname",
- prefix_str);
- if (ret < 0) {
- goto out;
- }
+ ret = dict_get_int32_sizen(dict, "snapcount", &snap_count);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get snapcount");
+ goto out;
+ }
- ret = dict_get_str (dict, key_buffer, &get_buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to fetch snapname %s ",
- key_buffer);
- goto out;
- }
- cli_out ("%s" INDENT_MAIN_HEAD "%s", indent, "Snapshot",
- ":", get_buffer);
+ if (snap_count == 0) {
+ cli_out("No snapshots present");
+ }
- ret = snprintf (key_buffer, sizeof (key_buffer), "%s.snap-id",
- prefix_str);
+ for (i = 1; i <= snap_count; i++) {
+ ret = snprintf(key, sizeof(key), "snap%d", i);
if (ret < 0) {
- goto out;
+ goto out;
}
-
- ret = dict_get_str (dict, key_buffer, &get_buffer);
+ ret = cli_get_each_snap_info(dict, key, bool_snap_driven);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to fetch snap-id %s ",
- key_buffer);
- goto out;
- }
- cli_out ("%s" INDENT_MAIN_HEAD "%s", indent, "Snap UUID",
- ":", get_buffer);
-
- ret = snprintf (key_buffer, sizeof (key_buffer), "%s.snap-desc",
- prefix_str);
- if (ret < 0) {
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Unable to print snap details");
+ goto out;
}
+ }
+out:
+ return ret;
+}
- ret = dict_get_str (dict, key_buffer, &get_buffer);
- if (!ret) {
- /* Ignore error for description */
- cli_out ("%s" INDENT_MAIN_HEAD "%s", indent,
- "Description", ":", get_buffer);
+static int
+cli_get_snaps_in_volume(dict_t *dict)
+{
+ int ret = -1;
+ int i = 0;
+ int count = 0;
+ int avail = 0;
+ char key[32] = "";
+ char *get_buffer = NULL;
+
+ GF_ASSERT(dict);
+
+ ret = dict_get_str_sizen(dict, "origin-volname", &get_buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch origin-volname");
+ goto out;
+ }
+ cli_out(INDENT_MAIN_HEAD "%s", "Volume Name", ":", get_buffer);
+
+ ret = dict_get_int32_sizen(dict, "snapcount", &avail);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch snapcount");
+ goto out;
+ }
+ cli_out(INDENT_MAIN_HEAD "%d", "Snaps Taken", ":", avail);
+
+ ret = dict_get_int32_sizen(dict, "snaps-available", &count);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch snaps-available");
+ goto out;
+ }
+ cli_out(INDENT_MAIN_HEAD "%d", "Snaps Available", ":", count);
+
+ for (i = 1; i <= avail; i++) {
+ snprintf(key, sizeof(key), "snap%d", i);
+ ret = cli_get_each_snap_info(dict, key, _gf_false);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to print snap details");
+ goto out;
}
- ret = snprintf (key_buffer, sizeof (key_buffer), "%s.snap-time",
- prefix_str);
+ ret = snprintf(key, sizeof(key), "snap%d.vol1", i);
if (ret < 0) {
- goto out;
+ goto out;
}
-
- ret = dict_get_str (dict, key_buffer, &get_buffer);
+ ret = cli_get_each_volinfo_in_snap(dict, key, _gf_false);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to fetch snap-time %s ",
- prefix_str);
- goto out;
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not get volume related information");
+ goto out;
}
- cli_out ("%s" INDENT_MAIN_HEAD "%s", indent, "Created",
- ":", get_buffer);
- if (snap_driven) {
- cli_out ("%-12s", "Snap Volumes:\n");
- ret = cli_get_volinfo_in_snap (dict, prefix_str);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to list details "
- "of the snaps");
- goto out;
- }
- }
+ cli_out(" ");
+ }
out:
- return ret;
+ return ret;
}
-/* This is a generic function to print snap related information.
- * arg - 0, dict : Response Dictionary
- */
-int
-cli_call_snapshot_info (dict_t *dict, gf_boolean_t bool_snap_driven) {
- int snap_count = 0;
- char key[PATH_MAX] = "";
- int ret = -1;
- int i = 0;
+static int
+cli_snapshot_list(dict_t *dict)
+{
+ int snapcount = 0;
+ char key[32] = "";
+ int ret = -1;
+ int i = 0;
+ char *get_buffer = NULL;
- GF_ASSERT (dict);
+ GF_ASSERT(dict);
- ret = dict_get_int32 (dict, "snapcount", &snap_count);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to get snapcount");
- goto out;
- }
+ ret = dict_get_int32_sizen(dict, "snapcount", &snapcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch snap count");
+ goto out;
+ }
- if (snap_count == 0) {
- cli_out ("No snapshots present");
+ if (snapcount == 0) {
+ cli_out("No snapshots present");
+ }
+
+ for (i = 1; i <= snapcount; i++) {
+ ret = snprintf(key, sizeof(key), "snapname%d", i);
+ if (ret < 0) {
+ goto out;
}
- for (i = 1 ; i <= snap_count ; i++) {
- ret = snprintf (key, sizeof (key), "snap%d", i);
- if (ret < 0) {
- goto out;
- }
- ret = cli_get_each_snap_info (dict, key, bool_snap_driven);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Unable to print snap details");
- goto out;
- }
+ ret = dict_get_strn(dict, key, ret, &get_buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not get %s ", key);
+ goto out;
+ } else {
+ cli_out("%s", get_buffer);
}
+ }
out:
- return ret;
+ return ret;
}
-int
-cli_get_snaps_in_volume (dict_t *dict) {
- int ret = -1;
- int i = 0;
- int count = 0;
- int avail = 0;
- char key[PATH_MAX] = "";
- char *get_buffer = NULL;
-
- GF_ASSERT (dict);
+static int
+cli_get_snap_volume_status(dict_t *dict, char *key_prefix)
+{
+ int ret = -1;
+ char key[PATH_MAX] = "";
+ char *buffer = NULL;
+ int brickcount = 0;
+ int i = 0;
+ int pid = 0;
+
+ GF_ASSERT(dict);
+ GF_ASSERT(key_prefix);
+
+ ret = snprintf(key, sizeof(key), "%s.brickcount", key_prefix);
+ if (ret < 0) {
+ goto out;
+ }
+ ret = dict_get_int32(dict, key, &brickcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to fetch brickcount");
+ goto out;
+ }
+
+ for (i = 0; i < brickcount; i++) {
+ ret = snprintf(key, sizeof(key), "%s.brick%d.path", key_prefix, i);
+ if (ret < 0) {
+ goto out;
+ }
- ret = dict_get_str (dict, "origin-volname", &get_buffer);
+ ret = dict_get_str(dict, key, &buffer);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch origin-volname");
- goto out;
+ gf_log("cli", GF_LOG_INFO, "Unable to get Brick Path");
+ continue;
}
- cli_out (INDENT_MAIN_HEAD "%s", "Volume Name", ":", get_buffer);
+ cli_out("\n\t%-17s %s %s", "Brick Path", ":", buffer);
- ret = dict_get_int32 (dict, "snapcount", &avail);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch snapcount");
- goto out;
+ ret = snprintf(key, sizeof(key), "%s.brick%d.vgname", key_prefix, i);
+ if (ret < 0) {
+ goto out;
}
- cli_out (INDENT_MAIN_HEAD "%d", "Snaps Taken", ":", avail);
- ret = dict_get_int32 (dict, "snaps-available", &count);
+ ret = dict_get_str(dict, key, &buffer);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch snaps-available");
- goto out;
- }
- cli_out (INDENT_MAIN_HEAD "%d", "Snaps Available", ":", count);
+ gf_log("cli", GF_LOG_INFO, "Unable to get Volume Group");
+ cli_out("\t%-17s %s %s", "Volume Group", ":", "N/A");
+ } else
+ cli_out("\t%-17s %s %s", "Volume Group", ":", buffer);
- for (i = 1 ; i <= avail ; i++) {
- snprintf (key, sizeof (key), "snap%d", i);
- ret = cli_get_each_snap_info (dict, key, _gf_false);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Unable to print snap details");
- goto out;
- }
+ ret = snprintf(key, sizeof(key), "%s.brick%d.status", key_prefix, i);
+ if (ret < 0) {
+ goto out;
+ }
- ret = snprintf (key, sizeof (key), "snap%d.vol1", i);
- if (ret < 0) {
- goto out;
- }
- ret = cli_get_each_volinfo_in_snap (dict, key, _gf_false);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not get volume "
- "related information");
- goto out;
- }
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_INFO, "Unable to get Brick Running");
+ cli_out("\t%-17s %s %s", "Brick Running", ":", "N/A");
+ } else
+ cli_out("\t%-17s %s %s", "Brick Running", ":", buffer);
- cli_out (" ");
+ ret = snprintf(key, sizeof(key), "%s.brick%d.pid", key_prefix, i);
+ if (ret < 0) {
+ goto out;
}
-out:
- return ret;
-}
-int
-cli_snapshot_list (dict_t *dict) {
- int snapcount = 0;
- char key[PATH_MAX] = "";
- int ret = -1;
- int i = 0;
- char *get_buffer = NULL;
+ ret = dict_get_int32(dict, key, &pid);
+ if (ret) {
+ gf_log("cli", GF_LOG_INFO, "Unable to get pid");
+ cli_out("\t%-17s %s %s", "Brick PID", ":", "N/A");
+ } else
+ cli_out("\t%-17s %s %d", "Brick PID", ":", pid);
- GF_ASSERT (dict);
+ ret = snprintf(key, sizeof(key), "%s.brick%d.data", key_prefix, i);
+ if (ret < 0) {
+ goto out;
+ }
- ret = dict_get_int32 (dict, "snapcount", &snapcount);
+ ret = dict_get_str(dict, key, &buffer);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch snap count");
- goto out;
- }
+ gf_log("cli", GF_LOG_INFO, "Unable to get Data Percent");
+ cli_out("\t%-17s %s %s", "Data Percentage", ":", "N/A");
+ } else
+ cli_out("\t%-17s %s %s", "Data Percentage", ":", buffer);
- if (snapcount == 0) {
- cli_out ("No snapshots present");
+ ret = snprintf(key, sizeof(key), "%s.brick%d.lvsize", key_prefix, i);
+ if (ret < 0) {
+ goto out;
}
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_INFO, "Unable to get LV Size");
+ cli_out("\t%-17s %s %s", "LV Size", ":", "N/A");
+ } else
+ cli_out("\t%-17s %s %s", "LV Size", ":", buffer);
+ }
- for (i = 1 ; i <= snapcount ; i++) {
- ret = snprintf (key, sizeof (key), "snapname%d", i);
- if (ret < 0) {
- goto out;
- }
+ ret = 0;
+out:
+ return ret;
+}
- ret = dict_get_str (dict, key, &get_buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not get %s ", key);
- goto out;
- } else {
- cli_out ("%s", get_buffer);
- }
+static int
+cli_get_single_snap_status(dict_t *dict, char *keyprefix)
+{
+ int ret = -1;
+ char key[64] = ""; /* keyprefix is ""status.snap0" */
+ int i = 0;
+ int volcount = 0;
+ char *get_buffer = NULL;
+
+ GF_ASSERT(dict);
+ GF_ASSERT(keyprefix);
+
+ ret = snprintf(key, sizeof(key), "%s.snapname", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str(dict, key, &get_buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get snapname");
+ goto out;
+ }
+ cli_out("\nSnap Name : %s", get_buffer);
+
+ ret = snprintf(key, sizeof(key), "%s.uuid", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str(dict, key, &get_buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get snap UUID");
+ goto out;
+ }
+ cli_out("Snap UUID : %s", get_buffer);
+
+ ret = snprintf(key, sizeof(key), "%s.volcount", keyprefix);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_int32(dict, key, &volcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get volume count");
+ goto out;
+ }
+
+ for (i = 0; i < volcount; i++) {
+ ret = snprintf(key, sizeof(key), "%s.vol%d", keyprefix, i);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = cli_get_snap_volume_status(dict, key);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not get snap volume status");
+ goto out;
}
+ }
out:
- return ret;
+ return ret;
}
-int
-cli_get_snap_volume_status (dict_t *dict, char *key_prefix)
+static int32_t
+cli_populate_req_dict_for_delete(dict_t *snap_dict, dict_t *dict, size_t index)
+{
+ int32_t ret = -1;
+ char key[PATH_MAX] = "";
+ char *buffer = NULL;
+
+ GF_ASSERT(snap_dict);
+ GF_ASSERT(dict);
+
+ ret = dict_set_int32_sizen(snap_dict, "sub-cmd", GF_SNAP_DELETE_TYPE_ITER);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not save command type in snap dictionary");
+ goto out;
+ }
+
+ ret = snprintf(key, sizeof(key), "snapname%zu", index);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snapname");
+ goto out;
+ }
+
+ ret = dict_set_dynstr_with_alloc(snap_dict, "snapname", buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to save snapname");
+ goto out;
+ }
+
+ ret = dict_set_int32_sizen(snap_dict, "type", GF_SNAP_OPTION_TYPE_DELETE);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to save command type");
+ goto out;
+ }
+
+ ret = dict_set_dynstr_with_alloc(snap_dict, "cmd-str", "snapshot delete");
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not save command string as delete");
+ goto out;
+ }
+out:
+ return ret;
+}
+
+static int
+cli_populate_req_dict_for_status(dict_t *snap_dict, dict_t *dict, int index)
{
- int ret = -1;
- char key[PATH_MAX] = "";
- char *buffer = NULL;
- int brickcount = 0;
- int i = 0;
- int pid = 0;
+ int ret = -1;
+ char key[PATH_MAX] = "";
+ char *buffer = NULL;
- GF_ASSERT (dict);
- GF_ASSERT (key_prefix);
+ GF_ASSERT(snap_dict);
+ GF_ASSERT(dict);
- ret = snprintf (key, sizeof (key), "%s.brickcount", key_prefix);
- if (ret < 0) {
- goto out;
- }
- ret = dict_get_int32 (dict, key, &brickcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to fetch brickcount");
- goto out;
- }
+ ret = dict_set_uint32(snap_dict, "sub-cmd", GF_SNAP_STATUS_TYPE_ITER);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not save command type in snap dict");
+ goto out;
+ }
- for (i = 0 ; i < brickcount ; i++) {
- ret = snprintf (key, sizeof (key), "%s.brick%d.path",
- key_prefix, i);
- if (ret < 0) {
- goto out;
- }
+ ret = snprintf(key, sizeof(key), "status.snap%d.snapname", index);
+ if (ret < 0) {
+ goto out;
+ }
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_INFO,
- "Unable to get Brick Path");
- continue;
- }
- cli_out ("\n\t%-17s %s %s", "Brick Path", ":", buffer);
+ ret = dict_get_strn(dict, key, ret, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not get snapname");
+ goto out;
+ }
- ret = snprintf (key, sizeof (key), "%s.brick%d.vgname",
- key_prefix, i);
- if (ret < 0) {
- goto out;
- }
+ ret = dict_set_str_sizen(snap_dict, "snapname", buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not save snapname in snap dict");
+ goto out;
+ }
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_INFO,
- "Unable to get Volume Group");
- cli_out ("\t%-17s %s %s", "Volume Group", ":",
- "N/A");
- } else
- cli_out ("\t%-17s %s %s", "Volume Group", ":",
- buffer);
-
- ret = snprintf (key, sizeof (key), "%s.brick%d.status",
- key_prefix, i);
- if (ret < 0) {
- goto out;
- }
+ ret = dict_set_int32_sizen(snap_dict, "type", GF_SNAP_OPTION_TYPE_STATUS);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not save command type");
+ goto out;
+ }
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_INFO,
- "Unable to get Brick Running");
- cli_out ("\t%-17s %s %s", "Brick Running", ":",
- "N/A");
- } else
- cli_out ("\t%-17s %s %s", "Brick Running", ":",
- buffer);
-
- ret = snprintf (key, sizeof (key), "%s.brick%d.pid",
- key_prefix, i);
- if (ret < 0) {
- goto out;
- }
+ ret = dict_set_dynstr_with_alloc(snap_dict, "cmd-str", "snapshot status");
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not save command string as status");
+ goto out;
+ }
- ret = dict_get_int32 (dict, key, &pid);
- if (ret) {
- gf_log ("cli", GF_LOG_INFO,
- "Unable to get pid");
- cli_out ("\t%-17s %s %s", "Brick PID", ":", "N/A");
- } else
- cli_out ("\t%-17s %s %d", "Brick PID", ":", pid);
-
- ret = snprintf (key, sizeof (key), "%s.brick%d.data",
- key_prefix, i);
- if (ret < 0) {
- goto out;
- }
+ ret = dict_set_int32_sizen(snap_dict, "hold_vol_locks", _gf_false);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Setting volume lock flag failed");
+ goto out;
+ }
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_INFO,
- "Unable to get Data Percent");
- cli_out ("\t%-17s %s %s", "Data Percentage", ":",
- "N/A");
- } else
- cli_out ("\t%-17s %s %s", "Data Percentage", ":",
- buffer);
-
- ret = snprintf (key, sizeof (key), "%s.brick%d.lvsize",
- key_prefix, i);
- if (ret < 0) {
- goto out;
- }
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_INFO, "Unable to get LV Size");
- cli_out ("\t%-17s %s %s", "LV Size", ":", "N/A");
- } else
- cli_out ("\t%-17s %s %s", "LV Size", ":", buffer);
+out:
+ return ret;
+}
+static int
+cli_snapshot_status(dict_t *dict, gf_cli_rsp *rsp, call_frame_t *frame)
+{
+ int ret = -1;
+ int status_cmd = -1;
+ cli_local_t *local = NULL;
+
+ GF_ASSERT(dict);
+ GF_ASSERT(rsp);
+ GF_ASSERT(frame);
+
+ local = ((call_frame_t *)frame)->local;
+ if (!local) {
+ gf_log("cli", GF_LOG_ERROR, "frame->local is NULL");
+ goto out;
+ }
+
+ if (rsp->op_ret) {
+ if (rsp->op_errstr) {
+ ret = dict_set_dynstr_with_alloc(local->dict, "op_err_str",
+ rsp->op_errstr);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to set op_errstr in local dictionary");
+ goto out;
+ }
+ }
+ ret = rsp->op_ret;
+ goto out;
+ }
+
+ ret = dict_get_int32_sizen(dict, "sub-cmd", &status_cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch status type");
+ goto out;
+ }
+
+ if ((status_cmd != GF_SNAP_STATUS_TYPE_SNAP) &&
+ (status_cmd != GF_SNAP_STATUS_TYPE_ITER)) {
+ dict_copy(dict, local->dict);
+ goto out;
+ }
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_snapshot_status_single_snap(local, dict, "status.snap0");
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create xml output for snapshot status");
}
+ } else {
+ ret = cli_get_single_snap_status(dict, "status.snap0");
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch status of snap");
+ }
+ }
- ret = 0;
out:
- return ret;
+ return ret;
}
+static int
+gf_cli_generate_snapshot_event(gf_cli_rsp *rsp, dict_t *dict, int32_t type,
+ char *snap_name, char *volname, char *snap_uuid,
+ char *clone_name)
+{
+ int ret = -1;
+ int config_command = 0;
+ int32_t delete_cmd = -1;
+ uint64_t hard_limit = 0;
+ uint64_t soft_limit = 0;
+ char *auto_delete = NULL;
+ char *snap_activate = NULL;
+ char msg[PATH_MAX] = {
+ 0,
+ };
+ char option[512] = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO("cli", dict, out);
+ GF_VALIDATE_OR_GOTO("cli", rsp, out);
+
+ switch (type) {
+ case GF_SNAP_OPTION_TYPE_CREATE:
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto out;
+ }
+ if (!volname) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get volume name");
+ goto out;
+ }
-int
-cli_get_single_snap_status (dict_t *dict, char *keyprefix)
-{
- int ret = -1;
- char key[PATH_MAX] = "";
- int i = 0;
- int volcount = 0;
- char *get_buffer = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
+ if (rsp->op_ret != 0) {
+ gf_event(EVENT_SNAPSHOT_CREATE_FAILED,
+ "snapshot_name=%s;volume_name=%s;error=%s", snap_name,
+ volname,
+ rsp->op_errstr ? rsp->op_errstr
+ : "Please check log file for details");
+ ret = 0;
+ break;
+ }
- ret = snprintf (key, sizeof (key), "%s.snapname", keyprefix);
- if (ret < 0) {
+ if (!snap_uuid) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
goto out;
- }
+ }
- ret = dict_get_str (dict, key, &get_buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to get snapname");
- goto out;
- }
- cli_out ("\nSnap Name : %s", get_buffer);
+ gf_event(EVENT_SNAPSHOT_CREATED,
+ "snapshot_name=%s;volume_name=%s;snapshot_uuid=%s",
+ snap_name, volname, snap_uuid);
- ret = snprintf (key, sizeof (key), "%s.uuid", keyprefix);
- if (ret < 0) {
- goto out;
- }
+ ret = 0;
+ break;
- ret = dict_get_str (dict, key, &get_buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to get snap UUID");
+ case GF_SNAP_OPTION_TYPE_ACTIVATE:
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
goto out;
- }
- cli_out ("Snap UUID : %s", get_buffer);
+ }
- ret = snprintf (key, sizeof (key), "%s.volcount", keyprefix);
- if (ret < 0) {
- goto out;
- }
+ if (rsp->op_ret != 0) {
+ gf_event(EVENT_SNAPSHOT_ACTIVATE_FAILED,
+ "snapshot_name=%s;error=%s", snap_name,
+ rsp->op_errstr ? rsp->op_errstr
+ : "Please check log file for details");
+ ret = 0;
+ break;
+ }
- ret = dict_get_int32 (dict, key, &volcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to get volume count");
+ if (!snap_uuid) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
goto out;
- }
+ }
- for (i = 0 ; i < volcount ; i++) {
- ret = snprintf (key, sizeof (key), "%s.vol%d", keyprefix, i);
- if (ret < 0) {
- goto out;
- }
+ gf_event(EVENT_SNAPSHOT_ACTIVATED,
+ "snapshot_name=%s;snapshot_uuid=%s", snap_name, snap_uuid);
- ret = cli_get_snap_volume_status (dict, key);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Could not get snap volume status");
- goto out;
- }
- }
-out:
- return ret;
-}
+ ret = 0;
+ break;
-int32_t
-cli_populate_req_dict_for_delete (dict_t *snap_dict, dict_t *dict, size_t index)
-{
- int32_t ret = -1;
- char key[PATH_MAX] = "";
- char *buffer = NULL;
- int type = 0;
- int snapcount = 0;
+ case GF_SNAP_OPTION_TYPE_DEACTIVATE:
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto out;
+ }
- GF_ASSERT (snap_dict);
- GF_ASSERT (dict);
+ if (rsp->op_ret != 0) {
+ gf_event(EVENT_SNAPSHOT_DEACTIVATE_FAILED,
+ "snapshot_name=%s;error=%s", snap_name,
+ rsp->op_errstr ? rsp->op_errstr
+ : "Please check log file for details");
+ ret = 0;
+ break;
+ }
- ret = dict_set_int32 (snap_dict, "sub-cmd",
- GF_SNAP_DELETE_TYPE_ITER);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save command "
- "type in snap dictionary");
+ if (!snap_uuid) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
goto out;
- }
+ }
- ret = snprintf (key, sizeof (key), "snapname%lu", index);
- if (ret < 0) {
- goto out;
- }
+ gf_event(EVENT_SNAPSHOT_DEACTIVATED,
+ "snapshot_name=%s;snapshot_uuid=%s", snap_name, snap_uuid);
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snapname");
- goto out;
- }
+ ret = 0;
+ break;
- ret = dict_set_dynstr_with_alloc (snap_dict, "snapname", buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to save snapname");
+ case GF_SNAP_OPTION_TYPE_RESTORE:
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
goto out;
- }
+ }
- ret = dict_set_int32 (snap_dict, "type", GF_SNAP_OPTION_TYPE_DELETE);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to save command type");
+ if (rsp->op_ret != 0) {
+ gf_event(EVENT_SNAPSHOT_RESTORE_FAILED,
+ "snapshot_name=%s;error=%s", snap_name,
+ rsp->op_errstr ? rsp->op_errstr
+ : "Please check log file for details");
+ ret = 0;
+ break;
+ }
+
+ if (!snap_uuid) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
goto out;
- }
+ }
- ret = dict_set_dynstr_with_alloc (snap_dict, "cmd-str",
- "snapshot delete");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Could not save command string as delete");
+ if (!volname) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Failed to get volname");
goto out;
- }
-out:
- return ret;
-}
+ }
-int
-cli_populate_req_dict_for_status (dict_t *snap_dict, dict_t *dict, int index) {
- int ret = -1;
- char key[PATH_MAX] = "";
- char *buffer = NULL;
- int type = 0;
- int snapcount = 0;
-
- GF_ASSERT (snap_dict);
- GF_ASSERT (dict);
-
- ret = dict_set_uint32 (snap_dict, "sub-cmd",
- GF_SNAP_STATUS_TYPE_SNAP);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save command "
- "type in snap dict");
+ gf_event(EVENT_SNAPSHOT_RESTORED,
+ "snapshot_name=%s;snapshot_uuid=%s;volume_name=%s",
+ snap_name, snap_uuid, volname);
+
+ ret = 0;
+ break;
+
+ case GF_SNAP_OPTION_TYPE_DELETE:
+ ret = dict_get_int32_sizen(dict, "sub-cmd", &delete_cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not get sub-cmd");
goto out;
- }
+ }
- ret = snprintf (key, sizeof (key), "status.snap%d.snapname", index);
- if (ret < 0) {
- goto out;
- }
+ /*
+ * Need not generate any event (success or failure) for delete *
+ * all, as it will trigger individual delete for all snapshots *
+ */
+ if (delete_cmd == GF_SNAP_DELETE_TYPE_ALL) {
+ ret = 0;
+ break;
+ }
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not get snapname");
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
goto out;
- }
+ }
- ret = dict_set_str (snap_dict, "snapname", buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not save snapname "
- "in snap dict");
+ if (rsp->op_ret != 0) {
+ gf_event(EVENT_SNAPSHOT_DELETE_FAILED,
+ "snapshot_name=%s;error=%s", snap_name,
+ rsp->op_errstr ? rsp->op_errstr
+ : "Please check log file for details");
+ ret = 0;
+ break;
+ }
+
+ if (!snap_uuid) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
goto out;
+ }
- }
+ gf_event(EVENT_SNAPSHOT_DELETED,
+ "snapshot_name=%s;snapshot_uuid=%s", snap_name, snap_uuid);
- ret = dict_set_int32 (snap_dict, "type", GF_SNAP_OPTION_TYPE_STATUS);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Could not save command type");
+ ret = 0;
+ break;
+
+ case GF_SNAP_OPTION_TYPE_CLONE:
+ if (!clone_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get clone name");
goto out;
- }
+ }
- ret = dict_set_dynstr_with_alloc (snap_dict, "cmd-str",
- "snapshot status");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Could not save command string as status");
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snapname name");
goto out;
- }
+ }
- ret = dict_set_int32 (snap_dict, "hold_vol_locks", _gf_false);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Setting volume lock flag failed");
+ if (rsp->op_ret != 0) {
+ gf_event(EVENT_SNAPSHOT_CLONE_FAILED,
+ "snapshot_name=%s;clone_name=%s;error=%s", snap_name,
+ clone_name,
+ rsp->op_errstr ? rsp->op_errstr
+ : "Please check log file for details");
+ ret = 0;
+ break;
+ }
+
+ if (!snap_uuid) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
goto out;
- }
+ }
-out:
- return ret;
-}
+ gf_event(EVENT_SNAPSHOT_CLONED,
+ "snapshot_name=%s;clone_name=%s;clone_uuid=%s", snap_name,
+ clone_name, snap_uuid);
-int
-cli_snapshot_status (dict_t *dict, gf_cli_rsp *rsp,
- call_frame_t *frame)
-{
- char key[PATH_MAX] = "";
- int ret = -1;
- int status_cmd = -1;
- cli_local_t *local = NULL;
+ ret = 0;
+ break;
- GF_ASSERT (dict);
- GF_ASSERT (rsp);
- GF_ASSERT (frame);
+ case GF_SNAP_OPTION_TYPE_CONFIG:
+ if (rsp->op_ret != 0) {
+ gf_event(EVENT_SNAPSHOT_CONFIG_UPDATE_FAILED, "error=%s",
+ rsp->op_errstr ? rsp->op_errstr
+ : "Please check log file for details");
+ ret = 0;
+ break;
+ }
- local = ((call_frame_t *) frame) -> local;
- if (!local) {
- gf_log ("cli", GF_LOG_ERROR, "frame->local is NULL");
+ ret = dict_get_int32_sizen(dict, "config-command", &config_command);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch config type");
goto out;
- }
+ }
- if (rsp->op_ret) {
- if (rsp->op_errstr) {
- ret = dict_set_dynstr_with_alloc (local->dict,
- "op_err_str",
- rsp->op_errstr);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to set "
- "op_errstr in local dictionary");
- goto out;
- }
- }
- ret = rsp->op_ret;
- goto out;
- }
+ if (config_command == GF_SNAP_CONFIG_DISPLAY) {
+ ret = 0;
+ break;
+ }
- ret = dict_get_int32 (dict, "sub-cmd", &status_cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch status type");
- goto out;
- }
+ /* These are optional parameters therefore ignore the error */
+ ret = dict_get_uint64(dict, "snap-max-hard-limit", &hard_limit);
+ ret = dict_get_uint64(dict, "snap-max-soft-limit", &soft_limit);
+ ret = dict_get_str_sizen(dict, "auto-delete", &auto_delete);
+ ret = dict_get_str_sizen(dict, "snap-activate-on-create",
+ &snap_activate);
- if (status_cmd != GF_SNAP_STATUS_TYPE_SNAP) {
- dict_copy (dict, local->dict);
+ if (!hard_limit && !soft_limit && !auto_delete && !snap_activate) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR,
+ "At least one option from "
+ "snap-max-hard-limit, snap-max-soft-limit, "
+ "auto-delete and snap-activate-on-create "
+ "should be set");
goto out;
- }
+ }
+ if (hard_limit || soft_limit) {
+ snprintf(option, sizeof(option), "%s=%" PRIu64,
+ hard_limit ? "hard_limit" : "soft_limit",
+ hard_limit ? hard_limit : soft_limit);
+ } else if (auto_delete || snap_activate) {
+ snprintf(option, sizeof(option), "%s=%s",
+ auto_delete ? "auto-delete" : "snap-activate",
+ auto_delete ? auto_delete : snap_activate);
+ }
- ret = snprintf (key, sizeof (key), "status.snap0");
- if (ret < 0) {
- goto out;
- }
+ volname = NULL;
+ ret = dict_get_str_sizen(dict, "volname", &volname);
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_snapshot_status_single_snap (local, dict, key);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot status");
- goto out;
- }
- } else {
- ret = cli_get_single_snap_status (dict, key);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch "
- "status of snap");
- goto out;
- }
- }
+ snprintf(msg, sizeof(msg), "config_type=%s;%s",
+ volname ? "volume_config" : "system_config", option);
+
+ gf_event(EVENT_SNAPSHOT_CONFIG_UPDATED, "%s", msg);
+
+ ret = 0;
+ break;
+
+ default:
+ gf_log("cli", GF_LOG_WARNING,
+ "Cannot generate event for unknown type.");
+ ret = 0;
+ goto out;
+ }
- ret = 0;
out:
- return ret;
+ return ret;
}
-int
-gf_cli_snapshot_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- gf_cli_rsp rsp = {0, };
- dict_t *dict = NULL;
- char *snap_name = NULL;
- char *clone_name = NULL;
- int32_t type = 0;
- call_frame_t *frame = NULL;
- gf_boolean_t snap_driven = _gf_false;
- int8_t soft_limit_flag = -1;
- char *volname = NULL;
-
- if (req->rpc_status == -1) {
- ret = -1;
- goto out;
- }
+/*
+ * Fetch necessary data from dict at one place instead of *
+ * repeating the same code again and again. *
+ */
+static int
+gf_cli_snapshot_get_data_from_dict(dict_t *dict, char **snap_name,
+ char **volname, char **snap_uuid,
+ int8_t *soft_limit_flag, char **clone_name)
+{
+ int ret = -1;
- frame = myframe;
+ GF_VALIDATE_OR_GOTO("cli", dict, out);
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
+ if (snap_name) {
+ ret = dict_get_str_sizen(dict, "snapname", snap_name);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get snapname from dict");
}
+ }
- dict = dict_new ();
-
- if (!dict) {
- ret = -1;
- goto out;
+ if (volname) {
+ ret = dict_get_str_sizen(dict, "volname1", volname);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get volname1 from dict");
}
+ }
- ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+ if (snap_uuid) {
+ ret = dict_get_str_sizen(dict, "snapuuid", snap_uuid);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "failed to get snapuuid from dict");
+ }
+ }
- if (ret)
- goto out;
+ if (soft_limit_flag) {
+ ret = dict_get_int8(dict, "soft-limit-reach", soft_limit_flag);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG,
+ "failed to get soft-limit-reach from dict");
+ }
+ }
- ret = dict_get_int32 (dict, "type", &type);
+ if (clone_name) {
+ ret = dict_get_str_sizen(dict, "clonename", clone_name);
if (ret) {
- gf_log (frame->this->name, GF_LOG_ERROR, "failed to get type");
- goto out;
+ gf_log("cli", GF_LOG_DEBUG, "failed to get clonename from dict");
}
+ }
- /* Snapshot status and delete command is handled separately */
- if (global_state->mode & GLUSTER_MODE_XML &&
- GF_SNAP_OPTION_TYPE_STATUS != type &&
- GF_SNAP_OPTION_TYPE_DELETE != type) {
- ret = cli_xml_output_snapshot (type, dict, rsp.op_ret,
- rsp.op_errno, rsp.op_errstr);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Error outputting to xml");
- }
+ ret = 0;
+out:
+ return ret;
+}
- goto out;
+static int
+gf_cli_snapshot_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ int ret = -1;
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ dict_t *dict = NULL;
+ char *snap_name = NULL;
+ char *clone_name = NULL;
+ int32_t type = 0;
+ call_frame_t *frame = NULL;
+ gf_boolean_t snap_driven = _gf_false;
+ int8_t soft_limit_flag = -1;
+ char *volname = NULL;
+ char *snap_uuid = NULL;
+
+ GF_ASSERT(myframe);
+
+ if (req->rpc_status == -1) {
+ goto out;
+ }
+
+ frame = myframe;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, XDR_DECODE_FAIL);
+ 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)
+ goto out;
+
+ ret = dict_get_int32_sizen(dict, "type", &type);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR, "failed to get type");
+ goto out;
+ }
+
+ ret = gf_cli_snapshot_get_data_from_dict(
+ dict, &snap_name, &volname, &snap_uuid, &soft_limit_flag, &clone_name);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to fetch data from dict.");
+ goto out;
+ }
+
+#if (USE_EVENTS)
+ ret = gf_cli_generate_snapshot_event(&rsp, dict, type, snap_name, volname,
+ snap_uuid, clone_name);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to generate snapshot event");
+ goto out;
+ }
+#endif
+
+ /* Snapshot status and delete command is handled separately */
+ if (global_state->mode & GLUSTER_MODE_XML &&
+ GF_SNAP_OPTION_TYPE_STATUS != type &&
+ GF_SNAP_OPTION_TYPE_DELETE != type) {
+ ret = cli_xml_output_snapshot(type, dict, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
}
- switch (type) {
+ goto out;
+ }
+
+ switch (type) {
case GF_SNAP_OPTION_TYPE_CREATE:
- if (rsp.op_ret) {
- cli_err("snapshot create: failed: %s",
- rsp.op_errstr ? rsp.op_errstr :
- "Please check log file for details");
- ret = rsp.op_ret;
- goto out;
- }
+ if (rsp.op_ret) {
+ cli_err("snapshot create: failed: %s",
+ rsp.op_errstr ? rsp.op_errstr
+ : "Please check log file for details");
+ ret = rsp.op_ret;
+ goto out;
+ }
- ret = dict_get_str (dict, "snapname", &snap_name);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to get snap name");
- goto out;
- }
+ if (!snap_name) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto out;
+ }
- /* TODO : Instead of using volname1 directly use
- * volname$i in loop once snapshot of multiple
- * volumes are supported
- */
- ret = dict_get_str (dict, "volname1", &volname);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to get volume name");
- goto out;
- }
+ if (!volname) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR, "Failed to get volume name");
+ goto out;
+ }
- cli_out ("snapshot create: success: Snap %s created "
- "successfully", snap_name);
+ cli_out("snapshot create: success: Snap %s created successfully",
+ snap_name);
- ret = dict_get_int8 (dict, "soft-limit-reach",
- &soft_limit_flag);
- if (soft_limit_flag == 1) {
- cli_out ("Warning: Soft-limit of volume (%s) is "
- "reached. Snapshot creation is not possible "
- "once hard-limit is reached.", volname);
- }
- ret = 0;
- break;
+ if (soft_limit_flag == 1) {
+ cli_out(
+ "Warning: Soft-limit of volume (%s) is "
+ "reached. Snapshot creation is not possible "
+ "once hard-limit is reached.",
+ volname);
+ }
+ ret = 0;
+ break;
case GF_SNAP_OPTION_TYPE_CLONE:
- if (rsp.op_ret) {
- cli_err("snapshot clone: failed: %s",
- rsp.op_errstr ? rsp.op_errstr :
- "Please check log file for details");
- ret = rsp.op_ret;
- goto out;
- }
+ if (rsp.op_ret) {
+ cli_err("snapshot clone: failed: %s",
+ rsp.op_errstr ? rsp.op_errstr
+ : "Please check log file for details");
+ ret = rsp.op_ret;
+ goto out;
+ }
- ret = dict_get_str (dict, "clonename", &clone_name);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to get clone name");
- goto out;
- }
+ if (!clone_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get clone name");
+ goto out;
+ }
- ret = dict_get_str (dict, "snapname", &snap_name);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to get snapname name");
- goto out;
- }
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snapname name");
+ goto out;
+ }
- cli_out ("snapshot clone: success: Clone %s created "
- "successfully", clone_name);
+ cli_out("snapshot clone: success: Clone %s created successfully",
+ clone_name);
- ret = 0;
- break;
+ ret = 0;
+ break;
case GF_SNAP_OPTION_TYPE_RESTORE:
- /* TODO: Check if rsp.op_ret needs to be checked here. Or is
- * it ok to check this in the start of the function where we
- * get rsp.*/
- if (rsp.op_ret) {
- cli_err("snapshot restore: failed: %s",
- rsp.op_errstr ? rsp.op_errstr :
- "Please check log file for details");
- ret = rsp.op_ret;
- goto out;
- }
+ if (rsp.op_ret) {
+ cli_err("snapshot restore: failed: %s",
+ rsp.op_errstr ? rsp.op_errstr
+ : "Please check log file for details");
+ ret = rsp.op_ret;
+ goto out;
+ }
- ret = dict_get_str (dict, "snapname", &snap_name);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to get snap name");
- goto out;
- }
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto out;
+ }
- cli_out ("Snapshot restore: %s: Snap restored "
- "successfully", snap_name);
+ cli_out("Snapshot restore: %s: Snap restored successfully",
+ snap_name);
- ret = 0;
- break;
+ ret = 0;
+ break;
case GF_SNAP_OPTION_TYPE_ACTIVATE:
- /* TODO: Check if rsp.op_ret needs to be checked here. Or is
- * it ok to check this in the start of the function where we
- * get rsp.*/
- if (rsp.op_ret) {
- cli_err("snapshot activate: failed: %s",
- rsp.op_errstr ? rsp.op_errstr :
- "Please check log file for details");
- ret = rsp.op_ret;
- goto out;
- }
+ if (rsp.op_ret) {
+ cli_err("snapshot activate: failed: %s",
+ rsp.op_errstr ? rsp.op_errstr
+ : "Please check log file for details");
+ ret = rsp.op_ret;
+ goto out;
+ }
- ret = dict_get_str (dict, "snapname", &snap_name);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to get snap name");
- goto out;
- }
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto out;
+ }
- cli_out ("Snapshot activate: %s: Snap activated "
- "successfully", snap_name);
+ cli_out("Snapshot activate: %s: Snap activated successfully",
+ snap_name);
- ret = 0;
- break;
+ ret = 0;
+ break;
case GF_SNAP_OPTION_TYPE_DEACTIVATE:
- /* TODO: Check if rsp.op_ret needs to be checked here. Or is
- * it ok to check this in the start of the function where we
- * get rsp.*/
- if (rsp.op_ret) {
- cli_err("snapshot deactivate: failed: %s",
- rsp.op_errstr ? rsp.op_errstr :
- "Please check log file for details");
- ret = rsp.op_ret;
- goto out;
- }
+ if (rsp.op_ret) {
+ cli_err("snapshot deactivate: failed: %s",
+ rsp.op_errstr ? rsp.op_errstr
+ : "Please check log file for details");
+ ret = rsp.op_ret;
+ goto out;
+ }
- ret = dict_get_str (dict, "snapname", &snap_name);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to get snap name");
- goto out;
- }
+ if (!snap_name) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto out;
+ }
- cli_out ("Snapshot deactivate: %s: Snap deactivated "
- "successfully", snap_name);
+ cli_out("Snapshot deactivate: %s: Snap deactivated successfully",
+ snap_name);
- ret = 0;
- break;
+ ret = 0;
+ break;
case GF_SNAP_OPTION_TYPE_INFO:
- if (rsp.op_ret) {
- cli_err ("Snapshot info : failed: %s",
- rsp.op_errstr ? rsp.op_errstr :
- "Please check log file for details");
- ret = rsp.op_ret;
- goto out;
- }
+ if (rsp.op_ret) {
+ cli_err("Snapshot info : failed: %s",
+ rsp.op_errstr ? rsp.op_errstr
+ : "Please check log file for details");
+ ret = rsp.op_ret;
+ goto out;
+ }
- snap_driven = dict_get_str_boolean (dict, "snap-driven",
- _gf_false);
- if (snap_driven == _gf_true) {
- ret = cli_call_snapshot_info (dict, snap_driven);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Snapshot info failed");
- goto out;
- }
- } else if (snap_driven == _gf_false) {
- ret = cli_get_snaps_in_volume (dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Snapshot info failed");
- goto out;
- }
+ snap_driven = dict_get_str_boolean(dict, "snap-driven", _gf_false);
+ if (snap_driven == _gf_true) {
+ ret = cli_call_snapshot_info(dict, snap_driven);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Snapshot info failed");
+ goto out;
}
- break;
-
- case GF_SNAP_OPTION_TYPE_CONFIG:
- ret = cli_snapshot_config_display (dict, &rsp);
+ } else if (snap_driven == _gf_false) {
+ ret = cli_get_snaps_in_volume(dict);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to display "
- "snapshot config output.");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Snapshot info failed");
+ goto out;
}
- break;
+ }
+ break;
+
+ case GF_SNAP_OPTION_TYPE_CONFIG:
+ ret = cli_snapshot_config_display(dict, &rsp);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to display snapshot config output.");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_LIST:
- if (rsp.op_ret) {
- cli_err ("Snapshot list : failed: %s",
- rsp.op_errstr ? rsp.op_errstr :
- "Please check log file for details");
- ret = rsp.op_ret;
- goto out;
- }
+ if (rsp.op_ret) {
+ cli_err("Snapshot list : failed: %s",
+ rsp.op_errstr ? rsp.op_errstr
+ : "Please check log file for details");
+ ret = rsp.op_ret;
+ goto out;
+ }
- ret = cli_snapshot_list (dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to display "
- "snapshot list");
- goto out;
- }
- break;
+ ret = cli_snapshot_list(dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to display snapshot list");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_DELETE:
- ret = cli_snapshot_remove_reply (&rsp, dict, frame);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Failed to delete snap");
- goto out;
- }
- break;
+ ret = cli_snapshot_remove_reply(&rsp, dict, frame);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to delete snap");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_STATUS:
- ret = cli_snapshot_status (dict, &rsp, frame);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to display "
- "snapshot status output.");
- goto out;
- }
- break;
+ ret = cli_snapshot_status(dict, &rsp, frame);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to display snapshot status output.");
+ goto out;
+ }
+ break;
default:
- cli_err ("Unknown command executed");
- ret = -1;
- goto out;
- }
+ cli_err("Unknown command executed");
+ ret = -1;
+ goto out;
+ }
out:
- if (dict)
- dict_unref (dict);
- cli_cmd_broadcast_response (ret);
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
- free (rsp.dict.dict_val);
- free (rsp.op_errstr);
+ free(rsp.dict.dict_val);
+ free(rsp.op_errstr);
- return ret;
+ return ret;
}
int32_t
-gf_cli_snapshot_for_delete (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gf_cli_req req = {{0,}};
- dict_t *options = NULL;
- int32_t ret = -1;
- int32_t cmd = -1;
- cli_local_t *local = NULL;
- dict_t *snap_dict = NULL;
- int32_t snapcount = 0;
- int i = 0;
- char question[PATH_MAX] = "";
- char *volname = NULL;
- gf_answer_t answer = GF_ANSWER_NO;
-
- GF_VALIDATE_OR_GOTO ("cli", frame, out);
- GF_VALIDATE_OR_GOTO ("cli", frame->local, out);
- GF_VALIDATE_OR_GOTO ("cli", this, out);
- GF_VALIDATE_OR_GOTO ("cli", data, out);
-
- local = frame->local;
-
- options = data;
-
- ret = dict_get_int32 (local->dict, "sub-cmd", &cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get "
- "sub-cmd");
- goto out;
- }
+gf_cli_snapshot_for_delete(call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf_cli_req req = {{
+ 0,
+ }};
+ int32_t ret = -1;
+ int32_t cmd = -1;
+ cli_local_t *local = NULL;
+ dict_t *snap_dict = NULL;
+ int32_t snapcount = 0;
+ int i = 0;
+ char question[PATH_MAX] = "";
+ char *volname = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+
+ GF_VALIDATE_OR_GOTO("cli", frame, out);
+ GF_VALIDATE_OR_GOTO("cli", frame->local, out);
+ GF_VALIDATE_OR_GOTO("cli", this, out);
+ GF_VALIDATE_OR_GOTO("cli", data, out);
+
+ local = frame->local;
+
+ ret = dict_get_int32_sizen(local->dict, "sub-cmd", &cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get sub-cmd");
+ goto out;
+ }
+
+ /* No need multiple RPCs for individual snapshot delete*/
+ if (cmd == GF_SNAP_DELETE_TYPE_SNAP) {
+ ret = 0;
+ goto out;
+ }
- /* No need multiple RPCs for individual snapshot delete*/
- if (cmd == GF_SNAP_DELETE_TYPE_SNAP) {
- ret = 0;
- goto out;
- }
+ ret = dict_get_int32_sizen(local->dict, "snapcount", &snapcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not get snapcount");
+ goto out;
+ }
- ret = dict_get_int32 (local->dict, "snapcount",
- &snapcount);
+ if (global_state->mode & GLUSTER_MODE_XML) {
+#ifdef HAVE_LIB_XML
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"snapCount", "%d", snapcount);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not get "
- "snapcount");
- goto out;
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to write xml element \"snapCount\"");
+ goto out;
}
-
- if (global_state->mode & GLUSTER_MODE_XML) {
-#ifdef HAVE_LIB_XML
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"snapCount",
- "%d", snapcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to write "
- "xml element \"snapCount\"");
- goto out;
- }
#endif /* HAVE_LIB_XML */
- } else if (snapcount == 0) {
- cli_out ("No snapshots present");
- goto out;
+ } else if (snapcount == 0) {
+ cli_out("No snapshots present");
+ goto out;
+ }
+
+ if (cmd == GF_SNAP_DELETE_TYPE_ALL) {
+ snprintf(question, sizeof(question),
+ "System contains %d snapshot(s).\nDo you still "
+ "want to continue and delete them? ",
+ snapcount);
+ } else {
+ ret = dict_get_str_sizen(local->dict, "volname", &volname);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to fetch volname from local dictionary");
+ goto out;
}
- if (cmd == GF_SNAP_DELETE_TYPE_ALL) {
- snprintf (question, sizeof (question), "System contains %d "
- "snapshot(s).\nDo you still "
- "want to continue and delete them? ",
- snapcount);
- } else {
- ret = dict_get_str (local->dict, "volname", &volname);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to fetch "
- "volname from local dictionary");
- goto out;
- }
+ snprintf(question, sizeof(question),
+ "Volume (%s) contains %d snapshot(s).\nDo you still want to "
+ "continue and delete them? ",
+ volname, snapcount);
+ }
- snprintf (question, sizeof (question), "Volume (%s) contains "
- "%d snapshot(s).\nDo you still want to "
- "continue and delete them? ", volname,
- snapcount);
- }
-
- answer = cli_cmd_get_confirmation (global_state, question);
- if (GF_ANSWER_NO == answer) {
- ret = 0;
- gf_log ("cli", GF_LOG_DEBUG, "User cancelled "
- "snapshot delete operation for snap delete");
- goto out;
- }
+ answer = cli_cmd_get_confirmation(global_state, question);
+ if (GF_ANSWER_NO == answer) {
+ ret = 0;
+ gf_log("cli", GF_LOG_DEBUG,
+ "User cancelled snapshot delete operation for snap delete");
+ goto out;
+ }
- for (i = 1 ; i <= snapcount ; i++) {
- ret = -1;
+ for (i = 1; i <= snapcount; i++) {
+ ret = -1;
- snap_dict = dict_new();
- if (!snap_dict)
- goto out;
+ snap_dict = dict_new();
+ if (!snap_dict)
+ goto out;
- ret = cli_populate_req_dict_for_delete (snap_dict,
- local->dict, i);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not "
- "populate snap request dictionary");
- goto out;
- }
+ ret = cli_populate_req_dict_for_delete(snap_dict, local->dict, i);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not populate snap request dictionary");
+ goto out;
+ }
- ret = cli_to_glusterd (&req, frame,
- gf_cli_snapshot_cbk,
- (xdrproc_t) xdr_gf_cli_req, snap_dict,
- GLUSTER_CLI_SNAP, this, cli_rpc_prog,
- NULL);
- if (ret) {
- /* Fail the operation if deleting one of the
- * snapshots is failed
- */
- gf_log ("cli", GF_LOG_ERROR, "cli_to_glusterd "
- "for snapshot delete failed");
- goto out;
- }
- dict_unref (snap_dict);
- snap_dict = NULL;
+ ret = cli_to_glusterd(&req, frame, gf_cli_snapshot_cbk,
+ (xdrproc_t)xdr_gf_cli_req, snap_dict,
+ GLUSTER_CLI_SNAP, this, cli_rpc_prog, NULL);
+ if (ret) {
+ /* Fail the operation if deleting one of the
+ * snapshots is failed
+ */
+ gf_log("cli", GF_LOG_ERROR,
+ "cli_to_glusterd for snapshot delete failed");
+ goto out;
}
+ dict_unref(snap_dict);
+ snap_dict = NULL;
+ }
out:
- if (snap_dict)
- dict_unref (snap_dict);
+ if (snap_dict)
+ dict_unref(snap_dict);
+ GF_FREE(req.dict.dict_val);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_snapshot_for_status (call_frame_t *frame, xlator_t *this,
- void *data)
-{
+static int32_t
+gf_cli_snapshot_for_status(call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf_cli_req req = {{
+ 0,
+ }};
+ int ret = -1;
+ int32_t cmd = -1;
+ cli_local_t *local = NULL;
+ dict_t *snap_dict = NULL;
+ int snapcount = 0;
+ int i = 0;
+
+ GF_VALIDATE_OR_GOTO("cli", frame, out);
+ GF_VALIDATE_OR_GOTO("cli", frame->local, out);
+ GF_VALIDATE_OR_GOTO("cli", this, out);
+ GF_VALIDATE_OR_GOTO("cli", data, out);
+
+ local = frame->local;
+
+ ret = dict_get_int32_sizen(local->dict, "sub-cmd", &cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get sub-cmd");
+ goto out;
+ }
+
+ /* Snapshot status of single snap (i.e. GF_SNAP_STATUS_TYPE_SNAP)
+ * is already handled. Therefore we can return from here.
+ * If want to get status of all snaps in the system or volume then
+ * we should get them one by one.*/
+ if ((cmd == GF_SNAP_STATUS_TYPE_SNAP) ||
+ (cmd == GF_SNAP_STATUS_TYPE_ITER)) {
+ ret = 0;
+ goto out;
+ }
- gf_cli_req req = {{0,}};
- dict_t *options = NULL;
- int ret = -1;
- int32_t cmd = -1;
- cli_local_t *local = NULL;
- dict_t *snap_dict = NULL;
- int snapcount = 0;
- int i = 0;
+ ret = dict_get_int32_sizen(local->dict, "status.snapcount", &snapcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not get snapcount");
+ goto out;
+ }
- GF_VALIDATE_OR_GOTO ("cli", frame, out);
- GF_VALIDATE_OR_GOTO ("cli", frame->local, out);
- GF_VALIDATE_OR_GOTO ("cli", this, out);
- GF_VALIDATE_OR_GOTO ("cli", data, out);
+ if (snapcount == 0 && !(global_state->mode & GLUSTER_MODE_XML)) {
+ cli_out("No snapshots present");
+ }
- local = frame->local;
- options = data;
+ for (i = 0; i < snapcount; i++) {
+ ret = -1;
- ret = dict_get_int32 (local->dict, "sub-cmd", &cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get sub-cmd");
- goto out;
- }
+ snap_dict = dict_new();
+ if (!snap_dict)
+ goto out;
- /* Snapshot status of single snap (i.e. GF_SNAP_STATUS_TYPE_SNAP)
- * is already handled. Therefore we can return from here.
- * If want to get status of all snaps in the system or volume then
- * we should get them one by one.*/
- if (cmd == GF_SNAP_STATUS_TYPE_SNAP) {
- ret = 0;
- goto out;
- }
-
- ret = dict_get_int32 (local->dict, "status.snapcount", &snapcount);
+ ret = cli_populate_req_dict_for_status(snap_dict, local->dict, i);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not get snapcount");
- goto out;
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not populate snap request dictionary");
+ goto out;
}
- if (snapcount == 0 && !(global_state->mode & GLUSTER_MODE_XML)) {
- cli_out ("No snapshots present");
- }
-
- for (i = 0 ; i < snapcount; i++) {
- ret = -1;
-
- snap_dict = dict_new();
- if (!snap_dict)
- goto out;
-
- ret = cli_populate_req_dict_for_status (snap_dict,
- local->dict, i);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not "
- "populate snap request dictionary");
- goto out;
- }
+ ret = cli_to_glusterd(&req, frame, gf_cli_snapshot_cbk,
+ (xdrproc_t)xdr_gf_cli_req, snap_dict,
+ GLUSTER_CLI_SNAP, this, cli_rpc_prog, NULL);
- ret = cli_to_glusterd (&req, frame,
- gf_cli_snapshot_cbk,
- (xdrproc_t) xdr_gf_cli_req, snap_dict,
- GLUSTER_CLI_SNAP, this, cli_rpc_prog,
- NULL);
-
- /* Ignore the return value and error for snapshot
- * status of type "ALL" or "VOL"
- *
- * Scenario : There might be case where status command
- * and delete command might be issued at the same time.
- * In that case when status tried to fetch detail of
- * snap which has been deleted by concurrent command,
- * then it will show snapshot not present. Which will
- * not be appropriate.
- */
- dict_unref (snap_dict);
- snap_dict = NULL;
+ /* Ignore the return value and error for snapshot
+ * status of type "ALL" or "VOL"
+ *
+ * Scenario : There might be case where status command
+ * and delete command might be issued at the same time.
+ * In that case when status tried to fetch detail of
+ * snap which has been deleted by concurrent command,
+ * then it will show snapshot not present. Which will
+ * not be appropriate.
+ */
+ if (ret && (cmd != GF_SNAP_STATUS_TYPE_ALL &&
+ cmd != GF_SNAP_STATUS_TYPE_VOL)) {
+ gf_log("cli", GF_LOG_ERROR,
+ "cli_to_glusterd for snapshot status failed");
+ goto out;
}
+ dict_unref(snap_dict);
+ snap_dict = NULL;
+ }
- ret = 0;
+ ret = 0;
out:
- if (snap_dict)
- dict_unref (snap_dict);
+ if (snap_dict)
+ dict_unref(snap_dict);
+ GF_FREE(req.dict.dict_val);
- return ret;
+ return ret;
}
-int32_t
-gf_cli_snapshot (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- gf_cli_req req = {{0,}};
- dict_t *options = NULL;
- int ret = -1;
- int tmp_ret = -1;
- cli_local_t *local = NULL;
- char *err_str = NULL;
- int type = -1;
-
- if (!frame || !this || !data)
- goto out;
-
- if (!frame->local)
- goto out;
+static int32_t
+gf_cli_snapshot(call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf_cli_req req = {{
+ 0,
+ }};
+ dict_t *options = NULL;
+ int ret = -1;
+ int tmp_ret = -1;
+ cli_local_t *local = NULL;
+ char *err_str = NULL;
+ int type = -1;
- local = frame->local;
+ if (!frame || !frame->local || !this || !data)
+ goto out;
- options = data;
+ local = frame->local;
- ret = dict_get_int32 (local->dict, "type", &type);
+ options = data;
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_snapshot_begin_composite_op (local);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to begin "
- "snapshot xml composite op");
- goto out;
- }
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_snapshot_begin_composite_op(local);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to begin snapshot xml composite op");
+ goto out;
}
+ }
+ ret = cli_to_glusterd(&req, frame, gf_cli_snapshot_cbk,
+ (xdrproc_t)xdr_gf_cli_req, options, GLUSTER_CLI_SNAP,
+ this, cli_rpc_prog, NULL);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "cli_to_glusterd for snapshot failed");
+ goto xmlend;
+ }
- ret = cli_to_glusterd (&req, frame, gf_cli_snapshot_cbk,
- (xdrproc_t) xdr_gf_cli_req, options,
- GLUSTER_CLI_SNAP, this, cli_rpc_prog,
- NULL);
+ ret = dict_get_int32_sizen(local->dict, "type", &type);
+
+ if (GF_SNAP_OPTION_TYPE_STATUS == type) {
+ ret = gf_cli_snapshot_for_status(frame, this, data);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "cli_to_glusterd for "
- "snapshot failed");
- goto xmlend;
+ gf_log("cli", GF_LOG_ERROR,
+ "cli to glusterd for snapshot status command failed");
}
- if (GF_SNAP_OPTION_TYPE_STATUS == type) {
- ret = gf_cli_snapshot_for_status (frame, this, data);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "cli to glusterd "
- "for snapshot status command failed");
- }
+ goto xmlend;
+ }
- goto xmlend;
+ if (GF_SNAP_OPTION_TYPE_DELETE == type) {
+ ret = gf_cli_snapshot_for_delete(frame, this, data);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "cli to glusterd for snapshot delete command failed");
}
- if (GF_SNAP_OPTION_TYPE_DELETE == type) {
- ret = gf_cli_snapshot_for_delete (frame, this, data);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "cli to glusterd "
- "for snapshot delete command failed");
- }
-
- goto xmlend;
- }
+ goto xmlend;
+ }
- ret = 0;
+ ret = 0;
xmlend:
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_snapshot_end_composite_op (local);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to end "
- "snapshot xml composite op");
- goto out;
- }
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_snapshot_end_composite_op(local);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to end snapshot xml composite op");
+ goto out;
}
+ }
out:
- if (ret && local && GF_SNAP_OPTION_TYPE_STATUS == type) {
- tmp_ret = dict_get_str (local->dict, "op_err_str", &err_str);
- if (err_str) {
- cli_err ("Snapshot Status : failed: %s", err_str);
- dict_del (local->dict, "op_err_str");
- } else {
- cli_err ("Snapshot Status : failed: %s", "Please "
- "check log file for details");
- }
+ if (ret && local && GF_SNAP_OPTION_TYPE_STATUS == type) {
+ tmp_ret = dict_get_str_sizen(local->dict, "op_err_str", &err_str);
+ if (tmp_ret || !err_str) {
+ cli_err("Snapshot Status : failed: %s",
+ "Please check log file for details");
+ } else {
+ cli_err("Snapshot Status : failed: %s", err_str);
+ dict_del_sizen(local->dict, "op_err_str");
}
+ }
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- GF_FREE (req.dict.dict_val);
+ GF_FREE(req.dict.dict_val);
- if (global_state->mode & GLUSTER_MODE_XML) {
- /* XML mode handles its own error */
- ret = 0;
- }
- return ret;
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ /* XML mode handles its own error */
+ ret = 0;
+ }
+ return ret;
}
-int32_t
-gf_cli_barrier_volume_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- 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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
- gf_log ("cli", GF_LOG_DEBUG, "Received response to barrier");
-
- if (rsp.op_ret) {
- if (rsp.op_errstr && (strlen (rsp.op_errstr) > 1)) {
- cli_err ("volume barrier: command unsuccessful : %s",
- rsp.op_errstr);
- } else {
- cli_err ("volume barrier: command unsuccessful");
- }
+static int32_t
+gf_cli_barrier_volume_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status)
+ goto out;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+ gf_log("cli", GF_LOG_DEBUG, "Received response to barrier");
+
+ if (rsp.op_ret) {
+ if (rsp.op_errstr && (strlen(rsp.op_errstr) > 1)) {
+ cli_err("volume barrier: command unsuccessful : %s", rsp.op_errstr);
} else {
- cli_out ("volume barrier: command successful");
+ cli_err("volume barrier: command unsuccessful");
}
- ret = rsp.op_ret;
+ } else {
+ cli_out("volume barrier: command successful");
+ }
+ ret = rsp.op_ret;
out:
- if (dict)
- dict_unref (dict);
- free (rsp.op_errstr);
- free (rsp.dict.dict_val);
- cli_cmd_broadcast_response (ret);
- return ret;
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int
-gf_cli_barrier_volume (call_frame_t *frame, xlator_t *this, void *data)
+static int
+gf_cli_barrier_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;
+ gf_cli_req req = {{
+ 0,
+ }};
+ dict_t *options = NULL;
+ int ret = -1;
- options = data;
+ options = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_barrier_volume_cbk,
- (xdrproc_t) xdr_gf_cli_req, options,
- GLUSTER_CLI_BARRIER_VOLUME, this, cli_rpc_prog,
- NULL);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ ret = cli_to_glusterd(&req, frame, gf_cli_barrier_volume_cbk,
+ (xdrproc_t)xdr_gf_cli_req, options,
+ GLUSTER_CLI_BARRIER_VOLUME, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- GF_FREE (req.dict.dict_val);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int32_t
-gf_cli_get_vol_opt_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gf_cli_rsp rsp = {0,};
- int ret = -1;
- dict_t *dict = NULL;
- char *key = NULL;
- char *value = NULL;
- char msg[1024] = {0,};
- int i = 0;
- char dict_key[50] = {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 (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
- gf_log ("cli", GF_LOG_DEBUG, "Received response to get volume option");
-
- if (rsp.op_ret) {
- if (strcmp (rsp.op_errstr, ""))
- snprintf (msg, sizeof (msg), "volume get option: "
- "failed: %s", rsp.op_errstr);
- else
- snprintf (msg, sizeof (msg), "volume get option: "
- "failed");
-
- if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_str ("volGetopts", msg, rsp.op_ret,
- rsp.op_errno, rsp.op_errstr);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Error outputting to xml");
- }
- } else {
- cli_err ("%s", msg);
- }
- ret = rsp.op_ret;
- goto out_nolog;
- }
- 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,
- "Failed rsp_dict unserialization");
- goto out;
- }
+static int32_t
+gf_cli_get_vol_opt_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ char msg[1024] = {
+ 0,
+ };
+ int i = 0;
+ char dict_key[50] = {
+ 0,
+ };
+
+ GF_ASSERT(myframe);
+
+ if (-1 == req->rpc_status)
+ goto out;
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+ gf_log("cli", GF_LOG_DEBUG, "Received response to get volume option");
+
+ if (rsp.op_ret) {
+ if (strcmp(rsp.op_errstr, ""))
+ snprintf(msg, sizeof(msg), "volume get option: failed: %s",
+ rsp.op_errstr);
+ else
+ snprintf(msg, sizeof(msg), "volume get option: failed");
if (global_state->mode & GLUSTER_MODE_XML) {
- ret = cli_xml_output_vol_getopts (dict, rsp.op_ret,
- rsp.op_errno,
- rsp.op_errstr);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "xml output generation "
- "failed");
- ret = 0;
- }
- goto out;
+ ret = cli_xml_output_str("volGetopts", msg, rsp.op_ret,
+ rsp.op_errno, rsp.op_errstr);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ }
+ } else {
+ cli_err("%s", msg);
}
-
- ret = dict_get_int32 (dict, "count", &count);
+ ret = rsp.op_ret;
+ goto out_nolog;
+ }
+ 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, DICT_UNSERIALIZE_FAIL);
+ goto out;
+ }
+
+ if (global_state->mode & GLUSTER_MODE_XML) {
+ ret = cli_xml_output_vol_getopts(dict, rsp.op_ret, rsp.op_errno,
+ rsp.op_errstr);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to retrieve count "
- "from the dictionary");
- goto out;
- }
- if (count <= 0) {
- gf_log ("cli", GF_LOG_ERROR, "Value of count :%d is "
- "invalid", count);
- ret = -1;
- goto out;
+ gf_log("cli", GF_LOG_ERROR, XML_ERROR);
+ ret = 0;
+ }
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(dict, "warning", &value);
+ if (!ret) {
+ cli_out("%s", value);
+ }
+
+ ret = dict_get_int32_sizen(dict, "count", &count);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to retrieve count from the dictionary");
+ goto out;
+ }
+
+ if (count <= 0) {
+ gf_log("cli", GF_LOG_ERROR, "Value of count :%d is invalid", count);
+ ret = -1;
+ goto out;
+ }
+
+ cli_out("%-40s%-40s", "Option", "Value");
+ cli_out("%-40s%-40s", "------", "-----");
+ for (i = 1; i <= count; i++) {
+ ret = snprintf(dict_key, sizeof dict_key, "key%d", i);
+ ret = dict_get_strn(dict, dict_key, ret, &key);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to retrieve %s from the dictionary", dict_key);
+ goto out;
}
-
- cli_out ("%-40s%-40s", "Option", "Value");
- cli_out ("%-40s%-40s", "------", "-----");
- for (i=1; i<=count; i++) {
- sprintf (dict_key, "key%d", i);
- ret = dict_get_str (dict, dict_key, &key);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to"
- " retrieve %s from the "
- "dictionary", dict_key);
- goto out;
- }
- sprintf (dict_key, "value%d", i);
- ret = dict_get_str (dict, dict_key, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to "
- "retrieve key value for %s from"
- "the dictionary", dict_key);
- goto out;
- }
- cli_out ("%-40s%-40s", key, value);
+ ret = snprintf(dict_key, sizeof dict_key, "value%d", i);
+ ret = dict_get_strn(dict, dict_key, ret, &value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to retrieve key value for %s from the dictionary",
+ dict_key);
+ goto out;
}
+ cli_out("%-40s%-40s", key, value);
+ }
out:
- if (ret) {
- cli_out ("volume get option failed. Check the cli/glusterd log "
- "file for more details");
- }
+ if (ret) {
+ cli_out(
+ "volume get option failed. Check the cli/glusterd log "
+ "file for more details");
+ }
out_nolog:
- if (dict)
- dict_unref (dict);
- free (rsp.op_errstr);
- free (rsp.dict.dict_val);
- cli_cmd_broadcast_response (ret);
- return ret;
+ if (dict)
+ dict_unref(dict);
+ cli_cmd_broadcast_response(ret);
+ gf_free_xdr_cli_rsp(rsp);
+ return ret;
}
-int
-gf_cli_get_vol_opt (call_frame_t *frame, xlator_t *this, void *data)
+static int
+gf_cli_get_vol_opt(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;
+ gf_cli_req req = {{
+ 0,
+ }};
+ dict_t *options = NULL;
+ int ret = -1;
- options = data;
+ options = data;
- ret = cli_to_glusterd (&req, frame, gf_cli_get_vol_opt_cbk,
- (xdrproc_t)xdr_gf_cli_req, options,
- GLUSTER_CLI_GET_VOL_OPT, this, cli_rpc_prog,
- NULL);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ ret = cli_to_glusterd(&req, frame, gf_cli_get_vol_opt_cbk,
+ (xdrproc_t)xdr_gf_cli_req, options,
+ GLUSTER_CLI_GET_VOL_OPT, this, cli_rpc_prog, NULL);
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
- GF_FREE (req.dict.dict_val);
- return ret;
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
-int
-cli_to_glusterd (gf_cli_req *req, call_frame_t *frame,
- fop_cbk_fn_t cbkfn, xdrproc_t xdrproc, dict_t *dict,
- int procnum, xlator_t *this, rpc_clnt_prog_t *prog,
- struct iobref *iobref)
-{
- int ret = 0;
- size_t len = 0;
- char *cmd = NULL;
- int i = 0;
- const char **words = NULL;
- cli_local_t *local = NULL;
-
- if (!this || !frame || !dict) {
- ret = -1;
- goto out;
- }
+static int
+add_cli_cmd_timeout_to_dict(dict_t *dict)
+{
+ int ret = 0;
- if (!frame->local) {
- ret = -1;
- goto out;
+ if (cli_default_conn_timeout > 120) {
+ ret = dict_set_uint32(dict, "timeout", cli_default_conn_timeout);
+ if (ret) {
+ gf_log("cli", GF_LOG_INFO, "Failed to save timeout to dict");
}
+ }
+ return ret;
+}
- local = frame->local;
+static int
+cli_to_glusterd(gf_cli_req *req, call_frame_t *frame, fop_cbk_fn_t cbkfn,
+ xdrproc_t xdrproc, dict_t *dict, int procnum, xlator_t *this,
+ rpc_clnt_prog_t *prog, struct iobref *iobref)
+{
+ int ret = 0;
+ size_t len = 0;
+ char *cmd = NULL;
+ int i = 0;
+ const char **words = NULL;
+ cli_local_t *local = NULL;
- if (!local->words) {
- ret = -1;
- goto out;
- }
+ if (!this || !frame || !frame->local || !dict) {
+ ret = -1;
+ goto out;
+ }
- words = local->words;
+ local = frame->local;
- while (words[i])
- len += strlen (words[i++]) + 1;
+ if (!local->words) {
+ ret = -1;
+ goto out;
+ }
- cmd = GF_CALLOC (1, len, gf_common_mt_char);
+ words = local->words;
- if (!cmd) {
- ret = -1;
- goto out;
- }
+ while (words[i])
+ len += strlen(words[i++]) + 1;
- for (i = 0; words[i]; i++) {
- strncat (cmd, words[i], strlen (words[i]));
- if (words[i+1] != NULL)
- strncat (cmd, " ", strlen (" "));
- }
+ cmd = GF_MALLOC(len + 1, gf_common_mt_char);
+ if (!cmd) {
+ ret = -1;
+ goto out;
+ }
+ cmd[0] = '\0';
- cmd [len - 1] = '\0';
+ for (i = 0; words[i]; i++) {
+ strncat(cmd, words[i], len - 1);
+ if (words[i + 1] != NULL)
+ strncat(cmd, " ", len - 1);
+ }
- ret = dict_set_dynstr (dict, "cmd-str", cmd);
- if (ret)
- goto out;
+ ret = dict_set_dynstr_sizen(dict, "cmd-str", cmd);
+ if (ret)
+ goto out;
- ret = dict_allocate_and_serialize (dict, &(req->dict).dict_val,
- &(req->dict).dict_len);
+ ret = add_cli_cmd_timeout_to_dict(dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get serialized length of dict");
- goto out;
- }
+ ret = dict_allocate_and_serialize(dict, &(req->dict).dict_val,
+ &(req->dict).dict_len);
- ret = cli_cmd_submit (NULL, req, frame, prog, procnum, iobref, this,
- cbkfn, (xdrproc_t) xdrproc);
+ if (ret < 0) {
+ gf_log(this->name, GF_LOG_DEBUG,
+ "failed to get serialized length of dict");
+ goto out;
+ }
+ ret = cli_cmd_submit(NULL, req, frame, prog, procnum, iobref, this, cbkfn,
+ (xdrproc_t)xdrproc);
out:
- return ret;
-
+ return ret;
}
-int
-gf_cli_bitrot_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int ret = -1;
- gf_cli_rsp rsp = {0, };
- dict_t *dict = NULL;
- call_frame_t *frame = NULL;
+static int
+gf_cli_print_bitrot_scrub_status(dict_t *dict)
+{
+ int i = 1;
+ int j = 0;
+ int ret = -1;
+ int count = 0;
+ char key[64] = {
+ 0,
+ };
+ char *volname = NULL;
+ char *node_name = NULL;
+ char *scrub_freq = NULL;
+ char *state_scrub = NULL;
+ char *scrub_impact = NULL;
+ char *bad_file_str = NULL;
+ char *scrub_log_file = NULL;
+ char *bitrot_log_file = NULL;
+ uint64_t scrub_files = 0;
+ uint64_t unsigned_files = 0;
+ uint64_t scrub_time = 0;
+ uint64_t days = 0;
+ uint64_t hours = 0;
+ uint64_t minutes = 0;
+ uint64_t seconds = 0;
+ char *last_scrub = NULL;
+ uint64_t error_count = 0;
+ int8_t scrub_running = 0;
+ char *scrub_state_op = NULL;
+
+ ret = dict_get_int32_sizen(dict, "count", &count);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "failed to get count value from dictionary");
+ goto out;
+ }
+
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get volume name");
+
+ ret = dict_get_str_sizen(dict, "features.scrub", &state_scrub);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get scrub state value");
+
+ ret = dict_get_str_sizen(dict, "features.scrub-throttle", &scrub_impact);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get scrub impact value");
+
+ ret = dict_get_str_sizen(dict, "features.scrub-freq", &scrub_freq);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get scrub -freq value");
+
+ ret = dict_get_str_sizen(dict, "bitrot_log_file", &bitrot_log_file);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get bitrot log file location");
+
+ ret = dict_get_str_sizen(dict, "scrub_log_file", &scrub_log_file);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get scrubber log file location");
+
+ for (i = 1; i <= count; i++) {
+ snprintf(key, sizeof(key), "scrub-running-%d", i);
+ ret = dict_get_int8(dict, key, &scrub_running);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get scrubbed files");
+ if (scrub_running)
+ break;
+ }
- if (req->rpc_status == -1) {
- ret = -1;
- goto out;
- }
+ if (scrub_running)
+ gf_asprintf(&scrub_state_op, "%s (In Progress)", state_scrub);
+ else
+ gf_asprintf(&scrub_state_op, "%s (Idle)", state_scrub);
- frame = myframe;
+ cli_out("\n%s: %s\n", "Volume name ", volname);
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "Failed to decode xdr response");
- goto out;
- }
+ cli_out("%s: %s\n", "State of scrub", scrub_state_op);
- if (rsp.op_ret) {
- ret = -1;
- if (global_state->mode & GLUSTER_MODE_XML)
- goto xml_output;
+ cli_out("%s: %s\n", "Scrub impact", scrub_impact);
- if (strcmp (rsp.op_errstr, ""))
- cli_err ("Bitrot command failed : %s", rsp.op_errstr);
- else
- cli_err ("Bitrot command : failed");
+ cli_out("%s: %s\n", "Scrub frequency", scrub_freq);
- goto out;
- }
+ cli_out("%s: %s\n", "Bitrot error log location", bitrot_log_file);
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
+ cli_out("%s: %s\n", "Scrubber error log location", scrub_log_file);
- if (!dict) {
- ret = -1;
- goto out;
- }
+ for (i = 1; i <= count; i++) {
+ /* Reset the variables to prevent carryover of values */
+ node_name = NULL;
+ last_scrub = NULL;
+ scrub_time = 0;
+ error_count = 0;
+ scrub_files = 0;
+ unsigned_files = 0;
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &dict);
+ snprintf(key, sizeof(key), "node-name-%d", i);
+ ret = dict_get_str(dict, key, &node_name);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get node-name");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "failed to unserialize "
- "req-buffer to dictionary");
- goto out;
- }
- }
+ snprintf(key, sizeof(key), "scrubbed-files-%d", i);
+ ret = dict_get_uint64(dict, key, &scrub_files);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get scrubbed files");
- gf_log ("cli", GF_LOG_DEBUG, "Received resp to bit rot command");
+ snprintf(key, sizeof(key), "unsigned-files-%d", i);
+ ret = dict_get_uint64(dict, key, &unsigned_files);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get unsigned files");
-xml_output:
- 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;
- }
+ snprintf(key, sizeof(key), "scrub-duration-%d", i);
+ ret = dict_get_uint64(dict, key, &scrub_time);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get last scrub duration");
+
+ snprintf(key, sizeof(key), "last-scrub-time-%d", i);
+ ret = dict_get_str(dict, key, &last_scrub);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get last scrub time");
+ snprintf(key, sizeof(key), "error-count-%d", i);
+ ret = dict_get_uint64(dict, key, &error_count);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get error count");
- if (!rsp.op_ret)
- cli_out ("volume bitrot: success");
+ cli_out("\n%s\n",
+ "=========================================================");
- ret = rsp.op_ret;
+ cli_out("%s: %s\n", "Node", node_name);
-out:
- if (dict)
- dict_unref (dict);
+ cli_out("%s: %" PRIu64 "\n", "Number of Scrubbed files", scrub_files);
- free (rsp.dict.dict_val);
- free (rsp.op_errstr);
+ cli_out("%s: %" PRIu64 "\n", "Number of Skipped files", unsigned_files);
- cli_cmd_broadcast_response (ret);
+ if ((!last_scrub) || !strcmp(last_scrub, ""))
+ cli_out("%s: %s\n", "Last completed scrub time",
+ "Scrubber pending to complete.");
+ else
+ cli_out("%s: %s\n", "Last completed scrub time", last_scrub);
+
+ /* Printing last scrub duration time in human readable form*/
+ seconds = scrub_time % 60;
+ minutes = (scrub_time / 60) % 60;
+ hours = (scrub_time / 3600) % 24;
+ days = scrub_time / 86400;
+ cli_out("%s: %" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n",
+ "Duration of last scrub (D:M:H:M:S)", days, hours, minutes,
+ seconds);
+
+ cli_out("%s: %" PRIu64 "\n", "Error count", error_count);
- return ret;
+ if (error_count) {
+ cli_out("%s:\n", "Corrupted object's [GFID]");
+ /* Printing list of bad file's (Corrupted object's)*/
+ for (j = 0; j < error_count; j++) {
+ snprintf(key, sizeof(key), "quarantine-%d-%d", j, i);
+ ret = dict_get_str(dict, key, &bad_file_str);
+ if (!ret) {
+ cli_out("%s\n", bad_file_str);
+ }
+ }
+ }
+ }
+ cli_out("%s\n",
+ "=========================================================");
+out:
+ GF_FREE(scrub_state_op);
+ return 0;
}
-int32_t
-gf_cli_bitrot (call_frame_t *frame, xlator_t *this, void *data)
-{
- gf_cli_req req = { {0,} };
- dict_t *options = NULL;
- int ret = -1;
+static int
+gf_cli_bitrot_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ int ret = -1;
+ int type = 0;
+ gf_cli_rsp rsp = {
+ 0,
+ };
+ dict_t *dict = NULL;
+ char *scrub_cmd = NULL;
+ char *volname = NULL;
+ char *cmd_str = NULL;
+ char *cmd_op = NULL;
+
+ GF_ASSERT(myframe);
+
+ if (req->rpc_status == -1) {
+ goto out;
+ }
+
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log(((call_frame_t *)myframe)->this->name, GF_LOG_ERROR,
+ XDR_DECODE_FAIL);
+ goto out;
+ }
+
+ if (rsp.op_ret) {
+ ret = -1;
+ if (global_state->mode & GLUSTER_MODE_XML)
+ goto xml_output;
- if (!frame || !this || !data)
- goto out;
+ if (strcmp(rsp.op_errstr, ""))
+ cli_err("Bitrot command failed : %s", rsp.op_errstr);
+ else
+ cli_err("Bitrot command : failed");
+
+ goto out;
+ }
- options = data;
+ if (rsp.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new();
+
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize(rsp.dict.dict_val, rsp.dict.dict_len, &dict);
- ret = cli_to_glusterd (&req, frame, gf_cli_bitrot_cbk,
- (xdrproc_t) xdr_gf_cli_req, options,
- GLUSTER_CLI_BITROT, this, cli_rpc_prog,
- NULL);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "cli_to_glusterd for "
- "bitrot failed");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, DICT_UNSERIALIZE_FAIL);
+ goto out;
}
+ }
+
+ gf_log("cli", GF_LOG_DEBUG, "Received resp to bit rot command");
+
+ ret = dict_get_int32_sizen(dict, "type", &type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get command type");
+ goto out;
+ }
+
+ if ((type == GF_BITROT_CMD_SCRUB_STATUS) &&
+ !(global_state->mode & GLUSTER_MODE_XML)) {
+ ret = gf_cli_print_bitrot_scrub_status(dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to print bitrot scrub status");
+ }
+ goto out;
+ }
+
+ /* Ignoring the error, as using dict val for cli output only */
+ ret = dict_get_str_sizen(dict, "volname", &volname);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get volume name");
+
+ ret = dict_get_str_sizen(dict, "scrub-value", &scrub_cmd);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "Failed to get scrub command");
+
+ ret = dict_get_str_sizen(dict, "cmd-str", &cmd_str);
+ if (ret)
+ gf_log("cli", GF_LOG_TRACE, "failed to get command string");
+
+ if (cmd_str)
+ cmd_op = strrchr(cmd_str, ' ') + 1;
+
+ switch (type) {
+ case GF_BITROT_OPTION_TYPE_ENABLE:
+ cli_out("volume bitrot: success bitrot enabled for volume %s",
+ volname);
+ ret = 0;
+ goto out;
+ case GF_BITROT_OPTION_TYPE_DISABLE:
+ cli_out("volume bitrot: success bitrot disabled for volume %s",
+ volname);
+ ret = 0;
+ goto out;
+ case GF_BITROT_CMD_SCRUB_ONDEMAND:
+ cli_out("volume bitrot: scrubber started ondemand for volume %s",
+ volname);
+ ret = 0;
+ goto out;
+ case GF_BITROT_OPTION_TYPE_SCRUB:
+ if (!strncmp("pause", scrub_cmd, sizeof("pause")))
+ cli_out("volume bitrot: scrubber paused for volume %s",
+ volname);
+ if (!strncmp("resume", scrub_cmd, sizeof("resume")))
+ cli_out("volume bitrot: scrubber resumed for volume %s",
+ volname);
+ ret = 0;
+ goto out;
+ case GF_BITROT_OPTION_TYPE_SCRUB_FREQ:
+ cli_out(
+ "volume bitrot: scrub-frequency is set to %s "
+ "successfully for volume %s",
+ cmd_op, volname);
+ ret = 0;
+ goto out;
+ case GF_BITROT_OPTION_TYPE_SCRUB_THROTTLE:
+ cli_out(
+ "volume bitrot: scrub-throttle is set to %s "
+ "successfully for volume %s",
+ cmd_op, volname);
+ ret = 0;
+ goto out;
+ }
+
+xml_output:
+ 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, XML_ERROR);
+ goto out;
+ }
+
+ if (!rsp.op_ret)
+ cli_out("volume bitrot: success");
+
+ ret = rsp.op_ret;
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
-
- GF_FREE (req.dict.dict_val);
-
- return ret;
-}
-
-struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
- [GLUSTER_CLI_NULL] = {"NULL", NULL },
- [GLUSTER_CLI_PROBE] = {"PROBE_QUERY", gf_cli_probe},
- [GLUSTER_CLI_DEPROBE] = {"DEPROBE_QUERY", gf_cli_deprobe},
- [GLUSTER_CLI_LIST_FRIENDS] = {"LIST_FRIENDS", gf_cli_list_friends},
- [GLUSTER_CLI_UUID_RESET] = {"UUID_RESET", gf_cli3_1_uuid_reset},
- [GLUSTER_CLI_UUID_GET] = {"UUID_GET", gf_cli3_1_uuid_get},
- [GLUSTER_CLI_CREATE_VOLUME] = {"CREATE_VOLUME", gf_cli_create_volume},
- [GLUSTER_CLI_DELETE_VOLUME] = {"DELETE_VOLUME", gf_cli_delete_volume},
- [GLUSTER_CLI_START_VOLUME] = {"START_VOLUME", gf_cli_start_volume},
- [GLUSTER_CLI_STOP_VOLUME] = {"STOP_VOLUME", gf_cli_stop_volume},
- [GLUSTER_CLI_RENAME_VOLUME] = {"RENAME_VOLUME", gf_cli_rename_volume},
- [GLUSTER_CLI_DEFRAG_VOLUME] = {"DEFRAG_VOLUME", gf_cli_defrag_volume},
- [GLUSTER_CLI_GET_VOLUME] = {"GET_VOLUME", gf_cli_get_volume},
- [GLUSTER_CLI_GET_NEXT_VOLUME] = {"GET_NEXT_VOLUME", gf_cli_get_next_volume},
- [GLUSTER_CLI_SET_VOLUME] = {"SET_VOLUME", gf_cli_set_volume},
- [GLUSTER_CLI_ADD_BRICK] = {"ADD_BRICK", gf_cli_add_brick},
- [GLUSTER_CLI_REMOVE_BRICK] = {"REMOVE_BRICK", gf_cli_remove_brick},
- [GLUSTER_CLI_REPLACE_BRICK] = {"REPLACE_BRICK", gf_cli_replace_brick},
- [GLUSTER_CLI_LOG_ROTATE] = {"LOG ROTATE", gf_cli_log_rotate},
- [GLUSTER_CLI_GETSPEC] = {"GETSPEC", gf_cli_getspec},
- [GLUSTER_CLI_PMAP_PORTBYBRICK] = {"PMAP PORTBYBRICK", gf_cli_pmap_b2p},
- [GLUSTER_CLI_SYNC_VOLUME] = {"SYNC_VOLUME", gf_cli_sync_volume},
- [GLUSTER_CLI_RESET_VOLUME] = {"RESET_VOLUME", gf_cli_reset_volume},
- [GLUSTER_CLI_FSM_LOG] = {"FSM_LOG", gf_cli_fsm_log},
- [GLUSTER_CLI_GSYNC_SET] = {"GSYNC_SET", gf_cli_gsync_set},
- [GLUSTER_CLI_PROFILE_VOLUME] = {"PROFILE_VOLUME", gf_cli_profile_volume},
- [GLUSTER_CLI_QUOTA] = {"QUOTA", gf_cli_quota},
- [GLUSTER_CLI_TOP_VOLUME] = {"TOP_VOLUME", gf_cli_top_volume},
- [GLUSTER_CLI_GETWD] = {"GETWD", gf_cli_getwd},
- [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", gf_cli_status_volume},
- [GLUSTER_CLI_STATUS_ALL] = {"STATUS_ALL", gf_cli_status_volume_all},
- [GLUSTER_CLI_MOUNT] = {"MOUNT", gf_cli_mount},
- [GLUSTER_CLI_UMOUNT] = {"UMOUNT", gf_cli_umount},
- [GLUSTER_CLI_HEAL_VOLUME] = {"HEAL_VOLUME", gf_cli_heal_volume},
- [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME", gf_cli_statedump_volume},
- [GLUSTER_CLI_LIST_VOLUME] = {"LIST_VOLUME", gf_cli_list_volume},
- [GLUSTER_CLI_CLRLOCKS_VOLUME] = {"CLEARLOCKS_VOLUME", gf_cli_clearlocks_volume},
- [GLUSTER_CLI_COPY_FILE] = {"COPY_FILE", gf_cli_copy_file},
- [GLUSTER_CLI_SYS_EXEC] = {"SYS_EXEC", gf_cli_sys_exec},
- [GLUSTER_CLI_SNAP] = {"SNAP", gf_cli_snapshot},
- [GLUSTER_CLI_BARRIER_VOLUME] = {"BARRIER VOLUME", gf_cli_barrier_volume},
- [GLUSTER_CLI_GANESHA] = {"GANESHA", gf_cli_ganesha},
- [GLUSTER_CLI_GET_VOL_OPT] = {"GET_VOL_OPT", gf_cli_get_vol_opt},
- [GLUSTER_CLI_BITROT] = {"BITROT", gf_cli_bitrot},
- [GLUSTER_CLI_ATTACH_TIER] = {"ATTACH_TIER", gf_cli_attach_tier},
- [GLUSTER_CLI_DETACH_TIER] = {"DETACH_TIER", gf_cli_detach_tier},
- [GLUSTER_CLI_TIER] = {"TIER", gf_cli_tier}
+ if (dict)
+ dict_unref(dict);
+
+ gf_free_xdr_cli_rsp(rsp);
+ cli_cmd_broadcast_response(ret);
+ return ret;
+}
+
+static int32_t
+gf_cli_bitrot(call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf_cli_req req = {{
+ 0,
+ }};
+ dict_t *options = NULL;
+ int ret = -1;
+
+ options = data;
+
+ ret = cli_to_glusterd(&req, frame, gf_cli_bitrot_cbk,
+ (xdrproc_t)xdr_gf_cli_req, options,
+ GLUSTER_CLI_BITROT, this, cli_rpc_prog, NULL);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "cli_to_glusterd for bitrot failed");
+ goto out;
+ }
+
+out:
+ gf_log("cli", GF_LOG_DEBUG, RETURNING, ret);
+
+ GF_FREE(req.dict.dict_val);
+
+ return ret;
+}
+
+static struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
+ [GLUSTER_CLI_NULL] = {"NULL", NULL},
+ [GLUSTER_CLI_PROBE] = {"PROBE_QUERY", gf_cli_probe},
+ [GLUSTER_CLI_DEPROBE] = {"DEPROBE_QUERY", gf_cli_deprobe},
+ [GLUSTER_CLI_LIST_FRIENDS] = {"LIST_FRIENDS", gf_cli_list_friends},
+ [GLUSTER_CLI_UUID_RESET] = {"UUID_RESET", gf_cli3_1_uuid_reset},
+ [GLUSTER_CLI_UUID_GET] = {"UUID_GET", gf_cli3_1_uuid_get},
+ [GLUSTER_CLI_CREATE_VOLUME] = {"CREATE_VOLUME", gf_cli_create_volume},
+ [GLUSTER_CLI_DELETE_VOLUME] = {"DELETE_VOLUME", gf_cli_delete_volume},
+ [GLUSTER_CLI_START_VOLUME] = {"START_VOLUME", gf_cli_start_volume},
+ [GLUSTER_CLI_STOP_VOLUME] = {"STOP_VOLUME", gf_cli_stop_volume},
+ [GLUSTER_CLI_RENAME_VOLUME] = {"RENAME_VOLUME", gf_cli_rename_volume},
+ [GLUSTER_CLI_DEFRAG_VOLUME] = {"DEFRAG_VOLUME", gf_cli_defrag_volume},
+ [GLUSTER_CLI_GET_VOLUME] = {"GET_VOLUME", gf_cli_get_volume},
+ [GLUSTER_CLI_GET_NEXT_VOLUME] = {"GET_NEXT_VOLUME", gf_cli_get_next_volume},
+ [GLUSTER_CLI_SET_VOLUME] = {"SET_VOLUME", gf_cli_set_volume},
+ [GLUSTER_CLI_ADD_BRICK] = {"ADD_BRICK", gf_cli_add_brick},
+ [GLUSTER_CLI_REMOVE_BRICK] = {"REMOVE_BRICK", gf_cli_remove_brick},
+ [GLUSTER_CLI_REPLACE_BRICK] = {"REPLACE_BRICK", gf_cli_replace_brick},
+ [GLUSTER_CLI_LOG_ROTATE] = {"LOG ROTATE", gf_cli_log_rotate},
+ [GLUSTER_CLI_GETSPEC] = {"GETSPEC", gf_cli_getspec},
+ [GLUSTER_CLI_PMAP_PORTBYBRICK] = {"PMAP PORTBYBRICK", gf_cli_pmap_b2p},
+ [GLUSTER_CLI_SYNC_VOLUME] = {"SYNC_VOLUME", gf_cli_sync_volume},
+ [GLUSTER_CLI_RESET_VOLUME] = {"RESET_VOLUME", gf_cli_reset_volume},
+ [GLUSTER_CLI_FSM_LOG] = {"FSM_LOG", gf_cli_fsm_log},
+ [GLUSTER_CLI_GSYNC_SET] = {"GSYNC_SET", gf_cli_gsync_set},
+ [GLUSTER_CLI_PROFILE_VOLUME] = {"PROFILE_VOLUME", gf_cli_profile_volume},
+ [GLUSTER_CLI_QUOTA] = {"QUOTA", gf_cli_quota},
+ [GLUSTER_CLI_TOP_VOLUME] = {"TOP_VOLUME", gf_cli_top_volume},
+ [GLUSTER_CLI_GETWD] = {"GETWD", gf_cli_getwd},
+ [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", gf_cli_status_volume},
+ [GLUSTER_CLI_STATUS_ALL] = {"STATUS_ALL", gf_cli_status_volume_all},
+ [GLUSTER_CLI_MOUNT] = {"MOUNT", gf_cli_mount},
+ [GLUSTER_CLI_UMOUNT] = {"UMOUNT", gf_cli_umount},
+ [GLUSTER_CLI_HEAL_VOLUME] = {"HEAL_VOLUME", gf_cli_heal_volume},
+ [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME",
+ gf_cli_statedump_volume},
+ [GLUSTER_CLI_LIST_VOLUME] = {"LIST_VOLUME", gf_cli_list_volume},
+ [GLUSTER_CLI_CLRLOCKS_VOLUME] = {"CLEARLOCKS_VOLUME",
+ gf_cli_clearlocks_volume},
+ [GLUSTER_CLI_COPY_FILE] = {"COPY_FILE", gf_cli_copy_file},
+ [GLUSTER_CLI_SYS_EXEC] = {"SYS_EXEC", gf_cli_sys_exec},
+ [GLUSTER_CLI_SNAP] = {"SNAP", gf_cli_snapshot},
+ [GLUSTER_CLI_BARRIER_VOLUME] = {"BARRIER VOLUME", gf_cli_barrier_volume},
+ [GLUSTER_CLI_GET_VOL_OPT] = {"GET_VOL_OPT", gf_cli_get_vol_opt},
+ [GLUSTER_CLI_BITROT] = {"BITROT", gf_cli_bitrot},
+ [GLUSTER_CLI_GET_STATE] = {"GET_STATE", gf_cli_get_state},
+ [GLUSTER_CLI_RESET_BRICK] = {"RESET_BRICK", gf_cli_reset_brick},
+ [GLUSTER_CLI_GANESHA] = {"GANESHA", gf_cli_ganesha},
};
struct rpc_clnt_program cli_prog = {
- .progname = "Gluster CLI",
- .prognum = GLUSTER_CLI_PROGRAM,
- .progver = GLUSTER_CLI_VERSION,
- .numproc = GLUSTER_CLI_MAXVALUE,
- .proctable = gluster_cli_actors,
+ .progname = "Gluster CLI",
+ .prognum = GLUSTER_CLI_PROGRAM,
+ .progver = GLUSTER_CLI_VERSION,
+ .numproc = GLUSTER_CLI_MAXVALUE,
+ .proctable = gluster_cli_actors,
};
-struct rpc_clnt_procedure cli_quotad_procs[GF_AGGREGATOR_MAXVALUE] = {
- [GF_AGGREGATOR_NULL] = {"NULL", NULL},
- [GF_AGGREGATOR_LOOKUP] = {"LOOKUP", NULL},
- [GF_AGGREGATOR_GETLIMIT] = {"GETLIMIT", cli_quotad_getlimit},
+static struct rpc_clnt_procedure cli_quotad_procs[GF_AGGREGATOR_MAXVALUE] = {
+ [GF_AGGREGATOR_NULL] = {"NULL", NULL},
+ [GF_AGGREGATOR_LOOKUP] = {"LOOKUP", NULL},
+ [GF_AGGREGATOR_GETLIMIT] = {"GETLIMIT", cli_quotad_getlimit},
};
struct rpc_clnt_program cli_quotad_clnt = {
- .progname = "CLI Quotad client",
- .prognum = GLUSTER_AGGREGATOR_PROGRAM,
- .progver = GLUSTER_AGGREGATOR_VERSION,
- .numproc = GF_AGGREGATOR_MAXVALUE,
- .proctable = cli_quotad_procs,
+ .progname = "CLI Quotad client",
+ .prognum = GLUSTER_AGGREGATOR_PROGRAM,
+ .progver = GLUSTER_AGGREGATOR_VERSION,
+ .numproc = GF_AGGREGATOR_MAXVALUE,
+ .proctable = cli_quotad_procs,
};
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c
index 327cd6c6ffd..069de75801c 100644
--- a/cli/src/cli-xml-output.c
+++ b/cli/src/cli-xml-output.c
@@ -10,15 +10,12 @@
#include <stdlib.h>
#include "cli.h"
#include "cli1-xdr.h"
-#include "run.h"
-#include "compat.h"
-#include "syscall.h"
+#include <glusterfs/run.h>
+#include <glusterfs/compat.h>
+#include <glusterfs/syscall.h>
+#include <glusterfs/upcall-utils.h>
-
-enum gf_task_types {
- GF_TASK_TYPE_REBALANCE,
- GF_TASK_TYPE_REMOVE_BRICK
-};
+enum gf_task_types { GF_TASK_TYPE_REBALANCE, GF_TASK_TYPE_REMOVE_BRICK };
/*
* IMPORTANT NOTE:
@@ -42,4109 +39,3796 @@ enum gf_task_types {
* }
* #endif
*
- * Following the above formate ensures that all xml related code is compliled
+ * Following the above format ensures that all xml related code is compiled
* only when libxml2 is present, and also keeps the rest of the codebase free
* of #if (HAVE_LIB_XML)
*/
-
#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) \
+#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, xmlDocPtr *doc)
+cli_begin_xml_output(xmlTextWriterPtr *writer, xmlDocPtr *doc)
{
- int ret = -1;
+ int ret = -1;
- *writer = xmlNewTextWriterDoc (doc, 0);
- if (writer == NULL) {
- ret = -1;
- goto out;
- }
+ *writer = xmlNewTextWriterDoc(doc, 0);
+ if (*writer == NULL) {
+ ret = -1;
+ goto out;
+ }
- ret = xmlTextWriterStartDocument (*writer, "1.0", "UTF-8", "yes");
- XML_RET_CHECK_AND_GOTO (ret, 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);
+ /* <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;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
int
-cli_end_xml_output (xmlTextWriterPtr writer, xmlDocPtr doc)
+cli_end_xml_output(xmlTextWriterPtr writer, xmlDocPtr doc)
{
- int ret = -1;
+ int ret = -1;
- /* </cliOutput> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </cliOutput> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterEndDocument (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterEndDocument(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ /* Dump xml document to stdout and pretty format it */
+ xmlSaveFormatFileEnc("-", doc, "UTF-8", 1);
- /* Dump xml document to stdout and pretty format it */
- xmlSaveFormatFileEnc ("-", doc, "UTF-8", 1);
-
- xmlFreeTextWriter (writer);
- xmlFreeDoc (doc);
+ xmlFreeTextWriter(writer);
+ xmlFreeDoc(doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ 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)
+cli_xml_output_common(xmlTextWriterPtr writer, int op_ret, int op_errno,
+ char *op_errstr)
{
- int ret = -1;
+ int ret = -1;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"opRet",
- "%d", op_ret);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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 *)"opErrno", "%d",
+ op_errno);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- if (op_errstr)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"opErrstr",
- "%s", op_errstr);
- else
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"opErrstr",
- "%s", "");
+ if (op_errstr)
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"opErrstr",
+ "%s", op_errstr);
+ else
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"opErrstr",
+ "%s", "");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
int
-cli_xml_output_str (char *op, char *str, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_str(char *op, char *str, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret)
+ goto out;
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
- if (ret)
- goto out;
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
- if (op) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"cliOp",
- "%s", op);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ if (op) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"cliOp", "%s",
+ op);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- if (str) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"output",
- "%s", str);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ if (str) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"output", "%s",
+ str);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
#if (HAVE_LIB_XML)
int
-cli_xml_output_data_pair (dict_t *this, char *key, data_t *value,
- void *data)
+cli_xml_output_data_pair(dict_t *this, char *key, data_t *value, void *data)
{
- int ret = -1;
- xmlTextWriterPtr *writer = NULL;
+ int ret = -1;
+ xmlTextWriterPtr *writer = NULL;
- writer = (xmlTextWriterPtr *)data;
+ writer = (xmlTextWriterPtr *)data;
- ret = xmlTextWriterWriteFormatElement (*writer, (xmlChar *)key,
- "%s", value->data);
+ ret = xmlTextWriterWriteFormatElement(*writer, (xmlChar *)key, "%s",
+ value->data);
- return ret;
+ XML_RET_CHECK_AND_GOTO(ret, out);
+out:
+ return ret;
}
#endif
int
-cli_xml_output_dict ( char *op, dict_t *dict, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_dict(char *op, dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret)
+ goto out;
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
- if (ret)
- goto out;
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
- /* <"op"> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)op);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <"op"> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)op);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- if (dict)
- dict_foreach (dict, cli_xml_output_data_pair, &writer);
+ if (dict)
+ dict_foreach(dict, cli_xml_output_data_pair, &writer);
- /* </"op"> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </"op"> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
#if (HAVE_LIB_XML)
int
-cli_xml_output_vol_status_common (xmlTextWriterPtr writer, dict_t *dict,
- int brick_index, int *online,
- gf_boolean_t *node_present)
+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;
- char *uuid = NULL;
- int port = 0;
- int rdma_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;
+ int ret = -1;
+ char *hostname = NULL;
+ char *path = NULL;
+ char *uuid = NULL;
+ int port = 0;
+ int rdma_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;
+
+ /* <node>
+ * will be closed in the calling function cli_xml_output_vol_status()*/
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"node");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"hostname", "%s",
+ hostname);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ 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);
+
+ snprintf(key, sizeof(key), "brick%d.peerid", brick_index);
+ ret = dict_get_str(dict, key, &uuid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"peerid", "%s",
+ uuid);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ 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;
+
+ snprintf(key, sizeof(key), "brick%d.port", brick_index);
+ ret = dict_get_int32(dict, key, &port);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "brick%d.rdma_port", brick_index);
+ ret = dict_get_int32(dict, key, &rdma_port);
+
+ /* If the process is either offline or doesn't provide a port (shd)
+ * port = "N/A"
+ * else print the port number of the process.
+ */
+
+ /*
+ * Tag 'port' can be removed once console management is started
+ * to support new tag ports.
+ */
+
+ if (*online == 1 && port != 0)
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"port", "%d",
+ port);
+ else
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"port", "%s",
+ "N/A");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"ports");
+ if (*online == 1 && (port != 0 || rdma_port != 0)) {
+ if (port) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"tcp",
+ "%d", port);
+ } else {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"tcp",
+ "%s", "N/A");
}
- *node_present = _gf_true;
-
- /* <node>
- * will be closed in the calling function cli_xml_output_vol_status()*/
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"node");
- XML_RET_CHECK_AND_GOTO (ret, 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.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.peerid", brick_index);
- ret = dict_get_str (dict, key, &uuid);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"peerid",
- "%s", uuid);
- 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.port", brick_index);
- ret = dict_get_int32 (dict, key, &port);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.rdma_port", brick_index);
- ret = dict_get_int32 (dict, key, &rdma_port);
-
- /* If the process is either offline or doesn't provide a port (shd)
- * port = "N/A"
- * else print the port number of the process.
- */
-
- /*
- * Tag 'port' can be removed once console management is started
- * to support new tag ports.
- */
-
- if (*online == 1 && port != 0)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"port",
- "%d", port);
- else
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"port",
- "%s", "N/A");
-
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"ports");
- if (*online == 1 && (port != 0 || rdma_port != 0)) {
-
- if (port) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"tcp",
- "%d", port);
- } else {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"tcp",
- "%s", "N/A");
- }
-
- if (rdma_port) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"rdma",
- "%d", rdma_port);
- } else {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"rdma",
- "%s", "N/A");
- }
-
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ if (rdma_port) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"rdma",
+ "%d", rdma_port);
} else {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"tcp",
- "%s", "N/A");
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"rdma",
- "%s", "N/A");
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"rdma",
+ "%s", "N/A");
}
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ } else {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"tcp", "%s",
+ "N/A");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"rdma", "%s",
+ "N/A");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- 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)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"sizeTotal",
- "%"PRIu64, size_total);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.free", brick_index);
- ret = dict_get_uint64 (dict, key, &size_free);
- if (!ret)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"sizeFree",
- "%"PRIu64, size_free);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.device", brick_index);
- ret = dict_get_str (dict, key, &device);
- if (!ret)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"device",
- "%s", device);
-
- 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)
- 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)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"mntOptions",
- "%s", mnt_options);
-
- 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)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"fsName",
- "%s", fs_name);
-
- /* inode details are only available for ext 2/3/4 & xfs */
- if (!fs_name || !IS_EXT_FS(fs_name) || strcmp (fs_name, "xfs")) {
- ret = 0;
- goto out;
- }
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, 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)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"inodeSize",
- "%s", fs_name);
-
- 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)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"inodesTotal",
- "%"PRIu64, inodes_total);
-
- 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)
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"inodesFree",
- "%"PRIu64, inodes_free);
+ 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;
+ 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)
+cli_xml_output_vol_status_detail(xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index)
{
- 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);
+ 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) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"sizeTotal",
+ "%" PRIu64, size_total);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ snprintf(key, sizeof(key), "brick%d.free", brick_index);
+ ret = dict_get_uint64(dict, key, &size_free);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"sizeFree",
+ "%" PRIu64, size_free);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ snprintf(key, sizeof(key), "brick%d.device", brick_index);
+ ret = dict_get_str(dict, key, &device);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"device", "%s",
+ device);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ snprintf(key, sizeof(key), "brick%d.block_size", brick_index);
+ ret = dict_get_uint64(dict, key, &block_size);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"blockSize",
+ "%" PRIu64, block_size);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ snprintf(key, sizeof(key), "brick%d.mnt_options", brick_index);
+ ret = dict_get_str(dict, key, &mnt_options);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"mntOptions",
+ "%s", mnt_options);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ snprintf(key, sizeof(key), "brick%d.fs_name", brick_index);
+ ret = dict_get_str(dict, key, &fs_name);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"fsName", "%s",
+ fs_name);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ snprintf(key, sizeof(key), "brick%d.inode_size", brick_index);
+ ret = dict_get_str(dict, key, &inode_size);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"inodeSize",
+ "%s", fs_name);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ snprintf(key, sizeof(key), "brick%d.total_inodes", brick_index);
+ ret = dict_get_uint64(dict, key, &inodes_total);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"inodesTotal",
+ "%" PRIu64, inodes_total);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ snprintf(key, sizeof(key), "brick%d.free_inodes", brick_index);
+ ret = dict_get_uint64(dict, key, &inodes_free);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"inodesFree",
+ "%" PRIu64, inodes_free);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ } else {
+ ret = 0;
+ }
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ 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)
+cli_xml_output_vol_status_mempool(xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
{
- 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);
+ 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), "brick%d.mallinfo.smblks", brick_index);
- ret = dict_get_int32 (dict, key, &smblks);
+ 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 *)"smblks",
- "%d", smblks);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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), "brick%d.mallinfo.hblks", brick_index);
- ret = dict_get_int32 (dict, key, &hblks);
+ 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 *)"hblks",
- "%d", hblks);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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), "brick%d.mallinfo.hblkhd", brick_index);
- ret = dict_get_int32 (dict, key, &hblkhd);
+ 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 *)"hblkhd",
- "%d", hblkhd);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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), "brick%d.mallinfo.usmblks", brick_index);
- ret = dict_get_int32 (dict, key, &usmblks);
+ 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 *)"usmblks",
- "%d", usmblks);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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), "brick%d.mallinfo.fsmblks", brick_index);
- ret = dict_get_int32 (dict, key, &fsmblks);
+ 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 *)"fsmblks",
- "%d", fsmblks);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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), "brick%d.mallinfo.uordblks", brick_index);
- ret = dict_get_int32 (dict, key, &uordblks);
+ 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 *)"uordblks",
- "%d", uordblks);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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), "brick%d.mallinfo.fordblks", brick_index);
- ret = dict_get_int32 (dict, key, &fordblks);
+ 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 *)"fordblks",
- "%d", fordblks);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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), "brick%d.mallinfo.keepcost", brick_index);
- ret = dict_get_int32 (dict, key, &keepcost);
+ 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 *)"keepcost",
- "%d", keepcost);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </mallinfo> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"maxStdAlloc",
+ "%d", maxalloc);
+ 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;
+ /* </pool> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- /* </memStatus> */
- 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;
+ 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)
+cli_xml_output_vol_status_mem(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);
- }
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
- /* </clientsStatus> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ 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)
+cli_xml_output_vol_status_clients(xmlTextWriterPtr writer, dict_t *dict,
+ int brick_index)
{
- 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);
+ int ret = -1;
+ int client_count = 0;
+ char *hostname = NULL;
+ uint64_t bytes_read = 0;
+ uint64_t bytes_write = 0;
+ uint32_t opversion = 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);
+
+ 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 *)"gfid",
- "%s", gfid);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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), "%s.nlookup", prefix);
- ret = dict_get_uint64 (dict, key, &nlookup);
+ 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 *)"nLookup",
- "%"PRIu64, nlookup);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ 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), "%s.ref", prefix);
- ret = dict_get_uint32 (dict, key, &ref);
+ 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 *)"ref",
- "%"PRIu32, ref);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"bytesWrite",
+ "%" PRIu64, bytes_write);
+ 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);
+ snprintf(key, sizeof(key), "brick%d.client%d.opversion", brick_index,
+ i);
+ ret = dict_get_uint32(dict, key, &opversion);
if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"iaType",
- "%d", ia_type);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"opVersion",
+ "%" PRIu32, opversion);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </inode> */
- ret = xmlTextWriterEndElement (writer);
- 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;
+ 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)
+cli_xml_output_vol_status_inode_entry(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)
+ 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);
+
+ 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);
+
+ 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);
+
+ 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++) {
+ snprintf(key, sizeof(key), "%s.active%d", prefix, i);
+ ret = cli_xml_output_vol_status_inode_entry(writer, dict, key);
+ 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);
}
+ /* </active> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+
+ 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);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.lru_size", prefix);
- ret = dict_get_uint32 (dict, key, &lru_size);
- if (ret)
+ for (i = 0; i < lru_size; i++) {
+ snprintf(key, sizeof(key), "%s.lru%d", prefix, i);
+ ret = cli_xml_output_vol_status_inode_entry(writer, dict, key);
+ 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);
}
+ /* </lru> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+
+ 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);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.purge_size", prefix);
- ret = dict_get_uint32 (dict, key, &purge_size);
- if (ret)
+ for (i = 0; i < purge_size; i++) {
+ snprintf(key, sizeof(key), "%s.purge%d", prefix, i);
+ ret = cli_xml_output_vol_status_inode_entry(writer, dict, key);
+ 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);
}
+ /* </purge> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ 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)
+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);
+ 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);
- snprintf (key, sizeof (key), "brick%d.conncount", brick_index);
- ret = dict_get_int32 (dict, key, &conn_count);
+ 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;
- 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;
+ goto out;
- /* </connection> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ /* </connection> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- /* </inodeStatus> */
- 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;
+ 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)
+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);
+ 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);
+
+ 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);
+
+ 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);
+
+ 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++) {
+ snprintf(key, sizeof(key), "%s.fdentry%d.pid", prefix, i);
+ ret = dict_get_int32(dict, key, &fd_pid);
if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"refCount",
- "%d", refcount);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ continue;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.maxfds", prefix);
- ret = dict_get_uint32 (dict, key, &maxfds);
+ snprintf(key, sizeof(key), "%s.fdentry%d.refcount", prefix, i);
+ ret = dict_get_int32(dict, key, &fd_refcount);
if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"maxFds",
- "%"PRIu32, maxfds);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ continue;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.firstfree", prefix);
- ret = dict_get_int32 (dict, key, &firstfree);
+ snprintf(key, sizeof(key), "%s.fdentry%d.flags", prefix, i);
+ ret = dict_get_int32(dict, key, &fd_flags);
if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"firstFree",
- "%d", firstfree);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ continue;
- 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;
+ /* <fd> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"fd");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- 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;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"entry", "%d",
+ i + 1);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- 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);
- }
+ 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);
- /* </fdTable> */
- ret = xmlTextWriterEndElement (writer);
- 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;
+ 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)
+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);
+ 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);
- snprintf (key, sizeof (key), "brick%d.conncount", brick_index);
- ret = dict_get_int32 (dict, key, &conn_count);
+ 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;
- 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;
+ goto out;
- /* </connection> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ /* </connection> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- /* </fdStatus> */
- 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;
+ 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)
+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);
- }
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
- }
+ 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);
- }
+ 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);
- }
+ 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);
- }
+ 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);
+ /* </callFrame> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ 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)
+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);
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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++) {
+ snprintf(key, sizeof(key), "%s.frame%d", prefix, i);
+ ret = cli_xml_output_vol_status_callframe(writer, dict, key);
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;
- }
+ goto out;
+ }
- /* </callStack> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </callStack> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ 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)
+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);
+ 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);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ for (i = 0; i < call_count; i++) {
+ 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;
- 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;
- }
+ goto out;
+ }
- /* </callpoolStatus> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </callpoolStatus> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
int
-cli_xml_output_vol_status_begin (cli_local_t *local, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_vol_status_begin(cli_local_t *local, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- ret = cli_begin_xml_output (&(local->writer), &(local->doc));
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = cli_begin_xml_output(&(local->writer), &(local->doc));
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_xml_output_common (local->writer, op_ret, op_errno,
- op_errstr);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = cli_xml_output_common(local->writer, op_ret, op_errno, op_errstr);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <volStatus> */
- ret = xmlTextWriterStartElement (local->writer,
- (xmlChar *) "volStatus");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <volStatus> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"volStatus");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <volumes> */
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"volumes");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <volumes> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"volumes");
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_status_end (cli_local_t *local)
+cli_xml_output_vol_status_end(cli_local_t *local)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- /* </volumes> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </volumes> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </volStatus> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO(ret, out);
+ /* </volStatus> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_end_xml_output (local->writer, local->doc);
+ ret = cli_end_xml_output(local->writer, local->doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
#if (HAVE_LIB_XML)
int
-cli_xml_output_remove_brick_task_params (xmlTextWriterPtr writer, dict_t *dict,
- char *prefix)
+cli_xml_output_remove_brick_task_params(xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
{
- int ret = -1;
- char key[1024] = {0,};
- int count = 0;
- int i = 0;
- char *brick = NULL;
-
- /* <params> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"params");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key, sizeof (key), "%s.count", prefix);
- ret = dict_get_int32 (dict, key, &count);
+ int ret = -1;
+ char key[1024] = {
+ 0,
+ };
+ int count = 0;
+ int i = 0;
+ char *brick = NULL;
+
+ /* <params> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"params");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "%s.count", prefix);
+ ret = dict_get_int32(dict, key, &count);
+ if (ret)
+ goto out;
+
+ for (i = 1; i <= count; i++) {
+ snprintf(key, sizeof(key), "%s.brick%d", prefix, i);
+ ret = dict_get_str(dict, key, &brick);
if (ret)
- goto out;
-
- for (i = 1; i <= count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.brick%d", prefix, i);
- ret = dict_get_str (dict, key, &brick);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"brick",
- "%s", brick);
- XML_RET_CHECK_AND_GOTO (ret, out);
- brick = NULL;
- }
-
- /* </param> */
- ret = xmlTextWriterEndElement (writer);
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"brick", "%s",
+ brick);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ brick = NULL;
+ }
+ /* </param> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
int
-cli_xml_output_vol_status_tasks (cli_local_t *local, dict_t *dict) {
- int ret = -1;
- char *task_type = NULL;
- char *task_id_str = NULL;
- int status = 0;
- int tasks = 0;
- char key[1024] = {0,};
- int i = 0;
-
- /* <tasks> */
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"tasks");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_int32 (dict, "tasks", &tasks);
+cli_xml_output_vol_status_tasks(cli_local_t *local, dict_t *dict)
+{
+ int ret = -1;
+ char *task_type = NULL;
+ char *task_id_str = NULL;
+ int status = 0;
+ int tasks = 0;
+ char key[1024] = {
+ 0,
+ };
+ int i = 0;
+
+ /* <tasks> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"tasks");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_int32(dict, "tasks", &tasks);
+ if (ret)
+ goto out;
+
+ for (i = 0; i < tasks; i++) {
+ /* <task> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"task");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "task%d.type", i);
+ ret = dict_get_str(dict, key, &task_type);
if (ret)
- goto out;
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"type",
+ "%s", task_type);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- for (i = 0; i < tasks; i++) {
- /* <task> */
- ret = xmlTextWriterStartElement (local->writer,
- (xmlChar *)"task");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "task%d.id", i);
+ ret = dict_get_str(dict, key, &task_id_str);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"id",
+ "%s", task_id_str);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.type", i);
- ret = dict_get_str (dict, key, &task_type);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"type",
- "%s", task_type);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d.id", i);
- ret = dict_get_str (dict, key, &task_id_str);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"id",
- "%s", task_id_str);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%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);
-
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"statusStr",
- "%s",
- cli_vol_task_status_str[status]);
-
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "task%d", i);
- if (!strcmp (task_type, "Remove brick")) {
- ret = cli_xml_output_remove_brick_task_params
- (local->writer, dict, key);
- if (ret)
- goto out;
- }
+ snprintf(key, sizeof(key), "task%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);
+ ret = xmlTextWriterWriteFormatElement(local->writer,
+ (xmlChar *)"statusStr", "%s",
+ cli_vol_task_status_str[status]);
- /* </task> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "task%d", i);
+ if (!strcmp(task_type, "Remove brick")) {
+ ret = cli_xml_output_remove_brick_task_params(local->writer, dict,
+ key);
+ if (ret)
+ goto out;
}
- /* </tasks> */
- ret = xmlTextWriterEndElement (local->writer);
+ /* </task> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ /* </tasks> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
int
-cli_xml_output_vol_status_tasks_detail (cli_local_t *local, dict_t *dict)
+cli_xml_output_vol_status_tasks_detail(cli_local_t *local, dict_t *dict)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- char *volname = NULL;
+ int ret = -1;
+ char *volname = NULL;
- /*<volume>*/
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"volume");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /*<volume>*/
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"volName", "%s",
- volname);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = dict_get_str(dict, "volname", &volname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"volName",
+ "%s", volname);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_xml_output_vol_status_tasks (local, dict);
- if (ret)
- goto out;
+ ret = cli_xml_output_vol_status_tasks(local, dict);
+ if (ret)
+ goto out;
- /* </volume> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </volume> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- return ret;
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_status (cli_local_t *local, dict_t *dict)
+cli_xml_output_vol_status(cli_local_t *local, dict_t *dict)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- 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;
-
-
- /* <volume> */
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"volume");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (local->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 (local->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)
+ int ret = -1;
+ 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;
+ int type = -1;
+
+ /* <volume> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "volname", &volname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(local->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(local->writer, (xmlChar *)"nodeCount",
+ "%d", brick_count);
+
+ XML_RET_CHECK_AND_GOTO(ret, 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;
+
+ ret = dict_get_int32(dict, "type", &type);
+ if (ret)
+ goto out;
+
+ for (i = 0; i <= index_max; i++) {
+ ret = cli_xml_output_vol_status_common(local->writer, dict, i, &online,
+ &node_present);
+ if (ret) {
+ if (node_present)
goto out;
+ else
+ continue;
+ }
- index_max = brick_index_max + other_count;
+ switch (cmd & GF_CLI_STATUS_MASK) {
+ case GF_CLI_STATUS_DETAIL:
+ ret = cli_xml_output_vol_status_detail(local->writer, dict, i);
+ if (ret)
+ goto out;
+ break;
- for (i = 0; i <= index_max; i++) {
- ret = cli_xml_output_vol_status_common (local->writer, dict, i,
- &online, &node_present);
- if (ret) {
- if (node_present)
- goto out;
- else
- continue;
+ case GF_CLI_STATUS_MEM:
+ if (online) {
+ ret = cli_xml_output_vol_status_mem(local->writer, dict, i);
+ if (ret)
+ goto out;
}
+ break;
- switch (cmd & GF_CLI_STATUS_MASK) {
- case GF_CLI_STATUS_DETAIL:
- ret = cli_xml_output_vol_status_detail (local->writer,
- dict, i);
- if (ret)
- goto out;
- break;
-
- case GF_CLI_STATUS_MEM:
- if (online) {
- ret = cli_xml_output_vol_status_mem
- (local->writer, dict, i);
- if (ret)
- goto out;
- }
- break;
-
- case GF_CLI_STATUS_CLIENTS:
- if (online) {
- ret = cli_xml_output_vol_status_clients
- (local->writer, dict, i);
- if (ret)
- goto out;
- }
- break;
-
- case GF_CLI_STATUS_INODE:
- if (online) {
- ret = cli_xml_output_vol_status_inode
- (local->writer, dict, i);
- if (ret)
- goto out;
- }
- break;
-
- case GF_CLI_STATUS_FD:
- if (online) {
- ret = cli_xml_output_vol_status_fd
- (local->writer, dict, i);
- if (ret)
- goto out;
- }
- break;
-
- case GF_CLI_STATUS_CALLPOOL:
- if (online) {
- ret = cli_xml_output_vol_status_callpool
- (local->writer, dict, i);
- if (ret)
- goto out;
- }
- break;
- default:
- break;
+ case GF_CLI_STATUS_CLIENTS:
+ if (online) {
+ ret = cli_xml_output_vol_status_clients(local->writer, dict,
+ i);
+ if (ret)
+ goto out;
+ }
+ break;
+ case GF_CLI_STATUS_INODE:
+ if (online) {
+ ret = cli_xml_output_vol_status_inode(local->writer, dict,
+ i);
+ if (ret)
+ goto out;
}
+ break;
- /* </node> was opened in cli_xml_output_vol_status_common()*/
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ case GF_CLI_STATUS_FD:
+ if (online) {
+ ret = cli_xml_output_vol_status_fd(local->writer, dict, i);
+ if (ret)
+ goto out;
+ }
+ break;
- /* Tasks are only present when a normal volume status call is done on a
- * single volume or on all volumes
- */
- if (((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE) &&
- (cmd & (GF_CLI_STATUS_VOL|GF_CLI_STATUS_ALL))) {
- ret = cli_xml_output_vol_status_tasks (local, dict);
- if (ret)
+ case GF_CLI_STATUS_CALLPOOL:
+ if (online) {
+ ret = cli_xml_output_vol_status_callpool(local->writer,
+ dict, i);
+ if (ret)
goto out;
+ }
+ break;
+ default:
+ break;
}
- /* </volume> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </node> was opened in cli_xml_output_vol_status_common()*/
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+
+ /* Tasks are only present when a normal volume status call is done on a
+ * single volume or on all volumes
+ */
+ if (((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE) &&
+ (cmd & (GF_CLI_STATUS_VOL | GF_CLI_STATUS_ALL))) {
+ ret = cli_xml_output_vol_status_tasks(local, dict);
+ if (ret)
+ goto out;
+ }
+
+ /* </volume> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
#if (HAVE_LIB_XML)
int
-cli_xml_output_vol_top_rw_perf (xmlTextWriterPtr writer, dict_t *dict,
- int brick_index, int member_index)
+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);
+ int ret = -1;
+ char *filename = NULL;
+ uint64_t throughput = 0;
+ struct timeval tv = {
+ 0,
+ };
+ char timestr[GF_TIMESTR_SIZE] = {
+ 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);
+
+ 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);
+
+ snprintf(key, sizeof(key), "%d-time-sec-%d", brick_index, member_index);
+ ret = dict_get_int32(dict, key, (int32_t *)&tv.tv_sec);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%d-time-usec-%d", brick_index, member_index);
+ ret = dict_get_int32(dict, key, (int32_t *)&tv.tv_usec);
+ if (ret)
+ goto out;
+
+ gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT);
+ 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;
+ 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)
+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);
+ 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);
+
+ 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;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
int
-cli_xml_output_vol_top (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_vol_top(dict_t *dict, int op_ret, int op_errno, char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = 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, &doc);
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = 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, &doc);
+ 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);
+
+ snprintf(key, sizeof(key), "%d-brick", i);
+ ret = dict_get_str(dict, key, &brick_name);
if (ret)
- goto out;
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ brick_name);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ snprintf(key, sizeof(key), "%d-members", i);
+ ret = dict_get_int32(dict, key, &members);
if (ret)
- goto out;
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"members",
+ "%d", members);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <volTop> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volTop");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ switch (top_op) {
+ case GF_CLI_TOP_OPEN:
+ 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);
- 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);
+ 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);
- 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);
+ 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);
- while (i < brick_count) {
- i++;
+ case GF_CLI_TOP_READ:
+ case GF_CLI_TOP_WRITE:
+ case GF_CLI_TOP_OPENDIR:
+ case GF_CLI_TOP_READDIR:
- /* <brick> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"brick");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ break;
- 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:
-
- 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);
- }
-
- break;
-
- default:
- ret = -1;
- goto out;
+ case GF_CLI_TOP_READ_PERF:
+ case GF_CLI_TOP_WRITE_PERF:
+ snprintf(key, sizeof(key), "%d-throughput", i);
+ ret = dict_get_double(dict, key, &throughput);
+ if (!ret) {
+ snprintf(key, sizeof(key), "%d-time", i);
+ ret = dict_get_double(dict, key, &time_taken);
}
- 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;
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"throughput", "%f", throughput);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"timeTaken", "%f", time_taken);
+ XML_RET_CHECK_AND_GOTO(ret, out);
}
+ break;
- /* </brick> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ default:
+ ret = -1;
+ goto out;
}
- /* </volTop> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- ret = cli_end_xml_output (writer, doc);
+ 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, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
#if (HAVE_LIB_XML)
int
-cli_xml_output_vol_profile_stats (xmlTextWriterPtr writer, dict_t *dict,
- int brick_index, int interval)
+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);
- }
+ 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);
- /* </blockStats> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"size",
+ "%" PRIu32, (1U << i));
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <fopStats> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"fopStats");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "%d-%d-read-%" PRIu32, brick_index, interval,
+ (1U << 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);
- 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;
+ snprintf(key, sizeof(key), "%d-%d-write-%" PRIu32, brick_index,
+ interval, (1U << 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);
- 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;
+ /* </block> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- 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;
+ /* </blockStats> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- 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;
+ /* <fopStats> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"fopStats");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <fop> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"fop");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ snprintf(key, sizeof(key), "%d-%d-%d-hits", brick_index, interval, i);
+ ret = dict_get_uint64(dict, key, &hits);
+ if (ret)
+ goto cont;
- ret = xmlTextWriterWriteFormatElement
- (writer, (xmlChar *)"name","%s", gf_fop_list[i]);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "%d-%d-%d-avglatency", brick_index, interval,
+ i);
+ ret = dict_get_double(dict, key, &avg_latency);
+ if (ret)
+ goto cont;
- ret = xmlTextWriterWriteFormatElement
- (writer, (xmlChar *)"hits", "%"PRIu64, hits);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "%d-%d-%d-minlatency", brick_index, interval,
+ i);
+ ret = dict_get_double(dict, key, &min_latency);
+ if (ret)
+ goto cont;
- ret = xmlTextWriterWriteFormatElement
- (writer, (xmlChar *)"avgLatency", "%f", avg_latency);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "%d-%d-%d-maxlatency", brick_index, interval,
+ i);
+ ret = dict_get_double(dict, key, &max_latency);
+ if (ret)
+ goto cont;
- ret = xmlTextWriterWriteFormatElement
- (writer, (xmlChar *)"minLatency", "%f", min_latency);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <fop> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"fop");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement
- (writer, (xmlChar *)"maxLatency", "%f", max_latency);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ gf_fop_list[i]);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </fop> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"hits",
+ "%" PRIu64, hits);
+ XML_RET_CHECK_AND_GOTO(ret, out);
-cont:
- hits = 0;
- avg_latency = 0.0;
- min_latency = 0.0;
- max_latency = 0.0;
- }
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"avgLatency",
+ "%f", avg_latency);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </fopStats> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"minLatency",
+ "%f", min_latency);
+ 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);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"maxLatency",
+ "%f", max_latency);
+ 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);
+ /* </fop> */
+ ret = xmlTextWriterEndElement(writer);
+ 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);
+ cont:
+ hits = 0;
+ avg_latency = 0.0;
+ min_latency = 0.0;
+ max_latency = 0.0;
+ }
+
+ for (i = 0; i < GF_UPCALL_FLAGS_MAXVALUE; i++) {
+ hits = 0;
+ avg_latency = 0.0;
+ min_latency = 0.0;
+ max_latency = 0.0;
+
+ snprintf(key, sizeof(key), "%d-%d-%d-upcall-hits", brick_index,
+ interval, i);
+ ret = dict_get_uint64(dict, key, &hits);
if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"totalWrite",
- "%"PRIu64, total_write);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ continue;
+
+ /* <fop> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"fop");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </cumulativeStats> || </intervalStats> */
- ret = xmlTextWriterEndElement (writer);
- 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);
+ }
+
+ /* </fopStats> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ 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);
+
+ 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);
+
+ 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;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
int
-cli_xml_output_vol_profile (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_vol_profile(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
- char *volname = NULL;
- int op = GF_CLI_STATS_NONE;
- int info_op = GF_CLI_INFO_NONE;
- int brick_count = 0;
- char *brick_name = NULL;
- int interval = 0;
- char key[1024] = {0,};
- int i = 0;
- int stats_cleared = 0;
-
- ret = cli_begin_xml_output (&writer, &doc);
- 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 (GF_CLI_STATS_INFO != op)
- goto cont;
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ char *volname = NULL;
+ int op = GF_CLI_STATS_NONE;
+ int info_op = GF_CLI_INFO_NONE;
+ int brick_count = 0;
+ char *brick_name = NULL;
+ int interval = 0;
+ char key[1024] = {
+ 0,
+ };
+ int i = 0;
+ int stats_cleared = 0;
+
+ ret = cli_begin_xml_output(&writer, &doc);
+ 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 (GF_CLI_STATS_INFO != op)
+ 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);
+
+ ret = dict_get_int32(dict, "info-op", &info_op);
+ if (ret)
+ goto out;
+
+ while (i < brick_count) {
+ i++;
+
+ /* <brick> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"brick");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_int32 (dict, "count", &brick_count);
+ snprintf(key, sizeof(key), "%d-brick", i);
+ ret = dict_get_str(dict, key, &brick_name);
if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"brickCount",
- "%d", brick_count);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"brickName",
+ "%s", brick_name);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_int32 (dict, "info-op", &info_op);
- if (ret)
+ if (GF_CLI_INFO_CLEAR == info_op) {
+ snprintf(key, sizeof(key), "%d-stats-cleared", i);
+ ret = dict_get_int32(dict, key, &stats_cleared);
+ if (ret)
goto 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);
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"clearStats", "%s",
+ stats_cleared ? "Cleared stats." : "Failed to clear stats.");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ } else {
+ 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;
- ret = xmlTextWriterWriteFormatElement
- (writer, (xmlChar *)"brickName", "%s", brick_name);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- if (GF_CLI_INFO_CLEAR == info_op) {
- snprintf (key, sizeof (key), "%d-stats-cleared", i);
- ret = dict_get_int32 (dict, key, &stats_cleared);
- if (ret)
- goto out;
-
- ret = xmlTextWriterWriteFormatElement
- (writer, (xmlChar *)"clearStats", "%s",
- stats_cleared ? "Cleared stats." :
- "Failed to clear stats.");
- if (ret)
- goto out;
- } else {
- 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);
+ goto out;
+ }
+
+ 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);
+ /* </volProfile> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_list (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_vol_list(dict_t *dict, int op_ret, int op_errno, char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
- int count = 0;
- char *volname = NULL;
- char key[1024] = {0,};
- int i = 0;
-
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
-
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ int count = 0;
+ char *volname = NULL;
+ char key[1024] = {
+ 0,
+ };
+ int i = 0;
+
+ ret = cli_begin_xml_output(&writer, &doc);
+ 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++) {
+ snprintf(key, sizeof(key), "volume%d", i);
+ ret = dict_get_str(dict, key, &volname);
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);
- }
+ 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);
+ /* </volList> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
#if (HAVE_LIB_XML)
int
-cli_xml_output_vol_info_option (xmlTextWriterPtr writer, char *substr,
- char *optstr, char *valstr)
+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);
+ int ret = -1;
+ char *ptr1 = NULL;
+ char *ptr2 = NULL;
+
+ ptr1 = substr;
+ ptr2 = optstr;
+
+ while (ptr1) {
+ if (*ptr1 != *ptr2)
+ break;
+ ptr1++;
+ ptr2++;
+ if (!*ptr1)
+ break;
+ if (!*ptr2)
+ break;
+ }
+ 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;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
struct tmp_xml_option_logger {
- char *key;
- xmlTextWriterPtr writer;
+ char *key;
+ xmlTextWriterPtr writer;
};
static int
-_output_vol_info_option (dict_t *d, char *k, data_t *v,
- void *data)
+_output_vol_info_option(dict_t *d, char *k, data_t *v, void *data)
{
- int ret = 0;
- char *ptr = NULL;
- struct tmp_xml_option_logger *tmp = NULL;
+ int ret = 0;
+ char *ptr = NULL;
+ struct tmp_xml_option_logger *tmp = NULL;
- tmp = data;
+ tmp = data;
- ptr = strstr (k, "option.");
- if (!ptr)
- goto out;
+ ptr = strstr(k, "option.");
+ if (!ptr)
+ goto out;
- if (!v) {
- ret = -1;
- goto out;
- }
- ret = cli_xml_output_vol_info_option (tmp->writer, tmp->key, k,
- v->data);
+ if (!v) {
+ ret = -1;
+ goto out;
+ }
+ ret = cli_xml_output_vol_info_option(tmp->writer, tmp->key, k, v->data);
out:
- return ret;
+ return ret;
}
int
-cli_xml_output_vol_info_options (xmlTextWriterPtr writer, dict_t *dict,
- char *prefix)
+cli_xml_output_vol_info_options(xmlTextWriterPtr writer, dict_t *dict,
+ char *prefix)
{
- int ret = -1;
- int opt_count = 0;
- char key[1024] = {0,};
- struct tmp_xml_option_logger tmp = {0,};
-
- 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);
- snprintf (key, sizeof (key), "%s.option.", prefix);
-
- tmp.key = key;
- tmp.writer = writer;
- ret = dict_foreach (dict, _output_vol_info_option, &tmp);
- if (ret)
- goto out;
-
- /* </options> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ int ret = -1;
+ int opt_count = 0;
+ char key[1024] = {
+ 0,
+ };
+ struct tmp_xml_option_logger tmp = {
+ 0,
+ };
+
+ 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);
+ snprintf(key, sizeof(key), "%s.option.", prefix);
+
+ tmp.key = key;
+ tmp.writer = writer;
+ ret = dict_foreach(dict, _output_vol_info_option, &tmp);
+ if (ret)
+ goto out;
+
+ /* </options> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
int
-cli_xml_output_vol_info (cli_local_t *local, dict_t *dict)
+cli_xml_output_vol_info(cli_local_t *local, dict_t *dict)
{
#if (HAVE_LIB_XML)
- int ret = 0;
- int count = 0;
- char *volname = NULL;
- char *volume_id = NULL;
- char *uuid = NULL;
- int type = 0;
- int status = 0;
- int brick_count = 0;
- int dist_count = 0;
- int stripe_count = 0;
- int replica_count = 0;
- int disperse_count = 0;
- int redundancy_count = 0;
- int transport = 0;
- char *brick = NULL;
- char key[1024] = {0,};
- int i = 0;
- int j = 1;
- char *caps = NULL;
- int k __attribute__((unused)) = 0;
-
- ret = dict_get_int32 (dict, "count", &count);
+ int ret = 0;
+ int count = 0;
+ char *volname = NULL;
+ char *volume_id = NULL;
+ char *uuid = NULL;
+ int type = 0;
+ int status = 0;
+ int brick_count = 0;
+ int dist_count = 0;
+ int stripe_count = 0;
+ int replica_count = 0;
+ int arbiter_count = 0;
+ int snap_count = 0;
+ int isArbiter = 0;
+ int disperse_count = 0;
+ int redundancy_count = 0;
+ int transport = 0;
+ char *brick = NULL;
+ char key[1024] = {
+ 0,
+ };
+ int i = 0;
+ int j = 1;
+ char *caps __attribute__((unused)) = NULL;
+ int k __attribute__((unused)) = 0;
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ ret = xmlTextWriterWriteFormatElement(local->writer,
+ (xmlChar *)"statusStr", "%s",
+ cli_vol_status_str[status]);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "volume%d.snap_count", i);
+ ret = dict_get_int32(dict, key, &snap_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"snapshotCount", "%d", snap_count);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ 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);
+
+ 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",
+ (brick_count / dist_count));
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ 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);
+
+ 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);
+
+ snprintf(key, sizeof(key), "volume%d.arbiter_count", i);
+ ret = dict_get_int32(dict, key, &arbiter_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"arbiterCount", "%d", arbiter_count);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "volume%d.disperse_count", i);
+ ret = dict_get_int32(dict, key, &disperse_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"disperseCount", "%d", disperse_count);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "volume%d.redundancy_count", i);
+ ret = dict_get_int32(dict, key, &redundancy_count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(local->writer,
+ (xmlChar *)"redundancyCount",
+ "%d", redundancy_count);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "volume%d.type", i);
+ ret = dict_get_int32(dict, key, &type);
+ if (ret)
+ goto out;
+ /* For Distributed-(stripe,replicate,stipe-replicate,disperse)
+ types
+ */
+ type = get_vol_type(type, dist_count, brick_count);
+
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"type",
+ "%d", type);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"typeStr", "%s", vol_type_str[type]);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ 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);
+
+ j = 1;
+
+ /* <bricks> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"bricks");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ while (j <= brick_count) {
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"brick");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "volume%d.brick%d.uuid", i, j);
+ ret = dict_get_str(dict, key, &uuid);
+ if (ret)
goto out;
+ ret = xmlTextWriterWriteFormatAttribute(
+ local->writer, (xmlChar *)"uuid", "%s", uuid);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- for (i = 0; i < count; i++) {
- /* <volume> */
- ret = xmlTextWriterStartElement (local->writer,
- (xmlChar *)"volume");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "volume%d.brick%d", i, j);
+ ret = dict_get_str(dict, key, &brick);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatString(local->writer, "%s", brick);
+ 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.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);
-
- ret =xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"statusStr", "%s",
- cli_vol_status_str[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.disperse_count", i);
- ret = dict_get_int32 (dict, key, &disperse_count);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"disperseCount",
- "%d", disperse_count);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.redundancy_count", i);
- ret = dict_get_int32 (dict, key, &redundancy_count);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"redundancyCount",
- "%d", redundancy_count);
- 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;
- /* For Distributed-(stripe,replicate,stipe-replicate,disperse)
- types
- */
- if ((type != GF_CLUSTER_TYPE_TIER) && (type > 0) &&
- (dist_count < brick_count))
- type = type + GF_CLUSTER_TYPE_MAX - 1;
-
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"type",
- "%d", type);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"typeStr",
- "%s",
- cli_vol_type_str[type]);
- 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);
-
-#ifdef HAVE_BD_XLATOR
- /* <xlators> */
- ret = xmlTextWriterStartElement (local->writer,
- (xmlChar *)"xlators");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- for (k = 0; ; k++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key),"volume%d.xlator%d", i, k);
- ret = dict_get_str (dict, key, &caps);
- if (ret)
- break;
-
- /* <xlator> */
- ret = xmlTextWriterStartElement (local->writer,
- (xmlChar *)"xlator");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"name", "%s", caps);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* <capabilities> */
- ret = xmlTextWriterStartElement (local->writer,
- (xmlChar *)
- "capabilities");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- j = 0;
- for (j = 0; ;j++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key),
- "volume%d.xlator%d.caps%d", i, k, j);
- ret = dict_get_str (dict, key, &caps);
- if (ret)
- break;
- ret = xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"capability",
- "%s", caps);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
- /* </capabilities> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- /* </xlator> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
- ret = xmlTextWriterFullEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- /* </xlators> */
-#else
- caps = 0; /* Avoid compiler warnings when BD not enabled */
-#endif
- j = 1;
-
- /* <bricks> */
- ret = xmlTextWriterStartElement (local->writer,
- (xmlChar *)"bricks");
- XML_RET_CHECK_AND_GOTO (ret, out);
- while (j <= brick_count) {
- ret = xmlTextWriterStartElement
- (local->writer, (xmlChar *)"brick");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.brick%d.uuid",
- i, j);
- ret = dict_get_str (dict, key, &uuid);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatAttribute
- (local->writer, (xmlChar *)"uuid", "%s",
- uuid);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- 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 = xmlTextWriterWriteFormatString
- (local->writer, "%s", brick);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"name", "%s",
- brick);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"hostUuid", "%s",
- uuid);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </brick> */
- ret = xmlTextWriterEndElement (local->writer);
- 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;
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"name", "%s", brick);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </volume> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"hostUuid", "%s", uuid);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "volume%d.brick%d.isArbiter", i, j);
+ if (dict_get(dict, key))
+ isArbiter = 1;
+ else
+ isArbiter = 0;
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"isArbiter", "%d", isArbiter);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- if (volname) {
- GF_FREE (local->get_vol.volname);
- local->get_vol.volname = gf_strdup (volname);
- local->vol_count += count;
+ /* </brick> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ j++;
}
+ /* </bricks> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ 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);
+ }
+
+ if (volname) {
+ 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;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_info_begin (cli_local_t *local, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_vol_info_begin(cli_local_t *local, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- GF_ASSERT (local);
+ GF_ASSERT(local);
- ret = cli_begin_xml_output (&(local->writer), &(local->doc));
- if (ret)
- goto out;
+ ret = cli_begin_xml_output(&(local->writer), &(local->doc));
+ if (ret)
+ goto out;
- ret = cli_xml_output_common (local->writer, op_ret, op_errno,
- op_errstr);
- 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);
+ /* <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);
+ /* <volumes> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"volumes");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* Init vol count */
- local->vol_count = 0;
+ /* Init vol count */
+ local->vol_count = 0;
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_info_end (cli_local_t *local)
+cli_xml_output_vol_info_end(cli_local_t *local)
{
#if (HAVE_LIB_XML)
- int ret = -1;
-
- GF_ASSERT (local);
+ int ret = -1;
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"count",
- "%d", local->vol_count);
+ GF_ASSERT(local);
- /* </volumes> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"count",
+ "%d", local->vol_count);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ /* </volumes> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </volInfo> */
- 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->doc);
+ ret = cli_end_xml_output(local->writer, local->doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_quota_limit_list_end (cli_local_t *local)
+cli_xml_output_vol_quota_limit_list_end(cli_local_t *local)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- ret = xmlTextWriterEndElement (local->writer);
- if (ret) {
- goto out;
- }
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_end_xml_output (local->writer, local->doc);
+ ret = cli_end_xml_output(local->writer, local->doc);
out:
- return ret;
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_quota_limit_list_begin (cli_local_t *local, int op_ret,
- int op_errno, char *op_errstr)
+cli_xml_output_vol_quota_limit_list_begin(cli_local_t *local, int op_ret,
+ int op_errno, char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- ret = cli_begin_xml_output (&(local->writer), &(local->doc));
- if (ret)
- goto out;
+ ret = cli_begin_xml_output(&(local->writer), &(local->doc));
+ if (ret)
+ goto out;
- ret = cli_xml_output_common (local->writer, op_ret, op_errno,
- op_errstr);
- if (ret)
- goto out;
-
- /* <volQuota> */
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"volQuota");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = cli_xml_output_common(local->writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+ /* <volQuota> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"volQuota");
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
#if (HAVE_LIB_XML)
static int
-cli_xml_output_peer_hostnames (xmlTextWriterPtr writer, dict_t *dict,
- const char *prefix, int count)
+cli_xml_output_peer_hostnames(xmlTextWriterPtr writer, dict_t *dict,
+ const char *prefix, int count)
{
- int ret = -1;
- int i = 0;
- char *hostname = NULL;
- char key[1024] = {0,};
-
- /* <hostnames> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"hostnames");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- for (i = 0; i < count; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.hostname%d", prefix, 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);
- hostname = NULL;
- }
-
- /* </hostnames> */
- ret = xmlTextWriterEndElement (writer);
+ int ret = -1;
+ int i = 0;
+ char *hostname = NULL;
+ char key[1024] = {
+ 0,
+ };
+
+ /* <hostnames> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"hostnames");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ for (i = 0; i < count; i++) {
+ ret = snprintf(key, sizeof(key), "%s.hostname%d", prefix, i);
+ if (ret < 0)
+ goto out;
+ 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);
+ hostname = NULL;
+ }
+ /* </hostnames> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
int
-cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_peer_status(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
- int count = 0;
- char *uuid = NULL;
- char *hostname = NULL;
- int connected = 0;
- int state_id = 0;
- char *state_str = NULL;
- int hostname_count = 0;
- int i = 1;
- char key[1024] = {0,};
-
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ int count = 0;
+ char *uuid = NULL;
+ char *hostname = NULL;
+ int connected = 0;
+ int state_id = 0;
+ char *state_str = NULL;
+ int hostname_count = 0;
+ int i = 1;
+ char key[1024] = {
+ 0,
+ };
+
+ ret = cli_begin_xml_output(&writer, &doc);
+ 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);
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ snprintf(key, sizeof(key), "friend%d.uuid", i);
+ ret = dict_get_str(dict, key, &uuid);
if (ret)
- goto out;
-
- /* <peerStatus> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"peerStatus");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ goto out;
- if (!dict)
- goto cont;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"uuid", "%s",
+ uuid);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_int32 (dict, "count", &count);
+ snprintf(key, sizeof(key), "friend%d.hostname", i);
+ ret = dict_get_str(dict, key, &hostname);
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);
+ goto 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);
- 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.hostname_count", i);
- ret = dict_get_int32 (dict, key, &hostname_count);
- if ((ret == 0) && (hostname_count > 0)) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "friend%d", i);
- ret = cli_xml_output_peer_hostnames (writer, dict, key,
- hostname_count);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ snprintf(key, sizeof(key), "friend%d.hostname_count", i);
+ ret = dict_get_int32(dict, key, &hostname_count);
+ if ((ret == 0) && (hostname_count > 0)) {
+ snprintf(key, sizeof(key), "friend%d", i);
+ ret = cli_xml_output_peer_hostnames(writer, dict, key,
+ hostname_count);
+ 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;
+ 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);
+ 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) {
- /* ignore */
+ snprintf(key, sizeof(key), "friend%d.stateId", i);
+ ret = dict_get_int32(dict, key, &state_id);
+ if (!ret) {
+ /* ignore */
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"state", "%d", state_id);
- XML_RET_CHECK_AND_GOTO (ret, 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) {
- /* ignore */
+ snprintf(key, sizeof(key), "friend%d.state", i);
+ ret = dict_get_str(dict, key, &state_str);
+ if (!ret) {
+ /* ignore */
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"stateStr", "%s", state_str);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"stateStr",
+ "%s", state_str);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- /* </peer> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </peer> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- i++;
- }
+ i++;
+ }
cont:
- /* </peerStatus> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </peerStatus> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
#if (HAVE_LIB_XML)
/* Used for rebalance stop/status, remove-brick status */
int
-cli_xml_output_vol_rebalance_status (xmlTextWriterPtr writer, dict_t *dict,
- enum gf_task_types task_type)
+cli_xml_output_vol_rebalance_status(xmlTextWriterPtr writer, dict_t *dict,
+ enum gf_task_types task_type)
{
- int ret = -1;
- int count = 0;
- char *node_name = NULL;
- char *node_uuid = NULL;
- uint64_t files = 0;
- uint64_t size = 0;
- uint64_t lookups = 0;
- int status_rcd = 0;
- uint64_t failures = 0;
- uint64_t skipped = 0;
- uint64_t total_files = 0;
- uint64_t total_size = 0;
- uint64_t total_lookups = 0;
- uint64_t total_failures = 0;
- uint64_t total_skipped = 0;
- char key[1024] = {0,};
- int i = 0;
- int overall_status = -1;
- double elapsed = 0;
- double overall_elapsed = 0;
-
- if (!dict) {
- ret = 0;
- goto out;
- }
+ int ret = -1;
+ int count = 0;
+ char *node_name = NULL;
+ char *node_uuid = NULL;
+ uint64_t files = 0;
+ uint64_t size = 0;
+ uint64_t lookups = 0;
+ int status_rcd = 0;
+ uint64_t failures = 0;
+ uint64_t skipped = 0;
+ uint64_t total_files = 0;
+ uint64_t total_size = 0;
+ uint64_t total_lookups = 0;
+ uint64_t total_failures = 0;
+ uint64_t total_skipped = 0;
+ char key[1024] = {
+ 0,
+ };
+ int i = 0;
+ int overall_status = -1;
+ double elapsed = 0;
+ double overall_elapsed = 0;
+
+ if (!dict) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_int32(dict, "count", &count);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"nodeCount", "%d",
+ count);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ while (i < count) {
+ i++;
+ /* Getting status early, to skip nodes that don't have the
+ * rebalance process started
+ */
+ snprintf(key, sizeof(key), "status-%d", i);
+ ret = dict_get_int32(dict, key, &status_rcd);
- ret = dict_get_int32 (dict, "count", &count);
+ /* If glusterd is down it fails to get the status, try
+ getting status from other nodes */
if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"nodeCount",
- "%d", count);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- while (i < count) {
- i++;
- /* Getting status early, to skip nodes that don't have the
- * rebalance process started
- */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "status-%d", i);
- ret = dict_get_int32 (dict, key, &status_rcd);
-
- /* If glusterd is down it fails to get the status, try
- getting status from other nodes */
- if (ret)
- continue;
- if (GF_DEFRAG_STATUS_NOT_STARTED == status_rcd)
- continue;
-
- /* <node> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"node");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "node-name-%d", i);
- ret = dict_get_str (dict, key, &node_name);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"nodeName",
- "%s", node_name);
+ continue;
+ if (GF_DEFRAG_STATUS_NOT_STARTED == status_rcd)
+ continue;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "node-uuid-%d", i);
- ret = dict_get_str (dict, key, &node_uuid);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"id",
- "%s", node_uuid);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "files-%d", i);
- ret = dict_get_uint64 (dict, key, &files);
- if (ret)
- goto out;
- total_files += files;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"files",
- "%"PRIu64, files);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "size-%d", i);
- ret = dict_get_uint64 (dict, key, &size);
- if (ret)
- goto out;
- total_size += size;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"size",
- "%"PRIu64,size);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "lookups-%d", i);
- ret = dict_get_uint64 (dict, key, &lookups);
- if (ret)
- goto out;
- total_lookups += lookups;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"lookups",
- "%"PRIu64, lookups);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "failures-%d", i);
- ret = dict_get_uint64 (dict, key, &failures);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "skipped-%d", i);
-
- ret = dict_get_uint64 (dict, key, &skipped);
- if (ret)
- goto out;
+ /* <node> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"node");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- if (task_type == GF_TASK_TYPE_REMOVE_BRICK) {
- failures += skipped;
- skipped = 0;
- }
+ snprintf(key, sizeof(key), "node-name-%d", i);
+ ret = dict_get_str(dict, key, &node_name);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"nodeName",
+ "%s", node_name);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- total_failures += failures;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"failures",
- "%"PRIu64, failures);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "node-uuid-%d", i);
+ ret = dict_get_str(dict, key, &node_uuid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"id", "%s",
+ node_uuid);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- total_skipped += skipped;
+ snprintf(key, sizeof(key), "files-%d", i);
+ ret = dict_get_uint64(dict, key, &files);
+ if (ret)
+ goto out;
+ total_files += files;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"files",
+ "%" PRIu64, files);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"skipped",
- "%"PRIu64, skipped);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "size-%d", i);
+ ret = dict_get_uint64(dict, key, &size);
+ if (ret)
+ goto out;
+ total_size += size;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"size",
+ "%" PRIu64, size);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"status",
- "%d", status_rcd);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "lookups-%d", i);
+ ret = dict_get_uint64(dict, key, &lookups);
+ if (ret)
+ goto out;
+ total_lookups += lookups;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"lookups",
+ "%" PRIu64, lookups);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"statusStr",
- "%s",
- cli_vol_task_status_str[status_rcd]);
+ snprintf(key, sizeof(key), "failures-%d", i);
+ ret = dict_get_uint64(dict, key, &failures);
+ if (ret)
+ goto out;
- memset (key, 0, 256);
- snprintf (key, 256, "run-time-%d", i);
- ret = dict_get_double (dict, key, &elapsed);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"runtime",
- "%.2f", elapsed);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ snprintf(key, sizeof(key), "skipped-%d", i);
- if (elapsed > overall_elapsed) {
- overall_elapsed = elapsed;
- }
+ ret = dict_get_uint64(dict, key, &skipped);
+ if (ret)
+ goto out;
- /* Rebalance has 5 states,
- * NOT_STARTED, STARTED, STOPPED, COMPLETE, FAILED
- * The precedence used to determine the aggregate status is as
- * below,
- * STARTED > FAILED > STOPPED > COMPLETE > NOT_STARTED
- */
- /* TODO: Move this to a common place utilities that both CLI and
- * glusterd need.
- * Till then if the below algorithm is changed, change it in
- * glusterd_volume_status_aggregate_tasks_status in
- * glusterd-utils.c
- */
-
- if (-1 == overall_status)
- overall_status = status_rcd;
- int rank[] = {
- [GF_DEFRAG_STATUS_STARTED] = 1,
- [GF_DEFRAG_STATUS_FAILED] = 2,
- [GF_DEFRAG_STATUS_STOPPED] = 3,
- [GF_DEFRAG_STATUS_COMPLETE] = 4,
- [GF_DEFRAG_STATUS_NOT_STARTED] = 5
- };
- if (rank[status_rcd] <= rank[overall_status])
- overall_status = status_rcd;
-
- /* </node> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ if (task_type == GF_TASK_TYPE_REMOVE_BRICK) {
+ failures += skipped;
+ skipped = 0;
}
- /* Aggregate status */
- /* <aggregate> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"aggregate");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"files",
- "%"PRIu64, total_files);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"size",
- "%"PRIu64, total_size);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"lookups",
- "%"PRIu64, total_lookups);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"failures",
- "%"PRIu64, total_failures);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"skipped",
- "%"PRIu64, total_skipped);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"status",
- "%d", overall_status);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ total_failures += failures;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"failures",
+ "%" PRIu64, failures);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"statusStr",
- "%s",
- cli_vol_task_status_str[overall_status]);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ total_skipped += skipped;
- ret = xmlTextWriterWriteFormatElement (writer,(xmlChar *)"runtime",
- "%.2f", overall_elapsed);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"skipped",
+ "%" PRIu64, skipped);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </aggregate> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"status", "%d",
+ status_rcd);
+ XML_RET_CHECK_AND_GOTO(ret, out);
-out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-#endif
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"statusStr", "%s",
+ cli_vol_task_status_str[status_rcd]);
+ XML_RET_CHECK_AND_GOTO(ret, out);
-int
-cli_xml_output_vol_tier_status (xmlTextWriterPtr writer, dict_t *dict,
- enum gf_task_types task_type)
-{
-#if (HAVE_LIB_XML)
+ snprintf(key, sizeof(key), "run-time-%d", i);
+ ret = dict_get_double(dict, key, &elapsed);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"runtime",
+ "%.2f", elapsed);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- int ret = -1;
- int count = 0;
- char *node_name = NULL;
- char *status_str = NULL;
- uint64_t promoted = 0;
- uint64_t demoted = 0;
- int i = 1;
- char key[1024] = {0,};
- gf_defrag_status_t status_rcd = GF_DEFRAG_STATUS_NOT_STARTED;
+ if (elapsed > overall_elapsed) {
+ overall_elapsed = elapsed;
+ }
+ /* Rebalance has 5 states,
+ * NOT_STARTED, STARTED, STOPPED, COMPLETE, FAILED
+ * The precedence used to determine the aggregate status is as
+ * below,
+ * STARTED > FAILED > STOPPED > COMPLETE > NOT_STARTED
+ */
+ /* TODO: Move this to a common place utilities that both CLI and
+ * glusterd need.
+ * Till then if the below algorithm is changed, change it in
+ * glusterd_volume_status_aggregate_tasks_status in
+ * glusterd-utils.c
+ */
- GF_VALIDATE_OR_GOTO ("cli", dict, out);
+ if (-1 == overall_status)
+ overall_status = status_rcd;
+ int rank[] = {[GF_DEFRAG_STATUS_STARTED] = 1,
+ [GF_DEFRAG_STATUS_FAILED] = 2,
+ [GF_DEFRAG_STATUS_STOPPED] = 3,
+ [GF_DEFRAG_STATUS_COMPLETE] = 4,
+ [GF_DEFRAG_STATUS_NOT_STARTED] = 5};
+ if (rank[status_rcd] <= rank[overall_status])
+ overall_status = status_rcd;
+
+ /* </node> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "count not set");
- goto out;
- }
+ /* Aggregate status */
+ /* <aggregate> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"aggregate");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"nodeCount",
- "%d", count);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"files",
+ "%" PRIu64, total_files);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- while (i <= count) {
- promoted = 0;
- node_name = NULL;
- demoted = 0;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"size", "%" PRIu64,
+ total_size);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"node");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"lookups",
+ "%" PRIu64, total_lookups);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "node-name-%d", i);
- ret = dict_get_str (dict, key, &node_name);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"nodeName",
- "%s", node_name);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "promoted-%d", i);
- ret = dict_get_uint64 (dict, key, &promoted);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"promoted"
- "Files", "%"PRIu64,
- promoted);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "demoted-%d", i);
- ret = dict_get_uint64 (dict, key, &demoted);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"demoted"
- "Files", "%"PRIu64,
- demoted);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"failures",
+ "%" PRIu64, total_failures);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- memset (key, 0, 256);
- snprintf (key, 256, "status-%d", i);
- ret = dict_get_int32 (dict, key, (int32_t *)&status_rcd);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"skipped",
+ "%" PRIu64, total_skipped);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- status_str = cli_vol_task_status_str[status_rcd];
+ if (overall_status == -1) {
+ overall_status = status_rcd;
+ }
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"statusStr",
- "%s", status_str);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"status", "%d",
+ overall_status);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"statusStr", "%s",
+ cli_vol_task_status_str[overall_status]);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"runtime", "%.2f",
+ overall_elapsed);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- i++;
- }
+ /* </aggregate> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-#else
- return 0;
-
-#endif
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
-
-
-
+#endif
int
-cli_xml_output_vol_rebalance (gf_cli_defrag_type op, dict_t *dict, int op_ret,
- int op_errno, char *op_errstr)
+cli_xml_output_vol_rebalance(gf_cli_defrag_type op, dict_t *dict, int op_ret,
+ int op_errno, char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
- char *task_id_str = NULL;
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ char *task_id_str = NULL;
+
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ /* <volRebalance> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volRebalance");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, GF_REBALANCE_TID_KEY, &task_id_str);
+ if (ret == 0) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"task-id",
+ "%s", task_id_str);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"op", "%d", op);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ if ((GF_DEFRAG_CMD_STOP == op) || (GF_DEFRAG_CMD_STATUS == op)) {
+ ret = cli_xml_output_vol_rebalance_status(writer, dict,
+ GF_TASK_TYPE_REBALANCE);
if (ret)
- goto out;
-
- /* <volRebalance> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volRebalance");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, GF_REBALANCE_TID_KEY, &task_id_str);
- if (ret == 0) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"task-id",
- "%s", task_id_str);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ goto out;
+ }
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"op",
- "%d", op);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </volRebalance> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- if (GF_DEFRAG_CMD_STATUS_TIER == op) {
- ret = cli_xml_output_vol_tier_status (writer,
- dict, GF_TASK_TYPE_REBALANCE);
- if (ret)
- goto out;
- }
- if ((GF_DEFRAG_CMD_STOP == op) || (GF_DEFRAG_CMD_STATUS == op)) {
-
- ret = cli_xml_output_vol_rebalance_status (writer, dict,
- GF_TASK_TYPE_REBALANCE);
- if (ret)
- goto out;
- }
-
- /* </volRebalance> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
-
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_remove_brick_detach_tier (gf_boolean_t status_op,
- dict_t *dict, int op_ret,
- int op_errno, char *op_errstr,
- const char *op)
+cli_xml_output_vol_remove_brick(gf_boolean_t status_op, dict_t *dict,
+ int op_ret, int op_errno, char *op_errstr,
+ const char *op)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
- char *task_id_str = NULL;
-
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ char *task_id_str = NULL;
+
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)op);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, GF_REMOVE_BRICK_TID_KEY, &task_id_str);
+ if (ret == 0) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"task-id",
+ "%s", task_id_str);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ if (status_op) {
+ ret = cli_xml_output_vol_rebalance_status(writer, dict,
+ GF_TASK_TYPE_REMOVE_BRICK);
if (ret)
- goto out;
-
- ret = xmlTextWriterStartElement (writer, (xmlChar *) op);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, GF_REMOVE_BRICK_TID_KEY, &task_id_str);
- if (ret == 0) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"task-id",
- "%s", task_id_str);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
-
- if (status_op) {
- ret = cli_xml_output_vol_rebalance_status (writer, dict,
- GF_TASK_TYPE_REMOVE_BRICK);
- if (ret)
- goto out;
- }
+ goto out;
+ }
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
-
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_replace_brick (char *op, dict_t *dict,
- int op_ret, int op_errno, char *op_errstr)
+cli_xml_output_vol_replace_brick(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- int status = 0;
- uint64_t files = 0;
- char *current_file = 0;
- char *task_id_str = NULL;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
-
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
- if (ret)
- goto out;
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_vol_create (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_vol_create(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
- char *volname = NULL;
- char *volid = NULL;
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ char *volname = NULL;
+ char *volid = NULL;
+
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ if (dict) {
+ /* <volCreate> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volCreate");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
+ /* <volume> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
+ ret = dict_get_str(dict, "volname", &volname);
if (ret)
- goto out;
-
- if (dict) {
- /* <volCreate> */
- ret = xmlTextWriterStartElement (writer,
- (xmlChar *)"volCreate");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* <volume> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volume");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "name",
- "%s", volname);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ volname);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, "volume-id", &volid);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"id",
- "%s", volid);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = dict_get_str(dict, "volume-id", &volid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"id", "%s",
+ volid);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </volume> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </volume> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </volCreate> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ /* </volCreate> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_generic_volume (char *op, dict_t *dict, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_generic_volume(char *op, dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
- char *volname = NULL;
- char *volid = NULL;
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ char *volname = NULL;
+ char *volid = NULL;
- GF_ASSERT (op);
+ GF_ASSERT(op);
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret)
+ goto out;
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
- if (ret)
- goto out;
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
- if (dict) {
- /* <"op"> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)op);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ if (dict) {
+ /* <"op"> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)op);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <volume> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volume");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <volume> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "name",
- "%s", volname);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = dict_get_str(dict, "volname", &volname);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ volname);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, "vol-id", &volid);
- if (ret)
- goto out;
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"id",
- "%s", volid);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = dict_get_str(dict, "vol-id", &volid);
+ if (ret)
+ goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"id", "%s",
+ volid);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </volume> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </volume> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </"op"> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ /* </"op"> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
#if (HAVE_LIB_XML)
int
-_output_gsync_config (FILE *fp, xmlTextWriterPtr writer, char *op_name)
+_output_gsync_config(FILE *fp, xmlTextWriterPtr writer, char *op_name)
{
- char resbuf[256 + PATH_MAX] = {0,};
- char *ptr = NULL;
- char *v = NULL;
- int blen = sizeof(resbuf);
- int ret = 0;
-
- for (;;) {
- ptr = fgets (resbuf, blen, fp);
- if (!ptr)
- break;
-
- v = resbuf + strlen (resbuf) - 1;
- while (isspace (*v)) {
- /* strip trailing space */
- *v-- = '\0';
- }
- if (v == resbuf) {
- /* skip empty line */
- continue;
- }
+ char resbuf[256 + PATH_MAX] = {
+ 0,
+ };
+ char *ptr = NULL;
+ char *v = NULL;
+ int blen = sizeof(resbuf);
+ int ret = 0;
+
+ for (;;) {
+ ptr = fgets(resbuf, blen, fp);
+ if (!ptr)
+ break;
- if (op_name!= NULL){
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)op_name,
- "%s", resbuf);
- XML_RET_CHECK_AND_GOTO (ret, out);
- goto out;
- }
+ v = resbuf + strlen(resbuf) - 1;
+ while (isspace(*v)) {
+ /* strip trailing space */
+ *v-- = '\0';
+ }
+ if (v == resbuf) {
+ /* skip empty line */
+ continue;
+ }
- v = strchr (resbuf, ':');
- if (!v) {
- ret = -1;
- goto out;
- }
- *v++ = '\0';
- while (isspace (*v))
- v++;
- v = gf_strdup (v);
- if (!v) {
- ret = -1;
- goto out;
- }
+ if (op_name != NULL) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)op_name,
+ "%s", resbuf);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ goto out;
+ }
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)resbuf,
- "%s", v);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ v = strchr(resbuf, ':');
+ if (!v) {
+ ret = -1;
+ goto out;
}
+ *v++ = '\0';
+ while (isspace(*v))
+ v++;
+ v = gf_strdup(v);
+ if (!v) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)resbuf, "%s",
+ v);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
#if (HAVE_LIB_XML)
int
-get_gsync_config (runner_t *runner,
- int (*op_conf)(FILE *fp,
- xmlTextWriterPtr writer,
- char *op_name),
- xmlTextWriterPtr writer, char *op_name)
+get_gsync_config(runner_t *runner,
+ int (*op_conf)(FILE *fp, xmlTextWriterPtr writer,
+ char *op_name),
+ xmlTextWriterPtr writer, char *op_name)
{
- int ret = 0;
+ int ret = 0;
- runner_redir (runner, STDOUT_FILENO, RUN_PIPE);
- if (runner_start (runner) != 0) {
- gf_log ("cli", GF_LOG_ERROR, "spawning child failed");
- return -1;
- }
+ runner_redir(runner, STDOUT_FILENO, RUN_PIPE);
+ if (runner_start(runner) != 0) {
+ gf_log("cli", GF_LOG_ERROR, "spawning child failed");
+ return -1;
+ }
- ret = op_conf (runner_chio (runner, STDOUT_FILENO), writer, op_name);
+ ret = op_conf(runner_chio(runner, STDOUT_FILENO), writer, op_name);
- ret |= runner_end (runner);
- if (ret)
- gf_log ("cli", GF_LOG_ERROR, "reading data from child failed");
+ ret |= runner_end(runner);
+ if (ret)
+ gf_log("cli", GF_LOG_ERROR, "reading data from child failed");
- return ret ? -1 : 0;
+ return ret ? -1 : 0;
}
#endif
#if (HAVE_LIB_XML)
int
-cli_xml_generate_gsync_config (dict_t *dict, xmlTextWriterPtr writer)
+cli_xml_generate_gsync_config(dict_t *dict, xmlTextWriterPtr writer)
{
- runner_t runner = {0,};
- char *subop = NULL;
- char *gwd = NULL;
- char *slave = NULL;
- char *confpath = NULL;
- char *master = NULL;
- char *op_name = NULL;
- int ret = -1;
- char conf_path[PATH_MAX] = "";
-
- if (dict_get_str (dict, "subop", &subop) != 0) {
- ret = -1;
- goto out;
- }
-
- if (strcmp (subop, "get") != 0 && strcmp (subop, "get-all") != 0) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"message",
- "%s",GEOREP" config updated successfully" );
- XML_RET_CHECK_AND_GOTO (ret, out);
- ret = 0;
- goto out;
- }
+ runner_t runner = {
+ 0,
+ };
+ char *subop = NULL;
+ char *gwd = NULL;
+ char *slave = NULL;
+ char *confpath = NULL;
+ char *master = NULL;
+ char *op_name = NULL;
+ int ret = -1;
+ char conf_path[PATH_MAX] = "";
+
+ if (dict_get_str(dict, "subop", &subop) != 0) {
+ ret = -1;
+ goto out;
+ }
+
+ if (strcmp(subop, "get") != 0 && strcmp(subop, "get-all") != 0) {
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"message", "%s",
+ GEOREP " config updated successfully");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ ret = 0;
+ goto out;
+ }
- if (dict_get_str (dict, "glusterd_workdir", &gwd) != 0 ||
- dict_get_str (dict, "slave", &slave) != 0) {
- ret = -1;
- goto out;
- }
+ if (dict_get_str(dict, "glusterd_workdir", &gwd) != 0 ||
+ dict_get_str(dict, "slave", &slave) != 0) {
+ ret = -1;
+ goto out;
+ }
- if (dict_get_str (dict, "master", &master) != 0)
- master = NULL;
+ if (dict_get_str(dict, "master", &master) != 0)
+ master = NULL;
- if (dict_get_str (dict, "op_name", &op_name) != 0)
- op_name = NULL;
+ if (dict_get_str(dict, "op_name", &op_name) != 0)
+ op_name = NULL;
- ret = dict_get_str (dict, "conf_path", &confpath);
- if (!confpath) {
- ret = snprintf (conf_path, sizeof (conf_path) - 1,
- "%s/"GEOREP"/gsyncd_template.conf", gwd);
- conf_path[ret] = '\0';
- confpath = conf_path;
- }
+ ret = dict_get_str(dict, "conf_path", &confpath);
+ if (!confpath) {
+ ret = snprintf(conf_path, sizeof(conf_path) - 1,
+ "%s/" GEOREP "/gsyncd_template.conf", gwd);
+ conf_path[ret] = '\0';
+ confpath = conf_path;
+ }
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s", confpath);
- runner_argprintf (&runner, "--iprefix=%s", DATADIR);
+ runinit(&runner);
+ runner_add_args(&runner, GSYNCD_PREFIX "/gsyncd", "-c", NULL);
+ runner_argprintf(&runner, "%s", confpath);
+ runner_argprintf(&runner, "--iprefix=%s", DATADIR);
- if (master)
- runner_argprintf (&runner, ":%s", master);
+ if (master)
+ runner_argprintf(&runner, ":%s", master);
- runner_add_arg (&runner, slave);
- runner_argprintf (&runner, "--config-%s", subop);
+ runner_add_arg(&runner, slave);
+ runner_argprintf(&runner, "--config-%s", subop);
- if (op_name)
- runner_add_arg (&runner, op_name);
+ if (op_name)
+ runner_add_arg(&runner, op_name);
- ret = get_gsync_config (&runner, _output_gsync_config,
- writer, op_name);
+ ret = get_gsync_config(&runner, _output_gsync_config, writer, op_name);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
#if (HAVE_LIB_XML)
int
-cli_xml_output_vol_gsync_status (dict_t *dict,
- xmlTextWriterPtr writer)
+cli_xml_output_vol_gsync_status(dict_t *dict, xmlTextWriterPtr writer)
{
- int ret = -1;
- int i = 1;
- int j = 0;
- int count = 0;
- const int number_of_fields = 20;
- int closed = 1;
- int session_closed = 1;
- gf_gsync_status_t **status_values = NULL;
- gf_boolean_t status_detail = _gf_false;
- char status_value_name[PATH_MAX] = "";
- char *tmp = NULL;
- char *volume = NULL;
- char *volume_next = NULL;
- char *slave = NULL;
- char *slave_next = NULL;
- char *title_values[] = {"master_node",
- "",
- "master_brick",
- "slave_user",
- "slave",
- "slave_node",
- "status",
- "crawl_status",
- /* last_synced */
- "",
- "entry",
- "data",
- "meta",
- "failures",
- /* checkpoint_time */
- "",
- "checkpoint_completed",
- /* checkpoint_completion_time */
- "",
- "master_node_uuid",
- /* last_synced_utc */
- "last_synced",
- /* checkpoint_time_utc */
- "checkpoint_time",
- /* checkpoint_completion_time_utc */
- "checkpoint_completion_time"};
-
- GF_ASSERT (dict);
-
- ret = dict_get_int32 (dict, "gsync-count", &count);
- if (ret)
- goto out;
+ int ret = -1;
+ int i = 1;
+ int j = 0;
+ int count = 0;
+ const int number_of_fields = 20;
+ int closed = 1;
+ int session_closed = 1;
+ gf_gsync_status_t **status_values = NULL;
+ char status_value_name[PATH_MAX] = "";
+ char *tmp = NULL;
+ char *volume = NULL;
+ char *volume_next = NULL;
+ char *slave = NULL;
+ char *slave_next = NULL;
+ static const char *title_values[] = {
+ "master_node", "", "master_brick", "slave_user", "slave", "slave_node",
+ "status", "crawl_status",
+ /* last_synced */
+ "", "entry", "data", "meta", "failures",
+ /* checkpoint_time */
+ "", "checkpoint_completed",
+ /* checkpoint_completion_time */
+ "", "master_node_uuid",
+ /* last_synced_utc */
+ "last_synced",
+ /* checkpoint_time_utc */
+ "checkpoint_time",
+ /* checkpoint_completion_time_utc */
+ "checkpoint_completion_time"};
+
+ GF_ASSERT(dict);
+
+ ret = dict_get_int32(dict, "gsync-count", &count);
+ if (ret)
+ goto out;
+
+ status_values = GF_MALLOC(count * sizeof(gf_gsync_status_t *),
+ gf_common_mt_char);
+ if (!status_values) {
+ ret = -1;
+ goto out;
+ }
- status_detail = dict_get_str_boolean (dict, "status-detail",
- _gf_false);
+ for (i = 0; i < count; i++) {
+ status_values[i] = GF_CALLOC(1, sizeof(gf_gsync_status_t),
+ gf_common_mt_char);
+ if (!status_values[i]) {
+ ret = -1;
+ goto out;
+ }
- status_values = GF_CALLOC (count, sizeof (gf_gsync_status_t *),
- gf_common_mt_char);
- if (!status_values) {
- ret = -1;
- goto out;
+ snprintf(status_value_name, sizeof(status_value_name), "status_value%d",
+ i);
+
+ ret = dict_get_bin(dict, status_value_name,
+ (void **)&(status_values[i]));
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "struct member empty.");
+ goto out;
}
+ }
- for (i = 0; i < count; i++) {
- status_values[i] = GF_CALLOC (1, sizeof (gf_gsync_status_t),
- gf_common_mt_char);
- if (!status_values[i]) {
- ret = -1;
- goto out;
- }
+ qsort(status_values, count, sizeof(gf_gsync_status_t *),
+ gf_gsync_status_t_comparator);
- snprintf (status_value_name, sizeof (status_value_name),
- "status_value%d", i);
+ for (i = 0; i < count; i++) {
+ if (closed) {
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_bin (dict, status_value_name,
- (void **)&(status_values[i]));
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "struct member empty.");
- goto out;
- }
- }
+ tmp = get_struct_variable(1, status_values[i]);
+ if (!tmp) {
+ gf_log("cli", GF_LOG_ERROR, "struct member empty.");
+ ret = -1;
+ goto out;
+ }
- qsort(status_values, count, sizeof (gf_gsync_status_t *),
- gf_gsync_status_t_comparator);
-
- for (i = 0; i < count; i++) {
- if (closed) {
- ret = xmlTextWriterStartElement (writer,
- (xmlChar *)"volume");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- tmp = get_struct_variable (1, status_values[i]);
- if (!tmp) {
- gf_log ("cli", GF_LOG_ERROR,
- "struct member empty.");
- ret = -1;
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"name",
- "%s",tmp);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterStartElement (writer,
- (xmlChar *)"sessions");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- closed = 0;
- }
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name",
+ "%s", tmp);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- if (session_closed) {
- ret = xmlTextWriterStartElement (writer,
- (xmlChar *)"session");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"sessions");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- session_closed = 0;
+ closed = 0;
+ }
- tmp = get_struct_variable (21, status_values[i]);
- if (!tmp) {
- gf_log ("cli", GF_LOG_ERROR,
- "struct member empty.");
- ret = -1;
- goto out;
- }
+ if (session_closed) {
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"session");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement
- (writer, (xmlChar *)"session_slave", "%s", tmp);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ session_closed = 0;
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"pair");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ tmp = get_struct_variable(21, status_values[i]);
+ if (!tmp) {
+ gf_log("cli", GF_LOG_ERROR, "struct member empty.");
+ ret = -1;
+ goto out;
+ }
- for (j = 0; j < number_of_fields; j++) {
- /* XML ignore fields */
- if (strcmp(title_values[j], "") == 0)
- continue;
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"session_slave", "%s", tmp);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- tmp = get_struct_variable (j, status_values[i]);
- if (!tmp) {
- gf_log ("cli", GF_LOG_ERROR,
- "struct member empty.");
- ret = -1;
- goto out;
- }
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"pair");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)title_values[j],
- "%s", tmp);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ for (j = 0; j < number_of_fields; j++) {
+ /* XML ignore fields */
+ if (strcmp(title_values[j], "") == 0)
+ continue;
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ tmp = get_struct_variable(j, status_values[i]);
+ if (!tmp) {
+ gf_log("cli", GF_LOG_ERROR, "struct member empty.");
+ ret = -1;
+ goto out;
+ }
- if (i+1 < count) {
- slave = get_struct_variable (20, status_values[i]);
- slave_next = get_struct_variable (20,
- status_values[i+1]);
- volume = get_struct_variable (1, status_values[i]);
- volume_next = get_struct_variable (1,
- status_values[i+1]);
- if (!slave || !slave_next || !volume || !volume_next) {
- gf_log ("cli", GF_LOG_ERROR,
- "struct member empty.");
- ret = -1;
- goto out;
- }
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)title_values[j], "%s", tmp);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- if (strcmp (volume, volume_next)!=0) {
- closed = 1;
- session_closed = 1;
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ if (i + 1 < count) {
+ slave = get_struct_variable(20, status_values[i]);
+ slave_next = get_struct_variable(20, status_values[i + 1]);
+ volume = get_struct_variable(1, status_values[i]);
+ volume_next = get_struct_variable(1, status_values[i + 1]);
+ if (!slave || !slave_next || !volume || !volume_next) {
+ gf_log("cli", GF_LOG_ERROR, "struct member empty.");
+ ret = -1;
+ goto out;
+ }
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ if (strcmp(volume, volume_next) != 0) {
+ closed = 1;
+ session_closed = 1;
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- } else if (strcmp (slave, slave_next)!=0) {
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- session_closed = 1;
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
- } else {
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ } else if (strcmp(slave, slave_next) != 0) {
+ session_closed = 1;
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ } else {
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
}
+ }
out:
- gf_log ("cli",GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ if (status_values)
+ GF_FREE(status_values);
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
#endif
int
-cli_xml_output_vol_gsync (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_vol_gsync(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
- char *master = NULL;
- char *slave = NULL;
- int type = 0;
-
- GF_ASSERT (dict);
-
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
-
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
- if (ret)
- goto out;
-
- /* <geoRep> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"geoRep");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get type");
- goto out;
- }
-
- switch (type) {
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ char *master = NULL;
+ char *slave = NULL;
+ int type = 0;
+
+ GF_ASSERT(dict);
+
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ /* <geoRep> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"geoRep");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_int32(dict, "type", &type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get type");
+ goto out;
+ }
+
+ switch (type) {
case GF_GSYNC_OPTION_TYPE_START:
case GF_GSYNC_OPTION_TYPE_STOP:
case GF_GSYNC_OPTION_TYPE_PAUSE:
case GF_GSYNC_OPTION_TYPE_RESUME:
case GF_GSYNC_OPTION_TYPE_CREATE:
case GF_GSYNC_OPTION_TYPE_DELETE:
- if (dict_get_str (dict, "master", &master) != 0)
- master = "???";
- if (dict_get_str (dict, "slave", &slave) != 0)
- slave = "???";
+ if (dict_get_str(dict, "master", &master) != 0)
+ master = "???";
+ if (dict_get_str(dict, "slave", &slave) != 0)
+ slave = "???";
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"master",
- "%s", master);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"master",
+ "%s", master);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"slave",
- "%s", slave);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"slave",
+ "%s", slave);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- break;
+ break;
case GF_GSYNC_OPTION_TYPE_CONFIG:
- if (op_ret == 0) {
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"config");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ if (op_ret == 0) {
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"config");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_xml_generate_gsync_config (dict, writer);
- if (ret)
- goto out;
+ ret = cli_xml_generate_gsync_config(dict, writer);
+ if (ret)
+ goto out;
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- break;
+ break;
case GF_GSYNC_OPTION_TYPE_STATUS:
- ret = cli_xml_output_vol_gsync_status (dict, writer);
- break;
+ ret = cli_xml_output_vol_gsync_status(dict, writer);
+ if (ret) {
+ gf_log("cli", GF_LOG_DEBUG, "Failed to get gsync status");
+ goto out;
+ }
+ break;
default:
- ret = 0;
- break;
- }
+ ret = 0;
+ break;
+ }
- /* </geoRep> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </geoRep> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_end_xml_output (writer, doc);
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli",GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
@@ -4158,56 +3842,113 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_create (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
+cli_xml_snapshot_create(xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
{
- int ret = -1;
- char *str_value = NULL;
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
-
- /* <snapCreate> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapCreate");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* <snapshot> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapshot");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "snapname", &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snap name");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name",
- "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "snapuuid", &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "uuid",
- "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </snapshot> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </snapCreate> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = 0;
+ int ret = -1;
+ char *str_value = NULL;
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+
+ /* <snapCreate> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapCreate");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* <snapshot> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapshot");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "snapname", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "snapuuid", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"uuid", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </snapshot> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </snapCreate> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
+/* This function will generate snapshot clone output in xml format.
+ *
+ * @param writer xmlTextWriterPtr
+ * @param doc xmlDocPtr
+ * @param dict dict containing create output
+ *
+ * @return 0 on success and -1 on failure
+ */
+static int
+cli_xml_snapshot_clone(xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
+{
+ int ret = -1;
+ char *str_value = NULL;
+
+ GF_VALIDATE_OR_GOTO("cli", writer, out);
+ GF_VALIDATE_OR_GOTO("cli", doc, out);
+ GF_VALIDATE_OR_GOTO("cli", dict, out);
+
+ /* <CloneCreate> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"CloneCreate");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* <volume> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "clonename", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get clone name");
+ goto out;
+ }
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "snapuuid", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get clone uuid");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"uuid", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </volume> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </CloneCreate> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = 0;
+out:
+ return ret;
+}
/* This function will generate snapshot restore output in xml format.
*
@@ -4218,84 +3959,83 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_restore (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
+cli_xml_snapshot_restore(xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
{
- int ret = -1;
- char *str_value = NULL;
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
-
- /* <snapRestore> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapRestore");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* <volume> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volume");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "volname", &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get vol name");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name",
- "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "volid", &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get volume id");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "uuid",
- "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </volume> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
-
- /* <snapshot> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapshot");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "snapname", &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snap name");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name",
- "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "snapuuid", &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "uuid",
- "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </snapshot> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </snapRestore> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = 0;
+ int ret = -1;
+ char *str_value = NULL;
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+
+ /* <snapRestore> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapRestore");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* <volume> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "volname", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get vol name");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "volid", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get volume id");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"uuid", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </volume> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* <snapshot> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapshot");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "snapname", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "snapuuid", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"uuid", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </snapshot> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </snapRestore> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot list output in xml format.
@@ -4307,57 +4047,57 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_list (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
+cli_xml_snapshot_list(xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
{
- int ret = -1;
- int i = 0;
- int snapcount = 0;
- char *str_value = NULL;
- char key[PATH_MAX] = "";
+ int ret = -1;
+ int i = 0;
+ int snapcount = 0;
+ char *str_value = NULL;
+ char key[PATH_MAX] = "";
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
- /* <snapList> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapList");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <snapList> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapList");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_int32 (dict, "snapcount", &snapcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snapcount");
- goto out;
- }
+ ret = dict_get_int32(dict, "snapcount", &snapcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snapcount");
+ goto out;
+ }
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "count",
- "%d", snapcount);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"count", "%d",
+ snapcount);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- for (i = 1; i <= snapcount; ++i) {
- ret = snprintf (key, sizeof (key), "snapname%d", i);
- if (ret < 0) {
- goto out;
- }
+ for (i = 1; i <= snapcount; ++i) {
+ ret = snprintf(key, sizeof(key), "snapname%d", i);
+ if (ret < 0) {
+ goto out;
+ }
- ret = dict_get_str (dict, key, &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not get %s ", key);
- goto out;
- } else {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"snapshot", "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ ret = dict_get_str(dict, key, &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not get %s ", key);
+ goto out;
+ } else {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"snapshot",
+ "%s", str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
}
+ }
- /* </snapList> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapList> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate xml output for origin volume
@@ -4371,66 +4111,66 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_info_orig_vol (xmlTextWriterPtr writer, xmlDocPtr doc,
- dict_t *dict, char *keyprefix)
+cli_xml_snapshot_info_orig_vol(xmlTextWriterPtr writer, xmlDocPtr doc,
+ dict_t *dict, char *keyprefix)
{
- int ret = -1;
- int value = 0;
- char *buffer = NULL;
- char key [PATH_MAX] = "";
+ int ret = -1;
+ int value = 0;
+ char *buffer = NULL;
+ char key[PATH_MAX] = "";
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (writer);
- GF_ASSERT (doc);
+ GF_ASSERT(dict);
+ GF_ASSERT(keyprefix);
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
- /* <originVolume> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"originVolume");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <originVolume> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"originVolume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- snprintf (key, sizeof (key), "%sorigin-volname", keyprefix);
+ snprintf(key, sizeof(key), "%sorigin-volname", keyprefix);
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_WARNING, "Failed to get %s", key);
- goto out;
- }
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_WARNING, "Failed to get %s", key);
+ goto out;
+ }
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- snprintf (key, sizeof (key), "%ssnapcount", keyprefix);
+ snprintf(key, sizeof(key), "%ssnapcount", keyprefix);
- ret = dict_get_int32 (dict, key, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
- goto out;
- }
+ ret = dict_get_int32(dict, key, &value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "snapCount",
- "%d", value);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"snapCount", "%d",
+ value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- snprintf (key, sizeof (key), "%ssnaps-available", keyprefix);
+ snprintf(key, sizeof(key), "%ssnaps-available", keyprefix);
- ret = dict_get_int32 (dict, key, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
- goto out;
- }
+ ret = dict_get_int32(dict, key, &value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "snapRemaining", "%d", value);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"snapRemaining",
+ "%d", value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </originVolume> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </originVolume> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate xml output of snapshot volume info.
@@ -4445,67 +4185,74 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_info_snap_vol (xmlTextWriterPtr writer, xmlDocPtr doc,
- dict_t *dict, char *keyprefix,
- gf_boolean_t snap_driven)
+cli_xml_snapshot_info_snap_vol(xmlTextWriterPtr writer, xmlDocPtr doc,
+ dict_t *dict, char *keyprefix,
+ gf_boolean_t snap_driven)
{
- char key [PATH_MAX] = "";
- char *buffer = NULL;
- int value = 0;
- int ret = -1;
-
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (writer);
- GF_ASSERT (doc);
-
- /* <snapVolume> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapVolume");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key, sizeof (key), "%s.volname", keyprefix);
-
- ret = dict_get_str (dict, key, &buffer);
+ char key[PATH_MAX] = "";
+ char *buffer = NULL;
+ int ret = -1;
+
+ GF_ASSERT(dict);
+ GF_ASSERT(keyprefix);
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+
+ /* <snapVolume> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapVolume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = snprintf(key, sizeof(key), "%s.volname", keyprefix);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = snprintf(key, sizeof(key), "%s.vol-status", keyprefix);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get %s", key);
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"status", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* If the command is snap_driven then we need to show origin volume
+ * info. Else this is shown in the start of info display.*/
+ if (snap_driven) {
+ ret = snprintf(key, sizeof(key), "%s.", keyprefix);
+ if (ret < 0)
+ goto out;
+
+ ret = cli_xml_snapshot_info_orig_vol(writer, doc, dict, key);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
- goto out;
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create "
+ "xml output for snapshot's origin volume");
+ goto out;
}
+ }
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key, sizeof (key), "%s.vol-status", keyprefix);
+ /* </snapVolume> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get %s", key);
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "status",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* If the command is snap_driven then we need to show origin volume
- * info. Else this is shown in the start of info display.*/
- if (snap_driven) {
- snprintf (key, sizeof (key), "%s.", keyprefix);
- ret = cli_xml_snapshot_info_orig_vol (writer, doc, dict, key);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot's origin volume");
- goto out;
- }
- }
-
- /* </snapVolume> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot info of individual snapshot
@@ -4521,112 +4268,118 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_info_per_snap (xmlTextWriterPtr writer, xmlDocPtr doc,
- dict_t *dict, char *keyprefix,
- gf_boolean_t snap_driven)
+cli_xml_snapshot_info_per_snap(xmlTextWriterPtr writer, xmlDocPtr doc,
+ dict_t *dict, char *keyprefix,
+ gf_boolean_t snap_driven)
{
- char key_buffer[PATH_MAX] = "";
- char *buffer = NULL;
- int volcount = 0;
- int ret = -1;
- int i = 0;
-
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
- GF_ASSERT (writer);
- GF_ASSERT (doc);
-
- /* <snapshot> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapshot");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key_buffer, sizeof (key_buffer), "%s.snapname",
- keyprefix);
-
- ret = dict_get_str (dict, key_buffer, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to fetch snapname %s ",
- key_buffer);
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key_buffer, sizeof (key_buffer), "%s.snap-id", keyprefix);
-
- ret = dict_get_str (dict, key_buffer, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to fetch snap-id %s ",
- key_buffer);
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "uuid",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key_buffer, sizeof (key_buffer), "%s.snap-desc", keyprefix);
-
- ret = dict_get_str (dict, key_buffer, &buffer);
- if (!ret) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "description",
- "%s", buffer);
- } else {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "description",
- "%s", "");
- }
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key_buffer, sizeof (key_buffer), "%s.snap-time", keyprefix);
-
- ret = dict_get_str (dict, key_buffer, &buffer);
+ char key_buffer[PATH_MAX] = "";
+ char *buffer = NULL;
+ int volcount = 0;
+ int ret = -1;
+ int i = 0;
+
+ GF_ASSERT(dict);
+ GF_ASSERT(keyprefix);
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+
+ /* <snapshot> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapshot");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.snapname", keyprefix);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_get_str(dict, key_buffer, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to fetch snapname %s ", key_buffer);
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.snap-id", keyprefix);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_get_str(dict, key_buffer, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to fetch snap-id %s ", key_buffer);
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"uuid", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.snap-desc", keyprefix);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_get_str(dict, key_buffer, &buffer);
+ if (!ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"description",
+ "%s", buffer);
+ } else {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"description",
+ "%s", "");
+ }
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.snap-time", keyprefix);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_get_str(dict, key_buffer, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to fetch snap-time %s ", keyprefix);
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"createTime", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.vol-count", keyprefix);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_get_int32(dict, key_buffer, &volcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Fail to get snap vol count");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"volCount", "%d",
+ volcount);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_int32(dict, key_buffer, &volcount);
+ /* Display info of each snapshot volume */
+ for (i = 1; i <= volcount; i++) {
+ ret = snprintf(key_buffer, sizeof(key_buffer), "%s.vol%d", keyprefix,
+ i);
+ if (ret < 0)
+ goto out;
+
+ ret = cli_xml_snapshot_info_snap_vol(writer, doc, dict, key_buffer,
+ snap_driven);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to fetch snap-time %s ",
- keyprefix);
- goto out;
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not list "
+ "details of volume in a snap");
+ goto out;
}
+ }
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "createTime",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key_buffer, sizeof (key_buffer), "%s.vol-count", keyprefix);
- ret = dict_get_int32 (dict, key_buffer, &volcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Fail to get snap vol count");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "volCount",
- "%d", volcount);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_int32 (dict, key_buffer, &volcount);
- /* Display info of each snapshot volume */
- for (i = 1 ; i <= volcount ; i++) {
- snprintf (key_buffer, sizeof (key_buffer), "%s.vol%d",
- keyprefix, i);
-
- ret = cli_xml_snapshot_info_snap_vol (writer, doc, dict,
- key_buffer, snap_driven);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not list "
- "details of volume in a snap");
- goto out;
- }
- }
-
- /* </snapshot> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapshot> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot info output in xml format.
@@ -4638,74 +4391,74 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_info (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
+cli_xml_snapshot_info(xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
{
- int ret = -1;
- int i = 0;
- int snapcount = 0;
- char key [PATH_MAX] = "";
- char *str_value = NULL;
- gf_boolean_t snap_driven = _gf_false;
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
-
- /* <snapInfo> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapInfo");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snap_driven = dict_get_str_boolean (dict, "snap-driven", _gf_false);
-
- /* If the approach is volume based then we should display orgin volume
- * information first followed by per snap info*/
- if (!snap_driven) {
- ret = cli_xml_snapshot_info_orig_vol (writer, doc, dict, "");
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot's origin volume");
- goto out;
- }
- }
-
- ret = dict_get_int32 (dict, "snapcount", &snapcount);
+ int ret = -1;
+ int i = 0;
+ int snapcount = 0;
+ char key[PATH_MAX] = "";
+ gf_boolean_t snap_driven = _gf_false;
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+
+ /* <snapInfo> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapInfo");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snap_driven = dict_get_str_boolean(dict, "snap-driven", _gf_false);
+
+ /* If the approach is volume based then we should display origin volume
+ * information first followed by per snap info*/
+ if (!snap_driven) {
+ ret = cli_xml_snapshot_info_orig_vol(writer, doc, dict, "");
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snapcount");
- goto out;
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create "
+ "xml output for snapshot's origin volume");
+ goto out;
}
+ }
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "count",
- "%d", snapcount);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = dict_get_int32(dict, "snapcount", &snapcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snapcount");
+ goto out;
+ }
- /* <snapshots> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapshots");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"count", "%d",
+ snapcount);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* Get snapshot info of individual snapshots */
- for (i = 1; i <= snapcount; ++i) {
- snprintf (key, sizeof (key), "snap%d", i);
+ /* <snapshots> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapshots");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_xml_snapshot_info_per_snap (writer, doc, dict,
- key, snap_driven);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not get %s ", key);
- goto out;
- }
+ /* Get snapshot info of individual snapshots */
+ for (i = 1; i <= snapcount; ++i) {
+ snprintf(key, sizeof(key), "snap%d", i);
+
+ ret = cli_xml_snapshot_info_per_snap(writer, doc, dict, key,
+ snap_driven);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not get %s ", key);
+ goto out;
}
+ }
- /* </snapshots> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapshots> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </snapInfo> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapInfo> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot status of individual
@@ -4719,125 +4472,148 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_volume_status (xmlTextWriterPtr writer, xmlDocPtr doc,
- dict_t *dict, const char *keyprefix)
+cli_xml_snapshot_volume_status(xmlTextWriterPtr writer, xmlDocPtr doc,
+ dict_t *dict, const char *keyprefix)
{
- int ret = -1;
- int brickcount = 0;
- int i = 0;
- int value = 0;
- int pid = 0;
- char *buffer = NULL;
- char key[PATH_MAX] = "";
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
-
- snprintf (key, sizeof (key), "%s.brickcount", keyprefix);
-
- ret = dict_get_int32 (dict, key, &brickcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to fetch brickcount");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "brickCount",
- "%d", brickcount);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ int ret = -1;
+ int brickcount = 0;
+ int i = 0;
+ int pid = 0;
+ char *buffer = NULL;
+ char key[PATH_MAX] = "";
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+ GF_ASSERT(keyprefix);
+
+ ret = snprintf(key, sizeof(key), "%s.brickcount", keyprefix);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_get_int32(dict, key, &brickcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to fetch brickcount");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"brickCount", "%d",
+ brickcount);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* Get status of every brick belonging to the snapshot volume */
+ for (i = 0; i < brickcount; i++) {
+ /* <snapInfo> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"brick");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* Get status of every brick belonging to the snapshot volume */
- for (i = 0 ; i < brickcount ; i++) {
- /* <snapInfo> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"brick");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = snprintf(key, sizeof(key), "%s.brick%d.path", keyprefix, i);
+ if (ret < 0)
+ goto out;
- snprintf (key, sizeof (key), "%s.brick%d.path", keyprefix, i);
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get Brick Path");
+ /*
+ * If path itself is not present, then end *
+ * this brick's status and continue to the *
+ * brick *
+ */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ continue;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"path", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_INFO, "Unable to get Brick Path");
- goto out;
- }
+ ret = snprintf(key, sizeof(key), "%s.brick%d.vgname", keyprefix, i);
+ if (ret < 0)
+ goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "path", "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get Volume Group");
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"volumeGroup", "N/A");
+ } else
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"volumeGroup", "%s", buffer);
- snprintf (key, sizeof (key), "%s.brick%d.vgname",
- keyprefix, i);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_INFO,
- "Unable to get Volume Group");
- goto out;
- }
+ ret = snprintf(key, sizeof(key), "%s.brick%d.status", keyprefix, i);
+ if (ret < 0)
+ goto out;
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "volumeGroup",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_INFO, "Unable to get Brick Running");
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"brick_running", "N/A");
+ } else
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"brick_running", "%s", buffer);
- snprintf (key, sizeof (key), "%s.brick%d.status", keyprefix, i);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Unable to get Brick Running");
- goto out;
- }
+ ret = snprintf(key, sizeof(key), "%s.brick%d.pid", keyprefix, i);
+ if (ret < 0)
+ goto out;
- snprintf (key, sizeof (key), "%s.brick%d.pid", keyprefix, i);
+ ret = dict_get_int32(dict, key, &pid);
+ if (ret) {
+ gf_log("cli", GF_LOG_INFO, "Unable to get pid");
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"pid",
+ "N/A");
+ } else
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"pid",
+ "%d", pid);
- ret = dict_get_int32 (dict, key, &pid);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to get pid");
- goto out;
- }
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "pid", "%d", pid);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = snprintf(key, sizeof(key), "%s.brick%d.data", keyprefix, i);
+ if (ret < 0)
+ goto out;
- snprintf (key, sizeof (key), "%s.brick%d.data", keyprefix, i);
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get Data Percent");
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"data_percentage", "N/A");
+ } else
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"data_percentage", "%s", buffer);
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Unable to get Data Percent");
- goto out;
- }
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "lvUsage",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = snprintf(key, sizeof(key), "%s.brick%d.lvsize", keyprefix, i);
+ if (ret < 0)
+ goto out;
- snprintf (key, sizeof (key), "%s.brick%d.lvsize",
- keyprefix, i);
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_INFO, "Unable to get LV Size");
- goto out;
- }
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get LV Size");
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"lvSize",
+ "N/A");
+ } else {
+ /* Truncate any newline character */
+ buffer = strtok(buffer, "\n");
- /* Truncate any newline character */
- buffer = strtok (buffer, "\n");
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"lvSize",
+ "%s", buffer);
+ }
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "lvSize",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </brick> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ /* </brick> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot status of individual
@@ -4850,88 +4626,85 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_status_per_snap (xmlTextWriterPtr writer, xmlDocPtr doc,
- dict_t *dict, const char *keyprefix)
+cli_xml_snapshot_status_per_snap(xmlTextWriterPtr writer, xmlDocPtr doc,
+ dict_t *dict, const char *keyprefix)
{
- int ret = -1;
- int snapcount = 0;
- int volcount = 0;
- int i = 0;
- char *buffer = NULL;
- char key [PATH_MAX] = "";
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
- GF_ASSERT (keyprefix);
-
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapshot");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key, sizeof (key), "%s.snapname", keyprefix);
-
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to get snapname");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key, sizeof (key), "%s.uuid", keyprefix);
-
- ret = dict_get_str (dict, key, &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to get snap UUID");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "uuid",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ int ret = -1;
+ int volcount = 0;
+ int i = 0;
+ char *buffer = NULL;
+ char key[PATH_MAX] = "";
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+ GF_ASSERT(keyprefix);
+
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapshot");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "%s.snapname", keyprefix);
+
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get snapname");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "%s.uuid", keyprefix);
+
+ ret = dict_get_str(dict, key, &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get snap UUID");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"uuid", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ snprintf(key, sizeof(key), "%s.volcount", keyprefix);
+
+ ret = dict_get_int32(dict, key, &volcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Unable to get volume count");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"volCount", "%d",
+ volcount);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* Get snapshot status of individual snapshot volume */
+ for (i = 0; i < volcount; i++) {
+ /* <volume> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- snprintf (key, sizeof (key), "%s.volcount", keyprefix);
+ snprintf(key, sizeof(key), "%s.vol%d", keyprefix, i);
- ret = dict_get_int32 (dict, key, &volcount);
+ ret = cli_xml_snapshot_volume_status(writer, doc, dict, key);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to get volume count");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Could not get snap volume status");
+ goto out;
}
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "volCount",
- "%d", volcount);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* Get snapshot status of individual snapshot volume */
- for (i = 0 ; i < volcount ; i++) {
- /* <volume> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volume");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (key, sizeof (key), "%s.vol%d", keyprefix, i);
-
- ret = cli_xml_snapshot_volume_status (writer, doc,
- dict, key);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Could not get snap volume status");
- goto out;
- }
-
- /* </volume> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ /* </volume> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- /* </snapshot> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapshot> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot status output in xml format.
@@ -4943,64 +4716,63 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_status (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
+cli_xml_snapshot_status(xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
{
- int ret = -1;
- int snapcount = 0;
- int i = 0;
- int status_cmd = 0;
- char *str_value = NULL;
- char key [PATH_MAX] = "";
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
-
- /* <snapStatus> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapStatus");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_int32 (dict, "sub-cmd", &status_cmd);
+ int ret = -1;
+ int snapcount = 0;
+ int i = 0;
+ int status_cmd = 0;
+ char key[PATH_MAX] = "";
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+
+ /* <snapStatus> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapStatus");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_int32(dict, "sub-cmd", &status_cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch status type");
+ goto out;
+ }
+
+ if ((GF_SNAP_STATUS_TYPE_SNAP == status_cmd) ||
+ (GF_SNAP_STATUS_TYPE_ITER == status_cmd)) {
+ snapcount = 1;
+ } else {
+ ret = dict_get_int32(dict, "status.snapcount", &snapcount);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch status type");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Could not get snapcount");
+ goto out;
}
- if (GF_SNAP_STATUS_TYPE_SNAP == status_cmd) {
- snapcount = 1;
- } else {
- ret = dict_get_int32 (dict, "status.snapcount", &snapcount);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not get snapcount");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "count",
- "%d", snapcount);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"count", "%d",
+ snapcount);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- for (i = 0 ; i < snapcount; i++) {
- snprintf (key, sizeof (key), "status.snap%d", i);
+ for (i = 0; i < snapcount; i++) {
+ snprintf(key, sizeof(key), "status.snap%d", i);
- ret = cli_xml_snapshot_status_per_snap (writer, doc,
- dict, key);
- if (ret < 0) {
- gf_log ("cli", GF_LOG_ERROR, "failed to create xml "
- "output for snapshot status");
- goto out;
- }
+ ret = cli_xml_snapshot_status_per_snap(writer, doc, dict, key);
+ if (ret < 0) {
+ gf_log("cli", GF_LOG_ERROR,
+ "failed to create xml "
+ "output for snapshot status");
+ goto out;
}
+ }
- /* </snapStatus> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapStatus> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot config show output in xml format.
@@ -5012,153 +4784,149 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_config_show (xmlTextWriterPtr writer,
- xmlDocPtr doc, dict_t *dict)
+cli_xml_snapshot_config_show(xmlTextWriterPtr writer, xmlDocPtr doc,
+ dict_t *dict)
{
- int ret = -1;
- uint64_t i = 0;
- uint64_t value = 0;
- uint64_t volcount = 0;
- char buf[PATH_MAX] = "";
- char *str_value = NULL;
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
-
- /* <systemConfig> */
- ret = xmlTextWriterStartElement (writer,
- (xmlChar *)"systemConfig");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_uint64 (dict, "snap-max-hard-limit", &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get "
- "snap-max-hard-limit");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "hardLimit", "%"PRIu64, value);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ int ret = -1;
+ uint64_t i = 0;
+ uint64_t value = 0;
+ uint64_t volcount = 0;
+ char buf[PATH_MAX] = "";
+ char *str_value = NULL;
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+
+ /* <systemConfig> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"systemConfig");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_uint64(dict, "snap-max-hard-limit", &value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to get "
+ "snap-max-hard-limit");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"hardLimit",
+ "%" PRIu64, value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_uint64(dict, "snap-max-soft-limit", &value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to get "
+ "snap-max-soft-limit");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"softLimit",
+ "%" PRIu64 "%%", value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "auto-delete", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch auto-delete");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"autoDelete", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "snap-activate-on-create", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not fetch snap-activate-on-create-delete");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"activateOnCreate",
+ "%s", str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </systemConfig> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* <volumeConfig> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volumeConfig");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_uint64(dict, "voldisplaycount", &volcount);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch volcount");
+ goto out;
+ }
+
+ /* Get config of all the volumes */
+ for (i = 0; i < volcount; i++) {
+ /* <volume> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volume");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_uint64 (dict, "snap-max-soft-limit", &value);
+ snprintf(buf, sizeof(buf), "volume%" PRIu64 "-volname", i);
+ ret = dict_get_str(dict, buf, &str_value);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get "
- "snap-max-soft-limit");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch %s", buf);
+ goto out;
}
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "softLimit",
- "%"PRIu64"%%", value);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, "auto-delete", &str_value);
+ snprintf(buf, sizeof(buf), "volume%" PRIu64 "-snap-max-hard-limit", i);
+ ret = dict_get_uint64(dict, buf, &value);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch auto-delete");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch %s", buf);
+ goto out;
}
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "autoDelete", "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"hardLimit",
+ "%" PRIu64, value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_str (dict, "snap-activate-on-create", &str_value);
+ snprintf(buf, sizeof(buf), "volume%" PRIu64 "-active-hard-limit", i);
+ ret = dict_get_uint64(dict, buf, &value);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR,
- "Could not fetch snap-activate-on-create-delete");
- goto out;
+ gf_log("cli", GF_LOG_ERROR,
+ "Could not fetch"
+ " effective snap_max_hard_limit for "
+ "%s",
+ str_value);
+ goto out;
}
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "activateOnCreate", "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </systemConfig> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* <volumeConfig> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volumeConfig");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"effectiveHardLimit", "%" PRIu64, value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_uint64 (dict, "voldisplaycount", &volcount);
+ snprintf(buf, sizeof(buf), "volume%" PRIu64 "-snap-max-soft-limit", i);
+ ret = dict_get_uint64(dict, buf, &value);
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch volcount");
- goto out;
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch %s", buf);
+ goto out;
}
- /* Get config of all the volumes */
- for (i = 0; i < volcount; i++) {
- /* <volume> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volume");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (buf, sizeof(buf), "volume%"PRIu64"-volname", i);
- ret = dict_get_str (dict, buf, &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch %s", buf);
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "name", "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
-
- snprintf (buf, sizeof(buf),
- "volume%"PRIu64"-snap-max-hard-limit", i);
- ret = dict_get_uint64 (dict, buf, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch %s", buf);
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "hardLimit", "%"PRIu64, value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (buf, sizeof(buf),
- "volume%"PRIu64"-active-hard-limit", i);
- ret = dict_get_uint64 (dict, buf, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch"
- " effective snap_max_hard_limit for "
- "%s", str_value);
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "effectiveHardLimit",
- "%"PRIu64, value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- snprintf (buf, sizeof(buf),
- "volume%"PRIu64"-snap-max-soft-limit", i);
- ret = dict_get_uint64 (dict, buf, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch %s", buf);
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "softLimit",
- "%"PRIu64, value);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </volume> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"softLimit",
+ "%" PRIu64, value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
/* </volume> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- ret = 0;
+ /* </volume> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot config set output in xml format.
@@ -5170,87 +4938,84 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_config_set (xmlTextWriterPtr writer, xmlDocPtr doc,
- dict_t *dict)
+cli_xml_snapshot_config_set(xmlTextWriterPtr writer, xmlDocPtr doc,
+ dict_t *dict)
{
- int ret = -1;
- uint64_t hard_limit = 0;
- uint64_t soft_limit = 0;
- char *volname = NULL;
- char *auto_delete = NULL;
- char *snap_activate = NULL;
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
-
- /* This is optional parameter therefore ignore the error */
- ret = dict_get_uint64 (dict, "snap-max-hard-limit", &hard_limit);
- /* This is optional parameter therefore ignore the error */
- ret = dict_get_uint64 (dict, "snap-max-soft-limit", &soft_limit);
- ret = dict_get_str (dict, "auto-delete", &auto_delete);
- ret = dict_get_str (dict, "snap-activate-on-create", &snap_activate);
-
- if (!hard_limit && !soft_limit && !auto_delete && !snap_activate) {
- ret = -1;
- gf_log ("cli", GF_LOG_ERROR, "At least one option from "
- "snap-max-hard-limit, snap-max-soft-limit, auto-delete"
- " and snap-activate-on-create should be set");
- goto out;
- }
-
- /* Ignore the error, as volname is optional */
- ret = dict_get_str (dict, "volname", &volname);
-
- if (NULL == volname) {
- /* <systemConfig> */
- ret = xmlTextWriterStartElement (writer,
- (xmlChar *)"systemConfig");
- } else {
- /* <volumeConfig> */
- ret = xmlTextWriterStartElement (writer,
- (xmlChar *)"volumeConfig");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ int ret = -1;
+ uint64_t hard_limit = 0;
+ uint64_t soft_limit = 0;
+ char *volname = NULL;
+ char *auto_delete = NULL;
+ char *snap_activate = NULL;
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+
+ /* This is optional parameter therefore ignore the error */
+ ret = dict_get_uint64(dict, "snap-max-hard-limit", &hard_limit);
+ /* This is optional parameter therefore ignore the error */
+ ret = dict_get_uint64(dict, "snap-max-soft-limit", &soft_limit);
+ ret = dict_get_str(dict, "auto-delete", &auto_delete);
+ ret = dict_get_str(dict, "snap-activate-on-create", &snap_activate);
+
+ if (!hard_limit && !soft_limit && !auto_delete && !snap_activate) {
+ ret = -1;
+ gf_log("cli", GF_LOG_ERROR,
+ "At least one option from "
+ "snap-max-hard-limit, snap-max-soft-limit, auto-delete"
+ " and snap-activate-on-create should be set");
+ goto out;
+ }
+
+ /* Ignore the error, as volname is optional */
+ ret = dict_get_str(dict, "volname", &volname);
+
+ if (NULL == volname) {
+ /* <systemConfig> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"systemConfig");
+ } else {
+ /* <volumeConfig> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volumeConfig");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "name", "%s", volname);
- }
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ volname);
+ }
- XML_RET_CHECK_AND_GOTO (ret, out);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- if (hard_limit) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "newHardLimit",
- "%"PRIu64, hard_limit);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ if (hard_limit) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"newHardLimit",
+ "%" PRIu64, hard_limit);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- if (soft_limit) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "newSoftLimit",
- "%"PRIu64, soft_limit);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ if (soft_limit) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"newSoftLimit",
+ "%" PRIu64, soft_limit);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- if (auto_delete) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "autoDelete", "%s", auto_delete);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ if (auto_delete) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"autoDelete",
+ "%s", auto_delete);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- if (snap_activate) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "activateOnCreate", "%s", snap_activate);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
+ if (snap_activate) {
+ ret = xmlTextWriterWriteFormatElement(
+ writer, (xmlChar *)"activateOnCreate", "%s", snap_activate);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
- /* </volumeConfig> or </systemConfig> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </volumeConfig> or </systemConfig> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot config output in xml format.
@@ -5262,58 +5027,60 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_config (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
+cli_xml_snapshot_config(xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict)
{
- int ret = -1;
- int config_command = 0;
+ int ret = -1;
+ int config_command = 0;
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
- /* <snapConfig> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapConfig");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <snapConfig> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapConfig");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_int32 (dict, "config-command", &config_command);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Could not fetch config type");
- goto out;
- }
+ ret = dict_get_int32(dict, "config-command", &config_command);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Could not fetch config type");
+ goto out;
+ }
- switch (config_command) {
+ switch (config_command) {
case GF_SNAP_CONFIG_TYPE_SET:
- ret = cli_xml_snapshot_config_set (writer, doc, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create xml "
- "output for snapshot config set command");
- goto out;
- }
+ ret = cli_xml_snapshot_config_set(writer, doc, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create xml "
+ "output for snapshot config set command");
+ goto out;
+ }
- break;
+ break;
case GF_SNAP_CONFIG_DISPLAY:
- ret = cli_xml_snapshot_config_show (writer, doc, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create xml "
- "output for snapshot config show command");
- goto out;
- }
- break;
+ ret = cli_xml_snapshot_config_show(writer, doc, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create xml "
+ "output for snapshot config show command");
+ goto out;
+ }
+ break;
default:
- gf_log ("cli", GF_LOG_ERROR, "Uknown config command :%d",
- config_command);
- ret = -1;
- goto out;
- }
+ gf_log("cli", GF_LOG_ERROR, "Unknown config command :%d",
+ config_command);
+ ret = -1;
+ goto out;
+ }
- /* </snapConfig> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapConfig> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/* This function will generate snapshot activate or
@@ -5326,67 +5093,66 @@ out:
* @return 0 on success and -1 on failure
*/
static int
-cli_xml_snapshot_activate_deactivate (xmlTextWriterPtr writer, xmlDocPtr doc,
- dict_t *dict, int cmd)
+cli_xml_snapshot_activate_deactivate(xmlTextWriterPtr writer, xmlDocPtr doc,
+ dict_t *dict, int cmd)
{
- int ret = -1;
- char *buffer = NULL;
- char *tag = NULL;
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
-
- if (GF_SNAP_OPTION_TYPE_ACTIVATE == cmd) {
- tag = "snapActivate";
- } else if (GF_SNAP_OPTION_TYPE_DEACTIVATE == cmd) {
- tag = "snapDeactivate";
- } else {
- gf_log ("cli", GF_LOG_ERROR, "invalid command %d", cmd);
- goto out;
- }
-
- /* <snapActivate> or <snapDeactivate> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)tag);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* <snapshot> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapshot");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "snapname", &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snap name");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "snapuuid", &buffer);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid");
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "uuid",
- "%s", buffer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- /* </snapshot> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
-
- /* </snapActivate> or </snapDeactivate> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = 0;
+ int ret = -1;
+ char *buffer = NULL;
+ char *tag = NULL;
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+
+ if (GF_SNAP_OPTION_TYPE_ACTIVATE == cmd) {
+ tag = "snapActivate";
+ } else if (GF_SNAP_OPTION_TYPE_DEACTIVATE == cmd) {
+ tag = "snapDeactivate";
+ } else {
+ gf_log("cli", GF_LOG_ERROR, "invalid command %d", cmd);
+ goto out;
+ }
+
+ /* <snapActivate> or <snapDeactivate> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)tag);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* <snapshot> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapshot");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "snapname", &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "snapuuid", &buffer);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
+ goto out;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"uuid", "%s",
+ buffer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </snapshot> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ /* </snapActivate> or </snapDeactivate> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
#endif /* HAVE_LIB_XML */
@@ -5400,191 +5166,183 @@ out:
* @return 0 on success and -1 on failure
*/
int
-cli_xml_snapshot_delete (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict,
- gf_cli_rsp *rsp)
+cli_xml_snapshot_delete(cli_local_t *local, dict_t *dict, gf_cli_rsp *rsp)
{
- int ret = -1;
+ int ret = -1;
#ifdef HAVE_LIB_XML
- char *str_value = NULL;
-
- GF_ASSERT (writer);
- GF_ASSERT (doc);
- GF_ASSERT (dict);
-
- /* <snapshot> */
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"snapshot");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = dict_get_str (dict, "snapname", &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snap name");
- goto xmlend;
- }
-
- if (!rsp->op_ret) {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "status",
- "Success");
- XML_RET_CHECK_AND_GOTO (ret, xmlend);
- } else {
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *) "status",
- "Failure");
- XML_RET_CHECK_AND_GOTO (ret, xmlend);
-
- ret = cli_xml_output_common (writer, rsp->op_ret,
- rsp->op_errno,
- rsp->op_errstr);
- XML_RET_CHECK_AND_GOTO (ret, xmlend);
- }
-
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "name",
- "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, xmlend);
-
- ret = dict_get_str (dict, "snapuuid", &str_value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snap uuid");
- goto xmlend;
- }
-
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *) "uuid",
- "%s", str_value);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ char *str_value = NULL;
+ xmlTextWriterPtr writer = local->writer;
+ xmlDocPtr doc = local->doc;
+
+ GF_ASSERT(writer);
+ GF_ASSERT(doc);
+ GF_ASSERT(dict);
+
+ /* <snapshot> */
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"snapshot");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_str(dict, "snapname", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap name");
+ goto xmlend;
+ }
+
+ if (!rsp->op_ret) {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"status",
+ "Success");
+ } else {
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"status",
+ "Failure");
+ XML_RET_CHECK_AND_GOTO(ret, xmlend);
+
+ ret = cli_xml_output_common(writer, rsp->op_ret, rsp->op_errno,
+ rsp->op_errstr);
+ }
+ XML_RET_CHECK_AND_GOTO(ret, xmlend);
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"name", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, xmlend);
+
+ ret = dict_get_str(dict, "snapuuid", &str_value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get snap uuid");
+ goto xmlend;
+ }
+
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"uuid", "%s",
+ str_value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
xmlend:
- /* </snapshot> */
- ret = xmlTextWriterEndElement (writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapshot> */
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
#endif /* HAVE_LIB_XML */
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
-cli_xml_output_snap_status_begin (cli_local_t *local, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_snap_status_begin(cli_local_t *local, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- GF_ASSERT (local);
+ GF_ASSERT(local);
- ret = cli_begin_xml_output (&(local->writer), &(local->doc));
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = cli_begin_xml_output(&(local->writer), &(local->doc));
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_xml_output_common (local->writer, op_ret, op_errno,
- op_errstr);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = cli_xml_output_common(local->writer, op_ret, op_errno, op_errstr);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <snapStatus> */
- ret = xmlTextWriterStartElement (local->writer,
- (xmlChar *) "snapStatus");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <snapStatus> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"snapStatus");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <snapshots> */
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"snapshots");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <snapshots> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"snapshots");
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_TRACE, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_snap_status_end (cli_local_t *local)
+cli_xml_output_snap_status_end(cli_local_t *local)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- GF_ASSERT (local);
+ GF_ASSERT(local);
- /* </snapshots> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapshots> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </snapStatus> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO(ret, out);
+ /* </snapStatus> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_end_xml_output (local->writer, local->doc);
+ ret = cli_end_xml_output(local->writer, local->doc);
out:
- gf_log ("cli", GF_LOG_TRACE, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_snap_delete_begin (cli_local_t *local, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_snap_delete_begin(cli_local_t *local, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- int delete_cmd = -1;
+ int ret = -1;
+ int delete_cmd = -1;
- GF_ASSERT (local);
+ GF_ASSERT(local);
- ret = cli_begin_xml_output (&(local->writer), &(local->doc));
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = cli_begin_xml_output(&(local->writer), &(local->doc));
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_int32 (local->dict, "sub-cmd", &delete_cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get sub-cmd");
- goto out;
- }
+ ret = dict_get_int32(local->dict, "sub-cmd", &delete_cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to get sub-cmd");
+ goto out;
+ }
- ret = cli_xml_output_common (local->writer, op_ret, op_errno,
- op_errstr);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = cli_xml_output_common(local->writer, op_ret, op_errno, op_errstr);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <snapStatus> */
- ret = xmlTextWriterStartElement (local->writer,
- (xmlChar *) "snapDelete");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <snapStatus> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"snapDelete");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* <snapshots> */
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"snapshots");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* <snapshots> */
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"snapshots");
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- gf_log ("cli", GF_LOG_TRACE, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_xml_output_snap_delete_end (cli_local_t *local)
+cli_xml_output_snap_delete_end(cli_local_t *local)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- GF_ASSERT (local);
+ GF_ASSERT(local);
- /* </snapshots> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ /* </snapshots> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- /* </snapDelete> */
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO(ret, out);
+ /* </snapDelete> */
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_end_xml_output (local->writer, local->doc);
+ ret = cli_end_xml_output(local->writer, local->doc);
out:
- gf_log ("cli", GF_LOG_TRACE, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
/* This function will generate xml output for all the snapshot commands
@@ -5598,466 +5356,484 @@ out:
* @return 0 on success and -1 on failure
*/
int
-cli_xml_output_snapshot (int cmd_type, dict_t *dict, int op_ret,
- int op_errno, char *op_errstr)
+cli_xml_output_snapshot(int cmd_type, dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
-
- GF_ASSERT (dict);
-
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to output "
- "xml begin block");
- goto out;
- }
-
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to output "
- "xml common block");
- goto out;
- }
-
- /* In case of command failure just printing the error message is good
- * enough */
- if (0 != op_ret) {
- goto end;
- }
-
- switch (cmd_type) {
+ int ret = -1;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+
+ GF_ASSERT(dict);
+
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to output "
+ "xml begin block");
+ goto out;
+ }
+
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to output "
+ "xml common block");
+ goto out;
+ }
+
+ /* In case of command failure just printing the error message is good
+ * enough */
+ if (0 != op_ret) {
+ goto end;
+ }
+
+ switch (cmd_type) {
case GF_SNAP_OPTION_TYPE_CREATE:
- ret = cli_xml_snapshot_create (writer, doc, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot create command");
- goto out;
- }
- break;
+ ret = cli_xml_snapshot_create(writer, doc, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create "
+ "xml output for snapshot create command");
+ goto out;
+ }
+ break;
+ case GF_SNAP_OPTION_TYPE_CLONE:
+ ret = cli_xml_snapshot_clone(writer, doc, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create "
+ "xml output for snapshot clone command");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_RESTORE:
- ret = cli_xml_snapshot_restore (writer, doc, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot restore command");
- goto out;
- }
- break;
+ ret = cli_xml_snapshot_restore(writer, doc, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create "
+ "xml output for snapshot restore command");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_LIST:
- ret = cli_xml_snapshot_list (writer, doc, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot list command");
- goto out;
- }
- break;
+ ret = cli_xml_snapshot_list(writer, doc, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create "
+ "xml output for snapshot list command");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_STATUS:
- ret = cli_xml_snapshot_status (writer, doc, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create"
- "xml output for snapshot status command");
- goto out;
- }
- break;
+ ret = cli_xml_snapshot_status(writer, doc, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create"
+ "xml output for snapshot status command");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_INFO:
- ret = cli_xml_snapshot_info (writer, doc, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot info command");
- goto out;
- }
- break;
+ ret = cli_xml_snapshot_info(writer, doc, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create "
+ "xml output for snapshot info command");
+ goto out;
+ }
+ break;
case GF_SNAP_OPTION_TYPE_ACTIVATE:
case GF_SNAP_OPTION_TYPE_DEACTIVATE:
- ret = cli_xml_snapshot_activate_deactivate (writer, doc,
- dict, cmd_type);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot config command");
- }
- break;
+ ret = cli_xml_snapshot_activate_deactivate(writer, doc, dict,
+ cmd_type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create "
+ "xml output for snapshot config command");
+ }
+ break;
case GF_SNAP_OPTION_TYPE_CONFIG:
- ret = cli_xml_snapshot_config (writer, doc, dict);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to create "
- "xml output for snapshot config command");
- }
- break;
+ ret = cli_xml_snapshot_config(writer, doc, dict);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to create "
+ "xml output for snapshot config command");
+ }
+ break;
default:
- gf_log ("cli", GF_LOG_ERROR,
- "Unexpected snapshot command: %d", cmd_type);
- goto out;
- }
+ gf_log("cli", GF_LOG_ERROR, "Unexpected snapshot command: %d",
+ cmd_type);
+ goto out;
+ }
end:
- ret = cli_end_xml_output (writer, doc);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to output "
- "xml end block");
- goto out;
- }
-
- ret = 0;
+ ret = cli_end_xml_output(writer, doc);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to output "
+ "xml end block");
+ goto out;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
#else
- return 0;
+ return 0;
#endif /* HAVE_LIB_XML */
}
int
-cli_xml_snapshot_begin_composite_op (cli_local_t *local)
+cli_xml_snapshot_begin_composite_op(cli_local_t *local)
{
- int ret = -1;
+ int ret = -1;
#ifdef HAVE_LIB_XML
- int cmd = -1;
- int type = -1;
-
- ret = dict_get_int32 (local->dict, "sub-cmd", &cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get "
- "sub-cmd");
- ret = 0;
- goto out;
- }
-
- if (cmd == GF_SNAP_STATUS_TYPE_SNAP ||
- cmd == GF_SNAP_DELETE_TYPE_SNAP){
- ret = 0;
- goto out;
- }
-
- ret = dict_get_int32 (local->dict, "type", &type);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snapshot "
- "command type from dictionary");
- goto out;
- }
-
- if (GF_SNAP_OPTION_TYPE_STATUS == type)
- ret = cli_xml_output_snap_status_begin (local, 0, 0, NULL);
- else if (GF_SNAP_OPTION_TYPE_DELETE == type)
- ret = cli_xml_output_snap_delete_begin (local, 0, 0, NULL);
+ int cmd = -1;
+ int type = -1;
+
+ ret = dict_get_int32(local->dict, "sub-cmd", &cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to get "
+ "sub-cmd");
+ ret = 0;
+ goto out;
+ }
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Error creating xml output");
- goto out;
- }
+ if (cmd == GF_SNAP_STATUS_TYPE_ITER || cmd == GF_SNAP_DELETE_TYPE_SNAP) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_int32(local->dict, "type", &type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to get snapshot "
+ "command type from dictionary");
+ goto out;
+ }
+
+ if (GF_SNAP_OPTION_TYPE_STATUS == type)
+ ret = cli_xml_output_snap_status_begin(local, 0, 0, NULL);
+ else if (GF_SNAP_OPTION_TYPE_DELETE == type)
+ ret = cli_xml_output_snap_delete_begin(local, 0, 0, NULL);
+
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "Error creating xml output");
+ goto out;
+ }
#endif /* HAVE_LIB_XML */
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
-cli_xml_snapshot_end_composite_op (cli_local_t *local)
+cli_xml_snapshot_end_composite_op(cli_local_t *local)
{
- int ret = -1;
+ int ret = -1;
#ifdef HAVE_LIB_XML
- int cmd = -1;
- int type = -1;
-
- ret = dict_get_int32 (local->dict, "sub-cmd", &cmd);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get "
- "sub-cmd");
- ret = 0;
- goto out;
- }
-
- if (cmd == GF_SNAP_STATUS_TYPE_SNAP ||
- cmd == GF_SNAP_DELETE_TYPE_SNAP){
- ret = 0;
- goto out;
- }
-
- ret = dict_get_int32 (local->dict, "type", &type);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to get snapshot "
- "command type from dictionary");
- goto out;
- }
-
- if (GF_SNAP_OPTION_TYPE_STATUS == type)
- ret = cli_xml_output_snap_status_end (local);
- else if (GF_SNAP_OPTION_TYPE_DELETE == type)
- ret = cli_xml_output_snap_delete_end (local);
+ int cmd = -1;
+ int type = -1;
+
+ ret = dict_get_int32(local->dict, "sub-cmd", &cmd);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to get "
+ "sub-cmd");
+ ret = 0;
+ goto out;
+ }
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Error creating xml "
- "output");
- goto out;
- }
-#endif /* HAVE_LIB_XML */
+ if (cmd == GF_SNAP_STATUS_TYPE_ITER || cmd == GF_SNAP_DELETE_TYPE_SNAP) {
ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_int32(local->dict, "type", &type);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to get snapshot "
+ "command type from dictionary");
+ goto out;
+ }
+
+ if (GF_SNAP_OPTION_TYPE_STATUS == type)
+ ret = cli_xml_output_snap_status_end(local);
+ else if (GF_SNAP_OPTION_TYPE_DELETE == type)
+ ret = cli_xml_output_snap_delete_end(local);
+
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Error creating xml "
+ "output");
+ goto out;
+ }
+#endif /* HAVE_LIB_XML */
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
-cli_xml_snapshot_status_single_snap (cli_local_t *local, dict_t *dict,
- char *key)
+cli_xml_snapshot_status_single_snap(cli_local_t *local, dict_t *dict, char *key)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- GF_VALIDATE_OR_GOTO ("cli", (local != NULL), out);
- GF_VALIDATE_OR_GOTO ("cli", (dict != NULL), out);
- GF_VALIDATE_OR_GOTO ("cli", (key != NULL), out);
+ GF_VALIDATE_OR_GOTO("cli", (local != NULL), out);
+ GF_VALIDATE_OR_GOTO("cli", (dict != NULL), out);
+ GF_VALIDATE_OR_GOTO("cli", (key != NULL), out);
- ret = cli_xml_snapshot_status_per_snap (local->writer, local->doc, dict,
- key);
+ ret = cli_xml_snapshot_status_per_snap(local->writer, local->doc, dict,
+ key);
out:
- return ret;
+ return ret;
#else
- return 0;
+ return 0;
#endif /* HAVE_LIB_XML */
}
int
-cli_xml_output_vol_getopts (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr)
+cli_xml_output_vol_getopts(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr)
{
#if (HAVE_LIB_XML)
- int i = 0;
- int ret = -1;
- int count = 0;
- xmlTextWriterPtr writer = NULL;
- xmlDocPtr doc = NULL;
- char *key = NULL;
- char *value = NULL;
- char dict_key[50] = {0,};
-
- ret = cli_begin_xml_output (&writer, &doc);
- if (ret)
- goto out;
+ int i = 0;
+ int ret = -1;
+ int count = 0;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ char dict_key[50] = {
+ 0,
+ };
+
+ ret = cli_begin_xml_output(&writer, &doc);
+ if (ret)
+ goto out;
+
+ ret = cli_xml_output_common(writer, op_ret, op_errno, op_errstr);
+ if (ret)
+ goto out;
+
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"volGetopts");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = dict_get_int32(dict, "count", &count);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to retrieve count "
+ "from the dictionary");
+ goto out;
+ }
+ if (count <= 0) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Value of count :%d is "
+ "invalid",
+ count);
+ ret = -1;
+ goto out;
+ }
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"count", "%d",
+ count);
+
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ for (i = 1; i <= count; i++) {
+ sprintf(dict_key, "key%d", i);
+ ret = dict_get_str(dict, dict_key, &key);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to"
+ " retrieve %s from the "
+ "dictionary",
+ dict_key);
+ goto out;
+ }
+ sprintf(dict_key, "value%d", i);
+ ret = dict_get_str(dict, dict_key, &value);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR,
+ "Failed to "
+ "retrieve key value for %s from"
+ "the dictionary",
+ dict_key);
+ goto out;
+ }
+ ret = xmlTextWriterStartElement(writer, (xmlChar *)"Opt");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = cli_xml_output_common (writer, op_ret, op_errno, op_errstr);
- if (ret)
- goto out;
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"Option", "%s",
+ key);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterStartElement (writer, (xmlChar *)"volGetopts");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"Value", "%s",
+ value);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to retrieve count "
- "from the dictionary");
- goto out;
- }
- if (count <= 0) {
- gf_log ("cli", GF_LOG_ERROR, "Value of count :%d is "
- "invalid", count);
- ret = -1;
- goto out;
- }
- ret = xmlTextWriterWriteFormatElement (writer, (xmlChar *)"count",
- "%d", count);
-
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- for (i=1; i<=count; i++) {
- sprintf (dict_key, "key%d", i);
- ret = dict_get_str (dict, dict_key, &key);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to"
- " retrieve %s from the "
- "dictionary", dict_key);
- goto out;
- }
- sprintf (dict_key, "value%d", i);
- ret = dict_get_str (dict, dict_key, &value);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Failed to "
- "retrieve key value for %s from"
- "the dictionary", dict_key);
- goto out;
- }
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"Option",
- "%s", key);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (writer,
- (xmlChar *)"Value",
- "%s", value);
- XML_RET_CHECK_AND_GOTO (ret, out);
- }
- ret = cli_end_xml_output (writer, doc);
+ ret = xmlTextWriterEndElement(writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ }
+ ret = cli_end_xml_output(writer, doc);
out:
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
#else
- return 0;
+ return 0;
#endif /* HAVE_LIB_XML */
}
int
-cli_quota_list_xml_error (cli_local_t *local, char *path,
- char *errstr)
+cli_quota_list_xml_error(cli_local_t *local, char *path, char *errstr)
{
#if (HAVE_LIB_XML)
- int ret = -1;
+ int ret = -1;
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"limit");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"limit");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"path",
- "%s", path);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"path",
+ "%s", path);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"errstr",
- "%s", errstr);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"errstr",
+ "%s", errstr);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- return ret;
+ return ret;
#else
- return 0;
+ return 0;
#endif
}
int
-cli_quota_xml_output (cli_local_t *local, char *path, char *hl_str,
- char *sl_final, void *used, void *avail, char *sl,
- char *hl)
+cli_quota_xml_output(cli_local_t *local, char *path, int64_t hl_str,
+ char *sl_final, int64_t sl_num, int64_t used,
+ int64_t avail, char *sl, char *hl, gf_boolean_t limit_set)
{
#if (HAVE_LIB_XML)
- int ret = -1;
-
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"limit");
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"path",
- "%s", path);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"hard_limit",
- "%s", hl_str);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"soft_limit",
- "%s", sl_final);
- XML_RET_CHECK_AND_GOTO (ret, out);
-
- if ((char *)used) {
- ret = xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"used_space", "%s",
- (char *)used);
- } else {
- ret = xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"user_space", "%11"PRIu64,
- *(long unsigned int *)used);
- }
- XML_RET_CHECK_AND_GOTO (ret, out);
+ int ret = -1;
- if ((char *)avail) {
- ret = xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"avail_space", "%s",
- (char *)avail);
- } else {
- ret = xmlTextWriterWriteFormatElement
- (local->writer, (xmlChar *)"avail_space", "%11"PRIu64,
- *(long unsigned int *)avail);
- }
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"limit");
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"path",
+ "%s", path);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"sl_exceeded",
- "%s", sl);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"hard_limit", !limit_set ? "N/A" : "%" PRId64,
+ hl_str);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"hl_exceeded",
- "%s", hl);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(local->writer,
+ (xmlChar *)"soft_limit_percent",
+ !limit_set ? "N/A" : "%s", sl_final);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"soft_limit_value",
+ !limit_set ? "N/A" : "%" PRId64, sl_num);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"used_space", "%" PRId64, used);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"avail_space",
+ !limit_set ? "N/A" : "%" PRId64, avail);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"sl_exceeded", !limit_set ? "N/A" : "%s", sl);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"hl_exceeded", !limit_set ? "N/A" : "%s", hl);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- return ret;
+ return ret;
#else
- return 0;
+ return 0;
#endif /* HAVE_LIB_XML */
}
int
-cli_quota_object_xml_output (cli_local_t *local, char *path, char *sl_str,
- quota_limits_t *limits, quota_meta_t *used_space,
- int64_t avail, char *sl, char *hl)
+cli_quota_object_xml_output(cli_local_t *local, char *path, char *sl_str,
+ int64_t sl_val, quota_limits_t *limits,
+ quota_meta_t *used_space, int64_t avail, char *sl,
+ char *hl, gf_boolean_t limit_set)
{
#if (HAVE_LIB_XML)
- int ret = -1;
-
- ret = xmlTextWriterStartElement (local->writer, (xmlChar *)"limit");
- XML_RET_CHECK_AND_GOTO (ret, out);
+ int ret = -1;
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"path",
- "%s", path);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterStartElement(local->writer, (xmlChar *)"limit");
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"hard_limit",
- "%"PRIu64, limits->hl);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"path",
+ "%s", path);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"soft_limit",
- "%s", sl_str);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"hard_limit", !limit_set ? "N/A" : "%" PRId64,
+ limits->hl);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"file_count",
- "%"PRIu64,
- used_space->file_count);
+ ret = xmlTextWriterWriteFormatElement(local->writer,
+ (xmlChar *)"soft_limit_percent",
+ !limit_set ? "N/A" : "%s", sl_str);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"soft_limit_value",
+ !limit_set ? "N/A" : "%" PRIu64, sl_val);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"dir_count", "%"PRIu64,
- used_space->dir_count);
+ ret = xmlTextWriterWriteFormatElement(local->writer,
+ (xmlChar *)"file_count", "%" PRId64,
+ used_space->file_count);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"dir_count",
+ "%" PRIu64, used_space->dir_count);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"available", "%"PRIu64,
- avail);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(local->writer, (xmlChar *)"available",
+ !limit_set ? "N/A" : "%" PRId64,
+ avail);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"sl_exceeded",
- "%s", sl);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterWriteFormatElement (local->writer,
- (xmlChar *)"hl_exceeded",
- "%s", hl);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"sl_exceeded", !limit_set ? "N/A" : "%s", sl);
+ XML_RET_CHECK_AND_GOTO(ret, out);
+ ret = xmlTextWriterWriteFormatElement(
+ local->writer, (xmlChar *)"hl_exceeded", !limit_set ? "N/A" : "%s", hl);
+ XML_RET_CHECK_AND_GOTO(ret, out);
- ret = xmlTextWriterEndElement (local->writer);
- XML_RET_CHECK_AND_GOTO (ret, out);
+ ret = xmlTextWriterEndElement(local->writer);
+ XML_RET_CHECK_AND_GOTO(ret, out);
out:
- return ret;
+ return ret;
#else
- return 0;
+ return 0;
#endif /* HAVE_LIB_XML */
}
diff --git a/cli/src/cli.c b/cli/src/cli.c
index 5707d3fbdd7..a52b39c5fb8 100644
--- a/cli/src/cli.c
+++ b/cli/src/cli.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010-2016 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
@@ -33,755 +33,880 @@
#include <malloc.h>
#endif
-#ifdef HAVE_MALLOC_STATS
-#ifdef DEBUG
-#include <mcheck.h>
-#endif
-#endif
-
#include "cli.h"
#include "cli-quotad-client.h"
#include "cli-cmd.h"
#include "cli-mem-types.h"
-#include "xlator.h"
-#include "glusterfs.h"
-#include "compat.h"
-#include "logging.h"
-#include "dict.h"
-#include "list.h"
-#include "timer.h"
-#include "stack.h"
-#include "revision.h"
-#include "common-utils.h"
-#include "event.h"
-#include "globals.h"
-#include "syscall.h"
-#include "call-stub.h"
+#include <glusterfs/xlator.h>
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/compat.h>
+#include <glusterfs/logging.h>
+#include <glusterfs/dict.h>
+#include <glusterfs/list.h>
+#include <glusterfs/timer.h>
+#include <glusterfs/stack.h>
+#include <glusterfs/revision.h>
+#include <glusterfs/common-utils.h>
+#include <glusterfs/gf-event.h>
+#include <glusterfs/syscall.h>
+#include <glusterfs/call-stub.h>
#include <fnmatch.h>
#include "xdr-generic.h"
-extern int connected;
/* using argp for command line parsing */
-const char *argp_program_version = "" \
- PACKAGE_NAME" "PACKAGE_VERSION" built on "__DATE__" "__TIME__ \
- "\nRepository revision: " GLUSTERFS_REPOSITORY_REVISION "\n" \
- "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 General Public License.";
-
+const char *argp_program_version =
+ "" PACKAGE_NAME " " PACKAGE_VERSION
+ "\nRepository revision: " GLUSTERFS_REPOSITORY_REVISION
+ "\n"
+ "Copyright (c) 2006-2016 Red Hat, Inc. "
+ "<https://www.gluster.org/>\n"
+ "GlusterFS comes with ABSOLUTELY NO WARRANTY.\n"
+ "It is licensed to you under your choice of the GNU Lesser\n"
+ "General Public License, version 3 or any later version (LGPLv3\n"
+ "or later), or the GNU General Public License, version 2 (GPLv2),\n"
+ "in all cases as published by the Free Software Foundation.";
const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
-
-
struct rpc_clnt *global_quotad_rpc;
+
struct rpc_clnt *global_rpc;
rpc_clnt_prog_t *cli_rpc_prog;
-
extern struct rpc_clnt_program cli_prog;
+int cli_default_conn_timeout = 120;
+int cli_ten_minutes_timeout = 600;
+
static int
-glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
+glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx)
{
- cmd_args_t *cmd_args = NULL;
- struct rlimit lim = {0, };
- call_pool_t *pool = NULL;
- int ret = -1;
-
- ret = xlator_mem_acct_init (THIS, cli_mt_end);
- if (ret != 0) {
- return ret;
- }
-
- ctx->process_uuid = generate_glusterfs_ctx_id ();
- if (!ctx->process_uuid)
- return -1;
-
- ctx->page_size = 128 * GF_UNIT_KB;
-
- ctx->iobuf_pool = iobuf_pool_new ();
- if (!ctx->iobuf_pool)
- return -1;
-
- ctx->event_pool = event_pool_new (DEFAULT_EVENT_POOL_SIZE,
- STARTING_EVENT_THREADS);
- if (!ctx->event_pool)
- return -1;
-
- pool = GF_CALLOC (1, sizeof (call_pool_t),
- cli_mt_call_pool_t);
- if (!pool)
- return -1;
-
- /* 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 * 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, 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;
-
- ctx->logbuf_pool = mem_pool_new (log_buf_t, 256);
- if (!ctx->logbuf_pool)
- return -1;
-
- INIT_LIST_HEAD (&pool->all_frames);
- LOCK_INIT (&pool->lock);
- ctx->pool = pool;
-
- pthread_mutex_init (&(ctx->lock), NULL);
-
- cmd_args = &ctx->cmd_args;
-
- INIT_LIST_HEAD (&cmd_args->xlator_options);
+ cmd_args_t *cmd_args = NULL;
+ struct rlimit lim = {
+ 0,
+ };
+ call_pool_t *pool = NULL;
+ int ret = -1;
+
+ if (!ctx)
+ return ret;
- lim.rlim_cur = RLIM_INFINITY;
- lim.rlim_max = RLIM_INFINITY;
- setrlimit (RLIMIT_CORE, &lim);
+ ret = xlator_mem_acct_init(THIS, cli_mt_end);
+ if (ret != 0) {
+ gf_log("cli", GF_LOG_ERROR, "Memory accounting init failed.");
+ return ret;
+ }
+
+ /* Resetting ret to -1 to so in case of failure
+ * we can relese allocated resource.
+ */
+ ret = -1;
+
+ ctx->process_uuid = generate_glusterfs_ctx_id();
+ if (!ctx->process_uuid) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to generate uuid.");
+ goto out;
+ }
+
+ ctx->page_size = 128 * GF_UNIT_KB;
+
+ ctx->iobuf_pool = iobuf_pool_new();
+ if (!ctx->iobuf_pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to create iobuf pool.");
+ goto out;
+ }
+
+ ctx->event_pool = gf_event_pool_new(DEFAULT_EVENT_POOL_SIZE,
+ STARTING_EVENT_THREADS);
+ if (!ctx->event_pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to create event pool.");
+ goto out;
+ }
+
+ pool = GF_CALLOC(1, sizeof(call_pool_t), cli_mt_call_pool_t);
+ if (!pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to create call pool.");
+ goto out;
+ }
+
+ /* frame_mem_pool size 112 * 64 */
+ pool->frame_mem_pool = mem_pool_new(call_frame_t, 32);
+ if (!pool->frame_mem_pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to create frame mem pool.");
+ goto out;
+ }
+
+ /* stack_mem_pool size 256 * 128 */
+ pool->stack_mem_pool = mem_pool_new(call_stack_t, 16);
+
+ if (!pool->stack_mem_pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to create stack mem pool.");
+ goto out;
+ }
+
+ ctx->stub_mem_pool = mem_pool_new(call_stub_t, 16);
+ if (!ctx->stub_mem_pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to stub mem pool.");
+ goto out;
+ }
+
+ ctx->dict_pool = mem_pool_new(dict_t, 32);
+ if (!ctx->dict_pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to create dict pool.");
+ goto out;
+ }
+
+ ctx->dict_pair_pool = mem_pool_new(data_pair_t, 512);
+ if (!ctx->dict_pair_pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to create dict pair pool.");
+ goto out;
+ }
+
+ ctx->dict_data_pool = mem_pool_new(data_t, 512);
+ if (!ctx->dict_data_pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to create dict data pool.");
+ goto out;
+ }
+
+ ctx->logbuf_pool = mem_pool_new(log_buf_t, 256);
+ if (!ctx->logbuf_pool) {
+ gf_log("cli", GF_LOG_ERROR, "Failed to create logbuf pool.");
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&pool->all_frames);
+ LOCK_INIT(&pool->lock);
+ ctx->pool = pool;
+
+ cmd_args = &ctx->cmd_args;
+
+ INIT_LIST_HEAD(&cmd_args->xlator_options);
+
+ lim.rlim_cur = RLIM_INFINITY;
+ lim.rlim_max = RLIM_INFINITY;
+ setrlimit(RLIMIT_CORE, &lim);
+
+ ret = 0;
- return 0;
+out:
+ if (ret != 0) {
+ if (pool) {
+ mem_pool_destroy(pool->frame_mem_pool);
+ mem_pool_destroy(pool->stack_mem_pool);
+ }
+ GF_FREE(pool);
+ pool = NULL;
+ GF_FREE(ctx->process_uuid);
+ mem_pool_destroy(ctx->stub_mem_pool);
+ mem_pool_destroy(ctx->dict_pool);
+ mem_pool_destroy(ctx->dict_pair_pool);
+ mem_pool_destroy(ctx->dict_data_pool);
+ mem_pool_destroy(ctx->logbuf_pool);
+ }
+
+ return ret;
}
-
static int
-logging_init (glusterfs_ctx_t *ctx, struct cli_state *state)
+logging_init(glusterfs_ctx_t *ctx, struct cli_state *state)
{
- char *log_file = state->log_file ? state->log_file :
- DEFAULT_CLI_LOG_FILE_DIRECTORY "/cli.log";
-
- /* passing ident as NULL means to use default ident for syslog */
- if (gf_log_init (ctx, log_file, NULL) == -1) {
- fprintf (stderr, "ERROR: failed to open logfile %s\n",
- log_file);
- return -1;
- }
-
- /* CLI should not have something to DEBUG after the release,
- hence defaulting to INFO loglevel */
- gf_log_set_loglevel ((state->log_level == GF_LOG_NONE) ? GF_LOG_INFO :
- state->log_level);
-
- return 0;
+ char *log_file = state->log_file ? state->log_file
+ : DEFAULT_CLI_LOG_FILE_DIRECTORY
+ "/cli.log";
+
+ /* passing ident as NULL means to use default ident for syslog */
+ if (gf_log_init(ctx, log_file, NULL) == -1) {
+ fprintf(stderr, "ERROR: failed to open logfile %s\n", log_file);
+ }
+
+ /* CLI should not have something to DEBUG after the release,
+ hence defaulting to INFO loglevel */
+ gf_log_set_loglevel(ctx, (state->log_level == GF_LOG_NONE)
+ ? GF_LOG_INFO
+ : state->log_level);
+
+ return 0;
}
int
-cli_submit_request (struct rpc_clnt *rpc, void *req, call_frame_t *frame,
- rpc_clnt_prog_t *prog,
- int procnum, struct iobref *iobref,
- xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
+cli_submit_request(struct rpc_clnt *rpc, void *req, call_frame_t *frame,
+ rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref,
+ xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
{
- int ret = -1;
- int count = 0;
- struct iovec iov = {0, };
- struct iobuf *iobuf = NULL;
- char new_iobref = 0;
- ssize_t xdr_size = 0;
-
- GF_ASSERT (this);
-
- 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;
- }
-
- new_iobref = 1;
- }
-
- iobref_add (iobref, iobuf);
-
- iov.iov_base = iobuf->ptr;
- iov.iov_len = iobuf_size (iobuf);
-
-
- /* Create the xdr payload */
- ret = xdr_serialize_generic (iov, req, xdrproc);
- if (ret == -1) {
- goto out;
- }
- iov.iov_len = ret;
- count = 1;
+ int ret = -1;
+ int count = 0;
+ struct iovec iov = {
+ 0,
+ };
+ struct iobuf *iobuf = NULL;
+ char new_iobref = 0;
+ ssize_t xdr_size = 0;
+
+ GF_ASSERT(this);
+
+ 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;
+ }
+
+ new_iobref = 1;
+ }
+
+ iobref_add(iobref, iobuf);
+
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = iobuf_size(iobuf);
+
+ /* Create the xdr payload */
+ ret = xdr_serialize_generic(iov, req, xdrproc);
+ if (ret == -1) {
+ goto out;
}
+ iov.iov_len = ret;
+ count = 1;
+ }
- if (!rpc)
- rpc = global_rpc;
- /* Send the msg */
- ret = rpc_clnt_submit (rpc, prog, procnum, cbkfn,
- &iov, count,
- NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
- ret = 0;
+ if (!rpc)
+ rpc = global_rpc;
+ /* Send the msg */
+ ret = rpc_clnt_submit(rpc, prog, procnum, cbkfn, &iov, count, NULL, 0,
+ iobref, frame, NULL, 0, NULL, 0, NULL);
+ ret = 0;
out:
- if (new_iobref)
- iobref_unref (iobref);
- if (iobuf)
- iobuf_unref (iobuf);
- return ret;
+ if (new_iobref)
+ iobref_unref(iobref);
+ if (iobuf)
+ iobuf_unref(iobuf);
+ return ret;
}
int
-cli_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
- void *data)
+cli_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
+ void *data)
{
- xlator_t *this = NULL;
- int ret = 0;
-
- this = mydata;
+ xlator_t *this = NULL;
+ int ret = 0;
- switch (event) {
- case RPC_CLNT_CONNECT:
- {
+ this = mydata;
- cli_cmd_broadcast_connected ();
- gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
- break;
+ switch (event) {
+ case RPC_CLNT_CONNECT: {
+ cli_cmd_broadcast_connected(_gf_true);
+ gf_log(this->name, GF_LOG_TRACE, "got RPC_CLNT_CONNECT");
+ break;
}
- case RPC_CLNT_DISCONNECT:
- {
- 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;
+ case RPC_CLNT_DISCONNECT: {
+ cli_cmd_broadcast_connected(_gf_false);
+ gf_log(this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT");
+ if (!global_state->prompt && global_state->await_connected) {
+ ret = 1;
+ cli_out(
+ "Connection failed. Please check if gluster "
+ "daemon is operational.");
+ exit(ret);
+ }
+ break;
}
default:
- gf_log (this->name, GF_LOG_TRACE,
- "got some other RPC event %d", event);
- ret = 0;
- break;
- }
+ gf_log(this->name, GF_LOG_TRACE, "got some other RPC event %d",
+ event);
+ ret = 0;
+ break;
+ }
- return ret;
+ return ret;
}
+static gf_boolean_t
+is_valid_int(char *str)
+{
+ if (*str == '-')
+ ++str;
+
+ /* Handle empty string or just "-".*/
+ if (!*str)
+ return _gf_false;
+
+ /* Check for non-digit chars in the rest of the string */
+ while (*str) {
+ if (!isdigit(*str))
+ return _gf_false;
+ else
+ ++str;
+ }
+ return _gf_true;
+}
/*
* ret: 0: option successfully processed
* 1: signalling end of option list
- * -1: unknown option or other issue
+ * -1: unknown option
+ * -2: parsing issue (avoid unknown option error)
*/
int
-cli_opt_parse (char *opt, struct cli_state *state)
+cli_opt_parse(char *opt, struct cli_state *state)
{
- char *oarg = NULL;
- gf_boolean_t secure_mgmt_tmp = 0;
-
- if (strcmp (opt, "") == 0)
- return 1;
-
- if (strcmp (opt, "version") == 0) {
- cli_out ("%s", argp_program_version);
- exit (0);
- }
-
- if (strcmp (opt, "print-logdir") == 0) {
- cli_out ("%s", DEFAULT_LOG_FILE_DIRECTORY);
- exit (0);
- }
-
- if (strcmp (opt, "print-statedumpdir") == 0) {
- cli_out ("%s", DEFAULT_VAR_RUN_DIRECTORY);
- exit (0);
- }
-
- if (strcmp (opt, "xml") == 0) {
+ char *oarg = NULL;
+ gf_boolean_t secure_mgmt_tmp = 0;
+
+ if (strcmp(opt, "") == 0)
+ return 1;
+ if (strcmp(opt, "help") == 0) {
+ cli_out(
+ " peer help - display help for peer commands\n"
+ " volume help - display help for volume commands\n"
+ " volume bitrot help - display help for volume"
+ " bitrot commands\n"
+ " volume quota help - display help for volume"
+ " quota commands\n"
+ " snapshot help - display help for snapshot commands\n"
+ " global help - list global commands\n");
+ exit(0);
+ }
+
+ if (strcmp(opt, "version") == 0) {
+ cli_out("%s", argp_program_version);
+ exit(0);
+ }
+
+ if (strcmp(opt, "print-logdir") == 0) {
+ cli_out("%s", DEFAULT_LOG_FILE_DIRECTORY);
+ exit(0);
+ }
+
+ if (strcmp(opt, "print-statedumpdir") == 0) {
+ cli_out("%s", DEFAULT_VAR_RUN_DIRECTORY);
+ exit(0);
+ }
+
+ if (strcmp(opt, "xml") == 0) {
#if (HAVE_LIB_XML)
- state->mode |= GLUSTER_MODE_XML;
+ state->mode |= GLUSTER_MODE_XML;
#else
- cli_err ("XML output not supported. Ignoring '--xml' option");
+ cli_err("XML output not supported. Ignoring '--xml' option");
#endif
- return 0;
- }
+ return 0;
+ }
- if (strcmp (opt, "wignore") == 0) {
- state->mode |= GLUSTER_MODE_WIGNORE;
- return 0;
- }
+ if (strcmp(opt, "nolog") == 0) {
+ state->mode |= GLUSTER_MODE_GLFSHEAL_NOLOG;
+ return 0;
+ }
- oarg = strtail (opt, "mode=");
- if (oarg) {
- if (strcmp (oarg, "script") == 0) {
- state->mode |= GLUSTER_MODE_SCRIPT;
- return 0;
- }
+ if (strcmp(opt, "wignore-partition") == 0) {
+ state->mode |= GLUSTER_MODE_WIGNORE_PARTITION;
+ return 0;
+ }
- if (strcmp (oarg, "interactive") == 0)
- return 0;
+ if (strcmp(opt, "wignore") == 0) {
+ state->mode |= GLUSTER_MODE_WIGNORE;
+ return 0;
+ }
- return -1;
+ oarg = strtail(opt, "mode=");
+ if (oarg) {
+ if (strcmp(oarg, "script") == 0) {
+ state->mode |= GLUSTER_MODE_SCRIPT;
+ return 0;
}
- oarg = strtail (opt, "remote-host=");
- if (oarg) {
- state->remote_host = oarg;
- return 0;
- }
+ if (strcmp(oarg, "interactive") == 0)
+ return 0;
- oarg = strtail (opt, "log-file=");
- if (oarg) {
- state->log_file = oarg;
- return 0;
- }
+ return -1;
+ }
- oarg = strtail (opt, "log-level=");
- if (oarg) {
- state->log_level = glusterd_check_log_level(oarg);
- if (state->log_level == -1)
- return -1;
- return 0;
- }
+ oarg = strtail(opt, "remote-host=");
+ if (oarg) {
+ state->remote_host = oarg;
+ return 0;
+ }
- oarg = strtail (opt, "glusterd-sock=");
- if (oarg) {
- state->glusterd_sock = oarg;
- return 0;
+ oarg = strtail(opt, "inet6");
+ if (oarg) {
+ state->address_family = "inet6";
+ return 0;
+ }
+
+ oarg = strtail(opt, "log-file=");
+ if (oarg) {
+ state->log_file = oarg;
+ return 0;
+ }
+ oarg = strtail(opt, "timeout=");
+ if (oarg) {
+ if (!is_valid_int(oarg) || atoi(oarg) <= 0) {
+ cli_err("timeout value should be a positive integer");
+ return -2; /* -2 instead of -1 to avoid unknown option
+ error */
}
+ cli_default_conn_timeout = atoi(oarg);
+ return 0;
+ }
+
+ oarg = strtail(opt, "log-level=");
+ if (oarg) {
+ int log_level = glusterd_check_log_level(oarg);
+ if (log_level == -1)
+ return -1;
+ state->log_level = (gf_loglevel_t)log_level;
+ return 0;
+ }
- oarg = strtail (opt, "secure-mgmt=");
- if (oarg) {
- if (gf_string2boolean(oarg,&secure_mgmt_tmp) == 0) {
- if (secure_mgmt_tmp) {
- /* See declaration for why this is an int. */
- state->ctx->secure_mgmt = 1;
- }
- }
- else {
- cli_err ("invalide secure-mgmt value (ignored)");
- }
- return 0;
+ oarg = strtail(opt, "glusterd-sock=");
+ if (oarg) {
+ state->glusterd_sock = oarg;
+ return 0;
+ }
+
+ oarg = strtail(opt, "secure-mgmt=");
+ if (oarg) {
+ if (gf_string2boolean(oarg, &secure_mgmt_tmp) == 0) {
+ if (secure_mgmt_tmp) {
+ /* See declaration for why this is an int. */
+ state->ctx->secure_mgmt = 1;
+ }
+ } else {
+ cli_err("invalid secure-mgmt value (ignored)");
}
+ return 0;
+ }
- return -1;
+ return -1;
}
int
-parse_cmdline (int argc, char *argv[], struct cli_state *state)
+parse_cmdline(int argc, char *argv[], struct cli_state *state)
{
- int ret = 0;
- int i = 0;
- int j = 0;
- char *opt = NULL;
- gf_boolean_t geo_rep_config = _gf_false;
-
- state->argc=argc-1;
- state->argv=&argv[1];
-
- /* Do this first so that an option can override. */
- if (access(SECURE_ACCESS_FILE,F_OK) == 0) {
- state->ctx->secure_mgmt = 1;
+ int ret = 0;
+ int i = 0;
+ int j = 0;
+ char *opt = NULL;
+
+ state->argc = argc - 1;
+ state->argv = &argv[1];
+
+ /* Do this first so that an option can override. */
+ if (sys_access(SECURE_ACCESS_FILE, F_OK) == 0) {
+ state->ctx->secure_mgmt = 1;
+ state->ctx->ssl_cert_depth = glusterfs_read_secure_access_file();
+ }
+
+ if (state->argc > GEO_REP_CMD_CONFIG_INDEX &&
+ strtail(state->argv[GEO_REP_CMD_INDEX], "geo") &&
+ strtail(state->argv[GEO_REP_CMD_CONFIG_INDEX], "co"))
+ goto done;
+
+ for (i = 0; i < state->argc; i++) {
+ opt = strtail(state->argv[i], "--");
+ if (!opt)
+ continue;
+ ret = cli_opt_parse(opt, state);
+ if (ret == -1) {
+ cli_out("unrecognized option --%s\n", opt);
+ usage();
+ return ret;
+ } else if (ret == -2) {
+ return ret;
}
-
- if (state->argc > GEO_REP_CMD_CONFIG_INDEX &&
- strtail (state->argv[GEO_REP_CMD_INDEX], "geo") &&
- strtail (state->argv[GEO_REP_CMD_CONFIG_INDEX], "co"))
- geo_rep_config = _gf_true;
-
- for (i = 0; i < state->argc; i++) {
- opt = strtail (state->argv[i], "--");
- if (opt && !geo_rep_config) {
- ret = cli_opt_parse (opt, state);
- if (ret == -1) {
- cli_out ("unrecognized option --%s", opt);
- return ret;
- }
- 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--;
- if (ret == 1) {
- /* end of cli options */
- ret = 0;
- break;
- }
- }
+ 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--;
+ if (ret == 1) {
+ /* end of cli options */
+ ret = 0;
+ break;
}
+ }
- state->argv[state->argc] = NULL;
+done:
+ state->argv[state->argc] = NULL;
- return ret;
+ return ret;
}
-
int
-cli_cmd_tree_init (struct cli_cmd_tree *tree)
+cli_cmd_tree_init(struct cli_cmd_tree *tree)
{
- struct cli_cmd_word *root = NULL;
- int ret = 0;
+ struct cli_cmd_word *root = NULL;
+ int ret = 0;
- root = &tree->root;
- root->tree = tree;
+ root = &tree->root;
+ root->tree = tree;
- return ret;
+ return ret;
}
-
int
-cli_state_init (struct cli_state *state)
+cli_state_init(struct cli_state *state)
{
- struct cli_cmd_tree *tree = NULL;
- int ret = 0;
+ struct cli_cmd_tree *tree = NULL;
+ int ret = 0;
+ state->log_level = GF_LOG_NONE;
- state->log_level = GF_LOG_NONE;
+ tree = &state->tree;
+ tree->state = state;
- tree = &state->tree;
- tree->state = state;
+ ret = cli_cmd_tree_init(tree);
- ret = cli_cmd_tree_init (tree);
-
- return ret;
+ return ret;
}
int
-cli_usage_out (const char *usage)
+cli_usage_out(const char *usage)
{
- GF_ASSERT (usage);
- GF_ASSERT (usage[0] != '\0');
+ GF_ASSERT(usage);
- if (!usage || usage[0] == '\0')
- return -1;
+ if (!usage || usage[0] == '\0')
+ return -1;
- cli_err ("Usage: %s", usage);
- return 0;
+ cli_err("\nUsage:\n%s\n", usage);
+ return 0;
}
int
-_cli_err (const char *fmt, ...)
+_cli_err(const char *fmt, ...)
{
- struct cli_state *state = NULL;
- va_list ap;
- int ret = 0;
-
- state = global_state;
+ va_list ap;
+ int ret = 0;
+#ifdef HAVE_READLINE
+ struct cli_state *state = global_state;
+#endif
- va_start (ap, fmt);
+ va_start(ap, fmt);
#ifdef HAVE_READLINE
- if (state->rl_enabled && !state->rl_processing)
- return cli_rl_err(state, fmt, ap);
+ if (state->rl_enabled && !state->rl_processing) {
+ ret = cli_rl_err(state, fmt, ap);
+ va_end(ap);
+ return ret;
+ }
#endif
- ret = vfprintf (stderr, fmt, ap);
- fprintf (stderr, "\n");
- va_end (ap);
+ ret = vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
- return ret;
+ return ret;
}
-
int
-_cli_out (const char *fmt, ...)
+_cli_out(const char *fmt, ...)
{
- struct cli_state *state = NULL;
- va_list ap;
- int ret = 0;
-
- state = global_state;
-
- va_start (ap, fmt);
+ va_list ap;
+ int ret = 0;
+#ifdef HAVE_READLINE
+ struct cli_state *state = global_state;
+#endif
+ va_start(ap, fmt);
#ifdef HAVE_READLINE
- if (state->rl_enabled && !state->rl_processing)
- return cli_rl_out(state, fmt, ap);
+ if (state->rl_enabled && !state->rl_processing) {
+ ret = cli_rl_out(state, fmt, ap);
+ va_end(ap);
+ return ret;
+ }
#endif
- ret = vprintf (fmt, ap);
- printf ("\n");
- va_end (ap);
+ ret = vprintf(fmt, ap);
+ printf("\n");
+ va_end(ap);
- return ret;
+ return ret;
}
struct rpc_clnt *
-cli_quotad_clnt_rpc_init (void)
+cli_quotad_clnt_rpc_init(void)
{
- struct rpc_clnt *rpc = NULL;
- dict_t *rpc_opts = NULL;
- int ret = -1;
-
- rpc_opts = dict_new ();
- if (!rpc_opts) {
- ret = -1;
- goto out;
- }
+ struct rpc_clnt *rpc = NULL;
+ dict_t *rpc_opts = NULL;
+ int ret = -1;
+
+ rpc_opts = dict_new();
+ if (!rpc_opts) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_str(rpc_opts, "transport.address-family", "unix");
+ if (ret)
+ goto out;
+
+ ret = dict_set_str(rpc_opts, "transport-type", "socket");
+ if (ret)
+ goto out;
+
+ ret = dict_set_str(rpc_opts, "transport.socket.connect-path",
+ "/var/run/gluster/quotad.socket");
+ if (ret)
+ goto out;
+
+ rpc = cli_quotad_clnt_init(THIS, rpc_opts);
+ if (!rpc)
+ goto out;
+
+ global_quotad_rpc = rpc;
+out:
+ if (rpc_opts) {
+ dict_unref(rpc_opts);
+ }
+ return rpc;
+}
- ret = dict_set_str (rpc_opts, "transport.address-family", "unix");
- if (ret)
- goto out;
+struct rpc_clnt *
+cli_rpc_init(struct cli_state *state)
+{
+ struct rpc_clnt *rpc = NULL;
+ dict_t *options = NULL;
+ int ret = -1;
+ int port = CLI_GLUSTERD_PORT;
+ xlator_t *this = NULL;
+#ifdef IPV6_DEFAULT
+ char *addr_family = "inet6";
+#else
+ char *addr_family = "inet";
+#endif
- ret = dict_set_str (rpc_opts, "transport-type", "socket");
+ this = THIS;
+ cli_rpc_prog = &cli_prog;
+
+ options = dict_new();
+ if (!options)
+ goto out;
+
+ /* If address family specified in CLI */
+ if (state->address_family) {
+ addr_family = state->address_family;
+ }
+
+ /* Connect to glusterd using the specified method, giving preference
+ * to a unix socket connection. If nothing is specified, connect to
+ * the default glusterd socket.
+ */
+ if (state->glusterd_sock) {
+ gf_log("cli", GF_LOG_INFO,
+ "Connecting to glusterd using "
+ "sockfile %s",
+ state->glusterd_sock);
+ ret = rpc_transport_unix_options_build(options, state->glusterd_sock,
+ 0);
if (ret)
- goto out;
-
- ret = dict_set_str (rpc_opts, "transport.socket.connect-path",
- "/var/run/gluster/quotad.socket");
+ goto out;
+ } else if (state->remote_host) {
+ gf_log("cli", GF_LOG_INFO,
+ "Connecting to remote glusterd at "
+ "%s",
+ state->remote_host);
+
+ ret = dict_set_str(options, "remote-host", state->remote_host);
if (ret)
- goto out;
-
- rpc = cli_quotad_clnt_init (THIS, rpc_opts);
- if (!rpc)
- goto out;
+ goto out;
- global_quotad_rpc = rpc;
-out:
- if (ret) {
- if (rpc_opts)
- dict_destroy(rpc_opts);
- }
- return rpc;
-}
+ if (state->remote_port)
+ port = state->remote_port;
-struct rpc_clnt *
-cli_rpc_init (struct cli_state *state)
-{
- struct rpc_clnt *rpc = NULL;
- dict_t *options = NULL;
- int ret = -1;
- int port = CLI_GLUSTERD_PORT;
- xlator_t *this = NULL;
-
- this = THIS;
- cli_rpc_prog = &cli_prog;
- options = dict_new ();
- if (!options)
- goto out;
+ ret = dict_set_int32(options, "remote-port", port);
+ if (ret)
+ goto out;
- /* Connect to glusterd using the specified method, giving preference
- * to a unix socket connection. If nothing is specified, connect to
- * the default glusterd socket.
- */
- if (state->glusterd_sock) {
- gf_log ("cli", GF_LOG_INFO, "Connecting to glusterd using "
- "sockfile %s", state->glusterd_sock);
- ret = rpc_transport_unix_options_build (&options,
- state->glusterd_sock,
- 0);
- if (ret)
- goto out;
- }
- else if (state->remote_host) {
- gf_log ("cli", GF_LOG_INFO, "Connecting to remote glusterd at "
- "%s", state->remote_host);
- ret = dict_set_str (options, "remote-host", state->remote_host);
- if (ret)
- goto out;
-
- if (state->remote_port)
- port = state->remote_port;
-
- ret = dict_set_int32 (options, "remote-port", port);
- if (ret)
- goto out;
-
- ret = dict_set_str (options, "transport.address-family",
- "inet");
- if (ret)
- goto out;
- }
- else {
- gf_log ("cli", GF_LOG_DEBUG, "Connecting to glusterd using "
- "default socket");
- ret = rpc_transport_unix_options_build
- (&options, DEFAULT_GLUSTERD_SOCKFILE, 0);
- if (ret)
- goto out;
- }
+ ret = dict_set_str(options, "transport.address-family", addr_family);
+ if (ret)
+ goto out;
+ } else {
+ gf_log("cli", GF_LOG_DEBUG,
+ "Connecting to glusterd using "
+ "default socket");
+ ret = rpc_transport_unix_options_build(options,
+ DEFAULT_GLUSTERD_SOCKFILE, 0);
+ if (ret)
+ goto out;
+ }
- rpc = rpc_clnt_new (options, this, this->name, 16);
- if (!rpc)
- goto out;
+ rpc = rpc_clnt_new(options, this, this->name, 16);
+ if (!rpc)
+ goto out;
- ret = rpc_clnt_register_notify (rpc, cli_rpc_notify, this);
- if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "failed to register notify");
- goto out;
- }
+ ret = rpc_clnt_register_notify(rpc, cli_rpc_notify, this);
+ if (ret) {
+ gf_log("cli", GF_LOG_ERROR, "failed to register notify");
+ goto out;
+ }
- ret = rpc_clnt_start (rpc);
+ ret = rpc_clnt_start(rpc);
out:
- if (ret) {
- if (rpc)
- rpc_clnt_unref (rpc);
- rpc = NULL;
- }
- return rpc;
+ if (options)
+ dict_unref(options);
+
+ if (ret) {
+ if (rpc)
+ rpc_clnt_unref(rpc);
+ rpc = NULL;
+ }
+ return rpc;
}
cli_local_t *
-cli_local_get ()
+cli_local_get()
{
- cli_local_t *local = NULL;
+ cli_local_t *local = NULL;
- local = GF_CALLOC (1, sizeof (*local), cli_mt_cli_local_t);
- LOCK_INIT (&local->lock);
+ local = GF_CALLOC(1, sizeof(*local), cli_mt_cli_local_t);
+ LOCK_INIT(&local->lock);
+ INIT_LIST_HEAD(&local->dict_list);
- return local;
+ return local;
}
void
-cli_local_wipe (cli_local_t *local)
+cli_local_wipe(cli_local_t *local)
{
- if (local) {
- GF_FREE (local->get_vol.volname);
- if (local->dict)
- dict_unref (local->dict);
- GF_FREE (local);
- }
-
- return;
+ if (local) {
+ GF_FREE(local->get_vol.volname);
+ if (local->dict)
+ dict_unref(local->dict);
+ GF_FREE(local);
+ }
+
+ return;
}
struct cli_state *global_state;
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- struct cli_state state = {0, };
- int ret = -1;
- glusterfs_ctx_t *ctx = NULL;
+ struct cli_state state = {
+ 0,
+ };
+ int ret = -1;
+ glusterfs_ctx_t *ctx = NULL;
- ctx = glusterfs_ctx_new ();
- if (!ctx)
- return ENOMEM;
+ mem_pools_init();
+
+ ctx = glusterfs_ctx_new();
+ if (!ctx)
+ return ENOMEM;
#ifdef DEBUG
- gf_mem_acct_enable_set (ctx);
+ gf_mem_acct_enable_set(ctx);
#endif
- ret = glusterfs_globals_init (ctx);
- if (ret)
- return ret;
+ ret = glusterfs_globals_init(ctx);
+ if (ret)
+ return ret;
- THIS->ctx = ctx;
+ THIS->ctx = ctx;
- ret = glusterfs_ctx_defaults_init (ctx);
- if (ret)
- goto out;
+ ret = glusterfs_ctx_defaults_init(ctx);
+ if (ret)
+ goto out;
- ret = cli_state_init (&state);
- if (ret)
- goto out;
+ cli_default_conn_timeout = 120;
+ cli_ten_minutes_timeout = 600;
- state.ctx = ctx;
- global_state = &state;
+ ret = cli_state_init(&state);
+ if (ret)
+ goto out;
- ret = parse_cmdline (argc, argv, &state);
- if (ret)
- goto out;
+ state.ctx = ctx;
+ global_state = &state;
- ret = logging_init (ctx, &state);
- if (ret)
- goto out;
+ ret = parse_cmdline(argc, argv, &state);
+ if (ret)
+ goto out;
- gf_log ("cli", GF_LOG_INFO, "Started running %s with version %s",
- argv[0], PACKAGE_VERSION);
+ ret = logging_init(ctx, &state);
+ if (ret)
+ goto out;
- global_rpc = cli_rpc_init (&state);
- if (!global_rpc)
- goto out;
+ gf_log("cli", GF_LOG_INFO, "Started running %s with version %s", argv[0],
+ PACKAGE_VERSION);
- global_quotad_rpc = cli_quotad_clnt_rpc_init ();
- if (!global_quotad_rpc)
- goto out;
+ global_rpc = cli_rpc_init(&state);
+ if (!global_rpc)
+ goto out;
- ret = cli_cmds_register (&state);
- if (ret)
- goto out;
+ global_quotad_rpc = cli_quotad_clnt_rpc_init();
+ if (!global_quotad_rpc)
+ goto out;
- ret = cli_cmd_cond_init ();
- if (ret)
- goto out;
+ ret = cli_cmds_register(&state);
+ if (ret)
+ goto out;
- ret = cli_input_init (&state);
- if (ret)
- goto out;
+ ret = cli_input_init(&state);
+ if (ret)
+ goto out;
- ret = event_dispatch (ctx->event_pool);
+ ret = gf_event_dispatch(ctx->event_pool);
out:
-// glusterfs_ctx_destroy (ctx);
+ // glusterfs_ctx_destroy (ctx);
- return ret;
+ mem_pools_fini();
+
+ return ret;
}
void
-cli_print_line (int len)
+cli_print_line(int len)
{
- GF_ASSERT (len > 0);
+ GF_ASSERT(len > 0);
- while (len--)
- printf ("-");
+ while (len--)
+ printf("-");
- printf ("\n");
+ printf("\n");
}
void
-print_quota_list_header (int type)
+print_quota_list_header(int type)
{
- if (type == GF_QUOTA_OPTION_TYPE_LIST) {
- cli_out (" Path Hard-limit "
- " Soft-limit Used Available Soft-limit "
- "exceeded? Hard-limit exceeded?");
- cli_out ("-----------------------------------------------------"
- "-----------------------------------------------------"
- "---------------------");
- } else {
- cli_out (" Path Hard-limit "
- " Soft-limit Files Dirs Available "
- "Soft-limit exceeded? Hard-limit exceeded?");
- cli_out ("-----------------------------------------------------"
- "-----------------------------------------------------"
- "-------------------------------------");
- }
+ if (type == GF_QUOTA_OPTION_TYPE_LIST) {
+ cli_out(
+ " Path Hard-limit "
+ " Soft-limit Used Available Soft-limit "
+ "exceeded? Hard-limit exceeded?");
+ cli_out(
+ "-----------------------------------------------------"
+ "-----------------------------------------------------"
+ "---------------------");
+ } else {
+ cli_out(
+ " Path Hard-limit "
+ " Soft-limit Files Dirs Available "
+ "Soft-limit exceeded? Hard-limit exceeded?");
+ cli_out(
+ "-----------------------------------------------------"
+ "-----------------------------------------------------"
+ "-------------------------------------");
+ }
}
void
-print_quota_list_empty (char *path, int type)
+print_quota_list_empty(char *path, int type)
{
- if (type == GF_QUOTA_OPTION_TYPE_LIST)
- cli_out ("%-40s %7s %9s %10s %7s %15s %20s", path,
- "N/A", "N/A", "N/A", "N/A", "N/A", "N/A");
- else
- cli_out ("%-40s %9s %9s %12s %10s %10s %15s %20s", path,
- "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A");
+ if (type == GF_QUOTA_OPTION_TYPE_LIST)
+ cli_out("%-40s %7s %9s %10s %7s %15s %20s", path, "N/A", "N/A", "N/A",
+ "N/A", "N/A", "N/A");
+ else
+ cli_out("%-40s %9s %9s %12s %10s %10s %15s %20s", path, "N/A", "N/A",
+ "N/A", "N/A", "N/A", "N/A", "N/A");
}
-
diff --git a/cli/src/cli.h b/cli/src/cli.h
index f5441c07ec0..c0d933e8f8a 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -11,468 +11,506 @@
#define __CLI_H__
#include "rpc-clnt.h"
-#include "glusterfs.h"
+#include <glusterfs/glusterfs.h>
#include "protocol-common.h"
-#include "logging.h"
-#include "quota-common-utils.h"
+#include <glusterfs/logging.h>
+#include <glusterfs/quota-common-utils.h>
#include "cli1-xdr.h"
+#include "gd-common-utils.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_TEN_MINUTES_TIMEOUT 600 //Longer timeout for volume top
-#define DEFAULT_CLI_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
-#define CLI_VOL_STATUS_BRICK_LEN 43
-#define CLI_TAB_LENGTH 8
-#define CLI_BRICK_STATUS_LINE_LEN 78
+#define DEFAULT_EVENT_POOL_SIZE 16384
+#define CLI_GLUSTERD_PORT 24007
+#define DEFAULT_CLI_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
+#define CLI_VOL_STATUS_BRICK_LEN 43
+#define CLI_TAB_LENGTH 8
+#define CLI_BRICK_STATUS_LINE_LEN 78
/* Geo-rep command positional arguments' index */
-#define GEO_REP_CMD_INDEX 1
-#define GEO_REP_CMD_CONFIG_INDEX 4
+#define GEO_REP_CMD_INDEX 1
+#define GEO_REP_CMD_CONFIG_INDEX 4
enum argp_option_keys {
- ARGP_DEBUG_KEY = 133,
- ARGP_PORT_KEY = 'p',
+ ARGP_DEBUG_KEY = 133,
+ ARGP_PORT_KEY = 'p',
};
-#define GLUSTER_MODE_SCRIPT (1 << 0)
+extern int cli_default_conn_timeout;
+extern int cli_ten_minutes_timeout;
+
+typedef enum {
+ COLD_BRICK_COUNT,
+ COLD_TYPE,
+ COLD_DIST_COUNT,
+ COLD_REPLICA_COUNT,
+ COLD_ARBITER_COUNT,
+ COLD_DISPERSE_COUNT,
+ COLD_REDUNDANCY_COUNT,
+ HOT_BRICK_COUNT,
+ HOT_TYPE,
+ HOT_REPLICA_COUNT,
+ MAX
+} values;
+
+#define GLUSTER_MODE_SCRIPT (1 << 0)
#define GLUSTER_MODE_ERR_FATAL (1 << 1)
-#define GLUSTER_MODE_XML (1 << 2)
-#define GLUSTER_MODE_WIGNORE (1 << 3)
+#define GLUSTER_MODE_XML (1 << 2)
+#define GLUSTER_MODE_WIGNORE (1 << 3)
+#define GLUSTER_MODE_WIGNORE_PARTITION (1 << 4)
+#define GLUSTER_MODE_GLFSHEAL_NOLOG (1 << 5)
-
-#define GLUSTERD_GET_QUOTA_AUX_MOUNT_PATH(abspath, volname, path) \
- snprintf (abspath, sizeof (abspath)-1, \
- DEFAULT_VAR_RUN_DIRECTORY"/%s%s", volname, path);
-
-#define GLUSTERFS_GET_AUX_MOUNT_PIDFILE(pidfile,volname) { \
- snprintf (pidfile, PATH_MAX-1, \
- DEFAULT_VAR_RUN_DIRECTORY"/%s.pid", volname); \
- }
+#define GLUSTERD_GET_QUOTA_LIST_MOUNT_PATH(abspath, volname, path) \
+ do { \
+ snprintf(abspath, sizeof(abspath) - 1, \
+ DEFAULT_VAR_RUN_DIRECTORY "/%s_quota_list%s", volname, path); \
+ } while (0)
struct cli_state;
struct cli_cmd_word;
struct cli_cmd_tree;
struct cli_cmd;
-extern char *cli_vol_type_str[];
extern char *cli_vol_status_str[];
extern char *cli_vol_task_status_str[];
-typedef int (cli_cmd_cbk_t)(struct cli_state *state,
- struct cli_cmd_word *word,
- const char **words,
- int wordcount);
-typedef void (cli_cmd_reg_cbk_t)( struct cli_cmd *this);
+typedef int(cli_cmd_cbk_t)(struct cli_state *state, struct cli_cmd_word *word,
+ const char **words, int wordcount);
+typedef void(cli_cmd_reg_cbk_t)(struct cli_cmd *this);
-typedef int (cli_cmd_match_t)(struct cli_cmd_word *word);
-typedef int (cli_cmd_filler_t)(struct cli_cmd_word *word);
+typedef int(cli_cmd_match_t)(struct cli_cmd_word *word);
+typedef int(cli_cmd_filler_t)(struct cli_cmd_word *word);
struct cli_cmd_word {
- struct cli_cmd_tree *tree;
- const char *word;
- cli_cmd_filler_t *filler;
- cli_cmd_match_t *match;
- cli_cmd_cbk_t *cbkfn;
- const char *desc;
- const char *pattern;
- int nextwords_cnt;
- struct cli_cmd_word **nextwords;
+ struct cli_cmd_tree *tree;
+ const char *word;
+ cli_cmd_filler_t *filler;
+ cli_cmd_match_t *match;
+ cli_cmd_cbk_t *cbkfn;
+ const char *desc;
+ const char *pattern;
+ int nextwords_cnt;
+ struct cli_cmd_word **nextwords;
};
-
struct cli_cmd_tree {
- struct cli_state *state;
- struct cli_cmd_word root;
+ struct cli_state *state;
+ struct cli_cmd_word root;
};
-
struct cli_state {
- int argc;
- char **argv;
+ int argc;
+ char **argv;
- char debug;
+ char debug;
- /* for events dispatching */
- glusterfs_ctx_t *ctx;
+ /* for events dispatching */
+ glusterfs_ctx_t *ctx;
- /* registry of known commands */
- struct cli_cmd_tree tree;
+ /* registry of known commands */
+ struct cli_cmd_tree tree;
- /* the thread which "executes" the command in non-interactive mode */
- /* also the thread which reads from stdin in non-readline mode */
- pthread_t input;
+ /* the thread which "executes" the command in non-interactive mode */
+ /* also the thread which reads from stdin in non-readline mode */
+ pthread_t input;
- /* terminal I/O */
- const char *prompt;
- int rl_enabled;
- int rl_async;
- int rl_processing;
+ /* terminal I/O */
+ const char *prompt;
+ int rl_enabled;
+ int rl_async;
+ int rl_processing;
- /* autocompletion state */
- char **matches;
- char **matchesp;
+ /* autocompletion state */
+ char **matches;
+ char **matchesp;
- char *remote_host;
- int remote_port;
- int mode;
- int await_connected;
+ char *remote_host;
+ int remote_port;
+ int mode;
+ int await_connected;
- char *log_file;
- gf_loglevel_t log_level;
+ char *log_file;
+ gf_loglevel_t log_level;
- char *glusterd_sock;
+ char *glusterd_sock;
+ char *address_family;
};
struct cli_local {
- struct {
- char *volname;
- int flags;
- } get_vol;
-
- dict_t *dict;
- const char **words;
- /* Marker for volume status all */
- gf_boolean_t all;
+ struct {
+ char *volname;
+ int flags;
+ } get_vol;
+
+ dict_t *dict;
+ const char **words;
+ /* Marker for volume status all */
+ gf_boolean_t all;
#if (HAVE_LIB_XML)
- xmlTextWriterPtr writer;
- xmlDocPtr doc;
- int vol_count;
+ xmlTextWriterPtr writer;
+ xmlDocPtr doc;
+ int vol_count;
#endif
- gf_lock_t lock;
+ gf_lock_t lock;
+ struct list_head dict_list;
};
struct cli_volume_status {
- int port;
- int rdma_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
+ int port;
+ int rdma_port;
+ int online;
+ uint64_t block_size;
+ uint64_t total_inodes;
+ uint64_t free_inodes;
+ char *brick;
+ char *pid_str;
+ char *free;
+ char *total;
+ char *fs_name;
+ char *mount_options;
+ char *device;
+ char *inode_size;
};
struct snap_config_opt_vals_ {
- char *op_name;
- char *question;
+ char *op_name;
+ char *question;
};
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);
+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);
+extern struct rpc_clnt *global_quotad_rpc;
-char *get_struct_variable (int mem_num, gf_gsync_status_t *sts_val);
+extern struct rpc_clnt *global_rpc;
-void *cli_getunamb (const char *tok, void **choices, cli_selector_t sel);
+extern rpc_clnt_prog_t *cli_rpc_prog;
-int cli_cmd_register (struct cli_cmd_tree *tree, struct cli_cmd *cmd);
-int cli_cmds_register (struct cli_state *state);
+typedef const char *(*cli_selector_t)(void *wcon);
-int cli_input_init (struct cli_state *state);
+char *
+get_struct_variable(int mem_num, gf_gsync_status_t *sts_val);
-int cli_cmd_process (struct cli_state *state, int argc, char *argv[]);
-int cli_cmd_process_line (struct cli_state *state, const char *line);
+void *
+cli_getunamb(const char *tok, void **choices, cli_selector_t sel);
-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_cmd_register(struct cli_cmd_tree *tree, struct cli_cmd *cmd);
+int
+cli_cmds_register(struct cli_state *state);
-int cli_usage_out (const char *usage);
+int
+cli_input_init(struct cli_state *state);
-int _cli_out (const char *fmt, ...);
-int _cli_err (const char *fmt, ...);
+int
+cli_cmd_process(struct cli_state *state, int argc, char *argv[]);
+int
+cli_cmd_process_line(struct cli_state *state, const char *line);
-#define cli_out(fmt...) do { \
- FMT_WARN (fmt); \
- \
- _cli_out(fmt); \
- \
- } while (0)
+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);
-#define cli_err(fmt...) do { \
- FMT_WARN (fmt); \
- \
- _cli_err(fmt); \
- \
- } while (0)
+int
+cli_usage_out(const char *usage);
int
-cli_submit_request (struct rpc_clnt *rpc, void *req, call_frame_t *frame,
- rpc_clnt_prog_t *prog,
- int procnum, struct iobref *iobref,
- xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
+_cli_out(const char *fmt, ...);
+int
+_cli_err(const char *fmt, ...);
-int32_t
-cli_cmd_volume_create_parse (struct cli_state *state, const char **words,
- int wordcount, dict_t **options);
+#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)
+
+#define usage() \
+ do { \
+ cli_out( \
+ " Usage: gluster [options] <help> <peer>" \
+ " <pool> <volume>\n" \
+ " Options:\n" \
+ " --help Shows the help information\n" \
+ " --version Shows the version\n" \
+ " --print-logdir Shows the log directory\n" \
+ " --print-statedumpdir Shows the state dump directory\n"); \
+ \
+ } while (0)
+
+int
+cli_submit_request(struct rpc_clnt *rpc, void *req, call_frame_t *frame,
+ rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref,
+ xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
int32_t
-cli_cmd_volume_reset_parse (const char **words, int wordcount, dict_t **opt);
+cli_cmd_volume_create_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **bricks);
int32_t
-cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **opt);
+cli_cmd_volume_reset_parse(const char **words, int wordcount, dict_t **opt);
int32_t
-cli_cmd_quota_parse (const char **words, int wordcount, dict_t **opt);
+cli_cmd_gsync_set_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **opt, char **errstr);
int32_t
-cli_cmd_inode_quota_parse (const char **words, int wordcount, dict_t **opt);
+cli_cmd_quota_parse(const char **words, int wordcount, dict_t **opt);
int32_t
-cli_cmd_bitrot_parse (const char **words, int wordcount, dict_t **opt);
+cli_cmd_inode_quota_parse(const char **words, int wordcount, dict_t **opt);
int32_t
-cli_cmd_volume_set_parse (struct cli_state *state, const char **words,
- int wordcount, dict_t **options, char **op_errstr);
+cli_cmd_bitrot_parse(const char **words, int wordcount, dict_t **opt);
+
int32_t
-cli_cmd_ganesha_parse (struct cli_state *state, const char **words,
- int wordcount, dict_t **options, char **op_errstr);
+cli_cmd_volume_set_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **op_errstr);
int32_t
-cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
- dict_t **options, int *type);
+cli_cmd_ganesha_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **op_errstr);
int32_t
-cli_cmd_volume_detach_tier_parse (const char **words, int wordcount,
- dict_t **options);
+cli_cmd_get_state_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **op_errstr);
int32_t
-cli_cmd_volume_tier_parse (const char **words, int wordcount,
- dict_t **options);
+cli_cmd_volume_add_brick_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, int *type);
int32_t
-cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
- dict_t **options, int *question);
+cli_cmd_volume_remove_brick_parse(struct cli_state *state, const char **words,
+ int wordcount, dict_t **options,
+ int *question, int *brick_count,
+ int32_t *command);
int32_t
-cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
+cli_cmd_volume_replace_brick_parse(const char **words, int wordcount,
dict_t **options);
int32_t
-cli_cmd_log_rotate_parse (const char **words, int wordcount, dict_t **options);
+cli_cmd_volume_reset_brick_parse(const char **words, int wordcount,
+ dict_t **options);
+
+int32_t
+cli_cmd_log_rotate_parse(const char **words, int wordcount, dict_t **options);
int32_t
-cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options);
+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);
+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);
+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_cmd_volume_clrlks_opts_parse(const char **words, int wordcount,
+ dict_t **options);
-cli_local_t * cli_local_get ();
+cli_local_t *
+cli_local_get();
void
-cli_local_wipe (cli_local_t *local);
+cli_local_wipe(cli_local_t *local);
+
+gf_boolean_t
+cli_cmd_connected();
int32_t
-cli_cmd_await_connected ();
+cli_cmd_await_connected(unsigned timeout);
int32_t
-cli_cmd_broadcast_connected ();
+cli_cmd_broadcast_connected(gf_boolean_t status);
int
-cli_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
- void *data);
+cli_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
+ void *data);
int32_t
-cli_cmd_volume_profile_parse (const char **words, int wordcount,
- dict_t **options);
+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);
+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);
+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);
+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);
+cli_cmd_volume_heal_options_parse(const char **words, int wordcount,
+ dict_t **options);
int
-cli_cmd_volume_defrag_parse (const char **words, int wordcount,
- dict_t **options);
+cli_cmd_volume_defrag_parse(const char **words, int wordcount,
+ dict_t **options);
int
-cli_print_brick_status (cli_volume_status_t *status);
+cli_print_brick_status(cli_volume_status_t *status);
void
-cli_print_detailed_status (cli_volume_status_t *status);
+cli_print_detailed_status(cli_volume_status_t *status);
int
-cli_get_detail_status (dict_t *dict, int i, cli_volume_status_t *status);
+cli_get_detail_status(dict_t *dict, int i, cli_volume_status_t *status);
void
-cli_print_line (int len);
+cli_print_line(int len);
int
-cli_xml_output_str (char *op, char *str, int op_ret, int op_errno,
- char *op_errstr);
+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);
+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);
+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);
+cli_xml_output_vol_profile(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_output_vol_status_begin (cli_local_t *local, int op_ret, int op_errno,
- char *op_errstr);
+cli_xml_output_vol_status_begin(cli_local_t *local, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_output_vol_status_end (cli_local_t *local);
+cli_xml_output_vol_status_end(cli_local_t *local);
int
-cli_xml_output_vol_status (cli_local_t *local, dict_t *dict);
+cli_xml_output_vol_status(cli_local_t *local, dict_t *dict);
int
-cli_xml_output_vol_list (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr);
+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);
+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);
+cli_xml_output_vol_info_end(cli_local_t *local);
int
-cli_xml_output_vol_info (cli_local_t *local, dict_t *dict);
+cli_xml_output_vol_info(cli_local_t *local, dict_t *dict);
int
-cli_xml_output_vol_quota_limit_list_begin (cli_local_t *local, int op_ret,
- int op_errno, char *op_errstr);
+cli_xml_output_vol_quota_limit_list_begin(cli_local_t *local, int op_ret,
+ int op_errno, char *op_errstr);
int
-cli_xml_output_vol_quota_limit_list_end (cli_local_t *local);
+cli_xml_output_vol_quota_limit_list_end(cli_local_t *local);
int
-cli_quota_list_xml_error (cli_local_t *local, char *path,
- char *errstr);
+cli_quota_list_xml_error(cli_local_t *local, char *path, char *errstr);
int
-cli_quota_xml_output (cli_local_t *local, char *path, char *hl_str,
- char *sl_final, void *used, void *avail,
- char *sl, char *hl);
+cli_quota_xml_output(cli_local_t *local, char *path, int64_t hl_str,
+ char *sl_final, int64_t sl_num, int64_t used,
+ int64_t avail, char *sl, char *hl, gf_boolean_t limit_set);
int
-cli_quota_object_xml_output (cli_local_t *local, char *path, char *sl_str,
- quota_limits_t *limits, quota_meta_t *used_space,
- int64_t avail, char *sl, char *hl);
+cli_quota_object_xml_output(cli_local_t *local, char *path, char *sl_str,
+ int64_t sl_val, quota_limits_t *limits,
+ quota_meta_t *used_space, int64_t avail, char *sl,
+ char *hl, gf_boolean_t limit_set);
int
-cli_xml_output_peer_status (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr);
+cli_xml_output_peer_status(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_output_vol_rebalance (gf_cli_defrag_type op, dict_t *dict, int op_ret,
- int op_errno, char *op_errstr);
+cli_xml_output_vol_rebalance(gf_cli_defrag_type op, dict_t *dict, int op_ret,
+ int op_errno, char *op_errstr);
int
-cli_xml_output_vol_remove_brick_detach_tier (gf_boolean_t status_op,
- dict_t *dict, int op_ret,
- int op_errno, char *op_errstr,
- const char *op);
+cli_xml_output_vol_remove_brick(gf_boolean_t status_op, dict_t *dict,
+ int op_ret, int op_errno, char *op_errstr,
+ const char *op);
int
-cli_xml_output_vol_replace_brick (char *op, dict_t *dict, int op_ret,
- int op_errno, char *op_errstr);
+cli_xml_output_vol_replace_brick(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_output_vol_create (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr);
+cli_xml_output_vol_create(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_output_generic_volume (char *op, dict_t *dict, int op_ret, int op_errno,
- char *op_errstr);
+cli_xml_output_generic_volume(char *op, dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_output_vol_gsync (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr);
+cli_xml_output_vol_gsync(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_output_vol_status_tasks_detail (cli_local_t *local, dict_t *dict);
+cli_xml_output_vol_status_tasks_detail(cli_local_t *local, dict_t *dict);
int
-cli_xml_output_common (xmlTextWriterPtr writer, int op_ret, int op_errno,
- char *op_errstr);
-int
-cli_xml_snapshot_delete (xmlTextWriterPtr writer, xmlDocPtr doc, dict_t *dict,
- gf_cli_rsp *rsp);
+cli_xml_snapshot_delete(cli_local_t *local, dict_t *dict, gf_cli_rsp *rsp);
+
int
-cli_xml_snapshot_begin_composite_op (cli_local_t *local);
+cli_xml_snapshot_begin_composite_op(cli_local_t *local);
int
-cli_xml_snapshot_end_composite_op (cli_local_t *local);
+cli_xml_snapshot_end_composite_op(cli_local_t *local);
int
-cli_xml_output_snap_delete_begin (cli_local_t *local, int op_ret, int op_errno,
- char *op_errstr);
+cli_xml_output_snap_delete_begin(cli_local_t *local, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_output_snap_delete_end (cli_local_t *local);
+cli_xml_output_snap_delete_end(cli_local_t *local);
int
-cli_xml_output_snap_status_begin (cli_local_t *local, int op_ret, int op_errno,
- char *op_errstr);
+cli_xml_output_snap_status_begin(cli_local_t *local, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_output_snap_status_end (cli_local_t *local);
+cli_xml_output_snap_status_end(cli_local_t *local);
int
-cli_xml_output_snapshot (int cmd_type, dict_t *dict, int op_ret,
- int op_errno, char *op_errstr);
+cli_xml_output_snapshot(int cmd_type, dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
int
-cli_xml_snapshot_status_single_snap (cli_local_t *local, dict_t *dict,
- char *key);
-char *
-is_server_debug_xlator (void *myframe);
-
+cli_xml_snapshot_status_single_snap(cli_local_t *local, dict_t *dict,
+ char *key);
int32_t
-cli_cmd_snapshot_parse (const char **words, int wordcount, dict_t **options,
- struct cli_state *state);
+cli_cmd_snapshot_parse(const char **words, int wordcount, dict_t **options,
+ struct cli_state *state);
int
-cli_xml_output_vol_getopts (dict_t *dict, int op_ret, int op_errno,
- char *op_errstr);
+cli_xml_output_vol_getopts(dict_t *dict, int op_ret, int op_errno,
+ char *op_errstr);
void
-print_quota_list_header (int type);
+print_quota_list_header(int type);
void
-print_quota_list_empty (char *path, int type);
+print_quota_list_empty(char *path, int type);
int
-gf_gsync_status_t_comparator (const void *p, const void *q);
-
+gf_gsync_status_t_comparator(const void *p, const void *q);
#endif /* __CLI_H__ */
diff --git a/cli/src/input.c b/cli/src/input.c
index 10fc39cd6b4..5ac1a20edb1 100644
--- a/cli/src/input.c
+++ b/cli/src/input.c
@@ -19,74 +19,75 @@
#define CMDBUFSIZ 1024
void *
-cli_batch (void *d)
+cli_batch(void *d)
{
- struct cli_state *state = NULL;
- int ret = 0;
+ struct cli_state *state = NULL;
+ int ret = 0;
- state = d;
+ state = d;
- ret = cli_cmd_process (state, state->argc, state->argv);
+ ret = cli_cmd_process(state, state->argc, state->argv);
- gf_log ("", GF_LOG_INFO, "Exiting with: %d", ret);
- exit (-ret);
+ gf_log("", GF_LOG_INFO, "Exiting with: %d", ret);
+ exit(-ret);
- return NULL;
+ return NULL;
}
-
void *
-cli_input (void *d)
+cli_input(void *d)
{
- struct cli_state *state = NULL;
- int ret = 0;
- char cmdbuf[CMDBUFSIZ];
- char *cmd = NULL;
- size_t len = 0;
-
- state = d;
-
- for (;;) {
- printf ("%s", state->prompt);
-
- cmd = fgets (cmdbuf, CMDBUFSIZ, stdin);
- if (!cmd)
- break;
- len = strlen(cmd);
- if (len > 0 && cmd[len - 1] == '\n') //strip trailing \n
- cmd[len - 1] = '\0';
- ret = cli_cmd_process_line (state, cmd);
- if (ret != 0 && state->mode & GLUSTER_MODE_ERR_FATAL)
- break;
- }
-
- exit (-ret);
-
- return NULL;
+ struct cli_state *state = NULL;
+ int ret = 0;
+ char cmdbuf[CMDBUFSIZ];
+ char *cmd = NULL;
+ size_t len = 0;
+
+ state = d;
+
+ fprintf(stderr,
+ "Welcome to gluster prompt, type 'help' to see the available "
+ "commands.\n");
+ for (;;) {
+ printf("%s", state->prompt);
+
+ cmd = fgets(cmdbuf, CMDBUFSIZ, stdin);
+ if (!cmd)
+ break;
+ len = strlen(cmd);
+ if (len > 0 && cmd[len - 1] == '\n') // strip trailing \n
+ cmd[len - 1] = '\0';
+ ret = cli_cmd_process_line(state, cmd);
+ if (ret != 0 && state->mode & GLUSTER_MODE_ERR_FATAL)
+ break;
+ }
+
+ exit(-ret);
+
+ return NULL;
}
-
int
-cli_input_init (struct cli_state *state)
+cli_input_init(struct cli_state *state)
{
- int ret = 0;
+ int ret = 0;
- if (state->argc) {
- ret = pthread_create (&state->input, NULL, cli_batch, state);
- return ret;
- }
+ if (state->argc) {
+ ret = pthread_create(&state->input, NULL, cli_batch, state);
+ return ret;
+ }
- if (isatty (STDIN_FILENO)) {
- state->prompt = "gluster> ";
+ if (isatty(STDIN_FILENO)) {
+ state->prompt = "gluster> ";
- cli_rl_enable (state);
- } else {
- state->prompt = "";
- state->mode |= GLUSTER_MODE_SCRIPT | GLUSTER_MODE_ERR_FATAL;
- }
+ cli_rl_enable(state);
+ } else {
+ state->prompt = "";
+ state->mode |= GLUSTER_MODE_SCRIPT | GLUSTER_MODE_ERR_FATAL;
+ }
- if (!state->rl_enabled)
- ret = pthread_create (&state->input, NULL, cli_input, state);
+ if (!state->rl_enabled)
+ ret = pthread_create(&state->input, NULL, cli_input, state);
- return ret;
+ return ret;
}
diff --git a/cli/src/registry.c b/cli/src/registry.c
index 1adf7d6e572..85f7686ade1 100644
--- a/cli/src/registry.c
+++ b/cli/src/registry.c
@@ -15,20 +15,18 @@
#include "cli.h"
#include "cli-cmd.h"
-
static int
-__is_spc (int ch)
+__is_spc(int ch)
{
- if (ch == ' ')
- return 1;
- return 0;
+ if (ch == ' ')
+ return 1;
+ return 0;
}
-
static int
-__is_div (int ch)
+__is_div(int ch)
{
- switch (ch) {
+ switch (ch) {
case '(':
case ')':
case '<':
@@ -38,369 +36,356 @@ __is_div (int ch)
case '{':
case '}':
case '|':
- return 1;
- }
+ return 1;
+ }
- return 0;
+ return 0;
}
-
static int
-__is_word (const char *word)
+__is_word(const char *word)
{
- return (!__is_div (*word) && !__is_spc (*word));
+ return (!__is_div(*word) && !__is_spc(*word));
}
-
int
-counter_char (int ch)
+counter_char(int ch)
{
- switch (ch) {
+ switch (ch) {
case '(':
- return ')';
+ return ')';
case '<':
- return '>';
+ return '>';
case '[':
- return ']';
+ return ']';
case '{':
- return '}';
- }
+ return '}';
+ }
- return -1;
+ return -1;
}
-
const char *
-__is_template_balanced (const char *template)
+__is_template_balanced(const char *template)
{
- const char *trav = NULL;
- int ch = 0;
-
- trav = template;
-
- while (*trav) {
- ch = *trav;
-
- switch (ch) {
- case '<':
- case '(':
- case '[':
- trav = __is_template_balanced (trav+1);
- if (!trav)
- return NULL;
- if (*trav != counter_char (ch))
- return NULL;
- break;
- case '>':
- case ')':
- case ']':
- return trav;
- }
+ const char *trav = NULL;
+ int ch = 0;
- trav++;
+ trav = template;
+
+ while (*trav) {
+ ch = *trav;
+
+ switch (ch) {
+ case '<':
+ case '(':
+ case '[':
+ trav = __is_template_balanced(trav + 1);
+ if (!trav)
+ return NULL;
+ if (*trav != counter_char(ch))
+ return NULL;
+ break;
+ case '>':
+ case ')':
+ case ']':
+ return trav;
}
- return trav;
-}
+ trav++;
+ }
+ return trav;
+}
int
-is_template_balanced (const char *template)
+is_template_balanced(const char *template)
{
- const char *trav = NULL;
+ const char *trav = NULL;
- trav = __is_template_balanced (template);
- if (!trav || *trav)
- return -1;
+ trav = __is_template_balanced(template);
+ if (!trav || *trav)
+ return -1;
- return 0;
+ return 0;
}
-
int
-cli_cmd_token_count (const char *template)
+cli_cmd_token_count(const char *template)
{
- int count = 0;
- const char *trav = NULL;
- int is_alnum = 0;
-
- for (trav = template; *trav; trav++) {
- switch (*trav) {
- case '<':
- case '>':
- case '(':
- case ')':
- case '[':
- case ']':
- case '{':
- case '}':
- case '|':
- count++;
- /* fall through */
- case ' ':
- is_alnum = 0;
- break;
- default:
- if (!is_alnum) {
- is_alnum = 1;
- count++;
- }
+ int count = 0;
+ const char *trav = NULL;
+ int is_alnum = 0;
+
+ for (trav = template; *trav; trav++) {
+ switch (*trav) {
+ case '<':
+ case '>':
+ case '(':
+ case ')':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ case '|':
+ count++;
+ /* fall through */
+ case ' ':
+ is_alnum = 0;
+ break;
+ default:
+ if (!is_alnum) {
+ is_alnum = 1;
+ count++;
}
}
+ }
- return count + 1;
+ return count + 1;
}
-
void
-cli_cmd_tokens_destroy (char **tokens)
+cli_cmd_tokens_destroy(char **tokens)
{
- char **tokenp = NULL;
+ char **tokenp = NULL;
- if (!tokens)
- return;
+ if (!tokens)
+ return;
- tokenp = tokens;
- while (*tokenp) {
- free (*tokenp);
- tokenp++;
- }
+ tokenp = tokens;
+ while (*tokenp) {
+ free(*tokenp);
+ tokenp++;
+ }
- free (tokens);
+ free(tokens);
}
-
int
-cli_cmd_tokens_fill (char **tokens, const char *template)
+cli_cmd_tokens_fill(char **tokens, const char *template)
{
- const char *trav = NULL;
- char **tokenp = NULL;
- char *token = NULL;
- int ret = 0;
- int ch = 0;
+ const char *trav = NULL;
+ char **tokenp = NULL;
+ char *token = NULL;
+ int ret = 0;
+ int ch = 0;
- tokenp = tokens;
+ tokenp = tokens;
- for (trav = template; *trav; trav++) {
- ch = *trav;
+ for (trav = template; *trav; trav++) {
+ ch = *trav;
- if (__is_spc (ch))
- continue;
+ if (__is_spc(ch))
+ continue;
- if (__is_div (ch)) {
- token = calloc (2, 1);
- if (!token)
- return -1;
- token[0] = ch;
+ if (__is_div(ch)) {
+ token = calloc(2, 1);
+ if (!token)
+ return -1;
+ token[0] = ch;
- *tokenp = token;
- tokenp++;
+ *tokenp = token;
+ tokenp++;
- continue;
- }
+ continue;
+ }
- token = strdup (trav);
- *tokenp = token;
- tokenp++;
+ token = strdup(trav);
+ *tokenp = token;
+ tokenp++;
- for (token++; *token; token++) {
- if (__is_spc (*token) || __is_div (*token)) {
- *token = 0;
- break;
- }
- trav++;
- }
+ for (token++; *token; token++) {
+ if (__is_spc(*token) || __is_div(*token)) {
+ *token = 0;
+ break;
+ }
+ trav++;
}
+ }
- return ret;
+ return ret;
}
-
char **
-cli_cmd_tokenize (const char *template)
+cli_cmd_tokenize(const char *template)
{
- char **tokens = NULL;
- int ret = 0;
- int count = 0;
+ char **tokens = NULL;
+ int ret = 0;
+ int count = 0;
- ret = is_template_balanced (template);
- if (ret)
- return NULL;
+ ret = is_template_balanced(template);
+ if (ret)
+ return NULL;
- count = cli_cmd_token_count (template);
- if (count <= 0)
- return NULL;
+ count = cli_cmd_token_count(template);
+ if (count <= 0)
+ return NULL;
- tokens = calloc (count + 1, sizeof (char *));
- if (!tokens)
- return NULL;
+ tokens = calloc(count + 1, sizeof(char *));
+ if (!tokens)
+ return NULL;
- ret = cli_cmd_tokens_fill (tokens, template);
- if (ret)
- goto err;
+ ret = cli_cmd_tokens_fill(tokens, template);
+ if (ret)
+ goto err;
- return tokens;
+ return tokens;
err:
- cli_cmd_tokens_destroy (tokens);
- return NULL;
+ cli_cmd_tokens_destroy(tokens);
+ return NULL;
}
void *
-cli_getunamb (const char *tok, void **choices, cli_selector_t sel)
+cli_getunamb(const char *tok, void **choices, cli_selector_t sel)
{
- void **wcon = NULL;
- char *w = NULL;
- unsigned mn = 0;
- void *ret = NULL;
-
- if (!choices || !tok || !*tok)
- return NULL;
-
- for (wcon = choices; *wcon; wcon++) {
- w = strtail ((char *)sel (*wcon), tok);
- if (!w)
- /* no match */
- continue;
- if (!*w)
- /* exact match */
- return *wcon;
-
- ret = *wcon;
- mn++;
- }
+ void **wcon = NULL;
+ char *w = NULL;
+ unsigned mn = 0;
+ void *ret = NULL;
-#ifdef FORCE_MATCH_EXACT
+ if (!choices || !tok || !*tok)
return NULL;
+
+ for (wcon = choices; *wcon; wcon++) {
+ w = strtail((char *)sel(*wcon), tok);
+ if (!w)
+ /* no match */
+ continue;
+ if (!*w)
+ /* exact match */
+ return *wcon;
+
+ ret = *wcon;
+ mn++;
+ }
+
+#ifdef FORCE_MATCH_EXACT
+ return NULL;
#else
- return (mn == 1) ? ret : NULL;
+ return (mn == 1) ? ret : NULL;
#endif
}
static const char *
-sel_cmd_word (void *wcon)
+sel_cmd_word(void *wcon)
{
- return ((struct cli_cmd_word *)wcon)->word;
+ return ((struct cli_cmd_word *)wcon)->word;
}
struct cli_cmd_word *
-cli_cmd_nextword (struct cli_cmd_word *word, const char *token)
+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);
+ return (struct cli_cmd_word *)cli_getunamb(token, (void **)word->nextwords,
+ sel_cmd_word);
}
-
struct cli_cmd_word *
-cli_cmd_newword (struct cli_cmd_word *word, const char *token)
+cli_cmd_newword(struct cli_cmd_word *word, const char *token)
{
- struct cli_cmd_word **nextwords = NULL;
- struct cli_cmd_word *nextword = NULL;
+ struct cli_cmd_word **nextwords = NULL;
+ struct cli_cmd_word *nextword = NULL;
- nextwords = realloc (word->nextwords,
- (word->nextwords_cnt + 2) * sizeof (*nextwords));
- if (!nextwords)
- return NULL;
+ nextwords = realloc(word->nextwords,
+ (word->nextwords_cnt + 2) * sizeof(*nextwords));
+ if (!nextwords)
+ return NULL;
- word->nextwords = nextwords;
+ word->nextwords = nextwords;
- nextword = calloc (1, sizeof (*nextword));
- if (!nextword)
- return NULL;
+ nextword = calloc(1, sizeof(*nextword));
+ if (!nextword)
+ return NULL;
- nextword->word = strdup (token);
- if (!nextword->word) {
- free (nextword);
- return NULL;
- }
+ nextword->word = strdup(token);
+ if (!nextword->word) {
+ free(nextword);
+ return NULL;
+ }
- nextword->tree = word->tree;
- nextwords[word->nextwords_cnt++] = nextword;
- nextwords[word->nextwords_cnt] = NULL;
+ nextword->tree = word->tree;
+ nextwords[word->nextwords_cnt++] = nextword;
+ nextwords[word->nextwords_cnt] = NULL;
- return nextword;
+ return nextword;
}
-
int
-cli_cmd_ingest (struct cli_cmd_tree *tree, char **tokens, cli_cmd_cbk_t *cbkfn,
- const char *desc, const char *pattern)
+cli_cmd_ingest(struct cli_cmd_tree *tree, char **tokens, cli_cmd_cbk_t *cbkfn,
+ const char *desc, const char *pattern)
{
- int ret = 0;
- char **tokenp = NULL;
- char *token = NULL;
- struct cli_cmd_word *word = NULL;
- struct cli_cmd_word *next = NULL;
-
- word = &tree->root;
+ int ret = 0;
+ char **tokenp = NULL;
+ char *token = NULL;
+ struct cli_cmd_word *word = NULL;
+ struct cli_cmd_word *next = NULL;
- for (tokenp = tokens; (token = *tokenp); tokenp++) {
- if (!__is_word (token))
- break;
+ word = &tree->root;
- next = cli_cmd_nextword (word, token);
- if (!next)
- next = cli_cmd_newword (word, token);
+ for (tokenp = tokens; (token = *tokenp); tokenp++) {
+ if (!__is_word(token))
+ break;
- word = next;
- if (!word)
- break;
- }
+ next = cli_cmd_nextword(word, token);
+ if (!next)
+ next = cli_cmd_newword(word, token);
+ word = next;
if (!word)
- return -1;
+ break;
+ }
- if (word->cbkfn) {
- /* warning - command already registered */
- }
+ if (!word)
+ return -1;
- word->cbkfn = cbkfn;
- word->desc = desc;
- word->pattern = pattern;
+ if (word->cbkfn) {
+ /* warning - command already registered */
+ }
- /* end of static strings in command template */
+ word->cbkfn = cbkfn;
+ word->desc = desc;
+ word->pattern = pattern;
- /* TODO: autocompletion beyond this point is just "nice to have" */
+ /* end of static strings in command template */
- return ret;
-}
+ /* TODO: autocompletion beyond this point is just "nice to have" */
+ return ret;
+}
int
-cli_cmd_register (struct cli_cmd_tree *tree, struct cli_cmd *cmd)
+cli_cmd_register(struct cli_cmd_tree *tree, struct cli_cmd *cmd)
{
- char **tokens = NULL;
- int ret = 0;
+ char **tokens = NULL;
+ int ret = 0;
- GF_ASSERT (cmd);
+ GF_ASSERT(cmd);
- if (cmd->reg_cbk)
- cmd->reg_cbk (cmd);
+ if (cmd->reg_cbk)
+ cmd->reg_cbk(cmd);
- if (cmd->disable) {
- ret = 0;
- goto out;
- }
+ if (cmd->disable) {
+ ret = 0;
+ goto out;
+ }
- tokens = cli_cmd_tokenize (cmd->pattern);
- if (!tokens) {
- ret = -1;
- goto out;
- }
+ tokens = cli_cmd_tokenize(cmd->pattern);
+ if (!tokens) {
+ ret = -1;
+ goto out;
+ }
- ret = cli_cmd_ingest (tree, tokens, cmd->cbk, cmd->desc, cmd->pattern);
- if (ret) {
- ret = -1;
- goto out;
- }
+ ret = cli_cmd_ingest(tree, tokens, cmd->cbk, cmd->desc, cmd->pattern);
+ if (ret) {
+ ret = -1;
+ goto out;
+ }
- ret = 0;
+ ret = 0;
out:
- if (tokens)
- cli_cmd_tokens_destroy (tokens);
+ if (tokens)
+ cli_cmd_tokens_destroy(tokens);
- gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
-
diff --git a/configure.ac b/configure.ac
index 3245d1fa20c..e2d6fd66cec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-dnl Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
+dnl Copyright (c) 2006-2016 Red Hat, Inc. <http://www.redhat.com>
dnl This file is part of GlusterFS.
dnl
dnl This file is licensed to you under your choice of the GNU Lesser
@@ -13,7 +13,7 @@ AC_INIT([glusterfs],
AC_SUBST([PACKAGE_RELEASE],
[m4_esyscmd([build-aux/pkg-version --release])])
-AM_INIT_AUTOMAKE(tar-pax)
+AM_INIT_AUTOMAKE([tar-pax foreign])
# Removes warnings when using automake 1.14 around (...but option 'subdir-objects' is disabled )
#but libglusterfs fails to build with contrib (Then are not set up that way?)
@@ -21,28 +21,21 @@ AM_INIT_AUTOMAKE(tar-pax)
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
-
-AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_HEADERS([config.h site.h])
AC_CONFIG_FILES([Makefile
libglusterfs/Makefile
libglusterfs/src/Makefile
- libglusterfs/src/gfdb/Makefile
+ libglusterd/Makefile
+ libglusterd/src/Makefile
geo-replication/src/peer_gsec_create
geo-replication/src/peer_mountbroker
+ geo-replication/src/peer_mountbroker.py
+ geo-replication/src/peer_georep-sshkey.py
extras/peer_add_secret_pub
- geo-replication/syncdaemon/configinterface.py
+ geo-replication/syncdaemon/conf.py
+ geo-replication/gsyncd.conf
+ extras/snap_scheduler/conf.py
glusterfsd/Makefile
glusterfsd/src/Makefile
rpc/Makefile
@@ -51,8 +44,6 @@ AC_CONFIG_FILES([Makefile
rpc/rpc-transport/Makefile
rpc/rpc-transport/socket/Makefile
rpc/rpc-transport/socket/src/Makefile
- rpc/rpc-transport/rdma/Makefile
- rpc/rpc-transport/rdma/src/Makefile
rpc/xdr/Makefile
rpc/xdr/src/Makefile
xlators/Makefile
@@ -67,13 +58,9 @@ AC_CONFIG_FILES([Makefile
xlators/storage/Makefile
xlators/storage/posix/Makefile
xlators/storage/posix/src/Makefile
- xlators/storage/bd/Makefile
- xlators/storage/bd/src/Makefile
xlators/cluster/Makefile
xlators/cluster/afr/Makefile
xlators/cluster/afr/src/Makefile
- xlators/cluster/stripe/Makefile
- xlators/cluster/stripe/src/Makefile
xlators/cluster/dht/Makefile
xlators/cluster/dht/src/Makefile
xlators/cluster/ec/Makefile
@@ -89,19 +76,23 @@ AC_CONFIG_FILES([Makefile
xlators/performance/io-threads/src/Makefile
xlators/performance/io-cache/Makefile
xlators/performance/io-cache/src/Makefile
- xlators/performance/symlink-cache/Makefile
- xlators/performance/symlink-cache/src/Makefile
xlators/performance/quick-read/Makefile
xlators/performance/quick-read/src/Makefile
xlators/performance/open-behind/Makefile
xlators/performance/open-behind/src/Makefile
xlators/performance/md-cache/Makefile
xlators/performance/md-cache/src/Makefile
+ xlators/performance/nl-cache/Makefile
+ xlators/performance/nl-cache/src/Makefile
xlators/debug/Makefile
+ xlators/debug/sink/Makefile
+ xlators/debug/sink/src/Makefile
xlators/debug/trace/Makefile
xlators/debug/trace/src/Makefile
xlators/debug/error-gen/Makefile
xlators/debug/error-gen/src/Makefile
+ xlators/debug/delay-gen/Makefile
+ xlators/debug/delay-gen/src/Makefile
xlators/debug/io-stats/Makefile
xlators/debug/io-stats/src/Makefile
xlators/protocol/Makefile
@@ -117,40 +108,34 @@ AC_CONFIG_FILES([Makefile
xlators/features/Makefile
xlators/features/arbiter/Makefile
xlators/features/arbiter/src/Makefile
+ xlators/features/thin-arbiter/Makefile
+ xlators/features/thin-arbiter/src/Makefile
xlators/features/changelog/Makefile
xlators/features/changelog/src/Makefile
xlators/features/changelog/lib/Makefile
xlators/features/changelog/lib/src/Makefile
- xlators/features/changetimerecorder/Makefile
- xlators/features/changetimerecorder/src/Makefile
- xlators/features/glupy/Makefile
- xlators/features/glupy/examples/Makefile
- xlators/features/glupy/src/Makefile
- xlators/features/glupy/src/setup.py
- xlators/features/glupy/src/__init__.py
- xlators/features/glupy/src/glupy/Makefile
xlators/features/locks/Makefile
xlators/features/locks/src/Makefile
xlators/features/quota/Makefile
xlators/features/quota/src/Makefile
xlators/features/marker/Makefile
xlators/features/marker/src/Makefile
+ xlators/features/selinux/Makefile
+ xlators/features/selinux/src/Makefile
+ xlators/features/sdfs/Makefile
+ xlators/features/sdfs/src/Makefile
xlators/features/read-only/Makefile
xlators/features/read-only/src/Makefile
xlators/features/compress/Makefile
xlators/features/compress/src/Makefile
- xlators/features/mac-compat/Makefile
- xlators/features/mac-compat/src/Makefile
+ xlators/features/namespace/Makefile
+ xlators/features/namespace/src/Makefile
xlators/features/quiesce/Makefile
xlators/features/quiesce/src/Makefile
xlators/features/barrier/Makefile
xlators/features/barrier/src/Makefile
- xlators/features/ganesha/Makefile
- xlators/features/ganesha/src/Makefile
xlators/features/index/Makefile
xlators/features/index/src/Makefile
- xlators/features/protect/Makefile
- xlators/features/protect/src/Makefile
xlators/features/gfid-access/Makefile
xlators/features/gfid-access/src/Makefile
xlators/features/trash/Makefile
@@ -167,16 +152,23 @@ AC_CONFIG_FILES([Makefile
xlators/features/bit-rot/src/Makefile
xlators/features/bit-rot/src/stub/Makefile
xlators/features/bit-rot/src/bitd/Makefile
+ xlators/features/leases/Makefile
+ xlators/features/leases/src/Makefile
+ xlators/features/cloudsync/Makefile
+ xlators/features/cloudsync/src/Makefile
+ xlators/features/utime/Makefile
+ xlators/features/utime/src/Makefile
+ xlators/features/cloudsync/src/cloudsync-plugins/Makefile
+ xlators/features/cloudsync/src/cloudsync-plugins/src/Makefile
+ xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/Makefile
+ xlators/features/cloudsync/src/cloudsync-plugins/src/cloudsyncs3/src/Makefile
+ xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/Makefile
+ xlators/features/cloudsync/src/cloudsync-plugins/src/cvlt/src/Makefile
+ xlators/features/metadisp/Makefile
+ xlators/features/metadisp/src/Makefile
xlators/playground/Makefile
xlators/playground/template/Makefile
xlators/playground/template/src/Makefile
- xlators/encryption/Makefile
- xlators/encryption/rot-13/Makefile
- xlators/encryption/rot-13/src/Makefile
- xlators/encryption/crypt/Makefile
- xlators/encryption/crypt/src/Makefile
- xlators/features/qemu-block/Makefile
- xlators/features/qemu-block/src/Makefile
xlators/system/Makefile
xlators/system/posix-acl/Makefile
xlators/system/posix-acl/src/Makefile
@@ -191,18 +183,25 @@ AC_CONFIG_FILES([Makefile
doc/Makefile
extras/Makefile
extras/glusterd.vol
+ extras/cliutils/Makefile
extras/init.d/Makefile
extras/init.d/glusterd.plist
extras/init.d/glusterd-Debian
extras/init.d/glusterd-Redhat
extras/init.d/glusterd-FreeBSD
extras/init.d/glusterd-SuSE
+ extras/init.d/glustereventsd-Debian
+ extras/init.d/glustereventsd-Redhat
+ extras/init.d/glustereventsd-FreeBSD
extras/ganesha/Makefile
extras/ganesha/config/Makefile
extras/ganesha/scripts/Makefile
extras/ganesha/ocf/Makefile
extras/systemd/Makefile
extras/systemd/glusterd.service
+ extras/systemd/glustereventsd.service
+ extras/systemd/glusterfssharedstorage.service
+ extras/systemd/gluster-ta-volume.service
extras/run-gluster.tmpfiles
extras/benchmarking/Makefile
extras/hook-scripts/Makefile
@@ -211,10 +210,15 @@ AC_CONFIG_FILES([Makefile
extras/ocf/volume
extras/LinuxRPM/Makefile
extras/geo-rep/Makefile
+ extras/geo-rep/schedule_georep.py
extras/firewalld/Makefile
extras/hook-scripts/add-brick/Makefile
extras/hook-scripts/add-brick/pre/Makefile
extras/hook-scripts/add-brick/post/Makefile
+ extras/hook-scripts/create/Makefile
+ extras/hook-scripts/create/post/Makefile
+ extras/hook-scripts/delete/Makefile
+ extras/hook-scripts/delete/pre/Makefile
extras/hook-scripts/start/Makefile
extras/hook-scripts/start/post/Makefile
extras/hook-scripts/set/Makefile
@@ -224,13 +228,16 @@ AC_CONFIG_FILES([Makefile
extras/hook-scripts/reset/Makefile
extras/hook-scripts/reset/post/Makefile
extras/hook-scripts/reset/pre/Makefile
+ extras/python/Makefile
extras/snap_scheduler/Makefile
+ events/Makefile
+ events/src/Makefile
+ events/src/eventsapiconf.py
+ events/tools/Makefile
contrib/fuse-util/Makefile
contrib/umountd/Makefile
- contrib/uuid/uuid_types.h
glusterfs-api.pc
libgfchangelog.pc
- libgfdb.pc
api/Makefile
api/src/Makefile
api/examples/Makefile
@@ -242,10 +249,12 @@ AC_CONFIG_FILES([Makefile
heal/Makefile
heal/src/Makefile
glusterfs.spec
- tools/glusterfind/src/tool.conf
- tools/glusterfind/glusterfind
- tools/glusterfind/Makefile
- tools/glusterfind/src/Makefile])
+ tools/glusterfind/src/tool.conf
+ tools/glusterfind/glusterfind
+ tools/glusterfind/Makefile
+ tools/glusterfind/src/Makefile
+ tools/setgfid2path/Makefile
+ tools/setgfid2path/src/Makefile])
AC_CANONICAL_HOST
@@ -266,10 +275,124 @@ AC_ARG_ENABLE([debug],
[Enable debug build options.]))
if test "x$enable_debug" = "xyes"; then
BUILD_DEBUG=yes
- CFLAGS="${CFLAGS} -g -O0 -DDEBUG"
+ GF_CFLAGS="${GF_CFLAGS} -g -O0 -DDEBUG"
else
BUILD_DEBUG=no
- CFLAGS="${CFLAGS} -g -O2"
+fi
+
+SANITIZER=none
+
+AC_ARG_ENABLE([asan],
+ AC_HELP_STRING([--enable-asan],
+ [Enable Address Sanitizer support]))
+if test "x$enable_asan" = "xyes"; then
+ SANITIZER=asan
+ AC_CHECK_LIB([asan], [__asan_init], ,
+ [AC_MSG_ERROR([--enable-asan requires libasan.so, exiting])])
+ GF_CFLAGS="${GF_CFLAGS} -O2 -g -fsanitize=address -fno-omit-frame-pointer"
+ GF_LDFLAGS="${GF_LDFLAGS} -lasan"
+fi
+
+AC_ARG_ENABLE([tsan],
+ AC_HELP_STRING([--enable-tsan],
+ [Enable Thread Sanitizer support]))
+if test "x$enable_tsan" = "xyes"; then
+ if test "x$SANITIZER" != "xnone"; then
+ AC_MSG_ERROR([only one sanitizer can be enabled at once])
+ fi
+ SANITIZER=tsan
+ AC_CHECK_LIB([tsan], [__tsan_init], ,
+ [AC_MSG_ERROR([--enable-tsan requires libtsan.so, exiting])])
+ if test "x$ac_cv_lib_tsan___tsan_init" = xyes; then
+ AC_MSG_CHECKING([whether tsan API can be used])
+ saved_CFLAGS=${CFLAGS}
+ CFLAGS="${CFLAGS} -fsanitize=thread"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([
+ [#include <sanitizer/tsan_interface.h>]],
+ [[__tsan_create_fiber(0)]])],
+ [TSAN_API=yes], [TSAN_API=no])
+ AC_MSG_RESULT([$TSAN_API])
+ if test x$TSAN_API = "xyes"; then
+ AC_DEFINE(HAVE_TSAN_API, 1, [Define if tsan API can be used.])
+ fi
+ CFLAGS=${saved_CFLAGS}
+ fi
+ GF_CFLAGS="${GF_CFLAGS} -O2 -g -fsanitize=thread -fno-omit-frame-pointer"
+ GF_LDFLAGS="${GF_LDFLAGS} -ltsan"
+fi
+
+AC_ARG_ENABLE([ubsan],
+ AC_HELP_STRING([--enable-ubsan],
+ [Enable Undefined Behavior Sanitizer support]))
+if test "x$enable_ubsan" = "xyes"; then
+ if test "x$SANITIZER" != "xnone"; then
+ AC_MSG_ERROR([only one sanitizer can be enabled at once])
+ fi
+ SANITIZER=ubsan
+ AC_CHECK_LIB([ubsan], [__ubsan_default_options], ,
+ [AC_MSG_ERROR([--enable-ubsan requires libubsan.so, exiting])])
+ GF_CFLAGS="${GF_CFLAGS} -O2 -g -fsanitize=undefined -fno-omit-frame-pointer"
+ GF_LDFLAGS="${GF_LDFLAGS} -lubsan"
+fi
+
+# Initialize CFLAGS before usage
+BUILD_TCMALLOC=no
+AC_ARG_ENABLE([tcmalloc],
+ AC_HELP_STRING([--enable-tcmalloc],
+ [Enable linking with tcmalloc library.]))
+if test "x$enable_tcmalloc" = "xyes"; then
+ BUILD_TCMALLOC=yes
+ GF_CFLAGS="${GF_CFLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free"
+ AC_CHECK_LIB([tcmalloc], [malloc], [],
+ [AC_MSG_ERROR([when --enable-tcmalloc is used, tcmalloc library needs to be present])])
+ GF_LDFLAGS="-ltcmalloc ${GF_LDFLAGS}"
+fi
+
+
+dnl When possible, prefer libtirpc over glibc rpc.
+dnl
+dnl On newer linux with only libtirpc, use libtirpc. (Specifying
+dnl --without-libtirpc is an error.)
+dnl
+dnl on older linux with glibc rpc and WITH libtirpc, use libtirpc
+dnl by default except when configured with --without-libtirpc.
+dnl
+dnl on old linux with glibc rpc and WITHOUT libtirpc, default to
+dnl use glibc rpc.
+dnl
+AC_ARG_WITH([libtirpc],
+ [AC_HELP_STRING([--without-libtirpc], [Use legacy glibc RPC.])],
+ [with_libtirpc="no"], [with_libtirpc="yes"])
+
+dnl ipv6-default is off by default
+dnl
+dnl ipv6-default requires libtirpc. (glibc rpc does not support IPv6.)
+dnl ipv6-default can only be enabled if libtipc is enabled.
+dnl
+AC_ARG_WITH([ipv6-default],
+ AC_HELP_STRING([--with-ipv6-default], [Set IPv6 as default.]),
+ [with_ipv6_default=${with_libtirpc}], [with_ipv6_default="no"])
+
+AC_CHECK_FILE([/etc/centos-release])
+if test "x$ac_cv_file__etc_centos_release" = "xyes"; then
+ if grep "release 6" /etc/centos-release; then
+ with_ipv6_default="no"
+ fi
+fi
+
+dnl On some distributions '-ldl' isn't automatically added to LIBS
+AC_CHECK_LIB([dl], [dlopen], [LIB_DL=-ldl])
+AC_SUBST(LIB_DL)
+
+AC_ARG_ENABLE([privport_tracking],
+ AC_HELP_STRING([--disable-privport_tracking],
+ [Disable internal tracking of privileged ports.]))
+TRACK_PRIVPORTS="yes"
+if test x"$enable_privport_tracking" = x"no"; then
+ TRACK_PRIVPORTS="no"
+ AC_DEFINE(GF_DISABLE_PRIVPORT_TRACKING, 1,
+ [Disable internal tracking of privileged ports.])
fi
case $host_os in
@@ -279,18 +402,42 @@ case $host_os in
fi
# OSX version lesser than 9 has llvm/clang optimization issues which leads to various segfaults
if test "`/usr/bin/sw_vers | grep ProductVersion: | cut -f 2 | cut -d. -f2`" -lt 9; then
- CFLAGS="${CFLAGS} -g -O0 -DDEBUG"
+ GF_CFLAGS="${GF_CFLAGS} -g -O0 -DDEBUG"
fi
;;
esac
+# --enable-valgrind prevents calling dlclose(), this leaks memory
+AC_ARG_ENABLE([valgrind],
+ AC_HELP_STRING([--enable-valgrind@<:@=memcheck,drd@:>@],
+ [Enable valgrind for resource leak (memcheck, which is
+ the default) or thread synchronization (drd) debugging.]))
+case x$enable_valgrind in
+ xmemcheck|xyes)
+ AC_DEFINE(RUN_WITH_MEMCHECK, 1,
+ [Define if all processes should run under 'valgrind --tool=memcheck'.])
+ VALGRIND_TOOL=memcheck
+ ;;
+ xdrd)
+ AC_DEFINE(RUN_WITH_DRD, 1,
+ [Define if all processes should run under 'valgrind --tool=drd'.])
+ VALGRIND_TOOL=drd
+ ;;
+ x|xno)
+ VALGRIND_TOOL=no
+ ;;
+ *)
+ AC_MSG_ERROR([Please specify --enable-valgrind@<:@=memcheck,drd@:>@])
+ ;;
+esac
+
AC_ARG_WITH([previous-options],
[AS_HELP_STRING([--with-previous-options],
[read config.status for configure options])
],
[ if test -r ./config.status && \
args=$(grep 'ac_cs_config=' config.status | \
- sed -e 's/.*"\(.*\)".*/\1/'| sed -e "s/'//g") ; then
+ sed -e 's/.*"\(.*\)".*/\1/' -e "s/'//g" -e "s/--with-previous-options//g") ; then
echo "###"
echo "### Rerunning as '$0 $args'"
echo "###"
@@ -311,10 +458,11 @@ AC_ARG_WITH(mountutildir,
AC_SUBST(mountutildir)
AC_ARG_WITH(systemddir,
- [ --with-systemddir=DIR systemd service files in DIR @<:@/usr/lib/systemd/system@:>@],
+ [ --with-systemddir=DIR systemd service files in DIR @<:@PREFIX/lib/systemd/system@:>@],
[systemddir=$withval],
- [systemddir='/usr/lib/systemd/system'])
+ [systemddir='${prefix}/lib/systemd/system'])
AC_SUBST(systemddir)
+AM_CONDITIONAL([USE_SYSTEMD], test [ -d '/usr/lib/systemd/system' ])
AC_ARG_WITH(initdir,
[ --with-initdir=DIR init.d scripts in DIR @<:@/etc/init.d@:>@],
@@ -342,6 +490,13 @@ AC_ARG_WITH([ocf],
)
AC_SUBST(OCF_SUBDIR)
+AC_ARG_WITH([server],
+ [AS_HELP_STRING([--without-server], [do not build server components])],
+ [with_server='no'],
+ [with_server='yes'],
+ )
+AM_CONDITIONAL([WITH_SERVER], [test x$with_server = xyes])
+
# LEX needs a check
AC_PROG_LEX
if test "x${LEX}" != "xflex" -a "x${FLEX}" != "xlex"; then
@@ -388,30 +543,54 @@ AC_CHECK_HEADERS([sys/ioctl.h], AC_DEFINE(HAVE_IOCTL_IN_SYS_IOCTL_H, 1, [have sy
AC_CHECK_HEADERS([sys/extattr.h])
+AC_CHECK_HEADERS([openssl/dh.h])
+
+AC_CHECK_HEADERS([openssl/ecdh.h])
+
+AC_CHECK_LIB([ssl], [SSL_CTX_get0_param], [AC_DEFINE([HAVE_SSL_CTX_GET0_PARAM], [1], [define if found OpenSSL SSL_CTX_get0_param])])
+
dnl Math library
AC_CHECK_LIB([m], [pow], [MATH_LIB='-lm'], [MATH_LIB=''])
AC_SUBST(MATH_LIB)
-dnl use libuuid.so or fall-back to contrib/uuid
+dnl depend on libuuid.so
PKG_CHECK_MODULES([UUID], [uuid],
- [HAVE_LIBUUID=yes
+ [have_uuid=yes
AC_DEFINE(HAVE_LIBUUID, 1, [have libuuid.so])
PKGCONFIG_UUID=uuid],
- [HAVE_LIBUUID=no
- UUID_CFLAGS='-I$(CONTRIBDIR)/uuid'])
-AM_CONDITIONAL([HAVE_LIBUUID], [test x$HAVE_LIBUUID = xyes])
+ [have_uuid=no])
+AM_CONDITIONAL([HAVE_LIBUUID], [test x$have_uuid = xyes])
dnl older version of libuuid (from e2fsprogs) require including uuid/uuid.h
saved_CFLAGS=${CFLAGS}
CFLAGS="${CFLAGS} ${UUID_CFLAGS}"
-AC_CHECK_HEADER([uuid.h], [], [AC_CHECK_HEADER([uuid/uuid.h])])
+AC_CHECK_HEADER([uuid.h], [], [AC_CHECK_HEADER([uuid/uuid.h])],
+ [[#if HAVE_UUID_H
+ #include <uuid.h>
+ #endif
+ ]])
CFLAGS=${saved_CFLAGS}
if test "x$ac_cv_header_uuid_uuid_h" = "xyes"; then
UUID_CFLAGS="${UUID_CFLAGS} -I$(pkg-config --variable=includedir uuid)/uuid"
+ have_uuid=yes
+fi
+
+if test "x$have_uuid" != "xyes"; then
+ case $host_os in
+ *freebsd*)
+ AC_MSG_ERROR([e2fsprogs-libuuid is required to build glusterfs])
+ ;;
+ linux*)
+ AC_MSG_ERROR([libuuid is required to build glusterfs])
+ ;;
+ *)
+ AC_MSG_ERROR([a Linux compatible libuuid is required to build glusterfs])
+ ;;
+ esac
fi
dnl libglusterfs needs uuid.h, practically everything depends on it
-GF_CPPFLAGS="${GF_CPPFLAGS} ${UUID_CFLAGS}"
+GF_CFLAGS="${GF_CFLAGS} ${UUID_CFLAGS}"
dnl PKGCONFIG_UUID is used for the dependency in *.pc.in files
AC_SUBST(PKGCONFIG_UUID)
@@ -457,6 +636,8 @@ AC_SUBST(ZLIB_LIBS)
AC_CHECK_HEADERS([linux/falloc.h])
+AC_CHECK_HEADERS([linux/oom.h], AC_DEFINE(HAVE_LINUX_OOM_H, 1, [have linux/oom.h]))
+
dnl Mac OS X does not have spinlocks
AC_CHECK_FUNC([pthread_spin_init], [have_spinlock=yes])
if test "x${have_spinlock}" = "xyes"; then
@@ -486,6 +667,57 @@ if test "x${have_umount2}" = "xyes"; then
AC_DEFINE(HAVE_UMOUNT2, 1, [define if found umount2])
fi
+dnl Check Python Availability
+have_python=no
+dnl if the user has not specified a python, pick one
+if test -z "${PYTHON}"; then
+ case $host_os in
+ freebsd*)
+ if test -x /usr/local/bin/python3; then
+ PYTHON=/usr/local/bin/python3
+ else
+ PYTHON=/usr/local/bin/python2
+ fi
+ ;;
+ *)
+ if test -x /usr/bin/python3; then
+ PYTHON=/usr/bin/python3
+ else
+ PYTHON=/usr/bin/python2
+ fi
+ ;;
+ esac
+fi
+AM_PATH_PYTHON([2.6],,[:])
+if test -n "${PYTHON}"; then
+ have_python=yes
+fi
+AM_CONDITIONAL(HAVE_PYTHON, test "x$have_python" = "xyes")
+
+dnl Use pkg-config to get runtime search path missing from ${PYTHON}-config
+dnl Just do "true" on failure so that configure does not bail out
+dnl Note: python 2.6's devel pkg (e.g. in CentOS/RHEL 6) does not have
+dnl pkg-config files, so this work-around instead
+if test "x${PYTHON_VERSION}" = "x2.6"; then
+ PYTHON_CFLAGS=$(python-config --includes)
+ PYTHON_LIBS=$(python-config --libs)
+else
+ PKG_CHECK_MODULES([PYTHON], "python-${PYTHON_VERSION}",,true)
+fi
+
+PYTHON_CFLAGS=$(echo ${PYTHON_CFLAGS} | sed -e 's|-I|-isystem |')
+
+BUILD_PYTHON_SITE_PACKAGES=${pythondir}
+AC_SUBST(BUILD_PYTHON_SITE_PACKAGES)
+
+# Eval two times to expand fully. First eval replaces $exec_prefix into $prefix
+# Second eval will expand $prefix
+build_python_site_packages_temp="${pythondir}"
+eval build_python_site_packages_temp=\"${build_python_site_packages_temp}\"
+eval build_python_site_packages_temp=\"${build_python_site_packages_temp}\"
+BUILD_PYTHON_SITE_PACKAGES_EXPANDED=${build_python_site_packages_temp}
+AC_SUBST(BUILD_PYTHON_SITE_PACKAGES_EXPANDED)
+
# FUSE section
AC_ARG_ENABLE([fuse-client],
AC_HELP_STRING([--disable-fuse-client],
@@ -497,70 +729,25 @@ if test "x$enable_fuse_client" != "xno"; then
BUILD_FUSE_CLIENT="yes"
fi
-AC_ARG_ENABLE([bd-xlator],
- AC_HELP_STRING([--enable-bd-xlator], [Build BD xlator]))
-
-if test "x$enable_bd_xlator" != "xno"; then
- AC_CHECK_LIB([lvm2app],
- [lvm_init,lvm_lv_from_name],
- [HAVE_BD_LIB="yes"],
- [HAVE_BD_LIB="no"])
-
-if test "x$HAVE_BD_LIB" = "xyes"; then
- # lvm_lv_from_name() has been made public with lvm2-2.02.79
- AC_CHECK_DECLS(
- [lvm_lv_from_name],
- [NEED_LVM_LV_FROM_NAME_DECL="no"],
- [NEED_LVM_LV_FROM_NAME_DECL="yes"],
- [[#include <lvm2app.h>]])
- fi
-fi
-
-if test "x$enable_bd_xlator" = "xyes" -a "x$HAVE_BD_LIB" = "xno"; then
- echo "BD xlator requested but required lvm2 development library not found."
- exit 1
-fi
-
-BUILD_BD_XLATOR=no
-if test "x${enable-bd-xlator}" != "xno" -a "x${HAVE_BD_LIB}" = "xyes"; then
- BUILD_BD_XLATOR=yes
- AC_DEFINE(HAVE_BD_XLATOR, 1, [define if lvm2app library found and bd xlator
- enabled])
- if test "x$NEED_LVM_LV_FROM_NAME_DECL" = "xyes"; then
- AC_DEFINE(NEED_LVM_LV_FROM_NAME_DECL, 1, [defined if lvm_lv_from_name()
- was not found in the lvm2app.h header, but can be linked])
- fi
-fi
-
-AM_CONDITIONAL([ENABLE_BD_XLATOR], [test x$BUILD_BD_XLATOR = xyes])
-
-dnl check for old openssl
-AC_CHECK_LIB([crypto], CRYPTO_THREADID_set_callback, [AC_DEFINE([HAVE_CRYPTO_THREADID], [1], [use new OpenSSL functions])])
-
-AC_CHECK_LIB([ssl], TLSv1_2_method, [AC_DEFINE([HAVE_TLSV1_2_METHOD], [1], [use new OpenSSL functions])])
+AC_SUBST(FUSE_CLIENT_SUBDIR)
-# start encryption/crypt section
+AC_ARG_ENABLE([fuse-notifications],
+ AS_HELP_STRING([--disable-fuse-notifications], [Disable FUSE notifications]))
-AC_CHECK_HEADERS([openssl/cmac.h], [have_cmac_h=yes], [have_cmac_h=no])
+AS_IF([test "x$enable_fuse_notifications" != "xno"], [
+ AC_DEFINE([HAVE_FUSE_NOTIFICATIONS], [1], [Use FUSE notifications])
+])
-AC_ARG_ENABLE([crypt-xlator],
- AC_HELP_STRING([--enable-crypt-xlator], [Build crypt encryption xlator]))
+# end FUSE section
-if test "x$enable_crypt_xlator" = "xyes" -a "x$have_cmac_h" = "xno"; then
- AC_MSG_ERROR([Encryption xlator requires OpenSSL with cmac.h])
-fi
-BUILD_CRYPT_XLATOR=no
-if test "x$enable_crypt_xlator" != "xno" -a "x$have_cmac_h" = "xyes"; then
- BUILD_CRYPT_XLATOR=yes
- AC_DEFINE(HAVE_CRYPT_XLATOR, 1, [enable building crypt encryption xlator])
+AC_CHECK_LIB([ssl], TLS_method, [HAVE_OPENSSL_1_1="yes"], [HAVE_OPENSSL_1_1="no"])
+if test "x$HAVE_OPENSSL_1_1" = "xyes"; then
+ AC_DEFINE([HAVE_TLS_METHOD], [1], [Using OpenSSL-1.1 TLS_method])
+else
+ AC_CHECK_LIB([ssl], TLSv1_2_method, [AC_DEFINE([HAVE_TLSV1_2_METHOD], [1], [Using OpenSSL-1.0 TLSv1_2_method])])
fi
-AM_CONDITIONAL([ENABLE_CRYPT_XLATOR], [test x$BUILD_CRYPT_XLATOR = xyes])
-
-AC_SUBST(FUSE_CLIENT_SUBDIR)
-# end FUSE section
-
# FUSERMOUNT section
AC_ARG_ENABLE([fusermount],
@@ -578,33 +765,6 @@ fi
AC_SUBST(FUSERMOUNT_SUBDIR)
#end FUSERMOUNT section
-# QEMU_BLOCK section
-
-AC_ARG_ENABLE([qemu-block],
- AC_HELP_STRING([--enable-qemu-block],
- [Build QEMU Block formats translator]))
-
-if test "x$enable_qemu_block" != "xno"; then
- PKG_CHECK_MODULES([GLIB], [glib-2.0],
- [HAVE_GLIB_2="yes"],
- [HAVE_GLIB_2="no"])
-fi
-
-if test "x$enable_qemu_block" = "xyes" -a "x$HAVE_GLIB_2" = "xno"; then
- echo "QEMU Block formats translator requires libglib-2.0, but missing."
- exit 1
-fi
-
-BUILD_QEMU_BLOCK=no
-if test "x${enable_qemu_block}" != "xno" -a "x${HAVE_GLIB_2}" = "xyes"; then
- BUILD_QEMU_BLOCK=yes
- AC_DEFINE(HAVE_QEMU_BLOCK, 1, [define if libglib-2.0 library found and QEMU
- Block translator enabled])
-fi
-
-
-# end QEMU_BLOCK section
-
# EPOLL section
AC_ARG_ENABLE([epoll],
AC_HELP_STRING([--disable-epoll],
@@ -618,53 +778,6 @@ if test "x$enable_epoll" != "xno"; then
fi
# end EPOLL section
-
-# IBVERBS section
-AC_ARG_ENABLE([ibverbs],
- AC_HELP_STRING([--disable-ibverbs],
- [Do not build the ibverbs transport]))
-
-if test "x$enable_ibverbs" != "xno"; then
- AC_CHECK_LIB([ibverbs],
- [ibv_get_device_list],
- [HAVE_LIBIBVERBS="yes"],
- [HAVE_LIBIBVERBS="no"])
- AC_CHECK_LIB([rdmacm], [rdma_create_id], [HAVE_RDMACM="yes"], [HAVE_RDMACM="no"])
- if test "x$HAVE_RDMACM" = "xyes" ; then
- AC_CHECK_DECLS(
- [RDMA_OPTION_ID_REUSEADDR],
- [],
- [AC_ERROR([Need at least version 1.0.15 of librdmacm])],
- [[#include <rdma/rdma_cma.h>]])
- fi
-fi
-
-if test "x$enable_ibverbs" = "xyes"; then
- if test "x$HAVE_LIBIBVERBS" = "xno"; then
- echo "ibverbs-transport requested, but libibverbs is not present."
- exit 1
- fi
-
- if test "x$HAVE_RDMACM" = "xno"; then
- echo "ibverbs-transport requested, but librdmacm is not present."
- exit 1
- fi
-fi
-
-BUILD_RDMA=no
-BUILD_IBVERBS=no
-if test "x$enable_ibverbs" != "xno" -a "x$HAVE_LIBIBVERBS" = "xyes" -a "x$HAVE_RDMACM" = "xyes"; then
- IBVERBS_SUBDIR=ib-verbs
- BUILD_IBVERBS=yes
- RDMA_SUBDIR=rdma
- BUILD_RDMA=yes
-fi
-
-AC_SUBST(IBVERBS_SUBDIR)
-AC_SUBST(RDMA_SUBDIR)
-# end IBVERBS section
-
-
# SYNCDAEMON section
AC_ARG_ENABLE([georeplication],
AC_HELP_STRING([--disable-georeplication],
@@ -672,6 +785,9 @@ AC_ARG_ENABLE([georeplication],
BUILD_SYNCDAEMON=no
case $host_os in
+ freebsd*)
+#do nothing
+ ;;
linux*)
#do nothing
;;
@@ -684,25 +800,20 @@ case $host_os in
;;
esac
SYNCDAEMON_COMPILE=0
-if test "x$enable_georeplication" != "xno"; then
- SYNCDAEMON_SUBDIR=geo-replication
- SYNCDAEMON_COMPILE=1
-
- BUILD_SYNCDAEMON="yes"
- AM_PATH_PYTHON([2.4])
- echo -n "checking if python is python 2.x... "
- if echo $PYTHON_VERSION | grep ^2; then
- :
+if test "x${with_server}" = "xyes" -a "x${enable_georeplication}" != "xno"; then
+ if test "x${have_python}" = "xno" ; then
+ AC_MSG_ERROR([only python 2 and 3 are supported])
else
- echo no
- AC_MSG_ERROR([only python 2.x is supported])
- fi
- echo -n "checking if python has ctypes support... "
- if "$PYTHON" -c 'import ctypes' 2>/dev/null; then
- echo yes
- else
- echo no
- AC_MSG_ERROR([python does not have ctypes support])
+ SYNCDAEMON_SUBDIR=geo-replication
+ SYNCDAEMON_COMPILE=1
+
+ BUILD_SYNCDAEMON="yes"
+ AC_MSG_CHECKING([if python has ctypes support...])
+ if "${PYTHON}" -c 'import ctypes' 2>/dev/null; then
+ AC_MSG_RESULT("yes")
+ else
+ AC_MSG_ERROR([python does not have ctypes support])
+ fi
fi
fi
AC_SUBST(SYNCDAEMON_COMPILE)
@@ -710,12 +821,54 @@ AC_SUBST(SYNCDAEMON_SUBDIR)
# end SYNCDAEMON section
# only install scripts from extras/geo-rep when enabled
-if test "x$enable_georeplication" != "xno"; then
+if test "x${with_server}" = "xyes" -a "x$enable_georeplication" != "xno"; then
GEOREP_EXTRAS_SUBDIR=geo-rep
fi
AC_SUBST(GEOREP_EXTRAS_SUBDIR)
AM_CONDITIONAL(USE_GEOREP, test "x$enable_georeplication" != "xno")
+# METADISP section
+AC_ARG_ENABLE([metadisp],
+ AC_HELP_STRING([--enable-metadisp],
+ [Enable the metadata dispersal xlator]))
+BUILD_METADISP=no
+if test "x${enable_metadisp}" = "xyes"; then
+ BUILD_METADISP=yes
+fi
+AM_CONDITIONAL([BUILD_METADISP], [test "x$BUILD_METADISP" = "xyes"])
+# end METADISP section
+
+# Events section
+AC_ARG_ENABLE([events],
+ AC_HELP_STRING([--disable-events],
+ [Do not install Events components]))
+
+BUILD_EVENTS=no
+EVENTS_ENABLED=0
+EVENTS_SUBDIR=
+if test "x$enable_events" != "xno"; then
+ EVENTS_SUBDIR=events
+ EVENTS_ENABLED=1
+
+ BUILD_EVENTS="yes"
+
+ if test "x${have_python}" = "xno"; then
+ if test "x${enable_events}" = "xyes"; then
+ AC_MSG_ERROR([python 2 or 3 required. exiting.])
+ fi
+ AC_MSG_WARN([python not found, disabling events])
+ EVENTS_SUBDIR=
+ EVENTS_ENABLED=0
+ BUILD_EVENTS="no"
+ else
+ AC_DEFINE(USE_EVENTS, 1, [define if events enabled])
+ fi
+fi
+AC_SUBST(EVENTS_ENABLED)
+AC_SUBST(EVENTS_SUBDIR)
+AM_CONDITIONAL([BUILD_EVENTS], [test "x${BUILD_EVENTS}" = "xyes"])
+# end Events section
+
# CDC xlator - check if libz is present if so enable HAVE_LIB_Z
BUILD_CDC=yes
PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.0],,
@@ -739,8 +892,8 @@ AC_ARG_ENABLE([firewalld],
[enable installation configuration for firewalld]),
[BUILD_FIREWALLD="${enableval}"], [BUILD_FIREWALLD="no"])
-if test "x${BUILD_FIREWALLD}" = "xyes"; then
- if !(which firewalld 1>/dev/null 2>&1) ; then
+if test "x${with_server}" = "xyes" -a "x${BUILD_FIREWALLD}" = "xyes"; then
+ if !(test -d /usr/lib/firewalld/services 1>/dev/null 2>&1) ; then
BUILD_FIREWALLD="no (firewalld not installed)"
fi
fi
@@ -748,73 +901,13 @@ AM_CONDITIONAL([USE_FIREWALLD],test ["x${BUILD_FIREWALLD}" = "xyes"])
#endof firewald section
-# Data tiering requires sqlite
-AC_ARG_ENABLE([tiering],
- AC_HELP_STRING([--disable-tiering],
- [Disable data classification/tiering]),
- [BUILD_GFDB="${enableval}"], [BUILD_GFDB="yes"])
-
-case $host_os in
- darwin*)
- SQLITE_LIBS="-lsqlite3"
- AC_CHECK_HEADERS([sqlite3.h], AC_DEFINE(USE_GFDB, 1))
- ;;
- *)
- if test "x${BUILD_GFDB}" = "xyes"; then
- PKG_CHECK_MODULES([SQLITE], [sqlite3],
- AC_DEFINE(USE_GFDB, 1),
- AC_MSG_ERROR([pass --disable-tiering to build without sqlite]))
- else
- AC_DEFINE(USE_GFDB, 0, [no sqlite, gfdb is disabled])
- fi
- ;;
-esac
-
-AC_SUBST(SQLITE_CFLAGS)
-AC_SUBST(SQLITE_LIBS)
-AM_CONDITIONAL(BUILD_GFDB, test "x${BUILD_GFDB}" = "xyes")
-AM_CONDITIONAL(USE_GFDB, test "x${BUILD_GFDB}" = "xyes")
-
-# check for systemtap/dtrace
-BUILD_SYSTEMTAP=no
-AC_MSG_CHECKING([whether to include systemtap tracing support])
-AC_ARG_ENABLE([systemtap],
- [AS_HELP_STRING([--enable-systemtap],
- [Enable inclusion of systemtap trace support])],
- [ENABLE_SYSTEMTAP="${enableval}"], [ENABLE_SYSTEMTAP="def"])
-
-AM_CONDITIONAL([ENABLE_SYSTEMTAP], [test "x${ENABLE_SYSTEMTAP}" = "xyes"])
-AC_MSG_RESULT(${ENABLE_SYSTEMTAP})
-
-if test "x${ENABLE_SYSTEMTAP}" != "xno"; then
- AC_CHECK_PROG(DTRACE, dtrace, "yes", "no")
- AC_CHECK_HEADER([sys/sdt.h], [SDT_H_FOUND="yes"],
- [SDT_H_FOUND="no"])
-fi
-
-if test "x${ENABLE_SYSTEMTAP}" = "xyes"; then
- if test "x${DTRACE}" = "xno"; then
- AC_MSG_ERROR([dtrace not found])
- elif test "$x{SDT_H_FOUND}" = "xno"; then
- AC_MSG_ERROR([systemtap support needs sys/sdt.h header])
- fi
-fi
-
-if test "x${DTRACE}" = "xyes" -a "x${SDT_H_FOUND}" = "xyes"; then
- AC_MSG_CHECKING([x"${DTRACE}"xy"${SDT_H_FOUND}"y])
- AC_DEFINE([HAVE_SYSTEMTAP], [1], [Define to 1 if using probes.])
- BUILD_SYSTEMTAP=yes
-fi
-# end of systemtap/dtrace
-
# xml-output
AC_ARG_ENABLE([xml-output],
AC_HELP_STRING([--disable-xml-output],
[Disable the xml output]))
BUILD_XML_OUTPUT="yes"
if test "x$enable_xml_output" != "xno"; then
- #check if libxml is present if so enable HAVE_LIB_XML
- m4_ifdef([AM_PATH_XML2],[AM_PATH_XML2([2.6.19])], [no_xml=yes])
+ PKG_CHECK_MODULES([XML], [libxml-2.0], [], [no_xml="yes"])
if test "x${no_xml}" = "x"; then
AC_DEFINE([HAVE_LIB_XML], [1], [Define to 1 if using libxml2.])
else
@@ -834,12 +927,74 @@ else
fi
# end of xml-output
+dnl cloudsync section
+BUILD_CLOUDSYNC="no"
+AC_CHECK_LIB([curl], [curl_easy_setopt], [LIBCURL="-lcurl"])
+if test -n "$LIBCURL";then
+ HAVE_LIBCURL="yes"
+fi
+AC_CHECK_HEADERS([openssl/hmac.h openssl/evp.h openssl/bio.h openssl/buffer.h], [HAVE_OPENSSL="yes"])
+if test "x$HAVE_LIBCURL" = "xyes" -a "x$HAVE_OPENSSL" = "xyes";then
+ HAVE_AMAZONS3="yes"
+fi
+AM_CONDITIONAL([BUILD_AMAZONS3_PLUGIN], [test "x$HAVE_AMAZONS3" = "xyes"])
+if test "x$HAVE_AMAZONS3" = "xyes";then
+ BUILD_CLOUDSYNC="yes"
+fi
+BUILD_CVLT_PLUGIN="no"
+case $host_os in
+#enable cvlt plugin only for linux platforms
+ linux*)
+ BUILD_CVLT_PLUGIN="yes"
+ BUILD_CLOUDSYNC="yes"
+ ;;
+ *)
+ ;;
+esac
+AM_CONDITIONAL([BUILD_CVLT_PLUGIN], [test "x$BUILD_CVLT_PLUGIN" = "xyes"])
+AM_CONDITIONAL([BUILD_CLOUDSYNC], [test "x$BUILD_CLOUDSYNC" = "xyes"])
+dnl end cloudsync section
+
+dnl SELinux feature enablement
+case $host_os in
+ linux*)
+ AC_ARG_ENABLE([selinux],
+ AC_HELP_STRING([--disable-selinux],
+ [Disable SELinux features]),
+ [USE_SELINUX="${enableval}"], [USE_SELINUX="yes"])
+ ;;
+ *)
+ USE_SELINUX=no
+ ;;
+esac
+AM_CONDITIONAL(USE_SELINUX, test "x${USE_SELINUX}" = "xyes")
+dnl end of SELinux feature enablement
+
AC_CHECK_HEADERS([execinfo.h], [have_backtrace=yes])
if test "x${have_backtrace}" = "xyes"; then
AC_DEFINE(HAVE_BACKTRACE, 1, [define if found backtrace])
fi
AC_SUBST(HAVE_BACKTRACE)
+dnl Old (before C11) compiler can compile (but not link) this:
+dnl
+dnl int main () {
+dnl _Static_assert(1, "True");
+dnl return 0;
+dnl }
+dnl
+dnl assuming that _Static_assert is an implicitly declared function. So
+dnl we're trying to link just to make sure that this is not the case.
+
+AC_MSG_CHECKING([whether $CC supports C11 _Static_assert])
+AC_TRY_LINK([], [_Static_assert(1, "True");],
+ [STATIC_ASSERT=yes], [STATIC_ASSERT=no])
+
+AC_MSG_RESULT([$STATIC_ASSERT])
+if test x$STATIC_ASSERT = "xyes"; then
+ AC_DEFINE(HAVE_STATIC_ASSERT, 1, [Define if C11 _Static_assert is supported.])
+fi
+
if test "x${have_backtrace}" != "xyes"; then
AC_TRY_COMPILE([#include <math.h>], [double x=0.0; x=ceil(0.0);],
[],
@@ -847,11 +1002,11 @@ AC_TRY_COMPILE([#include <math.h>], [double x=0.0; x=ceil(0.0);],
fi
dnl glusterfs prints memory usage to stderr by sending it SIGUSR1
-AC_CHECK_FUNC([malloc_stats], [have_malloc_stats=yes])
-if test "x${have_malloc_stats}" = "xyes"; then
- AC_DEFINE(HAVE_MALLOC_STATS, 1, [define if found malloc_stats])
+AC_CHECK_FUNC([mallinfo], [have_mallinfo=yes])
+if test "x${have_mallinfo}" = "xyes"; then
+ AC_DEFINE(HAVE_MALLINFO, 1, [define if found mallinfo])
fi
-AC_SUBST(HAVE_MALLOC_STATS)
+AC_SUBST(HAVE_MALLINFO)
dnl Linux, Solaris, Cygwin
AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec])
@@ -859,7 +1014,7 @@ dnl FreeBSD, NetBSD
AC_CHECK_MEMBERS([struct stat.st_atimespec.tv_nsec])
case $host_os in
*netbsd*)
- CFLAGS="${CFLAGS} -D_INCOMPLETE_XOPEN_C063 -DCONFIG_MACHINE_BSWAP_H"
+ GF_CFLAGS="${GF_CFLAGS} -D_INCOMPLETE_XOPEN_C063 -DCONFIG_MACHINE_BSWAP_H"
;;
esac
AC_CHECK_FUNC([linkat], [have_linkat=yes])
@@ -872,24 +1027,42 @@ dnl check for Monotonic clock
AC_CHECK_LIB([rt], [clock_gettime], ,
AC_MSG_WARN([System doesn't have monotonic clock using contrib]))
-dnl Check for argp
+dnl check for argp, FreeBSD has the header in /usr/local/include
+case $host_os in
+ *freebsd*)
+ CFLAGS="${CFLAGS} -isystem /usr/local/include"
+ ARGP_LDADD=-largp
+ ;;
+ *netbsd*)
+ ARGP_LDADD=-largp
+ ;;
+esac
+dnl argp-standalone does not provide a pkg-config file
AC_CHECK_HEADER([argp.h], AC_DEFINE(HAVE_ARGP, 1, [have argp]))
-
-BUILD_ARGP_STANDALONE=no
-if test "x${ac_cv_header_argp_h}" = "xno"; then
- AC_CONFIG_SUBDIRS(contrib/argp-standalone)
- BUILD_ARGP_STANDALONE=yes
- ARGP_STANDALONE_CPPFLAGS='-I${top_srcdir}/contrib/argp-standalone'
- ARGP_STANDALONE_LDADD='${top_builddir}/contrib/argp-standalone/libargp.a'
- ARGP_STANDALONE_DIR='${top_builddir}/contrib/argp-standalone'
+if test "x$ac_cv_header_argp_h" != "xyes"; then
+ AC_MSG_ERROR([argp.h not found, install libargp or argp-standalone])
fi
-
-dnl libglusterfs needs argp.h, practically everything depends on it
-GF_CPPFLAGS="${GF_CPPFLAGS} ${ARGP_STANDALONE_CPPFLAGS}"
-
-AC_SUBST(ARGP_STANDALONE_CPPFLAGS)
-AC_SUBST(ARGP_STANDALONE_LDADD)
-AC_SUBST(ARGP_STANDALONE_DIR)
+AC_SUBST(ARGP_LDADD)
+
+dnl Check for atomic operation support
+AC_MSG_CHECKING([for gcc __atomic builtins])
+AC_TRY_LINK([], [int v; __atomic_load_n(&v, __ATOMIC_ACQUIRE);],
+ [have_atomic_builtins=yes], [have_atomic_builtins=no])
+if test "x${have_atomic_builtins}" = "xyes"; then
+ AC_DEFINE(HAVE_ATOMIC_BUILTINS, 1, [define if __atomic_*() builtins are available])
+fi
+AC_SUBST(HAVE_ATOMIC_BUILTINS)
+AC_MSG_RESULT([$have_atomic_builtins])
+
+dnl __sync_*() will not be needed if __atomic_*() is available
+AC_MSG_CHECKING([for gcc __sync builtins])
+AC_TRY_LINK([], [__sync_synchronize();],
+ [have_sync_builtins=yes], [have_sync_builtins=no])
+if test "x${have_sync_builtins}" = "xyes"; then
+ AC_DEFINE(HAVE_SYNC_BUILTINS, 1, [define if __sync_*() builtins are available])
+fi
+AC_SUBST(HAVE_SYNC_BUILTINS)
+AC_MSG_RESULT([$have_sync_builtins])
AC_CHECK_HEADER([malloc.h], AC_DEFINE(HAVE_MALLOC_H, 1, [have malloc.h]))
@@ -913,6 +1086,63 @@ if test "x${have_posix_fallocate}" = "xyes"; then
AC_DEFINE(HAVE_POSIX_FALLOCATE, 1, [define if posix_fallocate exists])
fi
+# On fedora-29, copy_file_range syscall and the libc API both are present.
+# Whereas, on some machines such as centos-7, RHEL-7, the API is not there.
+# Only the system call is present. So, this change is to determine whether
+# the API is present or not. If not, then check whether the system call is
+# present or not. Accordingly sys_copy_file_range function will first call
+# the API if it is there. Otherwise it will call syscall(SYS_copy_file_range).
+AC_CHECK_FUNC([copy_file_range], [have_copy_file_range=yes])
+if test "x${have_copy_file_range}" = "xyes"; then
+ AC_DEFINE(HAVE_COPY_FILE_RANGE, 1, [define if copy_file_range exists])
+else
+ OLD_CFLAGS=${CFLAGS}
+ CFLAGS="-D_GNU_SOURCE"
+ AC_CHECK_DECL([SYS_copy_file_range], , , [#include <sys/syscall.h>])
+ if test "x${ac_cv_have_decl_SYS_copy_file_range}" = "xyes"; then
+ AC_DEFINE(HAVE_COPY_FILE_RANGE_SYS, 1, [define if SYS_copy_file_range is available])
+ fi
+ CFLAGS=${OLD_CFLAGS}
+fi
+
+AC_CHECK_FUNC([syncfs], [have_syncfs=yes])
+if test "x${have_syncfs}" = "xyes"; then
+ AC_DEFINE(HAVE_SYNCFS, 1, [define if syncfs exists])
+else
+ OLD_CFLAGS=${CFLAGS}
+ CFLAGS="-D_GNU_SOURCE"
+ AC_CHECK_DECL([SYS_syncfs], , , [#include <sys/syscall.h>])
+ if test "x${ac_cv_have_decl_SYS_syncfs}" = "xyes"; then
+ AC_DEFINE(HAVE_SYNCFS_SYS, 1, [define if SYS_syncfs is available])
+ fi
+ CFLAGS=${OLD_CFLAGS}
+fi
+
+BUILD_NANOSECOND_TIMESTAMPS=no
+AC_CHECK_FUNC([utimensat], [have_utimensat=yes])
+if test "x${have_utimensat}" = "xyes"; then
+ BUILD_NANOSECOND_TIMESTAMPS=yes
+ AC_DEFINE(HAVE_UTIMENSAT, 1, [define if utimensat exists])
+fi
+
+OLD_CFLAGS=${CFLAGS}
+CFLAGS="-D_GNU_SOURCE"
+AC_CHECK_DECL([SEEK_HOLE], , , [#include <unistd.h>])
+if test "x${ac_cv_have_decl_SEEK_HOLE}" = "xyes"; then
+ AC_DEFINE(HAVE_SEEK_HOLE, 1, [define if SEEK_HOLE is available])
+fi
+CFLAGS=${OLD_CFLAGS}
+
+AC_CHECK_FUNC([accept4], [have_accept4=yes])
+if test "x${have_accept4}" = "xyes"; then
+ AC_DEFINE(HAVE_ACCEPT4, 1, [define if accept4 exists])
+fi
+
+AC_CHECK_FUNC([paccept], [have_paccept=yes])
+if test "x${have_paccept}" = "xyes"; then
+AC_DEFINE(HAVE_PACCEPT, 1, [define if paccept exists])
+fi
+
# Check the distribution where you are compiling glusterfs on
GF_DISTRIBUTION=
@@ -933,7 +1163,34 @@ fi
AC_SUBST(GF_DISTRIBUTION)
GF_HOST_OS=""
-GF_LDFLAGS="-rdynamic"
+GF_LDFLAGS="${GF_LDFLAGS} -rdynamic"
+
+dnl see --with-libtirpc option check above, libtirpc(-devel) is required for
+dnl ipv6-default
+if test "x${with_libtirpc}" = "xyes" || test "x${with_ipv6_default}" = "xyes" ; then
+ PKG_CHECK_MODULES([TIRPC], [libtirpc],
+ [with_libtirpc="yes"; GF_CFLAGS="$GF_CFLAGS $TIRPC_CFLAGS"; GF_LDFLAGS="$GF_LDFLAGS $TIRPC_LIBS";],
+ [with_libtirpc="missing"; with_ipv6_default="no"])
+fi
+
+if test "x${with_libtirpc}" = "xmissing" ; then
+ AC_CHECK_HEADERS([rpc/rpc.h],[
+ AC_MSG_WARN([
+ ---------------------------------------------------------------------------------
+ libtirpc (and/or ipv6-default) were enabled but libtirpc-devel is not installed.
+ Disabling libtirpc and ipv6-default and falling back to legacy glibc rpc headers.
+ This is a transitional warning message. Eventually it will be an error message.
+ ---------------------------------------------------------------------------------])],[
+ AC_MSG_ERROR([
+ ---------------------------------------------------------------------------------
+ libtirpc (and/or ipv6-default) were enabled but libtirpc-devel is not installed
+ and there were no legacy glibc rpc headers and library to fall back to.
+ ---------------------------------------------------------------------------------])])
+fi
+
+if test "x$with_ipv6_default" = "xyes" ; then
+ GF_CFLAGS="$GF_CFLAGS -DIPV6_DEFAULT"
+fi
dnl check for gcc -Werror=format-security
saved_CFLAGS=$CFLAGS
@@ -941,12 +1198,10 @@ CFLAGS="-Wformat -Werror=format-security"
AC_MSG_CHECKING([whether $CC accepts -Werror=format-security])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [cc_werror_format_security=yes], [cc_werror_format_security=no])
echo $cc_werror_format_security
-if test "x$cc_werror_format_security" = "xno"; then
- CFLAGS="$saved_CFLAGS"
-else
- CFLAGS="$saved_CFLAGS $CFLAGS"
- GF_CFLAGS="$GF_CFLAGS $CFLAGS"
+if test "x$cc_werror_format_security" = "xyes"; then
+ GF_CFLAGS="$GF_CFLAGS ${CFLAGS}"
fi
+CFLAGS="$saved_CFLAGS"
dnl check for gcc -Werror=implicit-function-declaration
saved_CFLAGS=$CFLAGS
@@ -954,12 +1209,10 @@ CFLAGS="-Werror=implicit-function-declaration"
AC_MSG_CHECKING([whether $CC accepts -Werror=implicit-function-declaration])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [cc_werror_implicit=yes], [cc_werror_implicit=no])
echo $cc_werror_implicit
-if test "x$cc_werror_implicit" = "xno"; then
- CFLAGS="$saved_CFLAGS"
-else
- CFLAGS="$saved_CFLAGS $CFLAGS"
- GF_CFLAGS="$GF_CFLAGS $CFLAGS"
+if test "x$cc_werror_implicit" = "xyes"; then
+ GF_CFLAGS="${GF_CFLAGS} ${CFLAGS}"
fi
+CFLAGS="$saved_CFLAGS"
dnl clang is mostly GCC-compatible, but its version is much lower,
dnl so we have to check for it.
@@ -996,20 +1249,25 @@ fi
old_prefix=$prefix
if test "x$prefix" = xNONE; then
- prefix=$ac_default_prefix
+ prefix=$ac_default_prefix
fi
-GLUSTERFS_LIBEXECDIR="$(eval echo $prefix)/libexec/glusterfs"
-GLUSTERFSD_MISCDIR="$(eval echo $prefix)/var/lib/misc/glusterfsd"
+old_exec_prefix=$exec_prefix
+if test "x$exec_prefix" = xNONE; then
+ exec_prefix="$(eval echo $prefix)"
+fi
+GLUSTERFS_LIBEXECDIR="$(eval echo $libexecdir)/glusterfs"
prefix=$old_prefix
+exec_prefix=$old_exec_prefix
### Dirty hacky stuff to make LOCALSTATEDIR work
if test "x$prefix" = xNONE; then
test $localstatedir = '${prefix}/var' && localstatedir=$ac_default_prefix/var
localstatedir=/var
- LOCALSTATEDIR=$(eval echo ${localstatedir})
-else
- LOCALSTATEDIR=$(eval echo ${localstatedir})
fi
+localstatedir="$(eval echo ${localstatedir})"
+LOCALSTATEDIR=$localstatedir
+
+GLUSTERFSD_MISCDIR="$(eval echo ${localstatedir})/lib/misc/glusterfsd"
old_prefix=$prefix
if test "x$prefix" = xNONE; then
@@ -1019,6 +1277,7 @@ GLUSTERD_VOLFILE="$(eval echo ${sysconfdir})/glusterfs/glusterd.vol"
prefix=$old_prefix
+GFAPI_EXTRA_LDFLAGS='-Wl,--version-script=$(top_srcdir)/api/src/gfapi.map'
case $host_os in
linux*)
GF_HOST_OS="GF_LINUX_HOST_OS"
@@ -1038,9 +1297,9 @@ case $host_os in
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME"
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME"
GF_FUSE_CFLAGS="-DFUSERMOUNT_DIR=\\\"\$(sbindir)\\\""
- GF_LDADD="${ARGP_STANDALONE_LDADD}"
+ GF_LDADD="${ARGP_LDADD}"
if test "x$ac_cv_header_execinfo_h" = "xyes"; then
- GF_LDFLAGS="-lexecinfo"
+ GF_LDFLAGS="${GF_LDFLAGS} -lexecinfo"
fi
GF_FUSE_LDADD="-lperfuse"
BUILD_FUSE_CLIENT=yes
@@ -1051,17 +1310,13 @@ case $host_os in
;;
*freebsd*)
GF_HOST_OS="GF_BSD_HOST_OS"
- GF_CFLAGS="${GF_CFLAGS} ${ARGP_STANDALONE_CPPFLAGS} -O0"
- GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME"
- GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME"
- GF_CFLAGS="${GF_CFLAGS} -D_LIBGEN_H_"
GF_CFLAGS="${GF_CFLAGS} -DO_DSYNC=0"
GF_CFLAGS="${GF_CFLAGS} -Dxdr_quad_t=xdr_longlong_t"
GF_CFLAGS="${GF_CFLAGS} -Dxdr_u_quad_t=xdr_u_longlong_t"
GF_FUSE_CFLAGS="-DFUSERMOUNT_DIR=\\\"\$(sbindir)\\\""
- GF_LDADD="${ARGP_STANDALONE_LDADD}"
+ GF_LDADD="${ARGP_LDADD}"
if test "x$ac_cv_header_execinfo_h" = "xyes"; then
- GF_LDFLAGS="-lexecinfo"
+ GF_LDFLAGS="${GF_LDFLAGS} -lexecinfo"
fi
BUILD_FUSE_CLIENT=yes
BUILD_FUSERMOUNT=no
@@ -1071,29 +1326,41 @@ case $host_os in
darwin*)
GF_HOST_OS="GF_DARWIN_HOST_OS"
LIBTOOL=glibtool
- GF_CFLAGS="${GF_CFLAGS} ${ARGP_STANDALONE_CPPFLAGS} "
GF_CFLAGS="${GF_CFLAGS} -D_REENTRANT -D_XOPEN_SOURCE "
GF_CFLAGS="${GF_CFLAGS} -D_DARWIN_USE_64_BIT_INODE "
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_BASENAME"
GF_CFLAGS="${GF_CFLAGS} -DTHREAD_UNSAFE_DIRNAME"
- GF_LDADD="${ARGP_STANDALONE_LDADD}"
- GF_LDFLAGS=""
+ GF_LDADD="${ARGP_LDADD}"
+ GF_LDFLAGS="${GF_LDFLAGS}"
GF_FUSE_CFLAGS="-I\$(CONTRIBDIR)/macfuse"
BUILD_FUSERMOUNT="no"
FUSERMOUNT_SUBDIR=""
GLUSTERD_WORKDIR="${LOCALSTATEDIR}/db/glusterd"
- ;;
-esac
-
-case $host_os in
- darwin*)
GFAPI_EXTRA_LDFLAGS='-Wl,-alias_list,$(top_srcdir)/api/src/gfapi.aliases'
;;
- *)
- GFAPI_EXTRA_LDFLAGS='-Wl,--version-script=$(top_srcdir)/api/src/gfapi.map'
- ;;
esac
+# Default value for sbindir
+prefix_temp=$prefix
+exec_prefix_temp=$exec_prefix
+
+test "${prefix}" = "NONE" && prefix="${ac_default_prefix}"
+test "${exec_prefix}" = "NONE" && exec_prefix='${prefix}'
+sbintemp="${sbindir}"
+eval sbintemp=\"${sbintemp}\"
+eval sbintemp=\"${sbintemp}\"
+SBIN_DIR=${sbintemp}
+
+sysconfdirtemp="${sysconfdir}"
+eval sysconfdirtemp=\"${sysconfdirtemp}\"
+SYSCONF_DIR=${sysconfdirtemp}
+
+prefix=$prefix_temp
+exec_prefix=$exec_prefix_temp
+
+AC_SUBST(SBIN_DIR)
+AC_SUBST(SYSCONF_DIR)
+
# lazy umount emulation
UMOUNTD_SUBDIR=""
if test "x${GF_HOST_OS}" != "xGF_LINUX_HOST_OS" ; then
@@ -1101,15 +1368,21 @@ if test "x${GF_HOST_OS}" != "xGF_LINUX_HOST_OS" ; then
fi
AC_SUBST(UMOUNTD_SUBDIR)
-# enable/disable QEMU
-AM_CONDITIONAL([ENABLE_QEMU_BLOCK], [test x$BUILD_QEMU_BLOCK = xyes])
-
# enable debug section
AC_ARG_ENABLE([debug],
AC_HELP_STRING([--enable-debug],
[Enable debug build options.]))
+AC_ARG_ENABLE([mempool],
+ AC_HELP_STRING([--disable-mempool],
+ [Disable the Gluster memory pooler.]))
+
+USE_MEMPOOL="yes"
+if test "x$enable_mempool" = "xno"; then
+ USE_MEMPOOL="no"
+ AC_DEFINE(GF_DISABLE_MEMPOOL, 1, [Disable the Gluster memory pooler.])
+fi
# syslog section
AC_ARG_ENABLE([syslog],
@@ -1130,7 +1403,7 @@ AC_CHECK_LIB([readline -lcurses],[readline],[RLLIBS="-lreadline -lcurses"])
AC_CHECK_LIB([readline -ltermcap],[readline],[RLLIBS="-lreadline -ltermcap"])
AC_CHECK_LIB([readline -lncurses],[readline],[RLLIBS="-lreadline -lncurses"])
-if test "x$RLLIBS" != "x"; then
+if test -n "$RLLIBS"; then
if test "x$RL_UNDO" = "xyes"; then
AC_DEFINE(HAVE_READLINE, 1, [readline enabled CLI])
BUILD_READLINE=yes
@@ -1143,104 +1416,41 @@ fi
BUILD_LIBAIO=no
AC_CHECK_LIB([aio],[io_setup],[LIBAIO="-laio"])
-if test "x$LIBAIO" != "x"; then
+if test -n "$LIBAIO"; then
AC_DEFINE(HAVE_LIBAIO, 1, [libaio based POSIX enabled])
BUILD_LIBAIO=yes
fi
-# glupy section
-BUILD_GLUPY=no
-have_python2=no
-have_Python_h=no
-
-AM_PATH_PYTHON()
-if echo $PYTHON_VERSION | grep ^2; then
- have_python2=yes
+dnl gnfs section
+BUILD_GNFS="no"
+RPCBIND_SERVICE=""
+AC_ARG_ENABLE([gnfs],
+ AC_HELP_STRING([--enable-gnfs],
+ [Enable legacy gnfs server xlator.]))
+if test "x${with_server}" = "xyes" -a "x$enable_gnfs" = "xyes"; then
+ BUILD_GNFS="yes"
+ GF_CFLAGS="$GF_CFLAGS -DBUILD_GNFS"
+ RPCBIND_SERVICE="rpcbind.service"
fi
-
-# Save flags before testing python
-saved_CFLAGS=$CFLAGS
-saved_CPPFLAGS=$CPPFLAGS
-saved_LDFLAGS=$LDFLAGS
-
-# Use pkg-config to get runtime search patch missing from ${PYTHON}-config
-# Just do "true" on failure so that configure does not bail out
-PKG_CHECK_MODULES([PYTHON], "python-$PYTHON_VERSION",,true)
-CFLAGS="`${PYTHON}-config --cflags`"
-CPPFLAGS=$CFLAGS
-LDFLAGS="${PYTHON_LIBS} -L`${PYTHON}-config --prefix`/lib -L`${PYTHON}-config --prefix`/$libdir `${PYTHON}-config --ldflags`"
-
-AC_CHECK_HEADERS([python$PYTHON_VERSION/Python.h],[have_Python_h=yes],[])
-AC_ARG_ENABLE([glupy],
- AS_HELP_STRING([--enable-glupy],
- [build glupy]))
-case x$enable_glupy in
- xyes)
- if test "x$have_python2" = "xyes" -a "x$have_Python_h" = "xyes"; then
- BUILD_GLUPY=yes
- PYTHONDEV_CFLAGS="$CFLAGS"
- PYTHONDEV_CPPFLAGS="$CPPFLAGS"
- PYTHONDEV_LDFLAGS="$LDFLAGS"
- AC_SUBST(PYTHONDEV_CFLAGS)
- AC_SUBST(PYTHONDEV_CPPFLAGS)
- AC_SUBST(PYTHONDEV_LDFLAGS)
- else
- AC_MSG_ERROR([glupy requires python-devel/python-dev package and python2.x])
- fi
- ;;
- xno)
- ;;
- *)
- if test "x$have_python2" = "xyes" -a "x$have_Python_h" = "xyes"; then
- BUILD_GLUPY=yes
- PYTHONDEV_CFLAGS="$CFLAGS"
- PYTHONDEV_CPPFLAGS="$CPPFLAGS"
- PYTHONDEV_LDFLAGS="$LDFLAGS"
- AC_SUBST(PYTHONDEV_CFLAGS)
- AC_SUBST(PYTHONDEV_CPPFLAGS)
- AC_SUBST(PYTHONDEV_LDFLAGS)
- else
- AC_MSG_WARN([
- ---------------------------------------------------------------------------------
- cannot build glupy. python 2.x and python-devel/python-dev package are required.
- ---------------------------------------------------------------------------------])
- fi
- ;;
-esac
-# Restore flags
-CFLAGS=$saved_CFLAGS
-CPPFLAGS=$saved_CPPFLAGS
-LDFLAGS=$saved_LDFLAGS
-
-case $host_os in
- darwin*)
- BUILD_GLUPY=no
- ;;
-esac
-
-if test "x$BUILD_GLUPY" = "xyes"; then
- BUILD_PYTHON_SITE_PACKAGES=`$PYTHON -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib())'`
- BUILD_PYTHON_INC=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_inc()"`
- BUILD_PYTHON_LIB=python$PYTHON_VERSION
- GLUPY_SUBDIR=glupy
- GLUPY_SUBDIR_MAKEFILE=xlators/features/glupy/Makefile
- GLUPY_SUBDIR_SRC_MAKEFILE=xlators/features/glupy/src/Makefile
- echo "building glupy with -isystem $BUILD_PYTHON_INC -l $BUILD_PYTHON_LIB"
- AC_SUBST(BUILD_PYTHON_SITE_PACKAGES)
- AC_SUBST(BUILD_PYTHON_INC)
- AC_SUBST(BUILD_PYTHON_LIB)
- AC_SUBST(GLUPY_SUBDIR)
- AC_SUBST(GLUPY_SUBDIR_MAKEFILE)
- AC_SUBST(GLUPY_SUBDIR_SRC_MAKEFILE)
-fi
-# end glupy section
+AM_CONDITIONAL([BUILD_GNFS], [test x$BUILD_GNFS = xyes])
+AC_SUBST(BUILD_GNFS)
+AC_SUBST(RPCBIND_SERVICE)
+dnl end gnfs section
dnl Check for userspace-rcu
-PKG_CHECK_MODULES([URCU], [liburcu-bp])
+PKG_CHECK_MODULES([URCU], [liburcu-bp], [],
+ [AC_CHECK_HEADERS([urcu-bp.h],
+ [URCU_LIBS='-lurcu-bp'],
+ AC_MSG_ERROR([liburcu-bp not found]))])
PKG_CHECK_MODULES([URCU_CDS], [liburcu-cds >= 0.8], [],
[PKG_CHECK_MODULES([URCU_CDS], [liburcu-cds >= 0.7],
- [AC_DEFINE(URCU_0_7, 1, [Define if liburcu 0.7 is found])],
- [AC_MSG_ERROR([liburcu >= 0.7 required])])])
+ [AC_DEFINE(URCU_OLD, 1, [Define if liburcu 0.6 or 0.7 is found])
+ USE_CONTRIB_URCU='yes'],
+ [AC_CHECK_HEADERS([urcu/cds.h],
+ [AC_DEFINE(URCU_OLD, 1, [Define if liburcu 0.6 or 0.7 is found])
+ URCU_CDS_LIBS='-lurcu-cds'
+ USE_CONTRIB_URCU='yes'],
+ [AC_MSG_ERROR([liburcu-cds not found])])])])
BUILD_UNITTEST="no"
AC_ARG_ENABLE([cmocka],
@@ -1276,9 +1486,114 @@ AC_SUBST(UNITTEST_LDFLAGS)
AC_SUBST(CFLAGS)
# end enable debug section
+# EC dynamic code generation section
+
+EC_DYNAMIC_SUPPORT="none"
+EC_DYNAMIC_ARCH="none"
+
+AC_ARG_ENABLE([ec-dynamic],
+ AC_HELP_STRING([--disable-ec-dynamic],
+ [Disable all dynamic code generation extensions for EC module]))
+
+AC_ARG_ENABLE([ec-dynamic-intel],
+ AC_HELP_STRING([--disable-ec-dynamic-intel],
+ [Disable all INTEL dynamic code generation extensions for EC module]))
+
+AC_ARG_ENABLE([ec-dynamic-arm],
+ AC_HELP_STRING([--disable-ec-dynamic-arm],
+ [Disable all ARM dynamic code generation extensions for EC module]))
+
+AC_ARG_ENABLE([ec-dynamic-x64],
+ AC_HELP_STRING([--disable-ec-dynamic-x64],
+ [Disable dynamic INTEL x64 code generation for EC module]))
+
+AC_ARG_ENABLE([ec-dynamic-sse],
+ AC_HELP_STRING([--disable-ec-dynamic-sse],
+ [Disable dynamic INTEL SSE code generation for EC module]))
+
+AC_ARG_ENABLE([ec-dynamic-avx],
+ AC_HELP_STRING([--disable-ec-dynamic-avx],
+ [Disable dynamic INTEL AVX code generation for EC module]))
+
+AC_ARG_ENABLE([ec-dynamic-neon],
+ AC_HELP_STRING([--disable-ec-dynamic-neon],
+ [Disable dynamic ARM NEON code generation for EC module]))
+
+if test "x$enable_ec_dynamic" != "xno"; then
+ case $host in
+ x86_64*)
+ if test "x$enable_ec_dynamic_intel" != "xno"; then
+ if test "x$enable_ec_dynamic_x64" != "xno"; then
+ EC_DYNAMIC_SUPPORT="$EC_DYNAMIC_SUPPORT x64"
+ AC_DEFINE(USE_EC_DYNAMIC_X64, 1, [Defined if using dynamic INTEL x64 code])
+ fi
+ if test "x$enable_ec_dynamic_sse" != "xno"; then
+ EC_DYNAMIC_SUPPORT="$EC_DYNAMIC_SUPPORT sse"
+ AC_DEFINE(USE_EC_DYNAMIC_SSE, 1, [Defined if using dynamic INTEL SSE code])
+ fi
+ if test "x$enable_ec_dynamic_avx" != "xno"; then
+ EC_DYNAMIC_SUPPORT="$EC_DYNAMIC_SUPPORT avx"
+ AC_DEFINE(USE_EC_DYNAMIC_AVX, 1, [Defined if using dynamic INTEL AVX code])
+ fi
+
+ if test "x$EC_DYNAMIC_SUPPORT" != "xnone"; then
+ EC_DYNAMIC_ARCH="intel"
+ fi
+ fi
+ ;;
+ arm*)
+ if test "x$enable_ec_dynamic_arm" != "xno"; then
+ if test "x$enable_ec_dynamic_neon" != "xno"; then
+ EC_DYNAMIC_SUPPORT="$EC_DYNAMIC_SUPPORT neon"
+ AC_DEFINE(USE_EC_DYNAMIC_NEON, 1, [Defined if using dynamic ARM NEON code])
+ fi
+
+ if test "x$EC_DYNAMIC_SUPPORT" != "xnone"; then
+ EC_DYNAMIC_ARCH="arm"
+ fi
+ fi
+ ;;
+ esac
+
+ EC_DYNAMIC_SUPPORT="${EC_DYNAMIC_SUPPORT#none }"
+fi
+
+AM_CONDITIONAL([ENABLE_EC_DYNAMIC_INTEL], [test "x$EC_DYNAMIC_ARCH" = "xintel"])
+AM_CONDITIONAL([ENABLE_EC_DYNAMIC_ARM], [test "x$EC_DYNAMIC_ARCH" = "xarm"])
+
+AM_CONDITIONAL([ENABLE_EC_DYNAMIC_X64], [test "x${EC_DYNAMIC_SUPPORT##*x64*}" = "x"])
+AM_CONDITIONAL([ENABLE_EC_DYNAMIC_SSE], [test "x${EC_DYNAMIC_SUPPORT##*sse*}" = "x"])
+AM_CONDITIONAL([ENABLE_EC_DYNAMIC_AVX], [test "x${EC_DYNAMIC_SUPPORT##*avx*}" = "x"])
+AM_CONDITIONAL([ENABLE_EC_DYNAMIC_NEON], [test "x${EC_DYNAMIC_SUPPORT##*neon*}" = "x"])
+
+AC_SUBST(USE_EC_DYNAMIC_X64)
+AC_SUBST(USE_EC_DYNAMIC_SSE)
+AC_SUBST(USE_EC_DYNAMIC_AVX)
+AC_SUBST(USE_EC_DYNAMIC_NEON)
+
+# end EC dynamic code generation section
+
dnl libglusterfs.so uses math functions
GF_LDADD="${GF_LDADD} ${MATH_LIB}"
+case $host_os in
+ dnl Can't use libtool's portable "-no-undefined" as it seems to be ignored on Linux
+ linux*)
+ GF_NO_UNDEFINED='-Wl,--no-undefined'
+ ;;
+ darwin*)
+ GF_NO_UNDEFINED='-Wl,-undefined'
+ ;;
+ *)
+ dnl There's an issue on FreeBSD with reference to __progname used in some parts of code
+ GF_NO_UNDEFINED=''
+ ;;
+esac
+dnl GF_XLATOR_DEFAULT_LDFLAGS is for most xlators that expose a common set of symbols
+GF_XLATOR_DEFAULT_LDFLAGS='-avoid-version -export-symbols $(top_srcdir)/xlators/xlator.sym $(UUID_LIBS) $(GF_NO_UNDEFINED) $(TIRPC_LIBS)'
+dnl GF_XLATOR_LDFLAGS is for xlators that expose extra symbols, e.g. dht
+GF_XLATOR_LDFLAGS='-avoid-version $(UUID_LIBS) $(GF_NO_UNDEFINED) $(TIRPC_LIBS)'
+
AC_SUBST(GF_HOST_OS)
AC_SUBST(GF_CFLAGS)
AC_SUBST(GF_LDFLAGS)
@@ -1289,18 +1604,34 @@ AC_SUBST(RLLIBS)
AC_SUBST(LIBAIO)
AC_SUBST(AM_MAKEFLAGS)
AC_SUBST(AM_LIBTOOLFLAGS)
+AC_SUBST(GF_NO_UNDEFINED)
+AC_SUBST(GF_XLATOR_DEFAULT_LDFLAGS)
+AC_SUBST(GF_XLATOR_LDFLAGS)
+AC_SUBST(GF_XLATOR_MGNT_LIBADD)
+
+case $host_os in
+ *freebsd*)
+ GF_XLATOR_MGNT_LIBADD="-lutil -lprocstat"
+ ;;
+esac
CONTRIBDIR='$(top_srcdir)/contrib'
AC_SUBST(CONTRIBDIR)
GF_CPPDEFINES='-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)'
-GF_CPPINCLUDES='-include $(top_builddir)/config.h -I$(top_srcdir)/libglusterfs/src'
+GF_CPPINCLUDES='-include $(top_builddir)/config.h -include $(top_builddir)/site.h -I$(top_srcdir)/libglusterfs/src -I$(top_builddir)/libglusterfs/src'
+if test "x${USE_CONTRIB_URCU}" = "xyes"; then
+ GF_CPPINCLUDES="${GF_CPPINCLUDES} -I\$(CONTRIBDIR)/userspace-rcu"
+fi
GF_CPPFLAGS="$GF_CPPFLAGS $GF_CPPDEFINES $GF_CPPINCLUDES"
AC_SUBST([GF_CPPFLAGS])
AM_CONDITIONAL([GF_LINUX_HOST_OS], test "${GF_HOST_OS}" = "GF_LINUX_HOST_OS")
AM_CONDITIONAL([GF_DARWIN_HOST_OS], test "${GF_HOST_OS}" = "GF_DARWIN_HOST_OS")
AM_CONDITIONAL([GF_BSD_HOST_OS], test "${GF_HOST_OS}" = "GF_BSD_HOST_OS")
+if test "${GF_HOST_OS}" = "GF_BSD_HOST_OS"; then
+ AC_DEFINE(GF_BSD_HOST_OS, 1, [This is a BSD compatible OS.])
+fi
AC_SUBST(GLUSTERD_WORKDIR)
AM_CONDITIONAL([GF_INSTALL_GLUSTERD_WORKDIR], test ! -d ${GLUSTERD_WORKDIR} && test -d ${sysconfdir}/glusterd )
@@ -1322,8 +1653,6 @@ GFAPI_VERSION="7."${PACKAGE_VERSION}
LIBGFCHANGELOG_VERSION="0.0.1"
AC_SUBST(GFAPI_VERSION)
AC_SUBST(LIBGFCHANGELOG_VERSION)
-LIBGFDB_VERSION="0.0.1"
-AC_SUBST(LIBGFDB_VERSION)
dnl libtool versioning
LIBGFXDR_LT_VERSION="0:1:0"
@@ -1350,23 +1679,39 @@ echo
echo "GlusterFS configure summary"
echo "==========================="
echo "FUSE client : $BUILD_FUSE_CLIENT"
-echo "Infiniband verbs : $BUILD_IBVERBS"
echo "epoll IO multiplex : $BUILD_EPOLL"
-echo "argp-standalone : $BUILD_ARGP_STANDALONE"
echo "fusermount : $BUILD_FUSERMOUNT"
echo "readline : $BUILD_READLINE"
echo "georeplication : $BUILD_SYNCDAEMON"
echo "Linux-AIO : $BUILD_LIBAIO"
echo "Enable Debug : $BUILD_DEBUG"
-## echo "systemtap : $BUILD_SYSTEMTAP"
-echo "Block Device xlator : $BUILD_BD_XLATOR"
-echo "glupy : $BUILD_GLUPY"
+echo "Run with Valgrind : $VALGRIND_TOOL"
+echo "Sanitizer enabled : $SANITIZER"
echo "Use syslog : $USE_SYSLOG"
echo "XML output : $BUILD_XML_OUTPUT"
-echo "QEMU Block formats : $BUILD_QEMU_BLOCK"
-echo "Encryption xlator : $BUILD_CRYPT_XLATOR"
echo "Unit Tests : $BUILD_UNITTEST"
+echo "Track priv ports : $TRACK_PRIVPORTS"
echo "POSIX ACLs : $BUILD_POSIX_ACLS"
-echo "Data Classification : $BUILD_GFDB"
+echo "SELinux features : $USE_SELINUX"
echo "firewalld-config : $BUILD_FIREWALLD"
+echo "Events : $BUILD_EVENTS"
+echo "EC dynamic support : $EC_DYNAMIC_SUPPORT"
+echo "Use memory pools : $USE_MEMPOOL"
+echo "Nanosecond m/atimes : $BUILD_NANOSECOND_TIMESTAMPS"
+echo "Server components : $with_server"
+echo "Legacy gNFS server : $BUILD_GNFS"
+echo "IPV6 default : $with_ipv6_default"
+echo "Use TIRPC : $with_libtirpc"
+echo "With Python : ${PYTHON_VERSION}"
+echo "Cloudsync : $BUILD_CLOUDSYNC"
+echo "Metadata dispersal : $BUILD_METADISP"
+echo "Link with TCMALLOC : $BUILD_TCMALLOC"
echo
+
+# dnl Note: ${X^^} capitalization assumes bash >= 4.x
+if test "x$SANITIZER" != "xnone"; then
+ echo "Note: since glusterfs processes are daemon processes, use"
+ echo "'export ${SANITIZER^^}_OPTIONS=log_path=/path/to/xxx.log' to collect"
+ echo "sanitizer output. Further details and more options can be"
+ echo "found at https://github.com/google/sanitizers."
+fi
diff --git a/contrib/argp-standalone/Makefile.am b/contrib/argp-standalone/Makefile.am
deleted file mode 100644
index 4775d4876aa..00000000000
--- a/contrib/argp-standalone/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-# From glibc
-
-# Copyright (C) 1997, 2003, 2004 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 Library General Public License as
-# published by the Free Software Foundation; either version 2 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
-# Library General Public License for more details.
-
-# You should have received a copy of the GNU Library General Public
-# License along with the GNU C Library; see the file COPYING.LIB. If
-# not, write to the Free Software Foundation, Inc.,
-# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-AUTOMAKE_OPTIONS = foreign
-SUBDIRS = .
-
-LIBOBJS = @LIBOBJS@
-
-noinst_LIBRARIES = libargp.a
-
-noinst_HEADERS = argp.h argp-fmtstream.h argp-namefrob.h
-
-EXTRA_DIST = mempcpy.c strchrnul.c strndup.c strcasecmp.c vsnprintf.c autogen.sh
-
-# Leaves out argp-fs-xinl.c and argp-xinl.c
-libargp_a_SOURCES = argp-ba.c argp-eexst.c argp-fmtstream.c \
- argp-help.c argp-parse.c argp-pv.c \
- argp-pvh.c
-
-libargp_a_LIBADD = $(LIBOBJS)
-
-
diff --git a/contrib/argp-standalone/acinclude.m4 b/contrib/argp-standalone/acinclude.m4
deleted file mode 100644
index fb61e957dfa..00000000000
--- a/contrib/argp-standalone/acinclude.m4
+++ /dev/null
@@ -1,1084 +0,0 @@
-dnl Try to detect the type of the third arg to getsockname() et al
-AC_DEFUN([LSH_TYPE_SOCKLEN_T],
-[AH_TEMPLATE([socklen_t], [Length type used by getsockopt])
-AC_CACHE_CHECK([for socklen_t in sys/socket.h], ac_cv_type_socklen_t,
-[AC_EGREP_HEADER(socklen_t, sys/socket.h,
- [ac_cv_type_socklen_t=yes], [ac_cv_type_socklen_t=no])])
-if test $ac_cv_type_socklen_t = no; then
- AC_MSG_CHECKING(for AIX)
- AC_EGREP_CPP(yes, [
-#ifdef _AIX
- yes
-#endif
-],[
-AC_MSG_RESULT(yes)
-AC_DEFINE(socklen_t, size_t)
-],[
-AC_MSG_RESULT(no)
-AC_DEFINE(socklen_t, int)
-])
-fi
-])
-
-dnl Choose cc flags for compiling position independent code
-AC_DEFUN([LSH_CCPIC],
-[AC_MSG_CHECKING(CCPIC)
-AC_CACHE_VAL(lsh_cv_sys_ccpic,[
- if test -z "$CCPIC" ; then
- if test "$GCC" = yes ; then
- case `uname -sr` in
- BSD/OS*)
- case `uname -r` in
- 4.*) CCPIC="-fPIC";;
- *) CCPIC="";;
- esac
- ;;
- Darwin*)
- CCPIC="-fPIC"
- ;;
- SunOS\ 5.*)
- # Could also use -fPIC, if there are a large number of symbol reference
- CCPIC="-fPIC"
- ;;
- CYGWIN*)
- CCPIC=""
- ;;
- *)
- CCPIC="-fpic"
- ;;
- esac
- else
- case `uname -sr` in
- Darwin*)
- CCPIC="-fPIC"
- ;;
- IRIX*)
- CCPIC="-share"
- ;;
- hp*|HP*) CCPIC="+z"; ;;
- FreeBSD*) CCPIC="-fpic";;
- SCO_SV*) CCPIC="-KPIC -dy -Bdynamic";;
- UnixWare*|OpenUNIX*) CCPIC="-KPIC -dy -Bdynamic";;
- Solaris*) CCPIC="-KPIC -Bdynamic";;
- Windows_NT*) CCPIC="-shared" ;;
- esac
- fi
- fi
- OLD_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $CCPIC"
- AC_TRY_COMPILE([], [exit(0);],
- lsh_cv_sys_ccpic="$CCPIC", lsh_cv_sys_ccpic='')
- CFLAGS="$OLD_CFLAGS"
-])
-CCPIC="$lsh_cv_sys_ccpic"
-AC_MSG_RESULT($CCPIC)
-AC_SUBST([CCPIC])])
-
-dnl LSH_PATH_ADD(path-id, directory)
-AC_DEFUN([LSH_PATH_ADD],
-[AC_MSG_CHECKING($2)
-ac_exists=no
-if test -d "$2/." ; then
- ac_real_dir=`cd $2 && pwd`
- if test -n "$ac_real_dir" ; then
- ac_exists=yes
- for old in $1_REAL_DIRS ; do
- ac_found=no
- if test x$ac_real_dir = x$old ; then
- ac_found=yes;
- break;
- fi
- done
- if test $ac_found = yes ; then
- AC_MSG_RESULT(already added)
- else
- AC_MSG_RESULT(added)
- # LDFLAGS="$LDFLAGS -L $2"
- $1_REAL_DIRS="$ac_real_dir [$]$1_REAL_DIRS"
- $1_DIRS="$2 [$]$1_DIRS"
- fi
- fi
-fi
-if test $ac_exists = no ; then
- AC_MSG_RESULT(not found)
-fi
-])
-
-dnl LSH_RPATH_ADD(dir)
-AC_DEFUN([LSH_RPATH_ADD], [LSH_PATH_ADD(RPATH_CANDIDATE, $1)])
-
-dnl LSH_RPATH_INIT(candidates)
-AC_DEFUN([LSH_RPATH_INIT],
-[AC_MSG_CHECKING([for -R flag])
-RPATHFLAG=''
-case `uname -sr` in
- OSF1\ V4.*)
- RPATHFLAG="-rpath "
- ;;
- IRIX\ 6.*)
- RPATHFLAG="-rpath "
- ;;
- IRIX\ 5.*)
- RPATHFLAG="-rpath "
- ;;
- SunOS\ 5.*)
- if test "$TCC" = "yes"; then
- # tcc doesn't know about -R
- RPATHFLAG="-Wl,-R,"
- else
- RPATHFLAG=-R
- fi
- ;;
- Linux\ 2.*)
- RPATHFLAG="-Wl,-rpath,"
- ;;
- *)
- :
- ;;
-esac
-
-if test x$RPATHFLAG = x ; then
- AC_MSG_RESULT(none)
-else
- AC_MSG_RESULT([using $RPATHFLAG])
-fi
-
-RPATH_CANDIDATE_REAL_DIRS=''
-RPATH_CANDIDATE_DIRS=''
-
-AC_MSG_RESULT([Searching for libraries])
-
-for d in $1 ; do
- LSH_RPATH_ADD($d)
-done
-])
-
-dnl Try to execute a main program, and if it fails, try adding some
-dnl -R flag.
-dnl LSH_RPATH_FIX
-AC_DEFUN([LSH_RPATH_FIX],
-[if test $cross_compiling = no -a "x$RPATHFLAG" != x ; then
- ac_success=no
- AC_TRY_RUN([int main(int argc, char **argv) { return 0; }],
- ac_success=yes, ac_success=no, :)
-
- if test $ac_success = no ; then
- AC_MSG_CHECKING([Running simple test program failed. Trying -R flags])
-dnl echo RPATH_CANDIDATE_DIRS = $RPATH_CANDIDATE_DIRS
- ac_remaining_dirs=''
- ac_rpath_save_LDFLAGS="$LDFLAGS"
- for d in $RPATH_CANDIDATE_DIRS ; do
- if test $ac_success = yes ; then
- ac_remaining_dirs="$ac_remaining_dirs $d"
- else
- LDFLAGS="$RPATHFLAG$d $LDFLAGS"
-dnl echo LDFLAGS = $LDFLAGS
- AC_TRY_RUN([int main(int argc, char **argv) { return 0; }],
- [ac_success=yes
- ac_rpath_save_LDFLAGS="$LDFLAGS"
- AC_MSG_RESULT([adding $RPATHFLAG$d])
- ],
- [ac_remaining_dirs="$ac_remaining_dirs $d"], :)
- LDFLAGS="$ac_rpath_save_LDFLAGS"
- fi
- done
- RPATH_CANDIDATE_DIRS=$ac_remaining_dirs
- fi
- if test $ac_success = no ; then
- AC_MSG_RESULT(failed)
- fi
-fi
-])
-
-dnl Like AC_CHECK_LIB, but uses $KRB_LIBS rather than $LIBS.
-dnl LSH_CHECK_KRB_LIB(LIBRARY, FUNCTION, [, ACTION-IF-FOUND [,
-dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
-
-AC_DEFUN([LSH_CHECK_KRB_LIB],
-[AC_CHECK_LIB([$1], [$2],
- ifelse([$3], ,
- [[ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- AC_DEFINE_UNQUOTED($ac_tr_lib)
- KRB_LIBS="-l$1 $KRB_LIBS"
- ]], [$3]),
- ifelse([$4], , , [$4
-])dnl
-, [$5 $KRB_LIBS])
-])
-
-dnl LSH_LIB_ARGP(ACTION-IF-OK, ACTION-IF-BAD)
-AC_DEFUN([LSH_LIB_ARGP],
-[ ac_argp_save_LIBS="$LIBS"
- ac_argp_save_LDFLAGS="$LDFLAGS"
- ac_argp_ok=no
- # First check if we can link with argp.
- AC_SEARCH_LIBS(argp_parse, argp,
- [ LSH_RPATH_FIX
- AC_CACHE_CHECK([for working argp],
- lsh_cv_lib_argp_works,
- [ AC_TRY_RUN(
-[#include <argp.h>
-#include <stdlib.h>
-
-static const struct argp_option
-options[] =
-{
- { NULL, 0, NULL, 0, NULL, 0 }
-};
-
-struct child_state
-{
- int n;
-};
-
-static error_t
-child_parser(int key, char *arg, struct argp_state *state)
-{
- struct child_state *input = (struct child_state *) state->input;
-
- switch(key)
- {
- default:
- return ARGP_ERR_UNKNOWN;
- case ARGP_KEY_END:
- if (!input->n)
- input->n = 1;
- break;
- }
- return 0;
-}
-
-const struct argp child_argp =
-{
- options,
- child_parser,
- NULL, NULL, NULL, NULL, NULL
-};
-
-struct main_state
-{
- struct child_state child;
- int m;
-};
-
-static error_t
-main_parser(int key, char *arg, struct argp_state *state)
-{
- struct main_state *input = (struct main_state *) state->input;
-
- switch(key)
- {
- default:
- return ARGP_ERR_UNKNOWN;
- case ARGP_KEY_INIT:
- state->child_inputs[0] = &input->child;
- break;
- case ARGP_KEY_END:
- if (!input->m)
- input->m = input->child.n;
-
- break;
- }
- return 0;
-}
-
-static const struct argp_child
-main_children[] =
-{
- { &child_argp, 0, "", 0 },
- { NULL, 0, NULL, 0}
-};
-
-static const struct argp
-main_argp =
-{ options, main_parser,
- NULL,
- NULL,
- main_children,
- NULL, NULL
-};
-
-int main(int argc, char **argv)
-{
- struct main_state input = { { 0 }, 0 };
- char *v[2] = { "foo", NULL };
-
- argp_parse(&main_argp, 1, v, 0, NULL, &input);
-
- if ( (input.m == 1) && (input.child.n == 1) )
- return 0;
- else
- return 1;
-}
-], lsh_cv_lib_argp_works=yes,
- lsh_cv_lib_argp_works=no,
- lsh_cv_lib_argp_works=no)])
-
- if test x$lsh_cv_lib_argp_works = xyes ; then
- ac_argp_ok=yes
- else
- # Reset link flags
- LIBS="$ac_argp_save_LIBS"
- LDFLAGS="$ac_argp_save_LDFLAGS"
- fi])
-
- if test x$ac_argp_ok = xyes ; then
- ifelse([$1],, true, [$1])
- else
- ifelse([$2],, true, [$2])
- fi
-])
-
-dnl LSH_GCC_ATTRIBUTES
-dnl Check for gcc's __attribute__ construction
-
-AC_DEFUN([LSH_GCC_ATTRIBUTES],
-[AC_CACHE_CHECK(for __attribute__,
- lsh_cv_c_attribute,
-[ AC_TRY_COMPILE([
-#include <stdlib.h>
-],
-[
-static void foo(void) __attribute__ ((noreturn));
-
-static void __attribute__ ((noreturn))
-foo(void)
-{
- exit(1);
-}
-],
-lsh_cv_c_attribute=yes,
-lsh_cv_c_attribute=no)])
-
-AH_TEMPLATE([HAVE_GCC_ATTRIBUTE], [Define if the compiler understands __attribute__])
-if test "x$lsh_cv_c_attribute" = "xyes"; then
- AC_DEFINE(HAVE_GCC_ATTRIBUTE)
-fi
-
-AH_BOTTOM(
-[#if __GNUC__ || HAVE_GCC_ATTRIBUTE
-# define NORETURN __attribute__ ((__noreturn__))
-# define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a)))
-# define UNUSED __attribute__ ((__unused__))
-#else
-# define NORETURN
-# define PRINTF_STYLE(f, a)
-# define UNUSED
-#endif
-])])
-
-AC_DEFUN([LSH_GCC_FUNCTION_NAME],
-[# Check for gcc's __FUNCTION__ variable
-AH_TEMPLATE([HAVE_GCC_FUNCTION],
- [Define if the compiler understands __FUNCTION__])
-AH_BOTTOM(
-[#if HAVE_GCC_FUNCTION
-# define FUNCTION_NAME __FUNCTION__
-#else
-# define FUNCTION_NAME "Unknown"
-#endif
-])
-
-AC_CACHE_CHECK(for __FUNCTION__,
- lsh_cv_c_FUNCTION,
- [ AC_TRY_COMPILE(,
- [ #if __GNUC__ == 3
- # error __FUNCTION__ is broken in gcc-3
- #endif
- void foo(void) { char c = __FUNCTION__[0]; } ],
- lsh_cv_c_FUNCTION=yes,
- lsh_cv_c_FUNCTION=no)])
-
-if test "x$lsh_cv_c_FUNCTION" = "xyes"; then
- AC_DEFINE(HAVE_GCC_FUNCTION)
-fi
-])
-
-# Check for alloca, and include the standard blurb in config.h
-AC_DEFUN([LSH_FUNC_ALLOCA],
-[AC_FUNC_ALLOCA
-AC_CHECK_HEADERS([malloc.h])
-AH_BOTTOM(
-[/* AIX requires this to be the first thing in the file. */
-#ifndef __GNUC__
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifdef _AIX
- #pragma alloca
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-# endif
-# endif
-# endif
-#else /* defined __GNUC__ */
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# endif
-#endif
-/* Needed for alloca on windows */
-#if HAVE_MALLOC_H
-# include <malloc.h>
-#endif
-])])
-
-AC_DEFUN([LSH_FUNC_STRERROR],
-[AC_CHECK_FUNCS(strerror)
-AH_BOTTOM(
-[#if HAVE_STRERROR
-#define STRERROR strerror
-#else
-#define STRERROR(x) (sys_errlist[x])
-#endif
-])])
-
-AC_DEFUN([LSH_FUNC_STRSIGNAL],
-[AC_CHECK_FUNCS(strsignal)
-AC_CHECK_DECLS([sys_siglist, _sys_siglist])
-AH_BOTTOM(
-[#if HAVE_STRSIGNAL
-# define STRSIGNAL strsignal
-#else /* !HAVE_STRSIGNAL */
-# if HAVE_DECL_SYS_SIGLIST
-# define STRSIGNAL(x) (sys_siglist[x])
-# else
-# if HAVE_DECL__SYS_SIGLIST
-# define STRSIGNAL(x) (_sys_siglist[x])
-# else
-# define STRSIGNAL(x) "Unknown signal"
-# if __GNUC__
-# warning Using dummy STRSIGNAL
-# endif
-# endif
-# endif
-#endif /* !HAVE_STRSIGNAL */
-])])
-
-dnl LSH_MAKE_CONDITIONAL(symbol, test)
-AC_DEFUN([LSH_MAKE_CONDITIONAL],
-[if $2 ; then
- IF_$1=''
- UNLESS_$1='# '
-else
- IF_$1='# '
- UNLESS_$1=''
-fi
-AC_SUBST(IF_$1)
-AC_SUBST(UNLESS_$1)])
-
-dnl LSH_DEPENDENCY_TRACKING
-
-dnl Defines compiler flags DEP_FLAGS to generate dependency
-dnl information, and DEP_PROCESS that is any shell commands needed for
-dnl massaging the dependency information further. Dependencies are
-dnl generated as a side effect of compilation. Dependency files
-dnl themselves are not treated as targets.
-
-AC_DEFUN([LSH_DEPENDENCY_TRACKING],
-[AC_ARG_ENABLE(dependency_tracking,
- AC_HELP_STRING([--disable-dependency-tracking],
- [Disable dependency tracking. Dependency tracking doesn't work with BSD make]),,
- [enable_dependency_tracking=yes])
-
-DEP_FLAGS=''
-DEP_PROCESS='true'
-if test x$enable_dependency_tracking = xyes ; then
- if test x$GCC = xyes ; then
- gcc_version=`gcc --version | head -1`
- case "$gcc_version" in
- 2.*|*[[!0-9.]]2.*)
- enable_dependency_tracking=no
- AC_MSG_WARN([Dependency tracking disabled, gcc-3.x is needed])
- ;;
- *)
- DEP_FLAGS='-MT $[]@ -MD -MP -MF $[]@.d'
- DEP_PROCESS='true'
- ;;
- esac
- else
- enable_dependency_tracking=no
- AC_MSG_WARN([Dependency tracking disabled])
- fi
-fi
-
-if test x$enable_dependency_tracking = xyes ; then
- DEP_INCLUDE='include '
-else
- DEP_INCLUDE='# '
-fi
-
-AC_SUBST([DEP_INCLUDE])
-AC_SUBST([DEP_FLAGS])
-AC_SUBST([DEP_PROCESS])])
-
-dnl @synopsis AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEADERS-TO-CHECK])]
-dnl
-dnl the "ISO C9X: 7.18 Integer types <stdint.h>" section requires the
-dnl existence of an include file <stdint.h> that defines a set of
-dnl typedefs, especially uint8_t,int32_t,uintptr_t.
-dnl Many older installations will not provide this file, but some will
-dnl have the very same definitions in <inttypes.h>. In other enviroments
-dnl we can use the inet-types in <sys/types.h> which would define the
-dnl typedefs int8_t and u_int8_t respectivly.
-dnl
-dnl This macros will create a local "_stdint.h" or the headerfile given as
-dnl an argument. In many cases that file will just "#include <stdint.h>"
-dnl or "#include <inttypes.h>", while in other environments it will provide
-dnl the set of basic 'stdint's definitions/typedefs:
-dnl int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t
-dnl int_least32_t.. int_fast32_t.. intmax_t
-dnl which may or may not rely on the definitions of other files,
-dnl or using the AC_CHECK_SIZEOF macro to determine the actual
-dnl sizeof each type.
-dnl
-dnl if your header files require the stdint-types you will want to create an
-dnl installable file mylib-int.h that all your other installable header
-dnl may include. So if you have a library package named "mylib", just use
-dnl AX_CREATE_STDINT_H(mylib-int.h)
-dnl in configure.ac and go to install that very header file in Makefile.am
-dnl along with the other headers (mylib.h) - and the mylib-specific headers
-dnl can simply use "#include <mylib-int.h>" to obtain the stdint-types.
-dnl
-dnl Remember, if the system already had a valid <stdint.h>, the generated
-dnl file will include it directly. No need for fuzzy HAVE_STDINT_H things...
-dnl
-dnl @, (status: used on new platforms) (see http://ac-archive.sf.net/gstdint/)
-dnl @version $Id: acinclude.m4,v 1.27 2004/11/23 21:27:35 nisse Exp $
-dnl @author Guido Draheim <guidod@gmx.de>
-
-AC_DEFUN([AX_CREATE_STDINT_H],
-[# ------ AX CREATE STDINT H -------------------------------------
-AC_MSG_CHECKING([for stdint types])
-ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)`
-# try to shortcircuit - if the default include path of the compiler
-# can find a "stdint.h" header then we assume that all compilers can.
-AC_CACHE_VAL([ac_cv_header_stdint_t],[
-old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS=""
-old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS=""
-old_CFLAGS="$CFLAGS" ; CFLAGS=""
-AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;],
-[ac_cv_stdint_result="(assuming C99 compatible system)"
- ac_cv_header_stdint_t="stdint.h"; ],
-[ac_cv_header_stdint_t=""])
-CXXFLAGS="$old_CXXFLAGS"
-CPPFLAGS="$old_CPPFLAGS"
-CFLAGS="$old_CFLAGS" ])
-
-v="... $ac_cv_header_stdint_h"
-if test "$ac_stdint_h" = "stdint.h" ; then
- AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)])
-elif test "$ac_stdint_h" = "inttypes.h" ; then
- AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)])
-elif test "_$ac_cv_header_stdint_t" = "_" ; then
- AC_MSG_RESULT([(putting them into $ac_stdint_h)$v])
-else
- ac_cv_header_stdint="$ac_cv_header_stdint_t"
- AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)])
-fi
-
-if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit..
-
-dnl .....intro message done, now do a few system checks.....
-dnl btw, all CHECK_TYPE macros do automatically "DEFINE" a type, therefore
-dnl we use the autoconf implementation detail _AC CHECK_TYPE_NEW instead
-
-inttype_headers=`echo $2 | sed -e 's/,/ /g'`
-
-ac_cv_stdint_result="(no helpful system typedefs seen)"
-AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[
- ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h)
- AC_MSG_RESULT([(..)])
- for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do
- unset ac_cv_type_uintptr_t
- unset ac_cv_type_uint64_t
- _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl
- continue,[#include <$i>])
- AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
- ac_cv_stdint_result="(seen uintptr_t$and64 in $i)"
- break;
- done
- AC_MSG_CHECKING([for stdint uintptr_t])
- ])
-
-if test "_$ac_cv_header_stdint_x" = "_" ; then
-AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[
- ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h)
- AC_MSG_RESULT([(..)])
- for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do
- unset ac_cv_type_uint32_t
- unset ac_cv_type_uint64_t
- AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl
- continue,[#include <$i>])
- AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
- ac_cv_stdint_result="(seen uint32_t$and64 in $i)"
- break;
- done
- AC_MSG_CHECKING([for stdint uint32_t])
- ])
-fi
-
-if test "_$ac_cv_header_stdint_x" = "_" ; then
-if test "_$ac_cv_header_stdint_o" = "_" ; then
-AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[
- ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h)
- AC_MSG_RESULT([(..)])
- for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do
- unset ac_cv_type_u_int32_t
- unset ac_cv_type_u_int64_t
- AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl
- continue,[#include <$i>])
- AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>])
- ac_cv_stdint_result="(seen u_int32_t$and64 in $i)"
- break;
- done
- AC_MSG_CHECKING([for stdint u_int32_t])
- ])
-fi fi
-
-dnl if there was no good C99 header file, do some typedef checks...
-if test "_$ac_cv_header_stdint_x" = "_" ; then
- AC_MSG_CHECKING([for stdint datatype model])
- AC_MSG_RESULT([(..)])
- AC_CHECK_SIZEOF(char)
- AC_CHECK_SIZEOF(short)
- AC_CHECK_SIZEOF(int)
- AC_CHECK_SIZEOF(long)
- AC_CHECK_SIZEOF(void*)
- ac_cv_stdint_char_model=""
- ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char"
- ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short"
- ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int"
- ac_cv_stdint_long_model=""
- ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int"
- ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long"
- ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp"
- name="$ac_cv_stdint_long_model"
- case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in
- 122/242) name="$name, IP16 (standard 16bit machine)" ;;
- 122/244) name="$name, LP32 (standard 32bit mac/win)" ;;
- 122/*) name="$name (unusual int16 model)" ;;
- 124/444) name="$name, ILP32 (standard 32bit unixish)" ;;
- 124/488) name="$name, LP64 (standard 64bit unixish)" ;;
- 124/448) name="$name, LLP64 (unusual 64bit unixish)" ;;
- 124/*) name="$name (unusual int32 model)" ;;
- 128/888) name="$name, ILP64 (unusual 64bit numeric)" ;;
- 128/*) name="$name (unusual int64 model)" ;;
- 222/*|444/*) name="$name (unusual dsptype)" ;;
- *) name="$name (very unusal model)" ;;
- esac
- AC_MSG_RESULT([combined for stdint datatype model... $name])
-fi
-
-if test "_$ac_cv_header_stdint_x" != "_" ; then
- ac_cv_header_stdint="$ac_cv_header_stdint_x"
-elif test "_$ac_cv_header_stdint_o" != "_" ; then
- ac_cv_header_stdint="$ac_cv_header_stdint_o"
-elif test "_$ac_cv_header_stdint_u" != "_" ; then
- ac_cv_header_stdint="$ac_cv_header_stdint_u"
-else
- ac_cv_header_stdint="stddef.h"
-fi
-
-AC_MSG_CHECKING([for extra inttypes in chosen header])
-AC_MSG_RESULT([($ac_cv_header_stdint)])
-dnl see if int_least and int_fast types are present in _this_ header.
-unset ac_cv_type_int_least32_t
-unset ac_cv_type_int_fast32_t
-AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>])
-AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>])
-AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>])
-
-fi # shortcircut to system "stdint.h"
-# ------------------ PREPARE VARIABLES ------------------------------
-if test "$GCC" = "yes" ; then
-ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1`
-else
-ac_cv_stdint_message="using $CC"
-fi
-
-AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl
-$ac_cv_stdint_result])
-
-# ----------------- DONE inttypes.h checks START header -------------
-AC_CONFIG_COMMANDS([$ac_stdint_h],[
-AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h)
-ac_stdint=$tmp/_stdint.h
-
-echo "#ifndef" $_ac_stdint_h >$ac_stdint
-echo "#define" $_ac_stdint_h "1" >>$ac_stdint
-echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint
-echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint
-echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint
-if test "_$ac_cv_header_stdint_t" != "_" ; then
-echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint
-fi
-
-cat >>$ac_stdint <<STDINT_EOF
-
-/* ................... shortcircuit part ........................... */
-
-#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
-#include <stdint.h>
-#else
-#include <stddef.h>
-
-/* .................... configured part ............................ */
-
-STDINT_EOF
-
-echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint
-if test "_$ac_cv_header_stdint_x" != "_" ; then
- ac_header="$ac_cv_header_stdint_x"
- echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint
-else
- echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint
-fi
-
-echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint
-if test "_$ac_cv_header_stdint_o" != "_" ; then
- ac_header="$ac_cv_header_stdint_o"
- echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint
-else
- echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint
-fi
-
-echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint
-if test "_$ac_cv_header_stdint_u" != "_" ; then
- ac_header="$ac_cv_header_stdint_u"
- echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint
-else
- echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint
-fi
-
-echo "" >>$ac_stdint
-
-if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then
- echo "#include <$ac_header>" >>$ac_stdint
- echo "" >>$ac_stdint
-fi fi
-
-echo "/* which 64bit typedef has been found */" >>$ac_stdint
-if test "$ac_cv_type_uint64_t" = "yes" ; then
-echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint
-else
-echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint
-fi
-if test "$ac_cv_type_u_int64_t" = "yes" ; then
-echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint
-else
-echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint
-fi
-echo "" >>$ac_stdint
-
-echo "/* which type model has been detected */" >>$ac_stdint
-if test "_$ac_cv_stdint_char_model" != "_" ; then
-echo "#define _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint
-echo "#define _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint
-else
-echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint
-echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint
-fi
-echo "" >>$ac_stdint
-
-echo "/* whether int_least types were detected */" >>$ac_stdint
-if test "$ac_cv_type_int_least32_t" = "yes"; then
-echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint
-else
-echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint
-fi
-echo "/* whether int_fast types were detected */" >>$ac_stdint
-if test "$ac_cv_type_int_fast32_t" = "yes"; then
-echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint
-else
-echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint
-fi
-echo "/* whether intmax_t type was detected */" >>$ac_stdint
-if test "$ac_cv_type_intmax_t" = "yes"; then
-echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint
-else
-echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint
-fi
-echo "" >>$ac_stdint
-
- cat >>$ac_stdint <<STDINT_EOF
-/* .................... detections part ............................ */
-
-/* whether we need to define bitspecific types from compiler base types */
-#ifndef _STDINT_HEADER_INTPTR
-#ifndef _STDINT_HEADER_UINT32
-#ifndef _STDINT_HEADER_U_INT32
-#define _STDINT_NEED_INT_MODEL_T
-#else
-#define _STDINT_HAVE_U_INT_TYPES
-#endif
-#endif
-#endif
-
-#ifdef _STDINT_HAVE_U_INT_TYPES
-#undef _STDINT_NEED_INT_MODEL_T
-#endif
-
-#ifdef _STDINT_CHAR_MODEL
-#if _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
-#ifndef _STDINT_BYTE_MODEL
-#define _STDINT_BYTE_MODEL 12
-#endif
-#endif
-#endif
-
-#ifndef _STDINT_HAVE_INT_LEAST32_T
-#define _STDINT_NEED_INT_LEAST_T
-#endif
-
-#ifndef _STDINT_HAVE_INT_FAST32_T
-#define _STDINT_NEED_INT_FAST_T
-#endif
-
-#ifndef _STDINT_HEADER_INTPTR
-#define _STDINT_NEED_INTPTR_T
-#ifndef _STDINT_HAVE_INTMAX_T
-#define _STDINT_NEED_INTMAX_T
-#endif
-#endif
-
-
-/* .................... definition part ............................ */
-
-/* some system headers have good uint64_t */
-#ifndef _HAVE_UINT64_T
-#if defined _STDINT_HAVE_UINT64_T || defined HAVE_UINT64_T
-#define _HAVE_UINT64_T
-#elif defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
-#define _HAVE_UINT64_T
-typedef u_int64_t uint64_t;
-#endif
-#endif
-
-#ifndef _HAVE_UINT64_T
-/* .. here are some common heuristics using compiler runtime specifics */
-#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
-#define _HAVE_UINT64_T
-typedef long long int64_t;
-typedef unsigned long long uint64_t;
-
-#elif !defined __STRICT_ANSI__
-#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
-#define _HAVE_UINT64_T
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-
-#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
-/* note: all ELF-systems seem to have loff-support which needs 64-bit */
-#if !defined _NO_LONGLONG
-#define _HAVE_UINT64_T
-typedef long long int64_t;
-typedef unsigned long long uint64_t;
-#endif
-
-#elif defined __alpha || (defined __mips && defined _ABIN32)
-#if !defined _NO_LONGLONG
-typedef long int64_t;
-typedef unsigned long uint64_t;
-#endif
- /* compiler/cpu type to define int64_t */
-#endif
-#endif
-#endif
-
-#if defined _STDINT_HAVE_U_INT_TYPES
-/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
-typedef u_int8_t uint8_t;
-typedef u_int16_t uint16_t;
-typedef u_int32_t uint32_t;
-
-/* glibc compatibility */
-#ifndef __int8_t_defined
-#define __int8_t_defined
-#endif
-#endif
-
-#ifdef _STDINT_NEED_INT_MODEL_T
-/* we must guess all the basic types. Apart from byte-adressable system, */
-/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */
-/* (btw, those nibble-addressable systems are way off, or so we assume) */
-
-dnl /* have a look at "64bit and data size neutrality" at */
-dnl /* http://unix.org/version2/whatsnew/login_64bit.html */
-dnl /* (the shorthand "ILP" types always have a "P" part) */
-
-#if defined _STDINT_BYTE_MODEL
-#if _STDINT_LONG_MODEL+0 == 242
-/* 2:4:2 = IP16 = a normal 16-bit system */
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned long uint32_t;
-#ifndef __int8_t_defined
-#define __int8_t_defined
-typedef char int8_t;
-typedef short int16_t;
-typedef long int32_t;
-#endif
-#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444
-/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */
-/* 4:4:4 = ILP32 = a normal 32-bit system */
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-#ifndef __int8_t_defined
-#define __int8_t_defined
-typedef char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-#endif
-#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488
-/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */
-/* 4:8:8 = LP64 = a normal 64-bit system */
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-#ifndef __int8_t_defined
-#define __int8_t_defined
-typedef char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-#endif
-/* this system has a "long" of 64bit */
-#ifndef _HAVE_UINT64_T
-#define _HAVE_UINT64_T
-typedef unsigned long uint64_t;
-typedef long int64_t;
-#endif
-#elif _STDINT_LONG_MODEL+0 == 448
-/* LLP64 a 64-bit system derived from a 32-bit system */
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-#ifndef __int8_t_defined
-#define __int8_t_defined
-typedef char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-#endif
-/* assuming the system has a "long long" */
-#ifndef _HAVE_UINT64_T
-#define _HAVE_UINT64_T
-typedef unsigned long long uint64_t;
-typedef long long int64_t;
-#endif
-#else
-#define _STDINT_NO_INT32_T
-#endif
-#else
-#define _STDINT_NO_INT8_T
-#define _STDINT_NO_INT32_T
-#endif
-#endif
-
-/*
- * quote from SunOS-5.8 sys/inttypes.h:
- * Use at your own risk. As of February 1996, the committee is squarely
- * behind the fixed sized types; the "least" and "fast" types are still being
- * discussed. The probability that the "fast" types may be removed before
- * the standard is finalized is high enough that they are not currently
- * implemented.
- */
-
-#if defined _STDINT_NEED_INT_LEAST_T
-typedef int8_t int_least8_t;
-typedef int16_t int_least16_t;
-typedef int32_t int_least32_t;
-#ifdef _HAVE_UINT64_T
-typedef int64_t int_least64_t;
-#endif
-
-typedef uint8_t uint_least8_t;
-typedef uint16_t uint_least16_t;
-typedef uint32_t uint_least32_t;
-#ifdef _HAVE_UINT64_T
-typedef uint64_t uint_least64_t;
-#endif
- /* least types */
-#endif
-
-#if defined _STDINT_NEED_INT_FAST_T
-typedef int8_t int_fast8_t;
-typedef int int_fast16_t;
-typedef int32_t int_fast32_t;
-#ifdef _HAVE_UINT64_T
-typedef int64_t int_fast64_t;
-#endif
-
-typedef uint8_t uint_fast8_t;
-typedef unsigned uint_fast16_t;
-typedef uint32_t uint_fast32_t;
-#ifdef _HAVE_UINT64_T
-typedef uint64_t uint_fast64_t;
-#endif
- /* fast types */
-#endif
-
-#ifdef _STDINT_NEED_INTMAX_T
-#ifdef _HAVE_UINT64_T
-typedef int64_t intmax_t;
-typedef uint64_t uintmax_t;
-#else
-typedef long intmax_t;
-typedef unsigned long uintmax_t;
-#endif
-#endif
-
-#ifdef _STDINT_NEED_INTPTR_T
-#ifndef __intptr_t_defined
-#define __intptr_t_defined
-/* we encourage using "long" to store pointer values, never use "int" ! */
-#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484
-typedef unsinged int uintptr_t;
-typedef int intptr_t;
-#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444
-typedef unsigned long uintptr_t;
-typedef long intptr_t;
-#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T
-typedef uint64_t uintptr_t;
-typedef int64_t intptr_t;
-#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */
-typedef unsigned long uintptr_t;
-typedef long intptr_t;
-#endif
-#endif
-#endif
-
- /* shortcircuit*/
-#endif
- /* once */
-#endif
-#endif
-STDINT_EOF
- if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then
- AC_MSG_NOTICE([$ac_stdint_h is unchanged])
- else
- ac_dir=`AS_DIRNAME(["$ac_stdint_h"])`
- AS_MKDIR_P(["$ac_dir"])
- rm -f $ac_stdint_h
- mv $ac_stdint $ac_stdint_h
- fi
-],[# variables for create stdint.h replacement
-PACKAGE="$PACKAGE"
-VERSION="$VERSION"
-ac_stdint_h="$ac_stdint_h"
-_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h)
-ac_cv_stdint_message="$ac_cv_stdint_message"
-ac_cv_header_stdint_t="$ac_cv_header_stdint_t"
-ac_cv_header_stdint_x="$ac_cv_header_stdint_x"
-ac_cv_header_stdint_o="$ac_cv_header_stdint_o"
-ac_cv_header_stdint_u="$ac_cv_header_stdint_u"
-ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
-ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
-ac_cv_stdint_char_model="$ac_cv_stdint_char_model"
-ac_cv_stdint_long_model="$ac_cv_stdint_long_model"
-ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
-ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
-ac_cv_type_intmax_t="$ac_cv_type_intmax_t"
-])
-])
diff --git a/contrib/argp-standalone/argp-ba.c b/contrib/argp-standalone/argp-ba.c
deleted file mode 100644
index 0d3958c1151..00000000000
--- a/contrib/argp-standalone/argp-ba.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
- Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* If set by the user program, it should point to string that is the
- bug-reporting address for the program. It will be printed by argp_help if
- the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help
- messages), embedded in a sentence that says something like `Report bugs to
- ADDR.'. */
-const char *argp_program_bug_address = 0;
diff --git a/contrib/argp-standalone/argp-eexst.c b/contrib/argp-standalone/argp-eexst.c
deleted file mode 100644
index 46b27847ad4..00000000000
--- a/contrib/argp-standalone/argp-eexst.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Default definition for ARGP_ERR_EXIT_STATUS
- Copyright (C) 1997 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if HAVE_SYSEXITS_H
-# include <sysexits.h>
-#else
-# define EX_USAGE 64
-#endif
-
-#include "argp.h"
-
-/* The exit status that argp will use when exiting due to a parsing error.
- If not defined or set by the user program, this defaults to EX_USAGE from
- <sysexits.h>. */
-error_t argp_err_exit_status = EX_USAGE;
diff --git a/contrib/argp-standalone/argp-fmtstream.c b/contrib/argp-standalone/argp-fmtstream.c
deleted file mode 100644
index 494b6b31d12..00000000000
--- a/contrib/argp-standalone/argp-fmtstream.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/* Word-wrapping and line-truncating streams
- Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* This package emulates glibc `line_wrap_stream' semantics for systems that
- don't have that. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#include "argp-fmtstream.h"
-#include "argp-namefrob.h"
-
-#ifndef ARGP_FMTSTREAM_USE_LINEWRAP
-
-#ifndef isblank
-#define isblank(ch) ((ch)==' ' || (ch)=='\t')
-#endif
-
-#if defined _LIBC && defined USE_IN_LIBIO
-# include <libio/libioP.h>
-# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
-#endif
-
-#define INIT_BUF_SIZE 200
-#define PRINTF_SIZE_GUESS 150
-
-/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
- written on it with LMARGIN spaces and limits them to RMARGIN columns
- total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
- replacing the whitespace before them with a newline and WMARGIN spaces.
- Otherwise, chars beyond RMARGIN are simply dropped until a newline.
- Returns NULL if there was an error. */
-argp_fmtstream_t
-__argp_make_fmtstream (FILE *stream,
- size_t lmargin, size_t rmargin, ssize_t wmargin)
-{
- argp_fmtstream_t fs = malloc (sizeof (struct argp_fmtstream));
- if (fs)
- {
- fs->stream = stream;
-
- fs->lmargin = lmargin;
- fs->rmargin = rmargin;
- fs->wmargin = wmargin;
- fs->point_col = 0;
- fs->point_offs = 0;
-
- fs->buf = malloc (INIT_BUF_SIZE);
- if (! fs->buf)
- {
- free (fs);
- fs = 0;
- }
- else
- {
- fs->p = fs->buf;
- fs->end = fs->buf + INIT_BUF_SIZE;
- }
- }
-
- return fs;
-}
-#ifdef weak_alias
-weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
-#endif
-
-/* Flush FS to its stream, and free it (but don't close the stream). */
-void
-__argp_fmtstream_free (argp_fmtstream_t fs)
-{
- __argp_fmtstream_update (fs);
- if (fs->p > fs->buf)
- FWRITE_UNLOCKED (fs->buf, 1, fs->p - fs->buf, fs->stream);
- free (fs->buf);
- free (fs);
-}
-#ifdef weak_alias
-weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
-#endif
-
-/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
- end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
-void
-__argp_fmtstream_update (argp_fmtstream_t fs)
-{
- char *buf, *nl;
- size_t len;
-
- /* Scan the buffer for newlines. */
- buf = fs->buf + fs->point_offs;
- while (buf < fs->p)
- {
- size_t r;
-
- if (fs->point_col == 0 && fs->lmargin != 0)
- {
- /* We are starting a new line. Print spaces to the left margin. */
- const size_t pad = fs->lmargin;
- if (fs->p + pad < fs->end)
- {
- /* We can fit in them in the buffer by moving the
- buffer text up and filling in the beginning. */
- memmove (buf + pad, buf, fs->p - buf);
- fs->p += pad; /* Compensate for bigger buffer. */
- memset (buf, ' ', pad); /* Fill in the spaces. */
- buf += pad; /* Don't bother searching them. */
- }
- else
- {
- /* No buffer space for spaces. Must flush. */
- size_t i;
- for (i = 0; i < pad; i++)
- PUTC_UNLOCKED (' ', fs->stream);
- }
- fs->point_col = pad;
- }
-
- len = fs->p - buf;
- nl = memchr (buf, '\n', len);
-
- if (fs->point_col < 0)
- fs->point_col = 0;
-
- if (!nl)
- {
- /* The buffer ends in a partial line. */
-
- if (fs->point_col + len < fs->rmargin)
- {
- /* The remaining buffer text is a partial line and fits
- within the maximum line width. Advance point for the
- characters to be written and stop scanning. */
- fs->point_col += len;
- break;
- }
- else
- /* Set the end-of-line pointer for the code below to
- the end of the buffer. */
- nl = fs->p;
- }
- else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
- {
- /* The buffer contains a full line that fits within the maximum
- line width. Reset point and scan the next line. */
- fs->point_col = 0;
- buf = nl + 1;
- continue;
- }
-
- /* This line is too long. */
- r = fs->rmargin - 1;
-
- if (fs->wmargin < 0)
- {
- /* Truncate the line by overwriting the excess with the
- newline and anything after it in the buffer. */
- if (nl < fs->p)
- {
- memmove (buf + (r - fs->point_col), nl, fs->p - nl);
- fs->p -= buf + (r - fs->point_col) - nl;
- /* Reset point for the next line and start scanning it. */
- fs->point_col = 0;
- buf += r + 1; /* Skip full line plus \n. */
- }
- else
- {
- /* The buffer ends with a partial line that is beyond the
- maximum line width. Advance point for the characters
- written, and discard those past the max from the buffer. */
- fs->point_col += len;
- fs->p -= fs->point_col - r;
- break;
- }
- }
- else
- {
- /* Do word wrap. Go to the column just past the maximum line
- width and scan back for the beginning of the word there.
- Then insert a line break. */
-
- char *p, *nextline;
- int i;
-
- p = buf + (r + 1 - fs->point_col);
- while (p >= buf && !isblank (*p))
- --p;
- nextline = p + 1; /* This will begin the next line. */
-
- if (nextline > buf)
- {
- /* Swallow separating blanks. */
- if (p >= buf)
- do
- --p;
- while (p >= buf && isblank (*p));
- nl = p + 1; /* The newline will replace the first blank. */
- }
- else
- {
- /* A single word that is greater than the maximum line width.
- Oh well. Put it on an overlong line by itself. */
- p = buf + (r + 1 - fs->point_col);
- /* Find the end of the long word. */
- do
- ++p;
- while (p < nl && !isblank (*p));
- if (p == nl)
- {
- /* It already ends a line. No fussing required. */
- fs->point_col = 0;
- buf = nl + 1;
- continue;
- }
- /* We will move the newline to replace the first blank. */
- nl = p;
- /* Swallow separating blanks. */
- do
- ++p;
- while (isblank (*p));
- /* The next line will start here. */
- nextline = p;
- }
-
- /* Note: There are a bunch of tests below for
- NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
- at the end of the buffer, and NEXTLINE is in fact empty (and so
- we need not be careful to maintain its contents). */
-
- if (nextline == buf + len + 1
- ? fs->end - nl < fs->wmargin + 1
- : nextline - (nl + 1) < fs->wmargin)
- {
- /* The margin needs more blanks than we removed. */
- if (fs->end - fs->p > fs->wmargin + 1)
- /* Make some space for them. */
- {
- size_t mv = fs->p - nextline;
- memmove (nl + 1 + fs->wmargin, nextline, mv);
- nextline = nl + 1 + fs->wmargin;
- len = nextline + mv - buf;
- *nl++ = '\n';
- }
- else
- /* Output the first line so we can use the space. */
- {
- if (nl > fs->buf)
- FWRITE_UNLOCKED (fs->buf, 1, nl - fs->buf, fs->stream);
- PUTC_UNLOCKED ('\n', fs->stream);
- len += buf - fs->buf;
- nl = buf = fs->buf;
- }
- }
- else
- /* We can fit the newline and blanks in before
- the next word. */
- *nl++ = '\n';
-
- if (nextline - nl >= fs->wmargin
- || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
- /* Add blanks up to the wrap margin column. */
- for (i = 0; i < fs->wmargin; ++i)
- *nl++ = ' ';
- else
- for (i = 0; i < fs->wmargin; ++i)
- PUTC_UNLOCKED (' ', fs->stream);
-
- /* Copy the tail of the original buffer into the current buffer
- position. */
- if (nl < nextline)
- memmove (nl, nextline, buf + len - nextline);
- len -= nextline - buf;
-
- /* Continue the scan on the remaining lines in the buffer. */
- buf = nl;
-
- /* Restore bufp to include all the remaining text. */
- fs->p = nl + len;
-
- /* Reset the counter of what has been output this line. If wmargin
- is 0, we want to avoid the lmargin getting added, so we set
- point_col to a magic value of -1 in that case. */
- fs->point_col = fs->wmargin ? fs->wmargin : -1;
- }
- }
-
- /* Remember that we've scanned as far as the end of the buffer. */
- fs->point_offs = fs->p - fs->buf;
-}
-
-/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
- growing the buffer, or by flushing it. True is returned iff we succeed. */
-int
-__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
-{
- if ((size_t) (fs->end - fs->p) < amount)
- {
- ssize_t wrote;
-
- /* Flush FS's buffer. */
- __argp_fmtstream_update (fs);
-
- wrote = FWRITE_UNLOCKED (fs->buf, 1, fs->p - fs->buf, fs->stream);
- if (wrote == fs->p - fs->buf)
- {
- fs->p = fs->buf;
- fs->point_offs = 0;
- }
- else
- {
- fs->p -= wrote;
- fs->point_offs -= wrote;
- memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
- return 0;
- }
-
- if ((size_t) (fs->end - fs->buf) < amount)
- /* Gotta grow the buffer. */
- {
- size_t new_size = fs->end - fs->buf + amount;
- char *new_buf = realloc (fs->buf, new_size);
-
- if (! new_buf)
- {
- __set_errno (ENOMEM);
- return 0;
- }
-
- fs->buf = new_buf;
- fs->end = new_buf + new_size;
- fs->p = fs->buf;
- }
- }
-
- return 1;
-}
-
-ssize_t
-__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
-{
- size_t out;
- size_t avail;
- size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
-
- do
- {
- va_list args;
-
- if (! __argp_fmtstream_ensure (fs, size_guess))
- return -1;
-
- va_start (args, fmt);
- avail = fs->end - fs->p;
- out = __vsnprintf (fs->p, avail, fmt, args);
- va_end (args);
- if (out >= avail)
- size_guess = out + 1;
- }
- while (out >= avail);
-
- fs->p += out;
-
- return out;
-}
-#ifdef weak_alias
-weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
-#endif
-
-#if __STDC_VERSION__ - 199900L < 1
-/* Duplicate the inline definitions in argp-fmtstream.h, for compilers
- * that don't do inlining. */
-size_t
-__argp_fmtstream_write (argp_fmtstream_t __fs,
- __const char *__str, size_t __len)
-{
- if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
- {
- memcpy (__fs->p, __str, __len);
- __fs->p += __len;
- return __len;
- }
- else
- return 0;
-}
-
-int
-__argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str)
-{
- size_t __len = strlen (__str);
- if (__len)
- {
- size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
- return __wrote == __len ? 0 : -1;
- }
- else
- return 0;
-}
-
-int
-__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
-{
- if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
- return *__fs->p++ = __ch;
- else
- return EOF;
-}
-
-/* Set __FS's left margin to __LMARGIN and return the old value. */
-size_t
-__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
-{
- size_t __old;
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- __old = __fs->lmargin;
- __fs->lmargin = __lmargin;
- return __old;
-}
-
-/* Set __FS's right margin to __RMARGIN and return the old value. */
-size_t
-__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
-{
- size_t __old;
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- __old = __fs->rmargin;
- __fs->rmargin = __rmargin;
- return __old;
-}
-
-/* Set FS's wrap margin to __WMARGIN and return the old value. */
-size_t
-__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
-{
- size_t __old;
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- __old = __fs->wmargin;
- __fs->wmargin = __wmargin;
- return __old;
-}
-
-/* Return the column number of the current output point in __FS. */
-size_t
-__argp_fmtstream_point (argp_fmtstream_t __fs)
-{
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- return __fs->point_col >= 0 ? __fs->point_col : 0;
-}
-#endif /* __STDC_VERSION__ - 199900L < 1 */
-
-#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */
diff --git a/contrib/argp-standalone/argp-fmtstream.h b/contrib/argp-standalone/argp-fmtstream.h
deleted file mode 100644
index 828f4357d56..00000000000
--- a/contrib/argp-standalone/argp-fmtstream.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/* Word-wrapping and line-truncating streams.
- Copyright (C) 1997, 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* This package emulates glibc `line_wrap_stream' semantics for systems that
- don't have that. If the system does have it, it is just a wrapper for
- that. This header file is only used internally while compiling argp, and
- shouldn't be installed. */
-
-#ifndef _ARGP_FMTSTREAM_H
-#define _ARGP_FMTSTREAM_H
-
-#include <stdio.h>
-#include <string.h>
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#else
-/* This is a kludge to make the code compile on windows. Perhaps it
- would be better to just replace ssize_t with int through out the
- code. */
-# define ssize_t int
-#endif
-
-#if _LIBC || (defined (HAVE_FLOCKFILE) && defined(HAVE_PUTC_UNLOCKED) \
- && defined (HAVE_FPUTS_UNLOCKED) && defined (HAVE_FWRITE_UNLOCKED) )
-/* Use locking funxtions */
-# define FLOCKFILE(f) flockfile(f)
-# define FUNLOCKFILE(f) funlockfile(f)
-# define PUTC_UNLOCKED(c, f) putc_unlocked((c), (f))
-# define FPUTS_UNLOCKED(s, f) fputs_unlocked((s), (f))
-# define FWRITE_UNLOCKED(b, s, n, f) fwrite_unlocked((b), (s), (n), (f))
-#else
-/* Disable stdio locking */
-# define FLOCKFILE(f)
-# define FUNLOCKFILE(f)
-# define PUTC_UNLOCKED(c, f) putc((c), (f))
-# define FPUTS_UNLOCKED(s, f) fputs((s), (f))
-# define FWRITE_UNLOCKED(b, s, n, f) fwrite((b), (s), (n), (f))
-#endif /* No thread safe i/o */
-
-#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
- || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
-/* line_wrap_stream is available, so use that. */
-#define ARGP_FMTSTREAM_USE_LINEWRAP
-#endif
-
-#ifdef ARGP_FMTSTREAM_USE_LINEWRAP
-/* Just be a simple wrapper for line_wrap_stream; the semantics are
- *slightly* different, as line_wrap_stream doesn't actually make a new
- object, it just modifies the given stream (reversibly) to do
- line-wrapping. Since we control who uses this code, it doesn't matter. */
-
-#include <linewrap.h>
-
-typedef FILE *argp_fmtstream_t;
-
-#define argp_make_fmtstream line_wrap_stream
-#define __argp_make_fmtstream line_wrap_stream
-#define argp_fmtstream_free line_unwrap_stream
-#define __argp_fmtstream_free line_unwrap_stream
-
-#define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
-#define argp_fmtstream_putc(fs,ch) putc(ch,fs)
-#define __argp_fmtstream_puts(fs,str) fputs(str,fs)
-#define argp_fmtstream_puts(fs,str) fputs(str,fs)
-#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
-#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
-#define __argp_fmtstream_printf fprintf
-#define argp_fmtstream_printf fprintf
-
-#define __argp_fmtstream_lmargin line_wrap_lmargin
-#define argp_fmtstream_lmargin line_wrap_lmargin
-#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
-#define argp_fmtstream_set_lmargin line_wrap_set_lmargin
-#define __argp_fmtstream_rmargin line_wrap_rmargin
-#define argp_fmtstream_rmargin line_wrap_rmargin
-#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
-#define argp_fmtstream_set_rmargin line_wrap_set_rmargin
-#define __argp_fmtstream_wmargin line_wrap_wmargin
-#define argp_fmtstream_wmargin line_wrap_wmargin
-#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
-#define argp_fmtstream_set_wmargin line_wrap_set_wmargin
-#define __argp_fmtstream_point line_wrap_point
-#define argp_fmtstream_point line_wrap_point
-
-#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
-/* Guess we have to define our own version. */
-
-#ifndef __const
-#define __const const
-#endif
-
-
-struct argp_fmtstream
-{
- FILE *stream; /* The stream we're outputting to. */
-
- size_t lmargin, rmargin; /* Left and right margins. */
- ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */
-
- /* Point in buffer to which we've processed for wrapping, but not output. */
- size_t point_offs;
- /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */
- ssize_t point_col;
-
- char *buf; /* Output buffer. */
- char *p; /* Current end of text in BUF. */
- char *end; /* Absolute end of BUF. */
-};
-
-typedef struct argp_fmtstream *argp_fmtstream_t;
-
-/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
- written on it with LMARGIN spaces and limits them to RMARGIN columns
- total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
- replacing the whitespace before them with a newline and WMARGIN spaces.
- Otherwise, chars beyond RMARGIN are simply dropped until a newline.
- Returns NULL if there was an error. */
-extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
- size_t __lmargin,
- size_t __rmargin,
- ssize_t __wmargin);
-extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
- size_t __lmargin,
- size_t __rmargin,
- ssize_t __wmargin);
-
-/* Flush __FS to its stream, and free it (but don't close the stream). */
-extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
-extern void argp_fmtstream_free (argp_fmtstream_t __fs);
-
-extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
- __const char *__fmt, ...)
- PRINTF_STYLE(2,3);
-extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
- __const char *__fmt, ...)
- PRINTF_STYLE(2,3);
-
-#if __STDC_VERSION__ - 199900L < 1
-extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
-extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
-
-extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
-extern int argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
-
-extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
- __const char *__str, size_t __len);
-extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
- __const char *__str, size_t __len);
-#endif /* __STDC_VERSION__ - 199900L < 1 */
-
-/* Access macros for various bits of state. */
-#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
-#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
-#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
-#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
-#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
-#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
-
-#if __STDC_VERSION__ - 199900L < 1
-/* Set __FS's left margin to LMARGIN and return the old value. */
-extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
- size_t __lmargin);
-extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
- size_t __lmargin);
-
-/* Set __FS's right margin to __RMARGIN and return the old value. */
-extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
- size_t __rmargin);
-extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
- size_t __rmargin);
-
-/* Set __FS's wrap margin to __WMARGIN and return the old value. */
-extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
- size_t __wmargin);
-extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
- size_t __wmargin);
-
-/* Return the column number of the current output point in __FS. */
-extern size_t argp_fmtstream_point (argp_fmtstream_t __fs);
-extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs);
-#endif /* __STDC_VERSION__ - 199900L < 1 */
-
-/* Internal routines. */
-extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
-extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
-extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
-extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
-
-#ifdef __OPTIMIZE__
-/* Inline versions of above routines. */
-
-#if !_LIBC
-#define __argp_fmtstream_putc argp_fmtstream_putc
-#define __argp_fmtstream_puts argp_fmtstream_puts
-#define __argp_fmtstream_write argp_fmtstream_write
-#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
-#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
-#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
-#define __argp_fmtstream_point argp_fmtstream_point
-#define __argp_fmtstream_update _argp_fmtstream_update
-#define __argp_fmtstream_ensure _argp_fmtstream_ensure
-#endif
-
-#ifndef ARGP_FS_EI
-#if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__)
-#define ARGP_FS_EI extern inline
-#else
-#define ARGP_FS_EI inline
-#endif
-#endif
-
-ARGP_FS_EI size_t
-__argp_fmtstream_write (argp_fmtstream_t __fs,
- __const char *__str, size_t __len)
-{
- if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
- {
- memcpy (__fs->p, __str, __len);
- __fs->p += __len;
- return __len;
- }
- else
- return 0;
-}
-
-ARGP_FS_EI int
-__argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str)
-{
- size_t __len = strlen (__str);
- if (__len)
- {
- size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
- return __wrote == __len ? 0 : -1;
- }
- else
- return 0;
-}
-
-ARGP_FS_EI int
-__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
-{
- if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
- return *__fs->p++ = __ch;
- else
- return EOF;
-}
-
-/* Set __FS's left margin to __LMARGIN and return the old value. */
-ARGP_FS_EI size_t
-__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
-{
- size_t __old;
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- __old = __fs->lmargin;
- __fs->lmargin = __lmargin;
- return __old;
-}
-
-/* Set __FS's right margin to __RMARGIN and return the old value. */
-ARGP_FS_EI size_t
-__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
-{
- size_t __old;
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- __old = __fs->rmargin;
- __fs->rmargin = __rmargin;
- return __old;
-}
-
-/* Set FS's wrap margin to __WMARGIN and return the old value. */
-ARGP_FS_EI size_t
-__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
-{
- size_t __old;
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- __old = __fs->wmargin;
- __fs->wmargin = __wmargin;
- return __old;
-}
-
-/* Return the column number of the current output point in __FS. */
-ARGP_FS_EI size_t
-__argp_fmtstream_point (argp_fmtstream_t __fs)
-{
- if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
- __argp_fmtstream_update (__fs);
- return __fs->point_col >= 0 ? __fs->point_col : 0;
-}
-
-#if !_LIBC
-#undef __argp_fmtstream_putc
-#undef __argp_fmtstream_puts
-#undef __argp_fmtstream_write
-#undef __argp_fmtstream_set_lmargin
-#undef __argp_fmtstream_set_rmargin
-#undef __argp_fmtstream_set_wmargin
-#undef __argp_fmtstream_point
-#undef __argp_fmtstream_update
-#undef __argp_fmtstream_ensure
-#endif
-
-#endif /* __OPTIMIZE__ */
-
-#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
-
-#endif /* argp-fmtstream.h */
diff --git a/contrib/argp-standalone/argp-help.c b/contrib/argp-standalone/argp-help.c
deleted file mode 100644
index ced78c4cb26..00000000000
--- a/contrib/argp-standalone/argp-help.c
+++ /dev/null
@@ -1,1849 +0,0 @@
-/* Hierarchial argument parsing help output
- Copyright (C) 1995,96,97,98,99,2000, 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <stdarg.h>
-#include <ctype.h>
-#if HAVE_MALLOC_H
-/* Needed, for alloca on windows */
-# include <malloc.h>
-#endif
-
-#ifndef _
-/* This is for other GNU distributions with internationalized messages. */
-# if defined HAVE_LIBINTL_H || defined _LIBC
-# include <libintl.h>
-# ifdef _LIBC
-# undef dgettext
-# define dgettext(domain, msgid) __dcgettext (domain, msgid, LC_MESSAGES)
-# endif
-# else
-# define dgettext(domain, msgid) (msgid)
-# endif
-#endif
-
-#include "argp.h"
-#include "argp-fmtstream.h"
-#include "argp-namefrob.h"
-
-
-#ifndef _LIBC
-# ifndef __strchrnul
-# define __strchrnul strchrnul
-# endif
-# ifndef __mempcpy
-# define __mempcpy mempcpy
-# endif
-/* We need to use a different name, as __strndup is likely a macro. */
-# define STRNDUP strndup
-# if HAVE_STRERROR
-# define STRERROR strerror
-# else
-# define STRERROR(x) (sys_errlist[x])
-# endif
-#else /* _LIBC */
-# define FLOCKFILE __flockfile
-# define FUNLOCKFILE __funlockfile
-# define STRNDUP __strndup
-# define STRERROR strerror
-#endif
-
-#if !_LIBC
-# if !HAVE_STRNDUP
-char *strndup (const char *s, size_t size);
-# endif /* !HAVE_STRNDUP */
-
-# if !HAVE_MEMPCPY
-void *mempcpy (void *to, const void *from, size_t size);
-# endif /* !HAVE_MEMPCPY */
-
-# if !HAVE_STRCHRNUL
-char *strchrnul(const char *s, int c);
-# endif /* !HAVE_STRCHRNUL */
-
-# if !HAVE_STRCASECMP
-int strcasecmp(const char *s1, const char *s2);
-#endif
-
-#endif /* !_LIBC */
-
-
-/* User-selectable (using an environment variable) formatting parameters.
-
- These may be specified in an environment variable called `ARGP_HELP_FMT',
- with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
- Where VALn must be a positive integer. The list of variables is in the
- UPARAM_NAMES vector, below. */
-
-/* Default parameters. */
-#define DUP_ARGS 0 /* True if option argument can be duplicated. */
-#define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
-#define SHORT_OPT_COL 2 /* column in which short options start */
-#define LONG_OPT_COL 6 /* column in which long options start */
-#define DOC_OPT_COL 2 /* column in which doc options start */
-#define OPT_DOC_COL 29 /* column in which option text starts */
-#define HEADER_COL 1 /* column in which group headers are printed */
-#define USAGE_INDENT 12 /* indentation of wrapped usage lines */
-#define RMARGIN 79 /* right margin used for wrapping */
-
-/* User-selectable (using an environment variable) formatting parameters.
- They must all be of type `int' for the parsing code to work. */
-struct uparams
-{
- /* If true, arguments for an option are shown with both short and long
- options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
- If false, then if an option has both, the argument is only shown with
- the long one, e.g., `-x, --longx=ARG', and a message indicating that
- this really means both is printed below the options. */
- int dup_args;
-
- /* This is true if when DUP_ARGS is false, and some duplicate arguments have
- been suppressed, an explanatory message should be printed. */
- int dup_args_note;
-
- /* Various output columns. */
- int short_opt_col;
- int long_opt_col;
- int doc_opt_col;
- int opt_doc_col;
- int header_col;
- int usage_indent;
- int rmargin;
-
- int valid; /* True when the values in here are valid. */
-};
-
-/* This is a global variable, as user options are only ever read once. */
-static struct uparams uparams = {
- DUP_ARGS, DUP_ARGS_NOTE,
- SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
- USAGE_INDENT, RMARGIN,
- 0
-};
-
-/* A particular uparam, and what the user name is. */
-struct uparam_name
-{
- const char *name; /* User name. */
- int is_bool; /* Whether it's `boolean'. */
- size_t uparams_offs; /* Location of the (int) field in UPARAMS. */
-};
-
-/* The name-field mappings we know about. */
-static const struct uparam_name uparam_names[] =
-{
- { "dup-args", 1, offsetof (struct uparams, dup_args) },
- { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) },
- { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) },
- { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) },
- { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) },
- { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) },
- { "header-col", 0, offsetof (struct uparams, header_col) },
- { "usage-indent", 0, offsetof (struct uparams, usage_indent) },
- { "rmargin", 0, offsetof (struct uparams, rmargin) },
- { 0, 0, 0 }
-};
-
-/* Read user options from the environment, and fill in UPARAMS appropiately. */
-static void
-fill_in_uparams (const struct argp_state *state)
-{
-
- const char *var = getenv ("ARGP_HELP_FMT");
-
-#define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
-
- if (var)
- /* Parse var. */
- while (*var)
- {
- SKIPWS (var);
-
- if (isalpha (*var))
- {
- size_t var_len;
- const struct uparam_name *un;
- int unspec = 0, val = 0;
- const char *arg = var;
-
- while (isalnum (*arg) || *arg == '-' || *arg == '_')
- arg++;
- var_len = arg - var;
-
- SKIPWS (arg);
-
- if (*arg == '\0' || *arg == ',')
- unspec = 1;
- else if (*arg == '=')
- {
- arg++;
- SKIPWS (arg);
- }
-
- if (unspec)
- {
- if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
- {
- val = 0;
- var += 3;
- var_len -= 3;
- }
- else
- val = 1;
- }
- else if (isdigit (*arg))
- {
- val = atoi (arg);
- while (isdigit (*arg))
- arg++;
- SKIPWS (arg);
- }
-
- for (un = uparam_names; un->name; un++)
- if (strlen (un->name) == var_len
- && strncmp (var, un->name, var_len) == 0)
- {
- if (unspec && !un->is_bool)
- __argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain, "\
-%.*s: ARGP_HELP_FMT parameter requires a value"),
- (int) var_len, var);
- else
- *(int *)((char *)&uparams + un->uparams_offs) = val;
- break;
- }
- if (! un->name)
- __argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain, "\
-%.*s: Unknown ARGP_HELP_FMT parameter"),
- (int) var_len, var);
-
- var = arg;
- if (*var == ',')
- var++;
- }
- else if (*var)
- {
- __argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain,
- "Garbage in ARGP_HELP_FMT: %s"), var);
- break;
- }
- }
-}
-
-/* Returns true if OPT hasn't been marked invisible. Visibility only affects
- whether OPT is displayed or used in sorting, not option shadowing. */
-#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
-
-/* Returns true if OPT is an alias for an earlier option. */
-#define oalias(opt) ((opt)->flags & OPTION_ALIAS)
-
-/* Returns true if OPT is an documentation-only entry. */
-#define odoc(opt) ((opt)->flags & OPTION_DOC)
-
-/* Returns true if OPT is the end-of-list marker for a list of options. */
-#define oend(opt) __option_is_end (opt)
-
-/* Returns true if OPT has a short option. */
-#define oshort(opt) __option_is_short (opt)
-
-/*
- The help format for a particular option is like:
-
- -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
-
- Where ARG will be omitted if there's no argument, for this option, or
- will be surrounded by "[" and "]" appropiately if the argument is
- optional. The documentation string is word-wrapped appropiately, and if
- the list of options is long enough, it will be started on a separate line.
- If there are no short options for a given option, the first long option is
- indented slighly in a way that's supposed to make most long options appear
- to be in a separate column.
-
- For example, the following output (from ps):
-
- -p PID, --pid=PID List the process PID
- --pgrp=PGRP List processes in the process group PGRP
- -P, -x, --no-parent Include processes without parents
- -Q, --all-fields Don't elide unusable fields (normally if there's
- some reason ps can't print a field for any
- process, it's removed from the output entirely)
- -r, --reverse, --gratuitously-long-reverse-option
- Reverse the order of any sort
- --session[=SID] Add the processes from the session SID (which
- defaults to the sid of the current process)
-
- Here are some more options:
- -f ZOT, --foonly=ZOT Glork a foonly
- -z, --zaza Snit a zar
-
- -?, --help Give this help list
- --usage Give a short usage message
- -V, --version Print program version
-
- The struct argp_option array for the above could look like:
-
- {
- {"pid", 'p', "PID", 0, "List the process PID"},
- {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
- {"no-parent", 'P', 0, 0, "Include processes without parents"},
- {0, 'x', 0, OPTION_ALIAS},
- {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
- " if there's some reason ps can't"
- " print a field for any process, it's"
- " removed from the output entirely)" },
- {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
- {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
- {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
- "Add the processes from the session"
- " SID (which defaults to the sid of"
- " the current process)" },
-
- {0,0,0,0, "Here are some more options:"},
- {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
- {"zaza", 'z', 0, 0, "Snit a zar"},
-
- {0}
- }
-
- Note that the last three options are automatically supplied by argp_parse,
- unless you tell it not to with ARGP_NO_HELP.
-
-*/
-
-/* Returns true if CH occurs between BEG and END. */
-static int
-find_char (char ch, char *beg, char *end)
-{
- while (beg < end)
- if (*beg == ch)
- return 1;
- else
- beg++;
- return 0;
-}
-
-struct hol_cluster; /* fwd decl */
-
-struct hol_entry
-{
- /* First option. */
- const struct argp_option *opt;
- /* Number of options (including aliases). */
- unsigned num;
-
- /* A pointers into the HOL's short_options field, to the first short option
- letter for this entry. The order of the characters following this point
- corresponds to the order of options pointed to by OPT, and there are at
- most NUM. A short option recorded in a option following OPT is only
- valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
- probably been shadowed by some other entry). */
- char *short_options;
-
- /* Entries are sorted by their group first, in the order:
- 1, 2, ..., n, 0, -m, ..., -2, -1
- and then alphabetically within each group. The default is 0. */
- int group;
-
- /* The cluster of options this entry belongs to, or 0 if none. */
- struct hol_cluster *cluster;
-
- /* The argp from which this option came. */
- const struct argp *argp;
-};
-
-/* A cluster of entries to reflect the argp tree structure. */
-struct hol_cluster
-{
- /* A descriptive header printed before options in this cluster. */
- const char *header;
-
- /* Used to order clusters within the same group with the same parent,
- according to the order in which they occurred in the parent argp's child
- list. */
- int index;
-
- /* How to sort this cluster with respect to options and other clusters at the
- same depth (clusters always follow options in the same group). */
- int group;
-
- /* The cluster to which this cluster belongs, or 0 if it's at the base
- level. */
- struct hol_cluster *parent;
-
- /* The argp from which this cluster is (eventually) derived. */
- const struct argp *argp;
-
- /* The distance this cluster is from the root. */
- int depth;
-
- /* Clusters in a given hol are kept in a linked list, to make freeing them
- possible. */
- struct hol_cluster *next;
-};
-
-/* A list of options for help. */
-struct hol
-{
- /* An array of hol_entry's. */
- struct hol_entry *entries;
- /* The number of entries in this hol. If this field is zero, the others
- are undefined. */
- unsigned num_entries;
-
- /* A string containing all short options in this HOL. Each entry contains
- pointers into this string, so the order can't be messed with blindly. */
- char *short_options;
-
- /* Clusters of entries in this hol. */
- struct hol_cluster *clusters;
-};
-
-/* Create a struct hol from the options in ARGP. CLUSTER is the
- hol_cluster in which these entries occur, or 0, if at the root. */
-static struct hol *
-make_hol (const struct argp *argp, struct hol_cluster *cluster)
-{
- char *so;
- const struct argp_option *o;
- const struct argp_option *opts = argp->options;
- struct hol_entry *entry;
- unsigned num_short_options = 0;
- struct hol *hol = malloc (sizeof (struct hol));
-
- assert (hol);
-
- hol->num_entries = 0;
- hol->clusters = 0;
-
- if (opts)
- {
- int cur_group = 0;
-
- /* The first option must not be an alias. */
- assert (! oalias (opts));
-
- /* Calculate the space needed. */
- for (o = opts; ! oend (o); o++)
- {
- if (! oalias (o))
- hol->num_entries++;
- if (oshort (o))
- num_short_options++; /* This is an upper bound. */
- }
-
- hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
- hol->short_options = malloc (num_short_options + 1);
-
- assert (hol->entries && hol->short_options);
-
- /* Fill in the entries. */
- so = hol->short_options;
- for (o = opts, entry = hol->entries; ! oend (o); entry++)
- {
- entry->opt = o;
- entry->num = 0;
- entry->short_options = so;
- entry->group = cur_group =
- o->group
- ? o->group
- : ((!o->name && !o->key)
- ? cur_group + 1
- : cur_group);
- entry->cluster = cluster;
- entry->argp = argp;
-
- do
- {
- entry->num++;
- if (oshort (o) && ! find_char (o->key, hol->short_options, so))
- /* O has a valid short option which hasn't already been used.*/
- *so++ = o->key;
- o++;
- }
- while (! oend (o) && oalias (o));
- }
- *so = '\0'; /* null terminated so we can find the length */
- }
-
- return hol;
-}
-
-/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
- associated argp child list entry), INDEX, and PARENT, and return a pointer
- to it. ARGP is the argp that this cluster results from. */
-static struct hol_cluster *
-hol_add_cluster (struct hol *hol, int group, const char *header, int index,
- struct hol_cluster *parent, const struct argp *argp)
-{
- struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
- if (cl)
- {
- cl->group = group;
- cl->header = header;
-
- cl->index = index;
- cl->parent = parent;
- cl->argp = argp;
- cl->depth = parent ? parent->depth + 1 : 0;
-
- cl->next = hol->clusters;
- hol->clusters = cl;
- }
- return cl;
-}
-
-/* Free HOL and any resources it uses. */
-static void
-hol_free (struct hol *hol)
-{
- struct hol_cluster *cl = hol->clusters;
-
- while (cl)
- {
- struct hol_cluster *next = cl->next;
- free (cl);
- cl = next;
- }
-
- if (hol->num_entries > 0)
- {
- free (hol->entries);
- free (hol->short_options);
- }
-
- free (hol);
-}
-
-static inline int
-hol_entry_short_iterate (const struct hol_entry *entry,
- int (*func)(const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain, void *cookie),
- const char *domain, void *cookie)
-{
- unsigned nopts;
- int val = 0;
- const struct argp_option *opt, *real = entry->opt;
- char *so = entry->short_options;
-
- for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
- if (oshort (opt) && *so == opt->key)
- {
- if (!oalias (opt))
- real = opt;
- if (ovisible (opt))
- val = (*func)(opt, real, domain, cookie);
- so++;
- }
-
- return val;
-}
-
-static inline int
-hol_entry_long_iterate (const struct hol_entry *entry,
- int (*func)(const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain, void *cookie),
- const char *domain, void *cookie)
-{
- unsigned nopts;
- int val = 0;
- const struct argp_option *opt, *real = entry->opt;
-
- for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
- if (opt->name)
- {
- if (!oalias (opt))
- real = opt;
- if (ovisible (opt))
- val = (*func)(opt, real, domain, cookie);
- }
-
- return val;
-}
-
-/* Iterator that returns true for the first short option. */
-static inline int
-until_short (const struct argp_option *opt, const struct argp_option *real UNUSED,
- const char *domain UNUSED, void *cookie UNUSED)
-{
- return oshort (opt) ? opt->key : 0;
-}
-
-/* Returns the first valid short option in ENTRY, or 0 if there is none. */
-static char
-hol_entry_first_short (const struct hol_entry *entry)
-{
- return hol_entry_short_iterate (entry, until_short,
- entry->argp->argp_domain, 0);
-}
-
-/* Returns the first valid long option in ENTRY, or 0 if there is none. */
-static const char *
-hol_entry_first_long (const struct hol_entry *entry)
-{
- const struct argp_option *opt;
- unsigned num;
- for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
- if (opt->name && ovisible (opt))
- return opt->name;
- return 0;
-}
-
-/* Returns the entry in HOL with the long option name NAME, or 0 if there is
- none. */
-static struct hol_entry *
-hol_find_entry (struct hol *hol, const char *name)
-{
- struct hol_entry *entry = hol->entries;
- unsigned num_entries = hol->num_entries;
-
- while (num_entries-- > 0)
- {
- const struct argp_option *opt = entry->opt;
- unsigned num_opts = entry->num;
-
- while (num_opts-- > 0)
- if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
- return entry;
- else
- opt++;
-
- entry++;
- }
-
- return 0;
-}
-
-/* If an entry with the long option NAME occurs in HOL, set it's special
- sort position to GROUP. */
-static void
-hol_set_group (struct hol *hol, const char *name, int group)
-{
- struct hol_entry *entry = hol_find_entry (hol, name);
- if (entry)
- entry->group = group;
-}
-
-/* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1.
- EQ is what to return if GROUP1 and GROUP2 are the same. */
-static int
-group_cmp (int group1, int group2, int eq)
-{
- if (group1 == group2)
- return eq;
- else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
- return group1 - group2;
- else
- return group2 - group1;
-}
-
-/* Compare clusters CL1 & CL2 by the order that they should appear in
- output. */
-static int
-hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
-{
- /* If one cluster is deeper than the other, use its ancestor at the same
- level, so that finding the common ancestor is straightforward. */
- while (cl1->depth < cl2->depth)
- cl1 = cl1->parent;
- while (cl2->depth < cl1->depth)
- cl2 = cl2->parent;
-
- /* Now reduce both clusters to their ancestors at the point where both have
- a common parent; these can be directly compared. */
- while (cl1->parent != cl2->parent)
- cl1 = cl1->parent, cl2 = cl2->parent;
-
- return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
-}
-
-/* Return the ancestor of CL that's just below the root (i.e., has a parent
- of 0). */
-static struct hol_cluster *
-hol_cluster_base (struct hol_cluster *cl)
-{
- while (cl->parent)
- cl = cl->parent;
- return cl;
-}
-
-/* Return true if CL1 is a child of CL2. */
-static int
-hol_cluster_is_child (const struct hol_cluster *cl1,
- const struct hol_cluster *cl2)
-{
- while (cl1 && cl1 != cl2)
- cl1 = cl1->parent;
- return cl1 == cl2;
-}
-
-/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
- that should be used for comparisons, and returns true iff it should be
- treated as a non-option. */
-
-/* FIXME: Can we use unsigned char * for the argument? */
-static int
-canon_doc_option (const char **name)
-{
- int non_opt;
- /* Skip initial whitespace. */
- while (isspace ( (unsigned char) **name))
- (*name)++;
- /* Decide whether this looks like an option (leading `-') or not. */
- non_opt = (**name != '-');
- /* Skip until part of name used for sorting. */
- while (**name && !isalnum ( (unsigned char) **name))
- (*name)++;
- return non_opt;
-}
-
-/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
- listing. */
-static int
-hol_entry_cmp (const struct hol_entry *entry1,
- const struct hol_entry *entry2)
-{
- /* The group numbers by which the entries should be ordered; if either is
- in a cluster, then this is just the group within the cluster. */
- int group1 = entry1->group, group2 = entry2->group;
-
- if (entry1->cluster != entry2->cluster)
- {
- /* The entries are not within the same cluster, so we can't compare them
- directly, we have to use the appropiate clustering level too. */
- if (! entry1->cluster)
- /* ENTRY1 is at the `base level', not in a cluster, so we have to
- compare it's group number with that of the base cluster in which
- ENTRY2 resides. Note that if they're in the same group, the
- clustered option always comes laster. */
- return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
- else if (! entry2->cluster)
- /* Likewise, but ENTRY2's not in a cluster. */
- return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
- else
- /* Both entries are in clusters, we can just compare the clusters. */
- return hol_cluster_cmp (entry1->cluster, entry2->cluster);
- }
- else if (group1 == group2)
- /* The entries are both in the same cluster and group, so compare them
- alphabetically. */
- {
- int short1 = hol_entry_first_short (entry1);
- int short2 = hol_entry_first_short (entry2);
- int doc1 = odoc (entry1->opt);
- int doc2 = odoc (entry2->opt);
- /* FIXME: Can we use unsigned char * instead? */
- const char *long1 = hol_entry_first_long (entry1);
- const char *long2 = hol_entry_first_long (entry2);
-
- if (doc1)
- doc1 = canon_doc_option (&long1);
- if (doc2)
- doc2 = canon_doc_option (&long2);
-
- if (doc1 != doc2)
- /* `documentation' options always follow normal options (or
- documentation options that *look* like normal options). */
- return doc1 - doc2;
- else if (!short1 && !short2 && long1 && long2)
- /* Only long options. */
- return __strcasecmp (long1, long2);
- else
- /* Compare short/short, long/short, short/long, using the first
- character of long options. Entries without *any* valid
- options (such as options with OPTION_HIDDEN set) will be put
- first, but as they're not displayed, it doesn't matter where
- they are. */
- {
- unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0;
- unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0;
-#ifdef _tolower
- int lower_cmp = _tolower (first1) - _tolower (first2);
-#else
- int lower_cmp = tolower (first1) - tolower (first2);
-#endif
- /* Compare ignoring case, except when the options are both the
- same letter, in which case lower-case always comes first. */
- /* NOTE: The subtraction below does the right thing
- even with eight-bit chars: first1 and first2 are
- converted to int *before* the subtraction. */
- return lower_cmp ? lower_cmp : first2 - first1;
- }
- }
- else
- /* Within the same cluster, but not the same group, so just compare
- groups. */
- return group_cmp (group1, group2, 0);
-}
-
-/* Version of hol_entry_cmp with correct signature for qsort. */
-static int
-hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
-{
- return hol_entry_cmp (entry1_v, entry2_v);
-}
-
-/* Sort HOL by group and alphabetically by option name (with short options
- taking precedence over long). Since the sorting is for display purposes
- only, the shadowing of options isn't effected. */
-static void
-hol_sort (struct hol *hol)
-{
- if (hol->num_entries > 0)
- qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
- hol_entry_qcmp);
-}
-
-/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
- any in MORE with the same name. */
-static void
-hol_append (struct hol *hol, struct hol *more)
-{
- struct hol_cluster **cl_end = &hol->clusters;
-
- /* Steal MORE's cluster list, and add it to the end of HOL's. */
- while (*cl_end)
- cl_end = &(*cl_end)->next;
- *cl_end = more->clusters;
- more->clusters = 0;
-
- /* Merge entries. */
- if (more->num_entries > 0)
- {
- if (hol->num_entries == 0)
- {
- hol->num_entries = more->num_entries;
- hol->entries = more->entries;
- hol->short_options = more->short_options;
- more->num_entries = 0; /* Mark MORE's fields as invalid. */
- }
- else
- /* Append the entries in MORE to those in HOL, taking care to only add
- non-shadowed SHORT_OPTIONS values. */
- {
- unsigned left;
- char *so, *more_so;
- struct hol_entry *e;
- unsigned num_entries = hol->num_entries + more->num_entries;
- struct hol_entry *entries =
- malloc (num_entries * sizeof (struct hol_entry));
- unsigned hol_so_len = strlen (hol->short_options);
- char *short_options =
- malloc (hol_so_len + strlen (more->short_options) + 1);
-
- __mempcpy (__mempcpy (entries, hol->entries,
- hol->num_entries * sizeof (struct hol_entry)),
- more->entries,
- more->num_entries * sizeof (struct hol_entry));
-
- __mempcpy (short_options, hol->short_options, hol_so_len);
-
- /* Fix up the short options pointers from HOL. */
- for (e = entries, left = hol->num_entries; left > 0; e++, left--)
- e->short_options += (short_options - hol->short_options);
-
- /* Now add the short options from MORE, fixing up its entries
- too. */
- so = short_options + hol_so_len;
- more_so = more->short_options;
- for (left = more->num_entries; left > 0; e++, left--)
- {
- int opts_left;
- const struct argp_option *opt;
-
- e->short_options = so;
-
- for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
- {
- int ch = *more_so;
- if (oshort (opt) && ch == opt->key)
- /* The next short option in MORE_SO, CH, is from OPT. */
- {
- if (! find_char (ch, short_options,
- short_options + hol_so_len))
- /* The short option CH isn't shadowed by HOL's options,
- so add it to the sum. */
- *so++ = ch;
- more_so++;
- }
- }
- }
-
- *so = '\0';
-
- free (hol->entries);
- free (hol->short_options);
-
- hol->entries = entries;
- hol->num_entries = num_entries;
- hol->short_options = short_options;
- }
- }
-
- hol_free (more);
-}
-
-/* Inserts enough spaces to make sure STREAM is at column COL. */
-static void
-indent_to (argp_fmtstream_t stream, unsigned col)
-{
- int needed = col - __argp_fmtstream_point (stream);
- while (needed-- > 0)
- __argp_fmtstream_putc (stream, ' ');
-}
-
-/* Output to STREAM either a space, or a newline if there isn't room for at
- least ENSURE characters before the right margin. */
-static void
-space (argp_fmtstream_t stream, size_t ensure)
-{
- if (__argp_fmtstream_point (stream) + ensure
- >= __argp_fmtstream_rmargin (stream))
- __argp_fmtstream_putc (stream, '\n');
- else
- __argp_fmtstream_putc (stream, ' ');
-}
-
-/* If the option REAL has an argument, we print it in using the printf
- format REQ_FMT or OPT_FMT depending on whether it's a required or
- optional argument. */
-static void
-arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
- const char *domain UNUSED, argp_fmtstream_t stream)
-{
- if (real->arg)
- {
- if (real->flags & OPTION_ARG_OPTIONAL)
- __argp_fmtstream_printf (stream, opt_fmt,
- dgettext (domain, real->arg));
- else
- __argp_fmtstream_printf (stream, req_fmt,
- dgettext (domain, real->arg));
- }
-}
-
-/* Helper functions for hol_entry_help. */
-
-/* State used during the execution of hol_help. */
-struct hol_help_state
-{
- /* PREV_ENTRY should contain the previous entry printed, or 0. */
- struct hol_entry *prev_entry;
-
- /* If an entry is in a different group from the previous one, and SEP_GROUPS
- is true, then a blank line will be printed before any output. */
- int sep_groups;
-
- /* True if a duplicate option argument was suppressed (only ever set if
- UPARAMS.dup_args is false). */
- int suppressed_dup_arg;
-};
-
-/* Some state used while printing a help entry (used to communicate with
- helper functions). See the doc for hol_entry_help for more info, as most
- of the fields are copied from its arguments. */
-struct pentry_state
-{
- const struct hol_entry *entry;
- argp_fmtstream_t stream;
- struct hol_help_state *hhstate;
-
- /* True if nothing's been printed so far. */
- int first;
-
- /* If non-zero, the state that was used to print this help. */
- const struct argp_state *state;
-};
-
-/* If a user doc filter should be applied to DOC, do so. */
-static const char *
-filter_doc (const char *doc, int key, const struct argp *argp,
- const struct argp_state *state)
-{
- if (argp->help_filter)
- /* We must apply a user filter to this output. */
- {
- void *input = __argp_input (argp, state);
- return (*argp->help_filter) (key, doc, input);
- }
- else
- /* No filter. */
- return doc;
-}
-
-/* Prints STR as a header line, with the margin lines set appropiately, and
- notes the fact that groups should be separated with a blank line. ARGP is
- the argp that should dictate any user doc filtering to take place. Note
- that the previous wrap margin isn't restored, but the left margin is reset
- to 0. */
-static void
-print_header (const char *str, const struct argp *argp,
- struct pentry_state *pest)
-{
- const char *tstr = dgettext (argp->argp_domain, str);
- const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
-
- if (fstr)
- {
- if (*fstr)
- {
- if (pest->hhstate->prev_entry)
- /* Precede with a blank line. */
- __argp_fmtstream_putc (pest->stream, '\n');
- indent_to (pest->stream, uparams.header_col);
- __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
- __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
- __argp_fmtstream_puts (pest->stream, fstr);
- __argp_fmtstream_set_lmargin (pest->stream, 0);
- __argp_fmtstream_putc (pest->stream, '\n');
- }
-
- pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
- }
-
- if (fstr != tstr)
- free ((char *) fstr);
-}
-
-/* Inserts a comma if this isn't the first item on the line, and then makes
- sure we're at least to column COL. If this *is* the first item on a line,
- prints any pending whitespace/headers that should precede this line. Also
- clears FIRST. */
-static void
-comma (unsigned col, struct pentry_state *pest)
-{
- if (pest->first)
- {
- const struct hol_entry *pe = pest->hhstate->prev_entry;
- const struct hol_cluster *cl = pest->entry->cluster;
-
- if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
- __argp_fmtstream_putc (pest->stream, '\n');
-
- if (cl && cl->header && *cl->header
- && (!pe
- || (pe->cluster != cl
- && !hol_cluster_is_child (pe->cluster, cl))))
- /* If we're changing clusters, then this must be the start of the
- ENTRY's cluster unless that is an ancestor of the previous one
- (in which case we had just popped into a sub-cluster for a bit).
- If so, then print the cluster's header line. */
- {
- int old_wm = __argp_fmtstream_wmargin (pest->stream);
- print_header (cl->header, cl->argp, pest);
- __argp_fmtstream_set_wmargin (pest->stream, old_wm);
- }
-
- pest->first = 0;
- }
- else
- __argp_fmtstream_puts (pest->stream, ", ");
-
- indent_to (pest->stream, col);
-}
-
-/* Print help for ENTRY to STREAM. */
-static void
-hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
- argp_fmtstream_t stream, struct hol_help_state *hhstate)
-{
- unsigned num;
- const struct argp_option *real = entry->opt, *opt;
- char *so = entry->short_options;
- int have_long_opt = 0; /* We have any long options. */
- /* Saved margins. */
- int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
- int old_wm = __argp_fmtstream_wmargin (stream);
- /* PEST is a state block holding some of our variables that we'd like to
- share with helper functions. */
-
- /* Decent initializers are a GNU extension, so don't use it here. */
- struct pentry_state pest;
- pest.entry = entry;
- pest.stream = stream;
- pest.hhstate = hhstate;
- pest.first = 1;
- pest.state = state;
-
- if (! odoc (real))
- for (opt = real, num = entry->num; num > 0; opt++, num--)
- if (opt->name && ovisible (opt))
- {
- have_long_opt = 1;
- break;
- }
-
- /* First emit short options. */
- __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
- for (opt = real, num = entry->num; num > 0; opt++, num--)
- if (oshort (opt) && opt->key == *so)
- /* OPT has a valid (non shadowed) short option. */
- {
- if (ovisible (opt))
- {
- comma (uparams.short_opt_col, &pest);
- __argp_fmtstream_putc (stream, '-');
- __argp_fmtstream_putc (stream, *so);
- if (!have_long_opt || uparams.dup_args)
- arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
- else if (real->arg)
- hhstate->suppressed_dup_arg = 1;
- }
- so++;
- }
-
- /* Now, long options. */
- if (odoc (real))
- /* A `documentation' option. */
- {
- __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
- for (opt = real, num = entry->num; num > 0; opt++, num--)
- if (opt->name && ovisible (opt))
- {
- comma (uparams.doc_opt_col, &pest);
- /* Calling gettext here isn't quite right, since sorting will
- have been done on the original; but documentation options
- should be pretty rare anyway... */
- __argp_fmtstream_puts (stream,
- dgettext (state->root_argp->argp_domain,
- opt->name));
- }
- }
- else
- /* A real long option. */
- {
- int first_long_opt = 1;
-
- __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
- for (opt = real, num = entry->num; num > 0; opt++, num--)
- if (opt->name && ovisible (opt))
- {
- comma (uparams.long_opt_col, &pest);
- __argp_fmtstream_printf (stream, "--%s", opt->name);
- if (first_long_opt || uparams.dup_args)
- arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
- stream);
- else if (real->arg)
- hhstate->suppressed_dup_arg = 1;
- }
- }
-
- /* Next, documentation strings. */
- __argp_fmtstream_set_lmargin (stream, 0);
-
- if (pest.first)
- {
- /* Didn't print any switches, what's up? */
- if (!oshort (real) && !real->name)
- /* This is a group header, print it nicely. */
- print_header (real->doc, entry->argp, &pest);
- else
- /* Just a totally shadowed option or null header; print nothing. */
- goto cleanup; /* Just return, after cleaning up. */
- }
- else
- {
- const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
- real->doc) : 0;
- const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
- if (fstr && *fstr)
- {
- unsigned int col = __argp_fmtstream_point (stream);
-
- __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
- __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
-
- if (col > (unsigned int) (uparams.opt_doc_col + 3))
- __argp_fmtstream_putc (stream, '\n');
- else if (col >= (unsigned int) uparams.opt_doc_col)
- __argp_fmtstream_puts (stream, " ");
- else
- indent_to (stream, uparams.opt_doc_col);
-
- __argp_fmtstream_puts (stream, fstr);
- }
- if (fstr && fstr != tstr)
- free ((char *) fstr);
-
- /* Reset the left margin. */
- __argp_fmtstream_set_lmargin (stream, 0);
- __argp_fmtstream_putc (stream, '\n');
- }
-
- hhstate->prev_entry = entry;
-
-cleanup:
- __argp_fmtstream_set_lmargin (stream, old_lm);
- __argp_fmtstream_set_wmargin (stream, old_wm);
-}
-
-/* Output a long help message about the options in HOL to STREAM. */
-static void
-hol_help (struct hol *hol, const struct argp_state *state,
- argp_fmtstream_t stream)
-{
- unsigned num;
- struct hol_entry *entry;
- struct hol_help_state hhstate = { 0, 0, 0 };
-
- for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
- hol_entry_help (entry, state, stream, &hhstate);
-
- if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
- {
- const char *tstr = dgettext (state->root_argp->argp_domain, "\
-Mandatory or optional arguments to long options are also mandatory or \
-optional for any corresponding short options.");
- const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
- state ? state->root_argp : 0, state);
- if (fstr && *fstr)
- {
- __argp_fmtstream_putc (stream, '\n');
- __argp_fmtstream_puts (stream, fstr);
- __argp_fmtstream_putc (stream, '\n');
- }
- if (fstr && fstr != tstr)
- free ((char *) fstr);
- }
-}
-
-/* Helper functions for hol_usage. */
-
-/* If OPT is a short option without an arg, append its key to the string
- pointer pointer to by COOKIE, and advance the pointer. */
-static int
-add_argless_short_opt (const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain UNUSED, void *cookie)
-{
- char **snao_end = cookie;
- if (!(opt->arg || real->arg)
- && !((opt->flags | real->flags) & OPTION_NO_USAGE))
- *(*snao_end)++ = opt->key;
- return 0;
-}
-
-/* If OPT is a short option with an arg, output a usage entry for it to the
- stream pointed at by COOKIE. */
-static int
-usage_argful_short_opt (const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain UNUSED, void *cookie)
-{
- argp_fmtstream_t stream = cookie;
- const char *arg = opt->arg;
- int flags = opt->flags | real->flags;
-
- if (! arg)
- arg = real->arg;
-
- if (arg && !(flags & OPTION_NO_USAGE))
- {
- arg = dgettext (domain, arg);
-
- if (flags & OPTION_ARG_OPTIONAL)
- __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
- else
- {
- /* Manually do line wrapping so that it (probably) won't
- get wrapped at the embedded space. */
- space (stream, 6 + strlen (arg));
- __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
- }
- }
-
- return 0;
-}
-
-/* Output a usage entry for the long option opt to the stream pointed at by
- COOKIE. */
-static int
-usage_long_opt (const struct argp_option *opt,
- const struct argp_option *real,
- const char *domain UNUSED, void *cookie)
-{
- argp_fmtstream_t stream = cookie;
- const char *arg = opt->arg;
- int flags = opt->flags | real->flags;
-
- if (! arg)
- arg = real->arg;
-
- if (! (flags & OPTION_NO_USAGE))
- {
- if (arg)
- {
- arg = dgettext (domain, arg);
- if (flags & OPTION_ARG_OPTIONAL)
- __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
- else
- __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
- }
- else
- __argp_fmtstream_printf (stream, " [--%s]", opt->name);
- }
-
- return 0;
-}
-
-/* Print a short usage description for the arguments in HOL to STREAM. */
-static void
-hol_usage (struct hol *hol, argp_fmtstream_t stream)
-{
- if (hol->num_entries > 0)
- {
- unsigned nentries;
- struct hol_entry *entry;
- char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
- char *snao_end = short_no_arg_opts;
-
- /* First we put a list of short options without arguments. */
- for (entry = hol->entries, nentries = hol->num_entries
- ; nentries > 0
- ; entry++, nentries--)
- hol_entry_short_iterate (entry, add_argless_short_opt,
- entry->argp->argp_domain, &snao_end);
- if (snao_end > short_no_arg_opts)
- {
- *snao_end++ = 0;
- __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
- }
-
- /* Now a list of short options *with* arguments. */
- for (entry = hol->entries, nentries = hol->num_entries
- ; nentries > 0
- ; entry++, nentries--)
- hol_entry_short_iterate (entry, usage_argful_short_opt,
- entry->argp->argp_domain, stream);
-
- /* Finally, a list of long options (whew!). */
- for (entry = hol->entries, nentries = hol->num_entries
- ; nentries > 0
- ; entry++, nentries--)
- hol_entry_long_iterate (entry, usage_long_opt,
- entry->argp->argp_domain, stream);
- }
-}
-
-/* Make a HOL containing all levels of options in ARGP. CLUSTER is the
- cluster in which ARGP's entries should be clustered, or 0. */
-static struct hol *
-argp_hol (const struct argp *argp, struct hol_cluster *cluster)
-{
- const struct argp_child *child = argp->children;
- struct hol *hol = make_hol (argp, cluster);
- if (child)
- while (child->argp)
- {
- struct hol_cluster *child_cluster =
- ((child->group || child->header)
- /* Put CHILD->argp within its own cluster. */
- ? hol_add_cluster (hol, child->group, child->header,
- child - argp->children, cluster, argp)
- /* Just merge it into the parent's cluster. */
- : cluster);
- hol_append (hol, argp_hol (child->argp, child_cluster)) ;
- child++;
- }
- return hol;
-}
-
-/* Calculate how many different levels with alternative args strings exist in
- ARGP. */
-static size_t
-argp_args_levels (const struct argp *argp)
-{
- size_t levels = 0;
- const struct argp_child *child = argp->children;
-
- if (argp->args_doc && strchr (argp->args_doc, '\n'))
- levels++;
-
- if (child)
- while (child->argp)
- levels += argp_args_levels ((child++)->argp);
-
- return levels;
-}
-
-/* Print all the non-option args documented in ARGP to STREAM. Any output is
- preceded by a space. LEVELS is a pointer to a byte vector the length
- returned by argp_args_levels; it should be initialized to zero, and
- updated by this routine for the next call if ADVANCE is true. True is
- returned as long as there are more patterns to output. */
-static int
-argp_args_usage (const struct argp *argp, const struct argp_state *state,
- char **levels, int advance, argp_fmtstream_t stream)
-{
- char *our_level = *levels;
- int multiple = 0;
- const struct argp_child *child = argp->children;
- const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
- const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
-
- if (fdoc)
- {
- const char *cp = fdoc;
- nl = __strchrnul (cp, '\n');
- if (*nl != '\0')
- /* This is a `multi-level' args doc; advance to the correct position
- as determined by our state in LEVELS, and update LEVELS. */
- {
- int i;
- multiple = 1;
- for (i = 0; i < *our_level; i++)
- cp = nl + 1, nl = __strchrnul (cp, '\n');
- (*levels)++;
- }
-
- /* Manually do line wrapping so that it (probably) won't get wrapped at
- any embedded spaces. */
- space (stream, 1 + nl - cp);
-
- __argp_fmtstream_write (stream, cp, nl - cp);
- }
- if (fdoc && fdoc != tdoc)
- free ((char *)fdoc); /* Free user's modified doc string. */
-
- if (child)
- while (child->argp)
- advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
-
- if (advance && multiple)
- {
- /* Need to increment our level. */
- if (*nl)
- /* There's more we can do here. */
- {
- (*our_level)++;
- advance = 0; /* Our parent shouldn't advance also. */
- }
- else if (*our_level > 0)
- /* We had multiple levels, but used them up; reset to zero. */
- *our_level = 0;
- }
-
- return !advance;
-}
-
-/* Print the documentation for ARGP to STREAM; if POST is false, then
- everything preceeding a `\v' character in the documentation strings (or
- the whole string, for those with none) is printed, otherwise, everything
- following the `\v' character (nothing for strings without). Each separate
- bit of documentation is separated a blank line, and if PRE_BLANK is true,
- then the first is as well. If FIRST_ONLY is true, only the first
- occurrence is output. Returns true if anything was output. */
-static int
-argp_doc (const struct argp *argp, const struct argp_state *state,
- int post, int pre_blank, int first_only,
- argp_fmtstream_t stream)
-{
- const char *text;
- const char *inp_text;
- void *input = 0;
- int anything = 0;
- size_t inp_text_limit = 0;
- const char *doc = dgettext (argp->argp_domain, argp->doc);
- const struct argp_child *child = argp->children;
-
- if (doc)
- {
- char *vt = strchr (doc, '\v');
- inp_text = post ? (vt ? vt + 1 : 0) : doc;
- inp_text_limit = (!post && vt) ? (vt - doc) : 0;
- }
- else
- inp_text = 0;
-
- if (argp->help_filter)
- /* We have to filter the doc strings. */
- {
- if (inp_text_limit)
- /* Copy INP_TEXT so that it's nul-terminated. */
- inp_text = STRNDUP (inp_text, inp_text_limit);
- input = __argp_input (argp, state);
- text =
- (*argp->help_filter) (post
- ? ARGP_KEY_HELP_POST_DOC
- : ARGP_KEY_HELP_PRE_DOC,
- inp_text, input);
- }
- else
- text = (const char *) inp_text;
-
- if (text)
- {
- if (pre_blank)
- __argp_fmtstream_putc (stream, '\n');
-
- if (text == inp_text && inp_text_limit)
- __argp_fmtstream_write (stream, inp_text, inp_text_limit);
- else
- __argp_fmtstream_puts (stream, text);
-
- if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
- __argp_fmtstream_putc (stream, '\n');
-
- anything = 1;
- }
-
- if (text && text != inp_text)
- free ((char *) text); /* Free TEXT returned from the help filter. */
- if (inp_text && inp_text_limit && argp->help_filter)
- free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
-
- if (post && argp->help_filter)
- /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
- {
- text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
- if (text)
- {
- if (anything || pre_blank)
- __argp_fmtstream_putc (stream, '\n');
- __argp_fmtstream_puts (stream, text);
- free ((char *) text);
- if (__argp_fmtstream_point (stream)
- > __argp_fmtstream_lmargin (stream))
- __argp_fmtstream_putc (stream, '\n');
- anything = 1;
- }
- }
-
- if (child)
- while (child->argp && !(first_only && anything))
- anything |=
- argp_doc ((child++)->argp, state,
- post, anything || pre_blank, first_only,
- stream);
-
- return anything;
-}
-
-/* Output a usage message for ARGP to STREAM. If called from
- argp_state_help, STATE is the relevent parsing state. FLAGS are from the
- set ARGP_HELP_*. NAME is what to use wherever a `program name' is
- needed. */
-
-static void
-_help (const struct argp *argp, const struct argp_state *state, FILE *stream,
- unsigned flags, const char *name)
-{
- int anything = 0; /* Whether we've output anything. */
- struct hol *hol = 0;
- argp_fmtstream_t fs;
-
- if (! stream)
- return;
-
- FLOCKFILE (stream);
-
- if (! uparams.valid)
- fill_in_uparams (state);
-
- fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
- if (! fs)
- {
- FUNLOCKFILE (stream);
- return;
- }
-
- if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
- {
- hol = argp_hol (argp, 0);
-
- /* If present, these options always come last. */
- hol_set_group (hol, "help", -1);
- hol_set_group (hol, "version", -1);
-
- hol_sort (hol);
- }
-
- if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
- /* Print a short `Usage:' message. */
- {
- int first_pattern = 1, more_patterns;
- size_t num_pattern_levels = argp_args_levels (argp);
- char *pattern_levels = alloca (num_pattern_levels);
-
- memset (pattern_levels, 0, num_pattern_levels);
-
- do
- {
- int old_lm;
- int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
- char *levels = pattern_levels;
-
- if (first_pattern)
- __argp_fmtstream_printf (fs, "%s %s",
- dgettext (argp->argp_domain, "Usage:"),
- name);
- else
- __argp_fmtstream_printf (fs, "%s %s",
- dgettext (argp->argp_domain, " or: "),
- name);
-
- /* We set the lmargin as well as the wmargin, because hol_usage
- manually wraps options with newline to avoid annoying breaks. */
- old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
-
- if (flags & ARGP_HELP_SHORT_USAGE)
- /* Just show where the options go. */
- {
- if (hol->num_entries > 0)
- __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
- " [OPTION...]"));
- }
- else
- /* Actually print the options. */
- {
- hol_usage (hol, fs);
- flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */
- }
-
- more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
-
- __argp_fmtstream_set_wmargin (fs, old_wm);
- __argp_fmtstream_set_lmargin (fs, old_lm);
-
- __argp_fmtstream_putc (fs, '\n');
- anything = 1;
-
- first_pattern = 0;
- }
- while (more_patterns);
- }
-
- if (flags & ARGP_HELP_PRE_DOC)
- anything |= argp_doc (argp, state, 0, 0, 1, fs);
-
- if (flags & ARGP_HELP_SEE)
- {
- __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
-Try `%s --help' or `%s --usage' for more information.\n"),
- name, name);
- anything = 1;
- }
-
- if (flags & ARGP_HELP_LONG)
- /* Print a long, detailed help message. */
- {
- /* Print info about all the options. */
- if (hol->num_entries > 0)
- {
- if (anything)
- __argp_fmtstream_putc (fs, '\n');
- hol_help (hol, state, fs);
- anything = 1;
- }
- }
-
- if (flags & ARGP_HELP_POST_DOC)
- /* Print any documentation strings at the end. */
- anything |= argp_doc (argp, state, 1, anything, 0, fs);
-
- if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
- {
- if (anything)
- __argp_fmtstream_putc (fs, '\n');
- __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
- "Report bugs to %s.\n"),
- argp_program_bug_address);
- anything = 1;
- }
-
- FUNLOCKFILE (stream);
-
- if (hol)
- hol_free (hol);
-
- __argp_fmtstream_free (fs);
-}
-
-/* Output a usage message for ARGP to STREAM. FLAGS are from the set
- ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
-void __argp_help (const struct argp *argp, FILE *stream,
- unsigned flags, char *name)
-{
- _help (argp, 0, stream, flags, name);
-}
-#ifdef weak_alias
-weak_alias (__argp_help, argp_help)
-#endif
-
-char *__argp_basename(char *name)
-{
- char *short_name = strrchr(name, '/');
- return short_name ? short_name + 1 : name;
-}
-
-char *
-__argp_short_program_name(const struct argp_state *state)
-{
- if (state)
- return state->name;
-#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
- return program_invocation_short_name;
-#elif HAVE_DECL_PROGRAM_INVOCATION_NAME
- return __argp_basename(program_invocation_name);
-#else /* !HAVE_DECL_PROGRAM_INVOCATION_NAME */
- /* FIXME: What now? Miles suggests that it is better to use NULL,
- but currently the value is passed on directly to fputs_unlocked,
- so that requires more changes. */
-# if __GNUC__
- return "";
-# endif /* __GNUC__ */
-#endif /* !HAVE_DECL_PROGRAM_INVOCATION_NAME */
-}
-
-/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
- from the set ARGP_HELP_*. */
-void
-__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
-{
- if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
- {
- if (state && (state->flags & ARGP_LONG_ONLY))
- flags |= ARGP_HELP_LONG_ONLY;
-
- _help (state ? state->root_argp : 0, state, stream, flags,
- __argp_short_program_name(state));
-
- if (!state || ! (state->flags & ARGP_NO_EXIT))
- {
- if (flags & ARGP_HELP_EXIT_ERR)
- exit (argp_err_exit_status);
- if (flags & ARGP_HELP_EXIT_OK)
- exit (0);
- }
- }
-}
-#ifdef weak_alias
-weak_alias (__argp_state_help, argp_state_help)
-#endif
-
-/* If appropriate, print the printf string FMT and following args, preceded
- by the program name and `:', to stderr, and followed by a `Try ... --help'
- message, then exit (1). */
-void
-__argp_error (const struct argp_state *state, const char *fmt, ...)
-{
- if (!state || !(state->flags & ARGP_NO_ERRS))
- {
- FILE *stream = state ? state->err_stream : stderr;
-
- if (stream)
- {
- va_list ap;
-
- FLOCKFILE (stream);
-
- FPUTS_UNLOCKED (__argp_short_program_name(state),
- stream);
- PUTC_UNLOCKED (':', stream);
- PUTC_UNLOCKED (' ', stream);
-
- va_start (ap, fmt);
- vfprintf (stream, fmt, ap);
- va_end (ap);
-
- PUTC_UNLOCKED ('\n', stream);
-
- __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
-
- FUNLOCKFILE (stream);
- }
- }
-}
-#ifdef weak_alias
-weak_alias (__argp_error, argp_error)
-#endif
-
-/* Similar to the standard gnu error-reporting function error(), but will
- respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
- to STATE->err_stream. This is useful for argument parsing code that is
- shared between program startup (when exiting is desired) and runtime
- option parsing (when typically an error code is returned instead). The
- difference between this function and argp_error is that the latter is for
- *parsing errors*, and the former is for other problems that occur during
- parsing but don't reflect a (syntactic) problem with the input. */
-void
-__argp_failure (const struct argp_state *state, int status, int errnum,
- const char *fmt, ...)
-{
- if (!state || !(state->flags & ARGP_NO_ERRS))
- {
- FILE *stream = state ? state->err_stream : stderr;
-
- if (stream)
- {
- FLOCKFILE (stream);
-
- FPUTS_UNLOCKED (__argp_short_program_name(state),
- stream);
-
- if (fmt)
- {
- va_list ap;
-
- PUTC_UNLOCKED (':', stream);
- PUTC_UNLOCKED (' ', stream);
-
- va_start (ap, fmt);
- vfprintf (stream, fmt, ap);
- va_end (ap);
- }
-
- if (errnum)
- {
- PUTC_UNLOCKED (':', stream);
- PUTC_UNLOCKED (' ', stream);
- fputs (STRERROR (errnum), stream);
- }
-
- PUTC_UNLOCKED ('\n', stream);
-
- FUNLOCKFILE (stream);
-
- if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
- exit (status);
- }
- }
-}
-#ifdef weak_alias
-weak_alias (__argp_failure, argp_failure)
-#endif
diff --git a/contrib/argp-standalone/argp-namefrob.h b/contrib/argp-standalone/argp-namefrob.h
deleted file mode 100644
index 0ce11481a7b..00000000000
--- a/contrib/argp-standalone/argp-namefrob.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Name frobnication for compiling argp outside of glibc
- Copyright (C) 1997 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#if !_LIBC
-/* This code is written for inclusion in gnu-libc, and uses names in the
- namespace reserved for libc. If we're not compiling in libc, define those
- names to be the normal ones instead. */
-
-/* argp-parse functions */
-#undef __argp_parse
-#define __argp_parse argp_parse
-#undef __option_is_end
-#define __option_is_end _option_is_end
-#undef __option_is_short
-#define __option_is_short _option_is_short
-#undef __argp_input
-#define __argp_input _argp_input
-
-/* argp-help functions */
-#undef __argp_help
-#define __argp_help argp_help
-#undef __argp_error
-#define __argp_error argp_error
-#undef __argp_failure
-#define __argp_failure argp_failure
-#undef __argp_state_help
-#define __argp_state_help argp_state_help
-#undef __argp_usage
-#define __argp_usage argp_usage
-#undef __argp_basename
-#define __argp_basename _argp_basename
-#undef __argp_short_program_name
-#define __argp_short_program_name _argp_short_program_name
-
-/* argp-fmtstream functions */
-#undef __argp_make_fmtstream
-#define __argp_make_fmtstream argp_make_fmtstream
-#undef __argp_fmtstream_free
-#define __argp_fmtstream_free argp_fmtstream_free
-#undef __argp_fmtstream_putc
-#define __argp_fmtstream_putc argp_fmtstream_putc
-#undef __argp_fmtstream_puts
-#define __argp_fmtstream_puts argp_fmtstream_puts
-#undef __argp_fmtstream_write
-#define __argp_fmtstream_write argp_fmtstream_write
-#undef __argp_fmtstream_printf
-#define __argp_fmtstream_printf argp_fmtstream_printf
-#undef __argp_fmtstream_set_lmargin
-#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
-#undef __argp_fmtstream_set_rmargin
-#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
-#undef __argp_fmtstream_set_wmargin
-#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
-#undef __argp_fmtstream_point
-#define __argp_fmtstream_point argp_fmtstream_point
-#undef __argp_fmtstream_update
-#define __argp_fmtstream_update _argp_fmtstream_update
-#undef __argp_fmtstream_ensure
-#define __argp_fmtstream_ensure _argp_fmtstream_ensure
-#undef __argp_fmtstream_lmargin
-#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
-#undef __argp_fmtstream_rmargin
-#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
-#undef __argp_fmtstream_wmargin
-#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
-
-/* normal libc functions we call */
-#undef __sleep
-#define __sleep sleep
-#undef __strcasecmp
-#define __strcasecmp strcasecmp
-#undef __vsnprintf
-#define __vsnprintf vsnprintf
-
-#endif /* !_LIBC */
-
-#ifndef __set_errno
-#define __set_errno(e) (errno = (e))
-#endif
diff --git a/contrib/argp-standalone/argp-parse.c b/contrib/argp-standalone/argp-parse.c
deleted file mode 100644
index 78f7bf139b6..00000000000
--- a/contrib/argp-standalone/argp-parse.c
+++ /dev/null
@@ -1,1305 +0,0 @@
-/* Hierarchial argument parsing
- Copyright (C) 1995, 96, 97, 98, 99, 2000,2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <limits.h>
-#include <assert.h>
-
-#if HAVE_MALLOC_H
-/* Needed, for alloca on windows */
-# include <malloc.h>
-#endif
-
-#ifndef _
-/* This is for other GNU distributions with internationalized messages.
- When compiling libc, the _ macro is predefined. */
-# if defined HAVE_LIBINTL_H || defined _LIBC
-# include <libintl.h>
-# ifdef _LIBC
-# undef dgettext
-# define dgettext(domain, msgid) __dcgettext (domain, msgid, LC_MESSAGES)
-# endif
-# else
-# define dgettext(domain, msgid) (msgid)
-# define gettext(msgid) (msgid)
-# endif
-#endif
-#ifndef N_
-# define N_(msgid) (msgid)
-#endif
-
-#if _LIBC - 0
-#include <bits/libc-lock.h>
-#else
-#ifdef HAVE_CTHREADS_H
-#include <cthreads.h>
-#endif
-#endif /* _LIBC */
-
-#include "argp.h"
-#include "argp-namefrob.h"
-
-
-/* The meta-argument used to prevent any further arguments being interpreted
- as options. */
-#define QUOTE "--"
-
-/* EZ alias for ARGP_ERR_UNKNOWN. */
-#define EBADKEY ARGP_ERR_UNKNOWN
-
-
-/* Default options. */
-
-/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
- for one second intervals, decrementing _ARGP_HANG until it's zero. Thus
- you can force the program to continue by attaching a debugger and setting
- it to 0 yourself. */
-volatile int _argp_hang;
-
-#define OPT_PROGNAME -2
-#define OPT_USAGE -3
-#if HAVE_SLEEP && HAVE_GETPID
-#define OPT_HANG -4
-#endif
-
-static const struct argp_option argp_default_options[] =
-{
- {"help", '?', 0, 0, N_("Give this help list"), -1},
- {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message"), 0 },
- {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN,
- N_("Set the program name"), 0},
-#if OPT_HANG
- {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
- N_("Hang for SECS seconds (default 3600)"), 0 },
-#endif
- {0, 0, 0, 0, 0, 0}
-};
-
-static error_t
-argp_default_parser (int key, char *arg, struct argp_state *state)
-{
- switch (key)
- {
- case '?':
- __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
- break;
- case OPT_USAGE:
- __argp_state_help (state, state->out_stream,
- ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
- break;
-
- case OPT_PROGNAME: /* Set the program name. */
-#if HAVE_DECL_PROGRAM_INVOCATION_NAME
- program_invocation_name = arg;
-#endif
- /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
- __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
- to be that, so we have to be a bit careful here.] */
-
- /* Update what we use for messages. */
-
- state->name = __argp_basename(arg);
-
-#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
- program_invocation_short_name = state->name;
-#endif
-
- if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
- == ARGP_PARSE_ARGV0)
- /* Update what getopt uses too. */
- state->argv[0] = arg;
-
- break;
-
-#if OPT_HANG
- case OPT_HANG:
- _argp_hang = atoi (arg ? arg : "3600");
- fprintf(state->err_stream, "%s: pid = %ld\n",
- state->name, (long) getpid());
- while (_argp_hang-- > 0)
- __sleep (1);
- break;
-#endif
-
- default:
- return EBADKEY;
- }
- return 0;
-}
-
-static const struct argp argp_default_argp =
- {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
-
-
-static const struct argp_option argp_version_options[] =
-{
- {"version", 'V', 0, 0, N_("Print program version"), -1},
- {0, 0, 0, 0, 0, 0 }
-};
-
-static error_t
-argp_version_parser (int key, char *arg UNUSED, struct argp_state *state)
-{
- switch (key)
- {
- case 'V':
- if (argp_program_version_hook)
- (*argp_program_version_hook) (state->out_stream, state);
- else if (argp_program_version)
- fprintf (state->out_stream, "%s\n", argp_program_version);
- else
- __argp_error (state, dgettext (state->root_argp->argp_domain,
- "(PROGRAM ERROR) No version known!?"));
- if (! (state->flags & ARGP_NO_EXIT))
- exit (0);
- break;
- default:
- return EBADKEY;
- }
- return 0;
-}
-
-static const struct argp argp_version_argp =
- {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
-
-
-
-/* The state of a `group' during parsing. Each group corresponds to a
- particular argp structure from the tree of such descending from the top
- level argp passed to argp_parse. */
-struct group
-{
- /* This group's parsing function. */
- argp_parser_t parser;
-
- /* Which argp this group is from. */
- const struct argp *argp;
-
- /* The number of non-option args sucessfully handled by this parser. */
- unsigned args_processed;
-
- /* This group's parser's parent's group. */
- struct group *parent;
- unsigned parent_index; /* And the our position in the parent. */
-
- /* These fields are swapped into and out of the state structure when
- calling this group's parser. */
- void *input, **child_inputs;
- void *hook;
-};
-
-/* Call GROUP's parser with KEY and ARG, swapping any group-specific info
- from STATE before calling, and back into state afterwards. If GROUP has
- no parser, EBADKEY is returned. */
-static error_t
-group_parse (struct group *group, struct argp_state *state, int key, char *arg)
-{
- if (group->parser)
- {
- error_t err;
- state->hook = group->hook;
- state->input = group->input;
- state->child_inputs = group->child_inputs;
- state->arg_num = group->args_processed;
- err = (*group->parser)(key, arg, state);
- group->hook = state->hook;
- return err;
- }
- else
- return EBADKEY;
-}
-
-struct parser
-{
- const struct argp *argp;
-
- const char *posixly_correct;
-
- /* True if there are only no-option arguments left, which are just
- passed verbatim with ARGP_KEY_ARG. This is set if we encounter a
- quote, or the end of the proper options, but may be cleared again
- if the user moves the next argument pointer backwards. */
- int args_only;
-
- /* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything, the default is
- REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is
- defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options; stop option
- processing when the first non-option is seen. This is what Unix
- does. This mode of operation is selected by either setting the
- environment variable POSIXLY_CORRECT, or using `+' as the first
- character of the list of option characters.
-
- PERMUTE is the default. We permute the contents of ARGV as we
- scan, so that eventually all the non-options are at the end. This
- allows options to be given in any order, even with programs that
- were not written to expect this.
-
- RETURN_IN_ORDER is an option available to programs that were
- written to expect options and other ARGV-elements in any order
- and that care about the ordering of the two. We describe each
- non-option ARGV-element as if it were the argument of an option
- with character code 1. Using `-' as the first character of the
- list of option characters selects this mode of operation.
-
- */
- enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
-
- /* A segment of non-option arguments that have been skipped for
- later processing, after all options. `first_nonopt' is the index
- in ARGV of the first of them; `last_nonopt' is the index after
- the last of them.
-
- If quoted or args_only is non-zero, this segment should be empty. */
-
- /* FIXME: I'd prefer to use unsigned, but it's more consistent to
- use the same type as for state.next. */
- int first_nonopt;
- int last_nonopt;
-
- /* String of all recognized short options. Needed for ARGP_LONG_ONLY. */
- /* FIXME: Perhaps change to a pointer to a suitable bitmap instead? */
- char *short_opts;
-
- /* For parsing combined short options. */
- char *nextchar;
-
- /* States of the various parsing groups. */
- struct group *groups;
- /* The end of the GROUPS array. */
- struct group *egroup;
- /* An vector containing storage for the CHILD_INPUTS field in all groups. */
- void **child_inputs;
-
- /* State block supplied to parsing routines. */
- struct argp_state state;
-
- /* Memory used by this parser. */
- void *storage;
-};
-
-/* Search for a group defining a short option. */
-static const struct argp_option *
-find_short_option(struct parser *parser, int key, struct group **p)
-{
- struct group *group;
-
- assert(key >= 0);
- assert(isascii(key));
-
- for (group = parser->groups; group < parser->egroup; group++)
- {
- const struct argp_option *opts;
-
- for (opts = group->argp->options; !__option_is_end(opts); opts++)
- if (opts->key == key)
- {
- *p = group;
- return opts;
- }
- }
- return NULL;
-}
-
-enum match_result { MATCH_EXACT, MATCH_PARTIAL, MATCH_NO };
-
-/* If defined, allow complete.el-like abbreviations of long options. */
-#ifndef ARGP_COMPLETE
-#define ARGP_COMPLETE 0
-#endif
-
-/* Matches an encountern long-option argument ARG against an option NAME.
- * ARG is terminated by NUL or '='. */
-static enum match_result
-match_option(const char *arg, const char *name)
-{
- unsigned i, j;
- for (i = j = 0;; i++, j++)
- {
- switch(arg[i])
- {
- case '\0':
- case '=':
- return name[j] ? MATCH_PARTIAL : MATCH_EXACT;
-#if ARGP_COMPLETE
- case '-':
- while (name[j] != '-')
- if (!name[j++])
- return MATCH_NO;
- break;
-#endif
- default:
- if (arg[i] != name[j])
- return MATCH_NO;
- }
- }
-}
-
-static const struct argp_option *
-find_long_option(struct parser *parser,
- const char *arg,
- struct group **p)
-{
- struct group *group;
-
- /* Partial match found so far. */
- struct group *matched_group = NULL;
- const struct argp_option *matched_option = NULL;
-
- /* Number of partial matches. */
- int num_partial = 0;
-
- for (group = parser->groups; group < parser->egroup; group++)
- {
- const struct argp_option *opts;
-
- for (opts = group->argp->options; !__option_is_end(opts); opts++)
- {
- if (!opts->name)
- continue;
- switch (match_option(arg, opts->name))
- {
- case MATCH_NO:
- break;
- case MATCH_PARTIAL:
- num_partial++;
-
- matched_group = group;
- matched_option = opts;
-
- break;
- case MATCH_EXACT:
- /* Exact match. */
- *p = group;
- return opts;
- }
- }
- }
- if (num_partial == 1)
- {
- *p = matched_group;
- return matched_option;
- }
-
- return NULL;
-}
-
-
-/* The next usable entries in the various parser tables being filled in by
- convert_options. */
-struct parser_convert_state
-{
- struct parser *parser;
- char *short_end;
- void **child_inputs_end;
-};
-
-/* Initialize GROUP from ARGP. If CVT->SHORT_END is non-NULL, short
- options are recorded in the short options string. Returns the next
- unused group entry. CVT holds state used during the conversion. */
-static struct group *
-convert_options (const struct argp *argp,
- struct group *parent, unsigned parent_index,
- struct group *group, struct parser_convert_state *cvt)
-{
- const struct argp_option *opt = argp->options;
- const struct argp_child *children = argp->children;
-
- if (opt || argp->parser)
- {
- /* This parser needs a group. */
- if (cvt->short_end)
- {
- /* Record any short options. */
- for ( ; !__option_is_end (opt); opt++)
- if (__option_is_short(opt))
- *cvt->short_end++ = opt->key;
- }
-
- group->parser = argp->parser;
- group->argp = argp;
- group->args_processed = 0;
- group->parent = parent;
- group->parent_index = parent_index;
- group->input = 0;
- group->hook = 0;
- group->child_inputs = 0;
-
- if (children)
- /* Assign GROUP's CHILD_INPUTS field some space from
- CVT->child_inputs_end.*/
- {
- unsigned num_children = 0;
- while (children[num_children].argp)
- num_children++;
- group->child_inputs = cvt->child_inputs_end;
- cvt->child_inputs_end += num_children;
- }
- parent = group++;
- }
- else
- parent = 0;
-
- if (children)
- {
- unsigned index = 0;
- while (children->argp)
- group =
- convert_options (children++->argp, parent, index++, group, cvt);
- }
-
- return group;
-}
-/* Allocate and initialize the group structures, so that they are
- ordered as if by traversing the corresponding argp parser tree in
- pre-order. Also build the list of short options, if that is needed. */
-static void
-parser_convert (struct parser *parser, const struct argp *argp)
-{
- struct parser_convert_state cvt;
-
- cvt.parser = parser;
- cvt.short_end = parser->short_opts;
- cvt.child_inputs_end = parser->child_inputs;
-
- parser->argp = argp;
-
- if (argp)
- parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
- else
- parser->egroup = parser->groups; /* No parsers at all! */
-
- if (parser->short_opts)
- *cvt.short_end ='\0';
-}
-
-/* Lengths of various parser fields which we will allocated. */
-struct parser_sizes
-{
- /* Needed only ARGP_LONG_ONLY */
- size_t short_len; /* Number of short options. */
-
- size_t num_groups; /* Group structures we allocate. */
- size_t num_child_inputs; /* Child input slots. */
-};
-
-/* For ARGP, increments the NUM_GROUPS field in SZS by the total
- number of argp structures descended from it, and the SHORT_LEN by
- the total number of short options. */
-static void
-calc_sizes (const struct argp *argp, struct parser_sizes *szs)
-{
- const struct argp_child *child = argp->children;
- const struct argp_option *opt = argp->options;
-
- if (opt || argp->parser)
- {
- /* This parser needs a group. */
- szs->num_groups++;
- if (opt)
- {
- while (__option_is_short (opt++))
- szs->short_len++;
- }
- }
-
- if (child)
- while (child->argp)
- {
- calc_sizes ((child++)->argp, szs);
- szs->num_child_inputs++;
- }
-}
-
-/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */
-static error_t
-parser_init (struct parser *parser, const struct argp *argp,
- int argc, char **argv, int flags, void *input)
-{
- error_t err = 0;
- struct group *group;
- struct parser_sizes szs;
-
- parser->posixly_correct = getenv ("POSIXLY_CORRECT");
-
- if (flags & ARGP_IN_ORDER)
- parser->ordering = RETURN_IN_ORDER;
- else if (flags & ARGP_NO_ARGS)
- parser->ordering = REQUIRE_ORDER;
- else if (parser->posixly_correct)
- parser->ordering = REQUIRE_ORDER;
- else
- parser->ordering = PERMUTE;
-
- szs.short_len = 0;
- szs.num_groups = 0;
- szs.num_child_inputs = 0;
-
- if (argp)
- calc_sizes (argp, &szs);
-
- if (!(flags & ARGP_LONG_ONLY))
- /* We have no use for the short option array. */
- szs.short_len = 0;
-
- /* Lengths of the various bits of storage used by PARSER. */
-#define GLEN (szs.num_groups + 1) * sizeof (struct group)
-#define CLEN (szs.num_child_inputs * sizeof (void *))
-#define SLEN (szs.short_len + 1)
-#define STORAGE(offset) ((void *) (((char *) parser->storage) + (offset)))
-
- parser->storage = malloc (GLEN + CLEN + SLEN);
- if (! parser->storage)
- return ENOMEM;
-
- parser->groups = parser->storage;
-
- parser->child_inputs = STORAGE(GLEN);
- memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
-
- if (flags & ARGP_LONG_ONLY)
- parser->short_opts = STORAGE(GLEN + CLEN);
- else
- parser->short_opts = NULL;
-
- parser_convert (parser, argp);
-
- memset (&parser->state, 0, sizeof (struct argp_state));
-
- parser->state.root_argp = parser->argp;
- parser->state.argc = argc;
- parser->state.argv = argv;
- parser->state.flags = flags;
- parser->state.err_stream = stderr;
- parser->state.out_stream = stdout;
- parser->state.pstate = parser;
-
- parser->args_only = 0;
- parser->nextchar = NULL;
- parser->first_nonopt = parser->last_nonopt = 0;
-
- /* Call each parser for the first time, giving it a chance to propagate
- values to child parsers. */
- if (parser->groups < parser->egroup)
- parser->groups->input = input;
- for (group = parser->groups;
- group < parser->egroup && (!err || err == EBADKEY);
- group++)
- {
- if (group->parent)
- /* If a child parser, get the initial input value from the parent. */
- group->input = group->parent->child_inputs[group->parent_index];
-
- if (!group->parser
- && group->argp->children && group->argp->children->argp)
- /* For the special case where no parsing function is supplied for an
- argp, propagate its input to its first child, if any (this just
- makes very simple wrapper argps more convenient). */
- group->child_inputs[0] = group->input;
-
- err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);
- }
- if (err == EBADKEY)
- err = 0; /* Some parser didn't understand. */
-
- if (err)
- return err;
-
- if (argv[0] && !(parser->state.flags & ARGP_PARSE_ARGV0))
- /* There's an argv[0]; use it for messages. */
- {
- parser->state.name = __argp_basename(argv[0]);
-
- /* Don't parse it as an argument. */
- parser->state.next = 1;
- }
- else
- parser->state.name = __argp_short_program_name(NULL);
-
- return 0;
-}
-
-/* Free any storage consumed by PARSER (but not PARSER itself). */
-static error_t
-parser_finalize (struct parser *parser,
- error_t err, int arg_ebadkey, int *end_index)
-{
- struct group *group;
-
- if (err == EBADKEY && arg_ebadkey)
- /* Suppress errors generated by unparsed arguments. */
- err = 0;
-
- if (! err)
- {
- if (parser->state.next == parser->state.argc)
- /* We successfully parsed all arguments! Call all the parsers again,
- just a few more times... */
- {
- for (group = parser->groups;
- group < parser->egroup && (!err || err==EBADKEY);
- group++)
- if (group->args_processed == 0)
- err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0);
- for (group = parser->egroup - 1;
- group >= parser->groups && (!err || err==EBADKEY);
- group--)
- err = group_parse (group, &parser->state, ARGP_KEY_END, 0);
-
- if (err == EBADKEY)
- err = 0; /* Some parser didn't understand. */
-
- /* Tell the user that all arguments are parsed. */
- if (end_index)
- *end_index = parser->state.next;
- }
- else if (end_index)
- /* Return any remaining arguments to the user. */
- *end_index = parser->state.next;
- else
- /* No way to return the remaining arguments, they must be bogus. */
- {
- if (!(parser->state.flags & ARGP_NO_ERRS)
- && parser->state.err_stream)
- fprintf (parser->state.err_stream,
- dgettext (parser->argp->argp_domain,
- "%s: Too many arguments\n"),
- parser->state.name);
- err = EBADKEY;
- }
- }
-
- /* Okay, we're all done, with either an error or success; call the parsers
- to indicate which one. */
-
- if (err)
- {
- /* Maybe print an error message. */
- if (err == EBADKEY)
- /* An appropriate message describing what the error was should have
- been printed earlier. */
- __argp_state_help (&parser->state, parser->state.err_stream,
- ARGP_HELP_STD_ERR);
-
- /* Since we didn't exit, give each parser an error indication. */
- for (group = parser->groups; group < parser->egroup; group++)
- group_parse (group, &parser->state, ARGP_KEY_ERROR, 0);
- }
- else
- /* Notify parsers of success, and propagate back values from parsers. */
- {
- /* We pass over the groups in reverse order so that child groups are
- given a chance to do there processing before passing back a value to
- the parent. */
- for (group = parser->egroup - 1
- ; group >= parser->groups && (!err || err == EBADKEY)
- ; group--)
- err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0);
- if (err == EBADKEY)
- err = 0; /* Some parser didn't understand. */
- }
-
- /* Call parsers once more, to do any final cleanup. Errors are ignored. */
- for (group = parser->egroup - 1; group >= parser->groups; group--)
- group_parse (group, &parser->state, ARGP_KEY_FINI, 0);
-
- if (err == EBADKEY)
- err = EINVAL;
-
- free (parser->storage);
-
- return err;
-}
-
-/* Call the user parsers to parse the non-option argument VAL, at the
- current position, returning any error. The state NEXT pointer
- should point to the argument; this function will adjust it
- correctly to reflect however many args actually end up being
- consumed. */
-static error_t
-parser_parse_arg (struct parser *parser, char *val)
-{
- /* Save the starting value of NEXT */
- int index = parser->state.next;
- error_t err = EBADKEY;
- struct group *group;
- int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */
-
- /* Try to parse the argument in each parser. */
- for (group = parser->groups
- ; group < parser->egroup && err == EBADKEY
- ; group++)
- {
- parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */
- key = ARGP_KEY_ARG;
- err = group_parse (group, &parser->state, key, val);
-
- if (err == EBADKEY)
- /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */
- {
- parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */
- key = ARGP_KEY_ARGS;
- err = group_parse (group, &parser->state, key, 0);
- }
- }
-
- if (! err)
- {
- if (key == ARGP_KEY_ARGS)
- /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't
- changed by the user, *all* arguments should be considered
- consumed. */
- parser->state.next = parser->state.argc;
-
- if (parser->state.next > index)
- /* Remember that we successfully processed a non-option
- argument -- but only if the user hasn't gotten tricky and set
- the clock back. */
- (--group)->args_processed += (parser->state.next - index);
- else
- /* The user wants to reparse some args, so try looking for options again. */
- parser->args_only = 0;
- }
-
- return err;
-}
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,next), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved. */
-
-static void
-exchange (struct parser *parser)
-{
- int bottom = parser->first_nonopt;
- int middle = parser->last_nonopt;
- int top = parser->state.next;
- char **argv = parser->state.argv;
-
- char *tem;
-
- /* Exchange the shorter segment with the far end of the longer segment.
- That puts the shorter segment into the right place.
- It leaves the longer segment in the right place overall,
- but it consists of two parts that need to be swapped next. */
-
- while (top > middle && middle > bottom)
- {
- if (top - middle > middle - bottom)
- {
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
-
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- }
- /* Exclude the moved bottom segment from further swapping. */
- top -= len;
- }
- else
- {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
-
- /* Swap it with the bottom part of the bottom segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- }
- /* Exclude the moved top segment from further swapping. */
- bottom += len;
- }
- }
-
- /* Update records for the slots the non-options now occupy. */
-
- parser->first_nonopt += (parser->state.next - parser->last_nonopt);
- parser->last_nonopt = parser->state.next;
-}
-
-
-
-enum arg_type { ARG_ARG, ARG_SHORT_OPTION,
- ARG_LONG_OPTION, ARG_LONG_ONLY_OPTION,
- ARG_QUOTE };
-
-static enum arg_type
-classify_arg(struct parser *parser, char *arg, char **opt)
-{
- if (arg[0] == '-')
- /* Looks like an option... */
- switch (arg[1])
- {
- case '\0':
- /* "-" is not an option. */
- return ARG_ARG;
- case '-':
- /* Long option, or quote. */
- if (!arg[2])
- return ARG_QUOTE;
-
- /* A long option. */
- if (opt)
- *opt = arg + 2;
- return ARG_LONG_OPTION;
-
- default:
- /* Short option. But if ARGP_LONG_ONLY, it can also be a long option. */
-
- if (opt)
- *opt = arg + 1;
-
- if (parser->state.flags & ARGP_LONG_ONLY)
- {
- /* Rules from getopt.c:
-
- If long_only and the ARGV-element has the form "-f",
- where f is a valid short option, don't consider it an
- abbreviated form of a long option that starts with f.
- Otherwise there would be no way to give the -f short
- option.
-
- On the other hand, if there's a long option "fubar" and
- the ARGV-element is "-fu", do consider that an
- abbreviation of the long option, just like "--fu", and
- not "-f" with arg "u".
-
- This distinction seems to be the most useful approach. */
-
- assert(parser->short_opts);
-
- if (arg[2] || !strchr(parser->short_opts, arg[1]))
- return ARG_LONG_ONLY_OPTION;
- }
-
- return ARG_SHORT_OPTION;
- }
-
- else
- return ARG_ARG;
-}
-
-/* Parse the next argument in PARSER (as indicated by PARSER->state.next).
- Any error from the parsers is returned, and *ARGP_EBADKEY indicates
- whether a value of EBADKEY is due to an unrecognized argument (which is
- generally not fatal). */
-static error_t
-parser_parse_next (struct parser *parser, int *arg_ebadkey)
-{
- if (parser->state.quoted && parser->state.next < parser->state.quoted)
- /* The next argument pointer has been moved to before the quoted
- region, so pretend we never saw the quoting `--', and start
- looking for options again. If the `--' is still there we'll just
- process it one more time. */
- parser->state.quoted = parser->args_only = 0;
-
- /* Give FIRST_NONOPT & LAST_NONOPT rational values if NEXT has been
- moved back by the user (who may also have changed the arguments). */
- if (parser->last_nonopt > parser->state.next)
- parser->last_nonopt = parser->state.next;
- if (parser->first_nonopt > parser->state.next)
- parser->first_nonopt = parser->state.next;
-
- if (parser->nextchar)
- /* Deal with short options. */
- {
- struct group *group;
- char c;
- const struct argp_option *option;
- char *value = NULL;;
-
- assert(!parser->args_only);
-
- c = *parser->nextchar++;
-
- option = find_short_option(parser, c, &group);
- if (!option)
- {
- if (parser->posixly_correct)
- /* 1003.2 specifies the format of this message. */
- fprintf (parser->state.err_stream,
- dgettext(parser->state.root_argp->argp_domain,
- "%s: illegal option -- %c\n"),
- parser->state.name, c);
- else
- fprintf (parser->state.err_stream,
- dgettext(parser->state.root_argp->argp_domain,
- "%s: invalid option -- %c\n"),
- parser->state.name, c);
-
- *arg_ebadkey = 0;
- return EBADKEY;
- }
-
- if (!*parser->nextchar)
- parser->nextchar = NULL;
-
- if (option->arg)
- {
- value = parser->nextchar;
- parser->nextchar = NULL;
-
- if (!value
- && !(option->flags & OPTION_ARG_OPTIONAL))
- /* We need an mandatory argument. */
- {
- if (parser->state.next == parser->state.argc)
- /* Missing argument */
- {
- /* 1003.2 specifies the format of this message. */
- fprintf (parser->state.err_stream,
- dgettext(parser->state.root_argp->argp_domain,
- "%s: option requires an argument -- %c\n"),
- parser->state.name, c);
-
- *arg_ebadkey = 0;
- return EBADKEY;
- }
- value = parser->state.argv[parser->state.next++];
- }
- }
- return group_parse(group, &parser->state,
- option->key, value);
- }
- else
- /* Advance to the next ARGV-element. */
- {
- if (parser->args_only)
- {
- *arg_ebadkey = 1;
- if (parser->state.next >= parser->state.argc)
- /* We're done. */
- return EBADKEY;
- else
- return parser_parse_arg(parser,
- parser->state.argv[parser->state.next]);
- }
-
- if (parser->state.next >= parser->state.argc)
- /* Almost done. If there are non-options that we skipped
- previously, we should process them now. */
- {
- *arg_ebadkey = 1;
- if (parser->first_nonopt != parser->last_nonopt)
- {
- exchange(parser);
-
- /* Start processing the arguments we skipped previously. */
- parser->state.next = parser->first_nonopt;
-
- parser->first_nonopt = parser->last_nonopt = 0;
-
- parser->args_only = 1;
- return 0;
- }
- else
- /* Indicate that we're really done. */
- return EBADKEY;
- }
- else
- /* Look for options. */
- {
- char *arg = parser->state.argv[parser->state.next];
-
- char *optstart;
- enum arg_type token = classify_arg(parser, arg, &optstart);
-
- switch (token)
- {
- case ARG_ARG:
- switch (parser->ordering)
- {
- case PERMUTE:
- if (parser->first_nonopt == parser->last_nonopt)
- /* Skipped sequence is empty; start a new one. */
- parser->first_nonopt = parser->last_nonopt = parser->state.next;
-
- else if (parser->last_nonopt != parser->state.next)
- /* We have a non-empty skipped sequence, and
- we're not at the end-point, so move it. */
- exchange(parser);
-
- assert(parser->last_nonopt == parser->state.next);
-
- /* Skip this argument for now. */
- parser->state.next++;
- parser->last_nonopt = parser->state.next;
-
- return 0;
-
- case REQUIRE_ORDER:
- /* Implicit quote before the first argument. */
- parser->args_only = 1;
- return 0;
-
- case RETURN_IN_ORDER:
- *arg_ebadkey = 1;
- return parser_parse_arg(parser, arg);
-
- default:
- abort();
- }
- case ARG_QUOTE:
- /* Skip it, then exchange with any previous non-options. */
- parser->state.next++;
- assert (parser->last_nonopt != parser->state.next);
-
- if (parser->first_nonopt != parser->last_nonopt)
- {
- exchange(parser);
-
- /* Start processing the skipped and the quoted
- arguments. */
-
- parser->state.quoted = parser->state.next = parser->first_nonopt;
-
- /* Also empty the skipped-list, to avoid confusion
- if the user resets the next pointer. */
- parser->first_nonopt = parser->last_nonopt = 0;
- }
- else
- parser->state.quoted = parser->state.next;
-
- parser->args_only = 1;
- return 0;
-
- case ARG_LONG_ONLY_OPTION:
- case ARG_LONG_OPTION:
- {
- struct group *group;
- const struct argp_option *option;
- char *value;
-
- parser->state.next++;
- option = find_long_option(parser, optstart, &group);
-
- if (!option)
- {
- /* NOTE: This includes any "=something" in the output. */
- fprintf (parser->state.err_stream,
- dgettext(parser->state.root_argp->argp_domain,
- "%s: unrecognized option `%s'\n"),
- parser->state.name, arg);
- *arg_ebadkey = 0;
- return EBADKEY;
- }
-
- value = strchr(optstart, '=');
- if (value)
- value++;
-
- if (value && !option->arg)
- /* Unexpected argument. */
- {
- if (token == ARG_LONG_OPTION)
- /* --option */
- fprintf (parser->state.err_stream,
- dgettext(parser->state.root_argp->argp_domain,
- "%s: option `--%s' doesn't allow an argument\n"),
- parser->state.name, option->name);
- else
- /* +option or -option */
- fprintf (parser->state.err_stream,
- dgettext(parser->state.root_argp->argp_domain,
- "%s: option `%c%s' doesn't allow an argument\n"),
- parser->state.name, arg[0], option->name);
-
- *arg_ebadkey = 0;
- return EBADKEY;
- }
-
- if (option->arg && !value
- && !(option->flags & OPTION_ARG_OPTIONAL))
- /* We need an mandatory argument. */
- {
- if (parser->state.next == parser->state.argc)
- /* Missing argument */
- {
- if (token == ARG_LONG_OPTION)
- /* --option */
- fprintf (parser->state.err_stream,
- dgettext(parser->state.root_argp->argp_domain,
- "%s: option `--%s' requires an argument\n"),
- parser->state.name, option->name);
- else
- /* +option or -option */
- fprintf (parser->state.err_stream,
- dgettext(parser->state.root_argp->argp_domain,
- "%s: option `%c%s' requires an argument\n"),
- parser->state.name, arg[0], option->name);
-
- *arg_ebadkey = 0;
- return EBADKEY;
- }
-
- value = parser->state.argv[parser->state.next++];
- }
- *arg_ebadkey = 0;
- return group_parse(group, &parser->state,
- option->key, value);
- }
- case ARG_SHORT_OPTION:
- parser->state.next++;
- parser->nextchar = optstart;
- return 0;
-
- default:
- abort();
- }
- }
- }
-}
-
-/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
- FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the
- index in ARGV of the first unparsed option is returned in it. If an
- unknown option is present, EINVAL is returned; if some parser routine
- returned a non-zero value, it is returned; otherwise 0 is returned. */
-error_t
-__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
- int *end_index, void *input)
-{
- error_t err;
- struct parser parser;
-
- /* If true, then err == EBADKEY is a result of a non-option argument failing
- to be parsed (which in some cases isn't actually an error). */
- int arg_ebadkey = 0;
-
- if (! (flags & ARGP_NO_HELP))
- /* Add our own options. */
- {
- struct argp_child *child = alloca (4 * sizeof (struct argp_child));
- struct argp *top_argp = alloca (sizeof (struct argp));
-
- /* TOP_ARGP has no options, it just serves to group the user & default
- argps. */
- memset (top_argp, 0, sizeof (*top_argp));
- top_argp->children = child;
-
- memset (child, 0, 4 * sizeof (struct argp_child));
-
- if (argp)
- (child++)->argp = argp;
- (child++)->argp = &argp_default_argp;
- if (argp_program_version || argp_program_version_hook)
- (child++)->argp = &argp_version_argp;
- child->argp = 0;
-
- argp = top_argp;
- }
-
- /* Construct a parser for these arguments. */
- err = parser_init (&parser, argp, argc, argv, flags, input);
-
- if (! err)
- /* Parse! */
- {
- while (! err)
- err = parser_parse_next (&parser, &arg_ebadkey);
- err = parser_finalize (&parser, err, arg_ebadkey, end_index);
- }
-
- return err;
-}
-#ifdef weak_alias
-weak_alias (__argp_parse, argp_parse)
-#endif
-
-/* Return the input field for ARGP in the parser corresponding to STATE; used
- by the help routines. */
-void *
-__argp_input (const struct argp *argp, const struct argp_state *state)
-{
- if (state)
- {
- struct group *group;
- struct parser *parser = state->pstate;
-
- for (group = parser->groups; group < parser->egroup; group++)
- if (group->argp == argp)
- return group->input;
- }
-
- return 0;
-}
-#ifdef weak_alias
-weak_alias (__argp_input, _argp_input)
-#endif
-
-/* Defined here, in case a user is not inlining the definitions in
- * argp.h */
-void
-__argp_usage (__const struct argp_state *__state)
-{
- __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
-}
-
-int
-__option_is_short (__const struct argp_option *__opt)
-{
- if (__opt->flags & OPTION_DOC)
- return 0;
- else
- {
- int __key = __opt->key;
- /* FIXME: whether or not a particular key implies a short option
- * ought not to be locale dependent. */
- return __key > 0 && isprint (__key);
- }
-}
-
-int
-__option_is_end (__const struct argp_option *__opt)
-{
- return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
-}
diff --git a/contrib/argp-standalone/argp-pv.c b/contrib/argp-standalone/argp-pv.c
deleted file mode 100644
index d7d374a66bd..00000000000
--- a/contrib/argp-standalone/argp-pv.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Default definition for ARGP_PROGRAM_VERSION.
- Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-/* If set by the user program to a non-zero value, then a default option
- --version is added (unless the ARGP_NO_HELP flag is used), which will
- print this this string followed by a newline and exit (unless the
- ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
-const char *argp_program_version = 0;
diff --git a/contrib/argp-standalone/argp-pvh.c b/contrib/argp-standalone/argp-pvh.c
deleted file mode 100644
index 829a1cda80d..00000000000
--- a/contrib/argp-standalone/argp-pvh.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Default definition for ARGP_PROGRAM_VERSION_HOOK.
- Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "argp.h"
-
-/* If set by the user program to a non-zero value, then a default option
- --version is added (unless the ARGP_NO_HELP flag is used), which calls
- this function with a stream to print the version to and a pointer to the
- current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
- used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
-void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = 0;
diff --git a/contrib/argp-standalone/argp.h b/contrib/argp-standalone/argp.h
deleted file mode 100644
index 29d3dfe9720..00000000000
--- a/contrib/argp-standalone/argp.h
+++ /dev/null
@@ -1,602 +0,0 @@
-/* Hierarchial argument parsing.
- Copyright (C) 1995, 96, 97, 98, 99, 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#ifndef _ARGP_H
-#define _ARGP_H
-
-#include <stdio.h>
-#include <ctype.h>
-
-#define __need_error_t
-#include <errno.h>
-
-#ifndef __THROW
-# define __THROW
-#endif
-
-#ifndef __const
-# define __const const
-#endif
-
-#ifndef __error_t_defined
-typedef int error_t;
-# define __error_t_defined
-#endif
-
-/* FIXME: What's the right way to check for __restrict? Sun's cc seems
- not to have it. Perhaps it's easiest to just delete the use of
- __restrict from the prototypes. */
-#ifndef __restrict
-# ifndef __GNUC___
-# define __restrict
-# endif
-#endif
-
-/* NOTE: We can't use the autoconf tests, since this is supposed to be
- an installed header file and argp's config.h is of course not
- installed. */
-#ifndef PRINTF_STYLE
-# if __GNUC__ >= 2
-# define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a)))
-# else
-# define PRINTF_STYLE(f, a)
-# endif
-#endif
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* A description of a particular option. A pointer to an array of
- these is passed in the OPTIONS field of an argp structure. Each option
- entry can correspond to one long option and/or one short option; more
- names for the same option can be added by following an entry in an option
- array with options having the OPTION_ALIAS flag set. */
-struct argp_option
-{
- /* The long option name. For more than one name for the same option, you
- can use following options with the OPTION_ALIAS flag set. */
- __const char *name;
-
- /* What key is returned for this option. If > 0 and printable, then it's
- also accepted as a short option. */
- int key;
-
- /* If non-NULL, this is the name of the argument associated with this
- option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */
- __const char *arg;
-
- /* OPTION_ flags. */
- int flags;
-
- /* The doc string for this option. If both NAME and KEY are 0, This string
- will be printed outdented from the normal option column, making it
- useful as a group header (it will be the first thing printed in its
- group); in this usage, it's conventional to end the string with a `:'. */
- __const char *doc;
-
- /* The group this option is in. In a long help message, options are sorted
- alphabetically within each group, and the groups presented in the order
- 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with
- if this field 0 will inherit the group number of the previous entry, or
- zero if it's the first one, unless its a group header (NAME and KEY both
- 0), in which case, the previous entry + 1 is the default. Automagic
- options such as --help are put into group -1. */
- int group;
-};
-
-/* The argument associated with this option is optional. */
-#define OPTION_ARG_OPTIONAL 0x1
-
-/* This option isn't displayed in any help messages. */
-#define OPTION_HIDDEN 0x2
-
-/* This option is an alias for the closest previous non-alias option. This
- means that it will be displayed in the same help entry, and will inherit
- fields other than NAME and KEY from the aliased option. */
-#define OPTION_ALIAS 0x4
-
-/* This option isn't actually an option (and so should be ignored by the
- actual option parser), but rather an arbitrary piece of documentation that
- should be displayed in much the same manner as the options. If this flag
- is set, then the option NAME field is displayed unmodified (e.g., no `--'
- prefix is added) at the left-margin (where a *short* option would normally
- be displayed), and the documentation string in the normal place. For
- purposes of sorting, any leading whitespace and puncuation is ignored,
- except that if the first non-whitespace character is not `-', this entry
- is displayed after all options (and OPTION_DOC entries with a leading `-')
- in the same group. */
-#define OPTION_DOC 0x8
-
-/* This option shouldn't be included in `long' usage messages (but is still
- included in help messages). This is mainly intended for options that are
- completely documented in an argp's ARGS_DOC field, in which case including
- the option in the generic usage list would be redundant. For instance,
- if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to
- distinguish these two cases, -x should probably be marked
- OPTION_NO_USAGE. */
-#define OPTION_NO_USAGE 0x10
-
-struct argp; /* fwd declare this type */
-struct argp_state; /* " */
-struct argp_child; /* " */
-
-/* The type of a pointer to an argp parsing function. */
-typedef error_t (*argp_parser_t) (int key, char *arg,
- struct argp_state *state);
-
-/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such
- returns will simply be ignored. For user keys, this error will be turned
- into EINVAL (if the call to argp_parse is such that errors are propagated
- back to the user instead of exiting); returning EINVAL itself would result
- in an immediate stop to parsing in *all* cases. */
-#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */
-
-/* Special values for the KEY argument to an argument parsing function.
- ARGP_ERR_UNKNOWN should be returned if they aren't understood.
-
- The sequence of keys to a parsing function is either (where each
- uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key):
-
- INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all
- or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed
- or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized
-
- The third case is where every parser returned ARGP_KEY_UNKNOWN for an
- argument, in which case parsing stops at that argument (returning the
- unparsed arguments to the caller of argp_parse if requested, or stopping
- with an error message if not).
-
- If an error occurs (either detected by argp, or because the parsing
- function returned an error value), then the parser is called with
- ARGP_KEY_ERROR, and no further calls are made. */
-
-/* This is not an option at all, but rather a command line argument. If a
- parser receiving this key returns success, the fact is recorded, and the
- ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the
- argument, a parser function decrements the NEXT field of the state it's
- passed, the option won't be considered processed; this is to allow you to
- actually modify the argument (perhaps into an option), and have it
- processed again. */
-#define ARGP_KEY_ARG 0
-/* There are remaining arguments not parsed by any parser, which may be found
- starting at (STATE->argv + STATE->next). If success is returned, but
- STATE->next left untouched, it's assumed that all arguments were consume,
- otherwise, the parser should adjust STATE->next to reflect any arguments
- consumed. */
-#define ARGP_KEY_ARGS 0x1000006
-/* There are no more command line arguments at all. */
-#define ARGP_KEY_END 0x1000001
-/* Because it's common to want to do some special processing if there aren't
- any non-option args, user parsers are called with this key if they didn't
- successfully process any non-option arguments. Called just before
- ARGP_KEY_END (where more general validity checks on previously parsed
- arguments can take place). */
-#define ARGP_KEY_NO_ARGS 0x1000002
-/* Passed in before any parsing is done. Afterwards, the values of each
- element of the CHILD_INPUT field, if any, in the state structure is
- copied to each child's state to be the initial value of the INPUT field. */
-#define ARGP_KEY_INIT 0x1000003
-/* Use after all other keys, including SUCCESS & END. */
-#define ARGP_KEY_FINI 0x1000007
-/* Passed in when parsing has successfully been completed (even if there are
- still arguments remaining). */
-#define ARGP_KEY_SUCCESS 0x1000004
-/* Passed in if an error occurs. */
-#define ARGP_KEY_ERROR 0x1000005
-
-/* An argp structure contains a set of options declarations, a function to
- deal with parsing one, documentation string, a possible vector of child
- argp's, and perhaps a function to filter help output. When actually
- parsing options, getopt is called with the union of all the argp
- structures chained together through their CHILD pointers, with conflicts
- being resolved in favor of the first occurrence in the chain. */
-struct argp
-{
- /* An array of argp_option structures, terminated by an entry with both
- NAME and KEY having a value of 0. */
- __const struct argp_option *options;
-
- /* What to do with an option from this structure. KEY is the key
- associated with the option, and ARG is any associated argument (NULL if
- none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be
- returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then
- parsing is stopped immediately, and that value is returned from
- argp_parse(). For special (non-user-supplied) values of KEY, see the
- ARGP_KEY_ definitions below. */
- argp_parser_t parser;
-
- /* A string describing what other arguments are wanted by this program. It
- is only used by argp_usage to print the `Usage:' message. If it
- contains newlines, the strings separated by them are considered
- alternative usage patterns, and printed on separate lines (lines after
- the first are prefix by ` or: ' instead of `Usage:'). */
- __const char *args_doc;
-
- /* If non-NULL, a string containing extra text to be printed before and
- after the options in a long help message (separated by a vertical tab
- `\v' character). */
- __const char *doc;
-
- /* A vector of argp_children structures, terminated by a member with a 0
- argp field, pointing to child argps should be parsed with this one. Any
- conflicts are resolved in favor of this argp, or early argps in the
- CHILDREN list. This field is useful if you use libraries that supply
- their own argp structure, which you want to use in conjunction with your
- own. */
- __const struct argp_child *children;
-
- /* If non-zero, this should be a function to filter the output of help
- messages. KEY is either a key from an option, in which case TEXT is
- that option's help text, or a special key from the ARGP_KEY_HELP_
- defines, below, describing which other help text TEXT is. The function
- should return either TEXT, if it should be used as-is, a replacement
- string, which should be malloced, and will be freed by argp, or NULL,
- meaning `print nothing'. The value for TEXT is *after* any translation
- has been done, so if any of the replacement text also needs translation,
- that should be done by the filter function. INPUT is either the input
- supplied to argp_parse, or NULL, if argp_help was called directly. */
- char *(*help_filter) (int __key, __const char *__text, void *__input);
-
- /* If non-zero the strings used in the argp library are translated using
- the domain described by this string. Otherwise the currently installed
- default domain is used. */
- const char *argp_domain;
-};
-
-/* Possible KEY arguments to a help filter function. */
-#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */
-#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */
-#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */
-#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation;
- TEXT is NULL for this key. */
-/* Explanatory note emitted when duplicate option arguments have been
- suppressed. */
-#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005
-#define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */
-
-/* When an argp has a non-zero CHILDREN field, it should point to a vector of
- argp_child structures, each of which describes a subsidiary argp. */
-struct argp_child
-{
- /* The child parser. */
- __const struct argp *argp;
-
- /* Flags for this child. */
- int flags;
-
- /* If non-zero, an optional header to be printed in help output before the
- child options. As a side-effect, a non-zero value forces the child
- options to be grouped together; to achieve this effect without actually
- printing a header string, use a value of "". */
- __const char *header;
-
- /* Where to group the child options relative to the other (`consolidated')
- options in the parent argp; the values are the same as the GROUP field
- in argp_option structs, but all child-groupings follow parent options at
- a particular group level. If both this field and HEADER are zero, then
- they aren't grouped at all, but rather merged with the parent options
- (merging the child's grouping levels with the parents). */
- int group;
-};
-
-/* Parsing state. This is provided to parsing functions called by argp,
- which may examine and, as noted, modify fields. */
-struct argp_state
-{
- /* The top level ARGP being parsed. */
- __const struct argp *root_argp;
-
- /* The argument vector being parsed. May be modified. */
- int argc;
- char **argv;
-
- /* The index in ARGV of the next arg that to be parsed. May be modified. */
- int next;
-
- /* The flags supplied to argp_parse. May be modified. */
- unsigned flags;
-
- /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the
- number of the current arg, starting at zero, and incremented after each
- such call returns. At all other times, this is the number of such
- arguments that have been processed. */
- unsigned arg_num;
-
- /* If non-zero, the index in ARGV of the first argument following a special
- `--' argument (which prevents anything following being interpreted as an
- option). Only set once argument parsing has proceeded past this point. */
- int quoted;
-
- /* An arbitrary pointer passed in from the user. */
- void *input;
- /* Values to pass to child parsers. This vector will be the same length as
- the number of children for the current parser. */
- void **child_inputs;
-
- /* For the parser's use. Initialized to 0. */
- void *hook;
-
- /* The name used when printing messages. This is initialized to ARGV[0],
- or PROGRAM_INVOCATION_NAME if that is unavailable. */
- char *name;
-
- /* Streams used when argp prints something. */
- FILE *err_stream; /* For errors; initialized to stderr. */
- FILE *out_stream; /* For information; initialized to stdout. */
-
- void *pstate; /* Private, for use by argp. */
-};
-
-/* Flags for argp_parse (note that the defaults are those that are
- convenient for program command line parsing): */
-
-/* Don't ignore the first element of ARGV. Normally (and always unless
- ARGP_NO_ERRS is set) the first element of the argument vector is
- skipped for option parsing purposes, as it corresponds to the program name
- in a command line. */
-#define ARGP_PARSE_ARGV0 0x01
-
-/* Don't print error messages for unknown options to stderr; unless this flag
- is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program
- name in the error messages. This flag implies ARGP_NO_EXIT (on the
- assumption that silent exiting upon errors is bad behaviour). */
-#define ARGP_NO_ERRS 0x02
-
-/* Don't parse any non-option args. Normally non-option args are parsed by
- calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg
- as the value. Since it's impossible to know which parse function wants to
- handle it, each one is called in turn, until one returns 0 or an error
- other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the
- argp_parse returns prematurely (but with a return value of 0). If all
- args have been parsed without error, all parsing functions are called one
- last time with a key of ARGP_KEY_END. This flag needn't normally be set,
- as the normal behavior is to stop parsing as soon as some argument can't
- be handled. */
-#define ARGP_NO_ARGS 0x04
-
-/* Parse options and arguments in the same order they occur on the command
- line -- normally they're rearranged so that all options come first. */
-#define ARGP_IN_ORDER 0x08
-
-/* Don't provide the standard long option --help, which causes usage and
- option help information to be output to stdout, and exit (0) called. */
-#define ARGP_NO_HELP 0x10
-
-/* Don't exit on errors (they may still result in error messages). */
-#define ARGP_NO_EXIT 0x20
-
-/* Use the gnu getopt `long-only' rules for parsing arguments. */
-#define ARGP_LONG_ONLY 0x40
-
-/* Turns off any message-printing/exiting options. */
-#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP)
-
-/* Parse the options strings in ARGC & ARGV according to the options in ARGP.
- FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the
- index in ARGV of the first unparsed option is returned in it. If an
- unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser
- routine returned a non-zero value, it is returned; otherwise 0 is
- returned. This function may also call exit unless the ARGP_NO_HELP flag
- is set. INPUT is a pointer to a value to be passed in to the parser. */
-extern error_t argp_parse (__const struct argp *__restrict argp,
- int argc, char **__restrict argv,
- unsigned flags, int *__restrict arg_index,
- void *__restrict input) __THROW;
-extern error_t __argp_parse (__const struct argp *__restrict argp,
- int argc, char **__restrict argv,
- unsigned flags, int *__restrict arg_index,
- void *__restrict input) __THROW;
-
-/* Global variables. */
-
-/* If defined or set by the user program to a non-zero value, then a default
- option --version is added (unless the ARGP_NO_HELP flag is used), which
- will print this string followed by a newline and exit (unless the
- ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
-extern __const char *argp_program_version;
-
-/* If defined or set by the user program to a non-zero value, then a default
- option --version is added (unless the ARGP_NO_HELP flag is used), which
- calls this function with a stream to print the version to and a pointer to
- the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
- used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
-extern void (*argp_program_version_hook) (FILE *__restrict __stream,
- struct argp_state *__restrict
- __state);
-
-/* If defined or set by the user program, it should point to string that is
- the bug-reporting address for the program. It will be printed by
- argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
- standard help messages), embedded in a sentence that says something like
- `Report bugs to ADDR.'. */
-extern __const char *argp_program_bug_address;
-
-/* The exit status that argp will use when exiting due to a parsing error.
- If not defined or set by the user program, this defaults to EX_USAGE from
- <sysexits.h>. */
-extern error_t argp_err_exit_status;
-
-/* Flags for argp_help. */
-#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */
-#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */
-#define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */
-#define ARGP_HELP_LONG 0x08 /* a long help message. */
-#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */
-#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */
-#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
-#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */
-#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to
- reflect ARGP_LONG_ONLY mode. */
-
-/* These ARGP_HELP flags are only understood by argp_state_help. */
-#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */
-#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */
-
-/* The standard thing to do after a program command line parsing error, if an
- error message has already been printed. */
-#define ARGP_HELP_STD_ERR \
- (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
-/* The standard thing to do after a program command line parsing error, if no
- more specific error message has been printed. */
-#define ARGP_HELP_STD_USAGE \
- (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
-/* The standard thing to do in response to a --help option. */
-#define ARGP_HELP_STD_HELP \
- (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
- | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
-
-/* Output a usage message for ARGP to STREAM. FLAGS are from the set
- ARGP_HELP_*. */
-extern void argp_help (__const struct argp *__restrict __argp,
- FILE *__restrict __stream,
- unsigned __flags, char *__restrict __name) __THROW;
-extern void __argp_help (__const struct argp *__restrict __argp,
- FILE *__restrict __stream, unsigned __flags,
- char *__name) __THROW;
-
-/* The following routines are intended to be called from within an argp
- parsing routine (thus taking an argp_state structure as the first
- argument). They may or may not print an error message and exit, depending
- on the flags in STATE -- in any case, the caller should be prepared for
- them *not* to exit, and should return an appropiate error after calling
- them. [argp_usage & argp_error should probably be called argp_state_...,
- but they're used often enough that they should be short] */
-
-/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
- from the set ARGP_HELP_*. */
-extern void argp_state_help (__const struct argp_state *__restrict __state,
- FILE *__restrict __stream,
- unsigned int __flags) __THROW;
-extern void __argp_state_help (__const struct argp_state *__restrict __state,
- FILE *__restrict __stream,
- unsigned int __flags) __THROW;
-
-/* Possibly output the standard usage message for ARGP to stderr and exit. */
-extern void argp_usage (__const struct argp_state *__state) __THROW;
-extern void __argp_usage (__const struct argp_state *__state) __THROW;
-
-/* If appropriate, print the printf string FMT and following args, preceded
- by the program name and `:', to stderr, and followed by a `Try ... --help'
- message, then exit (1). */
-extern void argp_error (__const struct argp_state *__restrict __state,
- __const char *__restrict __fmt, ...) __THROW
- PRINTF_STYLE(2,3);
-extern void __argp_error (__const struct argp_state *__restrict __state,
- __const char *__restrict __fmt, ...) __THROW
- PRINTF_STYLE(2,3);
-
-/* Similar to the standard gnu error-reporting function error(), but will
- respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
- to STATE->err_stream. This is useful for argument parsing code that is
- shared between program startup (when exiting is desired) and runtime
- option parsing (when typically an error code is returned instead). The
- difference between this function and argp_error is that the latter is for
- *parsing errors*, and the former is for other problems that occur during
- parsing but don't reflect a (syntactic) problem with the input. */
-extern void argp_failure (__const struct argp_state *__restrict __state,
- int __status, int __errnum,
- __const char *__restrict __fmt, ...) __THROW
- PRINTF_STYLE(4,5);
-extern void __argp_failure (__const struct argp_state *__restrict __state,
- int __status, int __errnum,
- __const char *__restrict __fmt, ...) __THROW
- PRINTF_STYLE(4,5);
-
-/* Returns true if the option OPT is a valid short option. */
-extern int _option_is_short (__const struct argp_option *__opt) __THROW;
-extern int __option_is_short (__const struct argp_option *__opt) __THROW;
-
-/* Returns true if the option OPT is in fact the last (unused) entry in an
- options array. */
-extern int _option_is_end (__const struct argp_option *__opt) __THROW;
-extern int __option_is_end (__const struct argp_option *__opt) __THROW;
-
-/* Return the input field for ARGP in the parser corresponding to STATE; used
- by the help routines. */
-extern void *_argp_input (__const struct argp *__restrict __argp,
- __const struct argp_state *__restrict __state)
- __THROW;
-extern void *__argp_input (__const struct argp *__restrict __argp,
- __const struct argp_state *__restrict __state)
- __THROW;
-
-/* Used for extracting the program name from argv[0] */
-extern char *_argp_basename(char *name) __THROW;
-extern char *__argp_basename(char *name) __THROW;
-
-/* Getting the program name given an argp state */
-extern char *
-_argp_short_program_name(const struct argp_state *state) __THROW;
-extern char *
-__argp_short_program_name(const struct argp_state *state) __THROW;
-
-
-#ifdef __USE_EXTERN_INLINES
-
-# if !_LIBC
-# define __argp_usage argp_usage
-# define __argp_state_help argp_state_help
-# define __option_is_short _option_is_short
-# define __option_is_end _option_is_end
-# endif
-
-# ifndef ARGP_EI
-# define ARGP_EI extern __inline__
-# endif
-
-ARGP_EI void
-__argp_usage (__const struct argp_state *__state)
-{
- __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
-}
-
-ARGP_EI int
-__option_is_short (__const struct argp_option *__opt)
-{
- if (__opt->flags & OPTION_DOC)
- return 0;
- else
- {
- int __key = __opt->key;
- return __key > 0 && isprint (__key);
- }
-}
-
-ARGP_EI int
-__option_is_end (__const struct argp_option *__opt)
-{
- return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
-}
-
-# if !_LIBC
-# undef __argp_usage
-# undef __argp_state_help
-# undef __option_is_short
-# undef __option_is_end
-# endif
-#endif /* Use extern inlines. */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* argp.h */
diff --git a/contrib/argp-standalone/autogen.sh b/contrib/argp-standalone/autogen.sh
deleted file mode 100755
index 8337353b5ae..00000000000
--- a/contrib/argp-standalone/autogen.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-aclocal -I .
-autoheader
-autoconf
-automake --add-missing --copy --foreign
diff --git a/contrib/argp-standalone/configure.ac b/contrib/argp-standalone/configure.ac
deleted file mode 100644
index c0867eb5b35..00000000000
--- a/contrib/argp-standalone/configure.ac
+++ /dev/null
@@ -1,105 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-
-dnl This configure.ac is only for building a standalone argp library.
-AC_INIT([argp], [standalone-1.3])
-AC_PREREQ(2.54)
-AC_CONFIG_SRCDIR([argp-ba.c])
-# Needed to stop autoconf from looking for files in parent directories.
-AC_CONFIG_AUX_DIR([.])
-
-AM_INIT_AUTOMAKE
-AC_CONFIG_HEADERS(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
-# systems; no problems have been reported with it so far.
-AC_GNU_SOURCE
-
-# Checks for programs.
-AC_PROG_CC
-AC_PROG_MAKE_SET
-AC_PROG_RANLIB
-AC_PROG_CC
-
-if test "x$am_cv_prog_cc_stdc" = xno ; then
- AC_ERROR([the C compiler doesn't handle ANSI-C])
-fi
-
-# Checks for libraries.
-
-# Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS(libintl.h limits.h malloc.h unistd.h sysexits.h stdarg.h)
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_C_INLINE
-AC_TYPE_SIZE_T
-
-LSH_GCC_ATTRIBUTES
-
-# Checks for library functions.
-AC_FUNC_ALLOCA
-AC_FUNC_VPRINTF
-AC_CHECK_FUNCS(strerror sleep getpid snprintf)
-
-AC_REPLACE_FUNCS(mempcpy strndup strchrnul strcasecmp vsnprintf)
-
-dnl ARGP_CHECK_FUNC(includes, function-call [, if-found [, if-not-found]])
-AC_DEFUN([ARGP_CHECK_FUNC],
- [AS_VAR_PUSHDEF([ac_func], m4_substr([$2], 0, m4_index([$2], [(])))
- AS_VAR_PUSHDEF([ac_var], [ac_cv_func_call_]ac_func)
- AH_TEMPLATE(AS_TR_CPP(HAVE_[]ac_func),
- [Define to 1 if you have the `]ac_func[' function.])
- AC_CACHE_CHECK([for $2], ac_var,
- [AC_TRY_LINK([$1], [$2],
- [AS_VAR_SET(ac_var, yes)],
- [AS_VAR_SET(ac_var, no)])])
- if test AS_VAR_GET(ac_var) = yes ; then
- ifelse([$3],,
- [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_[]ac_func))],
- [$3
-])
- else
- ifelse([$4],, true, [$4])
- fi
- AS_VAR_POPDEF([ac_var])
- AS_VAR_POPDEF([ac_func])
- ])
-
-# At least on freebsd, putc_unlocked is a macro, so the standard
-# AC_CHECK_FUNCS doesn't work well.
-ARGP_CHECK_FUNC([#include <stdio.h>], [putc_unlocked('x', stdout)])
-
-AC_CHECK_FUNCS(flockfile)
-AC_CHECK_FUNCS(fputs_unlocked fwrite_unlocked)
-
-# Used only by argp-test.c, so don't use AC_REPLACE_FUNCS.
-AC_CHECK_FUNCS(strdup asprintf)
-
-AC_CHECK_DECLS([program_invocation_name, program_invocation_short_name],
- [], [], [[#include <errno.h>]])
-
-# Set these flags *last*, or else the test programs won't compile
-if test x$GCC = xyes ; then
- # Using -ggdb3 makes (some versions of) Redhat's gcc-2.96 dump core
- if "$CC" --version | grep '^2\.96$' 1>/dev/null 2>&1; then
- true
- else
- CFLAGS="$CFLAGS -ggdb3"
- fi
- CFLAGS="$CFLAGS -Wall -W \
- -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \
- -Waggregate-return \
- -Wpointer-arith -Wbad-function-cast -Wnested-externs"
-fi
-
-CPPFLAGS="$CPPFLAGS -I$srcdir"
-
-dnl Added for C99 standards
-CFLAGS="$CFLAGS -std=gnu89 -static"
-
-AC_OUTPUT(Makefile)
diff --git a/contrib/argp-standalone/mempcpy.c b/contrib/argp-standalone/mempcpy.c
deleted file mode 100644
index 21d8bd2ed94..00000000000
--- a/contrib/argp-standalone/mempcpy.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* strndup.c
- *
- */
-
-/* Written by Niels Mller <nisse@lysator.liu.se>
- *
- * This file is hereby placed in the public domain.
- */
-
-#include <string.h>
-
-void *
-mempcpy (void *, const void *, size_t) ;
-
-void *
-mempcpy (void *to, const void *from, size_t size)
-{
- memcpy(to, from, size);
- return (char *) to + size;
-}
-
diff --git a/contrib/argp-standalone/strcasecmp.c b/contrib/argp-standalone/strcasecmp.c
deleted file mode 100644
index 9c1637232fd..00000000000
--- a/contrib/argp-standalone/strcasecmp.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* strcasecmp.c
- *
- */
-
-/* Written by Niels Mller <nisse@lysator.liu.se>
- *
- * This file is hereby placed in the public domain.
- */
-
-#include <ctype.h>
-int strcasecmp(const char *, const char *);
-
-int strcasecmp(const char *s1, const char *s2)
-{
- unsigned i;
-
- for (i = 0; s1[i] && s2[i]; i++)
- {
- unsigned char c1 = tolower( (unsigned char) s1[i]);
- unsigned char c2 = tolower( (unsigned char) s2[i]);
-
- if (c1 < c2)
- return -1;
- else if (c1 > c2)
- return 1;
- }
-
- return !s2[i] - !s1[i];
-}
diff --git a/contrib/argp-standalone/strchrnul.c b/contrib/argp-standalone/strchrnul.c
deleted file mode 100644
index ee4145e4eda..00000000000
--- a/contrib/argp-standalone/strchrnul.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* strchrnul.c
- *
- */
-
-/* Written by Niels Mller <nisse@lysator.liu.se>
- *
- * This file is hereby placed in the public domain.
- */
-
-/* FIXME: What is this function supposed to do? My guess is that it is
- * like strchr, but returns a pointer to the NUL character, not a NULL
- * pointer, if the character isn't found. */
-
-char *strchrnul(const char *, int );
-
-char *strchrnul(const char *s, int c)
-{
- const char *p = s;
- while (*p && (*p != c))
- p++;
-
- return (char *) p;
-}
diff --git a/contrib/argp-standalone/strndup.c b/contrib/argp-standalone/strndup.c
deleted file mode 100644
index 4147b7a2051..00000000000
--- a/contrib/argp-standalone/strndup.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* strndup.c
- *
- */
-
-/* Written by Niels Mller <nisse@lysator.liu.se>
- *
- * This file is hereby placed in the public domain.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-char *
-strndup (const char *, size_t);
-
-char *
-strndup (const char *s, size_t size)
-{
- char *r;
- char *end = memchr(s, 0, size);
-
- if (end)
- /* Length + 1 */
- size = end - s + 1;
-
- r = malloc(size);
-
- if (size)
- {
- memcpy(r, s, size-1);
- r[size-1] = '\0';
- }
- return r;
-}
diff --git a/contrib/argp-standalone/vsnprintf.c b/contrib/argp-standalone/vsnprintf.c
deleted file mode 100644
index 33c9a5d0042..00000000000
--- a/contrib/argp-standalone/vsnprintf.c
+++ /dev/null
@@ -1,839 +0,0 @@
-/* Copied from http://www.fiction.net/blong/programs/snprintf.c */
-
-/*
- * Copyright Patrick Powell 1995
- * This code is based on code written by Patrick Powell (papowell@astart.com)
- * It may be used for any purpose as long as this notice remains intact
- * on all source code distributions
- */
-
-/**************************************************************
- * Original:
- * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
- * A bombproof version of doprnt (dopr) included.
- * Sigh. This sort of thing is always nasty do deal with. Note that
- * the version here does not include floating point...
- *
- * snprintf() is used instead of sprintf() as it does limit checks
- * for string length. This covers a nasty loophole.
- *
- * The other functions are there to prevent NULL pointers from
- * causing nast effects.
- *
- * More Recently:
- * Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
- * This was ugly. It is still ugly. I opted out of floating point
- * numbers, but the formatter understands just about everything
- * from the normal C string format, at least as far as I can tell from
- * the Solaris 2.5 printf(3S) man page.
- *
- * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
- * Ok, added some minimal floating point support, which means this
- * probably requires libm on most operating systems. Don't yet
- * support the exponent (e,E) and sigfig (g,G). Also, fmtint()
- * was pretty badly broken, it just wasn't being exercised in ways
- * which showed it, so that's been fixed. Also, formated the code
- * to mutt conventions, and removed dead code left over from the
- * original. Also, there is now a builtin-test, just compile with:
- * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
- * and run snprintf for results.
- *
- * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
- * The PGP code was using unsigned hexadecimal formats.
- * Unfortunately, unsigned formats simply didn't work.
- *
- * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
- * The original code assumed that both snprintf() and vsnprintf() were
- * missing. Some systems only have snprintf() but not vsnprintf(), so
- * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
- *
- * Andrew Tridgell (tridge@samba.org) Oct 1998
- * fixed handling of %.0f
- * added test for HAVE_LONG_DOUBLE
- *
- * Russ Allbery <rra@stanford.edu> 2000-08-26
- * fixed return value to comply with C99
- * fixed handling of snprintf(NULL, ...)
- *
- * Niels Mller <nisse@lysator.liu.se> 2004-03-05
- * fixed calls to isdigit to use unsigned char.
- * fixed calls to va_arg; short arguments are always passed as int.
- *
- **************************************************************/
-
-#if HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
-
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-
-/* Define this as a fall through, HAVE_STDARG_H is probably already set */
-
-#define HAVE_VARARGS_H
-
-
-/* varargs declarations: */
-
-#if defined(HAVE_STDARG_H)
-# include <stdarg.h>
-# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
-# define VA_LOCAL_DECL va_list ap
-# define VA_START(f) va_start(ap, f)
-# define VA_SHIFT(v,t) ; /* no-op for ANSI */
-# define VA_END va_end(ap)
-#else
-# if defined(HAVE_VARARGS_H)
-# include <varargs.h>
-# undef HAVE_STDARGS
-# define VA_LOCAL_DECL va_list ap
-# define VA_START(f) va_start(ap) /* f is ignored! */
-# define VA_SHIFT(v,t) v = va_arg(ap,t)
-# define VA_END va_end(ap)
-# else
-/*XX ** NO VARARGS ** XX*/
-# endif
-#endif
-
-#ifdef HAVE_LONG_DOUBLE
-#define LDOUBLE long double
-#else
-#define LDOUBLE double
-#endif
-
-int snprintf (char *str, size_t count, const char *fmt, ...);
-int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
-
-static int dopr (char *buffer, size_t maxlen, const char *format,
- va_list args);
-static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max);
-static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
- long value, int base, int min, int max, int flags);
-static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
- LDOUBLE fvalue, int min, int max, int flags);
-static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
-
-/*
- * dopr(): poor man's version of doprintf
- */
-
-/* format read states */
-#define DP_S_DEFAULT 0
-#define DP_S_FLAGS 1
-#define DP_S_MIN 2
-#define DP_S_DOT 3
-#define DP_S_MAX 4
-#define DP_S_MOD 5
-#define DP_S_CONV 6
-#define DP_S_DONE 7
-
-/* format flags - Bits */
-#define DP_F_MINUS (1 << 0)
-#define DP_F_PLUS (1 << 1)
-#define DP_F_SPACE (1 << 2)
-#define DP_F_NUM (1 << 3)
-#define DP_F_ZERO (1 << 4)
-#define DP_F_UP (1 << 5)
-#define DP_F_UNSIGNED (1 << 6)
-
-/* Conversion Flags */
-#define DP_C_SHORT 1
-#define DP_C_LONG 2
-#define DP_C_LDOUBLE 3
-
-#define char_to_int(p) (p - '0')
-#define MAX(p,q) ((p >= q) ? p : q)
-#define MIN(p,q) ((p <= q) ? p : q)
-
-static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
-{
- unsigned char ch;
- long value;
- LDOUBLE fvalue;
- char *strvalue;
- int min;
- int max;
- int state;
- int flags;
- int cflags;
- int total;
- size_t currlen;
-
- state = DP_S_DEFAULT;
- currlen = flags = cflags = min = 0;
- max = -1;
- ch = *format++;
- total = 0;
-
- while (state != DP_S_DONE)
- {
- if (ch == '\0')
- state = DP_S_DONE;
-
- switch(state)
- {
- case DP_S_DEFAULT:
- if (ch == '%')
- state = DP_S_FLAGS;
- else
- total += dopr_outch (buffer, &currlen, maxlen, ch);
- ch = *format++;
- break;
- case DP_S_FLAGS:
- switch (ch)
- {
- case '-':
- flags |= DP_F_MINUS;
- ch = *format++;
- break;
- case '+':
- flags |= DP_F_PLUS;
- ch = *format++;
- break;
- case ' ':
- flags |= DP_F_SPACE;
- ch = *format++;
- break;
- case '#':
- flags |= DP_F_NUM;
- ch = *format++;
- break;
- case '0':
- flags |= DP_F_ZERO;
- ch = *format++;
- break;
- default:
- state = DP_S_MIN;
- break;
- }
- break;
- case DP_S_MIN:
- if (isdigit(ch))
- {
- min = 10*min + char_to_int (ch);
- ch = *format++;
- }
- else if (ch == '*')
- {
- min = va_arg (args, int);
- ch = *format++;
- state = DP_S_DOT;
- }
- else
- state = DP_S_DOT;
- break;
- case DP_S_DOT:
- if (ch == '.')
- {
- state = DP_S_MAX;
- ch = *format++;
- }
- else
- state = DP_S_MOD;
- break;
- case DP_S_MAX:
- if (isdigit(ch))
- {
- if (max < 0)
- max = 0;
- max = 10*max + char_to_int (ch);
- ch = *format++;
- }
- else if (ch == '*')
- {
- max = va_arg (args, int);
- ch = *format++;
- state = DP_S_MOD;
- }
- else
- state = DP_S_MOD;
- break;
- case DP_S_MOD:
- /* Currently, we don't support Long Long, bummer */
- switch (ch)
- {
- case 'h':
- cflags = DP_C_SHORT;
- ch = *format++;
- break;
- case 'l':
- cflags = DP_C_LONG;
- ch = *format++;
- break;
- case 'L':
- cflags = DP_C_LDOUBLE;
- ch = *format++;
- break;
- default:
- break;
- }
- state = DP_S_CONV;
- break;
- case DP_S_CONV:
- switch (ch)
- {
- case 'd':
- case 'i':
- if (cflags == DP_C_SHORT)
- value = (short) va_arg (args, int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, long int);
- else
- value = va_arg (args, int);
- total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
- break;
- case 'o':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = (unsigned short) va_arg (args, unsigned);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, unsigned long int);
- else
- value = va_arg (args, unsigned int);
- total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
- break;
- case 'u':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = (unsigned short) va_arg (args, unsigned);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, unsigned long int);
- else
- value = va_arg (args, unsigned int);
- total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
- break;
- case 'X':
- flags |= DP_F_UP;
- case 'x':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = (unsigned short) va_arg (args, unsigned);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, unsigned long int);
- else
- value = va_arg (args, unsigned int);
- total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
- break;
- case 'f':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- /* um, floating point? */
- total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
- break;
- case 'E':
- flags |= DP_F_UP;
- case 'e':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- break;
- case 'G':
- flags |= DP_F_UP;
- case 'g':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, LDOUBLE);
- else
- fvalue = va_arg (args, double);
- break;
- case 'c':
- total += dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
- break;
- case 's':
- strvalue = va_arg (args, char *);
- total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
- break;
- case 'p':
- strvalue = va_arg (args, void *);
- total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min,
- max, flags);
- break;
- case 'n':
- if (cflags == DP_C_SHORT)
- {
- short int *num;
- num = va_arg (args, short int *);
- *num = currlen;
- }
- else if (cflags == DP_C_LONG)
- {
- long int *num;
- num = va_arg (args, long int *);
- *num = currlen;
- }
- else
- {
- int *num;
- num = va_arg (args, int *);
- *num = currlen;
- }
- break;
- case '%':
- total += dopr_outch (buffer, &currlen, maxlen, ch);
- break;
- case 'w':
- /* not supported yet, treat as next char */
- ch = *format++;
- break;
- default:
- /* Unknown, skip */
- break;
- }
- ch = *format++;
- state = DP_S_DEFAULT;
- flags = cflags = min = 0;
- max = -1;
- break;
- case DP_S_DONE:
- break;
- default:
- /* hmm? */
- break; /* some picky compilers need this */
- }
- }
- if (buffer != NULL)
- {
- if (currlen < maxlen - 1)
- buffer[currlen] = '\0';
- else
- buffer[maxlen - 1] = '\0';
- }
- return total;
-}
-
-static int fmtstr (char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max)
-{
- int padlen, strln; /* amount to pad */
- int cnt = 0;
- int total = 0;
-
- if (value == 0)
- {
- value = "<NULL>";
- }
-
- for (strln = 0; value[strln]; ++strln); /* strlen */
- if (max >= 0 && max < strln)
- strln = max;
- padlen = min - strln;
- if (padlen < 0)
- padlen = 0;
- if (flags & DP_F_MINUS)
- padlen = -padlen; /* Left Justify */
-
- while (padlen > 0)
- {
- total += dopr_outch (buffer, currlen, maxlen, ' ');
- --padlen;
- }
- while (*value && ((max < 0) || (cnt < max)))
- {
- total += dopr_outch (buffer, currlen, maxlen, *value++);
- ++cnt;
- }
- while (padlen < 0)
- {
- total += dopr_outch (buffer, currlen, maxlen, ' ');
- ++padlen;
- }
- return total;
-}
-
-/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
-
-static int fmtint (char *buffer, size_t *currlen, size_t maxlen,
- long value, int base, int min, int max, int flags)
-{
- int signvalue = 0;
- unsigned long uvalue;
- char convert[20];
- int place = 0;
- int spadlen = 0; /* amount to space pad */
- int zpadlen = 0; /* amount to zero pad */
- int caps = 0;
- int total = 0;
-
- if (max < 0)
- max = 0;
-
- uvalue = value;
-
- if(!(flags & DP_F_UNSIGNED))
- {
- if( value < 0 ) {
- signvalue = '-';
- uvalue = -value;
- }
- else
- if (flags & DP_F_PLUS) /* Do a sign (+/i) */
- signvalue = '+';
- else
- if (flags & DP_F_SPACE)
- signvalue = ' ';
- }
-
- if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-
- do {
- convert[place++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")
- [uvalue % (unsigned)base ];
- uvalue = (uvalue / (unsigned)base );
- } while(uvalue && (place < 20));
- if (place == 20) place--;
- convert[place] = 0;
-
- zpadlen = max - place;
- spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
- if (zpadlen < 0) zpadlen = 0;
- if (spadlen < 0) spadlen = 0;
- if (flags & DP_F_ZERO)
- {
- zpadlen = MAX(zpadlen, spadlen);
- spadlen = 0;
- }
- if (flags & DP_F_MINUS)
- spadlen = -spadlen; /* Left Justifty */
-
-#ifdef DEBUG_SNPRINTF
- dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
- zpadlen, spadlen, min, max, place));
-#endif
-
- /* Spaces */
- while (spadlen > 0)
- {
- total += dopr_outch (buffer, currlen, maxlen, ' ');
- --spadlen;
- }
-
- /* Sign */
- if (signvalue)
- total += dopr_outch (buffer, currlen, maxlen, signvalue);
-
- /* Zeros */
- if (zpadlen > 0)
- {
- while (zpadlen > 0)
- {
- total += dopr_outch (buffer, currlen, maxlen, '0');
- --zpadlen;
- }
- }
-
- /* Digits */
- while (place > 0)
- total += dopr_outch (buffer, currlen, maxlen, convert[--place]);
-
- /* Left Justified spaces */
- while (spadlen < 0) {
- total += dopr_outch (buffer, currlen, maxlen, ' ');
- ++spadlen;
- }
-
- return total;
-}
-
-static LDOUBLE abs_val (LDOUBLE value)
-{
- LDOUBLE result = value;
-
- if (value < 0)
- result = -value;
-
- return result;
-}
-
-static LDOUBLE pow10_argp (int exp)
-{
- LDOUBLE result = 1;
-
- while (exp)
- {
- result *= 10;
- exp--;
- }
-
- return result;
-}
-
-static long round_argp (LDOUBLE value)
-{
- long intpart;
-
- intpart = value;
- value = value - intpart;
- if (value >= 0.5)
- intpart++;
-
- return intpart;
-}
-
-static int fmtfp (char *buffer, size_t *currlen, size_t maxlen,
- LDOUBLE fvalue, int min, int max, int flags)
-{
- int signvalue = 0;
- LDOUBLE ufvalue;
- char iconvert[20];
- char fconvert[20];
- int iplace = 0;
- int fplace = 0;
- int padlen = 0; /* amount to pad */
- int zpadlen = 0;
- int caps = 0;
- int total = 0;
- long intpart;
- long fracpart;
-
- /*
- * AIX manpage says the default is 0, but Solaris says the default
- * is 6, and sprintf on AIX defaults to 6
- */
- if (max < 0)
- max = 6;
-
- ufvalue = abs_val (fvalue);
-
- if (fvalue < 0)
- signvalue = '-';
- else
- if (flags & DP_F_PLUS) /* Do a sign (+/i) */
- signvalue = '+';
- else
- if (flags & DP_F_SPACE)
- signvalue = ' ';
-
-#if 0
- if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-#endif
-
- intpart = ufvalue;
-
- /*
- * Sorry, we only support 9 digits past the decimal because of our
- * conversion method
- */
- if (max > 9)
- max = 9;
-
- /* We "cheat" by converting the fractional part to integer by
- * multiplying by a factor of 10
- */
- fracpart = round_argp ((pow10_argp (max)) * (ufvalue - intpart));
-
- if (fracpart >= pow10_argp (max))
- {
- intpart++;
- fracpart -= pow10_argp (max);
- }
-
-#ifdef DEBUG_SNPRINTF
- dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
-#endif
-
- /* Convert integer part */
- do {
- iconvert[iplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
- intpart = (intpart / 10);
- } while(intpart && (iplace < 20));
- if (iplace == 20) iplace--;
- iconvert[iplace] = 0;
-
- /* Convert fractional part */
- do {
- fconvert[fplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
- fracpart = (fracpart / 10);
- } while(fracpart && (fplace < 20));
- if (fplace == 20) fplace--;
- fconvert[fplace] = 0;
-
- /* -1 for decimal point, another -1 if we are printing a sign */
- padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
- zpadlen = max - fplace;
- if (zpadlen < 0)
- zpadlen = 0;
- if (padlen < 0)
- padlen = 0;
- if (flags & DP_F_MINUS)
- padlen = -padlen; /* Left Justifty */
-
- if ((flags & DP_F_ZERO) && (padlen > 0))
- {
- if (signvalue)
- {
- total += dopr_outch (buffer, currlen, maxlen, signvalue);
- --padlen;
- signvalue = 0;
- }
- while (padlen > 0)
- {
- total += dopr_outch (buffer, currlen, maxlen, '0');
- --padlen;
- }
- }
- while (padlen > 0)
- {
- total += dopr_outch (buffer, currlen, maxlen, ' ');
- --padlen;
- }
- if (signvalue)
- total += dopr_outch (buffer, currlen, maxlen, signvalue);
-
- while (iplace > 0)
- total += dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
-
- /*
- * Decimal point. This should probably use locale to find the correct
- * char to print out.
- */
- if (max > 0)
- {
- total += dopr_outch (buffer, currlen, maxlen, '.');
-
- while (fplace > 0)
- total += dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
- }
-
- while (zpadlen > 0)
- {
- total += dopr_outch (buffer, currlen, maxlen, '0');
- --zpadlen;
- }
-
- while (padlen < 0)
- {
- total += dopr_outch (buffer, currlen, maxlen, ' ');
- ++padlen;
- }
-
- return total;
-}
-
-static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
-{
- if (*currlen + 1 < maxlen)
- buffer[(*currlen)++] = c;
- return 1;
-}
-
-#ifndef HAVE_VSNPRINTF
-int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
-{
- if (str != NULL)
- str[0] = 0;
- return dopr(str, count, fmt, args);
-}
-#endif /* !HAVE_VSNPRINTF */
-
-#ifndef HAVE_SNPRINTF
-/* VARARGS3 */
-#ifdef HAVE_STDARGS
-int snprintf (char *str,size_t count,const char *fmt,...)
-#else
-int snprintf (va_alist) va_dcl
-#endif
-{
-#ifndef HAVE_STDARGS
- char *str;
- size_t count;
- char *fmt;
-#endif
- VA_LOCAL_DECL;
- int total;
-
- VA_START (fmt);
- VA_SHIFT (str, char *);
- VA_SHIFT (count, size_t );
- VA_SHIFT (fmt, char *);
- total = vsnprintf(str, count, fmt, ap);
- VA_END;
- return total;
-}
-#endif /* !HAVE_SNPRINTF */
-
-#ifdef TEST_SNPRINTF
-#ifndef LONG_STRING
-#define LONG_STRING 1024
-#endif
-int main (void)
-{
- char buf1[LONG_STRING];
- char buf2[LONG_STRING];
- char *fp_fmt[] = {
- "%-1.5f",
- "%1.5f",
- "%123.9f",
- "%10.5f",
- "% 10.5f",
- "%+22.9f",
- "%+4.9f",
- "%01.3f",
- "%4f",
- "%3.1f",
- "%3.2f",
- "%.0f",
- "%.1f",
- NULL
- };
- double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
- 0.9996, 1.996, 4.136, 0};
- char *int_fmt[] = {
- "%-1.5d",
- "%1.5d",
- "%123.9d",
- "%5.5d",
- "%10.5d",
- "% 10.5d",
- "%+22.33d",
- "%01.3d",
- "%4d",
- NULL
- };
- long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
- int x, y;
- int fail = 0;
- int num = 0;
-
- printf ("Testing snprintf format codes against system sprintf...\n");
-
- for (x = 0; fp_fmt[x] != NULL ; x++)
- for (y = 0; fp_nums[y] != 0 ; y++)
- {
- snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
- sprintf (buf2, fp_fmt[x], fp_nums[y]);
- if (strcmp (buf1, buf2))
- {
- printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
- fp_fmt[x], buf1, buf2);
- fail++;
- }
- num++;
- }
-
- for (x = 0; int_fmt[x] != NULL ; x++)
- for (y = 0; int_nums[y] != 0 ; y++)
- {
- snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
- sprintf (buf2, int_fmt[x], int_nums[y]);
- if (strcmp (buf1, buf2))
- {
- printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
- int_fmt[x], buf1, buf2);
- fail++;
- }
- num++;
- }
- printf ("%d tests failed out of %d.\n", fail, num);
-}
-#endif /* SNPRINTF_TEST */
-
-#endif /* !HAVE_SNPRINTF */
diff --git a/contrib/fuse-include/fuse-mount.h b/contrib/fuse-include/fuse-mount.h
index 9358ac810e1..7d28462de47 100644
--- a/contrib/fuse-include/fuse-mount.h
+++ b/contrib/fuse-include/fuse-mount.h
@@ -8,6 +8,6 @@
*/
void gf_fuse_unmount (const char *mountpoint, int fd);
-int gf_fuse_mount (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param,
+int gf_fuse_unmount_daemon (const char *mountpoint, int fd);
+int gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
pid_t *mtab_pid, int status_fd);
diff --git a/contrib/fuse-include/fuse_kernel.h b/contrib/fuse-include/fuse_kernel.h
index 60bb2f9f7b7..1e41e237e6f 100644
--- a/contrib/fuse-include/fuse_kernel.h
+++ b/contrib/fuse-include/fuse_kernel.h
@@ -93,6 +93,18 @@
*
* 7.22
* - add FUSE_ASYNC_DIO
+ *
+ * 7.23
+ * - add FUSE_WRITEBACK_CACHE
+ * - add time_gran to fuse_init_out
+ * - add reserved space to fuse_init_out
+ * - add FATTR_CTIME
+ * - add ctime and ctimensec to fuse_setattr_in
+ * - add FUSE_RENAME2 request
+ * - add FUSE_NO_OPEN_SUPPORT flag
+ *
+ * 7.24
+ * - add FUSE_LSEEK for SEEK_HOLE and SEEK_DATA support
*/
#ifndef _LINUX_FUSE_H
@@ -128,7 +140,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 22
+#define FUSE_KERNEL_MINOR_VERSION 24
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -188,6 +200,7 @@ struct fuse_file_lock {
#define FATTR_ATIME_NOW (1 << 7)
#define FATTR_MTIME_NOW (1 << 8)
#define FATTR_LOCKOWNER (1 << 9)
+#define FATTR_CTIME (1 << 10)
/**
* Flags returned by the OPEN request
@@ -219,6 +232,8 @@ struct fuse_file_lock {
* FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one)
* FUSE_READDIRPLUS_AUTO: adaptive readdirplus
* FUSE_ASYNC_DIO: asynchronous direct I/O submission
+ * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes
+ * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
@@ -236,6 +251,8 @@ struct fuse_file_lock {
#define FUSE_DO_READDIRPLUS (1 << 13)
#define FUSE_READDIRPLUS_AUTO (1 << 14)
#define FUSE_ASYNC_DIO (1 << 15)
+#define FUSE_WRITEBACK_CACHE (1 << 16)
+#define FUSE_NO_OPEN_SUPPORT (1 << 17)
/**
* CUSE INIT request/reply flags
@@ -343,6 +360,8 @@ enum fuse_opcode {
FUSE_BATCH_FORGET = 42,
FUSE_FALLOCATE = 43,
FUSE_READDIRPLUS = 44,
+ FUSE_RENAME2 = 45,
+ FUSE_LSEEK = 46,
/* CUSE specific operations */
CUSE_INIT = 4096,
@@ -421,6 +440,12 @@ struct fuse_rename_in {
uint64_t newdir;
};
+struct fuse_rename2_in {
+ uint64_t newdir;
+ uint32_t flags;
+ uint32_t padding;
+};
+
struct fuse_link_in {
uint64_t oldnodeid;
};
@@ -433,10 +458,10 @@ struct fuse_setattr_in {
uint64_t lock_owner;
uint64_t atime;
uint64_t mtime;
- uint64_t unused2;
+ uint64_t ctime;
uint32_t atimensec;
uint32_t mtimensec;
- uint32_t unused3;
+ uint32_t ctimensec;
uint32_t mode;
uint32_t unused4;
uint32_t uid;
@@ -554,6 +579,9 @@ struct fuse_init_in {
uint32_t flags;
};
+#define FUSE_COMPAT_INIT_OUT_SIZE 8
+#define FUSE_COMPAT_22_INIT_OUT_SIZE 24
+
struct fuse_init_out {
uint32_t major;
uint32_t minor;
@@ -562,6 +590,8 @@ struct fuse_init_out {
uint16_t max_background;
uint16_t congestion_threshold;
uint32_t max_write;
+ uint32_t time_gran;
+ uint32_t unused[9];
};
#define CUSE_INIT_INFO_MAX 4096
@@ -729,4 +759,15 @@ struct fuse_notify_retrieve_in {
uint64_t dummy4;
};
+struct fuse_lseek_in {
+ uint64_t fh;
+ uint64_t offset;
+ int32_t whence;
+ uint32_t padding;
+};
+
+struct fuse_lseek_out {
+ uint64_t offset;
+};
+
#endif /* _LINUX_FUSE_H */
diff --git a/contrib/fuse-lib/misc.c b/contrib/fuse-lib/misc.c
index 0c41b1a1917..1a9b418e511 100644
--- a/contrib/fuse-lib/misc.c
+++ b/contrib/fuse-lib/misc.c
@@ -10,7 +10,7 @@
#include <string.h>
#include <limits.h>
#include <fcntl.h>
-#include "glusterfs.h"
+#include "glusterfs/glusterfs.h"
#include "fuse_kernel.h"
#include "fuse-misc.h"
@@ -41,7 +41,6 @@ void
convert_fuse_file_lock (struct fuse_file_lock *fl, struct gf_flock *flock,
uint64_t lk_owner)
{
- memset (flock, 0, sizeof (struct flock));
flock->l_type = fl->type;
flock->l_whence = SEEK_SET;
flock->l_start = fl->start;
diff --git a/contrib/fuse-lib/mount-common.c b/contrib/fuse-lib/mount-common.c
index e9f80fe8154..cffd4c01ed5 100644
--- a/contrib/fuse-lib/mount-common.c
+++ b/contrib/fuse-lib/mount-common.c
@@ -32,7 +32,7 @@ mtab_needs_update (const char *mnt)
struct stat stbuf;
/* If mtab is within new mount, don't touch it */
- if (strncmp (mnt, _PATH_MOUNTED, strlen (mnt)) == 0 &&
+ if (strncmp (mnt, _PATH_MOUNTED, sizeof (_PATH_MOUNTED) - 1) == 0 &&
_PATH_MOUNTED[strlen (mnt)] == '/')
return 0;
@@ -255,16 +255,16 @@ fuse_mnt_umount (const char *progname, const char *abs_mnt,
exit (1);
}
#ifdef GF_LINUX_HOST_OS
- execl ("/bin/umount", "/bin/umount", "-i", rel_mnt,
+ execl ("umount", "umount", "-i", rel_mnt,
lazy ? "-l" : NULL, NULL);
- GFFUSE_LOGERR ("%s: failed to execute /bin/umount: %s",
+ GFFUSE_LOGERR ("%s: failed to execute umount: %s",
progname, strerror (errno));
#elif __NetBSD__
/* exitting the filesystem causes the umount */
exit (0);
#else
- execl ("/sbin/umount", "/sbin/umount", "-f", rel_mnt, NULL);
- GFFUSE_LOGERR ("%s: failed to execute /sbin/umount: %s",
+ execl ("umount", "umount", "-f", rel_mnt, NULL);
+ GFFUSE_LOGERR ("%s: failed to execute umount: %s",
progname, strerror (errno));
#endif /* GF_LINUX_HOST_OS */
exit (1);
diff --git a/contrib/fuse-lib/mount-gluster-compat.h b/contrib/fuse-lib/mount-gluster-compat.h
index 562f089dd1f..d3646d08d8e 100644
--- a/contrib/fuse-lib/mount-gluster-compat.h
+++ b/contrib/fuse-lib/mount-gluster-compat.h
@@ -30,17 +30,59 @@
#include <sys/wait.h>
#include <sys/mount.h>
+#ifdef GF_LINUX_HOST_OS
+typedef unsigned long mount_flag_t;
+#endif
+
#if defined(__NetBSD__)
#include <perfuse.h>
#define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0)
#define MS_RDONLY MNT_RDONLY
+#define MS_NOSUID MNT_NOSUID
+#define MS_NODEV MNT_NODEV
+#define MS_NOATIME MNT_NOATIME
+#define MS_NOEXEC MNT_NOEXEC
+typedef int mount_flag_t;
#endif
#if defined(GF_DARWIN_HOST_OS) || defined(__FreeBSD__)
#include <sys/param.h>
#include <sys/mount.h>
#define umount2(dir, flags) unmount(dir, ((flags) != 0) ? MNT_FORCE : 0)
+#endif
+
+#if defined(__FreeBSD__)
#define MS_RDONLY MNT_RDONLY
+#define MS_NOSUID MNT_NOSUID
+/* "nodev"/MNT_NODEV was removed from FreBSD, as it became unneeded because "As
+ * of FreeBSD 6.0 device nodes may be created in regular file systems but such
+ * nodes cannot be used to access devices." (See
+ * https://freebsd.org/cgi/man.cgi?query=mknod&sektion=8 .
+ * Also see:
+ * - https://github.com/freebsd/freebsd/commit/266790a
+ * - https://github.com/freebsd/freebsd/commit/a5e716d
+ * - 700008 in
+ * https://www.freebsd.org/doc/en/books/porters-handbook/versions-7.html .)
+ */
+#if __FreeBSD_version < 700008
+#define MS_NODEV MNT_NODEV
+#else
+#define MS_NODEV 0
+#endif
+#define MS_NOATIME MNT_NOATIME
+#define MS_NOEXEC MNT_NOEXEC
+#if __FreeBSD_version < 1000715
+typedef int mount_flag_t;
+#else
+/* __FreeBSD_version was not bumped for this type change. Anyway, see
+ * https://github.com/freebsd/freebsd/commit/e8d76f8
+ * and respective __FreeBSD_version:
+ * https://github.com/freebsd/freebsd/blob/e8d76f8/sys/sys/param.h#L61 .
+ * We use the subsequent value, 1000715, to switch. (Also see:
+ * https://www.freebsd.org/doc/en/books/porters-handbook/versions-10.html .)
+ */
+typedef long long mount_flag_t;
+#endif
#endif
#ifdef GF_LINUX_HOST_OS
@@ -54,9 +96,9 @@
#define FREE(ptr) free (ptr)
#define GFFUSE_LOGERR(...) fprintf (stderr, ## __VA_ARGS__)
#else /* FUSE_UTIL */
-#include "glusterfs.h"
-#include "logging.h"
-#include "common-utils.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/common-utils.h"
#define GFFUSE_LOGERR(...) \
gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__)
diff --git a/contrib/fuse-lib/mount.c b/contrib/fuse-lib/mount.c
index 1edde86014a..06ff191f542 100644
--- a/contrib/fuse-lib/mount.c
+++ b/contrib/fuse-lib/mount.c
@@ -52,12 +52,16 @@ gf_fuse_unmount (const char *mountpoint, int fd)
if (geteuid () == 0) {
fuse_mnt_umount ("fuse", mountpoint, mountpoint, 1);
return;
+ } else {
+ GFFUSE_LOGERR ("fuse: Effective-uid: %d", geteuid());
}
res = umount2 (mountpoint, 2);
if (res == 0)
return;
+ GFFUSE_LOGERR ("fuse: failed to unmount %s: %s",
+ mountpoint, strerror (errno));
pid = fork ();
if (pid == -1)
return;
@@ -67,6 +71,8 @@ gf_fuse_unmount (const char *mountpoint, int fd)
"--", mountpoint, NULL };
execvp (FUSERMOUNT_PROG, (char **)argv);
+ GFFUSE_LOGERR ("fuse: failed to execute fuserumount: %s",
+ strerror (errno));
_exit (1);
}
waitpid (pid, NULL, 0);
@@ -75,6 +81,54 @@ gf_fuse_unmount (const char *mountpoint, int fd)
/* gluster-specific routines */
+/* Unmounting in a daemon that lurks 'till main process exits */
+int
+gf_fuse_unmount_daemon (const char *mountpoint, int fd)
+{
+ int ret = -1;
+ pid_t pid = -1;
+
+ if (fd == -1)
+ return -1;
+
+ int ump[2] = {0,};
+
+ ret = pipe(ump);
+ if (ret == -1) {
+ close (fd);
+ return -1;
+ }
+
+ pid = fork ();
+ switch (pid) {
+ case 0:
+ {
+ char c = 0;
+ sigset_t sigset;
+
+ close_fds_except (ump, 1);
+
+ setsid();
+ (void)chdir("/");
+ sigfillset(&sigset);
+ sigprocmask(SIG_BLOCK, &sigset, NULL);
+
+ read (ump[0], &c, 1);
+
+ gf_fuse_unmount (mountpoint, fd);
+ exit (0);
+ }
+ case -1:
+ close (fd);
+ fd = -1;
+ ret = -1;
+ close (ump[1]);
+ }
+ close (ump[0]);
+
+ return ret;
+}
+
static char *
escape (char *s)
{
@@ -106,8 +160,7 @@ escape (char *s)
static int
fuse_mount_fusermount (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param,
- int fd)
+ char *mnt_param, int fd)
{
int pid = -1;
int res = 0;
@@ -130,8 +183,7 @@ fuse_mount_fusermount (const char *mountpoint, char *fsname,
return -1;
}
ret = asprintf (&fm_mnt_params,
- "%s%s,fsname=%s,nonempty,subtype=glusterfs",
- (mountflags & MS_RDONLY) ? "ro," : "",
+ "%s,fsname=%s,nonempty,subtype=glusterfs",
mnt_param, efsname);
FREE (efsname);
if (ret == -1) {
@@ -224,19 +276,101 @@ build_iovec_argf(struct iovec **iov, int *iovlen, const char *name,
}
#endif /* __FreeBSD__ */
+struct mount_flags {
+ const char *opt;
+ mount_flag_t flag;
+ int on;
+} mount_flags[] = {
+ /* We provide best effort cross platform support for mount flags by
+ * defining the ones which are commonly used in Unix-like OS-es.
+ */
+ {"ro", MS_RDONLY, 1},
+ {"nosuid", MS_NOSUID, 1},
+ {"nodev", MS_NODEV, 1},
+ {"noatime", MS_NOATIME, 1},
+ {"noexec", MS_NOEXEC, 1},
+#ifdef GF_LINUX_HOST_OS
+ {"rw", MS_RDONLY, 0},
+ {"suid", MS_NOSUID, 0},
+ {"dev", MS_NODEV, 0},
+ {"exec", MS_NOEXEC, 0},
+ {"async", MS_SYNCHRONOUS, 0},
+ {"sync", MS_SYNCHRONOUS, 1},
+ {"atime", MS_NOATIME, 0},
+ {"dirsync", MS_DIRSYNC, 1},
+#endif
+ {NULL, 0, 0}
+};
+
+static int
+mount_param_to_flag (char *mnt_param, mount_flag_t *mntflags,
+ char **mnt_param_new)
+{
+ gf_boolean_t found = _gf_false;
+ struct mount_flags *flag = NULL;
+ char *param_tok = NULL;
+ token_iter_t tit = {0,};
+ gf_boolean_t iter_end = _gf_false;
+
+ /* Allocate a buffer that will hold the mount parameters remaining
+ * after the ones corresponding to mount flags are processed and
+ * removed.The length of the original params are a good upper bound
+ * of the size needed.
+ */
+ *mnt_param_new = strdup (mnt_param);
+ if (!*mnt_param_new)
+ return -1;
+
+ for (param_tok = token_iter_init (*mnt_param_new, ',', &tit) ;;) {
+ iter_end = next_token (&param_tok, &tit);
+
+ found = _gf_false;
+ for (flag = mount_flags; flag->opt; flag++) {
+ /* Compare the mount flag name to the param
+ * name at hand.
+ */
+ if (strcmp (flag->opt, param_tok) == 0) {
+ /* If there is a match, adjust mntflags
+ * accordingly and break.
+ */
+ if (flag->on) {
+ *mntflags |= flag->flag;
+ } else {
+ *mntflags &= ~flag->flag;
+ }
+ found = _gf_true;
+ break;
+ }
+ }
+ /* Exclude flag names from new parameter list. */
+ if (found)
+ drop_token (param_tok, &tit);
+
+ if (iter_end)
+ break;
+ }
+
+ return 0;
+}
+
static int
fuse_mount_sys (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param, int fd)
+ char *mnt_param, int fd)
{
int ret = -1;
unsigned mounted = 0;
char *mnt_param_mnt = NULL;
char *fstype = "fuse.glusterfs";
char *source = fsname;
-
- ret = asprintf (&mnt_param_mnt,
- "%s,fd=%i,rootmode=%o,user_id=%i,group_id=%i",
- mnt_param, fd, S_IFDIR, getuid (), getgid ());
+ mount_flag_t mountflags = 0;
+ char *mnt_param_new = NULL;
+
+ ret = mount_param_to_flag (mnt_param, &mountflags, &mnt_param_new);
+ if (ret == 0)
+ ret = asprintf (&mnt_param_mnt,
+ "%s,fd=%i,rootmode=%o,user_id=%i,group_id=%i",
+ mnt_param_new, fd, S_IFDIR, getuid (),
+ getgid ());
if (ret == -1) {
GFFUSE_LOGERR ("Out of memory");
@@ -256,6 +390,7 @@ fuse_mount_sys (const char *mountpoint, char *fsname,
build_iovec (&iov, &iovlen, "from", "/dev/fuse", -1);
build_iovec (&iov, &iovlen, "volname", source, -1);
build_iovec (&iov, &iovlen, "fd", fdstr, -1);
+ build_iovec (&iov, &iovlen, "allow_other", NULL, -1);
ret = nmount (iov, iovlen, mountflags);
#else
ret = mount (source, mountpoint, fstype, mountflags,
@@ -295,7 +430,7 @@ fuse_mount_sys (const char *mountpoint, char *fsname,
ret = asprintf (&mnt_param_mtab, "%s%s",
mountflags & MS_RDONLY ? "ro," : "",
- mnt_param);
+ mnt_param_new);
if (ret == -1)
GFFUSE_LOGERR ("Out of memory");
else {
@@ -320,6 +455,7 @@ out:
umount2 (mountpoint, 2); /* lazy umount */
}
FREE (mnt_param_mnt);
+ FREE (mnt_param_new);
if (source != fsname)
FREE (source);
@@ -328,8 +464,7 @@ out:
int
gf_fuse_mount (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param,
- pid_t *mnt_pid, int status_fd)
+ char *mnt_param, pid_t *mnt_pid, int status_fd)
{
int fd = -1;
pid_t pid = -1;
@@ -356,16 +491,19 @@ gf_fuse_mount (const char *mountpoint, char *fsname,
exit (pid == -1 ? 1 : 0);
}
- ret = fuse_mount_sys (mountpoint, fsname, mountflags, mnt_param,
- fd);
+ ret = fuse_mount_sys (mountpoint, fsname, mnt_param, fd);
if (ret == -1) {
gf_log ("glusterfs-fuse", GF_LOG_INFO,
- "direct mount failed (%s) errno %d, "
- "retry to mount via fusermount",
+ "direct mount failed (%s) errno %d",
strerror (errno), errno);
- ret = fuse_mount_fusermount (mountpoint, fsname,
- mountflags, mnt_param, fd);
+ if (errno == EPERM) {
+ gf_log ("glusterfs-fuse", GF_LOG_INFO,
+ "retry to mount via fusermount");
+
+ ret = fuse_mount_fusermount (mountpoint, fsname,
+ mnt_param, fd);
+ }
}
if (ret == -1)
diff --git a/contrib/fuse-util/fusermount.c b/contrib/fuse-util/fusermount.c
index a64d8e102ff..ff743f75a21 100644
--- a/contrib/fuse-util/fusermount.c
+++ b/contrib/fuse-util/fusermount.c
@@ -520,20 +520,22 @@ static void parse_line(char *line, int linenum)
static void read_conf(void)
{
+ int len;
FILE *fp = fopen(FUSE_CONF, "r");
if (fp != NULL) {
int linenum = 1;
char line[256];
int isnewline = 1;
while (fgets(line, sizeof(line), fp) != NULL) {
+ len = strlen (line);
if (isnewline) {
- if (strlen(line) && line[strlen(line)-1] == '\n') {
+ if (len && line[len-1] == '\n') {
strip_line(line);
parse_line(line, linenum);
} else {
isnewline = 0;
}
- } else if(strlen(line) && line[strlen(line)-1] == '\n') {
+ } else if (len && line[len-1] == '\n') {
fprintf(stderr, "%s: reading %s: line %i too long\n", progname, FUSE_CONF, linenum);
isnewline = 1;
diff --git a/contrib/ipaddr-py/COPYING b/contrib/ipaddr-py/COPYING
deleted file mode 100644
index d6456956733..00000000000
--- a/contrib/ipaddr-py/COPYING
+++ /dev/null
@@ -1,202 +0,0 @@
-
- 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
deleted file mode 100644
index f572804441b..00000000000
--- a/contrib/ipaddr-py/MANIFEST.in
+++ /dev/null
@@ -1,3 +0,0 @@
-include COPYING
-include ipaddr_test.py
-include RELEASENOTES
diff --git a/contrib/ipaddr-py/OWNERS b/contrib/ipaddr-py/OWNERS
deleted file mode 100644
index 501673e0395..00000000000
--- a/contrib/ipaddr-py/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-pmoody
-harro
-mshields
-smart
diff --git a/contrib/ipaddr-py/README b/contrib/ipaddr-py/README
deleted file mode 100644
index 1b54294bb10..00000000000
--- a/contrib/ipaddr-py/README
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index a89298a315d..00000000000
--- a/contrib/ipaddr-py/ipaddr.py
+++ /dev/null
@@ -1,1907 +0,0 @@
-#!/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
deleted file mode 100755
index 09bece0e751..00000000000
--- a/contrib/ipaddr-py/ipaddr_test.py
+++ /dev/null
@@ -1,1099 +0,0 @@
-#!/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
deleted file mode 100755
index 33564320e45..00000000000
--- a/contrib/ipaddr-py/setup.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/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
deleted file mode 100755
index 408d665bcc2..00000000000
--- a/contrib/ipaddr-py/test-2to3.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/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/macfuse/mount_darwin.c b/contrib/macfuse/mount_darwin.c
index 10eff204bc6..d1d1c34e761 100644
--- a/contrib/macfuse/mount_darwin.c
+++ b/contrib/macfuse/mount_darwin.c
@@ -34,16 +34,15 @@
#include "fuse_param.h"
#include "fuse_ioctl.h"
-#include "glusterfs.h"
-#include "logging.h"
-#include "common-utils.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/common-utils.h"
#define GFFUSE_LOGERR(...) \
gf_log ("glusterfs-fuse", GF_LOG_ERROR, ## __VA_ARGS__)
int
-gf_fuse_mount (const char *mountpoint, char *fsname,
- unsigned long mountflags, char *mnt_param,
+gf_fuse_mount (const char *mountpoint, char *fsname, char *mnt_param,
pid_t *mnt_pid, int status_fd) /* Not used on OS X */
{
int fd = 0;
@@ -95,7 +94,7 @@ gf_fuse_mount (const char *mountpoint, char *fsname,
}
/* sysctlbyname() includes the trailing '\0' in version_len */
- version_len_desired = strlen("2.x.y") + 1;
+ version_len_desired = sizeof ("2.x.y");
if (version_len != version_len_desired) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
diff --git a/contrib/mount/mntent.c b/contrib/mount/mntent.c
index e9b448845a7..9a7e5f39bdb 100644
--- a/contrib/mount/mntent.c
+++ b/contrib/mount/mntent.c
@@ -36,6 +36,7 @@
*/
#if !defined(GF_LINUX_HOST_OS)
+
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
@@ -49,166 +50,209 @@ typedef struct statvfs gf_statfs_t;
typedef struct statfs gf_statfs_t;
#endif
-static int pos = -1;
-static int mntsize = -1;
-static struct mntent _mntent;
+typedef struct _mntent_state {
+ struct mntent mntent;
+ gf_statfs_t *statfs;
+ int count;
+ int pos;
+ /* A buffer big enough to store all defined flags as a string.
+ * Increase it if necessary when more flags are defined. */
+ char buf[256];
+} mntent_state_t;
+
+typedef struct _mntflag {
+ unsigned long value;
+ const char *on;
+ const char *off;
+} mntflag_t;
+
+static mntflag_t mntflags[] = {
+ { MNT_RDONLY, "ro", "rw" },
+ { MNT_SYNCHRONOUS, "sync", NULL },
+ { MNT_NOEXEC, "noexec", NULL },
+ { MNT_NOSUID, "nosuid", NULL },
+#if !defined(__FreeBSD__)
+ { MNT_NODEV, "nodev", NULL },
+#endif /* __FreeBSD__ */
+ { MNT_UNION, "union", NULL },
+ { MNT_ASYNC, "async", NULL },
+#if !defined(GF_DARWIN_HOST_OS)
+ { MNT_NOATIME, "noatime", NULL },
+#if !defined(__NetBSD__)
+ { MNT_NOCLUSTERR, "noclusterr", NULL },
+ { MNT_NOCLUSTERW, "noclusterw", NULL },
+ { MNT_NOSYMFOLLOW, "nosymfollow", NULL },
+ { MNT_SUIDDIR, "suiddir", NULL },
+#endif /* !__NetBSD__ */
+#endif /* !GF_DARWIN_HOST_OS */
+ { 0, NULL, NULL }
+};
char *
hasmntopt (const struct mntent *mnt, const char *option)
{
- int found;
char *opt, *optbuf;
+ int len;
optbuf = strdup(mnt->mnt_opts);
- found = 0;
- for (opt = optbuf; (opt = strtok(opt, " ")) != NULL; opt = NULL) {
- if (!strcasecmp(opt, option)) {
- opt = opt - optbuf + mnt->mnt_opts;
- free (optbuf);
- return (opt);
+ if (optbuf == NULL) {
+ return NULL;
+ }
+
+ opt = optbuf;
+ len = 0;
+ while (*opt) {
+ while (opt[len] != 0) {
+ if (opt[len] == ' ') {
+ opt[len++] = 0;
+ break;
+ }
+ len++;
+ }
+ if ((*opt != 0) && (strcasecmp(opt, option) == 0)) {
+ break;
}
+ opt += len;
+ len = 0;
}
- free (optbuf);
- return (NULL);
+ free(optbuf);
+ if (len == 0) {
+ return NULL;
+ }
+
+ return opt - optbuf + mnt->mnt_opts;
}
-static char *
-concatopt (char *s0, const char *s1)
+static int
+writeopt(const char *text, char *buf, int buflen, int pos)
{
- size_t i;
- char *cp;
-
- if (s1 == NULL || *s1 == '\0')
- return s0;
- if (s0 && *s0) {
- i = strlen(s0) + strlen(s1) + 1 + 1;
- if ((cp = (char *)malloc(i)) == NULL)
- return (NULL);
- (void)snprintf(cp, i, "%s %s", s0, s1);
- } else
- cp = strdup(s1);
-
- if (s0)
- free(s0);
- return (cp);
-}
+ int len;
+
+ /* buflen must be > 0 */
+
+ if (text == NULL) {
+ return pos;
+ }
+
+ buf += pos;
+ if (pos > 0) {
+ /* We are sure we have at least one byte to store the space.
+ * We don't need to check buflen here. */
+ *buf++ = ' ';
+ pos++;
+ }
+ len = strlen(text) + 1;
+ pos += len;
+ if (pos >= buflen) {
+ /* There won't be enough space for the text and the
+ * terminating null character. We copy as much as we can
+ * of the text and mark the end of the string with '...' */
+ memcpy(buf, text, buflen - pos + len);
+ if (buflen > 3) {
+ strcpy(buf + buflen - 4, "...");
+ } else {
+ strncpy(buf, "...", buflen - 1);
+ buf[buflen - 1] = 0;
+ }
+ pos = buflen;
+ } else {
+ memcpy(buf, text, len);
+ }
+ return pos;
+}
static char *
-flags2opts (int flags)
+flags2opts (int flags, char *buf, int buflen)
{
- char *res;
- res = NULL;
- res = concatopt(res, (flags & MNT_RDONLY) ? "ro" : "rw");
- if (flags & MNT_SYNCHRONOUS) res = concatopt(res, "sync");
- if (flags & MNT_NOEXEC) res = concatopt(res, "noexec");
- if (flags & MNT_NOSUID) res = concatopt(res, "nosuid");
-#if !defined(__FreeBSD__)
- if (flags & MNT_NODEV) res = concatopt(res, "nodev");
-#endif /* __FreeBSD__ */
- if (flags & MNT_UNION) res = concatopt(res, "union");
- if (flags & MNT_ASYNC) res = concatopt(res, "async");
-#if !defined(GF_DARWIN_HOST_OS)
- if (flags & MNT_NOATIME) res = concatopt(res, "noatime");
-#if !defined(__NetBSD__)
- if (flags & MNT_NOCLUSTERR) res = concatopt(res, "noclusterr");
- if (flags & MNT_NOCLUSTERW) res = concatopt(res, "noclusterw");
- if (flags & MNT_NOSYMFOLLOW) res = concatopt(res, "nosymfollow");
- if (flags & MNT_SUIDDIR) res = concatopt(res, "suiddir");
-#endif /* !__NetBSD__ */
-#endif /* !GF_DARWIN_HOS_OS */
- return res;
+ char other[16];
+ mntflag_t *flg;
+ int pos;
+
+ if (buflen == 0) {
+ return NULL;
+ }
+
+ pos = 0;
+ for (flg = mntflags; flg->value != 0; flg++) {
+ pos = writeopt((flags & flg->value) == 0 ? flg->off : flg->on,
+ buf, buflen, pos);
+ flags &= ~flg->value;
+ }
+
+ if (flags != 0) {
+ sprintf(other, "[0x%x]", flags);
+ writeopt(other, buf, buflen, pos);
+ }
+
+ return buf;
}
-static struct mntent *
-statfs_to_mntent (gf_statfs_t *mntbuf)
+static void
+statfs_to_mntent (struct mntent *mntent, gf_statfs_t *mntbuf, char *buf,
+ int buflen)
{
- static char opts_buf[40], *tmp;
int f_flags;
- _mntent.mnt_fsname = mntbuf->f_mntfromname;
- _mntent.mnt_dir = mntbuf->f_mntonname;
- _mntent.mnt_type = mntbuf->f_fstypename;
+ mntent->mnt_fsname = mntbuf->f_mntfromname;
+ mntent->mnt_dir = mntbuf->f_mntonname;
+ mntent->mnt_type = mntbuf->f_fstypename;
#ifdef __NetBSD__
f_flags = mntbuf->f_flag;
#else
f_flags = mntbuf->f_flags;
#endif
- tmp = flags2opts (f_flags);
- if (tmp) {
- opts_buf[sizeof(opts_buf)-1] = '\0';
- strncpy (opts_buf, tmp, sizeof(opts_buf)-1);
- free (tmp);
- } else {
- *opts_buf = '\0';
- }
- _mntent.mnt_opts = opts_buf;
- _mntent.mnt_freq = _mntent.mnt_passno = 0;
- return (&_mntent);
+ mntent->mnt_opts = flags2opts (f_flags, buf, buflen);
+
+ mntent->mnt_freq = mntent->mnt_passno = 0;
}
struct mntent *
-getmntent (FILE *fp)
+getmntent_r (FILE *fp, struct mntent *mntent, char *buf, int buflen)
{
- gf_statfs_t *mntbuf;
+ mntent_state_t *state = (mntent_state_t *)fp;
- if (!fp)
+ if (state->pos >= state->count) {
return NULL;
-
- if (pos == -1 || mntsize == -1)
- mntsize = getmntinfo (&mntbuf, MNT_NOWAIT);
-
- ++pos;
- if (pos == mntsize) {
- pos = mntsize = -1;
- return (NULL);
}
- return (statfs_to_mntent (&mntbuf[pos]));
+ statfs_to_mntent(mntent, &state->statfs[state->pos++], buf, buflen);
+
+ return mntent;
}
-/*
- Careful using this function ``buffer`` and ``bufsize`` are
- ignored since there is no stream with strings to populate
- them on OSX or NetBSD, if one wishes to populate them then
- perhaps a new function should be written in this source file
- which uses 'getmntinfo()' to stringify the mntent's
-*/
-
-struct mntent *getmntent_r (FILE *fp, struct mntent *result,
- char *buffer, int bufsize)
+struct mntent *
+getmntent (FILE *fp)
{
- struct mntent *ment = NULL;
-
- if (!fp)
- return NULL;
+ mntent_state_t *state = (mntent_state_t *)fp;
- flockfile (fp);
- ment = getmntent (fp);
- memcpy (result, ment, sizeof(*ment));
- funlockfile (fp);
-
- return result;
+ return getmntent_r(fp, &state->mntent, state->buf,
+ sizeof(state->buf));
}
FILE *
setmntent (const char *filename, const char *type)
{
- FILE *fp = NULL;
-#ifdef GF_DARWIN_HOST_OS
- fp = fopen (filename, "w");
-#else
- fp = fopen (filename, type);
-#endif
- return fp;
+ mntent_state_t *state;
+
+ /* We don't really need to access any file so we'll use the FILE* as
+ * a fake file to store state information.
+ */
+
+ state = malloc(sizeof(mntent_state_t));
+ if (state != NULL) {
+ state->pos = 0;
+ state->count = getmntinfo(&state->statfs, MNT_NOWAIT);
+ }
+
+ return (FILE *)state;
}
int
endmntent (FILE *fp)
{
- if (fp)
- fclose (fp);
+ free(fp);
return 1; /* endmntent() always returns 1 */
}
diff --git a/contrib/qemu/block.c b/contrib/qemu/block.c
deleted file mode 100644
index b56024113b8..00000000000
--- a/contrib/qemu/block.c
+++ /dev/null
@@ -1,4604 +0,0 @@
-/*
- * QEMU System Emulator block driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "config-host.h"
-#include "qemu-common.h"
-#include "trace.h"
-#include "monitor/monitor.h"
-#include "block/block_int.h"
-#include "block/blockjob.h"
-#include "qemu/module.h"
-#include "qapi/qmp/qjson.h"
-#include "sysemu/sysemu.h"
-#include "qemu/notify.h"
-#include "block/coroutine.h"
-#include "qmp-commands.h"
-#include "qemu/timer.h"
-
-#ifdef CONFIG_BSD
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/queue.h>
-#ifndef __DragonFly__
-#include <sys/disk.h>
-#endif
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
-
-typedef enum {
- BDRV_REQ_COPY_ON_READ = 0x1,
- BDRV_REQ_ZERO_WRITE = 0x2,
-} BdrvRequestFlags;
-
-static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
-static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- QEMUIOVector *iov);
-static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- QEMUIOVector *iov);
-static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov,
- int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque,
- bool is_write);
-static void coroutine_fn bdrv_co_do_rw(void *opaque);
-static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors);
-
-static bool bdrv_exceed_bps_limits(BlockDriverState *bs, int nb_sectors,
- bool is_write, double elapsed_time, uint64_t *wait);
-static bool bdrv_exceed_iops_limits(BlockDriverState *bs, bool is_write,
- double elapsed_time, uint64_t *wait);
-static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors,
- bool is_write, int64_t *wait);
-
-static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
- QTAILQ_HEAD_INITIALIZER(bdrv_states);
-
-static QLIST_HEAD(, BlockDriver) bdrv_drivers =
- QLIST_HEAD_INITIALIZER(bdrv_drivers);
-
-/* If non-zero, use only whitelisted block drivers */
-static int use_bdrv_whitelist;
-
-#ifdef _WIN32
-static int is_windows_drive_prefix(const char *filename)
-{
- return (((filename[0] >= 'a' && filename[0] <= 'z') ||
- (filename[0] >= 'A' && filename[0] <= 'Z')) &&
- filename[1] == ':');
-}
-
-int is_windows_drive(const char *filename)
-{
- if (is_windows_drive_prefix(filename) &&
- filename[2] == '\0')
- return 1;
- if (strstart(filename, "\\\\.\\", NULL) ||
- strstart(filename, "//./", NULL))
- return 1;
- return 0;
-}
-#endif
-
-/* throttling disk I/O limits */
-void bdrv_io_limits_disable(BlockDriverState *bs)
-{
- bs->io_limits_enabled = false;
-
- while (qemu_co_queue_next(&bs->throttled_reqs));
-
- if (bs->block_timer) {
- qemu_del_timer(bs->block_timer);
- qemu_free_timer(bs->block_timer);
- bs->block_timer = NULL;
- }
-
- bs->slice_start = 0;
- bs->slice_end = 0;
-}
-
-static void bdrv_block_timer(void *opaque)
-{
- BlockDriverState *bs = opaque;
-
- qemu_co_queue_next(&bs->throttled_reqs);
-}
-
-void bdrv_io_limits_enable(BlockDriverState *bs)
-{
- qemu_co_queue_init(&bs->throttled_reqs);
- bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs);
- bs->io_limits_enabled = true;
-}
-
-bool bdrv_io_limits_enabled(BlockDriverState *bs)
-{
- BlockIOLimit *io_limits = &bs->io_limits;
- return io_limits->bps[BLOCK_IO_LIMIT_READ]
- || io_limits->bps[BLOCK_IO_LIMIT_WRITE]
- || io_limits->bps[BLOCK_IO_LIMIT_TOTAL]
- || io_limits->iops[BLOCK_IO_LIMIT_READ]
- || io_limits->iops[BLOCK_IO_LIMIT_WRITE]
- || io_limits->iops[BLOCK_IO_LIMIT_TOTAL];
-}
-
-static void bdrv_io_limits_intercept(BlockDriverState *bs,
- bool is_write, int nb_sectors)
-{
- int64_t wait_time = -1;
-
- if (!qemu_co_queue_empty(&bs->throttled_reqs)) {
- qemu_co_queue_wait(&bs->throttled_reqs);
- }
-
- /* In fact, we hope to keep each request's timing, in FIFO mode. The next
- * throttled requests will not be dequeued until the current request is
- * allowed to be serviced. So if the current request still exceeds the
- * limits, it will be inserted to the head. All requests followed it will
- * be still in throttled_reqs queue.
- */
-
- while (bdrv_exceed_io_limits(bs, nb_sectors, is_write, &wait_time)) {
- qemu_mod_timer(bs->block_timer,
- wait_time + qemu_get_clock_ns(vm_clock));
- qemu_co_queue_wait_insert_head(&bs->throttled_reqs);
- }
-
- qemu_co_queue_next(&bs->throttled_reqs);
-}
-
-/* check if the path starts with "<protocol>:" */
-static int path_has_protocol(const char *path)
-{
- const char *p;
-
-#ifdef _WIN32
- if (is_windows_drive(path) ||
- is_windows_drive_prefix(path)) {
- return 0;
- }
- p = path + strcspn(path, ":/\\");
-#else
- p = path + strcspn(path, ":/");
-#endif
-
- return *p == ':';
-}
-
-int path_is_absolute(const char *path)
-{
-#ifdef _WIN32
- /* specific case for names like: "\\.\d:" */
- if (is_windows_drive(path) || is_windows_drive_prefix(path)) {
- return 1;
- }
- return (*path == '/' || *path == '\\');
-#else
- return (*path == '/');
-#endif
-}
-
-/* if filename is absolute, just copy it to dest. Otherwise, build a
- path to it by considering it is relative to base_path. URL are
- supported. */
-void path_combine(char *dest, int dest_size,
- const char *base_path,
- const char *filename)
-{
- const char *p, *p1;
- int len;
-
- if (dest_size <= 0)
- return;
- if (path_is_absolute(filename)) {
- pstrcpy(dest, dest_size, filename);
- } else {
- p = strchr(base_path, ':');
- if (p)
- p++;
- else
- p = base_path;
- p1 = strrchr(base_path, '/');
-#ifdef _WIN32
- {
- const char *p2;
- p2 = strrchr(base_path, '\\');
- if (!p1 || p2 > p1)
- p1 = p2;
- }
-#endif
- if (p1)
- p1++;
- else
- p1 = base_path;
- if (p1 > p)
- p = p1;
- len = p - base_path;
- if (len > dest_size - 1)
- len = dest_size - 1;
- memcpy(dest, base_path, len);
- dest[len] = '\0';
- pstrcat(dest, dest_size, filename);
- }
-}
-
-void bdrv_get_full_backing_filename(BlockDriverState *bs, char *dest, size_t sz)
-{
- if (bs->backing_file[0] == '\0' || path_has_protocol(bs->backing_file)) {
- pstrcpy(dest, sz, bs->backing_file);
- } else {
- path_combine(dest, sz, bs->filename, bs->backing_file);
- }
-}
-
-void bdrv_register(BlockDriver *bdrv)
-{
- /* Block drivers without coroutine functions need emulation */
- if (!bdrv->bdrv_co_readv) {
- bdrv->bdrv_co_readv = bdrv_co_readv_em;
- bdrv->bdrv_co_writev = bdrv_co_writev_em;
-
- /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if
- * the block driver lacks aio we need to emulate that too.
- */
- if (!bdrv->bdrv_aio_readv) {
- /* add AIO emulation layer */
- bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
- bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
- }
- }
-
- QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
-}
-
-/* create a new block device (by default it is empty) */
-BlockDriverState *bdrv_new(const char *device_name)
-{
- BlockDriverState *bs;
-
- bs = g_malloc0(sizeof(BlockDriverState));
- pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
- if (device_name[0] != '\0') {
- QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
- }
- bdrv_iostatus_disable(bs);
- notifier_list_init(&bs->close_notifiers);
- notifier_with_return_list_init(&bs->before_write_notifiers);
-
- return bs;
-}
-
-void bdrv_add_close_notifier(BlockDriverState *bs, Notifier *notify)
-{
- notifier_list_add(&bs->close_notifiers, notify);
-}
-
-BlockDriver *bdrv_find_format(const char *format_name)
-{
- BlockDriver *drv1;
- QLIST_FOREACH(drv1, &bdrv_drivers, list) {
- if (!strcmp(drv1->format_name, format_name)) {
- return drv1;
- }
- }
- return NULL;
-}
-
-static int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
-{
- static const char *whitelist_rw[] = {
- CONFIG_BDRV_RW_WHITELIST
- };
- static const char *whitelist_ro[] = {
- CONFIG_BDRV_RO_WHITELIST
- };
- const char **p;
-
- if (!whitelist_rw[0] && !whitelist_ro[0]) {
- return 1; /* no whitelist, anything goes */
- }
-
- for (p = whitelist_rw; *p; p++) {
- if (!strcmp(drv->format_name, *p)) {
- return 1;
- }
- }
- if (read_only) {
- for (p = whitelist_ro; *p; p++) {
- if (!strcmp(drv->format_name, *p)) {
- return 1;
- }
- }
- }
- return 0;
-}
-
-BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
- bool read_only)
-{
- BlockDriver *drv = bdrv_find_format(format_name);
- return drv && bdrv_is_whitelisted(drv, read_only) ? drv : NULL;
-}
-
-typedef struct CreateCo {
- BlockDriver *drv;
- char *filename;
- QEMUOptionParameter *options;
- int ret;
-} CreateCo;
-
-static void coroutine_fn bdrv_create_co_entry(void *opaque)
-{
- CreateCo *cco = opaque;
- assert(cco->drv);
-
- cco->ret = cco->drv->bdrv_create(cco->filename, cco->options);
-}
-
-int bdrv_create(BlockDriver *drv, const char* filename,
- QEMUOptionParameter *options)
-{
- int ret;
-
- Coroutine *co;
- CreateCo cco = {
- .drv = drv,
- .filename = g_strdup(filename),
- .options = options,
- .ret = NOT_DONE,
- };
-
- if (!drv->bdrv_create) {
- ret = -ENOTSUP;
- goto out;
- }
-
- if (qemu_in_coroutine()) {
- /* Fast-path if already in coroutine context */
- bdrv_create_co_entry(&cco);
- } else {
- co = qemu_coroutine_create(bdrv_create_co_entry);
- qemu_coroutine_enter(co, &cco);
- while (cco.ret == NOT_DONE) {
- qemu_aio_wait();
- }
- }
-
- ret = cco.ret;
-
-out:
- g_free(cco.filename);
- return ret;
-}
-
-int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
-{
- BlockDriver *drv;
-
- drv = bdrv_find_protocol(filename, true);
- if (drv == NULL) {
- return -ENOENT;
- }
-
- return bdrv_create(drv, filename, options);
-}
-
-/*
- * Create a uniquely-named empty temporary file.
- * Return 0 upon success, otherwise a negative errno value.
- */
-int get_tmp_filename(char *filename, int size)
-{
-#ifdef _WIN32
- char temp_dir[MAX_PATH];
- /* GetTempFileName requires that its output buffer (4th param)
- have length MAX_PATH or greater. */
- assert(size >= MAX_PATH);
- return (GetTempPath(MAX_PATH, temp_dir)
- && GetTempFileName(temp_dir, "qem", 0, filename)
- ? 0 : -GetLastError());
-#else
- int fd;
- const char *tmpdir;
- tmpdir = getenv("TMPDIR");
- if (!tmpdir)
- tmpdir = "/tmp";
- if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) {
- return -EOVERFLOW;
- }
- fd = mkstemp(filename);
- if (fd < 0) {
- return -errno;
- }
- if (close(fd) != 0) {
- unlink(filename);
- return -errno;
- }
- return 0;
-#endif
-}
-
-/*
- * Detect host devices. By convention, /dev/cdrom[N] is always
- * recognized as a host CDROM.
- */
-static BlockDriver *find_hdev_driver(const char *filename)
-{
- int score_max = 0, score;
- BlockDriver *drv = NULL, *d;
-
- QLIST_FOREACH(d, &bdrv_drivers, list) {
- if (d->bdrv_probe_device) {
- score = d->bdrv_probe_device(filename);
- if (score > score_max) {
- score_max = score;
- drv = d;
- }
- }
- }
-
- return drv;
-}
-
-BlockDriver *bdrv_find_protocol(const char *filename,
- bool allow_protocol_prefix)
-{
- BlockDriver *drv1;
- char protocol[128];
- int len;
- const char *p;
-
- /* TODO Drivers without bdrv_file_open must be specified explicitly */
-
- /*
- * XXX(hch): we really should not let host device detection
- * override an explicit protocol specification, but moving this
- * later breaks access to device names with colons in them.
- * Thanks to the brain-dead persistent naming schemes on udev-
- * based Linux systems those actually are quite common.
- */
- drv1 = find_hdev_driver(filename);
- if (drv1) {
- return drv1;
- }
-
- if (!path_has_protocol(filename) || !allow_protocol_prefix) {
- return bdrv_find_format("file");
- }
-
- p = strchr(filename, ':');
- assert(p != NULL);
- len = p - filename;
- if (len > sizeof(protocol) - 1)
- len = sizeof(protocol) - 1;
- memcpy(protocol, filename, len);
- protocol[len] = '\0';
- QLIST_FOREACH(drv1, &bdrv_drivers, list) {
- if (drv1->protocol_name &&
- !strcmp(drv1->protocol_name, protocol)) {
- return drv1;
- }
- }
- return NULL;
-}
-
-static int find_image_format(BlockDriverState *bs, const char *filename,
- BlockDriver **pdrv)
-{
- int score, score_max;
- BlockDriver *drv1, *drv;
- uint8_t buf[2048];
- int ret = 0;
-
- /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
- if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
- drv = bdrv_find_format("raw");
- if (!drv) {
- ret = -ENOENT;
- }
- *pdrv = drv;
- return ret;
- }
-
- ret = bdrv_pread(bs, 0, buf, sizeof(buf));
- if (ret < 0) {
- *pdrv = NULL;
- return ret;
- }
-
- score_max = 0;
- drv = NULL;
- QLIST_FOREACH(drv1, &bdrv_drivers, list) {
- if (drv1->bdrv_probe) {
- score = drv1->bdrv_probe(buf, ret, filename);
- if (score > score_max) {
- score_max = score;
- drv = drv1;
- }
- }
- }
- if (!drv) {
- ret = -ENOENT;
- }
- *pdrv = drv;
- return ret;
-}
-
-/**
- * Set the current 'total_sectors' value
- */
-static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
-{
- BlockDriver *drv = bs->drv;
-
- /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */
- if (bs->sg)
- return 0;
-
- /* query actual device if possible, otherwise just trust the hint */
- if (drv->bdrv_getlength) {
- int64_t length = drv->bdrv_getlength(bs);
- if (length < 0) {
- return length;
- }
- hint = length >> BDRV_SECTOR_BITS;
- }
-
- bs->total_sectors = hint;
- return 0;
-}
-
-/**
- * Set open flags for a given discard mode
- *
- * Return 0 on success, -1 if the discard mode was invalid.
- */
-int bdrv_parse_discard_flags(const char *mode, int *flags)
-{
- *flags &= ~BDRV_O_UNMAP;
-
- if (!strcmp(mode, "off") || !strcmp(mode, "ignore")) {
- /* do nothing */
- } else if (!strcmp(mode, "on") || !strcmp(mode, "unmap")) {
- *flags |= BDRV_O_UNMAP;
- } else {
- return -1;
- }
-
- return 0;
-}
-
-/**
- * Set open flags for a given cache mode
- *
- * Return 0 on success, -1 if the cache mode was invalid.
- */
-int bdrv_parse_cache_flags(const char *mode, int *flags)
-{
- *flags &= ~BDRV_O_CACHE_MASK;
-
- if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
- *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
- } else if (!strcmp(mode, "directsync")) {
- *flags |= BDRV_O_NOCACHE;
- } else if (!strcmp(mode, "writeback")) {
- *flags |= BDRV_O_CACHE_WB;
- } else if (!strcmp(mode, "unsafe")) {
- *flags |= BDRV_O_CACHE_WB;
- *flags |= BDRV_O_NO_FLUSH;
- } else if (!strcmp(mode, "writethrough")) {
- /* this is the default */
- } else {
- return -1;
- }
-
- return 0;
-}
-
-/**
- * The copy-on-read flag is actually a reference count so multiple users may
- * use the feature without worrying about clobbering its previous state.
- * Copy-on-read stays enabled until all users have called to disable it.
- */
-void bdrv_enable_copy_on_read(BlockDriverState *bs)
-{
- bs->copy_on_read++;
-}
-
-void bdrv_disable_copy_on_read(BlockDriverState *bs)
-{
- assert(bs->copy_on_read > 0);
- bs->copy_on_read--;
-}
-
-static int bdrv_open_flags(BlockDriverState *bs, int flags)
-{
- int open_flags = flags | BDRV_O_CACHE_WB;
-
- /*
- * Clear flags that are internal to the block layer before opening the
- * image.
- */
- open_flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
-
- /*
- * Snapshots should be writable.
- */
- if (bs->is_temporary) {
- open_flags |= BDRV_O_RDWR;
- }
-
- return open_flags;
-}
-
-/*
- * Common part for opening disk images and files
- *
- * Removes all processed options from *options.
- */
-static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
- QDict *options, int flags, BlockDriver *drv)
-{
- int ret, open_flags;
- const char *filename;
-
- assert(drv != NULL);
- assert(bs->file == NULL);
- assert(options != NULL && bs->options != options);
-
- if (file != NULL) {
- filename = file->filename;
- } else {
- filename = qdict_get_try_str(options, "filename");
- }
-
- trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name);
-
- /* bdrv_open() with directly using a protocol as drv. This layer is already
- * opened, so assign it to bs (while file becomes a closed BlockDriverState)
- * and return immediately. */
- if (file != NULL && drv->bdrv_file_open) {
- bdrv_swap(file, bs);
- return 0;
- }
-
- bs->open_flags = flags;
- bs->buffer_alignment = 512;
- open_flags = bdrv_open_flags(bs, flags);
- bs->read_only = !(open_flags & BDRV_O_RDWR);
-
- if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) {
- return -ENOTSUP;
- }
-
- assert(bs->copy_on_read == 0); /* bdrv_new() and bdrv_close() make it so */
- if (!bs->read_only && (flags & BDRV_O_COPY_ON_READ)) {
- bdrv_enable_copy_on_read(bs);
- }
-
- if (filename != NULL) {
- pstrcpy(bs->filename, sizeof(bs->filename), filename);
- } else {
- bs->filename[0] = '\0';
- }
-
- bs->drv = drv;
- bs->opaque = g_malloc0(drv->instance_size);
-
- bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);
-
- /* Open the image, either directly or using a protocol */
- if (drv->bdrv_file_open) {
- assert(file == NULL);
- assert(drv->bdrv_parse_filename || filename != NULL);
- ret = drv->bdrv_file_open(bs, options, open_flags);
- } else {
- if (file == NULL) {
- qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't use '%s' as a "
- "block driver for the protocol level",
- drv->format_name);
- ret = -EINVAL;
- goto free_and_fail;
- }
- assert(file != NULL);
- bs->file = file;
- ret = drv->bdrv_open(bs, options, open_flags);
- }
-
- if (ret < 0) {
- goto free_and_fail;
- }
-
- ret = refresh_total_sectors(bs, bs->total_sectors);
- if (ret < 0) {
- goto free_and_fail;
- }
-
-#ifndef _WIN32
- if (bs->is_temporary) {
- assert(filename != NULL);
- unlink(filename);
- }
-#endif
- return 0;
-
-free_and_fail:
- bs->file = NULL;
- g_free(bs->opaque);
- bs->opaque = NULL;
- bs->drv = NULL;
- return ret;
-}
-
-/*
- * Opens a file using a protocol (file, host_device, nbd, ...)
- *
- * options is a QDict of options to pass to the block drivers, or NULL for an
- * empty set of options. The reference to the QDict belongs to the block layer
- * after the call (even on failure), so if the caller intends to reuse the
- * dictionary, it needs to use QINCREF() before calling bdrv_file_open.
- */
-int bdrv_file_open(BlockDriverState **pbs, const char *filename,
- QDict *options, int flags)
-{
- BlockDriverState *bs;
- BlockDriver *drv;
- const char *drvname;
- bool allow_protocol_prefix = false;
- int ret;
-
- /* NULL means an empty set of options */
- if (options == NULL) {
- options = qdict_new();
- }
-
- bs = bdrv_new("");
- bs->options = options;
- options = qdict_clone_shallow(options);
-
- /* Fetch the file name from the options QDict if necessary */
- if (!filename) {
- filename = qdict_get_try_str(options, "filename");
- } else if (filename && !qdict_haskey(options, "filename")) {
- qdict_put(options, "filename", qstring_from_str(filename));
- allow_protocol_prefix = true;
- } else {
- qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and "
- "'filename' options at the same time");
- ret = -EINVAL;
- goto fail;
- }
-
- /* Find the right block driver */
- drvname = qdict_get_try_str(options, "driver");
- if (drvname) {
- drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
- qdict_del(options, "driver");
- } else if (filename) {
- drv = bdrv_find_protocol(filename, allow_protocol_prefix);
- if (!drv) {
- qerror_report(ERROR_CLASS_GENERIC_ERROR, "Unknown protocol");
- }
- } else {
- qerror_report(ERROR_CLASS_GENERIC_ERROR,
- "Must specify either driver or file");
- drv = NULL;
- }
-
- if (!drv) {
- ret = -ENOENT;
- goto fail;
- }
-
- /* Parse the filename and open it */
- if (drv->bdrv_parse_filename && filename) {
- Error *local_err = NULL;
- drv->bdrv_parse_filename(filename, options, &local_err);
- if (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- ret = -EINVAL;
- goto fail;
- }
- qdict_del(options, "filename");
- } else if (!drv->bdrv_parse_filename && !filename) {
- qerror_report(ERROR_CLASS_GENERIC_ERROR,
- "The '%s' block driver requires a file name",
- drv->format_name);
- ret = -EINVAL;
- goto fail;
- }
-
- ret = bdrv_open_common(bs, NULL, options, flags, drv);
- if (ret < 0) {
- goto fail;
- }
-
- /* Check if any unknown options were used */
- if (qdict_size(options) != 0) {
- const QDictEntry *entry = qdict_first(options);
- qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block protocol '%s' doesn't "
- "support the option '%s'",
- drv->format_name, entry->key);
- ret = -EINVAL;
- goto fail;
- }
- QDECREF(options);
-
- bs->growable = 1;
- *pbs = bs;
- return 0;
-
-fail:
- QDECREF(options);
- if (!bs->drv) {
- QDECREF(bs->options);
- }
- bdrv_delete(bs);
- return ret;
-}
-
-/*
- * Opens the backing file for a BlockDriverState if not yet open
- *
- * options is a QDict of options to pass to the block drivers, or NULL for an
- * empty set of options. The reference to the QDict is transferred to this
- * function (even on failure), so if the caller intends to reuse the dictionary,
- * it needs to use QINCREF() before calling bdrv_file_open.
- */
-int bdrv_open_backing_file(BlockDriverState *bs, QDict *options)
-{
- char backing_filename[PATH_MAX];
- int back_flags, ret;
- BlockDriver *back_drv = NULL;
-
- if (bs->backing_hd != NULL) {
- QDECREF(options);
- return 0;
- }
-
- /* NULL means an empty set of options */
- if (options == NULL) {
- options = qdict_new();
- }
-
- bs->open_flags &= ~BDRV_O_NO_BACKING;
- if (qdict_haskey(options, "file.filename")) {
- backing_filename[0] = '\0';
- } else if (bs->backing_file[0] == '\0' && qdict_size(options) == 0) {
- QDECREF(options);
- return 0;
- }
-
- bs->backing_hd = bdrv_new("");
- bdrv_get_full_backing_filename(bs, backing_filename,
- sizeof(backing_filename));
-
- if (bs->backing_format[0] != '\0') {
- back_drv = bdrv_find_format(bs->backing_format);
- }
-
- /* backing files always opened read-only */
- back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT);
-
- ret = bdrv_open(bs->backing_hd,
- *backing_filename ? backing_filename : NULL, options,
- back_flags, back_drv);
- if (ret < 0) {
- bdrv_delete(bs->backing_hd);
- bs->backing_hd = NULL;
- bs->open_flags |= BDRV_O_NO_BACKING;
- return ret;
- }
- return 0;
-}
-
-static void extract_subqdict(QDict *src, QDict **dst, const char *start)
-{
- const QDictEntry *entry, *next;
- const char *p;
-
- *dst = qdict_new();
- entry = qdict_first(src);
-
- while (entry != NULL) {
- next = qdict_next(src, entry);
- if (strstart(entry->key, start, &p)) {
- qobject_incref(entry->value);
- qdict_put_obj(*dst, p, entry->value);
- qdict_del(src, entry->key);
- }
- entry = next;
- }
-}
-
-/*
- * Opens a disk image (raw, qcow2, vmdk, ...)
- *
- * options is a QDict of options to pass to the block drivers, or NULL for an
- * empty set of options. The reference to the QDict belongs to the block layer
- * after the call (even on failure), so if the caller intends to reuse the
- * dictionary, it needs to use QINCREF() before calling bdrv_open.
- */
-int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
- int flags, BlockDriver *drv)
-{
- int ret;
- /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
- char tmp_filename[PATH_MAX + 1];
- BlockDriverState *file = NULL;
- QDict *file_options = NULL;
-
- /* NULL means an empty set of options */
- if (options == NULL) {
- options = qdict_new();
- }
-
- bs->options = options;
- options = qdict_clone_shallow(options);
-
- /* For snapshot=on, create a temporary qcow2 overlay */
- if (flags & BDRV_O_SNAPSHOT) {
- BlockDriverState *bs1;
- int64_t total_size;
- BlockDriver *bdrv_qcow2;
- QEMUOptionParameter *create_options;
- char backing_filename[PATH_MAX];
-
- if (qdict_size(options) != 0) {
- error_report("Can't use snapshot=on with driver-specific options");
- ret = -EINVAL;
- goto fail;
- }
- assert(filename != NULL);
-
- /* if snapshot, we create a temporary backing file and open it
- instead of opening 'filename' directly */
-
- /* if there is a backing file, use it */
- bs1 = bdrv_new("");
- ret = bdrv_open(bs1, filename, NULL, 0, drv);
- if (ret < 0) {
- bdrv_delete(bs1);
- goto fail;
- }
- total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
-
- bdrv_delete(bs1);
-
- ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
- if (ret < 0) {
- goto fail;
- }
-
- /* Real path is meaningless for protocols */
- if (path_has_protocol(filename)) {
- snprintf(backing_filename, sizeof(backing_filename),
- "%s", filename);
- } else if (!realpath(filename, backing_filename)) {
- ret = -errno;
- goto fail;
- }
-
- bdrv_qcow2 = bdrv_find_format("qcow2");
- create_options = parse_option_parameters("", bdrv_qcow2->create_options,
- NULL);
-
- set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
- set_option_parameter(create_options, BLOCK_OPT_BACKING_FILE,
- backing_filename);
- if (drv) {
- set_option_parameter(create_options, BLOCK_OPT_BACKING_FMT,
- drv->format_name);
- }
-
- ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options);
- free_option_parameters(create_options);
- if (ret < 0) {
- goto fail;
- }
-
- filename = tmp_filename;
- drv = bdrv_qcow2;
- bs->is_temporary = 1;
- }
-
- /* Open image file without format layer */
- if (flags & BDRV_O_RDWR) {
- flags |= BDRV_O_ALLOW_RDWR;
- }
-
- extract_subqdict(options, &file_options, "file.");
-
- ret = bdrv_file_open(&file, filename, file_options,
- bdrv_open_flags(bs, flags | BDRV_O_UNMAP));
- if (ret < 0) {
- goto fail;
- }
-
- /* Find the right image format driver */
- if (!drv) {
- ret = find_image_format(file, filename, &drv);
- }
-
- if (!drv) {
- goto unlink_and_fail;
- }
-
- /* Open the image */
- ret = bdrv_open_common(bs, file, options, flags, drv);
- if (ret < 0) {
- goto unlink_and_fail;
- }
-
- if (bs->file != file) {
- bdrv_delete(file);
- file = NULL;
- }
-
- /* If there is a backing file, use it */
- if ((flags & BDRV_O_NO_BACKING) == 0) {
- QDict *backing_options;
-
- extract_subqdict(options, &backing_options, "backing.");
- ret = bdrv_open_backing_file(bs, backing_options);
- if (ret < 0) {
- goto close_and_fail;
- }
- }
-
- /* Check if any unknown options were used */
- if (qdict_size(options) != 0) {
- const QDictEntry *entry = qdict_first(options);
- qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by "
- "device '%s' doesn't support the option '%s'",
- drv->format_name, bs->device_name, entry->key);
-
- ret = -EINVAL;
- goto close_and_fail;
- }
- QDECREF(options);
-
- if (!bdrv_key_required(bs)) {
- bdrv_dev_change_media_cb(bs, true);
- }
-
- /* throttling disk I/O limits */
- if (bs->io_limits_enabled) {
- bdrv_io_limits_enable(bs);
- }
-
- return 0;
-
-unlink_and_fail:
- if (file != NULL) {
- bdrv_delete(file);
- }
- if (bs->is_temporary) {
- unlink(filename);
- }
-fail:
- QDECREF(bs->options);
- QDECREF(options);
- bs->options = NULL;
- return ret;
-
-close_and_fail:
- bdrv_close(bs);
- QDECREF(options);
- return ret;
-}
-
-typedef struct BlockReopenQueueEntry {
- bool prepared;
- BDRVReopenState state;
- QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry;
-} BlockReopenQueueEntry;
-
-/*
- * Adds a BlockDriverState to a simple queue for an atomic, transactional
- * reopen of multiple devices.
- *
- * bs_queue can either be an existing BlockReopenQueue that has had QSIMPLE_INIT
- * already performed, or alternatively may be NULL a new BlockReopenQueue will
- * be created and initialized. This newly created BlockReopenQueue should be
- * passed back in for subsequent calls that are intended to be of the same
- * atomic 'set'.
- *
- * bs is the BlockDriverState to add to the reopen queue.
- *
- * flags contains the open flags for the associated bs
- *
- * returns a pointer to bs_queue, which is either the newly allocated
- * bs_queue, or the existing bs_queue being used.
- *
- */
-BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
- BlockDriverState *bs, int flags)
-{
- assert(bs != NULL);
-
- BlockReopenQueueEntry *bs_entry;
- if (bs_queue == NULL) {
- bs_queue = g_new0(BlockReopenQueue, 1);
- QSIMPLEQ_INIT(bs_queue);
- }
-
- if (bs->file) {
- bdrv_reopen_queue(bs_queue, bs->file, flags);
- }
-
- bs_entry = g_new0(BlockReopenQueueEntry, 1);
- QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
-
- bs_entry->state.bs = bs;
- bs_entry->state.flags = flags;
-
- return bs_queue;
-}
-
-/*
- * Reopen multiple BlockDriverStates atomically & transactionally.
- *
- * The queue passed in (bs_queue) must have been built up previous
- * via bdrv_reopen_queue().
- *
- * Reopens all BDS specified in the queue, with the appropriate
- * flags. All devices are prepared for reopen, and failure of any
- * device will cause all device changes to be abandonded, and intermediate
- * data cleaned up.
- *
- * If all devices prepare successfully, then the changes are committed
- * to all devices.
- *
- */
-int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
-{
- int ret = -1;
- BlockReopenQueueEntry *bs_entry, *next;
- Error *local_err = NULL;
-
- assert(bs_queue != NULL);
-
- bdrv_drain_all();
-
- QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
- if (bdrv_reopen_prepare(&bs_entry->state, bs_queue, &local_err)) {
- error_propagate(errp, local_err);
- goto cleanup;
- }
- bs_entry->prepared = true;
- }
-
- /* If we reach this point, we have success and just need to apply the
- * changes
- */
- QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
- bdrv_reopen_commit(&bs_entry->state);
- }
-
- ret = 0;
-
-cleanup:
- QSIMPLEQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
- if (ret && bs_entry->prepared) {
- bdrv_reopen_abort(&bs_entry->state);
- }
- g_free(bs_entry);
- }
- g_free(bs_queue);
- return ret;
-}
-
-
-/* Reopen a single BlockDriverState with the specified flags. */
-int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp)
-{
- int ret = -1;
- Error *local_err = NULL;
- BlockReopenQueue *queue = bdrv_reopen_queue(NULL, bs, bdrv_flags);
-
- ret = bdrv_reopen_multiple(queue, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- }
- return ret;
-}
-
-
-/*
- * Prepares a BlockDriverState for reopen. All changes are staged in the
- * 'opaque' field of the BDRVReopenState, which is used and allocated by
- * the block driver layer .bdrv_reopen_prepare()
- *
- * bs is the BlockDriverState to reopen
- * flags are the new open flags
- * queue is the reopen queue
- *
- * Returns 0 on success, non-zero on error. On error errp will be set
- * as well.
- *
- * On failure, bdrv_reopen_abort() will be called to clean up any data.
- * It is the responsibility of the caller to then call the abort() or
- * commit() for any other BDS that have been left in a prepare() state
- *
- */
-int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
- Error **errp)
-{
- int ret = -1;
- Error *local_err = NULL;
- BlockDriver *drv;
-
- assert(reopen_state != NULL);
- assert(reopen_state->bs->drv != NULL);
- drv = reopen_state->bs->drv;
-
- /* if we are to stay read-only, do not allow permission change
- * to r/w */
- if (!(reopen_state->bs->open_flags & BDRV_O_ALLOW_RDWR) &&
- reopen_state->flags & BDRV_O_RDWR) {
- error_set(errp, QERR_DEVICE_IS_READ_ONLY,
- reopen_state->bs->device_name);
- goto error;
- }
-
-
- ret = bdrv_flush(reopen_state->bs);
- if (ret) {
- error_set(errp, ERROR_CLASS_GENERIC_ERROR, "Error (%s) flushing drive",
- strerror(-ret));
- goto error;
- }
-
- if (drv->bdrv_reopen_prepare) {
- ret = drv->bdrv_reopen_prepare(reopen_state, queue, &local_err);
- if (ret) {
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- } else {
- error_setg(errp, "failed while preparing to reopen image '%s'",
- reopen_state->bs->filename);
- }
- goto error;
- }
- } else {
- /* It is currently mandatory to have a bdrv_reopen_prepare()
- * handler for each supported drv. */
- error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
- drv->format_name, reopen_state->bs->device_name,
- "reopening of file");
- ret = -1;
- goto error;
- }
-
- ret = 0;
-
-error:
- return ret;
-}
-
-/*
- * Takes the staged changes for the reopen from bdrv_reopen_prepare(), and
- * makes them final by swapping the staging BlockDriverState contents into
- * the active BlockDriverState contents.
- */
-void bdrv_reopen_commit(BDRVReopenState *reopen_state)
-{
- BlockDriver *drv;
-
- assert(reopen_state != NULL);
- drv = reopen_state->bs->drv;
- assert(drv != NULL);
-
- /* If there are any driver level actions to take */
- if (drv->bdrv_reopen_commit) {
- drv->bdrv_reopen_commit(reopen_state);
- }
-
- /* set BDS specific flags now */
- reopen_state->bs->open_flags = reopen_state->flags;
- reopen_state->bs->enable_write_cache = !!(reopen_state->flags &
- BDRV_O_CACHE_WB);
- reopen_state->bs->read_only = !(reopen_state->flags & BDRV_O_RDWR);
-}
-
-/*
- * Abort the reopen, and delete and free the staged changes in
- * reopen_state
- */
-void bdrv_reopen_abort(BDRVReopenState *reopen_state)
-{
- BlockDriver *drv;
-
- assert(reopen_state != NULL);
- drv = reopen_state->bs->drv;
- assert(drv != NULL);
-
- if (drv->bdrv_reopen_abort) {
- drv->bdrv_reopen_abort(reopen_state);
- }
-}
-
-
-void bdrv_close(BlockDriverState *bs)
-{
- if (bs->job) {
- block_job_cancel_sync(bs->job);
- }
- bdrv_drain_all(); /* complete I/O */
- bdrv_flush(bs);
- bdrv_drain_all(); /* in case flush left pending I/O */
- notifier_list_notify(&bs->close_notifiers, bs);
-
- if (bs->drv) {
- if (bs->backing_hd) {
- bdrv_delete(bs->backing_hd);
- bs->backing_hd = NULL;
- }
- bs->drv->bdrv_close(bs);
- g_free(bs->opaque);
-#ifdef _WIN32
- if (bs->is_temporary) {
- unlink(bs->filename);
- }
-#endif
- bs->opaque = NULL;
- bs->drv = NULL;
- bs->copy_on_read = 0;
- bs->backing_file[0] = '\0';
- bs->backing_format[0] = '\0';
- bs->total_sectors = 0;
- bs->encrypted = 0;
- bs->valid_key = 0;
- bs->sg = 0;
- bs->growable = 0;
- QDECREF(bs->options);
- bs->options = NULL;
-
- if (bs->file != NULL) {
- bdrv_delete(bs->file);
- bs->file = NULL;
- }
- }
-
- bdrv_dev_change_media_cb(bs, false);
-
- /*throttling disk I/O limits*/
- if (bs->io_limits_enabled) {
- bdrv_io_limits_disable(bs);
- }
-}
-
-void bdrv_close_all(void)
-{
- BlockDriverState *bs;
-
- QTAILQ_FOREACH(bs, &bdrv_states, list) {
- bdrv_close(bs);
- }
-}
-
-/*
- * Wait for pending requests to complete across all BlockDriverStates
- *
- * This function does not flush data to disk, use bdrv_flush_all() for that
- * after calling this function.
- *
- * Note that completion of an asynchronous I/O operation can trigger any
- * number of other I/O operations on other devices---for example a coroutine
- * can be arbitrarily complex and a constant flow of I/O can come until the
- * coroutine is complete. Because of this, it is not possible to have a
- * function to drain a single device's I/O queue.
- */
-void bdrv_drain_all(void)
-{
- BlockDriverState *bs;
- bool busy;
-
- do {
- busy = qemu_aio_wait();
-
- /* FIXME: We do not have timer support here, so this is effectively
- * a busy wait.
- */
- QTAILQ_FOREACH(bs, &bdrv_states, list) {
- if (!qemu_co_queue_empty(&bs->throttled_reqs)) {
- qemu_co_queue_restart_all(&bs->throttled_reqs);
- busy = true;
- }
- }
- } while (busy);
-
- /* If requests are still pending there is a bug somewhere */
- QTAILQ_FOREACH(bs, &bdrv_states, list) {
- assert(QLIST_EMPTY(&bs->tracked_requests));
- assert(qemu_co_queue_empty(&bs->throttled_reqs));
- }
-}
-
-/* make a BlockDriverState anonymous by removing from bdrv_state list.
- Also, NULL terminate the device_name to prevent double remove */
-void bdrv_make_anon(BlockDriverState *bs)
-{
- if (bs->device_name[0] != '\0') {
- QTAILQ_REMOVE(&bdrv_states, bs, list);
- }
- bs->device_name[0] = '\0';
-}
-
-static void bdrv_rebind(BlockDriverState *bs)
-{
- if (bs->drv && bs->drv->bdrv_rebind) {
- bs->drv->bdrv_rebind(bs);
- }
-}
-
-static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
- BlockDriverState *bs_src)
-{
- /* move some fields that need to stay attached to the device */
- bs_dest->open_flags = bs_src->open_flags;
-
- /* dev info */
- bs_dest->dev_ops = bs_src->dev_ops;
- bs_dest->dev_opaque = bs_src->dev_opaque;
- bs_dest->dev = bs_src->dev;
- bs_dest->buffer_alignment = bs_src->buffer_alignment;
- bs_dest->copy_on_read = bs_src->copy_on_read;
-
- bs_dest->enable_write_cache = bs_src->enable_write_cache;
-
- /* i/o timing parameters */
- bs_dest->slice_start = bs_src->slice_start;
- bs_dest->slice_end = bs_src->slice_end;
- bs_dest->slice_submitted = bs_src->slice_submitted;
- bs_dest->io_limits = bs_src->io_limits;
- bs_dest->throttled_reqs = bs_src->throttled_reqs;
- bs_dest->block_timer = bs_src->block_timer;
- bs_dest->io_limits_enabled = bs_src->io_limits_enabled;
-
- /* r/w error */
- bs_dest->on_read_error = bs_src->on_read_error;
- bs_dest->on_write_error = bs_src->on_write_error;
-
- /* i/o status */
- bs_dest->iostatus_enabled = bs_src->iostatus_enabled;
- bs_dest->iostatus = bs_src->iostatus;
-
- /* dirty bitmap */
- bs_dest->dirty_bitmap = bs_src->dirty_bitmap;
-
- /* job */
- bs_dest->in_use = bs_src->in_use;
- bs_dest->job = bs_src->job;
-
- /* keep the same entry in bdrv_states */
- pstrcpy(bs_dest->device_name, sizeof(bs_dest->device_name),
- bs_src->device_name);
- bs_dest->list = bs_src->list;
-}
-
-/*
- * Swap bs contents for two image chains while they are live,
- * while keeping required fields on the BlockDriverState that is
- * actually attached to a device.
- *
- * This will modify the BlockDriverState fields, and swap contents
- * between bs_new and bs_old. Both bs_new and bs_old are modified.
- *
- * bs_new is required to be anonymous.
- *
- * This function does not create any image files.
- */
-void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
-{
- BlockDriverState tmp;
-
- /* bs_new must be anonymous and shouldn't have anything fancy enabled */
- assert(bs_new->device_name[0] == '\0');
- assert(bs_new->dirty_bitmap == NULL);
- assert(bs_new->job == NULL);
- assert(bs_new->dev == NULL);
- assert(bs_new->in_use == 0);
- assert(bs_new->io_limits_enabled == false);
- assert(bs_new->block_timer == NULL);
-
- tmp = *bs_new;
- *bs_new = *bs_old;
- *bs_old = tmp;
-
- /* there are some fields that should not be swapped, move them back */
- bdrv_move_feature_fields(&tmp, bs_old);
- bdrv_move_feature_fields(bs_old, bs_new);
- bdrv_move_feature_fields(bs_new, &tmp);
-
- /* bs_new shouldn't be in bdrv_states even after the swap! */
- assert(bs_new->device_name[0] == '\0');
-
- /* Check a few fields that should remain attached to the device */
- assert(bs_new->dev == NULL);
- assert(bs_new->job == NULL);
- assert(bs_new->in_use == 0);
- assert(bs_new->io_limits_enabled == false);
- assert(bs_new->block_timer == NULL);
-
- bdrv_rebind(bs_new);
- bdrv_rebind(bs_old);
-}
-
-/*
- * Add new bs contents at the top of an image chain while the chain is
- * live, while keeping required fields on the top layer.
- *
- * This will modify the BlockDriverState fields, and swap contents
- * between bs_new and bs_top. Both bs_new and bs_top are modified.
- *
- * bs_new is required to be anonymous.
- *
- * This function does not create any image files.
- */
-void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top)
-{
- bdrv_swap(bs_new, bs_top);
-
- /* The contents of 'tmp' will become bs_top, as we are
- * swapping bs_new and bs_top contents. */
- bs_top->backing_hd = bs_new;
- bs_top->open_flags &= ~BDRV_O_NO_BACKING;
- pstrcpy(bs_top->backing_file, sizeof(bs_top->backing_file),
- bs_new->filename);
- pstrcpy(bs_top->backing_format, sizeof(bs_top->backing_format),
- bs_new->drv ? bs_new->drv->format_name : "");
-}
-
-void bdrv_delete(BlockDriverState *bs)
-{
- assert(!bs->dev);
- assert(!bs->job);
- assert(!bs->in_use);
-
- /* remove from list, if necessary */
- bdrv_make_anon(bs);
-
- bdrv_close(bs);
-
- g_free(bs);
-}
-
-int bdrv_attach_dev(BlockDriverState *bs, void *dev)
-/* TODO change to DeviceState *dev when all users are qdevified */
-{
- if (bs->dev) {
- return -EBUSY;
- }
- bs->dev = dev;
- bdrv_iostatus_reset(bs);
- return 0;
-}
-
-/* TODO qdevified devices don't use this, remove when devices are qdevified */
-void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
-{
- if (bdrv_attach_dev(bs, dev) < 0) {
- abort();
- }
-}
-
-void bdrv_detach_dev(BlockDriverState *bs, void *dev)
-/* TODO change to DeviceState *dev when all users are qdevified */
-{
- assert(bs->dev == dev);
- bs->dev = NULL;
- bs->dev_ops = NULL;
- bs->dev_opaque = NULL;
- bs->buffer_alignment = 512;
-}
-
-/* TODO change to return DeviceState * when all users are qdevified */
-void *bdrv_get_attached_dev(BlockDriverState *bs)
-{
- return bs->dev;
-}
-
-void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
- void *opaque)
-{
- bs->dev_ops = ops;
- bs->dev_opaque = opaque;
-}
-
-void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
- enum MonitorEvent ev,
- BlockErrorAction action, bool is_read)
-{
- QObject *data;
- const char *action_str;
-
- switch (action) {
- case BDRV_ACTION_REPORT:
- action_str = "report";
- break;
- case BDRV_ACTION_IGNORE:
- action_str = "ignore";
- break;
- case BDRV_ACTION_STOP:
- action_str = "stop";
- break;
- default:
- abort();
- }
-
- data = qobject_from_jsonf("{ 'device': %s, 'action': %s, 'operation': %s }",
- bdrv->device_name,
- action_str,
- is_read ? "read" : "write");
- monitor_protocol_event(ev, data);
-
- qobject_decref(data);
-}
-
-static void bdrv_emit_qmp_eject_event(BlockDriverState *bs, bool ejected)
-{
- QObject *data;
-
- data = qobject_from_jsonf("{ 'device': %s, 'tray-open': %i }",
- bdrv_get_device_name(bs), ejected);
- monitor_protocol_event(QEVENT_DEVICE_TRAY_MOVED, data);
-
- qobject_decref(data);
-}
-
-static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
-{
- if (bs->dev_ops && bs->dev_ops->change_media_cb) {
- bool tray_was_closed = !bdrv_dev_is_tray_open(bs);
- bs->dev_ops->change_media_cb(bs->dev_opaque, load);
- if (tray_was_closed) {
- /* tray open */
- bdrv_emit_qmp_eject_event(bs, true);
- }
- if (load) {
- /* tray close */
- bdrv_emit_qmp_eject_event(bs, false);
- }
- }
-}
-
-bool bdrv_dev_has_removable_media(BlockDriverState *bs)
-{
- return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
-}
-
-void bdrv_dev_eject_request(BlockDriverState *bs, bool force)
-{
- if (bs->dev_ops && bs->dev_ops->eject_request_cb) {
- bs->dev_ops->eject_request_cb(bs->dev_opaque, force);
- }
-}
-
-bool bdrv_dev_is_tray_open(BlockDriverState *bs)
-{
- if (bs->dev_ops && bs->dev_ops->is_tray_open) {
- return bs->dev_ops->is_tray_open(bs->dev_opaque);
- }
- return false;
-}
-
-static void bdrv_dev_resize_cb(BlockDriverState *bs)
-{
- if (bs->dev_ops && bs->dev_ops->resize_cb) {
- bs->dev_ops->resize_cb(bs->dev_opaque);
- }
-}
-
-bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
-{
- if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
- return bs->dev_ops->is_medium_locked(bs->dev_opaque);
- }
- return false;
-}
-
-/*
- * Run consistency checks on an image
- *
- * Returns 0 if the check could be completed (it doesn't mean that the image is
- * free of errors) or -errno when an internal error occurred. The results of the
- * check are stored in res.
- */
-int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
-{
- if (bs->drv->bdrv_check == NULL) {
- return -ENOTSUP;
- }
-
- memset(res, 0, sizeof(*res));
- return bs->drv->bdrv_check(bs, res, fix);
-}
-
-#define COMMIT_BUF_SECTORS 2048
-
-/* commit COW file into the raw image */
-int bdrv_commit(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- int64_t sector, total_sectors;
- int n, ro, open_flags;
- int ret = 0;
- uint8_t *buf;
- char filename[PATH_MAX];
-
- if (!drv)
- return -ENOMEDIUM;
-
- if (!bs->backing_hd) {
- return -ENOTSUP;
- }
-
- if (bdrv_in_use(bs) || bdrv_in_use(bs->backing_hd)) {
- return -EBUSY;
- }
-
- ro = bs->backing_hd->read_only;
- /* Use pstrcpy (not strncpy): filename must be NUL-terminated. */
- pstrcpy(filename, sizeof(filename), bs->backing_hd->filename);
- open_flags = bs->backing_hd->open_flags;
-
- if (ro) {
- if (bdrv_reopen(bs->backing_hd, open_flags | BDRV_O_RDWR, NULL)) {
- return -EACCES;
- }
- }
-
- total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
- buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
-
- for (sector = 0; sector < total_sectors; sector += n) {
- if (bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
-
- if (bdrv_read(bs, sector, buf, n) != 0) {
- ret = -EIO;
- goto ro_cleanup;
- }
-
- if (bdrv_write(bs->backing_hd, sector, buf, n) != 0) {
- ret = -EIO;
- goto ro_cleanup;
- }
- }
- }
-
- if (drv->bdrv_make_empty) {
- ret = drv->bdrv_make_empty(bs);
- bdrv_flush(bs);
- }
-
- /*
- * Make sure all data we wrote to the backing device is actually
- * stable on disk.
- */
- if (bs->backing_hd)
- bdrv_flush(bs->backing_hd);
-
-ro_cleanup:
- g_free(buf);
-
- if (ro) {
- /* ignoring error return here */
- bdrv_reopen(bs->backing_hd, open_flags & ~BDRV_O_RDWR, NULL);
- }
-
- return ret;
-}
-
-int bdrv_commit_all(void)
-{
- BlockDriverState *bs;
-
- QTAILQ_FOREACH(bs, &bdrv_states, list) {
- if (bs->drv && bs->backing_hd) {
- int ret = bdrv_commit(bs);
- if (ret < 0) {
- return ret;
- }
- }
- }
- return 0;
-}
-
-/**
- * Remove an active request from the tracked requests list
- *
- * This function should be called when a tracked request is completing.
- */
-static void tracked_request_end(BdrvTrackedRequest *req)
-{
- QLIST_REMOVE(req, list);
- qemu_co_queue_restart_all(&req->wait_queue);
-}
-
-/**
- * Add an active request to the tracked requests list
- */
-static void tracked_request_begin(BdrvTrackedRequest *req,
- BlockDriverState *bs,
- int64_t sector_num,
- int nb_sectors, bool is_write)
-{
- *req = (BdrvTrackedRequest){
- .bs = bs,
- .sector_num = sector_num,
- .nb_sectors = nb_sectors,
- .is_write = is_write,
- .co = qemu_coroutine_self(),
- };
-
- qemu_co_queue_init(&req->wait_queue);
-
- QLIST_INSERT_HEAD(&bs->tracked_requests, req, list);
-}
-
-/**
- * Round a region to cluster boundaries
- */
-void bdrv_round_to_clusters(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- int64_t *cluster_sector_num,
- int *cluster_nb_sectors)
-{
- BlockDriverInfo bdi;
-
- if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
- *cluster_sector_num = sector_num;
- *cluster_nb_sectors = nb_sectors;
- } else {
- int64_t c = bdi.cluster_size / BDRV_SECTOR_SIZE;
- *cluster_sector_num = QEMU_ALIGN_DOWN(sector_num, c);
- *cluster_nb_sectors = QEMU_ALIGN_UP(sector_num - *cluster_sector_num +
- nb_sectors, c);
- }
-}
-
-static bool tracked_request_overlaps(BdrvTrackedRequest *req,
- int64_t sector_num, int nb_sectors) {
- /* aaaa bbbb */
- if (sector_num >= req->sector_num + req->nb_sectors) {
- return false;
- }
- /* bbbb aaaa */
- if (req->sector_num >= sector_num + nb_sectors) {
- return false;
- }
- return true;
-}
-
-static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors)
-{
- BdrvTrackedRequest *req;
- int64_t cluster_sector_num;
- int cluster_nb_sectors;
- bool retry;
-
- /* If we touch the same cluster it counts as an overlap. This guarantees
- * that allocating writes will be serialized and not race with each other
- * for the same cluster. For example, in copy-on-read it ensures that the
- * CoR read and write operations are atomic and guest writes cannot
- * interleave between them.
- */
- bdrv_round_to_clusters(bs, sector_num, nb_sectors,
- &cluster_sector_num, &cluster_nb_sectors);
-
- do {
- retry = false;
- QLIST_FOREACH(req, &bs->tracked_requests, list) {
- if (tracked_request_overlaps(req, cluster_sector_num,
- cluster_nb_sectors)) {
- /* Hitting this means there was a reentrant request, for
- * example, a block driver issuing nested requests. This must
- * never happen since it means deadlock.
- */
- assert(qemu_coroutine_self() != req->co);
-
- qemu_co_queue_wait(&req->wait_queue);
- retry = true;
- break;
- }
- }
- } while (retry);
-}
-
-/*
- * Return values:
- * 0 - success
- * -EINVAL - backing format specified, but no file
- * -ENOSPC - can't update the backing file because no space is left in the
- * image file header
- * -ENOTSUP - format driver doesn't support changing the backing file
- */
-int bdrv_change_backing_file(BlockDriverState *bs,
- const char *backing_file, const char *backing_fmt)
-{
- BlockDriver *drv = bs->drv;
- int ret;
-
- /* Backing file format doesn't make sense without a backing file */
- if (backing_fmt && !backing_file) {
- return -EINVAL;
- }
-
- if (drv->bdrv_change_backing_file != NULL) {
- ret = drv->bdrv_change_backing_file(bs, backing_file, backing_fmt);
- } else {
- ret = -ENOTSUP;
- }
-
- if (ret == 0) {
- pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_file ?: "");
- pstrcpy(bs->backing_format, sizeof(bs->backing_format), backing_fmt ?: "");
- }
- return ret;
-}
-
-/*
- * Finds the image layer in the chain that has 'bs' as its backing file.
- *
- * active is the current topmost image.
- *
- * Returns NULL if bs is not found in active's image chain,
- * or if active == bs.
- */
-BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
- BlockDriverState *bs)
-{
- BlockDriverState *overlay = NULL;
- BlockDriverState *intermediate;
-
- assert(active != NULL);
- assert(bs != NULL);
-
- /* if bs is the same as active, then by definition it has no overlay
- */
- if (active == bs) {
- return NULL;
- }
-
- intermediate = active;
- while (intermediate->backing_hd) {
- if (intermediate->backing_hd == bs) {
- overlay = intermediate;
- break;
- }
- intermediate = intermediate->backing_hd;
- }
-
- return overlay;
-}
-
-typedef struct BlkIntermediateStates {
- BlockDriverState *bs;
- QSIMPLEQ_ENTRY(BlkIntermediateStates) entry;
-} BlkIntermediateStates;
-
-
-/*
- * Drops images above 'base' up to and including 'top', and sets the image
- * above 'top' to have base as its backing file.
- *
- * Requires that the overlay to 'top' is opened r/w, so that the backing file
- * information in 'bs' can be properly updated.
- *
- * E.g., this will convert the following chain:
- * bottom <- base <- intermediate <- top <- active
- *
- * to
- *
- * bottom <- base <- active
- *
- * It is allowed for bottom==base, in which case it converts:
- *
- * base <- intermediate <- top <- active
- *
- * to
- *
- * base <- active
- *
- * Error conditions:
- * if active == top, that is considered an error
- *
- */
-int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
- BlockDriverState *base)
-{
- BlockDriverState *intermediate;
- BlockDriverState *base_bs = NULL;
- BlockDriverState *new_top_bs = NULL;
- BlkIntermediateStates *intermediate_state, *next;
- int ret = -EIO;
-
- QSIMPLEQ_HEAD(states_to_delete, BlkIntermediateStates) states_to_delete;
- QSIMPLEQ_INIT(&states_to_delete);
-
- if (!top->drv || !base->drv) {
- goto exit;
- }
-
- new_top_bs = bdrv_find_overlay(active, top);
-
- if (new_top_bs == NULL) {
- /* we could not find the image above 'top', this is an error */
- goto exit;
- }
-
- /* special case of new_top_bs->backing_hd already pointing to base - nothing
- * to do, no intermediate images */
- if (new_top_bs->backing_hd == base) {
- ret = 0;
- goto exit;
- }
-
- intermediate = top;
-
- /* now we will go down through the list, and add each BDS we find
- * into our deletion queue, until we hit the 'base'
- */
- while (intermediate) {
- intermediate_state = g_malloc0(sizeof(BlkIntermediateStates));
- intermediate_state->bs = intermediate;
- QSIMPLEQ_INSERT_TAIL(&states_to_delete, intermediate_state, entry);
-
- if (intermediate->backing_hd == base) {
- base_bs = intermediate->backing_hd;
- break;
- }
- intermediate = intermediate->backing_hd;
- }
- if (base_bs == NULL) {
- /* something went wrong, we did not end at the base. safely
- * unravel everything, and exit with error */
- goto exit;
- }
-
- /* success - we can delete the intermediate states, and link top->base */
- ret = bdrv_change_backing_file(new_top_bs, base_bs->filename,
- base_bs->drv ? base_bs->drv->format_name : "");
- if (ret) {
- goto exit;
- }
- new_top_bs->backing_hd = base_bs;
-
-
- QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, next) {
- /* so that bdrv_close() does not recursively close the chain */
- intermediate_state->bs->backing_hd = NULL;
- bdrv_delete(intermediate_state->bs);
- }
- ret = 0;
-
-exit:
- QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, next) {
- g_free(intermediate_state);
- }
- return ret;
-}
-
-
-static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
- size_t size)
-{
- int64_t len;
-
- if (!bdrv_is_inserted(bs))
- return -ENOMEDIUM;
-
- if (bs->growable)
- return 0;
-
- len = bdrv_getlength(bs);
-
- if (offset < 0)
- return -EIO;
-
- if ((offset > len) || (len - offset < size))
- return -EIO;
-
- return 0;
-}
-
-static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors)
-{
- return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE,
- nb_sectors * BDRV_SECTOR_SIZE);
-}
-
-typedef struct RwCo {
- BlockDriverState *bs;
- int64_t sector_num;
- int nb_sectors;
- QEMUIOVector *qiov;
- bool is_write;
- int ret;
-} RwCo;
-
-static void coroutine_fn bdrv_rw_co_entry(void *opaque)
-{
- RwCo *rwco = opaque;
-
- if (!rwco->is_write) {
- rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
- rwco->nb_sectors, rwco->qiov, 0);
- } else {
- rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
- rwco->nb_sectors, rwco->qiov, 0);
- }
-}
-
-/*
- * Process a vectored synchronous request using coroutines
- */
-static int bdrv_rwv_co(BlockDriverState *bs, int64_t sector_num,
- QEMUIOVector *qiov, bool is_write)
-{
- Coroutine *co;
- RwCo rwco = {
- .bs = bs,
- .sector_num = sector_num,
- .nb_sectors = qiov->size >> BDRV_SECTOR_BITS,
- .qiov = qiov,
- .is_write = is_write,
- .ret = NOT_DONE,
- };
- assert((qiov->size & (BDRV_SECTOR_SIZE - 1)) == 0);
-
- /**
- * In sync call context, when the vcpu is blocked, this throttling timer
- * will not fire; so the I/O throttling function has to be disabled here
- * if it has been enabled.
- */
- if (bs->io_limits_enabled) {
- fprintf(stderr, "Disabling I/O throttling on '%s' due "
- "to synchronous I/O.\n", bdrv_get_device_name(bs));
- bdrv_io_limits_disable(bs);
- }
-
- if (qemu_in_coroutine()) {
- /* Fast-path if already in coroutine context */
- bdrv_rw_co_entry(&rwco);
- } else {
- co = qemu_coroutine_create(bdrv_rw_co_entry);
- qemu_coroutine_enter(co, &rwco);
- while (rwco.ret == NOT_DONE) {
- qemu_aio_wait();
- }
- }
- return rwco.ret;
-}
-
-/*
- * Process a synchronous request using coroutines
- */
-static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
- int nb_sectors, bool is_write)
-{
- QEMUIOVector qiov;
- struct iovec iov = {
- .iov_base = (void *)buf,
- .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
- };
-
- qemu_iovec_init_external(&qiov, &iov, 1);
- return bdrv_rwv_co(bs, sector_num, &qiov, is_write);
-}
-
-/* return < 0 if error. See bdrv_write() for the return codes */
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
-}
-
-/* Just like bdrv_read(), but with I/O throttling temporarily disabled */
-int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- bool enabled;
- int ret;
-
- enabled = bs->io_limits_enabled;
- bs->io_limits_enabled = false;
- ret = bdrv_read(bs, 0, buf, 1);
- bs->io_limits_enabled = enabled;
- return ret;
-}
-
-/* Return < 0 if error. Important errors are:
- -EIO generic I/O error (may happen for all errors)
- -ENOMEDIUM No media inserted.
- -EINVAL Invalid sector number or nb_sectors
- -EACCES Trying to write a read-only device
-*/
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
-}
-
-int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov)
-{
- return bdrv_rwv_co(bs, sector_num, qiov, true);
-}
-
-int bdrv_pread(BlockDriverState *bs, int64_t offset,
- void *buf, int count1)
-{
- uint8_t tmp_buf[BDRV_SECTOR_SIZE];
- int len, nb_sectors, count;
- int64_t sector_num;
- int ret;
-
- count = count1;
- /* first read to align to sector start */
- len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
- if (len > count)
- len = count;
- sector_num = offset >> BDRV_SECTOR_BITS;
- if (len > 0) {
- if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
- return ret;
- memcpy(buf, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), len);
- count -= len;
- if (count == 0)
- return count1;
- sector_num++;
- buf += len;
- }
-
- /* read the sectors "in place" */
- nb_sectors = count >> BDRV_SECTOR_BITS;
- if (nb_sectors > 0) {
- if ((ret = bdrv_read(bs, sector_num, buf, nb_sectors)) < 0)
- return ret;
- sector_num += nb_sectors;
- len = nb_sectors << BDRV_SECTOR_BITS;
- buf += len;
- count -= len;
- }
-
- /* add data from the last sector */
- if (count > 0) {
- if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
- return ret;
- memcpy(buf, tmp_buf, count);
- }
- return count1;
-}
-
-int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov)
-{
- uint8_t tmp_buf[BDRV_SECTOR_SIZE];
- int len, nb_sectors, count;
- int64_t sector_num;
- int ret;
-
- count = qiov->size;
-
- /* first write to align to sector start */
- len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
- if (len > count)
- len = count;
- sector_num = offset >> BDRV_SECTOR_BITS;
- if (len > 0) {
- if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
- return ret;
- qemu_iovec_to_buf(qiov, 0, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)),
- len);
- if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
- return ret;
- count -= len;
- if (count == 0)
- return qiov->size;
- sector_num++;
- }
-
- /* write the sectors "in place" */
- nb_sectors = count >> BDRV_SECTOR_BITS;
- if (nb_sectors > 0) {
- QEMUIOVector qiov_inplace;
-
- qemu_iovec_init(&qiov_inplace, qiov->niov);
- qemu_iovec_concat(&qiov_inplace, qiov, len,
- nb_sectors << BDRV_SECTOR_BITS);
- ret = bdrv_writev(bs, sector_num, &qiov_inplace);
- qemu_iovec_destroy(&qiov_inplace);
- if (ret < 0) {
- return ret;
- }
-
- sector_num += nb_sectors;
- len = nb_sectors << BDRV_SECTOR_BITS;
- count -= len;
- }
-
- /* add data from the last sector */
- if (count > 0) {
- if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
- return ret;
- qemu_iovec_to_buf(qiov, qiov->size - count, tmp_buf, count);
- if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
- return ret;
- }
- return qiov->size;
-}
-
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
- const void *buf, int count1)
-{
- QEMUIOVector qiov;
- struct iovec iov = {
- .iov_base = (void *) buf,
- .iov_len = count1,
- };
-
- qemu_iovec_init_external(&qiov, &iov, 1);
- return bdrv_pwritev(bs, offset, &qiov);
-}
-
-/*
- * Writes to the file and ensures that no writes are reordered across this
- * request (acts as a barrier)
- *
- * Returns 0 on success, -errno in error cases.
- */
-int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
- const void *buf, int count)
-{
- int ret;
-
- ret = bdrv_pwrite(bs, offset, buf, count);
- if (ret < 0) {
- return ret;
- }
-
- /* No flush needed for cache modes that already do it */
- if (bs->enable_write_cache) {
- bdrv_flush(bs);
- }
-
- return 0;
-}
-
-static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
-{
- /* Perform I/O through a temporary buffer so that users who scribble over
- * their read buffer while the operation is in progress do not end up
- * modifying the image file. This is critical for zero-copy guest I/O
- * where anything might happen inside guest memory.
- */
- void *bounce_buffer;
-
- BlockDriver *drv = bs->drv;
- struct iovec iov;
- QEMUIOVector bounce_qiov;
- int64_t cluster_sector_num;
- int cluster_nb_sectors;
- size_t skip_bytes;
- int ret;
-
- /* Cover entire cluster so no additional backing file I/O is required when
- * allocating cluster in the image file.
- */
- bdrv_round_to_clusters(bs, sector_num, nb_sectors,
- &cluster_sector_num, &cluster_nb_sectors);
-
- trace_bdrv_co_do_copy_on_readv(bs, sector_num, nb_sectors,
- cluster_sector_num, cluster_nb_sectors);
-
- iov.iov_len = cluster_nb_sectors * BDRV_SECTOR_SIZE;
- iov.iov_base = bounce_buffer = qemu_blockalign(bs, iov.iov_len);
- qemu_iovec_init_external(&bounce_qiov, &iov, 1);
-
- ret = drv->bdrv_co_readv(bs, cluster_sector_num, cluster_nb_sectors,
- &bounce_qiov);
- if (ret < 0) {
- goto err;
- }
-
- if (drv->bdrv_co_write_zeroes &&
- buffer_is_zero(bounce_buffer, iov.iov_len)) {
- ret = bdrv_co_do_write_zeroes(bs, cluster_sector_num,
- cluster_nb_sectors);
- } else {
- /* This does not change the data on the disk, it is not necessary
- * to flush even in cache=writethrough mode.
- */
- ret = drv->bdrv_co_writev(bs, cluster_sector_num, cluster_nb_sectors,
- &bounce_qiov);
- }
-
- if (ret < 0) {
- /* It might be okay to ignore write errors for guest requests. If this
- * is a deliberate copy-on-read then we don't want to ignore the error.
- * Simply report it in all cases.
- */
- goto err;
- }
-
- skip_bytes = (sector_num - cluster_sector_num) * BDRV_SECTOR_SIZE;
- qemu_iovec_from_buf(qiov, 0, bounce_buffer + skip_bytes,
- nb_sectors * BDRV_SECTOR_SIZE);
-
-err:
- qemu_vfree(bounce_buffer);
- return ret;
-}
-
-/*
- * Handle a read request in coroutine context
- */
-static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
- BdrvRequestFlags flags)
-{
- BlockDriver *drv = bs->drv;
- BdrvTrackedRequest req;
- int ret;
-
- if (!drv) {
- return -ENOMEDIUM;
- }
- if (bdrv_check_request(bs, sector_num, nb_sectors)) {
- return -EIO;
- }
-
- /* throttling disk read I/O */
- if (bs->io_limits_enabled) {
- bdrv_io_limits_intercept(bs, false, nb_sectors);
- }
-
- if (bs->copy_on_read) {
- flags |= BDRV_REQ_COPY_ON_READ;
- }
- if (flags & BDRV_REQ_COPY_ON_READ) {
- bs->copy_on_read_in_flight++;
- }
-
- if (bs->copy_on_read_in_flight) {
- wait_for_overlapping_requests(bs, sector_num, nb_sectors);
- }
-
- tracked_request_begin(&req, bs, sector_num, nb_sectors, false);
-
- if (flags & BDRV_REQ_COPY_ON_READ) {
- int pnum;
-
- ret = bdrv_co_is_allocated(bs, sector_num, nb_sectors, &pnum);
- if (ret < 0) {
- goto out;
- }
-
- if (!ret || pnum != nb_sectors) {
- ret = bdrv_co_do_copy_on_readv(bs, sector_num, nb_sectors, qiov);
- goto out;
- }
- }
-
- ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
-
-out:
- tracked_request_end(&req);
-
- if (flags & BDRV_REQ_COPY_ON_READ) {
- bs->copy_on_read_in_flight--;
- }
-
- return ret;
-}
-
-int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov)
-{
- trace_bdrv_co_readv(bs, sector_num, nb_sectors);
-
- return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov, 0);
-}
-
-int coroutine_fn bdrv_co_copy_on_readv(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
-{
- trace_bdrv_co_copy_on_readv(bs, sector_num, nb_sectors);
-
- return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov,
- BDRV_REQ_COPY_ON_READ);
-}
-
-static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors)
-{
- BlockDriver *drv = bs->drv;
- QEMUIOVector qiov;
- struct iovec iov;
- int ret;
-
- /* TODO Emulate only part of misaligned requests instead of letting block
- * drivers return -ENOTSUP and emulate everything */
-
- /* First try the efficient write zeroes operation */
- if (drv->bdrv_co_write_zeroes) {
- ret = drv->bdrv_co_write_zeroes(bs, sector_num, nb_sectors);
- if (ret != -ENOTSUP) {
- return ret;
- }
- }
-
- /* Fall back to bounce buffer if write zeroes is unsupported */
- iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
- iov.iov_base = qemu_blockalign(bs, iov.iov_len);
- memset(iov.iov_base, 0, iov.iov_len);
- qemu_iovec_init_external(&qiov, &iov, 1);
-
- ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, &qiov);
-
- qemu_vfree(iov.iov_base);
- return ret;
-}
-
-/*
- * Handle a write request in coroutine context
- */
-static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
- BdrvRequestFlags flags)
-{
- BlockDriver *drv = bs->drv;
- BdrvTrackedRequest req;
- int ret;
-
- if (!bs->drv) {
- return -ENOMEDIUM;
- }
- if (bs->read_only) {
- return -EACCES;
- }
- if (bdrv_check_request(bs, sector_num, nb_sectors)) {
- return -EIO;
- }
-
- /* throttling disk write I/O */
- if (bs->io_limits_enabled) {
- bdrv_io_limits_intercept(bs, true, nb_sectors);
- }
-
- if (bs->copy_on_read_in_flight) {
- wait_for_overlapping_requests(bs, sector_num, nb_sectors);
- }
-
- tracked_request_begin(&req, bs, sector_num, nb_sectors, true);
-
- ret = notifier_with_return_list_notify(&bs->before_write_notifiers, &req);
-
- if (ret < 0) {
- /* Do nothing, write notifier decided to fail this request */
- } else if (flags & BDRV_REQ_ZERO_WRITE) {
- ret = bdrv_co_do_write_zeroes(bs, sector_num, nb_sectors);
- } else {
- ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
- }
-
- if (ret == 0 && !bs->enable_write_cache) {
- ret = bdrv_co_flush(bs);
- }
-
- if (bs->dirty_bitmap) {
- bdrv_set_dirty(bs, sector_num, nb_sectors);
- }
-
- if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
- bs->wr_highest_sector = sector_num + nb_sectors - 1;
- }
-
- tracked_request_end(&req);
-
- return ret;
-}
-
-int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov)
-{
- trace_bdrv_co_writev(bs, sector_num, nb_sectors);
-
- return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov, 0);
-}
-
-int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors)
-{
- trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors);
-
- return bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL,
- BDRV_REQ_ZERO_WRITE);
-}
-
-/**
- * Truncate file to 'offset' bytes (needed only for file protocols)
- */
-int bdrv_truncate(BlockDriverState *bs, int64_t offset)
-{
- BlockDriver *drv = bs->drv;
- int ret;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_truncate)
- return -ENOTSUP;
- if (bs->read_only)
- return -EACCES;
- if (bdrv_in_use(bs))
- return -EBUSY;
- ret = drv->bdrv_truncate(bs, offset);
- if (ret == 0) {
- ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
- bdrv_dev_resize_cb(bs);
- }
- return ret;
-}
-
-/**
- * Length of a allocated file in bytes. Sparse files are counted by actual
- * allocated space. Return < 0 if error or unknown.
- */
-int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- if (!drv) {
- return -ENOMEDIUM;
- }
- if (drv->bdrv_get_allocated_file_size) {
- return drv->bdrv_get_allocated_file_size(bs);
- }
- if (bs->file) {
- return bdrv_get_allocated_file_size(bs->file);
- }
- return -ENOTSUP;
-}
-
-/**
- * Length of a file in bytes. Return < 0 if error or unknown.
- */
-int64_t bdrv_getlength(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
-
- if (bs->growable || bdrv_dev_has_removable_media(bs)) {
- if (drv->bdrv_getlength) {
- return drv->bdrv_getlength(bs);
- }
- }
- return bs->total_sectors * BDRV_SECTOR_SIZE;
-}
-
-/* return 0 as number of sectors if no device present or error */
-void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
-{
- int64_t length;
- length = bdrv_getlength(bs);
- if (length < 0)
- length = 0;
- else
- length = length >> BDRV_SECTOR_BITS;
- *nb_sectors_ptr = length;
-}
-
-/* throttling disk io limits */
-void bdrv_set_io_limits(BlockDriverState *bs,
- BlockIOLimit *io_limits)
-{
- bs->io_limits = *io_limits;
- bs->io_limits_enabled = bdrv_io_limits_enabled(bs);
-}
-
-void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error,
- BlockdevOnError on_write_error)
-{
- bs->on_read_error = on_read_error;
- bs->on_write_error = on_write_error;
-}
-
-BlockdevOnError bdrv_get_on_error(BlockDriverState *bs, bool is_read)
-{
- return is_read ? bs->on_read_error : bs->on_write_error;
-}
-
-BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int error)
-{
- BlockdevOnError on_err = is_read ? bs->on_read_error : bs->on_write_error;
-
- switch (on_err) {
- case BLOCKDEV_ON_ERROR_ENOSPC:
- return (error == ENOSPC) ? BDRV_ACTION_STOP : BDRV_ACTION_REPORT;
- case BLOCKDEV_ON_ERROR_STOP:
- return BDRV_ACTION_STOP;
- case BLOCKDEV_ON_ERROR_REPORT:
- return BDRV_ACTION_REPORT;
- case BLOCKDEV_ON_ERROR_IGNORE:
- return BDRV_ACTION_IGNORE;
- default:
- abort();
- }
-}
-
-/* This is done by device models because, while the block layer knows
- * about the error, it does not know whether an operation comes from
- * the device or the block layer (from a job, for example).
- */
-void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
- bool is_read, int error)
-{
- assert(error >= 0);
- bdrv_emit_qmp_error_event(bs, QEVENT_BLOCK_IO_ERROR, action, is_read);
- if (action == BDRV_ACTION_STOP) {
- vm_stop(RUN_STATE_IO_ERROR);
- bdrv_iostatus_set_err(bs, error);
- }
-}
-
-int bdrv_is_read_only(BlockDriverState *bs)
-{
- return bs->read_only;
-}
-
-int bdrv_is_sg(BlockDriverState *bs)
-{
- return bs->sg;
-}
-
-int bdrv_enable_write_cache(BlockDriverState *bs)
-{
- return bs->enable_write_cache;
-}
-
-void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce)
-{
- bs->enable_write_cache = wce;
-
- /* so a reopen() will preserve wce */
- if (wce) {
- bs->open_flags |= BDRV_O_CACHE_WB;
- } else {
- bs->open_flags &= ~BDRV_O_CACHE_WB;
- }
-}
-
-int bdrv_is_encrypted(BlockDriverState *bs)
-{
- if (bs->backing_hd && bs->backing_hd->encrypted)
- return 1;
- return bs->encrypted;
-}
-
-int bdrv_key_required(BlockDriverState *bs)
-{
- BlockDriverState *backing_hd = bs->backing_hd;
-
- if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
- return 1;
- return (bs->encrypted && !bs->valid_key);
-}
-
-int bdrv_set_key(BlockDriverState *bs, const char *key)
-{
- int ret;
- if (bs->backing_hd && bs->backing_hd->encrypted) {
- ret = bdrv_set_key(bs->backing_hd, key);
- if (ret < 0)
- return ret;
- if (!bs->encrypted)
- return 0;
- }
- if (!bs->encrypted) {
- return -EINVAL;
- } else if (!bs->drv || !bs->drv->bdrv_set_key) {
- return -ENOMEDIUM;
- }
- ret = bs->drv->bdrv_set_key(bs, key);
- if (ret < 0) {
- bs->valid_key = 0;
- } else if (!bs->valid_key) {
- bs->valid_key = 1;
- /* call the change callback now, we skipped it on open */
- bdrv_dev_change_media_cb(bs, true);
- }
- return ret;
-}
-
-const char *bdrv_get_format_name(BlockDriverState *bs)
-{
- return bs->drv ? bs->drv->format_name : NULL;
-}
-
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
- void *opaque)
-{
- BlockDriver *drv;
-
- QLIST_FOREACH(drv, &bdrv_drivers, list) {
- it(opaque, drv->format_name);
- }
-}
-
-BlockDriverState *bdrv_find(const char *name)
-{
- BlockDriverState *bs;
-
- QTAILQ_FOREACH(bs, &bdrv_states, list) {
- if (!strcmp(name, bs->device_name)) {
- return bs;
- }
- }
- return NULL;
-}
-
-BlockDriverState *bdrv_next(BlockDriverState *bs)
-{
- if (!bs) {
- return QTAILQ_FIRST(&bdrv_states);
- }
- return QTAILQ_NEXT(bs, list);
-}
-
-void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
-{
- BlockDriverState *bs;
-
- QTAILQ_FOREACH(bs, &bdrv_states, list) {
- it(opaque, bs);
- }
-}
-
-const char *bdrv_get_device_name(BlockDriverState *bs)
-{
- return bs->device_name;
-}
-
-int bdrv_get_flags(BlockDriverState *bs)
-{
- return bs->open_flags;
-}
-
-int bdrv_flush_all(void)
-{
- BlockDriverState *bs;
- int result = 0;
-
- QTAILQ_FOREACH(bs, &bdrv_states, list) {
- int ret = bdrv_flush(bs);
- if (ret < 0 && !result) {
- result = ret;
- }
- }
-
- return result;
-}
-
-int bdrv_has_zero_init_1(BlockDriverState *bs)
-{
- return 1;
-}
-
-int bdrv_has_zero_init(BlockDriverState *bs)
-{
- assert(bs->drv);
-
- if (bs->drv->bdrv_has_zero_init) {
- return bs->drv->bdrv_has_zero_init(bs);
- }
-
- /* safe default */
- return 0;
-}
-
-typedef struct BdrvCoIsAllocatedData {
- BlockDriverState *bs;
- BlockDriverState *base;
- int64_t sector_num;
- int nb_sectors;
- int *pnum;
- int ret;
- bool done;
-} BdrvCoIsAllocatedData;
-
-/*
- * Returns true iff the specified sector is present in the disk image. Drivers
- * not implementing the functionality are assumed to not support backing files,
- * hence all their sectors are reported as allocated.
- *
- * If 'sector_num' is beyond the end of the disk image the return value is 0
- * and 'pnum' is set to 0.
- *
- * 'pnum' is set to the number of sectors (including and immediately following
- * the specified sector) that are known to be in the same
- * allocated/unallocated state.
- *
- * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
- * beyond the end of the disk image it will be clamped.
- */
-int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- int64_t n;
-
- if (sector_num >= bs->total_sectors) {
- *pnum = 0;
- return 0;
- }
-
- n = bs->total_sectors - sector_num;
- if (n < nb_sectors) {
- nb_sectors = n;
- }
-
- if (!bs->drv->bdrv_co_is_allocated) {
- *pnum = nb_sectors;
- return 1;
- }
-
- return bs->drv->bdrv_co_is_allocated(bs, sector_num, nb_sectors, pnum);
-}
-
-/* Coroutine wrapper for bdrv_is_allocated() */
-static void coroutine_fn bdrv_is_allocated_co_entry(void *opaque)
-{
- BdrvCoIsAllocatedData *data = opaque;
- BlockDriverState *bs = data->bs;
-
- data->ret = bdrv_co_is_allocated(bs, data->sector_num, data->nb_sectors,
- data->pnum);
- data->done = true;
-}
-
-/*
- * Synchronous wrapper around bdrv_co_is_allocated().
- *
- * See bdrv_co_is_allocated() for details.
- */
-int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
- int *pnum)
-{
- Coroutine *co;
- BdrvCoIsAllocatedData data = {
- .bs = bs,
- .sector_num = sector_num,
- .nb_sectors = nb_sectors,
- .pnum = pnum,
- .done = false,
- };
-
- co = qemu_coroutine_create(bdrv_is_allocated_co_entry);
- qemu_coroutine_enter(co, &data);
- while (!data.done) {
- qemu_aio_wait();
- }
- return data.ret;
-}
-
-/*
- * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
- *
- * Return true if the given sector is allocated in any image between
- * BASE and TOP (inclusive). BASE can be NULL to check if the given
- * sector is allocated in any image of the chain. Return false otherwise.
- *
- * 'pnum' is set to the number of sectors (including and immediately following
- * the specified sector) that are known to be in the same
- * allocated/unallocated state.
- *
- */
-int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
- BlockDriverState *base,
- int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BlockDriverState *intermediate;
- int ret, n = nb_sectors;
-
- intermediate = top;
- while (intermediate && intermediate != base) {
- int pnum_inter;
- ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors,
- &pnum_inter);
- if (ret < 0) {
- return ret;
- } else if (ret) {
- *pnum = pnum_inter;
- return 1;
- }
-
- /*
- * [sector_num, nb_sectors] is unallocated on top but intermediate
- * might have
- *
- * [sector_num+x, nr_sectors] allocated.
- */
- if (n > pnum_inter &&
- (intermediate == top ||
- sector_num + pnum_inter < intermediate->total_sectors)) {
- n = pnum_inter;
- }
-
- intermediate = intermediate->backing_hd;
- }
-
- *pnum = n;
- return 0;
-}
-
-/* Coroutine wrapper for bdrv_is_allocated_above() */
-static void coroutine_fn bdrv_is_allocated_above_co_entry(void *opaque)
-{
- BdrvCoIsAllocatedData *data = opaque;
- BlockDriverState *top = data->bs;
- BlockDriverState *base = data->base;
-
- data->ret = bdrv_co_is_allocated_above(top, base, data->sector_num,
- data->nb_sectors, data->pnum);
- data->done = true;
-}
-
-/*
- * Synchronous wrapper around bdrv_co_is_allocated_above().
- *
- * See bdrv_co_is_allocated_above() for details.
- */
-int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
- int64_t sector_num, int nb_sectors, int *pnum)
-{
- Coroutine *co;
- BdrvCoIsAllocatedData data = {
- .bs = top,
- .base = base,
- .sector_num = sector_num,
- .nb_sectors = nb_sectors,
- .pnum = pnum,
- .done = false,
- };
-
- co = qemu_coroutine_create(bdrv_is_allocated_above_co_entry);
- qemu_coroutine_enter(co, &data);
- while (!data.done) {
- qemu_aio_wait();
- }
- return data.ret;
-}
-
-const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
-{
- if (bs->backing_hd && bs->backing_hd->encrypted)
- return bs->backing_file;
- else if (bs->encrypted)
- return bs->filename;
- else
- return NULL;
-}
-
-void bdrv_get_backing_filename(BlockDriverState *bs,
- char *filename, int filename_size)
-{
- pstrcpy(filename, filename_size, bs->backing_file);
-}
-
-int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_write_compressed)
- return -ENOTSUP;
- if (bdrv_check_request(bs, sector_num, nb_sectors))
- return -EIO;
-
- assert(!bs->dirty_bitmap);
-
- return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
-}
-
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (!drv->bdrv_get_info)
- return -ENOTSUP;
- memset(bdi, 0, sizeof(*bdi));
- return drv->bdrv_get_info(bs, bdi);
-}
-
-int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
- int64_t pos, int size)
-{
- QEMUIOVector qiov;
- struct iovec iov = {
- .iov_base = (void *) buf,
- .iov_len = size,
- };
-
- qemu_iovec_init_external(&qiov, &iov, 1);
- return bdrv_writev_vmstate(bs, &qiov, pos);
-}
-
-int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv) {
- return -ENOMEDIUM;
- } else if (drv->bdrv_save_vmstate) {
- return drv->bdrv_save_vmstate(bs, qiov, pos);
- } else if (bs->file) {
- return bdrv_writev_vmstate(bs->file, qiov, pos);
- }
-
- return -ENOTSUP;
-}
-
-int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
- int64_t pos, int size)
-{
- BlockDriver *drv = bs->drv;
- if (!drv)
- return -ENOMEDIUM;
- if (drv->bdrv_load_vmstate)
- return drv->bdrv_load_vmstate(bs, buf, pos, size);
- if (bs->file)
- return bdrv_load_vmstate(bs->file, buf, pos, size);
- return -ENOTSUP;
-}
-
-void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event)
-{
- if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) {
- return;
- }
-
- bs->drv->bdrv_debug_event(bs, event);
-}
-
-int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
- const char *tag)
-{
- while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) {
- bs = bs->file;
- }
-
- if (bs && bs->drv && bs->drv->bdrv_debug_breakpoint) {
- return bs->drv->bdrv_debug_breakpoint(bs, event, tag);
- }
-
- return -ENOTSUP;
-}
-
-int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
-{
- while (bs && bs->drv && !bs->drv->bdrv_debug_resume) {
- bs = bs->file;
- }
-
- if (bs && bs->drv && bs->drv->bdrv_debug_resume) {
- return bs->drv->bdrv_debug_resume(bs, tag);
- }
-
- return -ENOTSUP;
-}
-
-bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)
-{
- while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) {
- bs = bs->file;
- }
-
- if (bs && bs->drv && bs->drv->bdrv_debug_is_suspended) {
- return bs->drv->bdrv_debug_is_suspended(bs, tag);
- }
-
- return false;
-}
-
-int bdrv_is_snapshot(BlockDriverState *bs)
-{
- return !!(bs->open_flags & BDRV_O_SNAPSHOT);
-}
-
-/* backing_file can either be relative, or absolute, or a protocol. If it is
- * relative, it must be relative to the chain. So, passing in bs->filename
- * from a BDS as backing_file should not be done, as that may be relative to
- * the CWD rather than the chain. */
-BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
- const char *backing_file)
-{
- char *filename_full = NULL;
- char *backing_file_full = NULL;
- char *filename_tmp = NULL;
- int is_protocol = 0;
- BlockDriverState *curr_bs = NULL;
- BlockDriverState *retval = NULL;
-
- if (!bs || !bs->drv || !backing_file) {
- return NULL;
- }
-
- filename_full = g_malloc(PATH_MAX);
- backing_file_full = g_malloc(PATH_MAX);
- filename_tmp = g_malloc(PATH_MAX);
-
- is_protocol = path_has_protocol(backing_file);
-
- for (curr_bs = bs; curr_bs->backing_hd; curr_bs = curr_bs->backing_hd) {
-
- /* If either of the filename paths is actually a protocol, then
- * compare unmodified paths; otherwise make paths relative */
- if (is_protocol || path_has_protocol(curr_bs->backing_file)) {
- if (strcmp(backing_file, curr_bs->backing_file) == 0) {
- retval = curr_bs->backing_hd;
- break;
- }
- } else {
- /* If not an absolute filename path, make it relative to the current
- * image's filename path */
- path_combine(filename_tmp, PATH_MAX, curr_bs->filename,
- backing_file);
-
- /* We are going to compare absolute pathnames */
- if (!realpath(filename_tmp, filename_full)) {
- continue;
- }
-
- /* We need to make sure the backing filename we are comparing against
- * is relative to the current image filename (or absolute) */
- path_combine(filename_tmp, PATH_MAX, curr_bs->filename,
- curr_bs->backing_file);
-
- if (!realpath(filename_tmp, backing_file_full)) {
- continue;
- }
-
- if (strcmp(backing_file_full, filename_full) == 0) {
- retval = curr_bs->backing_hd;
- break;
- }
- }
- }
-
- g_free(filename_full);
- g_free(backing_file_full);
- g_free(filename_tmp);
- return retval;
-}
-
-int bdrv_get_backing_file_depth(BlockDriverState *bs)
-{
- if (!bs->drv) {
- return 0;
- }
-
- if (!bs->backing_hd) {
- return 0;
- }
-
- return 1 + bdrv_get_backing_file_depth(bs->backing_hd);
-}
-
-BlockDriverState *bdrv_find_base(BlockDriverState *bs)
-{
- BlockDriverState *curr_bs = NULL;
-
- if (!bs) {
- return NULL;
- }
-
- curr_bs = bs;
-
- while (curr_bs->backing_hd) {
- curr_bs = curr_bs->backing_hd;
- }
- return curr_bs;
-}
-
-/**************************************************************/
-/* async I/Os */
-
-BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
-
- return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
- cb, opaque, false);
-}
-
-BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
-
- return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
- cb, opaque, true);
-}
-
-
-typedef struct MultiwriteCB {
- int error;
- int num_requests;
- int num_callbacks;
- struct {
- BlockDriverCompletionFunc *cb;
- void *opaque;
- QEMUIOVector *free_qiov;
- } callbacks[];
-} MultiwriteCB;
-
-static void multiwrite_user_cb(MultiwriteCB *mcb)
-{
- int i;
-
- for (i = 0; i < mcb->num_callbacks; i++) {
- mcb->callbacks[i].cb(mcb->callbacks[i].opaque, mcb->error);
- if (mcb->callbacks[i].free_qiov) {
- qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
- }
- g_free(mcb->callbacks[i].free_qiov);
- }
-}
-
-static void multiwrite_cb(void *opaque, int ret)
-{
- MultiwriteCB *mcb = opaque;
-
- trace_multiwrite_cb(mcb, ret);
-
- if (ret < 0 && !mcb->error) {
- mcb->error = ret;
- }
-
- mcb->num_requests--;
- if (mcb->num_requests == 0) {
- multiwrite_user_cb(mcb);
- g_free(mcb);
- }
-}
-
-static int multiwrite_req_compare(const void *a, const void *b)
-{
- const BlockRequest *req1 = a, *req2 = b;
-
- /*
- * Note that we can't simply subtract req2->sector from req1->sector
- * here as that could overflow the return value.
- */
- if (req1->sector > req2->sector) {
- return 1;
- } else if (req1->sector < req2->sector) {
- return -1;
- } else {
- return 0;
- }
-}
-
-/*
- * Takes a bunch of requests and tries to merge them. Returns the number of
- * requests that remain after merging.
- */
-static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
- int num_reqs, MultiwriteCB *mcb)
-{
- int i, outidx;
-
- // Sort requests by start sector
- qsort(reqs, num_reqs, sizeof(*reqs), &multiwrite_req_compare);
-
- // Check if adjacent requests touch the same clusters. If so, combine them,
- // filling up gaps with zero sectors.
- outidx = 0;
- for (i = 1; i < num_reqs; i++) {
- int merge = 0;
- int64_t oldreq_last = reqs[outidx].sector + reqs[outidx].nb_sectors;
-
- // Handle exactly sequential writes and overlapping writes.
- if (reqs[i].sector <= oldreq_last) {
- merge = 1;
- }
-
- if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
- merge = 0;
- }
-
- if (merge) {
- size_t size;
- QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
- qemu_iovec_init(qiov,
- reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
-
- // Add the first request to the merged one. If the requests are
- // overlapping, drop the last sectors of the first request.
- size = (reqs[i].sector - reqs[outidx].sector) << 9;
- qemu_iovec_concat(qiov, reqs[outidx].qiov, 0, size);
-
- // We should need to add any zeros between the two requests
- assert (reqs[i].sector <= oldreq_last);
-
- // Add the second request
- qemu_iovec_concat(qiov, reqs[i].qiov, 0, reqs[i].qiov->size);
-
- reqs[outidx].nb_sectors = qiov->size >> 9;
- reqs[outidx].qiov = qiov;
-
- mcb->callbacks[i].free_qiov = reqs[outidx].qiov;
- } else {
- outidx++;
- reqs[outidx].sector = reqs[i].sector;
- reqs[outidx].nb_sectors = reqs[i].nb_sectors;
- reqs[outidx].qiov = reqs[i].qiov;
- }
- }
-
- return outidx + 1;
-}
-
-/*
- * Submit multiple AIO write requests at once.
- *
- * On success, the function returns 0 and all requests in the reqs array have
- * been submitted. In error case this function returns -1, and any of the
- * requests may or may not be submitted yet. In particular, this means that the
- * callback will be called for some of the requests, for others it won't. The
- * caller must check the error field of the BlockRequest to wait for the right
- * callbacks (if error != 0, no callback will be called).
- *
- * The implementation may modify the contents of the reqs array, e.g. to merge
- * requests. However, the fields opaque and error are left unmodified as they
- * are used to signal failure for a single request to the caller.
- */
-int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
-{
- MultiwriteCB *mcb;
- int i;
-
- /* don't submit writes if we don't have a medium */
- if (bs->drv == NULL) {
- for (i = 0; i < num_reqs; i++) {
- reqs[i].error = -ENOMEDIUM;
- }
- return -1;
- }
-
- if (num_reqs == 0) {
- return 0;
- }
-
- // Create MultiwriteCB structure
- mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
- mcb->num_requests = 0;
- mcb->num_callbacks = num_reqs;
-
- for (i = 0; i < num_reqs; i++) {
- mcb->callbacks[i].cb = reqs[i].cb;
- mcb->callbacks[i].opaque = reqs[i].opaque;
- }
-
- // Check for mergable requests
- num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
-
- trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs);
-
- /* Run the aio requests. */
- mcb->num_requests = num_reqs;
- for (i = 0; i < num_reqs; i++) {
- bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
- reqs[i].nb_sectors, multiwrite_cb, mcb);
- }
-
- return 0;
-}
-
-void bdrv_aio_cancel(BlockDriverAIOCB *acb)
-{
- acb->aiocb_info->cancel(acb);
-}
-
-/* block I/O throttling */
-static bool bdrv_exceed_bps_limits(BlockDriverState *bs, int nb_sectors,
- bool is_write, double elapsed_time, uint64_t *wait)
-{
- uint64_t bps_limit = 0;
- uint64_t extension;
- double bytes_limit, bytes_base, bytes_res;
- double slice_time, wait_time;
-
- if (bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL]) {
- bps_limit = bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL];
- } else if (bs->io_limits.bps[is_write]) {
- bps_limit = bs->io_limits.bps[is_write];
- } else {
- if (wait) {
- *wait = 0;
- }
-
- return false;
- }
-
- slice_time = bs->slice_end - bs->slice_start;
- slice_time /= (NANOSECONDS_PER_SECOND);
- bytes_limit = bps_limit * slice_time;
- bytes_base = bs->slice_submitted.bytes[is_write];
- if (bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL]) {
- bytes_base += bs->slice_submitted.bytes[!is_write];
- }
-
- /* bytes_base: the bytes of data which have been read/written; and
- * it is obtained from the history statistic info.
- * bytes_res: the remaining bytes of data which need to be read/written.
- * (bytes_base + bytes_res) / bps_limit: used to calcuate
- * the total time for completing reading/writting all data.
- */
- bytes_res = (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
-
- if (bytes_base + bytes_res <= bytes_limit) {
- if (wait) {
- *wait = 0;
- }
-
- return false;
- }
-
- /* Calc approx time to dispatch */
- wait_time = (bytes_base + bytes_res) / bps_limit - elapsed_time;
-
- /* When the I/O rate at runtime exceeds the limits,
- * bs->slice_end need to be extended in order that the current statistic
- * info can be kept until the timer fire, so it is increased and tuned
- * based on the result of experiment.
- */
- extension = wait_time * NANOSECONDS_PER_SECOND;
- extension = DIV_ROUND_UP(extension, BLOCK_IO_SLICE_TIME) *
- BLOCK_IO_SLICE_TIME;
- bs->slice_end += extension;
- if (wait) {
- *wait = wait_time * NANOSECONDS_PER_SECOND;
- }
-
- return true;
-}
-
-static bool bdrv_exceed_iops_limits(BlockDriverState *bs, bool is_write,
- double elapsed_time, uint64_t *wait)
-{
- uint64_t iops_limit = 0;
- double ios_limit, ios_base;
- double slice_time, wait_time;
-
- if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) {
- iops_limit = bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL];
- } else if (bs->io_limits.iops[is_write]) {
- iops_limit = bs->io_limits.iops[is_write];
- } else {
- if (wait) {
- *wait = 0;
- }
-
- return false;
- }
-
- slice_time = bs->slice_end - bs->slice_start;
- slice_time /= (NANOSECONDS_PER_SECOND);
- ios_limit = iops_limit * slice_time;
- ios_base = bs->slice_submitted.ios[is_write];
- if (bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]) {
- ios_base += bs->slice_submitted.ios[!is_write];
- }
-
- if (ios_base + 1 <= ios_limit) {
- if (wait) {
- *wait = 0;
- }
-
- return false;
- }
-
- /* Calc approx time to dispatch, in seconds */
- wait_time = (ios_base + 1) / iops_limit;
- if (wait_time > elapsed_time) {
- wait_time = wait_time - elapsed_time;
- } else {
- wait_time = 0;
- }
-
- /* Exceeded current slice, extend it by another slice time */
- bs->slice_end += BLOCK_IO_SLICE_TIME;
- if (wait) {
- *wait = wait_time * NANOSECONDS_PER_SECOND;
- }
-
- return true;
-}
-
-static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors,
- bool is_write, int64_t *wait)
-{
- int64_t now, max_wait;
- uint64_t bps_wait = 0, iops_wait = 0;
- double elapsed_time;
- int bps_ret, iops_ret;
-
- now = qemu_get_clock_ns(vm_clock);
- if (now > bs->slice_end) {
- bs->slice_start = now;
- bs->slice_end = now + BLOCK_IO_SLICE_TIME;
- memset(&bs->slice_submitted, 0, sizeof(bs->slice_submitted));
- }
-
- elapsed_time = now - bs->slice_start;
- elapsed_time /= (NANOSECONDS_PER_SECOND);
-
- bps_ret = bdrv_exceed_bps_limits(bs, nb_sectors,
- is_write, elapsed_time, &bps_wait);
- iops_ret = bdrv_exceed_iops_limits(bs, is_write,
- elapsed_time, &iops_wait);
- if (bps_ret || iops_ret) {
- max_wait = bps_wait > iops_wait ? bps_wait : iops_wait;
- if (wait) {
- *wait = max_wait;
- }
-
- now = qemu_get_clock_ns(vm_clock);
- if (bs->slice_end < now + max_wait) {
- bs->slice_end = now + max_wait;
- }
-
- return true;
- }
-
- if (wait) {
- *wait = 0;
- }
-
- bs->slice_submitted.bytes[is_write] += (int64_t)nb_sectors *
- BDRV_SECTOR_SIZE;
- bs->slice_submitted.ios[is_write]++;
-
- return false;
-}
-
-/**************************************************************/
-/* async block device emulation */
-
-typedef struct BlockDriverAIOCBSync {
- BlockDriverAIOCB common;
- QEMUBH *bh;
- int ret;
- /* vector translation state */
- QEMUIOVector *qiov;
- uint8_t *bounce;
- int is_write;
-} BlockDriverAIOCBSync;
-
-static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
-{
- BlockDriverAIOCBSync *acb =
- container_of(blockacb, BlockDriverAIOCBSync, common);
- qemu_bh_delete(acb->bh);
- acb->bh = NULL;
- qemu_aio_release(acb);
-}
-
-static const AIOCBInfo bdrv_em_aiocb_info = {
- .aiocb_size = sizeof(BlockDriverAIOCBSync),
- .cancel = bdrv_aio_cancel_em,
-};
-
-static void bdrv_aio_bh_cb(void *opaque)
-{
- BlockDriverAIOCBSync *acb = opaque;
-
- if (!acb->is_write)
- qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
- qemu_vfree(acb->bounce);
- acb->common.cb(acb->common.opaque, acb->ret);
- qemu_bh_delete(acb->bh);
- acb->bh = NULL;
- qemu_aio_release(acb);
-}
-
-static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov,
- int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque,
- int is_write)
-
-{
- BlockDriverAIOCBSync *acb;
-
- acb = qemu_aio_get(&bdrv_em_aiocb_info, bs, cb, opaque);
- acb->is_write = is_write;
- acb->qiov = qiov;
- acb->bounce = qemu_blockalign(bs, qiov->size);
- acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
-
- if (is_write) {
- qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
- acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
- } else {
- acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
- }
-
- qemu_bh_schedule(acb->bh);
-
- return &acb->common;
-}
-
-static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
-}
-
-static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
-}
-
-
-typedef struct BlockDriverAIOCBCoroutine {
- BlockDriverAIOCB common;
- BlockRequest req;
- bool is_write;
- bool *done;
- QEMUBH* bh;
-} BlockDriverAIOCBCoroutine;
-
-static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
-{
- BlockDriverAIOCBCoroutine *acb =
- container_of(blockacb, BlockDriverAIOCBCoroutine, common);
- bool done = false;
-
- acb->done = &done;
- while (!done) {
- qemu_aio_wait();
- }
-}
-
-static const AIOCBInfo bdrv_em_co_aiocb_info = {
- .aiocb_size = sizeof(BlockDriverAIOCBCoroutine),
- .cancel = bdrv_aio_co_cancel_em,
-};
-
-static void bdrv_co_em_bh(void *opaque)
-{
- BlockDriverAIOCBCoroutine *acb = opaque;
-
- acb->common.cb(acb->common.opaque, acb->req.error);
-
- if (acb->done) {
- *acb->done = true;
- }
-
- qemu_bh_delete(acb->bh);
- qemu_aio_release(acb);
-}
-
-/* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
-static void coroutine_fn bdrv_co_do_rw(void *opaque)
-{
- BlockDriverAIOCBCoroutine *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
-
- if (!acb->is_write) {
- acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
- acb->req.nb_sectors, acb->req.qiov, 0);
- } else {
- acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
- acb->req.nb_sectors, acb->req.qiov, 0);
- }
-
- acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
- qemu_bh_schedule(acb->bh);
-}
-
-static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov,
- int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque,
- bool is_write)
-{
- Coroutine *co;
- BlockDriverAIOCBCoroutine *acb;
-
- acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
- acb->req.sector = sector_num;
- acb->req.nb_sectors = nb_sectors;
- acb->req.qiov = qiov;
- acb->is_write = is_write;
- acb->done = NULL;
-
- co = qemu_coroutine_create(bdrv_co_do_rw);
- qemu_coroutine_enter(co, acb);
-
- return &acb->common;
-}
-
-static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
-{
- BlockDriverAIOCBCoroutine *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
-
- acb->req.error = bdrv_co_flush(bs);
- acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
- qemu_bh_schedule(acb->bh);
-}
-
-BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- trace_bdrv_aio_flush(bs, opaque);
-
- Coroutine *co;
- BlockDriverAIOCBCoroutine *acb;
-
- acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
- acb->done = NULL;
-
- co = qemu_coroutine_create(bdrv_aio_flush_co_entry);
- qemu_coroutine_enter(co, acb);
-
- return &acb->common;
-}
-
-static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
-{
- BlockDriverAIOCBCoroutine *acb = opaque;
- BlockDriverState *bs = acb->common.bs;
-
- acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
- acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
- qemu_bh_schedule(acb->bh);
-}
-
-BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- Coroutine *co;
- BlockDriverAIOCBCoroutine *acb;
-
- trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
-
- acb = qemu_aio_get(&bdrv_em_co_aiocb_info, bs, cb, opaque);
- acb->req.sector = sector_num;
- acb->req.nb_sectors = nb_sectors;
- acb->done = NULL;
- co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
- qemu_coroutine_enter(co, acb);
-
- return &acb->common;
-}
-
-void bdrv_init(void)
-{
- module_call_init(MODULE_INIT_BLOCK);
-}
-
-void bdrv_init_with_whitelist(void)
-{
- use_bdrv_whitelist = 1;
- bdrv_init();
-}
-
-void *qemu_aio_get(const AIOCBInfo *aiocb_info, BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriverAIOCB *acb;
-
- acb = g_slice_alloc(aiocb_info->aiocb_size);
- acb->aiocb_info = aiocb_info;
- acb->bs = bs;
- acb->cb = cb;
- acb->opaque = opaque;
- return acb;
-}
-
-void qemu_aio_release(void *p)
-{
- BlockDriverAIOCB *acb = p;
- g_slice_free1(acb->aiocb_info->aiocb_size, acb);
-}
-
-/**************************************************************/
-/* Coroutine block device emulation */
-
-typedef struct CoroutineIOCompletion {
- Coroutine *coroutine;
- int ret;
-} CoroutineIOCompletion;
-
-static void bdrv_co_io_em_complete(void *opaque, int ret)
-{
- CoroutineIOCompletion *co = opaque;
-
- co->ret = ret;
- qemu_coroutine_enter(co->coroutine, NULL);
-}
-
-static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *iov,
- bool is_write)
-{
- CoroutineIOCompletion co = {
- .coroutine = qemu_coroutine_self(),
- };
- BlockDriverAIOCB *acb;
-
- if (is_write) {
- acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
- bdrv_co_io_em_complete, &co);
- } else {
- acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
- bdrv_co_io_em_complete, &co);
- }
-
- trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
- if (!acb) {
- return -EIO;
- }
- qemu_coroutine_yield();
-
- return co.ret;
-}
-
-static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- QEMUIOVector *iov)
-{
- return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
-}
-
-static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- QEMUIOVector *iov)
-{
- return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
-}
-
-static void coroutine_fn bdrv_flush_co_entry(void *opaque)
-{
- RwCo *rwco = opaque;
-
- rwco->ret = bdrv_co_flush(rwco->bs);
-}
-
-int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
-{
- int ret;
-
- if (!bs || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
- return 0;
- }
-
- /* Write back cached data to the OS even with cache=unsafe */
- BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_OS);
- if (bs->drv->bdrv_co_flush_to_os) {
- ret = bs->drv->bdrv_co_flush_to_os(bs);
- if (ret < 0) {
- return ret;
- }
- }
-
- /* But don't actually force it to the disk with cache=unsafe */
- if (bs->open_flags & BDRV_O_NO_FLUSH) {
- goto flush_parent;
- }
-
- BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_DISK);
- if (bs->drv->bdrv_co_flush_to_disk) {
- ret = bs->drv->bdrv_co_flush_to_disk(bs);
- } else if (bs->drv->bdrv_aio_flush) {
- BlockDriverAIOCB *acb;
- CoroutineIOCompletion co = {
- .coroutine = qemu_coroutine_self(),
- };
-
- acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
- if (acb == NULL) {
- ret = -EIO;
- } else {
- qemu_coroutine_yield();
- ret = co.ret;
- }
- } else {
- /*
- * Some block drivers always operate in either writethrough or unsafe
- * mode and don't support bdrv_flush therefore. Usually qemu doesn't
- * know how the server works (because the behaviour is hardcoded or
- * depends on server-side configuration), so we can't ensure that
- * everything is safe on disk. Returning an error doesn't work because
- * that would break guests even if the server operates in writethrough
- * mode.
- *
- * Let's hope the user knows what he's doing.
- */
- ret = 0;
- }
- if (ret < 0) {
- return ret;
- }
-
- /* Now flush the underlying protocol. It will also have BDRV_O_NO_FLUSH
- * in the case of cache=unsafe, so there are no useless flushes.
- */
-flush_parent:
- return bdrv_co_flush(bs->file);
-}
-
-void bdrv_invalidate_cache(BlockDriverState *bs)
-{
- if (bs->drv && bs->drv->bdrv_invalidate_cache) {
- bs->drv->bdrv_invalidate_cache(bs);
- }
-}
-
-void bdrv_invalidate_cache_all(void)
-{
- BlockDriverState *bs;
-
- QTAILQ_FOREACH(bs, &bdrv_states, list) {
- bdrv_invalidate_cache(bs);
- }
-}
-
-void bdrv_clear_incoming_migration_all(void)
-{
- BlockDriverState *bs;
-
- QTAILQ_FOREACH(bs, &bdrv_states, list) {
- bs->open_flags = bs->open_flags & ~(BDRV_O_INCOMING);
- }
-}
-
-int bdrv_flush(BlockDriverState *bs)
-{
- Coroutine *co;
- RwCo rwco = {
- .bs = bs,
- .ret = NOT_DONE,
- };
-
- if (qemu_in_coroutine()) {
- /* Fast-path if already in coroutine context */
- bdrv_flush_co_entry(&rwco);
- } else {
- co = qemu_coroutine_create(bdrv_flush_co_entry);
- qemu_coroutine_enter(co, &rwco);
- while (rwco.ret == NOT_DONE) {
- qemu_aio_wait();
- }
- }
-
- return rwco.ret;
-}
-
-static void coroutine_fn bdrv_discard_co_entry(void *opaque)
-{
- RwCo *rwco = opaque;
-
- rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
-}
-
-int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors)
-{
- if (!bs->drv) {
- return -ENOMEDIUM;
- } else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
- return -EIO;
- } else if (bs->read_only) {
- return -EROFS;
- }
-
- if (bs->dirty_bitmap) {
- bdrv_reset_dirty(bs, sector_num, nb_sectors);
- }
-
- /* Do nothing if disabled. */
- if (!(bs->open_flags & BDRV_O_UNMAP)) {
- return 0;
- }
-
- if (bs->drv->bdrv_co_discard) {
- return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
- } else if (bs->drv->bdrv_aio_discard) {
- BlockDriverAIOCB *acb;
- CoroutineIOCompletion co = {
- .coroutine = qemu_coroutine_self(),
- };
-
- acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
- bdrv_co_io_em_complete, &co);
- if (acb == NULL) {
- return -EIO;
- } else {
- qemu_coroutine_yield();
- return co.ret;
- }
- } else {
- return 0;
- }
-}
-
-int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
-{
- Coroutine *co;
- RwCo rwco = {
- .bs = bs,
- .sector_num = sector_num,
- .nb_sectors = nb_sectors,
- .ret = NOT_DONE,
- };
-
- if (qemu_in_coroutine()) {
- /* Fast-path if already in coroutine context */
- bdrv_discard_co_entry(&rwco);
- } else {
- co = qemu_coroutine_create(bdrv_discard_co_entry);
- qemu_coroutine_enter(co, &rwco);
- while (rwco.ret == NOT_DONE) {
- qemu_aio_wait();
- }
- }
-
- return rwco.ret;
-}
-
-/**************************************************************/
-/* removable device support */
-
-/**
- * Return TRUE if the media is present
- */
-int bdrv_is_inserted(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
-
- if (!drv)
- return 0;
- if (!drv->bdrv_is_inserted)
- return 1;
- return drv->bdrv_is_inserted(bs);
-}
-
-/**
- * Return whether the media changed since the last call to this
- * function, or -ENOTSUP if we don't know. Most drivers don't know.
- */
-int bdrv_media_changed(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
-
- if (drv && drv->bdrv_media_changed) {
- return drv->bdrv_media_changed(bs);
- }
- return -ENOTSUP;
-}
-
-/**
- * If eject_flag is TRUE, eject the media. Otherwise, close the tray
- */
-void bdrv_eject(BlockDriverState *bs, bool eject_flag)
-{
- BlockDriver *drv = bs->drv;
-
- if (drv && drv->bdrv_eject) {
- drv->bdrv_eject(bs, eject_flag);
- }
-
- if (bs->device_name[0] != '\0') {
- bdrv_emit_qmp_eject_event(bs, eject_flag);
- }
-}
-
-/**
- * Lock or unlock the media (if it is locked, the user won't be able
- * to eject it manually).
- */
-void bdrv_lock_medium(BlockDriverState *bs, bool locked)
-{
- BlockDriver *drv = bs->drv;
-
- trace_bdrv_lock_medium(bs, locked);
-
- if (drv && drv->bdrv_lock_medium) {
- drv->bdrv_lock_medium(bs, locked);
- }
-}
-
-/* needed for generic scsi interface */
-
-int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
-{
- BlockDriver *drv = bs->drv;
-
- if (drv && drv->bdrv_ioctl)
- return drv->bdrv_ioctl(bs, req, buf);
- return -ENOTSUP;
-}
-
-BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
- unsigned long int req, void *buf,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BlockDriver *drv = bs->drv;
-
- if (drv && drv->bdrv_aio_ioctl)
- return drv->bdrv_aio_ioctl(bs, req, buf, cb, opaque);
- return NULL;
-}
-
-void bdrv_set_buffer_alignment(BlockDriverState *bs, int align)
-{
- bs->buffer_alignment = align;
-}
-
-void *qemu_blockalign(BlockDriverState *bs, size_t size)
-{
- return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size);
-}
-
-/*
- * Check if all memory in this vector is sector aligned.
- */
-bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
-{
- int i;
-
- for (i = 0; i < qiov->niov; i++) {
- if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) {
- return false;
- }
- }
-
- return true;
-}
-
-void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity)
-{
- int64_t bitmap_size;
-
- assert((granularity & (granularity - 1)) == 0);
-
- if (granularity) {
- granularity >>= BDRV_SECTOR_BITS;
- assert(!bs->dirty_bitmap);
- bitmap_size = (bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
- bs->dirty_bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1);
- } else {
- if (bs->dirty_bitmap) {
- hbitmap_free(bs->dirty_bitmap);
- bs->dirty_bitmap = NULL;
- }
- }
-}
-
-int bdrv_get_dirty(BlockDriverState *bs, int64_t sector)
-{
- if (bs->dirty_bitmap) {
- return hbitmap_get(bs->dirty_bitmap, sector);
- } else {
- return 0;
- }
-}
-
-void bdrv_dirty_iter_init(BlockDriverState *bs, HBitmapIter *hbi)
-{
- hbitmap_iter_init(hbi, bs->dirty_bitmap, 0);
-}
-
-void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
- int nr_sectors)
-{
- hbitmap_set(bs->dirty_bitmap, cur_sector, nr_sectors);
-}
-
-void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector,
- int nr_sectors)
-{
- hbitmap_reset(bs->dirty_bitmap, cur_sector, nr_sectors);
-}
-
-int64_t bdrv_get_dirty_count(BlockDriverState *bs)
-{
- if (bs->dirty_bitmap) {
- return hbitmap_count(bs->dirty_bitmap);
- } else {
- return 0;
- }
-}
-
-void bdrv_set_in_use(BlockDriverState *bs, int in_use)
-{
- assert(bs->in_use != in_use);
- bs->in_use = in_use;
-}
-
-int bdrv_in_use(BlockDriverState *bs)
-{
- return bs->in_use;
-}
-
-void bdrv_iostatus_enable(BlockDriverState *bs)
-{
- bs->iostatus_enabled = true;
- bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
-}
-
-/* The I/O status is only enabled if the drive explicitly
- * enables it _and_ the VM is configured to stop on errors */
-bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
-{
- return (bs->iostatus_enabled &&
- (bs->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC ||
- bs->on_write_error == BLOCKDEV_ON_ERROR_STOP ||
- bs->on_read_error == BLOCKDEV_ON_ERROR_STOP));
-}
-
-void bdrv_iostatus_disable(BlockDriverState *bs)
-{
- bs->iostatus_enabled = false;
-}
-
-void bdrv_iostatus_reset(BlockDriverState *bs)
-{
- if (bdrv_iostatus_is_enabled(bs)) {
- bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
- if (bs->job) {
- block_job_iostatus_reset(bs->job);
- }
- }
-}
-
-void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
-{
- assert(bdrv_iostatus_is_enabled(bs));
- if (bs->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
- bs->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
- BLOCK_DEVICE_IO_STATUS_FAILED;
- }
-}
-
-void
-bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
- enum BlockAcctType type)
-{
- assert(type < BDRV_MAX_IOTYPE);
-
- cookie->bytes = bytes;
- cookie->start_time_ns = get_clock();
- cookie->type = type;
-}
-
-void
-bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
-{
- assert(cookie->type < BDRV_MAX_IOTYPE);
-
- bs->nr_bytes[cookie->type] += cookie->bytes;
- bs->nr_ops[cookie->type]++;
- bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
-}
-
-void bdrv_img_create(const char *filename, const char *fmt,
- const char *base_filename, const char *base_fmt,
- char *options, uint64_t img_size, int flags,
- Error **errp, bool quiet)
-{
- QEMUOptionParameter *param = NULL, *create_options = NULL;
- QEMUOptionParameter *backing_fmt, *backing_file, *size;
- BlockDriverState *bs = NULL;
- BlockDriver *drv, *proto_drv;
- BlockDriver *backing_drv = NULL;
- int ret = 0;
-
- /* Find driver and parse its options */
- drv = bdrv_find_format(fmt);
- if (!drv) {
- error_setg(errp, "Unknown file format '%s'", fmt);
- return;
- }
-
- proto_drv = bdrv_find_protocol(filename, true);
- if (!proto_drv) {
- error_setg(errp, "Unknown protocol '%s'", filename);
- return;
- }
-
- create_options = append_option_parameters(create_options,
- drv->create_options);
- create_options = append_option_parameters(create_options,
- proto_drv->create_options);
-
- /* Create parameter list with default values */
- param = parse_option_parameters("", create_options, param);
-
- set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
-
- /* Parse -o options */
- if (options) {
- param = parse_option_parameters(options, create_options, param);
- if (param == NULL) {
- error_setg(errp, "Invalid options for file format '%s'.", fmt);
- goto out;
- }
- }
-
- if (base_filename) {
- if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
- base_filename)) {
- error_setg(errp, "Backing file not supported for file format '%s'",
- fmt);
- goto out;
- }
- }
-
- if (base_fmt) {
- if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
- error_setg(errp, "Backing file format not supported for file "
- "format '%s'", fmt);
- goto out;
- }
- }
-
- backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
- if (backing_file && backing_file->value.s) {
- if (!strcmp(filename, backing_file->value.s)) {
- error_setg(errp, "Error: Trying to create an image with the "
- "same filename as the backing file");
- goto out;
- }
- }
-
- backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
- if (backing_fmt && backing_fmt->value.s) {
- backing_drv = bdrv_find_format(backing_fmt->value.s);
- if (!backing_drv) {
- error_setg(errp, "Unknown backing file format '%s'",
- backing_fmt->value.s);
- goto out;
- }
- }
-
- // The size for the image must always be specified, with one exception:
- // If we are using a backing file, we can obtain the size from there
- size = get_option_parameter(param, BLOCK_OPT_SIZE);
- if (size && size->value.n == -1) {
- if (backing_file && backing_file->value.s) {
- uint64_t size;
- char buf[32];
- int back_flags;
-
- /* backing files always opened read-only */
- back_flags =
- flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
-
- bs = bdrv_new("");
-
- ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
- backing_drv);
- if (ret < 0) {
- error_setg_errno(errp, -ret, "Could not open '%s'",
- backing_file->value.s);
- goto out;
- }
- bdrv_get_geometry(bs, &size);
- size *= 512;
-
- snprintf(buf, sizeof(buf), "%" PRId64, size);
- set_option_parameter(param, BLOCK_OPT_SIZE, buf);
- } else {
- error_setg(errp, "Image creation needs a size parameter");
- goto out;
- }
- }
-
- if (!quiet) {
- printf("Formatting '%s', fmt=%s ", filename, fmt);
- print_option_parameters(param);
- puts("");
- }
- ret = bdrv_create(drv, filename, param);
- if (ret < 0) {
- if (ret == -ENOTSUP) {
- error_setg(errp,"Formatting or formatting option not supported for "
- "file format '%s'", fmt);
- } else if (ret == -EFBIG) {
- const char *cluster_size_hint = "";
- if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) {
- cluster_size_hint = " (try using a larger cluster size)";
- }
- error_setg(errp, "The image size is too large for file format '%s'%s",
- fmt, cluster_size_hint);
- } else {
- error_setg(errp, "%s: error while creating %s: %s", filename, fmt,
- strerror(-ret));
- }
- }
-
-out:
- free_option_parameters(create_options);
- free_option_parameters(param);
-
- if (bs) {
- bdrv_delete(bs);
- }
-}
-
-AioContext *bdrv_get_aio_context(BlockDriverState *bs)
-{
- /* Currently BlockDriverState always uses the main loop AioContext */
- return qemu_get_aio_context();
-}
-
-void bdrv_add_before_write_notifier(BlockDriverState *bs,
- NotifierWithReturn *notifier)
-{
- notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
-}
diff --git a/contrib/qemu/block/qcow.c b/contrib/qemu/block/qcow.c
deleted file mode 100644
index 5239bd68f1c..00000000000
--- a/contrib/qemu/block/qcow.c
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * Block driver for the QCOW format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/module.h"
-#include <zlib.h>
-#include "qemu/aes.h"
-#include "migration/migration.h"
-
-/**************************************************************/
-/* QEMU COW block driver with compression and encryption support */
-
-#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
-#define QCOW_VERSION 1
-
-#define QCOW_CRYPT_NONE 0
-#define QCOW_CRYPT_AES 1
-
-#define QCOW_OFLAG_COMPRESSED (1LL << 63)
-
-typedef struct QCowHeader {
- uint32_t magic;
- uint32_t version;
- uint64_t backing_file_offset;
- uint32_t backing_file_size;
- uint32_t mtime;
- uint64_t size; /* in bytes */
- uint8_t cluster_bits;
- uint8_t l2_bits;
- uint32_t crypt_method;
- uint64_t l1_table_offset;
-} QCowHeader;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct BDRVQcowState {
- int cluster_bits;
- int cluster_size;
- int cluster_sectors;
- int l2_bits;
- int l2_size;
- int l1_size;
- uint64_t cluster_offset_mask;
- uint64_t l1_table_offset;
- uint64_t *l1_table;
- uint64_t *l2_cache;
- uint64_t l2_cache_offsets[L2_CACHE_SIZE];
- uint32_t l2_cache_counts[L2_CACHE_SIZE];
- uint8_t *cluster_cache;
- uint8_t *cluster_data;
- uint64_t cluster_cache_offset;
- uint32_t crypt_method; /* current crypt method, 0 if no key yet */
- uint32_t crypt_method_header;
- AES_KEY aes_encrypt_key;
- AES_KEY aes_decrypt_key;
- CoMutex lock;
- Error *migration_blocker;
-} BDRVQcowState;
-
-static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
-
-static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const QCowHeader *cow_header = (const void *)buf;
-
- if (buf_size >= sizeof(QCowHeader) &&
- be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
- be32_to_cpu(cow_header->version) == QCOW_VERSION)
- return 100;
- else
- return 0;
-}
-
-static int qcow_open(BlockDriverState *bs, QDict *options, int flags)
-{
- BDRVQcowState *s = bs->opaque;
- int len, i, shift, ret;
- QCowHeader header;
-
- ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
- if (ret < 0) {
- goto fail;
- }
- be32_to_cpus(&header.magic);
- be32_to_cpus(&header.version);
- be64_to_cpus(&header.backing_file_offset);
- be32_to_cpus(&header.backing_file_size);
- be32_to_cpus(&header.mtime);
- be64_to_cpus(&header.size);
- be32_to_cpus(&header.crypt_method);
- be64_to_cpus(&header.l1_table_offset);
-
- if (header.magic != QCOW_MAGIC) {
- ret = -EMEDIUMTYPE;
- goto fail;
- }
- if (header.version != QCOW_VERSION) {
- char version[64];
- snprintf(version, sizeof(version), "QCOW version %d", header.version);
- qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
- bs->device_name, "qcow", version);
- ret = -ENOTSUP;
- goto fail;
- }
-
- if (header.size <= 1 || header.cluster_bits < 9) {
- ret = -EINVAL;
- goto fail;
- }
- if (header.crypt_method > QCOW_CRYPT_AES) {
- ret = -EINVAL;
- goto fail;
- }
- s->crypt_method_header = header.crypt_method;
- if (s->crypt_method_header) {
- bs->encrypted = 1;
- }
- s->cluster_bits = header.cluster_bits;
- s->cluster_size = 1 << s->cluster_bits;
- s->cluster_sectors = 1 << (s->cluster_bits - 9);
- s->l2_bits = header.l2_bits;
- s->l2_size = 1 << s->l2_bits;
- bs->total_sectors = header.size / 512;
- s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
-
- /* read the level 1 table */
- shift = s->cluster_bits + s->l2_bits;
- s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
-
- s->l1_table_offset = header.l1_table_offset;
- s->l1_table = g_malloc(s->l1_size * sizeof(uint64_t));
-
- ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,
- s->l1_size * sizeof(uint64_t));
- if (ret < 0) {
- goto fail;
- }
-
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
- /* alloc L2 cache */
- s->l2_cache = g_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
- s->cluster_cache = g_malloc(s->cluster_size);
- s->cluster_data = g_malloc(s->cluster_size);
- s->cluster_cache_offset = -1;
-
- /* read the backing file name */
- if (header.backing_file_offset != 0) {
- len = header.backing_file_size;
- if (len > 1023) {
- len = 1023;
- }
- ret = bdrv_pread(bs->file, header.backing_file_offset,
- bs->backing_file, len);
- if (ret < 0) {
- goto fail;
- }
- bs->backing_file[len] = '\0';
- }
-
- /* Disable migration when qcow images are used */
- error_set(&s->migration_blocker,
- QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
- "qcow", bs->device_name, "live migration");
- migrate_add_blocker(s->migration_blocker);
-
- qemu_co_mutex_init(&s->lock);
- return 0;
-
- fail:
- g_free(s->l1_table);
- g_free(s->l2_cache);
- g_free(s->cluster_cache);
- g_free(s->cluster_data);
- return ret;
-}
-
-
-/* We have nothing to do for QCOW reopen, stubs just return
- * success */
-static int qcow_reopen_prepare(BDRVReopenState *state,
- BlockReopenQueue *queue, Error **errp)
-{
- return 0;
-}
-
-static int qcow_set_key(BlockDriverState *bs, const char *key)
-{
- BDRVQcowState *s = bs->opaque;
- uint8_t keybuf[16];
- int len, i;
-
- memset(keybuf, 0, 16);
- len = strlen(key);
- if (len > 16)
- len = 16;
- /* XXX: we could compress the chars to 7 bits to increase
- entropy */
- for(i = 0;i < len;i++) {
- keybuf[i] = key[i];
- }
- s->crypt_method = s->crypt_method_header;
-
- if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
- return -1;
- if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
- return -1;
- return 0;
-}
-
-/* The crypt function is compatible with the linux cryptoloop
- algorithm for < 4 GB images. NOTE: out_buf == in_buf is
- supported */
-static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
- uint8_t *out_buf, const uint8_t *in_buf,
- int nb_sectors, int enc,
- const AES_KEY *key)
-{
- union {
- uint64_t ll[2];
- uint8_t b[16];
- } ivec;
- int i;
-
- for(i = 0; i < nb_sectors; i++) {
- ivec.ll[0] = cpu_to_le64(sector_num);
- ivec.ll[1] = 0;
- AES_cbc_encrypt(in_buf, out_buf, 512, key,
- ivec.b, enc);
- sector_num++;
- in_buf += 512;
- out_buf += 512;
- }
-}
-
-/* 'allocate' is:
- *
- * 0 to not allocate.
- *
- * 1 to allocate a normal cluster (for sector indexes 'n_start' to
- * 'n_end')
- *
- * 2 to allocate a compressed cluster of size
- * 'compressed_size'. 'compressed_size' must be > 0 and <
- * cluster_size
- *
- * return 0 if not allocated.
- */
-static uint64_t get_cluster_offset(BlockDriverState *bs,
- uint64_t offset, int allocate,
- int compressed_size,
- int n_start, int n_end)
-{
- BDRVQcowState *s = bs->opaque;
- int min_index, i, j, l1_index, l2_index;
- uint64_t l2_offset, *l2_table, cluster_offset, tmp;
- uint32_t min_count;
- int new_l2_table;
-
- l1_index = offset >> (s->l2_bits + s->cluster_bits);
- l2_offset = s->l1_table[l1_index];
- new_l2_table = 0;
- if (!l2_offset) {
- if (!allocate)
- return 0;
- /* allocate a new l2 entry */
- l2_offset = bdrv_getlength(bs->file);
- /* round to cluster size */
- l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1);
- /* update the L1 entry */
- s->l1_table[l1_index] = l2_offset;
- tmp = cpu_to_be64(l2_offset);
- if (bdrv_pwrite_sync(bs->file,
- s->l1_table_offset + l1_index * sizeof(tmp),
- &tmp, sizeof(tmp)) < 0)
- return 0;
- new_l2_table = 1;
- }
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (l2_offset == s->l2_cache_offsets[i]) {
- /* increment the hit count */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
- }
- }
- l2_table = s->l2_cache + (i << s->l2_bits);
- goto found;
- }
- }
- /* not found: load a new entry in the least used one */
- min_index = 0;
- min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
- min_index = i;
- }
- }
- l2_table = s->l2_cache + (min_index << s->l2_bits);
- if (new_l2_table) {
- memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
- if (bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
- s->l2_size * sizeof(uint64_t)) < 0)
- return 0;
- } else {
- if (bdrv_pread(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- }
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
- found:
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
- if (!cluster_offset ||
- ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
- if (!allocate)
- return 0;
- /* allocate a new cluster */
- if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
- (n_end - n_start) < s->cluster_sectors) {
- /* if the cluster is already compressed, we must
- decompress it in the case it is not completely
- overwritten */
- if (decompress_cluster(bs, cluster_offset) < 0)
- return 0;
- cluster_offset = bdrv_getlength(bs->file);
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
- ~(s->cluster_size - 1);
- /* write the cluster content */
- if (bdrv_pwrite(bs->file, cluster_offset, s->cluster_cache, s->cluster_size) !=
- s->cluster_size)
- return -1;
- } else {
- cluster_offset = bdrv_getlength(bs->file);
- if (allocate == 1) {
- /* round to cluster size */
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
- ~(s->cluster_size - 1);
- bdrv_truncate(bs->file, cluster_offset + s->cluster_size);
- /* if encrypted, we must initialize the cluster
- content which won't be written */
- if (s->crypt_method &&
- (n_end - n_start) < s->cluster_sectors) {
- uint64_t start_sect;
- start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
- memset(s->cluster_data + 512, 0x00, 512);
- for(i = 0; i < s->cluster_sectors; i++) {
- if (i < n_start || i >= n_end) {
- encrypt_sectors(s, start_sect + i,
- s->cluster_data,
- s->cluster_data + 512, 1, 1,
- &s->aes_encrypt_key);
- if (bdrv_pwrite(bs->file, cluster_offset + i * 512,
- s->cluster_data, 512) != 512)
- return -1;
- }
- }
- }
- } else if (allocate == 2) {
- cluster_offset |= QCOW_OFLAG_COMPRESSED |
- (uint64_t)compressed_size << (63 - s->cluster_bits);
- }
- }
- /* update L2 table */
- tmp = cpu_to_be64(cluster_offset);
- l2_table[l2_index] = tmp;
- if (bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
- &tmp, sizeof(tmp)) < 0)
- return 0;
- }
- return cluster_offset;
-}
-
-static int coroutine_fn qcow_co_is_allocated(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, int *pnum)
-{
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
-
- qemu_co_mutex_lock(&s->lock);
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
- qemu_co_mutex_unlock(&s->lock);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- *pnum = n;
- return (cluster_offset != 0);
-}
-
-static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
- const uint8_t *buf, int buf_size)
-{
- z_stream strm1, *strm = &strm1;
- int ret, out_len;
-
- memset(strm, 0, sizeof(*strm));
-
- strm->next_in = (uint8_t *)buf;
- strm->avail_in = buf_size;
- strm->next_out = out_buf;
- strm->avail_out = out_buf_size;
-
- ret = inflateInit2(strm, -12);
- if (ret != Z_OK)
- return -1;
- ret = inflate(strm, Z_FINISH);
- out_len = strm->next_out - out_buf;
- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
- out_len != out_buf_size) {
- inflateEnd(strm);
- return -1;
- }
- inflateEnd(strm);
- return 0;
-}
-
-static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, csize;
- uint64_t coffset;
-
- coffset = cluster_offset & s->cluster_offset_mask;
- if (s->cluster_cache_offset != coffset) {
- csize = cluster_offset >> (63 - s->cluster_bits);
- csize &= (s->cluster_size - 1);
- ret = bdrv_pread(bs->file, coffset, s->cluster_data, csize);
- if (ret != csize)
- return -1;
- if (decompress_buffer(s->cluster_cache, s->cluster_size,
- s->cluster_data, csize) < 0) {
- return -1;
- }
- s->cluster_cache_offset = coffset;
- }
- return 0;
-}
-
-static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov)
-{
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster;
- int ret = 0, n;
- uint64_t cluster_offset;
- struct iovec hd_iov;
- QEMUIOVector hd_qiov;
- uint8_t *buf;
- void *orig_buf;
-
- if (qiov->niov > 1) {
- buf = orig_buf = qemu_blockalign(bs, qiov->size);
- } else {
- orig_buf = NULL;
- buf = (uint8_t *)qiov->iov->iov_base;
- }
-
- qemu_co_mutex_lock(&s->lock);
-
- while (nb_sectors != 0) {
- /* prepare next request */
- cluster_offset = get_cluster_offset(bs, sector_num << 9,
- 0, 0, 0, 0);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors) {
- n = nb_sectors;
- }
-
- if (!cluster_offset) {
- if (bs->backing_hd) {
- /* read from the base image */
- hd_iov.iov_base = (void *)buf;
- hd_iov.iov_len = n * 512;
- qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
- qemu_co_mutex_unlock(&s->lock);
- ret = bdrv_co_readv(bs->backing_hd, sector_num,
- n, &hd_qiov);
- qemu_co_mutex_lock(&s->lock);
- if (ret < 0) {
- goto fail;
- }
- } else {
- /* Note: in this case, no need to wait */
- memset(buf, 0, 512 * n);
- }
- } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
- /* add AIO support for compressed blocks ? */
- if (decompress_cluster(bs, cluster_offset) < 0) {
- goto fail;
- }
- memcpy(buf,
- s->cluster_cache + index_in_cluster * 512, 512 * n);
- } else {
- if ((cluster_offset & 511) != 0) {
- goto fail;
- }
- hd_iov.iov_base = (void *)buf;
- hd_iov.iov_len = n * 512;
- qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
- qemu_co_mutex_unlock(&s->lock);
- ret = bdrv_co_readv(bs->file,
- (cluster_offset >> 9) + index_in_cluster,
- n, &hd_qiov);
- qemu_co_mutex_lock(&s->lock);
- if (ret < 0) {
- break;
- }
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, buf, buf,
- n, 0,
- &s->aes_decrypt_key);
- }
- }
- ret = 0;
-
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
-
-done:
- qemu_co_mutex_unlock(&s->lock);
-
- if (qiov->niov > 1) {
- qemu_iovec_from_buf(qiov, 0, orig_buf, qiov->size);
- qemu_vfree(orig_buf);
- }
-
- return ret;
-
-fail:
- ret = -EIO;
- goto done;
-}
-
-static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov)
-{
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster;
- uint64_t cluster_offset;
- const uint8_t *src_buf;
- int ret = 0, n;
- uint8_t *cluster_data = NULL;
- struct iovec hd_iov;
- QEMUIOVector hd_qiov;
- uint8_t *buf;
- void *orig_buf;
-
- s->cluster_cache_offset = -1; /* disable compressed cache */
-
- if (qiov->niov > 1) {
- buf = orig_buf = qemu_blockalign(bs, qiov->size);
- qemu_iovec_to_buf(qiov, 0, buf, qiov->size);
- } else {
- orig_buf = NULL;
- buf = (uint8_t *)qiov->iov->iov_base;
- }
-
- qemu_co_mutex_lock(&s->lock);
-
- while (nb_sectors != 0) {
-
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors) {
- n = nb_sectors;
- }
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
- index_in_cluster,
- index_in_cluster + n);
- if (!cluster_offset || (cluster_offset & 511) != 0) {
- ret = -EIO;
- break;
- }
- if (s->crypt_method) {
- if (!cluster_data) {
- cluster_data = g_malloc0(s->cluster_size);
- }
- encrypt_sectors(s, sector_num, cluster_data, buf,
- n, 1, &s->aes_encrypt_key);
- src_buf = cluster_data;
- } else {
- src_buf = buf;
- }
-
- hd_iov.iov_base = (void *)src_buf;
- hd_iov.iov_len = n * 512;
- qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
- qemu_co_mutex_unlock(&s->lock);
- ret = bdrv_co_writev(bs->file,
- (cluster_offset >> 9) + index_in_cluster,
- n, &hd_qiov);
- qemu_co_mutex_lock(&s->lock);
- if (ret < 0) {
- break;
- }
- ret = 0;
-
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- qemu_co_mutex_unlock(&s->lock);
-
- if (qiov->niov > 1) {
- qemu_vfree(orig_buf);
- }
- g_free(cluster_data);
-
- return ret;
-}
-
-static void qcow_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
-
- g_free(s->l1_table);
- g_free(s->l2_cache);
- g_free(s->cluster_cache);
- g_free(s->cluster_data);
-
- migrate_del_blocker(s->migration_blocker);
- error_free(s->migration_blocker);
-}
-
-static int qcow_create(const char *filename, QEMUOptionParameter *options)
-{
- int header_size, backing_filename_len, l1_size, shift, i;
- QCowHeader header;
- uint8_t *tmp;
- int64_t total_size = 0;
- const char *backing_file = NULL;
- int flags = 0;
- int ret;
- BlockDriverState *qcow_bs;
-
- /* Read out options */
- while (options && options->name) {
- if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
- total_size = options->value.n / 512;
- } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
- backing_file = options->value.s;
- } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
- flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
- }
- options++;
- }
-
- ret = bdrv_create_file(filename, options);
- if (ret < 0) {
- return ret;
- }
-
- ret = bdrv_file_open(&qcow_bs, filename, NULL, BDRV_O_RDWR);
- if (ret < 0) {
- return ret;
- }
-
- ret = bdrv_truncate(qcow_bs, 0);
- if (ret < 0) {
- goto exit;
- }
-
- memset(&header, 0, sizeof(header));
- header.magic = cpu_to_be32(QCOW_MAGIC);
- header.version = cpu_to_be32(QCOW_VERSION);
- header.size = cpu_to_be64(total_size * 512);
- header_size = sizeof(header);
- backing_filename_len = 0;
- if (backing_file) {
- if (strcmp(backing_file, "fat:")) {
- header.backing_file_offset = cpu_to_be64(header_size);
- backing_filename_len = strlen(backing_file);
- header.backing_file_size = cpu_to_be32(backing_filename_len);
- header_size += backing_filename_len;
- } else {
- /* special backing file for vvfat */
- backing_file = NULL;
- }
- header.cluster_bits = 9; /* 512 byte cluster to avoid copying
- unmodifyed sectors */
- header.l2_bits = 12; /* 32 KB L2 tables */
- } else {
- header.cluster_bits = 12; /* 4 KB clusters */
- header.l2_bits = 9; /* 4 KB L2 tables */
- }
- header_size = (header_size + 7) & ~7;
- shift = header.cluster_bits + header.l2_bits;
- l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
-
- header.l1_table_offset = cpu_to_be64(header_size);
- if (flags & BLOCK_FLAG_ENCRYPT) {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
- } else {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
- }
-
- /* write all the data */
- ret = bdrv_pwrite(qcow_bs, 0, &header, sizeof(header));
- if (ret != sizeof(header)) {
- goto exit;
- }
-
- if (backing_file) {
- ret = bdrv_pwrite(qcow_bs, sizeof(header),
- backing_file, backing_filename_len);
- if (ret != backing_filename_len) {
- goto exit;
- }
- }
-
- tmp = g_malloc0(BDRV_SECTOR_SIZE);
- for (i = 0; i < ((sizeof(uint64_t)*l1_size + BDRV_SECTOR_SIZE - 1)/
- BDRV_SECTOR_SIZE); i++) {
- ret = bdrv_pwrite(qcow_bs, header_size +
- BDRV_SECTOR_SIZE*i, tmp, BDRV_SECTOR_SIZE);
- if (ret != BDRV_SECTOR_SIZE) {
- g_free(tmp);
- goto exit;
- }
- }
-
- g_free(tmp);
- ret = 0;
-exit:
- bdrv_delete(qcow_bs);
- return ret;
-}
-
-static int qcow_make_empty(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- uint32_t l1_length = s->l1_size * sizeof(uint64_t);
- int ret;
-
- memset(s->l1_table, 0, l1_length);
- if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
- l1_length) < 0)
- return -1;
- ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
- if (ret < 0)
- return ret;
-
- memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
- memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
- memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t));
-
- return 0;
-}
-
-/* XXX: put compressed sectors first, then all the cluster aligned
- tables to avoid losing bytes in alignment */
-static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- z_stream strm;
- int ret, out_len;
- uint8_t *out_buf;
- uint64_t cluster_offset;
-
- if (nb_sectors != s->cluster_sectors) {
- ret = -EINVAL;
-
- /* Zero-pad last write if image size is not cluster aligned */
- if (sector_num + nb_sectors == bs->total_sectors &&
- nb_sectors < s->cluster_sectors) {
- uint8_t *pad_buf = qemu_blockalign(bs, s->cluster_size);
- memset(pad_buf, 0, s->cluster_size);
- memcpy(pad_buf, buf, nb_sectors * BDRV_SECTOR_SIZE);
- ret = qcow_write_compressed(bs, sector_num,
- pad_buf, s->cluster_sectors);
- qemu_vfree(pad_buf);
- }
- return ret;
- }
-
- out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
-
- /* best compression, small window, no zlib header */
- memset(&strm, 0, sizeof(strm));
- ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -12,
- 9, Z_DEFAULT_STRATEGY);
- if (ret != 0) {
- ret = -EINVAL;
- goto fail;
- }
-
- strm.avail_in = s->cluster_size;
- strm.next_in = (uint8_t *)buf;
- strm.avail_out = s->cluster_size;
- strm.next_out = out_buf;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END && ret != Z_OK) {
- deflateEnd(&strm);
- ret = -EINVAL;
- goto fail;
- }
- out_len = strm.next_out - out_buf;
-
- deflateEnd(&strm);
-
- if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
- /* could not compress: write normal cluster */
- ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
- if (ret < 0) {
- goto fail;
- }
- } else {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
- out_len, 0, 0);
- if (cluster_offset == 0) {
- ret = -EIO;
- goto fail;
- }
-
- cluster_offset &= s->cluster_offset_mask;
- ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
- if (ret < 0) {
- goto fail;
- }
- }
-
- ret = 0;
-fail:
- g_free(out_buf);
- return ret;
-}
-
-static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BDRVQcowState *s = bs->opaque;
- bdi->cluster_size = s->cluster_size;
- return 0;
-}
-
-
-static QEMUOptionParameter qcow_create_options[] = {
- {
- .name = BLOCK_OPT_SIZE,
- .type = OPT_SIZE,
- .help = "Virtual disk size"
- },
- {
- .name = BLOCK_OPT_BACKING_FILE,
- .type = OPT_STRING,
- .help = "File name of a base image"
- },
- {
- .name = BLOCK_OPT_ENCRYPT,
- .type = OPT_FLAG,
- .help = "Encrypt the image"
- },
- { NULL }
-};
-
-static BlockDriver bdrv_qcow = {
- .format_name = "qcow",
- .instance_size = sizeof(BDRVQcowState),
- .bdrv_probe = qcow_probe,
- .bdrv_open = qcow_open,
- .bdrv_close = qcow_close,
- .bdrv_reopen_prepare = qcow_reopen_prepare,
- .bdrv_create = qcow_create,
- .bdrv_has_zero_init = bdrv_has_zero_init_1,
-
- .bdrv_co_readv = qcow_co_readv,
- .bdrv_co_writev = qcow_co_writev,
- .bdrv_co_is_allocated = qcow_co_is_allocated,
-
- .bdrv_set_key = qcow_set_key,
- .bdrv_make_empty = qcow_make_empty,
- .bdrv_write_compressed = qcow_write_compressed,
- .bdrv_get_info = qcow_get_info,
-
- .create_options = qcow_create_options,
-};
-
-static void bdrv_qcow_init(void)
-{
- bdrv_register(&bdrv_qcow);
-}
-
-block_init(bdrv_qcow_init);
diff --git a/contrib/qemu/block/qcow2-cache.c b/contrib/qemu/block/qcow2-cache.c
deleted file mode 100644
index 2f3114ecc24..00000000000
--- a/contrib/qemu/block/qcow2-cache.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * L2/refcount table cache for the QCOW2 format
- *
- * Copyright (c) 2010 Kevin Wolf <kwolf@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "block/block_int.h"
-#include "qemu-common.h"
-#include "qcow2.h"
-#include "trace.h"
-
-typedef struct Qcow2CachedTable {
- void* table;
- int64_t offset;
- bool dirty;
- int cache_hits;
- int ref;
-} Qcow2CachedTable;
-
-struct Qcow2Cache {
- Qcow2CachedTable* entries;
- struct Qcow2Cache* depends;
- int size;
- bool depends_on_flush;
-};
-
-Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables)
-{
- BDRVQcowState *s = bs->opaque;
- Qcow2Cache *c;
- int i;
-
- c = g_malloc0(sizeof(*c));
- c->size = num_tables;
- c->entries = g_malloc0(sizeof(*c->entries) * num_tables);
-
- for (i = 0; i < c->size; i++) {
- c->entries[i].table = qemu_blockalign(bs, s->cluster_size);
- }
-
- return c;
-}
-
-int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c)
-{
- int i;
-
- for (i = 0; i < c->size; i++) {
- assert(c->entries[i].ref == 0);
- qemu_vfree(c->entries[i].table);
- }
-
- g_free(c->entries);
- g_free(c);
-
- return 0;
-}
-
-static int qcow2_cache_flush_dependency(BlockDriverState *bs, Qcow2Cache *c)
-{
- int ret;
-
- ret = qcow2_cache_flush(bs, c->depends);
- if (ret < 0) {
- return ret;
- }
-
- c->depends = NULL;
- c->depends_on_flush = false;
-
- return 0;
-}
-
-static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
-{
- BDRVQcowState *s = bs->opaque;
- int ret = 0;
-
- if (!c->entries[i].dirty || !c->entries[i].offset) {
- return 0;
- }
-
- trace_qcow2_cache_entry_flush(qemu_coroutine_self(),
- c == s->l2_table_cache, i);
-
- if (c->depends) {
- ret = qcow2_cache_flush_dependency(bs, c);
- } else if (c->depends_on_flush) {
- ret = bdrv_flush(bs->file);
- if (ret >= 0) {
- c->depends_on_flush = false;
- }
- }
-
- if (ret < 0) {
- return ret;
- }
-
- if (c == s->refcount_block_cache) {
- BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART);
- } else if (c == s->l2_table_cache) {
- BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
- }
-
- ret = bdrv_pwrite(bs->file, c->entries[i].offset, c->entries[i].table,
- s->cluster_size);
- if (ret < 0) {
- return ret;
- }
-
- c->entries[i].dirty = false;
-
- return 0;
-}
-
-int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
-{
- BDRVQcowState *s = bs->opaque;
- int result = 0;
- int ret;
- int i;
-
- trace_qcow2_cache_flush(qemu_coroutine_self(), c == s->l2_table_cache);
-
- for (i = 0; i < c->size; i++) {
- ret = qcow2_cache_entry_flush(bs, c, i);
- if (ret < 0 && result != -ENOSPC) {
- result = ret;
- }
- }
-
- if (result == 0) {
- ret = bdrv_flush(bs->file);
- if (ret < 0) {
- result = ret;
- }
- }
-
- return result;
-}
-
-int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
- Qcow2Cache *dependency)
-{
- int ret;
-
- if (dependency->depends) {
- ret = qcow2_cache_flush_dependency(bs, dependency);
- if (ret < 0) {
- return ret;
- }
- }
-
- if (c->depends && (c->depends != dependency)) {
- ret = qcow2_cache_flush_dependency(bs, c);
- if (ret < 0) {
- return ret;
- }
- }
-
- c->depends = dependency;
- return 0;
-}
-
-void qcow2_cache_depends_on_flush(Qcow2Cache *c)
-{
- c->depends_on_flush = true;
-}
-
-static int qcow2_cache_find_entry_to_replace(Qcow2Cache *c)
-{
- int i;
- int min_count = INT_MAX;
- int min_index = -1;
-
-
- for (i = 0; i < c->size; i++) {
- if (c->entries[i].ref) {
- continue;
- }
-
- if (c->entries[i].cache_hits < min_count) {
- min_index = i;
- min_count = c->entries[i].cache_hits;
- }
-
- /* Give newer hits priority */
- /* TODO Check how to optimize the replacement strategy */
- c->entries[i].cache_hits /= 2;
- }
-
- if (min_index == -1) {
- /* This can't happen in current synchronous code, but leave the check
- * here as a reminder for whoever starts using AIO with the cache */
- abort();
- }
- return min_index;
-}
-
-static int qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c,
- uint64_t offset, void **table, bool read_from_disk)
-{
- BDRVQcowState *s = bs->opaque;
- int i;
- int ret;
-
- trace_qcow2_cache_get(qemu_coroutine_self(), c == s->l2_table_cache,
- offset, read_from_disk);
-
- /* Check if the table is already cached */
- for (i = 0; i < c->size; i++) {
- if (c->entries[i].offset == offset) {
- goto found;
- }
- }
-
- /* If not, write a table back and replace it */
- i = qcow2_cache_find_entry_to_replace(c);
- trace_qcow2_cache_get_replace_entry(qemu_coroutine_self(),
- c == s->l2_table_cache, i);
- if (i < 0) {
- return i;
- }
-
- ret = qcow2_cache_entry_flush(bs, c, i);
- if (ret < 0) {
- return ret;
- }
-
- trace_qcow2_cache_get_read(qemu_coroutine_self(),
- c == s->l2_table_cache, i);
- c->entries[i].offset = 0;
- if (read_from_disk) {
- if (c == s->l2_table_cache) {
- BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
- }
-
- ret = bdrv_pread(bs->file, offset, c->entries[i].table, s->cluster_size);
- if (ret < 0) {
- return ret;
- }
- }
-
- /* Give the table some hits for the start so that it won't be replaced
- * immediately. The number 32 is completely arbitrary. */
- c->entries[i].cache_hits = 32;
- c->entries[i].offset = offset;
-
- /* And return the right table */
-found:
- c->entries[i].cache_hits++;
- c->entries[i].ref++;
- *table = c->entries[i].table;
-
- trace_qcow2_cache_get_done(qemu_coroutine_self(),
- c == s->l2_table_cache, i);
-
- return 0;
-}
-
-int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
- void **table)
-{
- return qcow2_cache_do_get(bs, c, offset, table, true);
-}
-
-int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
- void **table)
-{
- return qcow2_cache_do_get(bs, c, offset, table, false);
-}
-
-int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table)
-{
- int i;
-
- for (i = 0; i < c->size; i++) {
- if (c->entries[i].table == *table) {
- goto found;
- }
- }
- return -ENOENT;
-
-found:
- c->entries[i].ref--;
- *table = NULL;
-
- assert(c->entries[i].ref >= 0);
- return 0;
-}
-
-void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table)
-{
- int i;
-
- for (i = 0; i < c->size; i++) {
- if (c->entries[i].table == table) {
- goto found;
- }
- }
- abort();
-
-found:
- c->entries[i].dirty = true;
-}
diff --git a/contrib/qemu/block/qcow2-cluster.c b/contrib/qemu/block/qcow2-cluster.c
deleted file mode 100644
index cca76d4fcdd..00000000000
--- a/contrib/qemu/block/qcow2-cluster.c
+++ /dev/null
@@ -1,1478 +0,0 @@
-/*
- * Block driver for the QCOW version 2 format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <zlib.h>
-
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "block/qcow2.h"
-#include "trace.h"
-
-int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
- bool exact_size)
-{
- BDRVQcowState *s = bs->opaque;
- int new_l1_size2, ret, i;
- uint64_t *new_l1_table;
- int64_t new_l1_table_offset, new_l1_size;
- uint8_t data[12];
-
- if (min_size <= s->l1_size)
- return 0;
-
- if (exact_size) {
- new_l1_size = min_size;
- } else {
- /* Bump size up to reduce the number of times we have to grow */
- new_l1_size = s->l1_size;
- if (new_l1_size == 0) {
- new_l1_size = 1;
- }
- while (min_size > new_l1_size) {
- new_l1_size = (new_l1_size * 3 + 1) / 2;
- }
- }
-
- if (new_l1_size > INT_MAX) {
- return -EFBIG;
- }
-
-#ifdef DEBUG_ALLOC2
- fprintf(stderr, "grow l1_table from %d to %" PRId64 "\n",
- s->l1_size, new_l1_size);
-#endif
-
- new_l1_size2 = sizeof(uint64_t) * new_l1_size;
- new_l1_table = g_malloc0(align_offset(new_l1_size2, 512));
- memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
-
- /* write new table (align to cluster) */
- BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE);
- new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2);
- if (new_l1_table_offset < 0) {
- g_free(new_l1_table);
- return new_l1_table_offset;
- }
-
- ret = qcow2_cache_flush(bs, s->refcount_block_cache);
- if (ret < 0) {
- goto fail;
- }
-
- BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
- for(i = 0; i < s->l1_size; i++)
- new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
- ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);
- if (ret < 0)
- goto fail;
- for(i = 0; i < s->l1_size; i++)
- new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
-
- /* set new table */
- BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);
- cpu_to_be32w((uint32_t*)data, new_l1_size);
- cpu_to_be64wu((uint64_t*)(data + 4), new_l1_table_offset);
- ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
- if (ret < 0) {
- goto fail;
- }
- g_free(s->l1_table);
- qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t),
- QCOW2_DISCARD_OTHER);
- s->l1_table_offset = new_l1_table_offset;
- s->l1_table = new_l1_table;
- s->l1_size = new_l1_size;
- return 0;
- fail:
- g_free(new_l1_table);
- qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2,
- QCOW2_DISCARD_OTHER);
- return ret;
-}
-
-/*
- * l2_load
- *
- * Loads a L2 table into memory. If the table is in the cache, the cache
- * is used; otherwise the L2 table is loaded from the image file.
- *
- * Returns a pointer to the L2 table on success, or NULL if the read from
- * the image file failed.
- */
-
-static int l2_load(BlockDriverState *bs, uint64_t l2_offset,
- uint64_t **l2_table)
-{
- BDRVQcowState *s = bs->opaque;
- int ret;
-
- ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset, (void**) l2_table);
-
- return ret;
-}
-
-/*
- * Writes one sector of the L1 table to the disk (can't update single entries
- * and we really don't want bdrv_pread to perform a read-modify-write)
- */
-#define L1_ENTRIES_PER_SECTOR (512 / 8)
-static int write_l1_entry(BlockDriverState *bs, int l1_index)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t buf[L1_ENTRIES_PER_SECTOR];
- int l1_start_index;
- int i, ret;
-
- l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR - 1);
- for (i = 0; i < L1_ENTRIES_PER_SECTOR; i++) {
- buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
- }
-
- BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
- ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index,
- buf, sizeof(buf));
- if (ret < 0) {
- return ret;
- }
-
- return 0;
-}
-
-/*
- * l2_allocate
- *
- * Allocate a new l2 entry in the file. If l1_index points to an already
- * used entry in the L2 table (i.e. we are doing a copy on write for the L2
- * table) copy the contents of the old L2 table into the newly allocated one.
- * Otherwise the new table is initialized with zeros.
- *
- */
-
-static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t old_l2_offset;
- uint64_t *l2_table;
- int64_t l2_offset;
- int ret;
-
- old_l2_offset = s->l1_table[l1_index];
-
- trace_qcow2_l2_allocate(bs, l1_index);
-
- /* allocate a new l2 entry */
-
- l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
- if (l2_offset < 0) {
- return l2_offset;
- }
-
- ret = qcow2_cache_flush(bs, s->refcount_block_cache);
- if (ret < 0) {
- goto fail;
- }
-
- /* allocate a new entry in the l2 cache */
-
- trace_qcow2_l2_allocate_get_empty(bs, l1_index);
- ret = qcow2_cache_get_empty(bs, s->l2_table_cache, l2_offset, (void**) table);
- if (ret < 0) {
- return ret;
- }
-
- l2_table = *table;
-
- if ((old_l2_offset & L1E_OFFSET_MASK) == 0) {
- /* if there was no old l2 table, clear the new table */
- memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
- } else {
- uint64_t* old_table;
-
- /* if there was an old l2 table, read it from the disk */
- BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_COW_READ);
- ret = qcow2_cache_get(bs, s->l2_table_cache,
- old_l2_offset & L1E_OFFSET_MASK,
- (void**) &old_table);
- if (ret < 0) {
- goto fail;
- }
-
- memcpy(l2_table, old_table, s->cluster_size);
-
- ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &old_table);
- if (ret < 0) {
- goto fail;
- }
- }
-
- /* write the l2 table to the file */
- BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE);
-
- trace_qcow2_l2_allocate_write_l2(bs, l1_index);
- qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
- ret = qcow2_cache_flush(bs, s->l2_table_cache);
- if (ret < 0) {
- goto fail;
- }
-
- /* update the L1 entry */
- trace_qcow2_l2_allocate_write_l1(bs, l1_index);
- s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
- ret = write_l1_entry(bs, l1_index);
- if (ret < 0) {
- goto fail;
- }
-
- *table = l2_table;
- trace_qcow2_l2_allocate_done(bs, l1_index, 0);
- return 0;
-
-fail:
- trace_qcow2_l2_allocate_done(bs, l1_index, ret);
- qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
- s->l1_table[l1_index] = old_l2_offset;
- return ret;
-}
-
-/*
- * Checks how many clusters in a given L2 table are contiguous in the image
- * file. As soon as one of the flags in the bitmask stop_flags changes compared
- * to the first cluster, the search is stopped and the cluster is not counted
- * as contiguous. (This allows it, for example, to stop at the first compressed
- * cluster which may require a different handling)
- */
-static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size,
- uint64_t *l2_table, uint64_t start, uint64_t stop_flags)
-{
- int i;
- uint64_t mask = stop_flags | L2E_OFFSET_MASK;
- uint64_t offset = be64_to_cpu(l2_table[0]) & mask;
-
- if (!offset)
- return 0;
-
- for (i = start; i < start + nb_clusters; i++) {
- uint64_t l2_entry = be64_to_cpu(l2_table[i]) & mask;
- if (offset + (uint64_t) i * cluster_size != l2_entry) {
- break;
- }
- }
-
- return (i - start);
-}
-
-static int count_contiguous_free_clusters(uint64_t nb_clusters, uint64_t *l2_table)
-{
- int i;
-
- for (i = 0; i < nb_clusters; i++) {
- int type = qcow2_get_cluster_type(be64_to_cpu(l2_table[i]));
-
- if (type != QCOW2_CLUSTER_UNALLOCATED) {
- break;
- }
- }
-
- return i;
-}
-
-/* The crypt function is compatible with the linux cryptoloop
- algorithm for < 4 GB images. NOTE: out_buf == in_buf is
- supported */
-void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
- uint8_t *out_buf, const uint8_t *in_buf,
- int nb_sectors, int enc,
- const AES_KEY *key)
-{
- union {
- uint64_t ll[2];
- uint8_t b[16];
- } ivec;
- int i;
-
- for(i = 0; i < nb_sectors; i++) {
- ivec.ll[0] = cpu_to_le64(sector_num);
- ivec.ll[1] = 0;
- AES_cbc_encrypt(in_buf, out_buf, 512, key,
- ivec.b, enc);
- sector_num++;
- in_buf += 512;
- out_buf += 512;
- }
-}
-
-static int coroutine_fn copy_sectors(BlockDriverState *bs,
- uint64_t start_sect,
- uint64_t cluster_offset,
- int n_start, int n_end)
-{
- BDRVQcowState *s = bs->opaque;
- QEMUIOVector qiov;
- struct iovec iov;
- int n, ret;
-
- /*
- * If this is the last cluster and it is only partially used, we must only
- * copy until the end of the image, or bdrv_check_request will fail for the
- * bdrv_read/write calls below.
- */
- if (start_sect + n_end > bs->total_sectors) {
- n_end = bs->total_sectors - start_sect;
- }
-
- n = n_end - n_start;
- if (n <= 0) {
- return 0;
- }
-
- iov.iov_len = n * BDRV_SECTOR_SIZE;
- iov.iov_base = qemu_blockalign(bs, iov.iov_len);
-
- qemu_iovec_init_external(&qiov, &iov, 1);
-
- BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);
-
- /* Call .bdrv_co_readv() directly instead of using the public block-layer
- * interface. This avoids double I/O throttling and request tracking,
- * which can lead to deadlock when block layer copy-on-read is enabled.
- */
- ret = bs->drv->bdrv_co_readv(bs, start_sect + n_start, n, &qiov);
- if (ret < 0) {
- goto out;
- }
-
- if (s->crypt_method) {
- qcow2_encrypt_sectors(s, start_sect + n_start,
- iov.iov_base, iov.iov_base, n, 1,
- &s->aes_encrypt_key);
- }
-
- BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
- ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + n_start, n, &qiov);
- if (ret < 0) {
- goto out;
- }
-
- ret = 0;
-out:
- qemu_vfree(iov.iov_base);
- return ret;
-}
-
-
-/*
- * get_cluster_offset
- *
- * For a given offset of the disk image, find the cluster offset in
- * qcow2 file. The offset is stored in *cluster_offset.
- *
- * on entry, *num is the number of contiguous sectors we'd like to
- * access following offset.
- *
- * on exit, *num is the number of contiguous sectors we can read.
- *
- * Returns the cluster type (QCOW2_CLUSTER_*) on success, -errno in error
- * cases.
- */
-int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
- int *num, uint64_t *cluster_offset)
-{
- BDRVQcowState *s = bs->opaque;
- unsigned int l2_index;
- uint64_t l1_index, l2_offset, *l2_table;
- int l1_bits, c;
- unsigned int index_in_cluster, nb_clusters;
- uint64_t nb_available, nb_needed;
- int ret;
-
- index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1);
- nb_needed = *num + index_in_cluster;
-
- l1_bits = s->l2_bits + s->cluster_bits;
-
- /* compute how many bytes there are between the offset and
- * the end of the l1 entry
- */
-
- nb_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1));
-
- /* compute the number of available sectors */
-
- nb_available = (nb_available >> 9) + index_in_cluster;
-
- if (nb_needed > nb_available) {
- nb_needed = nb_available;
- }
-
- *cluster_offset = 0;
-
- /* seek the the l2 offset in the l1 table */
-
- l1_index = offset >> l1_bits;
- if (l1_index >= s->l1_size) {
- ret = QCOW2_CLUSTER_UNALLOCATED;
- goto out;
- }
-
- l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK;
- if (!l2_offset) {
- ret = QCOW2_CLUSTER_UNALLOCATED;
- goto out;
- }
-
- /* load the l2 table in memory */
-
- ret = l2_load(bs, l2_offset, &l2_table);
- if (ret < 0) {
- return ret;
- }
-
- /* find the cluster offset for the given disk offset */
-
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
- *cluster_offset = be64_to_cpu(l2_table[l2_index]);
- nb_clusters = size_to_clusters(s, nb_needed << 9);
-
- ret = qcow2_get_cluster_type(*cluster_offset);
- switch (ret) {
- case QCOW2_CLUSTER_COMPRESSED:
- /* Compressed clusters can only be processed one by one */
- c = 1;
- *cluster_offset &= L2E_COMPRESSED_OFFSET_SIZE_MASK;
- break;
- case QCOW2_CLUSTER_ZERO:
- if (s->qcow_version < 3) {
- return -EIO;
- }
- c = count_contiguous_clusters(nb_clusters, s->cluster_size,
- &l2_table[l2_index], 0,
- QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO);
- *cluster_offset = 0;
- break;
- case QCOW2_CLUSTER_UNALLOCATED:
- /* how many empty clusters ? */
- c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]);
- *cluster_offset = 0;
- break;
- case QCOW2_CLUSTER_NORMAL:
- /* how many allocated clusters ? */
- c = count_contiguous_clusters(nb_clusters, s->cluster_size,
- &l2_table[l2_index], 0,
- QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO);
- *cluster_offset &= L2E_OFFSET_MASK;
- break;
- default:
- abort();
- }
-
- qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
-
- nb_available = (c * s->cluster_sectors);
-
-out:
- if (nb_available > nb_needed)
- nb_available = nb_needed;
-
- *num = nb_available - index_in_cluster;
-
- return ret;
-}
-
-/*
- * get_cluster_table
- *
- * for a given disk offset, load (and allocate if needed)
- * the l2 table.
- *
- * the l2 table offset in the qcow2 file and the cluster index
- * in the l2 table are given to the caller.
- *
- * Returns 0 on success, -errno in failure case
- */
-static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
- uint64_t **new_l2_table,
- int *new_l2_index)
-{
- BDRVQcowState *s = bs->opaque;
- unsigned int l2_index;
- uint64_t l1_index, l2_offset;
- uint64_t *l2_table = NULL;
- int ret;
-
- /* seek the the l2 offset in the l1 table */
-
- l1_index = offset >> (s->l2_bits + s->cluster_bits);
- if (l1_index >= s->l1_size) {
- ret = qcow2_grow_l1_table(bs, l1_index + 1, false);
- if (ret < 0) {
- return ret;
- }
- }
-
- assert(l1_index < s->l1_size);
- l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK;
-
- /* seek the l2 table of the given l2 offset */
-
- if (s->l1_table[l1_index] & QCOW_OFLAG_COPIED) {
- /* load the l2 table in memory */
- ret = l2_load(bs, l2_offset, &l2_table);
- if (ret < 0) {
- return ret;
- }
- } else {
- /* First allocate a new L2 table (and do COW if needed) */
- ret = l2_allocate(bs, l1_index, &l2_table);
- if (ret < 0) {
- return ret;
- }
-
- /* Then decrease the refcount of the old table */
- if (l2_offset) {
- qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t),
- QCOW2_DISCARD_OTHER);
- }
- }
-
- /* find the cluster offset for the given disk offset */
-
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
-
- *new_l2_table = l2_table;
- *new_l2_index = l2_index;
-
- return 0;
-}
-
-/*
- * alloc_compressed_cluster_offset
- *
- * For a given offset of the disk image, return cluster offset in
- * qcow2 file.
- *
- * If the offset is not found, allocate a new compressed cluster.
- *
- * Return the cluster offset if successful,
- * Return 0, otherwise.
- *
- */
-
-uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
- uint64_t offset,
- int compressed_size)
-{
- BDRVQcowState *s = bs->opaque;
- int l2_index, ret;
- uint64_t *l2_table;
- int64_t cluster_offset;
- int nb_csectors;
-
- ret = get_cluster_table(bs, offset, &l2_table, &l2_index);
- if (ret < 0) {
- return 0;
- }
-
- /* Compression can't overwrite anything. Fail if the cluster was already
- * allocated. */
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
- if (cluster_offset & L2E_OFFSET_MASK) {
- qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- return 0;
- }
-
- cluster_offset = qcow2_alloc_bytes(bs, compressed_size);
- if (cluster_offset < 0) {
- qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- return 0;
- }
-
- nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
- (cluster_offset >> 9);
-
- cluster_offset |= QCOW_OFLAG_COMPRESSED |
- ((uint64_t)nb_csectors << s->csize_shift);
-
- /* update L2 table */
-
- /* compressed clusters never have the copied flag */
-
- BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
- qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
- l2_table[l2_index] = cpu_to_be64(cluster_offset);
- ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- if (ret < 0) {
- return 0;
- }
-
- return cluster_offset;
-}
-
-static int perform_cow(BlockDriverState *bs, QCowL2Meta *m, Qcow2COWRegion *r)
-{
- BDRVQcowState *s = bs->opaque;
- int ret;
-
- if (r->nb_sectors == 0) {
- return 0;
- }
-
- qemu_co_mutex_unlock(&s->lock);
- ret = copy_sectors(bs, m->offset / BDRV_SECTOR_SIZE, m->alloc_offset,
- r->offset / BDRV_SECTOR_SIZE,
- r->offset / BDRV_SECTOR_SIZE + r->nb_sectors);
- qemu_co_mutex_lock(&s->lock);
-
- if (ret < 0) {
- return ret;
- }
-
- /*
- * Before we update the L2 table to actually point to the new cluster, we
- * need to be sure that the refcounts have been increased and COW was
- * handled.
- */
- qcow2_cache_depends_on_flush(s->l2_table_cache);
-
- return 0;
-}
-
-int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
-{
- BDRVQcowState *s = bs->opaque;
- int i, j = 0, l2_index, ret;
- uint64_t *old_cluster, *l2_table;
- uint64_t cluster_offset = m->alloc_offset;
-
- trace_qcow2_cluster_link_l2(qemu_coroutine_self(), m->nb_clusters);
- assert(m->nb_clusters > 0);
-
- old_cluster = g_malloc(m->nb_clusters * sizeof(uint64_t));
-
- /* copy content of unmodified sectors */
- ret = perform_cow(bs, m, &m->cow_start);
- if (ret < 0) {
- goto err;
- }
-
- ret = perform_cow(bs, m, &m->cow_end);
- if (ret < 0) {
- goto err;
- }
-
- /* Update L2 table. */
- if (s->use_lazy_refcounts) {
- qcow2_mark_dirty(bs);
- }
- if (qcow2_need_accurate_refcounts(s)) {
- qcow2_cache_set_dependency(bs, s->l2_table_cache,
- s->refcount_block_cache);
- }
-
- ret = get_cluster_table(bs, m->offset, &l2_table, &l2_index);
- if (ret < 0) {
- goto err;
- }
- qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
-
- for (i = 0; i < m->nb_clusters; i++) {
- /* if two concurrent writes happen to the same unallocated cluster
- * each write allocates separate cluster and writes data concurrently.
- * The first one to complete updates l2 table with pointer to its
- * cluster the second one has to do RMW (which is done above by
- * copy_sectors()), update l2 table with its cluster pointer and free
- * old cluster. This is what this loop does */
- if(l2_table[l2_index + i] != 0)
- old_cluster[j++] = l2_table[l2_index + i];
-
- l2_table[l2_index + i] = cpu_to_be64((cluster_offset +
- (i << s->cluster_bits)) | QCOW_OFLAG_COPIED);
- }
-
-
- ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- if (ret < 0) {
- goto err;
- }
-
- /*
- * If this was a COW, we need to decrease the refcount of the old cluster.
- * Also flush bs->file to get the right order for L2 and refcount update.
- *
- * Don't discard clusters that reach a refcount of 0 (e.g. compressed
- * clusters), the next write will reuse them anyway.
- */
- if (j != 0) {
- for (i = 0; i < j; i++) {
- qcow2_free_any_clusters(bs, be64_to_cpu(old_cluster[i]), 1,
- QCOW2_DISCARD_NEVER);
- }
- }
-
- ret = 0;
-err:
- g_free(old_cluster);
- return ret;
- }
-
-/*
- * Returns the number of contiguous clusters that can be used for an allocating
- * write, but require COW to be performed (this includes yet unallocated space,
- * which must copy from the backing file)
- */
-static int count_cow_clusters(BDRVQcowState *s, int nb_clusters,
- uint64_t *l2_table, int l2_index)
-{
- int i;
-
- for (i = 0; i < nb_clusters; i++) {
- uint64_t l2_entry = be64_to_cpu(l2_table[l2_index + i]);
- int cluster_type = qcow2_get_cluster_type(l2_entry);
-
- switch(cluster_type) {
- case QCOW2_CLUSTER_NORMAL:
- if (l2_entry & QCOW_OFLAG_COPIED) {
- goto out;
- }
- break;
- case QCOW2_CLUSTER_UNALLOCATED:
- case QCOW2_CLUSTER_COMPRESSED:
- case QCOW2_CLUSTER_ZERO:
- break;
- default:
- abort();
- }
- }
-
-out:
- assert(i <= nb_clusters);
- return i;
-}
-
-/*
- * Check if there already is an AIO write request in flight which allocates
- * the same cluster. In this case we need to wait until the previous
- * request has completed and updated the L2 table accordingly.
- *
- * Returns:
- * 0 if there was no dependency. *cur_bytes indicates the number of
- * bytes from guest_offset that can be read before the next
- * dependency must be processed (or the request is complete)
- *
- * -EAGAIN if we had to wait for another request, previously gathered
- * information on cluster allocation may be invalid now. The caller
- * must start over anyway, so consider *cur_bytes undefined.
- */
-static int handle_dependencies(BlockDriverState *bs, uint64_t guest_offset,
- uint64_t *cur_bytes, QCowL2Meta **m)
-{
- BDRVQcowState *s = bs->opaque;
- QCowL2Meta *old_alloc;
- uint64_t bytes = *cur_bytes;
-
- QLIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) {
-
- uint64_t start = guest_offset;
- uint64_t end = start + bytes;
- uint64_t old_start = l2meta_cow_start(old_alloc);
- uint64_t old_end = l2meta_cow_end(old_alloc);
-
- if (end <= old_start || start >= old_end) {
- /* No intersection */
- } else {
- if (start < old_start) {
- /* Stop at the start of a running allocation */
- bytes = old_start - start;
- } else {
- bytes = 0;
- }
-
- /* Stop if already an l2meta exists. After yielding, it wouldn't
- * be valid any more, so we'd have to clean up the old L2Metas
- * and deal with requests depending on them before starting to
- * gather new ones. Not worth the trouble. */
- if (bytes == 0 && *m) {
- *cur_bytes = 0;
- return 0;
- }
-
- if (bytes == 0) {
- /* Wait for the dependency to complete. We need to recheck
- * the free/allocated clusters when we continue. */
- qemu_co_mutex_unlock(&s->lock);
- qemu_co_queue_wait(&old_alloc->dependent_requests);
- qemu_co_mutex_lock(&s->lock);
- return -EAGAIN;
- }
- }
- }
-
- /* Make sure that existing clusters and new allocations are only used up to
- * the next dependency if we shortened the request above */
- *cur_bytes = bytes;
-
- return 0;
-}
-
-/*
- * Checks how many already allocated clusters that don't require a copy on
- * write there are at the given guest_offset (up to *bytes). If
- * *host_offset is not zero, only physically contiguous clusters beginning at
- * this host offset are counted.
- *
- * Note that guest_offset may not be cluster aligned. In this case, the
- * returned *host_offset points to exact byte referenced by guest_offset and
- * therefore isn't cluster aligned as well.
- *
- * Returns:
- * 0: if no allocated clusters are available at the given offset.
- * *bytes is normally unchanged. It is set to 0 if the cluster
- * is allocated and doesn't need COW, but doesn't have the right
- * physical offset.
- *
- * 1: if allocated clusters that don't require a COW are available at
- * the requested offset. *bytes may have decreased and describes
- * the length of the area that can be written to.
- *
- * -errno: in error cases
- */
-static int handle_copied(BlockDriverState *bs, uint64_t guest_offset,
- uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m)
-{
- BDRVQcowState *s = bs->opaque;
- int l2_index;
- uint64_t cluster_offset;
- uint64_t *l2_table;
- unsigned int nb_clusters;
- unsigned int keep_clusters;
- int ret, pret;
-
- trace_qcow2_handle_copied(qemu_coroutine_self(), guest_offset, *host_offset,
- *bytes);
-
- assert(*host_offset == 0 || offset_into_cluster(s, guest_offset)
- == offset_into_cluster(s, *host_offset));
-
- /*
- * Calculate the number of clusters to look for. We stop at L2 table
- * boundaries to keep things simple.
- */
- nb_clusters =
- size_to_clusters(s, offset_into_cluster(s, guest_offset) + *bytes);
-
- l2_index = offset_to_l2_index(s, guest_offset);
- nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
-
- /* Find L2 entry for the first involved cluster */
- ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index);
- if (ret < 0) {
- return ret;
- }
-
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
-
- /* Check how many clusters are already allocated and don't need COW */
- if (qcow2_get_cluster_type(cluster_offset) == QCOW2_CLUSTER_NORMAL
- && (cluster_offset & QCOW_OFLAG_COPIED))
- {
- /* If a specific host_offset is required, check it */
- bool offset_matches =
- (cluster_offset & L2E_OFFSET_MASK) == *host_offset;
-
- if (*host_offset != 0 && !offset_matches) {
- *bytes = 0;
- ret = 0;
- goto out;
- }
-
- /* We keep all QCOW_OFLAG_COPIED clusters */
- keep_clusters =
- count_contiguous_clusters(nb_clusters, s->cluster_size,
- &l2_table[l2_index], 0,
- QCOW_OFLAG_COPIED | QCOW_OFLAG_ZERO);
- assert(keep_clusters <= nb_clusters);
-
- *bytes = MIN(*bytes,
- keep_clusters * s->cluster_size
- - offset_into_cluster(s, guest_offset));
-
- ret = 1;
- } else {
- ret = 0;
- }
-
- /* Cleanup */
-out:
- pret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- if (pret < 0) {
- return pret;
- }
-
- /* Only return a host offset if we actually made progress. Otherwise we
- * would make requirements for handle_alloc() that it can't fulfill */
- if (ret) {
- *host_offset = (cluster_offset & L2E_OFFSET_MASK)
- + offset_into_cluster(s, guest_offset);
- }
-
- return ret;
-}
-
-/*
- * Allocates new clusters for the given guest_offset.
- *
- * At most *nb_clusters are allocated, and on return *nb_clusters is updated to
- * contain the number of clusters that have been allocated and are contiguous
- * in the image file.
- *
- * If *host_offset is non-zero, it specifies the offset in the image file at
- * which the new clusters must start. *nb_clusters can be 0 on return in this
- * case if the cluster at host_offset is already in use. If *host_offset is
- * zero, the clusters can be allocated anywhere in the image file.
- *
- * *host_offset is updated to contain the offset into the image file at which
- * the first allocated cluster starts.
- *
- * Return 0 on success and -errno in error cases. -EAGAIN means that the
- * function has been waiting for another request and the allocation must be
- * restarted, but the whole request should not be failed.
- */
-static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
- uint64_t *host_offset, unsigned int *nb_clusters)
-{
- BDRVQcowState *s = bs->opaque;
-
- trace_qcow2_do_alloc_clusters_offset(qemu_coroutine_self(), guest_offset,
- *host_offset, *nb_clusters);
-
- /* Allocate new clusters */
- trace_qcow2_cluster_alloc_phys(qemu_coroutine_self());
- if (*host_offset == 0) {
- int64_t cluster_offset =
- qcow2_alloc_clusters(bs, *nb_clusters * s->cluster_size);
- if (cluster_offset < 0) {
- return cluster_offset;
- }
- *host_offset = cluster_offset;
- return 0;
- } else {
- int ret = qcow2_alloc_clusters_at(bs, *host_offset, *nb_clusters);
- if (ret < 0) {
- return ret;
- }
- *nb_clusters = ret;
- return 0;
- }
-}
-
-/*
- * Allocates new clusters for an area that either is yet unallocated or needs a
- * copy on write. If *host_offset is non-zero, clusters are only allocated if
- * the new allocation can match the specified host offset.
- *
- * Note that guest_offset may not be cluster aligned. In this case, the
- * returned *host_offset points to exact byte referenced by guest_offset and
- * therefore isn't cluster aligned as well.
- *
- * Returns:
- * 0: if no clusters could be allocated. *bytes is set to 0,
- * *host_offset is left unchanged.
- *
- * 1: if new clusters were allocated. *bytes may be decreased if the
- * new allocation doesn't cover all of the requested area.
- * *host_offset is updated to contain the host offset of the first
- * newly allocated cluster.
- *
- * -errno: in error cases
- */
-static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
- uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m)
-{
- BDRVQcowState *s = bs->opaque;
- int l2_index;
- uint64_t *l2_table;
- uint64_t entry;
- unsigned int nb_clusters;
- int ret;
-
- uint64_t alloc_cluster_offset;
-
- trace_qcow2_handle_alloc(qemu_coroutine_self(), guest_offset, *host_offset,
- *bytes);
- assert(*bytes > 0);
-
- /*
- * Calculate the number of clusters to look for. We stop at L2 table
- * boundaries to keep things simple.
- */
- nb_clusters =
- size_to_clusters(s, offset_into_cluster(s, guest_offset) + *bytes);
-
- l2_index = offset_to_l2_index(s, guest_offset);
- nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
-
- /* Find L2 entry for the first involved cluster */
- ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index);
- if (ret < 0) {
- return ret;
- }
-
- entry = be64_to_cpu(l2_table[l2_index]);
-
- /* For the moment, overwrite compressed clusters one by one */
- if (entry & QCOW_OFLAG_COMPRESSED) {
- nb_clusters = 1;
- } else {
- nb_clusters = count_cow_clusters(s, nb_clusters, l2_table, l2_index);
- }
-
- /* This function is only called when there were no non-COW clusters, so if
- * we can't find any unallocated or COW clusters either, something is
- * wrong with our code. */
- assert(nb_clusters > 0);
-
- ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- if (ret < 0) {
- return ret;
- }
-
- /* Allocate, if necessary at a given offset in the image file */
- alloc_cluster_offset = start_of_cluster(s, *host_offset);
- ret = do_alloc_cluster_offset(bs, guest_offset, &alloc_cluster_offset,
- &nb_clusters);
- if (ret < 0) {
- goto fail;
- }
-
- /* Can't extend contiguous allocation */
- if (nb_clusters == 0) {
- *bytes = 0;
- return 0;
- }
-
- /*
- * Save info needed for meta data update.
- *
- * requested_sectors: Number of sectors from the start of the first
- * newly allocated cluster to the end of the (possibly shortened
- * before) write request.
- *
- * avail_sectors: Number of sectors from the start of the first
- * newly allocated to the end of the last newly allocated cluster.
- *
- * nb_sectors: The number of sectors from the start of the first
- * newly allocated cluster to the end of the area that the write
- * request actually writes to (excluding COW at the end)
- */
- int requested_sectors =
- (*bytes + offset_into_cluster(s, guest_offset))
- >> BDRV_SECTOR_BITS;
- int avail_sectors = nb_clusters
- << (s->cluster_bits - BDRV_SECTOR_BITS);
- int alloc_n_start = offset_into_cluster(s, guest_offset)
- >> BDRV_SECTOR_BITS;
- int nb_sectors = MIN(requested_sectors, avail_sectors);
- QCowL2Meta *old_m = *m;
-
- *m = g_malloc0(sizeof(**m));
-
- **m = (QCowL2Meta) {
- .next = old_m,
-
- .alloc_offset = alloc_cluster_offset,
- .offset = start_of_cluster(s, guest_offset),
- .nb_clusters = nb_clusters,
- .nb_available = nb_sectors,
-
- .cow_start = {
- .offset = 0,
- .nb_sectors = alloc_n_start,
- },
- .cow_end = {
- .offset = nb_sectors * BDRV_SECTOR_SIZE,
- .nb_sectors = avail_sectors - nb_sectors,
- },
- };
- qemu_co_queue_init(&(*m)->dependent_requests);
- QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);
-
- *host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset);
- *bytes = MIN(*bytes, (nb_sectors * BDRV_SECTOR_SIZE)
- - offset_into_cluster(s, guest_offset));
- assert(*bytes != 0);
-
- return 1;
-
-fail:
- if (*m && (*m)->nb_clusters > 0) {
- QLIST_REMOVE(*m, next_in_flight);
- }
- return ret;
-}
-
-/*
- * alloc_cluster_offset
- *
- * For a given offset on the virtual disk, find the cluster offset in qcow2
- * file. If the offset is not found, allocate a new cluster.
- *
- * If the cluster was already allocated, m->nb_clusters is set to 0 and
- * other fields in m are meaningless.
- *
- * If the cluster is newly allocated, m->nb_clusters is set to the number of
- * contiguous clusters that have been allocated. In this case, the other
- * fields of m are valid and contain information about the first allocated
- * cluster.
- *
- * If the request conflicts with another write request in flight, the coroutine
- * is queued and will be reentered when the dependency has completed.
- *
- * Return 0 on success and -errno in error cases
- */
-int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
- int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t start, remaining;
- uint64_t cluster_offset;
- uint64_t cur_bytes;
- int ret;
-
- trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset,
- n_start, n_end);
-
- assert(n_start * BDRV_SECTOR_SIZE == offset_into_cluster(s, offset));
- offset = start_of_cluster(s, offset);
-
-again:
- start = offset + (n_start << BDRV_SECTOR_BITS);
- remaining = (n_end - n_start) << BDRV_SECTOR_BITS;
- cluster_offset = 0;
- *host_offset = 0;
- cur_bytes = 0;
- *m = NULL;
-
- while (true) {
-
- if (!*host_offset) {
- *host_offset = start_of_cluster(s, cluster_offset);
- }
-
- assert(remaining >= cur_bytes);
-
- start += cur_bytes;
- remaining -= cur_bytes;
- cluster_offset += cur_bytes;
-
- if (remaining == 0) {
- break;
- }
-
- cur_bytes = remaining;
-
- /*
- * Now start gathering as many contiguous clusters as possible:
- *
- * 1. Check for overlaps with in-flight allocations
- *
- * a) Overlap not in the first cluster -> shorten this request and
- * let the caller handle the rest in its next loop iteration.
- *
- * b) Real overlaps of two requests. Yield and restart the search
- * for contiguous clusters (the situation could have changed
- * while we were sleeping)
- *
- * c) TODO: Request starts in the same cluster as the in-flight
- * allocation ends. Shorten the COW of the in-fight allocation,
- * set cluster_offset to write to the same cluster and set up
- * the right synchronisation between the in-flight request and
- * the new one.
- */
- ret = handle_dependencies(bs, start, &cur_bytes, m);
- if (ret == -EAGAIN) {
- /* Currently handle_dependencies() doesn't yield if we already had
- * an allocation. If it did, we would have to clean up the L2Meta
- * structs before starting over. */
- assert(*m == NULL);
- goto again;
- } else if (ret < 0) {
- return ret;
- } else if (cur_bytes == 0) {
- break;
- } else {
- /* handle_dependencies() may have decreased cur_bytes (shortened
- * the allocations below) so that the next dependency is processed
- * correctly during the next loop iteration. */
- }
-
- /*
- * 2. Count contiguous COPIED clusters.
- */
- ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m);
- if (ret < 0) {
- return ret;
- } else if (ret) {
- continue;
- } else if (cur_bytes == 0) {
- break;
- }
-
- /*
- * 3. If the request still hasn't completed, allocate new clusters,
- * considering any cluster_offset of steps 1c or 2.
- */
- ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m);
- if (ret < 0) {
- return ret;
- } else if (ret) {
- continue;
- } else {
- assert(cur_bytes == 0);
- break;
- }
- }
-
- *num = (n_end - n_start) - (remaining >> BDRV_SECTOR_BITS);
- assert(*num > 0);
- assert(*host_offset != 0);
-
- return 0;
-}
-
-static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
- const uint8_t *buf, int buf_size)
-{
- z_stream strm1, *strm = &strm1;
- int ret, out_len;
-
- memset(strm, 0, sizeof(*strm));
-
- strm->next_in = (uint8_t *)buf;
- strm->avail_in = buf_size;
- strm->next_out = out_buf;
- strm->avail_out = out_buf_size;
-
- ret = inflateInit2(strm, -12);
- if (ret != Z_OK)
- return -1;
- ret = inflate(strm, Z_FINISH);
- out_len = strm->next_out - out_buf;
- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
- out_len != out_buf_size) {
- inflateEnd(strm);
- return -1;
- }
- inflateEnd(strm);
- return 0;
-}
-
-int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, csize, nb_csectors, sector_offset;
- uint64_t coffset;
-
- coffset = cluster_offset & s->cluster_offset_mask;
- if (s->cluster_cache_offset != coffset) {
- nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
- sector_offset = coffset & 511;
- csize = nb_csectors * 512 - sector_offset;
- BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
- ret = bdrv_read(bs->file, coffset >> 9, s->cluster_data, nb_csectors);
- if (ret < 0) {
- return ret;
- }
- if (decompress_buffer(s->cluster_cache, s->cluster_size,
- s->cluster_data + sector_offset, csize) < 0) {
- return -EIO;
- }
- s->cluster_cache_offset = coffset;
- }
- return 0;
-}
-
-/*
- * This discards as many clusters of nb_clusters as possible at once (i.e.
- * all clusters in the same L2 table) and returns the number of discarded
- * clusters.
- */
-static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
- unsigned int nb_clusters)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t *l2_table;
- int l2_index;
- int ret;
- int i;
-
- ret = get_cluster_table(bs, offset, &l2_table, &l2_index);
- if (ret < 0) {
- return ret;
- }
-
- /* Limit nb_clusters to one L2 table */
- nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
-
- for (i = 0; i < nb_clusters; i++) {
- uint64_t old_offset;
-
- old_offset = be64_to_cpu(l2_table[l2_index + i]);
- if ((old_offset & L2E_OFFSET_MASK) == 0) {
- continue;
- }
-
- /* First remove L2 entries */
- qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
- l2_table[l2_index + i] = cpu_to_be64(0);
-
- /* Then decrease the refcount */
- qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST);
- }
-
- ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- if (ret < 0) {
- return ret;
- }
-
- return nb_clusters;
-}
-
-int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
- int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t end_offset;
- unsigned int nb_clusters;
- int ret;
-
- end_offset = offset + (nb_sectors << BDRV_SECTOR_BITS);
-
- /* Round start up and end down */
- offset = align_offset(offset, s->cluster_size);
- end_offset &= ~(s->cluster_size - 1);
-
- if (offset > end_offset) {
- return 0;
- }
-
- nb_clusters = size_to_clusters(s, end_offset - offset);
-
- s->cache_discards = true;
-
- /* Each L2 table is handled by its own loop iteration */
- while (nb_clusters > 0) {
- ret = discard_single_l2(bs, offset, nb_clusters);
- if (ret < 0) {
- goto fail;
- }
-
- nb_clusters -= ret;
- offset += (ret * s->cluster_size);
- }
-
- ret = 0;
-fail:
- s->cache_discards = false;
- qcow2_process_discards(bs, ret);
-
- return ret;
-}
-
-/*
- * This zeroes as many clusters of nb_clusters as possible at once (i.e.
- * all clusters in the same L2 table) and returns the number of zeroed
- * clusters.
- */
-static int zero_single_l2(BlockDriverState *bs, uint64_t offset,
- unsigned int nb_clusters)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t *l2_table;
- int l2_index;
- int ret;
- int i;
-
- ret = get_cluster_table(bs, offset, &l2_table, &l2_index);
- if (ret < 0) {
- return ret;
- }
-
- /* Limit nb_clusters to one L2 table */
- nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
-
- for (i = 0; i < nb_clusters; i++) {
- uint64_t old_offset;
-
- old_offset = be64_to_cpu(l2_table[l2_index + i]);
-
- /* Update L2 entries */
- qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
- if (old_offset & QCOW_OFLAG_COMPRESSED) {
- l2_table[l2_index + i] = cpu_to_be64(QCOW_OFLAG_ZERO);
- qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST);
- } else {
- l2_table[l2_index + i] |= cpu_to_be64(QCOW_OFLAG_ZERO);
- }
- }
-
- ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- if (ret < 0) {
- return ret;
- }
-
- return nb_clusters;
-}
-
-int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- unsigned int nb_clusters;
- int ret;
-
- /* The zero flag is only supported by version 3 and newer */
- if (s->qcow_version < 3) {
- return -ENOTSUP;
- }
-
- /* Each L2 table is handled by its own loop iteration */
- nb_clusters = size_to_clusters(s, nb_sectors << BDRV_SECTOR_BITS);
-
- s->cache_discards = true;
-
- while (nb_clusters > 0) {
- ret = zero_single_l2(bs, offset, nb_clusters);
- if (ret < 0) {
- goto fail;
- }
-
- nb_clusters -= ret;
- offset += (ret * s->cluster_size);
- }
-
- ret = 0;
-fail:
- s->cache_discards = false;
- qcow2_process_discards(bs, ret);
-
- return ret;
-}
diff --git a/contrib/qemu/block/qcow2-refcount.c b/contrib/qemu/block/qcow2-refcount.c
deleted file mode 100644
index 1244693f39e..00000000000
--- a/contrib/qemu/block/qcow2-refcount.c
+++ /dev/null
@@ -1,1374 +0,0 @@
-/*
- * Block driver for the QCOW version 2 format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "block/qcow2.h"
-
-static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size);
-static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length,
- int addend, enum qcow2_discard_type type);
-
-
-/*********************************************************/
-/* refcount handling */
-
-int qcow2_refcount_init(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, refcount_table_size2, i;
-
- refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t);
- s->refcount_table = g_malloc(refcount_table_size2);
- if (s->refcount_table_size > 0) {
- BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD);
- ret = bdrv_pread(bs->file, s->refcount_table_offset,
- s->refcount_table, refcount_table_size2);
- if (ret != refcount_table_size2)
- goto fail;
- for(i = 0; i < s->refcount_table_size; i++)
- be64_to_cpus(&s->refcount_table[i]);
- }
- return 0;
- fail:
- return -ENOMEM;
-}
-
-void qcow2_refcount_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- g_free(s->refcount_table);
-}
-
-
-static int load_refcount_block(BlockDriverState *bs,
- int64_t refcount_block_offset,
- void **refcount_block)
-{
- BDRVQcowState *s = bs->opaque;
- int ret;
-
- BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_LOAD);
- ret = qcow2_cache_get(bs, s->refcount_block_cache, refcount_block_offset,
- refcount_block);
-
- return ret;
-}
-
-/*
- * Returns the refcount of the cluster given by its index. Any non-negative
- * return value is the refcount of the cluster, negative values are -errno
- * and indicate an error.
- */
-static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
-{
- BDRVQcowState *s = bs->opaque;
- int refcount_table_index, block_index;
- int64_t refcount_block_offset;
- int ret;
- uint16_t *refcount_block;
- uint16_t refcount;
-
- refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
- if (refcount_table_index >= s->refcount_table_size)
- return 0;
- refcount_block_offset = s->refcount_table[refcount_table_index];
- if (!refcount_block_offset)
- return 0;
-
- ret = qcow2_cache_get(bs, s->refcount_block_cache, refcount_block_offset,
- (void**) &refcount_block);
- if (ret < 0) {
- return ret;
- }
-
- block_index = cluster_index &
- ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
- refcount = be16_to_cpu(refcount_block[block_index]);
-
- ret = qcow2_cache_put(bs, s->refcount_block_cache,
- (void**) &refcount_block);
- if (ret < 0) {
- return ret;
- }
-
- return refcount;
-}
-
-/*
- * Rounds the refcount table size up to avoid growing the table for each single
- * refcount block that is allocated.
- */
-static unsigned int next_refcount_table_size(BDRVQcowState *s,
- unsigned int min_size)
-{
- unsigned int min_clusters = (min_size >> (s->cluster_bits - 3)) + 1;
- unsigned int refcount_table_clusters =
- MAX(1, s->refcount_table_size >> (s->cluster_bits - 3));
-
- while (min_clusters > refcount_table_clusters) {
- refcount_table_clusters = (refcount_table_clusters * 3 + 1) / 2;
- }
-
- return refcount_table_clusters << (s->cluster_bits - 3);
-}
-
-
-/* Checks if two offsets are described by the same refcount block */
-static int in_same_refcount_block(BDRVQcowState *s, uint64_t offset_a,
- uint64_t offset_b)
-{
- uint64_t block_a = offset_a >> (2 * s->cluster_bits - REFCOUNT_SHIFT);
- uint64_t block_b = offset_b >> (2 * s->cluster_bits - REFCOUNT_SHIFT);
-
- return (block_a == block_b);
-}
-
-/*
- * Loads a refcount block. If it doesn't exist yet, it is allocated first
- * (including growing the refcount table if needed).
- *
- * Returns 0 on success or -errno in error case
- */
-static int alloc_refcount_block(BlockDriverState *bs,
- int64_t cluster_index, uint16_t **refcount_block)
-{
- BDRVQcowState *s = bs->opaque;
- unsigned int refcount_table_index;
- int ret;
-
- BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC);
-
- /* Find the refcount block for the given cluster */
- refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
-
- if (refcount_table_index < s->refcount_table_size) {
-
- uint64_t refcount_block_offset =
- s->refcount_table[refcount_table_index] & REFT_OFFSET_MASK;
-
- /* If it's already there, we're done */
- if (refcount_block_offset) {
- return load_refcount_block(bs, refcount_block_offset,
- (void**) refcount_block);
- }
- }
-
- /*
- * If we came here, we need to allocate something. Something is at least
- * a cluster for the new refcount block. It may also include a new refcount
- * table if the old refcount table is too small.
- *
- * Note that allocating clusters here needs some special care:
- *
- * - We can't use the normal qcow2_alloc_clusters(), it would try to
- * increase the refcount and very likely we would end up with an endless
- * recursion. Instead we must place the refcount blocks in a way that
- * they can describe them themselves.
- *
- * - We need to consider that at this point we are inside update_refcounts
- * and doing the initial refcount increase. This means that some clusters
- * have already been allocated by the caller, but their refcount isn't
- * accurate yet. free_cluster_index tells us where this allocation ends
- * as long as we don't overwrite it by freeing clusters.
- *
- * - alloc_clusters_noref and qcow2_free_clusters may load a different
- * refcount block into the cache
- */
-
- *refcount_block = NULL;
-
- /* We write to the refcount table, so we might depend on L2 tables */
- ret = qcow2_cache_flush(bs, s->l2_table_cache);
- if (ret < 0) {
- return ret;
- }
-
- /* Allocate the refcount block itself and mark it as used */
- int64_t new_block = alloc_clusters_noref(bs, s->cluster_size);
- if (new_block < 0) {
- return new_block;
- }
-
-#ifdef DEBUG_ALLOC2
- fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64
- " at %" PRIx64 "\n",
- refcount_table_index, cluster_index << s->cluster_bits, new_block);
-#endif
-
- if (in_same_refcount_block(s, new_block, cluster_index << s->cluster_bits)) {
- /* Zero the new refcount block before updating it */
- ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,
- (void**) refcount_block);
- if (ret < 0) {
- goto fail_block;
- }
-
- memset(*refcount_block, 0, s->cluster_size);
-
- /* The block describes itself, need to update the cache */
- int block_index = (new_block >> s->cluster_bits) &
- ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
- (*refcount_block)[block_index] = cpu_to_be16(1);
- } else {
- /* Described somewhere else. This can recurse at most twice before we
- * arrive at a block that describes itself. */
- ret = update_refcount(bs, new_block, s->cluster_size, 1,
- QCOW2_DISCARD_NEVER);
- if (ret < 0) {
- goto fail_block;
- }
-
- ret = qcow2_cache_flush(bs, s->refcount_block_cache);
- if (ret < 0) {
- goto fail_block;
- }
-
- /* Initialize the new refcount block only after updating its refcount,
- * update_refcount uses the refcount cache itself */
- ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,
- (void**) refcount_block);
- if (ret < 0) {
- goto fail_block;
- }
-
- memset(*refcount_block, 0, s->cluster_size);
- }
-
- /* Now the new refcount block needs to be written to disk */
- BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE);
- qcow2_cache_entry_mark_dirty(s->refcount_block_cache, *refcount_block);
- ret = qcow2_cache_flush(bs, s->refcount_block_cache);
- if (ret < 0) {
- goto fail_block;
- }
-
- /* If the refcount table is big enough, just hook the block up there */
- if (refcount_table_index < s->refcount_table_size) {
- uint64_t data64 = cpu_to_be64(new_block);
- BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);
- ret = bdrv_pwrite_sync(bs->file,
- s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),
- &data64, sizeof(data64));
- if (ret < 0) {
- goto fail_block;
- }
-
- s->refcount_table[refcount_table_index] = new_block;
- return 0;
- }
-
- ret = qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);
- if (ret < 0) {
- goto fail_block;
- }
-
- /*
- * If we come here, we need to grow the refcount table. Again, a new
- * refcount table needs some space and we can't simply allocate to avoid
- * endless recursion.
- *
- * Therefore let's grab new refcount blocks at the end of the image, which
- * will describe themselves and the new refcount table. This way we can
- * reference them only in the new table and do the switch to the new
- * refcount table at once without producing an inconsistent state in
- * between.
- */
- BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_GROW);
-
- /* Calculate the number of refcount blocks needed so far */
- uint64_t refcount_block_clusters = 1 << (s->cluster_bits - REFCOUNT_SHIFT);
- uint64_t blocks_used = (s->free_cluster_index +
- refcount_block_clusters - 1) / refcount_block_clusters;
-
- /* And now we need at least one block more for the new metadata */
- uint64_t table_size = next_refcount_table_size(s, blocks_used + 1);
- uint64_t last_table_size;
- uint64_t blocks_clusters;
- do {
- uint64_t table_clusters =
- size_to_clusters(s, table_size * sizeof(uint64_t));
- blocks_clusters = 1 +
- ((table_clusters + refcount_block_clusters - 1)
- / refcount_block_clusters);
- uint64_t meta_clusters = table_clusters + blocks_clusters;
-
- last_table_size = table_size;
- table_size = next_refcount_table_size(s, blocks_used +
- ((meta_clusters + refcount_block_clusters - 1)
- / refcount_block_clusters));
-
- } while (last_table_size != table_size);
-
-#ifdef DEBUG_ALLOC2
- fprintf(stderr, "qcow2: Grow refcount table %" PRId32 " => %" PRId64 "\n",
- s->refcount_table_size, table_size);
-#endif
-
- /* Create the new refcount table and blocks */
- uint64_t meta_offset = (blocks_used * refcount_block_clusters) *
- s->cluster_size;
- uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size;
- uint16_t *new_blocks = g_malloc0(blocks_clusters * s->cluster_size);
- uint64_t *new_table = g_malloc0(table_size * sizeof(uint64_t));
-
- assert(meta_offset >= (s->free_cluster_index * s->cluster_size));
-
- /* Fill the new refcount table */
- memcpy(new_table, s->refcount_table,
- s->refcount_table_size * sizeof(uint64_t));
- new_table[refcount_table_index] = new_block;
-
- int i;
- for (i = 0; i < blocks_clusters; i++) {
- new_table[blocks_used + i] = meta_offset + (i * s->cluster_size);
- }
-
- /* Fill the refcount blocks */
- uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t));
- int block = 0;
- for (i = 0; i < table_clusters + blocks_clusters; i++) {
- new_blocks[block++] = cpu_to_be16(1);
- }
-
- /* Write refcount blocks to disk */
- BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS);
- ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks,
- blocks_clusters * s->cluster_size);
- g_free(new_blocks);
- if (ret < 0) {
- goto fail_table;
- }
-
- /* Write refcount table to disk */
- for(i = 0; i < table_size; i++) {
- cpu_to_be64s(&new_table[i]);
- }
-
- BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);
- ret = bdrv_pwrite_sync(bs->file, table_offset, new_table,
- table_size * sizeof(uint64_t));
- if (ret < 0) {
- goto fail_table;
- }
-
- for(i = 0; i < table_size; i++) {
- be64_to_cpus(&new_table[i]);
- }
-
- /* Hook up the new refcount table in the qcow2 header */
- uint8_t data[12];
- cpu_to_be64w((uint64_t*)data, table_offset);
- cpu_to_be32w((uint32_t*)(data + 8), table_clusters);
- BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE);
- ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, refcount_table_offset),
- data, sizeof(data));
- if (ret < 0) {
- goto fail_table;
- }
-
- /* And switch it in memory */
- uint64_t old_table_offset = s->refcount_table_offset;
- uint64_t old_table_size = s->refcount_table_size;
-
- g_free(s->refcount_table);
- s->refcount_table = new_table;
- s->refcount_table_size = table_size;
- s->refcount_table_offset = table_offset;
-
- /* Free old table. Remember, we must not change free_cluster_index */
- uint64_t old_free_cluster_index = s->free_cluster_index;
- qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t),
- QCOW2_DISCARD_OTHER);
- s->free_cluster_index = old_free_cluster_index;
-
- ret = load_refcount_block(bs, new_block, (void**) refcount_block);
- if (ret < 0) {
- return ret;
- }
-
- return 0;
-
-fail_table:
- g_free(new_table);
-fail_block:
- if (*refcount_block != NULL) {
- qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);
- }
- return ret;
-}
-
-void qcow2_process_discards(BlockDriverState *bs, int ret)
-{
- BDRVQcowState *s = bs->opaque;
- Qcow2DiscardRegion *d, *next;
-
- QTAILQ_FOREACH_SAFE(d, &s->discards, next, next) {
- QTAILQ_REMOVE(&s->discards, d, next);
-
- /* Discard is optional, ignore the return value */
- if (ret >= 0) {
- bdrv_discard(bs->file,
- d->offset >> BDRV_SECTOR_BITS,
- d->bytes >> BDRV_SECTOR_BITS);
- }
-
- g_free(d);
- }
-}
-
-static void update_refcount_discard(BlockDriverState *bs,
- uint64_t offset, uint64_t length)
-{
- BDRVQcowState *s = bs->opaque;
- Qcow2DiscardRegion *d, *p, *next;
-
- QTAILQ_FOREACH(d, &s->discards, next) {
- uint64_t new_start = MIN(offset, d->offset);
- uint64_t new_end = MAX(offset + length, d->offset + d->bytes);
-
- if (new_end - new_start <= length + d->bytes) {
- /* There can't be any overlap, areas ending up here have no
- * references any more and therefore shouldn't get freed another
- * time. */
- assert(d->bytes + length == new_end - new_start);
- d->offset = new_start;
- d->bytes = new_end - new_start;
- goto found;
- }
- }
-
- d = g_malloc(sizeof(*d));
- *d = (Qcow2DiscardRegion) {
- .bs = bs,
- .offset = offset,
- .bytes = length,
- };
- QTAILQ_INSERT_TAIL(&s->discards, d, next);
-
-found:
- /* Merge discard requests if they are adjacent now */
- QTAILQ_FOREACH_SAFE(p, &s->discards, next, next) {
- if (p == d
- || p->offset > d->offset + d->bytes
- || d->offset > p->offset + p->bytes)
- {
- continue;
- }
-
- /* Still no overlap possible */
- assert(p->offset == d->offset + d->bytes
- || d->offset == p->offset + p->bytes);
-
- QTAILQ_REMOVE(&s->discards, p, next);
- d->offset = MIN(d->offset, p->offset);
- d->bytes += p->bytes;
- }
-}
-
-/* XXX: cache several refcount block clusters ? */
-static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
- int64_t offset, int64_t length, int addend, enum qcow2_discard_type type)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t start, last, cluster_offset;
- uint16_t *refcount_block = NULL;
- int64_t old_table_index = -1;
- int ret;
-
-#ifdef DEBUG_ALLOC2
- fprintf(stderr, "update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n",
- offset, length, addend);
-#endif
- if (length < 0) {
- return -EINVAL;
- } else if (length == 0) {
- return 0;
- }
-
- if (addend < 0) {
- qcow2_cache_set_dependency(bs, s->refcount_block_cache,
- s->l2_table_cache);
- }
-
- start = offset & ~(s->cluster_size - 1);
- last = (offset + length - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
- cluster_offset += s->cluster_size)
- {
- int block_index, refcount;
- int64_t cluster_index = cluster_offset >> s->cluster_bits;
- int64_t table_index =
- cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
-
- /* Load the refcount block and allocate it if needed */
- if (table_index != old_table_index) {
- if (refcount_block) {
- ret = qcow2_cache_put(bs, s->refcount_block_cache,
- (void**) &refcount_block);
- if (ret < 0) {
- goto fail;
- }
- }
-
- ret = alloc_refcount_block(bs, cluster_index, &refcount_block);
- if (ret < 0) {
- goto fail;
- }
- }
- old_table_index = table_index;
-
- qcow2_cache_entry_mark_dirty(s->refcount_block_cache, refcount_block);
-
- /* we can update the count and save it */
- block_index = cluster_index &
- ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
-
- refcount = be16_to_cpu(refcount_block[block_index]);
- refcount += addend;
- if (refcount < 0 || refcount > 0xffff) {
- ret = -EINVAL;
- goto fail;
- }
- if (refcount == 0 && cluster_index < s->free_cluster_index) {
- s->free_cluster_index = cluster_index;
- }
- refcount_block[block_index] = cpu_to_be16(refcount);
-
- if (refcount == 0 && s->discard_passthrough[type]) {
- update_refcount_discard(bs, cluster_offset, s->cluster_size);
- }
- }
-
- ret = 0;
-fail:
- if (!s->cache_discards) {
- qcow2_process_discards(bs, ret);
- }
-
- /* Write last changed block to disk */
- if (refcount_block) {
- int wret;
- wret = qcow2_cache_put(bs, s->refcount_block_cache,
- (void**) &refcount_block);
- if (wret < 0) {
- return ret < 0 ? ret : wret;
- }
- }
-
- /*
- * Try do undo any updates if an error is returned (This may succeed in
- * some cases like ENOSPC for allocating a new refcount block)
- */
- if (ret < 0) {
- int dummy;
- dummy = update_refcount(bs, offset, cluster_offset - offset, -addend,
- QCOW2_DISCARD_NEVER);
- (void)dummy;
- }
-
- return ret;
-}
-
-/*
- * Increases or decreases the refcount of a given cluster by one.
- * addend must be 1 or -1.
- *
- * If the return value is non-negative, it is the new refcount of the cluster.
- * If it is negative, it is -errno and indicates an error.
- */
-static int update_cluster_refcount(BlockDriverState *bs,
- int64_t cluster_index,
- int addend,
- enum qcow2_discard_type type)
-{
- BDRVQcowState *s = bs->opaque;
- int ret;
-
- ret = update_refcount(bs, cluster_index << s->cluster_bits, 1, addend,
- type);
- if (ret < 0) {
- return ret;
- }
-
- return get_refcount(bs, cluster_index);
-}
-
-
-
-/*********************************************************/
-/* cluster allocation functions */
-
-
-
-/* return < 0 if error */
-static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size)
-{
- BDRVQcowState *s = bs->opaque;
- int i, nb_clusters, refcount;
-
- nb_clusters = size_to_clusters(s, size);
-retry:
- for(i = 0; i < nb_clusters; i++) {
- int64_t next_cluster_index = s->free_cluster_index++;
- refcount = get_refcount(bs, next_cluster_index);
-
- if (refcount < 0) {
- return refcount;
- } else if (refcount != 0) {
- goto retry;
- }
- }
-#ifdef DEBUG_ALLOC2
- fprintf(stderr, "alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",
- size,
- (s->free_cluster_index - nb_clusters) << s->cluster_bits);
-#endif
- return (s->free_cluster_index - nb_clusters) << s->cluster_bits;
-}
-
-int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size)
-{
- int64_t offset;
- int ret;
-
- BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC);
- offset = alloc_clusters_noref(bs, size);
- if (offset < 0) {
- return offset;
- }
-
- ret = update_refcount(bs, offset, size, 1, QCOW2_DISCARD_NEVER);
- if (ret < 0) {
- return ret;
- }
-
- return offset;
-}
-
-int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
- int nb_clusters)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t cluster_index;
- uint64_t old_free_cluster_index;
- int i, refcount, ret;
-
- /* Check how many clusters there are free */
- cluster_index = offset >> s->cluster_bits;
- for(i = 0; i < nb_clusters; i++) {
- refcount = get_refcount(bs, cluster_index++);
-
- if (refcount < 0) {
- return refcount;
- } else if (refcount != 0) {
- break;
- }
- }
-
- /* And then allocate them */
- old_free_cluster_index = s->free_cluster_index;
- s->free_cluster_index = cluster_index + i;
-
- ret = update_refcount(bs, offset, i << s->cluster_bits, 1,
- QCOW2_DISCARD_NEVER);
- if (ret < 0) {
- return ret;
- }
-
- s->free_cluster_index = old_free_cluster_index;
-
- return i;
-}
-
-/* only used to allocate compressed sectors. We try to allocate
- contiguous sectors. size must be <= cluster_size */
-int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t offset, cluster_offset;
- int free_in_cluster;
-
- BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_BYTES);
- assert(size > 0 && size <= s->cluster_size);
- if (s->free_byte_offset == 0) {
- offset = qcow2_alloc_clusters(bs, s->cluster_size);
- if (offset < 0) {
- return offset;
- }
- s->free_byte_offset = offset;
- }
- redo:
- free_in_cluster = s->cluster_size -
- (s->free_byte_offset & (s->cluster_size - 1));
- if (size <= free_in_cluster) {
- /* enough space in current cluster */
- offset = s->free_byte_offset;
- s->free_byte_offset += size;
- free_in_cluster -= size;
- if (free_in_cluster == 0)
- s->free_byte_offset = 0;
- if ((offset & (s->cluster_size - 1)) != 0)
- update_cluster_refcount(bs, offset >> s->cluster_bits, 1,
- QCOW2_DISCARD_NEVER);
- } else {
- offset = qcow2_alloc_clusters(bs, s->cluster_size);
- if (offset < 0) {
- return offset;
- }
- cluster_offset = s->free_byte_offset & ~(s->cluster_size - 1);
- if ((cluster_offset + s->cluster_size) == offset) {
- /* we are lucky: contiguous data */
- offset = s->free_byte_offset;
- update_cluster_refcount(bs, offset >> s->cluster_bits, 1,
- QCOW2_DISCARD_NEVER);
- s->free_byte_offset += size;
- } else {
- s->free_byte_offset = offset;
- goto redo;
- }
- }
-
- /* The cluster refcount was incremented, either by qcow2_alloc_clusters()
- * or explicitly by update_cluster_refcount(). Refcount blocks must be
- * flushed before the caller's L2 table updates.
- */
- qcow2_cache_set_dependency(bs, s->l2_table_cache, s->refcount_block_cache);
- return offset;
-}
-
-void qcow2_free_clusters(BlockDriverState *bs,
- int64_t offset, int64_t size,
- enum qcow2_discard_type type)
-{
- int ret;
-
- BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_FREE);
- ret = update_refcount(bs, offset, size, -1, type);
- if (ret < 0) {
- fprintf(stderr, "qcow2_free_clusters failed: %s\n", strerror(-ret));
- /* TODO Remember the clusters to free them later and avoid leaking */
- }
-}
-
-/*
- * Free a cluster using its L2 entry (handles clusters of all types, e.g.
- * normal cluster, compressed cluster, etc.)
- */
-void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t l2_entry,
- int nb_clusters, enum qcow2_discard_type type)
-{
- BDRVQcowState *s = bs->opaque;
-
- switch (qcow2_get_cluster_type(l2_entry)) {
- case QCOW2_CLUSTER_COMPRESSED:
- {
- int nb_csectors;
- nb_csectors = ((l2_entry >> s->csize_shift) &
- s->csize_mask) + 1;
- qcow2_free_clusters(bs,
- (l2_entry & s->cluster_offset_mask) & ~511,
- nb_csectors * 512, type);
- }
- break;
- case QCOW2_CLUSTER_NORMAL:
- qcow2_free_clusters(bs, l2_entry & L2E_OFFSET_MASK,
- nb_clusters << s->cluster_bits, type);
- break;
- case QCOW2_CLUSTER_UNALLOCATED:
- case QCOW2_CLUSTER_ZERO:
- break;
- default:
- abort();
- }
-}
-
-
-
-/*********************************************************/
-/* snapshots and image creation */
-
-
-
-/* update the refcounts of snapshots and the copied flag */
-int qcow2_update_snapshot_refcount(BlockDriverState *bs,
- int64_t l1_table_offset, int l1_size, int addend)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t *l1_table, *l2_table, l2_offset, offset, l1_size2, l1_allocated;
- int64_t old_offset, old_l2_offset;
- int i, j, l1_modified = 0, nb_csectors, refcount;
- int ret;
-
- l2_table = NULL;
- l1_table = NULL;
- l1_size2 = l1_size * sizeof(uint64_t);
-
- s->cache_discards = true;
-
- /* WARNING: qcow2_snapshot_goto relies on this function not using the
- * l1_table_offset when it is the current s->l1_table_offset! Be careful
- * when changing this! */
- if (l1_table_offset != s->l1_table_offset) {
- l1_table = g_malloc0(align_offset(l1_size2, 512));
- l1_allocated = 1;
-
- ret = bdrv_pread(bs->file, l1_table_offset, l1_table, l1_size2);
- if (ret < 0) {
- goto fail;
- }
-
- for(i = 0;i < l1_size; i++)
- be64_to_cpus(&l1_table[i]);
- } else {
- assert(l1_size == s->l1_size);
- l1_table = s->l1_table;
- l1_allocated = 0;
- }
-
- for(i = 0; i < l1_size; i++) {
- l2_offset = l1_table[i];
- if (l2_offset) {
- old_l2_offset = l2_offset;
- l2_offset &= L1E_OFFSET_MASK;
-
- ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset,
- (void**) &l2_table);
- if (ret < 0) {
- goto fail;
- }
-
- for(j = 0; j < s->l2_size; j++) {
- offset = be64_to_cpu(l2_table[j]);
- if (offset != 0) {
- old_offset = offset;
- offset &= ~QCOW_OFLAG_COPIED;
- if (offset & QCOW_OFLAG_COMPRESSED) {
- nb_csectors = ((offset >> s->csize_shift) &
- s->csize_mask) + 1;
- if (addend != 0) {
- int ret;
- ret = update_refcount(bs,
- (offset & s->cluster_offset_mask) & ~511,
- nb_csectors * 512, addend,
- QCOW2_DISCARD_SNAPSHOT);
- if (ret < 0) {
- goto fail;
- }
- }
- /* compressed clusters are never modified */
- refcount = 2;
- } else {
- uint64_t cluster_index = (offset & L2E_OFFSET_MASK) >> s->cluster_bits;
- if (addend != 0) {
- refcount = update_cluster_refcount(bs, cluster_index, addend,
- QCOW2_DISCARD_SNAPSHOT);
- } else {
- refcount = get_refcount(bs, cluster_index);
- }
-
- if (refcount < 0) {
- ret = refcount;
- goto fail;
- }
- }
-
- if (refcount == 1) {
- offset |= QCOW_OFLAG_COPIED;
- }
- if (offset != old_offset) {
- if (addend > 0) {
- qcow2_cache_set_dependency(bs, s->l2_table_cache,
- s->refcount_block_cache);
- }
- l2_table[j] = cpu_to_be64(offset);
- qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
- }
- }
- }
-
- ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- if (ret < 0) {
- goto fail;
- }
-
-
- if (addend != 0) {
- refcount = update_cluster_refcount(bs, l2_offset >> s->cluster_bits, addend,
- QCOW2_DISCARD_SNAPSHOT);
- } else {
- refcount = get_refcount(bs, l2_offset >> s->cluster_bits);
- }
- if (refcount < 0) {
- ret = refcount;
- goto fail;
- } else if (refcount == 1) {
- l2_offset |= QCOW_OFLAG_COPIED;
- }
- if (l2_offset != old_l2_offset) {
- l1_table[i] = l2_offset;
- l1_modified = 1;
- }
- }
- }
-
- ret = bdrv_flush(bs);
-fail:
- if (l2_table) {
- qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
- }
-
- s->cache_discards = false;
- qcow2_process_discards(bs, ret);
-
- /* Update L1 only if it isn't deleted anyway (addend = -1) */
- if (ret == 0 && addend >= 0 && l1_modified) {
- for (i = 0; i < l1_size; i++) {
- cpu_to_be64s(&l1_table[i]);
- }
-
- ret = bdrv_pwrite_sync(bs->file, l1_table_offset, l1_table, l1_size2);
-
- for (i = 0; i < l1_size; i++) {
- be64_to_cpus(&l1_table[i]);
- }
- }
- if (l1_allocated)
- g_free(l1_table);
- return ret;
-}
-
-
-
-
-/*********************************************************/
-/* refcount checking functions */
-
-
-
-/*
- * Increases the refcount for a range of clusters in a given refcount table.
- * This is used to construct a temporary refcount table out of L1 and L2 tables
- * which can be compared the the refcount table saved in the image.
- *
- * Modifies the number of errors in res.
- */
-static void inc_refcounts(BlockDriverState *bs,
- BdrvCheckResult *res,
- uint16_t *refcount_table,
- int refcount_table_size,
- int64_t offset, int64_t size)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t start, last, cluster_offset;
- int k;
-
- if (size <= 0)
- return;
-
- start = offset & ~(s->cluster_size - 1);
- last = (offset + size - 1) & ~(s->cluster_size - 1);
- for(cluster_offset = start; cluster_offset <= last;
- cluster_offset += s->cluster_size) {
- k = cluster_offset >> s->cluster_bits;
- if (k < 0) {
- fprintf(stderr, "ERROR: invalid cluster offset=0x%" PRIx64 "\n",
- cluster_offset);
- res->corruptions++;
- } else if (k >= refcount_table_size) {
- fprintf(stderr, "Warning: cluster offset=0x%" PRIx64 " is after "
- "the end of the image file, can't properly check refcounts.\n",
- cluster_offset);
- res->check_errors++;
- } else {
- if (++refcount_table[k] == 0) {
- fprintf(stderr, "ERROR: overflow cluster offset=0x%" PRIx64
- "\n", cluster_offset);
- res->corruptions++;
- }
- }
- }
-}
-
-/* Flags for check_refcounts_l1() and check_refcounts_l2() */
-enum {
- CHECK_OFLAG_COPIED = 0x1, /* check QCOW_OFLAG_COPIED matches refcount */
- CHECK_FRAG_INFO = 0x2, /* update BlockFragInfo counters */
-};
-
-/*
- * Increases the refcount in the given refcount table for the all clusters
- * referenced in the L2 table. While doing so, performs some checks on L2
- * entries.
- *
- * Returns the number of errors found by the checks or -errno if an internal
- * error occurred.
- */
-static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
- uint16_t *refcount_table, int refcount_table_size, int64_t l2_offset,
- int flags)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t *l2_table, l2_entry;
- uint64_t next_contiguous_offset = 0;
- int i, l2_size, nb_csectors, refcount;
-
- /* Read L2 table from disk */
- l2_size = s->l2_size * sizeof(uint64_t);
- l2_table = g_malloc(l2_size);
-
- if (bdrv_pread(bs->file, l2_offset, l2_table, l2_size) != l2_size)
- goto fail;
-
- /* Do the actual checks */
- for(i = 0; i < s->l2_size; i++) {
- l2_entry = be64_to_cpu(l2_table[i]);
-
- switch (qcow2_get_cluster_type(l2_entry)) {
- case QCOW2_CLUSTER_COMPRESSED:
- /* Compressed clusters don't have QCOW_OFLAG_COPIED */
- if (l2_entry & QCOW_OFLAG_COPIED) {
- fprintf(stderr, "ERROR: cluster %" PRId64 ": "
- "copied flag must never be set for compressed "
- "clusters\n", l2_entry >> s->cluster_bits);
- l2_entry &= ~QCOW_OFLAG_COPIED;
- res->corruptions++;
- }
-
- /* Mark cluster as used */
- nb_csectors = ((l2_entry >> s->csize_shift) &
- s->csize_mask) + 1;
- l2_entry &= s->cluster_offset_mask;
- inc_refcounts(bs, res, refcount_table, refcount_table_size,
- l2_entry & ~511, nb_csectors * 512);
-
- if (flags & CHECK_FRAG_INFO) {
- res->bfi.allocated_clusters++;
- res->bfi.compressed_clusters++;
-
- /* Compressed clusters are fragmented by nature. Since they
- * take up sub-sector space but we only have sector granularity
- * I/O we need to re-read the same sectors even for adjacent
- * compressed clusters.
- */
- res->bfi.fragmented_clusters++;
- }
- break;
-
- case QCOW2_CLUSTER_ZERO:
- if ((l2_entry & L2E_OFFSET_MASK) == 0) {
- break;
- }
- /* fall through */
-
- case QCOW2_CLUSTER_NORMAL:
- {
- /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
- uint64_t offset = l2_entry & L2E_OFFSET_MASK;
-
- if (flags & CHECK_OFLAG_COPIED) {
- refcount = get_refcount(bs, offset >> s->cluster_bits);
- if (refcount < 0) {
- fprintf(stderr, "Can't get refcount for offset %"
- PRIx64 ": %s\n", l2_entry, strerror(-refcount));
- goto fail;
- }
- if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
- fprintf(stderr, "ERROR OFLAG_COPIED: offset=%"
- PRIx64 " refcount=%d\n", l2_entry, refcount);
- res->corruptions++;
- }
- }
-
- if (flags & CHECK_FRAG_INFO) {
- res->bfi.allocated_clusters++;
- if (next_contiguous_offset &&
- offset != next_contiguous_offset) {
- res->bfi.fragmented_clusters++;
- }
- next_contiguous_offset = offset + s->cluster_size;
- }
-
- /* Mark cluster as used */
- inc_refcounts(bs, res, refcount_table,refcount_table_size,
- offset, s->cluster_size);
-
- /* Correct offsets are cluster aligned */
- if (offset & (s->cluster_size - 1)) {
- fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "
- "properly aligned; L2 entry corrupted.\n", offset);
- res->corruptions++;
- }
- break;
- }
-
- case QCOW2_CLUSTER_UNALLOCATED:
- break;
-
- default:
- abort();
- }
- }
-
- g_free(l2_table);
- return 0;
-
-fail:
- fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n");
- g_free(l2_table);
- return -EIO;
-}
-
-/*
- * Increases the refcount for the L1 table, its L2 tables and all referenced
- * clusters in the given refcount table. While doing so, performs some checks
- * on L1 and L2 entries.
- *
- * Returns the number of errors found by the checks or -errno if an internal
- * error occurred.
- */
-static int check_refcounts_l1(BlockDriverState *bs,
- BdrvCheckResult *res,
- uint16_t *refcount_table,
- int refcount_table_size,
- int64_t l1_table_offset, int l1_size,
- int flags)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t *l1_table, l2_offset, l1_size2;
- int i, refcount, ret;
-
- l1_size2 = l1_size * sizeof(uint64_t);
-
- /* Mark L1 table as used */
- inc_refcounts(bs, res, refcount_table, refcount_table_size,
- l1_table_offset, l1_size2);
-
- /* Read L1 table entries from disk */
- if (l1_size2 == 0) {
- l1_table = NULL;
- } else {
- l1_table = g_malloc(l1_size2);
- if (bdrv_pread(bs->file, l1_table_offset,
- l1_table, l1_size2) != l1_size2)
- goto fail;
- for(i = 0;i < l1_size; i++)
- be64_to_cpus(&l1_table[i]);
- }
-
- /* Do the actual checks */
- for(i = 0; i < l1_size; i++) {
- l2_offset = l1_table[i];
- if (l2_offset) {
- /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
- if (flags & CHECK_OFLAG_COPIED) {
- refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED)
- >> s->cluster_bits);
- if (refcount < 0) {
- fprintf(stderr, "Can't get refcount for l2_offset %"
- PRIx64 ": %s\n", l2_offset, strerror(-refcount));
- goto fail;
- }
- if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) {
- fprintf(stderr, "ERROR OFLAG_COPIED: l2_offset=%" PRIx64
- " refcount=%d\n", l2_offset, refcount);
- res->corruptions++;
- }
- }
-
- /* Mark L2 table as used */
- l2_offset &= L1E_OFFSET_MASK;
- inc_refcounts(bs, res, refcount_table, refcount_table_size,
- l2_offset, s->cluster_size);
-
- /* L2 tables are cluster aligned */
- if (l2_offset & (s->cluster_size - 1)) {
- fprintf(stderr, "ERROR l2_offset=%" PRIx64 ": Table is not "
- "cluster aligned; L1 entry corrupted\n", l2_offset);
- res->corruptions++;
- }
-
- /* Process and check L2 entries */
- ret = check_refcounts_l2(bs, res, refcount_table,
- refcount_table_size, l2_offset, flags);
- if (ret < 0) {
- goto fail;
- }
- }
- }
- g_free(l1_table);
- return 0;
-
-fail:
- fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");
- res->check_errors++;
- g_free(l1_table);
- return -EIO;
-}
-
-/*
- * Checks an image for refcount consistency.
- *
- * Returns 0 if no errors are found, the number of errors in case the image is
- * detected as corrupted, and -errno when an internal error occurred.
- */
-int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
- BdrvCheckMode fix)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t size, i, highest_cluster;
- int nb_clusters, refcount1, refcount2;
- QCowSnapshot *sn;
- uint16_t *refcount_table;
- int ret;
-
- size = bdrv_getlength(bs->file);
- nb_clusters = size_to_clusters(s, size);
- refcount_table = g_malloc0(nb_clusters * sizeof(uint16_t));
-
- res->bfi.total_clusters =
- size_to_clusters(s, bs->total_sectors * BDRV_SECTOR_SIZE);
-
- /* header */
- inc_refcounts(bs, res, refcount_table, nb_clusters,
- 0, s->cluster_size);
-
- /* current L1 table */
- ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
- s->l1_table_offset, s->l1_size,
- CHECK_OFLAG_COPIED | CHECK_FRAG_INFO);
- if (ret < 0) {
- goto fail;
- }
-
- /* snapshots */
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
- sn->l1_table_offset, sn->l1_size, 0);
- if (ret < 0) {
- goto fail;
- }
- }
- inc_refcounts(bs, res, refcount_table, nb_clusters,
- s->snapshots_offset, s->snapshots_size);
-
- /* refcount data */
- inc_refcounts(bs, res, refcount_table, nb_clusters,
- s->refcount_table_offset,
- s->refcount_table_size * sizeof(uint64_t));
-
- for(i = 0; i < s->refcount_table_size; i++) {
- uint64_t offset, cluster;
- offset = s->refcount_table[i];
- cluster = offset >> s->cluster_bits;
-
- /* Refcount blocks are cluster aligned */
- if (offset & (s->cluster_size - 1)) {
- fprintf(stderr, "ERROR refcount block %" PRId64 " is not "
- "cluster aligned; refcount table entry corrupted\n", i);
- res->corruptions++;
- continue;
- }
-
- if (cluster >= nb_clusters) {
- fprintf(stderr, "ERROR refcount block %" PRId64
- " is outside image\n", i);
- res->corruptions++;
- continue;
- }
-
- if (offset != 0) {
- inc_refcounts(bs, res, refcount_table, nb_clusters,
- offset, s->cluster_size);
- if (refcount_table[cluster] != 1) {
- fprintf(stderr, "ERROR refcount block %" PRId64
- " refcount=%d\n",
- i, refcount_table[cluster]);
- res->corruptions++;
- }
- }
- }
-
- /* compare ref counts */
- for (i = 0, highest_cluster = 0; i < nb_clusters; i++) {
- refcount1 = get_refcount(bs, i);
- if (refcount1 < 0) {
- fprintf(stderr, "Can't get refcount for cluster %" PRId64 ": %s\n",
- i, strerror(-refcount1));
- res->check_errors++;
- continue;
- }
-
- refcount2 = refcount_table[i];
-
- if (refcount1 > 0 || refcount2 > 0) {
- highest_cluster = i;
- }
-
- if (refcount1 != refcount2) {
-
- /* Check if we're allowed to fix the mismatch */
- int *num_fixed = NULL;
- if (refcount1 > refcount2 && (fix & BDRV_FIX_LEAKS)) {
- num_fixed = &res->leaks_fixed;
- } else if (refcount1 < refcount2 && (fix & BDRV_FIX_ERRORS)) {
- num_fixed = &res->corruptions_fixed;
- }
-
- fprintf(stderr, "%s cluster %" PRId64 " refcount=%d reference=%d\n",
- num_fixed != NULL ? "Repairing" :
- refcount1 < refcount2 ? "ERROR" :
- "Leaked",
- i, refcount1, refcount2);
-
- if (num_fixed) {
- ret = update_refcount(bs, i << s->cluster_bits, 1,
- refcount2 - refcount1,
- QCOW2_DISCARD_ALWAYS);
- if (ret >= 0) {
- (*num_fixed)++;
- continue;
- }
- }
-
- /* And if we couldn't, print an error */
- if (refcount1 < refcount2) {
- res->corruptions++;
- } else {
- res->leaks++;
- }
- }
- }
-
- res->image_end_offset = (highest_cluster + 1) * s->cluster_size;
- ret = 0;
-
-fail:
- g_free(refcount_table);
-
- return ret;
-}
-
diff --git a/contrib/qemu/block/qcow2-snapshot.c b/contrib/qemu/block/qcow2-snapshot.c
deleted file mode 100644
index 0caac9055f8..00000000000
--- a/contrib/qemu/block/qcow2-snapshot.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * Block driver for the QCOW version 2 format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "block/qcow2.h"
-
-typedef struct QEMU_PACKED QCowSnapshotHeader {
- /* header is 8 byte aligned */
- uint64_t l1_table_offset;
-
- uint32_t l1_size;
- uint16_t id_str_size;
- uint16_t name_size;
-
- uint32_t date_sec;
- uint32_t date_nsec;
-
- uint64_t vm_clock_nsec;
-
- uint32_t vm_state_size;
- uint32_t extra_data_size; /* for extension */
- /* extra data follows */
- /* id_str follows */
- /* name follows */
-} QCowSnapshotHeader;
-
-typedef struct QEMU_PACKED QCowSnapshotExtraData {
- uint64_t vm_state_size_large;
- uint64_t disk_size;
-} QCowSnapshotExtraData;
-
-void qcow2_free_snapshots(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int i;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- g_free(s->snapshots[i].name);
- g_free(s->snapshots[i].id_str);
- }
- g_free(s->snapshots);
- s->snapshots = NULL;
- s->nb_snapshots = 0;
-}
-
-int qcow2_read_snapshots(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshotHeader h;
- QCowSnapshotExtraData extra;
- QCowSnapshot *sn;
- int i, id_str_size, name_size;
- int64_t offset;
- uint32_t extra_data_size;
- int ret;
-
- if (!s->nb_snapshots) {
- s->snapshots = NULL;
- s->snapshots_size = 0;
- return 0;
- }
-
- offset = s->snapshots_offset;
- s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot));
-
- for(i = 0; i < s->nb_snapshots; i++) {
- /* Read statically sized part of the snapshot header */
- offset = align_offset(offset, 8);
- ret = bdrv_pread(bs->file, offset, &h, sizeof(h));
- if (ret < 0) {
- goto fail;
- }
-
- offset += sizeof(h);
- sn = s->snapshots + i;
- sn->l1_table_offset = be64_to_cpu(h.l1_table_offset);
- sn->l1_size = be32_to_cpu(h.l1_size);
- sn->vm_state_size = be32_to_cpu(h.vm_state_size);
- sn->date_sec = be32_to_cpu(h.date_sec);
- sn->date_nsec = be32_to_cpu(h.date_nsec);
- sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec);
- extra_data_size = be32_to_cpu(h.extra_data_size);
-
- id_str_size = be16_to_cpu(h.id_str_size);
- name_size = be16_to_cpu(h.name_size);
-
- /* Read extra data */
- ret = bdrv_pread(bs->file, offset, &extra,
- MIN(sizeof(extra), extra_data_size));
- if (ret < 0) {
- goto fail;
- }
- offset += extra_data_size;
-
- if (extra_data_size >= 8) {
- sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large);
- }
-
- if (extra_data_size >= 16) {
- sn->disk_size = be64_to_cpu(extra.disk_size);
- } else {
- sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
- }
-
- /* Read snapshot ID */
- sn->id_str = g_malloc(id_str_size + 1);
- ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size);
- if (ret < 0) {
- goto fail;
- }
- offset += id_str_size;
- sn->id_str[id_str_size] = '\0';
-
- /* Read snapshot name */
- sn->name = g_malloc(name_size + 1);
- ret = bdrv_pread(bs->file, offset, sn->name, name_size);
- if (ret < 0) {
- goto fail;
- }
- offset += name_size;
- sn->name[name_size] = '\0';
- }
-
- s->snapshots_size = offset - s->snapshots_offset;
- return 0;
-
-fail:
- qcow2_free_snapshots(bs);
- return ret;
-}
-
-/* add at the end of the file a new list of snapshots */
-static int qcow2_write_snapshots(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- QCowSnapshotHeader h;
- QCowSnapshotExtraData extra;
- int i, name_size, id_str_size, snapshots_size;
- struct {
- uint32_t nb_snapshots;
- uint64_t snapshots_offset;
- } QEMU_PACKED header_data;
- int64_t offset, snapshots_offset;
- int ret;
-
- /* compute the size of the snapshots */
- offset = 0;
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- offset = align_offset(offset, 8);
- offset += sizeof(h);
- offset += sizeof(extra);
- offset += strlen(sn->id_str);
- offset += strlen(sn->name);
- }
- snapshots_size = offset;
-
- /* Allocate space for the new snapshot list */
- snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);
- offset = snapshots_offset;
- if (offset < 0) {
- return offset;
- }
- ret = bdrv_flush(bs);
- if (ret < 0) {
- return ret;
- }
-
- /* Write all snapshots to the new list */
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- memset(&h, 0, sizeof(h));
- h.l1_table_offset = cpu_to_be64(sn->l1_table_offset);
- h.l1_size = cpu_to_be32(sn->l1_size);
- /* If it doesn't fit in 32 bit, older implementations should treat it
- * as a disk-only snapshot rather than truncate the VM state */
- if (sn->vm_state_size <= 0xffffffff) {
- h.vm_state_size = cpu_to_be32(sn->vm_state_size);
- }
- h.date_sec = cpu_to_be32(sn->date_sec);
- h.date_nsec = cpu_to_be32(sn->date_nsec);
- h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);
- h.extra_data_size = cpu_to_be32(sizeof(extra));
-
- memset(&extra, 0, sizeof(extra));
- extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size);
- extra.disk_size = cpu_to_be64(sn->disk_size);
-
- id_str_size = strlen(sn->id_str);
- name_size = strlen(sn->name);
- h.id_str_size = cpu_to_be16(id_str_size);
- h.name_size = cpu_to_be16(name_size);
- offset = align_offset(offset, 8);
-
- ret = bdrv_pwrite(bs->file, offset, &h, sizeof(h));
- if (ret < 0) {
- goto fail;
- }
- offset += sizeof(h);
-
- ret = bdrv_pwrite(bs->file, offset, &extra, sizeof(extra));
- if (ret < 0) {
- goto fail;
- }
- offset += sizeof(extra);
-
- ret = bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size);
- if (ret < 0) {
- goto fail;
- }
- offset += id_str_size;
-
- ret = bdrv_pwrite(bs->file, offset, sn->name, name_size);
- if (ret < 0) {
- goto fail;
- }
- offset += name_size;
- }
-
- /*
- * Update the header to point to the new snapshot table. This requires the
- * new table and its refcounts to be stable on disk.
- */
- ret = bdrv_flush(bs);
- if (ret < 0) {
- goto fail;
- }
-
- QEMU_BUILD_BUG_ON(offsetof(QCowHeader, snapshots_offset) !=
- offsetof(QCowHeader, nb_snapshots) + sizeof(header_data.nb_snapshots));
-
- header_data.nb_snapshots = cpu_to_be32(s->nb_snapshots);
- header_data.snapshots_offset = cpu_to_be64(snapshots_offset);
-
- ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
- &header_data, sizeof(header_data));
- if (ret < 0) {
- goto fail;
- }
-
- /* free the old snapshot table */
- qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size,
- QCOW2_DISCARD_SNAPSHOT);
- s->snapshots_offset = snapshots_offset;
- s->snapshots_size = snapshots_size;
- return 0;
-
-fail:
- return ret;
-}
-
-static void find_new_snapshot_id(BlockDriverState *bs,
- char *id_str, int id_str_size)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- int i, id, id_max = 0;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- sn = s->snapshots + i;
- id = strtoul(sn->id_str, NULL, 10);
- if (id > id_max)
- id_max = id;
- }
- snprintf(id_str, id_str_size, "%d", id_max + 1);
-}
-
-static int find_snapshot_by_id(BlockDriverState *bs, const char *id_str)
-{
- BDRVQcowState *s = bs->opaque;
- int i;
-
- for(i = 0; i < s->nb_snapshots; i++) {
- if (!strcmp(s->snapshots[i].id_str, id_str))
- return i;
- }
- return -1;
-}
-
-static int find_snapshot_by_id_or_name(BlockDriverState *bs, const char *name)
-{
- BDRVQcowState *s = bs->opaque;
- int i, ret;
-
- ret = find_snapshot_by_id(bs, name);
- if (ret >= 0)
- return ret;
- for(i = 0; i < s->nb_snapshots; i++) {
- if (!strcmp(s->snapshots[i].name, name))
- return i;
- }
- return -1;
-}
-
-/* if no id is provided, a new one is constructed */
-int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *new_snapshot_list = NULL;
- QCowSnapshot *old_snapshot_list = NULL;
- QCowSnapshot sn1, *sn = &sn1;
- int i, ret;
- uint64_t *l1_table = NULL;
- int64_t l1_table_offset;
-
- memset(sn, 0, sizeof(*sn));
-
- /* Generate an ID if it wasn't passed */
- if (sn_info->id_str[0] == '\0') {
- find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str));
- }
-
- /* Check that the ID is unique */
- if (find_snapshot_by_id(bs, sn_info->id_str) >= 0) {
- return -EEXIST;
- }
-
- /* Populate sn with passed data */
- sn->id_str = g_strdup(sn_info->id_str);
- sn->name = g_strdup(sn_info->name);
-
- sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
- sn->vm_state_size = sn_info->vm_state_size;
- sn->date_sec = sn_info->date_sec;
- sn->date_nsec = sn_info->date_nsec;
- sn->vm_clock_nsec = sn_info->vm_clock_nsec;
-
- /* Allocate the L1 table of the snapshot and copy the current one there. */
- l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t));
- if (l1_table_offset < 0) {
- ret = l1_table_offset;
- goto fail;
- }
-
- sn->l1_table_offset = l1_table_offset;
- sn->l1_size = s->l1_size;
-
- l1_table = g_malloc(s->l1_size * sizeof(uint64_t));
- for(i = 0; i < s->l1_size; i++) {
- l1_table[i] = cpu_to_be64(s->l1_table[i]);
- }
-
- ret = bdrv_pwrite(bs->file, sn->l1_table_offset, l1_table,
- s->l1_size * sizeof(uint64_t));
- if (ret < 0) {
- goto fail;
- }
-
- g_free(l1_table);
- l1_table = NULL;
-
- /*
- * Increase the refcounts of all clusters and make sure everything is
- * stable on disk before updating the snapshot table to contain a pointer
- * to the new L1 table.
- */
- ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1);
- if (ret < 0) {
- goto fail;
- }
-
- /* Append the new snapshot to the snapshot list */
- new_snapshot_list = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
- if (s->snapshots) {
- memcpy(new_snapshot_list, s->snapshots,
- s->nb_snapshots * sizeof(QCowSnapshot));
- old_snapshot_list = s->snapshots;
- }
- s->snapshots = new_snapshot_list;
- s->snapshots[s->nb_snapshots++] = *sn;
-
- ret = qcow2_write_snapshots(bs);
- if (ret < 0) {
- g_free(s->snapshots);
- s->snapshots = old_snapshot_list;
- goto fail;
- }
-
- g_free(old_snapshot_list);
-
-#ifdef DEBUG_ALLOC
- {
- BdrvCheckResult result = {0};
- qcow2_check_refcounts(bs, &result, 0);
- }
-#endif
- return 0;
-
-fail:
- g_free(sn->id_str);
- g_free(sn->name);
- g_free(l1_table);
-
- return ret;
-}
-
-/* copy the snapshot 'snapshot_name' into the current disk image */
-int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- int i, snapshot_index;
- int cur_l1_bytes, sn_l1_bytes;
- int ret;
- uint64_t *sn_l1_table = NULL;
-
- /* Search the snapshot */
- snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
- if (snapshot_index < 0) {
- return -ENOENT;
- }
- sn = &s->snapshots[snapshot_index];
-
- if (sn->disk_size != bs->total_sectors * BDRV_SECTOR_SIZE) {
- error_report("qcow2: Loading snapshots with different disk "
- "size is not implemented");
- ret = -ENOTSUP;
- goto fail;
- }
-
- /*
- * Make sure that the current L1 table is big enough to contain the whole
- * L1 table of the snapshot. If the snapshot L1 table is smaller, the
- * current one must be padded with zeros.
- */
- ret = qcow2_grow_l1_table(bs, sn->l1_size, true);
- if (ret < 0) {
- goto fail;
- }
-
- cur_l1_bytes = s->l1_size * sizeof(uint64_t);
- sn_l1_bytes = sn->l1_size * sizeof(uint64_t);
-
- /*
- * Copy the snapshot L1 table to the current L1 table.
- *
- * Before overwriting the old current L1 table on disk, make sure to
- * increase all refcounts for the clusters referenced by the new one.
- * Decrease the refcount referenced by the old one only when the L1
- * table is overwritten.
- */
- sn_l1_table = g_malloc0(cur_l1_bytes);
-
- ret = bdrv_pread(bs->file, sn->l1_table_offset, sn_l1_table, sn_l1_bytes);
- if (ret < 0) {
- goto fail;
- }
-
- ret = qcow2_update_snapshot_refcount(bs, sn->l1_table_offset,
- sn->l1_size, 1);
- if (ret < 0) {
- goto fail;
- }
-
- ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset, sn_l1_table,
- cur_l1_bytes);
- if (ret < 0) {
- goto fail;
- }
-
- /*
- * Decrease refcount of clusters of current L1 table.
- *
- * At this point, the in-memory s->l1_table points to the old L1 table,
- * whereas on disk we already have the new one.
- *
- * qcow2_update_snapshot_refcount special cases the current L1 table to use
- * the in-memory data instead of really using the offset to load a new one,
- * which is why this works.
- */
- ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset,
- s->l1_size, -1);
-
- /*
- * Now update the in-memory L1 table to be in sync with the on-disk one. We
- * need to do this even if updating refcounts failed.
- */
- for(i = 0;i < s->l1_size; i++) {
- s->l1_table[i] = be64_to_cpu(sn_l1_table[i]);
- }
-
- if (ret < 0) {
- goto fail;
- }
-
- g_free(sn_l1_table);
- sn_l1_table = NULL;
-
- /*
- * Update QCOW_OFLAG_COPIED in the active L1 table (it may have changed
- * when we decreased the refcount of the old snapshot.
- */
- ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);
- if (ret < 0) {
- goto fail;
- }
-
-#ifdef DEBUG_ALLOC
- {
- BdrvCheckResult result = {0};
- qcow2_check_refcounts(bs, &result, 0);
- }
-#endif
- return 0;
-
-fail:
- g_free(sn_l1_table);
- return ret;
-}
-
-int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
-{
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot sn;
- int snapshot_index, ret;
-
- /* Search the snapshot */
- snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
- if (snapshot_index < 0) {
- return -ENOENT;
- }
- sn = s->snapshots[snapshot_index];
-
- /* Remove it from the snapshot list */
- memmove(s->snapshots + snapshot_index,
- s->snapshots + snapshot_index + 1,
- (s->nb_snapshots - snapshot_index - 1) * sizeof(sn));
- s->nb_snapshots--;
- ret = qcow2_write_snapshots(bs);
- if (ret < 0) {
- return ret;
- }
-
- /*
- * The snapshot is now unused, clean up. If we fail after this point, we
- * won't recover but just leak clusters.
- */
- g_free(sn.id_str);
- g_free(sn.name);
-
- /*
- * Now decrease the refcounts of clusters referenced by the snapshot and
- * free the L1 table.
- */
- ret = qcow2_update_snapshot_refcount(bs, sn.l1_table_offset,
- sn.l1_size, -1);
- if (ret < 0) {
- return ret;
- }
- qcow2_free_clusters(bs, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t),
- QCOW2_DISCARD_SNAPSHOT);
-
- /* must update the copied flag on the current cluster offsets */
- ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);
- if (ret < 0) {
- return ret;
- }
-
-#ifdef DEBUG_ALLOC
- {
- BdrvCheckResult result = {0};
- qcow2_check_refcounts(bs, &result, 0);
- }
-#endif
- return 0;
-}
-
-int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
-{
- BDRVQcowState *s = bs->opaque;
- QEMUSnapshotInfo *sn_tab, *sn_info;
- QCowSnapshot *sn;
- int i;
-
- if (!s->nb_snapshots) {
- *psn_tab = NULL;
- return s->nb_snapshots;
- }
-
- sn_tab = g_malloc0(s->nb_snapshots * sizeof(QEMUSnapshotInfo));
- for(i = 0; i < s->nb_snapshots; i++) {
- sn_info = sn_tab + i;
- sn = s->snapshots + i;
- pstrcpy(sn_info->id_str, sizeof(sn_info->id_str),
- sn->id_str);
- pstrcpy(sn_info->name, sizeof(sn_info->name),
- sn->name);
- sn_info->vm_state_size = sn->vm_state_size;
- sn_info->date_sec = sn->date_sec;
- sn_info->date_nsec = sn->date_nsec;
- sn_info->vm_clock_nsec = sn->vm_clock_nsec;
- }
- *psn_tab = sn_tab;
- return s->nb_snapshots;
-}
-
-int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
-{
- int i, snapshot_index;
- BDRVQcowState *s = bs->opaque;
- QCowSnapshot *sn;
- uint64_t *new_l1_table;
- int new_l1_bytes;
- int ret;
-
- assert(bs->read_only);
-
- /* Search the snapshot */
- snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_name);
- if (snapshot_index < 0) {
- return -ENOENT;
- }
- sn = &s->snapshots[snapshot_index];
-
- /* Allocate and read in the snapshot's L1 table */
- new_l1_bytes = s->l1_size * sizeof(uint64_t);
- new_l1_table = g_malloc0(align_offset(new_l1_bytes, 512));
-
- ret = bdrv_pread(bs->file, sn->l1_table_offset, new_l1_table, new_l1_bytes);
- if (ret < 0) {
- g_free(new_l1_table);
- return ret;
- }
-
- /* Switch the L1 table */
- g_free(s->l1_table);
-
- s->l1_size = sn->l1_size;
- s->l1_table_offset = sn->l1_table_offset;
- s->l1_table = new_l1_table;
-
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
-
- return 0;
-}
diff --git a/contrib/qemu/block/qcow2.c b/contrib/qemu/block/qcow2.c
deleted file mode 100644
index 0eceefe2cd9..00000000000
--- a/contrib/qemu/block/qcow2.c
+++ /dev/null
@@ -1,1825 +0,0 @@
-/*
- * Block driver for the QCOW version 2 format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/module.h"
-#include <zlib.h>
-#include "qemu/aes.h"
-#include "block/qcow2.h"
-#include "qemu/error-report.h"
-#include "qapi/qmp/qerror.h"
-#include "qapi/qmp/qbool.h"
-#include "trace.h"
-
-/*
- Differences with QCOW:
-
- - Support for multiple incremental snapshots.
- - Memory management by reference counts.
- - Clusters which have a reference count of one have the bit
- QCOW_OFLAG_COPIED to optimize write performance.
- - Size of compressed clusters is stored in sectors to reduce bit usage
- in the cluster offsets.
- - Support for storing additional data (such as the VM state) in the
- snapshots.
- - If a backing store is used, the cluster size is not constrained
- (could be backported to QCOW).
- - L2 tables have always a size of one cluster.
-*/
-
-
-typedef struct {
- uint32_t magic;
- uint32_t len;
-} QCowExtension;
-
-#define QCOW2_EXT_MAGIC_END 0
-#define QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA
-#define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
-
-static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const QCowHeader *cow_header = (const void *)buf;
-
- if (buf_size >= sizeof(QCowHeader) &&
- be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
- be32_to_cpu(cow_header->version) >= 2)
- return 100;
- else
- return 0;
-}
-
-
-/*
- * read qcow2 extension and fill bs
- * start reading from start_offset
- * finish reading upon magic of value 0 or when end_offset reached
- * unknown magic is skipped (future extension this version knows nothing about)
- * return 0 upon success, non-0 otherwise
- */
-static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
- uint64_t end_offset, void **p_feature_table)
-{
- BDRVQcowState *s = bs->opaque;
- QCowExtension ext;
- uint64_t offset;
- int ret;
-
-#ifdef DEBUG_EXT
- printf("qcow2_read_extensions: start=%ld end=%ld\n", start_offset, end_offset);
-#endif
- offset = start_offset;
- while (offset < end_offset) {
-
-#ifdef DEBUG_EXT
- /* Sanity check */
- if (offset > s->cluster_size)
- printf("qcow2_read_extension: suspicious offset %lu\n", offset);
-
- printf("attempting to read extended header in offset %lu\n", offset);
-#endif
-
- if (bdrv_pread(bs->file, offset, &ext, sizeof(ext)) != sizeof(ext)) {
- fprintf(stderr, "qcow2_read_extension: ERROR: "
- "pread fail from offset %" PRIu64 "\n",
- offset);
- return 1;
- }
- be32_to_cpus(&ext.magic);
- be32_to_cpus(&ext.len);
- offset += sizeof(ext);
-#ifdef DEBUG_EXT
- printf("ext.magic = 0x%x\n", ext.magic);
-#endif
- if (ext.len > end_offset - offset) {
- error_report("Header extension too large");
- return -EINVAL;
- }
-
- switch (ext.magic) {
- case QCOW2_EXT_MAGIC_END:
- return 0;
-
- case QCOW2_EXT_MAGIC_BACKING_FORMAT:
- if (ext.len >= sizeof(bs->backing_format)) {
- fprintf(stderr, "ERROR: ext_backing_format: len=%u too large"
- " (>=%zu)\n",
- ext.len, sizeof(bs->backing_format));
- return 2;
- }
- if (bdrv_pread(bs->file, offset , bs->backing_format,
- ext.len) != ext.len)
- return 3;
- bs->backing_format[ext.len] = '\0';
-#ifdef DEBUG_EXT
- printf("Qcow2: Got format extension %s\n", bs->backing_format);
-#endif
- break;
-
- case QCOW2_EXT_MAGIC_FEATURE_TABLE:
- if (p_feature_table != NULL) {
- void* feature_table = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature));
- ret = bdrv_pread(bs->file, offset , feature_table, ext.len);
- if (ret < 0) {
- return ret;
- }
-
- *p_feature_table = feature_table;
- }
- break;
-
- default:
- /* unknown magic - save it in case we need to rewrite the header */
- {
- Qcow2UnknownHeaderExtension *uext;
-
- uext = g_malloc0(sizeof(*uext) + ext.len);
- uext->magic = ext.magic;
- uext->len = ext.len;
- QLIST_INSERT_HEAD(&s->unknown_header_ext, uext, next);
-
- ret = bdrv_pread(bs->file, offset , uext->data, uext->len);
- if (ret < 0) {
- return ret;
- }
- }
- break;
- }
-
- offset += ((ext.len + 7) & ~7);
- }
-
- return 0;
-}
-
-static void cleanup_unknown_header_ext(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- Qcow2UnknownHeaderExtension *uext, *next;
-
- QLIST_FOREACH_SAFE(uext, &s->unknown_header_ext, next, next) {
- QLIST_REMOVE(uext, next);
- g_free(uext);
- }
-}
-
-static void GCC_FMT_ATTR(2, 3) report_unsupported(BlockDriverState *bs,
- const char *fmt, ...)
-{
- char msg[64];
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(msg, sizeof(msg), fmt, ap);
- va_end(ap);
-
- qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
- bs->device_name, "qcow2", msg);
-}
-
-static void report_unsupported_feature(BlockDriverState *bs,
- Qcow2Feature *table, uint64_t mask)
-{
- while (table && table->name[0] != '\0') {
- if (table->type == QCOW2_FEAT_TYPE_INCOMPATIBLE) {
- if (mask & (1 << table->bit)) {
- report_unsupported(bs, "%.46s",table->name);
- mask &= ~(1 << table->bit);
- }
- }
- table++;
- }
-
- if (mask) {
- report_unsupported(bs, "Unknown incompatible feature: %" PRIx64, mask);
- }
-}
-
-/*
- * Sets the dirty bit and flushes afterwards if necessary.
- *
- * The incompatible_features bit is only set if the image file header was
- * updated successfully. Therefore it is not required to check the return
- * value of this function.
- */
-int qcow2_mark_dirty(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t val;
- int ret;
-
- assert(s->qcow_version >= 3);
-
- if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) {
- return 0; /* already dirty */
- }
-
- val = cpu_to_be64(s->incompatible_features | QCOW2_INCOMPAT_DIRTY);
- ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, incompatible_features),
- &val, sizeof(val));
- if (ret < 0) {
- return ret;
- }
- ret = bdrv_flush(bs->file);
- if (ret < 0) {
- return ret;
- }
-
- /* Only treat image as dirty if the header was updated successfully */
- s->incompatible_features |= QCOW2_INCOMPAT_DIRTY;
- return 0;
-}
-
-/*
- * Clears the dirty bit and flushes before if necessary. Only call this
- * function when there are no pending requests, it does not guard against
- * concurrent requests dirtying the image.
- */
-static int qcow2_mark_clean(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
-
- if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) {
- int ret = bdrv_flush(bs);
- if (ret < 0) {
- return ret;
- }
-
- s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY;
- return qcow2_update_header(bs);
- }
- return 0;
-}
-
-static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
- BdrvCheckMode fix)
-{
- int ret = qcow2_check_refcounts(bs, result, fix);
- if (ret < 0) {
- return ret;
- }
-
- if (fix && result->check_errors == 0 && result->corruptions == 0) {
- return qcow2_mark_clean(bs);
- }
- return ret;
-}
-
-static QemuOptsList qcow2_runtime_opts = {
- .name = "qcow2",
- .head = QTAILQ_HEAD_INITIALIZER(qcow2_runtime_opts.head),
- .desc = {
- {
- .name = "lazy_refcounts",
- .type = QEMU_OPT_BOOL,
- .help = "Postpone refcount updates",
- },
- {
- .name = QCOW2_OPT_DISCARD_REQUEST,
- .type = QEMU_OPT_BOOL,
- .help = "Pass guest discard requests to the layer below",
- },
- {
- .name = QCOW2_OPT_DISCARD_SNAPSHOT,
- .type = QEMU_OPT_BOOL,
- .help = "Generate discard requests when snapshot related space "
- "is freed",
- },
- {
- .name = QCOW2_OPT_DISCARD_OTHER,
- .type = QEMU_OPT_BOOL,
- .help = "Generate discard requests when other clusters are freed",
- },
- { /* end of list */ }
- },
-};
-
-static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
-{
- BDRVQcowState *s = bs->opaque;
- int len, i, ret = 0;
- QCowHeader header;
- QemuOpts *opts;
- Error *local_err = NULL;
- uint64_t ext_end;
- uint64_t l1_vm_state_index;
-
- ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
- if (ret < 0) {
- goto fail;
- }
- be32_to_cpus(&header.magic);
- be32_to_cpus(&header.version);
- be64_to_cpus(&header.backing_file_offset);
- be32_to_cpus(&header.backing_file_size);
- be64_to_cpus(&header.size);
- be32_to_cpus(&header.cluster_bits);
- be32_to_cpus(&header.crypt_method);
- be64_to_cpus(&header.l1_table_offset);
- be32_to_cpus(&header.l1_size);
- be64_to_cpus(&header.refcount_table_offset);
- be32_to_cpus(&header.refcount_table_clusters);
- be64_to_cpus(&header.snapshots_offset);
- be32_to_cpus(&header.nb_snapshots);
-
- if (header.magic != QCOW_MAGIC) {
- ret = -EMEDIUMTYPE;
- goto fail;
- }
- if (header.version < 2 || header.version > 3) {
- report_unsupported(bs, "QCOW version %d", header.version);
- ret = -ENOTSUP;
- goto fail;
- }
-
- s->qcow_version = header.version;
-
- /* Initialise version 3 header fields */
- if (header.version == 2) {
- header.incompatible_features = 0;
- header.compatible_features = 0;
- header.autoclear_features = 0;
- header.refcount_order = 4;
- header.header_length = 72;
- } else {
- be64_to_cpus(&header.incompatible_features);
- be64_to_cpus(&header.compatible_features);
- be64_to_cpus(&header.autoclear_features);
- be32_to_cpus(&header.refcount_order);
- be32_to_cpus(&header.header_length);
- }
-
- if (header.header_length > sizeof(header)) {
- s->unknown_header_fields_size = header.header_length - sizeof(header);
- s->unknown_header_fields = g_malloc(s->unknown_header_fields_size);
- ret = bdrv_pread(bs->file, sizeof(header), s->unknown_header_fields,
- s->unknown_header_fields_size);
- if (ret < 0) {
- goto fail;
- }
- }
-
- if (header.backing_file_offset) {
- ext_end = header.backing_file_offset;
- } else {
- ext_end = 1 << header.cluster_bits;
- }
-
- /* Handle feature bits */
- s->incompatible_features = header.incompatible_features;
- s->compatible_features = header.compatible_features;
- s->autoclear_features = header.autoclear_features;
-
- if (s->incompatible_features & ~QCOW2_INCOMPAT_MASK) {
- void *feature_table = NULL;
- qcow2_read_extensions(bs, header.header_length, ext_end,
- &feature_table);
- report_unsupported_feature(bs, feature_table,
- s->incompatible_features &
- ~QCOW2_INCOMPAT_MASK);
- ret = -ENOTSUP;
- goto fail;
- }
-
- /* Check support for various header values */
- if (header.refcount_order != 4) {
- report_unsupported(bs, "%d bit reference counts",
- 1 << header.refcount_order);
- ret = -ENOTSUP;
- goto fail;
- }
-
- if (header.cluster_bits < MIN_CLUSTER_BITS ||
- header.cluster_bits > MAX_CLUSTER_BITS) {
- ret = -EINVAL;
- goto fail;
- }
- if (header.crypt_method > QCOW_CRYPT_AES) {
- ret = -EINVAL;
- goto fail;
- }
- s->crypt_method_header = header.crypt_method;
- if (s->crypt_method_header) {
- bs->encrypted = 1;
- }
- s->cluster_bits = header.cluster_bits;
- s->cluster_size = 1 << s->cluster_bits;
- s->cluster_sectors = 1 << (s->cluster_bits - 9);
- s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */
- s->l2_size = 1 << s->l2_bits;
- bs->total_sectors = header.size / 512;
- s->csize_shift = (62 - (s->cluster_bits - 8));
- s->csize_mask = (1 << (s->cluster_bits - 8)) - 1;
- s->cluster_offset_mask = (1LL << s->csize_shift) - 1;
- s->refcount_table_offset = header.refcount_table_offset;
- s->refcount_table_size =
- header.refcount_table_clusters << (s->cluster_bits - 3);
-
- s->snapshots_offset = header.snapshots_offset;
- s->nb_snapshots = header.nb_snapshots;
-
- /* read the level 1 table */
- s->l1_size = header.l1_size;
-
- l1_vm_state_index = size_to_l1(s, header.size);
- if (l1_vm_state_index > INT_MAX) {
- ret = -EFBIG;
- goto fail;
- }
- s->l1_vm_state_index = l1_vm_state_index;
-
- /* the L1 table must contain at least enough entries to put
- header.size bytes */
- if (s->l1_size < s->l1_vm_state_index) {
- ret = -EINVAL;
- goto fail;
- }
- s->l1_table_offset = header.l1_table_offset;
- if (s->l1_size > 0) {
- s->l1_table = g_malloc0(
- align_offset(s->l1_size * sizeof(uint64_t), 512));
- ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,
- s->l1_size * sizeof(uint64_t));
- if (ret < 0) {
- goto fail;
- }
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
- }
-
- /* alloc L2 table/refcount block cache */
- s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE);
- s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE);
-
- s->cluster_cache = g_malloc(s->cluster_size);
- /* one more sector for decompressed data alignment */
- s->cluster_data = qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size
- + 512);
- s->cluster_cache_offset = -1;
- s->flags = flags;
-
- ret = qcow2_refcount_init(bs);
- if (ret != 0) {
- goto fail;
- }
-
- QLIST_INIT(&s->cluster_allocs);
- QTAILQ_INIT(&s->discards);
-
- /* read qcow2 extensions */
- if (qcow2_read_extensions(bs, header.header_length, ext_end, NULL)) {
- ret = -EINVAL;
- goto fail;
- }
-
- /* read the backing file name */
- if (header.backing_file_offset != 0) {
- len = header.backing_file_size;
- if (len > 1023) {
- len = 1023;
- }
- ret = bdrv_pread(bs->file, header.backing_file_offset,
- bs->backing_file, len);
- if (ret < 0) {
- goto fail;
- }
- bs->backing_file[len] = '\0';
- }
-
- ret = qcow2_read_snapshots(bs);
- if (ret < 0) {
- goto fail;
- }
-
- /* Clear unknown autoclear feature bits */
- if (!bs->read_only && s->autoclear_features != 0) {
- s->autoclear_features = 0;
- ret = qcow2_update_header(bs);
- if (ret < 0) {
- goto fail;
- }
- }
-
- /* Initialise locks */
- qemu_co_mutex_init(&s->lock);
-
- /* Repair image if dirty */
- if (!(flags & BDRV_O_CHECK) && !bs->read_only &&
- (s->incompatible_features & QCOW2_INCOMPAT_DIRTY)) {
- BdrvCheckResult result = {0};
-
- ret = qcow2_check(bs, &result, BDRV_FIX_ERRORS);
- if (ret < 0) {
- goto fail;
- }
- }
-
- /* Enable lazy_refcounts according to image and command line options */
- opts = qemu_opts_create_nofail(&qcow2_runtime_opts);
- qemu_opts_absorb_qdict(opts, options, &local_err);
- if (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- ret = -EINVAL;
- goto fail;
- }
-
- s->use_lazy_refcounts = qemu_opt_get_bool(opts, QCOW2_OPT_LAZY_REFCOUNTS,
- (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS));
-
- s->discard_passthrough[QCOW2_DISCARD_NEVER] = false;
- s->discard_passthrough[QCOW2_DISCARD_ALWAYS] = true;
- s->discard_passthrough[QCOW2_DISCARD_REQUEST] =
- qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_REQUEST,
- flags & BDRV_O_UNMAP);
- s->discard_passthrough[QCOW2_DISCARD_SNAPSHOT] =
- qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_SNAPSHOT, true);
- s->discard_passthrough[QCOW2_DISCARD_OTHER] =
- qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_OTHER, false);
-
- qemu_opts_del(opts);
-
- if (s->use_lazy_refcounts && s->qcow_version < 3) {
- qerror_report(ERROR_CLASS_GENERIC_ERROR, "Lazy refcounts require "
- "a qcow2 image with at least qemu 1.1 compatibility level");
- ret = -EINVAL;
- goto fail;
- }
-
-#ifdef DEBUG_ALLOC
- {
- BdrvCheckResult result = {0};
- qcow2_check_refcounts(bs, &result, 0);
- }
-#endif
- return ret;
-
- fail:
- g_free(s->unknown_header_fields);
- cleanup_unknown_header_ext(bs);
- qcow2_free_snapshots(bs);
- qcow2_refcount_close(bs);
- g_free(s->l1_table);
- if (s->l2_table_cache) {
- qcow2_cache_destroy(bs, s->l2_table_cache);
- }
- g_free(s->cluster_cache);
- qemu_vfree(s->cluster_data);
- return ret;
-}
-
-static int qcow2_set_key(BlockDriverState *bs, const char *key)
-{
- BDRVQcowState *s = bs->opaque;
- uint8_t keybuf[16];
- int len, i;
-
- memset(keybuf, 0, 16);
- len = strlen(key);
- if (len > 16)
- len = 16;
- /* XXX: we could compress the chars to 7 bits to increase
- entropy */
- for(i = 0;i < len;i++) {
- keybuf[i] = key[i];
- }
- s->crypt_method = s->crypt_method_header;
-
- if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
- return -1;
- if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
- return -1;
-#if 0
- /* test */
- {
- uint8_t in[16];
- uint8_t out[16];
- uint8_t tmp[16];
- for(i=0;i<16;i++)
- in[i] = i;
- AES_encrypt(in, tmp, &s->aes_encrypt_key);
- AES_decrypt(tmp, out, &s->aes_decrypt_key);
- for(i = 0; i < 16; i++)
- printf(" %02x", tmp[i]);
- printf("\n");
- for(i = 0; i < 16; i++)
- printf(" %02x", out[i]);
- printf("\n");
- }
-#endif
- return 0;
-}
-
-/* We have nothing to do for QCOW2 reopen, stubs just return
- * success */
-static int qcow2_reopen_prepare(BDRVReopenState *state,
- BlockReopenQueue *queue, Error **errp)
-{
- return 0;
-}
-
-static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, int *pnum)
-{
- BDRVQcowState *s = bs->opaque;
- uint64_t cluster_offset;
- int ret;
-
- *pnum = nb_sectors;
- /* FIXME We can get errors here, but the bdrv_co_is_allocated interface
- * can't pass them on today */
- qemu_co_mutex_lock(&s->lock);
- ret = qcow2_get_cluster_offset(bs, sector_num << 9, pnum, &cluster_offset);
- qemu_co_mutex_unlock(&s->lock);
- if (ret < 0) {
- *pnum = 0;
- }
-
- return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO);
-}
-
-/* handle reading after the end of the backing file */
-int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
- int64_t sector_num, int nb_sectors)
-{
- int n1;
- if ((sector_num + nb_sectors) <= bs->total_sectors)
- return nb_sectors;
- if (sector_num >= bs->total_sectors)
- n1 = 0;
- else
- n1 = bs->total_sectors - sector_num;
-
- qemu_iovec_memset(qiov, 512 * n1, 0, 512 * (nb_sectors - n1));
-
- return n1;
-}
-
-static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
- int remaining_sectors, QEMUIOVector *qiov)
-{
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster, n1;
- int ret;
- int cur_nr_sectors; /* number of sectors in current iteration */
- uint64_t cluster_offset = 0;
- uint64_t bytes_done = 0;
- QEMUIOVector hd_qiov;
- uint8_t *cluster_data = NULL;
-
- qemu_iovec_init(&hd_qiov, qiov->niov);
-
- qemu_co_mutex_lock(&s->lock);
-
- while (remaining_sectors != 0) {
-
- /* prepare next request */
- cur_nr_sectors = remaining_sectors;
- if (s->crypt_method) {
- cur_nr_sectors = MIN(cur_nr_sectors,
- QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
- }
-
- ret = qcow2_get_cluster_offset(bs, sector_num << 9,
- &cur_nr_sectors, &cluster_offset);
- if (ret < 0) {
- goto fail;
- }
-
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
-
- qemu_iovec_reset(&hd_qiov);
- qemu_iovec_concat(&hd_qiov, qiov, bytes_done,
- cur_nr_sectors * 512);
-
- switch (ret) {
- case QCOW2_CLUSTER_UNALLOCATED:
-
- if (bs->backing_hd) {
- /* read from the base image */
- n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov,
- sector_num, cur_nr_sectors);
- if (n1 > 0) {
- BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
- qemu_co_mutex_unlock(&s->lock);
- ret = bdrv_co_readv(bs->backing_hd, sector_num,
- n1, &hd_qiov);
- qemu_co_mutex_lock(&s->lock);
- if (ret < 0) {
- goto fail;
- }
- }
- } else {
- /* Note: in this case, no need to wait */
- qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);
- }
- break;
-
- case QCOW2_CLUSTER_ZERO:
- qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);
- break;
-
- case QCOW2_CLUSTER_COMPRESSED:
- /* add AIO support for compressed blocks ? */
- ret = qcow2_decompress_cluster(bs, cluster_offset);
- if (ret < 0) {
- goto fail;
- }
-
- qemu_iovec_from_buf(&hd_qiov, 0,
- s->cluster_cache + index_in_cluster * 512,
- 512 * cur_nr_sectors);
- break;
-
- case QCOW2_CLUSTER_NORMAL:
- if ((cluster_offset & 511) != 0) {
- ret = -EIO;
- goto fail;
- }
-
- if (s->crypt_method) {
- /*
- * For encrypted images, read everything into a temporary
- * contiguous buffer on which the AES functions can work.
- */
- if (!cluster_data) {
- cluster_data =
- qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
- }
-
- assert(cur_nr_sectors <=
- QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
- qemu_iovec_reset(&hd_qiov);
- qemu_iovec_add(&hd_qiov, cluster_data,
- 512 * cur_nr_sectors);
- }
-
- BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
- qemu_co_mutex_unlock(&s->lock);
- ret = bdrv_co_readv(bs->file,
- (cluster_offset >> 9) + index_in_cluster,
- cur_nr_sectors, &hd_qiov);
- qemu_co_mutex_lock(&s->lock);
- if (ret < 0) {
- goto fail;
- }
- if (s->crypt_method) {
- qcow2_encrypt_sectors(s, sector_num, cluster_data,
- cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);
- qemu_iovec_from_buf(qiov, bytes_done,
- cluster_data, 512 * cur_nr_sectors);
- }
- break;
-
- default:
- g_assert_not_reached();
- ret = -EIO;
- goto fail;
- }
-
- remaining_sectors -= cur_nr_sectors;
- sector_num += cur_nr_sectors;
- bytes_done += cur_nr_sectors * 512;
- }
- ret = 0;
-
-fail:
- qemu_co_mutex_unlock(&s->lock);
-
- qemu_iovec_destroy(&hd_qiov);
- qemu_vfree(cluster_data);
-
- return ret;
-}
-
-static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
- int64_t sector_num,
- int remaining_sectors,
- QEMUIOVector *qiov)
-{
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster;
- int n_end;
- int ret;
- int cur_nr_sectors; /* number of sectors in current iteration */
- uint64_t cluster_offset;
- QEMUIOVector hd_qiov;
- uint64_t bytes_done = 0;
- uint8_t *cluster_data = NULL;
- QCowL2Meta *l2meta = NULL;
-
- trace_qcow2_writev_start_req(qemu_coroutine_self(), sector_num,
- remaining_sectors);
-
- qemu_iovec_init(&hd_qiov, qiov->niov);
-
- s->cluster_cache_offset = -1; /* disable compressed cache */
-
- qemu_co_mutex_lock(&s->lock);
-
- while (remaining_sectors != 0) {
-
- l2meta = NULL;
-
- trace_qcow2_writev_start_part(qemu_coroutine_self());
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n_end = index_in_cluster + remaining_sectors;
- if (s->crypt_method &&
- n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) {
- n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
- }
-
- ret = qcow2_alloc_cluster_offset(bs, sector_num << 9,
- index_in_cluster, n_end, &cur_nr_sectors, &cluster_offset, &l2meta);
- if (ret < 0) {
- goto fail;
- }
-
- assert((cluster_offset & 511) == 0);
-
- qemu_iovec_reset(&hd_qiov);
- qemu_iovec_concat(&hd_qiov, qiov, bytes_done,
- cur_nr_sectors * 512);
-
- if (s->crypt_method) {
- if (!cluster_data) {
- cluster_data = qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS *
- s->cluster_size);
- }
-
- assert(hd_qiov.size <=
- QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
- qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size);
-
- qcow2_encrypt_sectors(s, sector_num, cluster_data,
- cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key);
-
- qemu_iovec_reset(&hd_qiov);
- qemu_iovec_add(&hd_qiov, cluster_data,
- cur_nr_sectors * 512);
- }
-
- qemu_co_mutex_unlock(&s->lock);
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
- trace_qcow2_writev_data(qemu_coroutine_self(),
- (cluster_offset >> 9) + index_in_cluster);
- ret = bdrv_co_writev(bs->file,
- (cluster_offset >> 9) + index_in_cluster,
- cur_nr_sectors, &hd_qiov);
- qemu_co_mutex_lock(&s->lock);
- if (ret < 0) {
- goto fail;
- }
-
- while (l2meta != NULL) {
- QCowL2Meta *next;
-
- ret = qcow2_alloc_cluster_link_l2(bs, l2meta);
- if (ret < 0) {
- goto fail;
- }
-
- /* Take the request off the list of running requests */
- if (l2meta->nb_clusters != 0) {
- QLIST_REMOVE(l2meta, next_in_flight);
- }
-
- qemu_co_queue_restart_all(&l2meta->dependent_requests);
-
- next = l2meta->next;
- g_free(l2meta);
- l2meta = next;
- }
-
- remaining_sectors -= cur_nr_sectors;
- sector_num += cur_nr_sectors;
- bytes_done += cur_nr_sectors * 512;
- trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_nr_sectors);
- }
- ret = 0;
-
-fail:
- qemu_co_mutex_unlock(&s->lock);
-
- while (l2meta != NULL) {
- QCowL2Meta *next;
-
- if (l2meta->nb_clusters != 0) {
- QLIST_REMOVE(l2meta, next_in_flight);
- }
- qemu_co_queue_restart_all(&l2meta->dependent_requests);
-
- next = l2meta->next;
- g_free(l2meta);
- l2meta = next;
- }
-
- qemu_iovec_destroy(&hd_qiov);
- qemu_vfree(cluster_data);
- trace_qcow2_writev_done_req(qemu_coroutine_self(), ret);
-
- return ret;
-}
-
-static void qcow2_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- g_free(s->l1_table);
-
- qcow2_cache_flush(bs, s->l2_table_cache);
- qcow2_cache_flush(bs, s->refcount_block_cache);
-
- qcow2_mark_clean(bs);
-
- qcow2_cache_destroy(bs, s->l2_table_cache);
- qcow2_cache_destroy(bs, s->refcount_block_cache);
-
- g_free(s->unknown_header_fields);
- cleanup_unknown_header_ext(bs);
-
- g_free(s->cluster_cache);
- qemu_vfree(s->cluster_data);
- qcow2_refcount_close(bs);
- qcow2_free_snapshots(bs);
-}
-
-static void qcow2_invalidate_cache(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int flags = s->flags;
- AES_KEY aes_encrypt_key;
- AES_KEY aes_decrypt_key;
- uint32_t crypt_method = 0;
- QDict *options;
-
- /*
- * Backing files are read-only which makes all of their metadata immutable,
- * that means we don't have to worry about reopening them here.
- */
-
- if (s->crypt_method) {
- crypt_method = s->crypt_method;
- memcpy(&aes_encrypt_key, &s->aes_encrypt_key, sizeof(aes_encrypt_key));
- memcpy(&aes_decrypt_key, &s->aes_decrypt_key, sizeof(aes_decrypt_key));
- }
-
- qcow2_close(bs);
-
- options = qdict_new();
- qdict_put(options, QCOW2_OPT_LAZY_REFCOUNTS,
- qbool_from_int(s->use_lazy_refcounts));
-
- memset(s, 0, sizeof(BDRVQcowState));
- qcow2_open(bs, options, flags);
-
- QDECREF(options);
-
- if (crypt_method) {
- s->crypt_method = crypt_method;
- memcpy(&s->aes_encrypt_key, &aes_encrypt_key, sizeof(aes_encrypt_key));
- memcpy(&s->aes_decrypt_key, &aes_decrypt_key, sizeof(aes_decrypt_key));
- }
-}
-
-static size_t header_ext_add(char *buf, uint32_t magic, const void *s,
- size_t len, size_t buflen)
-{
- QCowExtension *ext_backing_fmt = (QCowExtension*) buf;
- size_t ext_len = sizeof(QCowExtension) + ((len + 7) & ~7);
-
- if (buflen < ext_len) {
- return -ENOSPC;
- }
-
- *ext_backing_fmt = (QCowExtension) {
- .magic = cpu_to_be32(magic),
- .len = cpu_to_be32(len),
- };
- memcpy(buf + sizeof(QCowExtension), s, len);
-
- return ext_len;
-}
-
-/*
- * Updates the qcow2 header, including the variable length parts of it, i.e.
- * the backing file name and all extensions. qcow2 was not designed to allow
- * such changes, so if we run out of space (we can only use the first cluster)
- * this function may fail.
- *
- * Returns 0 on success, -errno in error cases.
- */
-int qcow2_update_header(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- QCowHeader *header;
- char *buf;
- size_t buflen = s->cluster_size;
- int ret;
- uint64_t total_size;
- uint32_t refcount_table_clusters;
- size_t header_length;
- Qcow2UnknownHeaderExtension *uext;
-
- buf = qemu_blockalign(bs, buflen);
-
- /* Header structure */
- header = (QCowHeader*) buf;
-
- if (buflen < sizeof(*header)) {
- ret = -ENOSPC;
- goto fail;
- }
-
- header_length = sizeof(*header) + s->unknown_header_fields_size;
- total_size = bs->total_sectors * BDRV_SECTOR_SIZE;
- refcount_table_clusters = s->refcount_table_size >> (s->cluster_bits - 3);
-
- *header = (QCowHeader) {
- /* Version 2 fields */
- .magic = cpu_to_be32(QCOW_MAGIC),
- .version = cpu_to_be32(s->qcow_version),
- .backing_file_offset = 0,
- .backing_file_size = 0,
- .cluster_bits = cpu_to_be32(s->cluster_bits),
- .size = cpu_to_be64(total_size),
- .crypt_method = cpu_to_be32(s->crypt_method_header),
- .l1_size = cpu_to_be32(s->l1_size),
- .l1_table_offset = cpu_to_be64(s->l1_table_offset),
- .refcount_table_offset = cpu_to_be64(s->refcount_table_offset),
- .refcount_table_clusters = cpu_to_be32(refcount_table_clusters),
- .nb_snapshots = cpu_to_be32(s->nb_snapshots),
- .snapshots_offset = cpu_to_be64(s->snapshots_offset),
-
- /* Version 3 fields */
- .incompatible_features = cpu_to_be64(s->incompatible_features),
- .compatible_features = cpu_to_be64(s->compatible_features),
- .autoclear_features = cpu_to_be64(s->autoclear_features),
- .refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT),
- .header_length = cpu_to_be32(header_length),
- };
-
- /* For older versions, write a shorter header */
- switch (s->qcow_version) {
- case 2:
- ret = offsetof(QCowHeader, incompatible_features);
- break;
- case 3:
- ret = sizeof(*header);
- break;
- default:
- ret = -EINVAL;
- goto fail;
- }
-
- buf += ret;
- buflen -= ret;
- memset(buf, 0, buflen);
-
- /* Preserve any unknown field in the header */
- if (s->unknown_header_fields_size) {
- if (buflen < s->unknown_header_fields_size) {
- ret = -ENOSPC;
- goto fail;
- }
-
- memcpy(buf, s->unknown_header_fields, s->unknown_header_fields_size);
- buf += s->unknown_header_fields_size;
- buflen -= s->unknown_header_fields_size;
- }
-
- /* Backing file format header extension */
- if (*bs->backing_format) {
- ret = header_ext_add(buf, QCOW2_EXT_MAGIC_BACKING_FORMAT,
- bs->backing_format, strlen(bs->backing_format),
- buflen);
- if (ret < 0) {
- goto fail;
- }
-
- buf += ret;
- buflen -= ret;
- }
-
- /* Feature table */
- Qcow2Feature features[] = {
- {
- .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
- .bit = QCOW2_INCOMPAT_DIRTY_BITNR,
- .name = "dirty bit",
- },
- {
- .type = QCOW2_FEAT_TYPE_COMPATIBLE,
- .bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
- .name = "lazy refcounts",
- },
- };
-
- ret = header_ext_add(buf, QCOW2_EXT_MAGIC_FEATURE_TABLE,
- features, sizeof(features), buflen);
- if (ret < 0) {
- goto fail;
- }
- buf += ret;
- buflen -= ret;
-
- /* Keep unknown header extensions */
- QLIST_FOREACH(uext, &s->unknown_header_ext, next) {
- ret = header_ext_add(buf, uext->magic, uext->data, uext->len, buflen);
- if (ret < 0) {
- goto fail;
- }
-
- buf += ret;
- buflen -= ret;
- }
-
- /* End of header extensions */
- ret = header_ext_add(buf, QCOW2_EXT_MAGIC_END, NULL, 0, buflen);
- if (ret < 0) {
- goto fail;
- }
-
- buf += ret;
- buflen -= ret;
-
- /* Backing file name */
- if (*bs->backing_file) {
- size_t backing_file_len = strlen(bs->backing_file);
-
- if (buflen < backing_file_len) {
- ret = -ENOSPC;
- goto fail;
- }
-
- /* Using strncpy is ok here, since buf is not NUL-terminated. */
- strncpy(buf, bs->backing_file, buflen);
-
- header->backing_file_offset = cpu_to_be64(buf - ((char*) header));
- header->backing_file_size = cpu_to_be32(backing_file_len);
- }
-
- /* Write the new header */
- ret = bdrv_pwrite(bs->file, 0, header, s->cluster_size);
- if (ret < 0) {
- goto fail;
- }
-
- ret = 0;
-fail:
- qemu_vfree(header);
- return ret;
-}
-
-static int qcow2_change_backing_file(BlockDriverState *bs,
- const char *backing_file, const char *backing_fmt)
-{
- pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_file ?: "");
- pstrcpy(bs->backing_format, sizeof(bs->backing_format), backing_fmt ?: "");
-
- return qcow2_update_header(bs);
-}
-
-static int preallocate(BlockDriverState *bs)
-{
- uint64_t nb_sectors;
- uint64_t offset;
- uint64_t host_offset = 0;
- int num;
- int ret;
- QCowL2Meta *meta;
-
- nb_sectors = bdrv_getlength(bs) >> 9;
- offset = 0;
-
- while (nb_sectors) {
- num = MIN(nb_sectors, INT_MAX >> 9);
- ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num,
- &host_offset, &meta);
- if (ret < 0) {
- return ret;
- }
-
- ret = qcow2_alloc_cluster_link_l2(bs, meta);
- if (ret < 0) {
- qcow2_free_any_clusters(bs, meta->alloc_offset, meta->nb_clusters,
- QCOW2_DISCARD_NEVER);
- return ret;
- }
-
- /* There are no dependent requests, but we need to remove our request
- * from the list of in-flight requests */
- if (meta != NULL) {
- QLIST_REMOVE(meta, next_in_flight);
- }
-
- /* TODO Preallocate data if requested */
-
- nb_sectors -= num;
- offset += num << 9;
- }
-
- /*
- * It is expected that the image file is large enough to actually contain
- * all of the allocated clusters (otherwise we get failing reads after
- * EOF). Extend the image to the last allocated sector.
- */
- if (host_offset != 0) {
- uint8_t buf[512];
- memset(buf, 0, 512);
- ret = bdrv_write(bs->file, (host_offset >> 9) + num - 1, buf, 1);
- if (ret < 0) {
- return ret;
- }
- }
-
- return 0;
-}
-
-static int qcow2_create2(const char *filename, int64_t total_size,
- const char *backing_file, const char *backing_format,
- int flags, size_t cluster_size, int prealloc,
- QEMUOptionParameter *options, int version)
-{
- /* Calculate cluster_bits */
- int cluster_bits;
- cluster_bits = ffs(cluster_size) - 1;
- if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS ||
- (1 << cluster_bits) != cluster_size)
- {
- error_report(
- "Cluster size must be a power of two between %d and %dk",
- 1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
- return -EINVAL;
- }
-
- /*
- * Open the image file and write a minimal qcow2 header.
- *
- * We keep things simple and start with a zero-sized image. We also
- * do without refcount blocks or a L1 table for now. We'll fix the
- * inconsistency later.
- *
- * We do need a refcount table because growing the refcount table means
- * allocating two new refcount blocks - the seconds of which would be at
- * 2 GB for 64k clusters, and we don't want to have a 2 GB initial file
- * size for any qcow2 image.
- */
- BlockDriverState* bs;
- QCowHeader header;
- uint8_t* refcount_table;
- int ret;
-
- ret = bdrv_create_file(filename, options);
- if (ret < 0) {
- return ret;
- }
-
- ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR);
- if (ret < 0) {
- return ret;
- }
-
- /* Write the header */
- memset(&header, 0, sizeof(header));
- header.magic = cpu_to_be32(QCOW_MAGIC);
- header.version = cpu_to_be32(version);
- header.cluster_bits = cpu_to_be32(cluster_bits);
- header.size = cpu_to_be64(0);
- header.l1_table_offset = cpu_to_be64(0);
- header.l1_size = cpu_to_be32(0);
- header.refcount_table_offset = cpu_to_be64(cluster_size);
- header.refcount_table_clusters = cpu_to_be32(1);
- header.refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT);
- header.header_length = cpu_to_be32(sizeof(header));
-
- if (flags & BLOCK_FLAG_ENCRYPT) {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
- } else {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
- }
-
- if (flags & BLOCK_FLAG_LAZY_REFCOUNTS) {
- header.compatible_features |=
- cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS);
- }
-
- ret = bdrv_pwrite(bs, 0, &header, sizeof(header));
- if (ret < 0) {
- goto out;
- }
-
- /* Write an empty refcount table */
- refcount_table = g_malloc0(cluster_size);
- ret = bdrv_pwrite(bs, cluster_size, refcount_table, cluster_size);
- g_free(refcount_table);
-
- if (ret < 0) {
- goto out;
- }
-
- bdrv_close(bs);
-
- /*
- * And now open the image and make it consistent first (i.e. increase the
- * refcount of the cluster that is occupied by the header and the refcount
- * table)
- */
- BlockDriver* drv = bdrv_find_format("qcow2");
- assert(drv != NULL);
- ret = bdrv_open(bs, filename, NULL,
- BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv);
- if (ret < 0) {
- goto out;
- }
-
- ret = qcow2_alloc_clusters(bs, 2 * cluster_size);
- if (ret < 0) {
- goto out;
-
- } else if (ret != 0) {
- error_report("Huh, first cluster in empty image is already in use?");
- abort();
- }
-
- /* Okay, now that we have a valid image, let's give it the right size */
- ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE);
- if (ret < 0) {
- goto out;
- }
-
- /* Want a backing file? There you go.*/
- if (backing_file) {
- ret = bdrv_change_backing_file(bs, backing_file, backing_format);
- if (ret < 0) {
- goto out;
- }
- }
-
- /* And if we're supposed to preallocate metadata, do that now */
- if (prealloc) {
- BDRVQcowState *s = bs->opaque;
- qemu_co_mutex_lock(&s->lock);
- ret = preallocate(bs);
- qemu_co_mutex_unlock(&s->lock);
- if (ret < 0) {
- goto out;
- }
- }
-
- ret = 0;
-out:
- bdrv_delete(bs);
- return ret;
-}
-
-static int qcow2_create(const char *filename, QEMUOptionParameter *options)
-{
- const char *backing_file = NULL;
- const char *backing_fmt = NULL;
- uint64_t sectors = 0;
- int flags = 0;
- size_t cluster_size = DEFAULT_CLUSTER_SIZE;
- int prealloc = 0;
- int version = 2;
-
- /* Read out options */
- while (options && options->name) {
- if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
- sectors = options->value.n / 512;
- } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
- backing_file = options->value.s;
- } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
- backing_fmt = options->value.s;
- } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
- flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
- } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
- if (options->value.n) {
- cluster_size = options->value.n;
- }
- } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
- if (!options->value.s || !strcmp(options->value.s, "off")) {
- prealloc = 0;
- } else if (!strcmp(options->value.s, "metadata")) {
- prealloc = 1;
- } else {
- fprintf(stderr, "Invalid preallocation mode: '%s'\n",
- options->value.s);
- return -EINVAL;
- }
- } else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) {
- if (!options->value.s || !strcmp(options->value.s, "0.10")) {
- version = 2;
- } else if (!strcmp(options->value.s, "1.1")) {
- version = 3;
- } else {
- fprintf(stderr, "Invalid compatibility level: '%s'\n",
- options->value.s);
- return -EINVAL;
- }
- } else if (!strcmp(options->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
- flags |= options->value.n ? BLOCK_FLAG_LAZY_REFCOUNTS : 0;
- }
- options++;
- }
-
- if (backing_file && prealloc) {
- fprintf(stderr, "Backing file and preallocation cannot be used at "
- "the same time\n");
- return -EINVAL;
- }
-
- if (version < 3 && (flags & BLOCK_FLAG_LAZY_REFCOUNTS)) {
- fprintf(stderr, "Lazy refcounts only supported with compatibility "
- "level 1.1 and above (use compat=1.1 or greater)\n");
- return -EINVAL;
- }
-
- return qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
- cluster_size, prealloc, options, version);
-}
-
-static int qcow2_make_empty(BlockDriverState *bs)
-{
-#if 0
- /* XXX: not correct */
- BDRVQcowState *s = bs->opaque;
- uint32_t l1_length = s->l1_size * sizeof(uint64_t);
- int ret;
-
- memset(s->l1_table, 0, l1_length);
- if (bdrv_pwrite(bs->file, s->l1_table_offset, s->l1_table, l1_length) < 0)
- return -1;
- ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
- if (ret < 0)
- return ret;
-
- l2_cache_reset(bs);
-#endif
- return 0;
-}
-
-static coroutine_fn int qcow2_co_write_zeroes(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors)
-{
- int ret;
- BDRVQcowState *s = bs->opaque;
-
- /* Emulate misaligned zero writes */
- if (sector_num % s->cluster_sectors || nb_sectors % s->cluster_sectors) {
- return -ENOTSUP;
- }
-
- /* Whatever is left can use real zero clusters */
- qemu_co_mutex_lock(&s->lock);
- ret = qcow2_zero_clusters(bs, sector_num << BDRV_SECTOR_BITS,
- nb_sectors);
- qemu_co_mutex_unlock(&s->lock);
-
- return ret;
-}
-
-static coroutine_fn int qcow2_co_discard(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors)
-{
- int ret;
- BDRVQcowState *s = bs->opaque;
-
- qemu_co_mutex_lock(&s->lock);
- ret = qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS,
- nb_sectors);
- qemu_co_mutex_unlock(&s->lock);
- return ret;
-}
-
-static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t new_l1_size;
- int ret;
-
- if (offset & 511) {
- error_report("The new size must be a multiple of 512");
- return -EINVAL;
- }
-
- /* cannot proceed if image has snapshots */
- if (s->nb_snapshots) {
- error_report("Can't resize an image which has snapshots");
- return -ENOTSUP;
- }
-
- /* shrinking is currently not supported */
- if (offset < bs->total_sectors * 512) {
- error_report("qcow2 doesn't support shrinking images yet");
- return -ENOTSUP;
- }
-
- new_l1_size = size_to_l1(s, offset);
- ret = qcow2_grow_l1_table(bs, new_l1_size, true);
- if (ret < 0) {
- return ret;
- }
-
- /* write updated header.size */
- offset = cpu_to_be64(offset);
- ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
- &offset, sizeof(uint64_t));
- if (ret < 0) {
- return ret;
- }
-
- s->l1_vm_state_index = new_l1_size;
- return 0;
-}
-
-/* XXX: put compressed sectors first, then all the cluster aligned
- tables to avoid losing bytes in alignment */
-static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- z_stream strm;
- int ret, out_len;
- uint8_t *out_buf;
- uint64_t cluster_offset;
-
- if (nb_sectors == 0) {
- /* align end of file to a sector boundary to ease reading with
- sector based I/Os */
- cluster_offset = bdrv_getlength(bs->file);
- cluster_offset = (cluster_offset + 511) & ~511;
- bdrv_truncate(bs->file, cluster_offset);
- return 0;
- }
-
- if (nb_sectors != s->cluster_sectors) {
- ret = -EINVAL;
-
- /* Zero-pad last write if image size is not cluster aligned */
- if (sector_num + nb_sectors == bs->total_sectors &&
- nb_sectors < s->cluster_sectors) {
- uint8_t *pad_buf = qemu_blockalign(bs, s->cluster_size);
- memset(pad_buf, 0, s->cluster_size);
- memcpy(pad_buf, buf, nb_sectors * BDRV_SECTOR_SIZE);
- ret = qcow2_write_compressed(bs, sector_num,
- pad_buf, s->cluster_sectors);
- qemu_vfree(pad_buf);
- }
- return ret;
- }
-
- out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
-
- /* best compression, small window, no zlib header */
- memset(&strm, 0, sizeof(strm));
- ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -12,
- 9, Z_DEFAULT_STRATEGY);
- if (ret != 0) {
- ret = -EINVAL;
- goto fail;
- }
-
- strm.avail_in = s->cluster_size;
- strm.next_in = (uint8_t *)buf;
- strm.avail_out = s->cluster_size;
- strm.next_out = out_buf;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END && ret != Z_OK) {
- deflateEnd(&strm);
- ret = -EINVAL;
- goto fail;
- }
- out_len = strm.next_out - out_buf;
-
- deflateEnd(&strm);
-
- if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
- /* could not compress: write normal cluster */
- ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
- if (ret < 0) {
- goto fail;
- }
- } else {
- cluster_offset = qcow2_alloc_compressed_cluster_offset(bs,
- sector_num << 9, out_len);
- if (!cluster_offset) {
- ret = -EIO;
- goto fail;
- }
- cluster_offset &= s->cluster_offset_mask;
- BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
- ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
- if (ret < 0) {
- goto fail;
- }
- }
-
- ret = 0;
-fail:
- g_free(out_buf);
- return ret;
-}
-
-static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int ret;
-
- qemu_co_mutex_lock(&s->lock);
- ret = qcow2_cache_flush(bs, s->l2_table_cache);
- if (ret < 0) {
- qemu_co_mutex_unlock(&s->lock);
- return ret;
- }
-
- if (qcow2_need_accurate_refcounts(s)) {
- ret = qcow2_cache_flush(bs, s->refcount_block_cache);
- if (ret < 0) {
- qemu_co_mutex_unlock(&s->lock);
- return ret;
- }
- }
- qemu_co_mutex_unlock(&s->lock);
-
- return 0;
-}
-
-static int64_t qcow2_vm_state_offset(BDRVQcowState *s)
-{
- return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
-}
-
-static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BDRVQcowState *s = bs->opaque;
- bdi->cluster_size = s->cluster_size;
- bdi->vm_state_offset = qcow2_vm_state_offset(s);
- return 0;
-}
-
-#if 0
-static void dump_refcounts(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- int64_t nb_clusters, k, k1, size;
- int refcount;
-
- size = bdrv_getlength(bs->file);
- nb_clusters = size_to_clusters(s, size);
- for(k = 0; k < nb_clusters;) {
- k1 = k;
- refcount = get_refcount(bs, k);
- k++;
- while (k < nb_clusters && get_refcount(bs, k) == refcount)
- k++;
- printf("%" PRId64 ": refcount=%d nb=%" PRId64 "\n", k, refcount,
- k - k1);
- }
-}
-#endif
-
-static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
- int64_t pos)
-{
- BDRVQcowState *s = bs->opaque;
- int growable = bs->growable;
- int ret;
-
- BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
- bs->growable = 1;
- ret = bdrv_pwritev(bs, qcow2_vm_state_offset(s) + pos, qiov);
- bs->growable = growable;
-
- return ret;
-}
-
-static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf,
- int64_t pos, int size)
-{
- BDRVQcowState *s = bs->opaque;
- int growable = bs->growable;
- int ret;
-
- BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD);
- bs->growable = 1;
- ret = bdrv_pread(bs, qcow2_vm_state_offset(s) + pos, buf, size);
- bs->growable = growable;
-
- return ret;
-}
-
-static QEMUOptionParameter qcow2_create_options[] = {
- {
- .name = BLOCK_OPT_SIZE,
- .type = OPT_SIZE,
- .help = "Virtual disk size"
- },
- {
- .name = BLOCK_OPT_COMPAT_LEVEL,
- .type = OPT_STRING,
- .help = "Compatibility level (0.10 or 1.1)"
- },
- {
- .name = BLOCK_OPT_BACKING_FILE,
- .type = OPT_STRING,
- .help = "File name of a base image"
- },
- {
- .name = BLOCK_OPT_BACKING_FMT,
- .type = OPT_STRING,
- .help = "Image format of the base image"
- },
- {
- .name = BLOCK_OPT_ENCRYPT,
- .type = OPT_FLAG,
- .help = "Encrypt the image"
- },
- {
- .name = BLOCK_OPT_CLUSTER_SIZE,
- .type = OPT_SIZE,
- .help = "qcow2 cluster size",
- .value = { .n = DEFAULT_CLUSTER_SIZE },
- },
- {
- .name = BLOCK_OPT_PREALLOC,
- .type = OPT_STRING,
- .help = "Preallocation mode (allowed values: off, metadata)"
- },
- {
- .name = BLOCK_OPT_LAZY_REFCOUNTS,
- .type = OPT_FLAG,
- .help = "Postpone refcount updates",
- },
- { NULL }
-};
-
-static BlockDriver bdrv_qcow2 = {
- .format_name = "qcow2",
- .instance_size = sizeof(BDRVQcowState),
- .bdrv_probe = qcow2_probe,
- .bdrv_open = qcow2_open,
- .bdrv_close = qcow2_close,
- .bdrv_reopen_prepare = qcow2_reopen_prepare,
- .bdrv_create = qcow2_create,
- .bdrv_has_zero_init = bdrv_has_zero_init_1,
- .bdrv_co_is_allocated = qcow2_co_is_allocated,
- .bdrv_set_key = qcow2_set_key,
- .bdrv_make_empty = qcow2_make_empty,
-
- .bdrv_co_readv = qcow2_co_readv,
- .bdrv_co_writev = qcow2_co_writev,
- .bdrv_co_flush_to_os = qcow2_co_flush_to_os,
-
- .bdrv_co_write_zeroes = qcow2_co_write_zeroes,
- .bdrv_co_discard = qcow2_co_discard,
- .bdrv_truncate = qcow2_truncate,
- .bdrv_write_compressed = qcow2_write_compressed,
-
- .bdrv_snapshot_create = qcow2_snapshot_create,
- .bdrv_snapshot_goto = qcow2_snapshot_goto,
- .bdrv_snapshot_delete = qcow2_snapshot_delete,
- .bdrv_snapshot_list = qcow2_snapshot_list,
- .bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp,
- .bdrv_get_info = qcow2_get_info,
-
- .bdrv_save_vmstate = qcow2_save_vmstate,
- .bdrv_load_vmstate = qcow2_load_vmstate,
-
- .bdrv_change_backing_file = qcow2_change_backing_file,
-
- .bdrv_invalidate_cache = qcow2_invalidate_cache,
-
- .create_options = qcow2_create_options,
- .bdrv_check = qcow2_check,
-};
-
-static void bdrv_qcow2_init(void)
-{
- bdrv_register(&bdrv_qcow2);
-}
-
-block_init(bdrv_qcow2_init);
diff --git a/contrib/qemu/block/qcow2.h b/contrib/qemu/block/qcow2.h
deleted file mode 100644
index 3b2d5cda71f..00000000000
--- a/contrib/qemu/block/qcow2.h
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Block driver for the QCOW version 2 format
- *
- * Copyright (c) 2004-2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef BLOCK_QCOW2_H
-#define BLOCK_QCOW2_H
-
-#include "qemu/aes.h"
-#include "block/coroutine.h"
-
-//#define DEBUG_ALLOC
-//#define DEBUG_ALLOC2
-//#define DEBUG_EXT
-
-#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
-
-#define QCOW_CRYPT_NONE 0
-#define QCOW_CRYPT_AES 1
-
-#define QCOW_MAX_CRYPT_CLUSTERS 32
-
-/* indicate that the refcount of the referenced cluster is exactly one. */
-#define QCOW_OFLAG_COPIED (1LL << 63)
-/* indicate that the cluster is compressed (they never have the copied flag) */
-#define QCOW_OFLAG_COMPRESSED (1LL << 62)
-/* The cluster reads as all zeros */
-#define QCOW_OFLAG_ZERO (1LL << 0)
-
-#define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
-
-#define MIN_CLUSTER_BITS 9
-#define MAX_CLUSTER_BITS 21
-
-#define L2_CACHE_SIZE 16
-
-/* Must be at least 4 to cover all cases of refcount table growth */
-#define REFCOUNT_CACHE_SIZE 4
-
-#define DEFAULT_CLUSTER_SIZE 65536
-
-
-#define QCOW2_OPT_LAZY_REFCOUNTS "lazy_refcounts"
-#define QCOW2_OPT_DISCARD_REQUEST "pass_discard_request"
-#define QCOW2_OPT_DISCARD_SNAPSHOT "pass_discard_snapshot"
-#define QCOW2_OPT_DISCARD_OTHER "pass_discard_other"
-
-typedef struct QCowHeader {
- uint32_t magic;
- uint32_t version;
- uint64_t backing_file_offset;
- uint32_t backing_file_size;
- uint32_t cluster_bits;
- uint64_t size; /* in bytes */
- uint32_t crypt_method;
- uint32_t l1_size; /* XXX: save number of clusters instead ? */
- uint64_t l1_table_offset;
- uint64_t refcount_table_offset;
- uint32_t refcount_table_clusters;
- uint32_t nb_snapshots;
- uint64_t snapshots_offset;
-
- /* The following fields are only valid for version >= 3 */
- uint64_t incompatible_features;
- uint64_t compatible_features;
- uint64_t autoclear_features;
-
- uint32_t refcount_order;
- uint32_t header_length;
-} QCowHeader;
-
-typedef struct QCowSnapshot {
- uint64_t l1_table_offset;
- uint32_t l1_size;
- char *id_str;
- char *name;
- uint64_t disk_size;
- uint64_t vm_state_size;
- uint32_t date_sec;
- uint32_t date_nsec;
- uint64_t vm_clock_nsec;
-} QCowSnapshot;
-
-struct Qcow2Cache;
-typedef struct Qcow2Cache Qcow2Cache;
-
-typedef struct Qcow2UnknownHeaderExtension {
- uint32_t magic;
- uint32_t len;
- QLIST_ENTRY(Qcow2UnknownHeaderExtension) next;
- uint8_t data[];
-} Qcow2UnknownHeaderExtension;
-
-enum {
- QCOW2_FEAT_TYPE_INCOMPATIBLE = 0,
- QCOW2_FEAT_TYPE_COMPATIBLE = 1,
- QCOW2_FEAT_TYPE_AUTOCLEAR = 2,
-};
-
-/* Incompatible feature bits */
-enum {
- QCOW2_INCOMPAT_DIRTY_BITNR = 0,
- QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
-
- QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY,
-};
-
-/* Compatible feature bits */
-enum {
- QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR = 0,
- QCOW2_COMPAT_LAZY_REFCOUNTS = 1 << QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
-
- QCOW2_COMPAT_FEAT_MASK = QCOW2_COMPAT_LAZY_REFCOUNTS,
-};
-
-enum qcow2_discard_type {
- QCOW2_DISCARD_NEVER = 0,
- QCOW2_DISCARD_ALWAYS,
- QCOW2_DISCARD_REQUEST,
- QCOW2_DISCARD_SNAPSHOT,
- QCOW2_DISCARD_OTHER,
- QCOW2_DISCARD_MAX
-};
-
-typedef struct Qcow2Feature {
- uint8_t type;
- uint8_t bit;
- char name[46];
-} QEMU_PACKED Qcow2Feature;
-
-typedef struct Qcow2DiscardRegion {
- BlockDriverState *bs;
- uint64_t offset;
- uint64_t bytes;
- QTAILQ_ENTRY(Qcow2DiscardRegion) next;
-} Qcow2DiscardRegion;
-
-typedef struct BDRVQcowState {
- int cluster_bits;
- int cluster_size;
- int cluster_sectors;
- int l2_bits;
- int l2_size;
- int l1_size;
- int l1_vm_state_index;
- int csize_shift;
- int csize_mask;
- uint64_t cluster_offset_mask;
- uint64_t l1_table_offset;
- uint64_t *l1_table;
-
- Qcow2Cache* l2_table_cache;
- Qcow2Cache* refcount_block_cache;
-
- uint8_t *cluster_cache;
- uint8_t *cluster_data;
- uint64_t cluster_cache_offset;
- QLIST_HEAD(QCowClusterAlloc, QCowL2Meta) cluster_allocs;
-
- uint64_t *refcount_table;
- uint64_t refcount_table_offset;
- uint32_t refcount_table_size;
- int64_t free_cluster_index;
- int64_t free_byte_offset;
-
- CoMutex lock;
-
- uint32_t crypt_method; /* current crypt method, 0 if no key yet */
- uint32_t crypt_method_header;
- AES_KEY aes_encrypt_key;
- AES_KEY aes_decrypt_key;
- uint64_t snapshots_offset;
- int snapshots_size;
- int nb_snapshots;
- QCowSnapshot *snapshots;
-
- int flags;
- int qcow_version;
- bool use_lazy_refcounts;
-
- bool discard_passthrough[QCOW2_DISCARD_MAX];
-
- uint64_t incompatible_features;
- uint64_t compatible_features;
- uint64_t autoclear_features;
-
- size_t unknown_header_fields_size;
- void* unknown_header_fields;
- QLIST_HEAD(, Qcow2UnknownHeaderExtension) unknown_header_ext;
- QTAILQ_HEAD (, Qcow2DiscardRegion) discards;
- bool cache_discards;
-} BDRVQcowState;
-
-/* XXX: use std qcow open function ? */
-typedef struct QCowCreateState {
- int cluster_size;
- int cluster_bits;
- uint16_t *refcount_block;
- uint64_t *refcount_table;
- int64_t l1_table_offset;
- int64_t refcount_table_offset;
- int64_t refcount_block_offset;
-} QCowCreateState;
-
-struct QCowAIOCB;
-
-typedef struct Qcow2COWRegion {
- /**
- * Offset of the COW region in bytes from the start of the first cluster
- * touched by the request.
- */
- uint64_t offset;
-
- /** Number of sectors to copy */
- int nb_sectors;
-} Qcow2COWRegion;
-
-/**
- * Describes an in-flight (part of a) write request that writes to clusters
- * that are not referenced in their L2 table yet.
- */
-typedef struct QCowL2Meta
-{
- /** Guest offset of the first newly allocated cluster */
- uint64_t offset;
-
- /** Host offset of the first newly allocated cluster */
- uint64_t alloc_offset;
-
- /**
- * Number of sectors from the start of the first allocated cluster to
- * the end of the (possibly shortened) request
- */
- int nb_available;
-
- /** Number of newly allocated clusters */
- int nb_clusters;
-
- /**
- * Requests that overlap with this allocation and wait to be restarted
- * when the allocating request has completed.
- */
- CoQueue dependent_requests;
-
- /**
- * The COW Region between the start of the first allocated cluster and the
- * area the guest actually writes to.
- */
- Qcow2COWRegion cow_start;
-
- /**
- * The COW Region between the area the guest actually writes to and the
- * end of the last allocated cluster.
- */
- Qcow2COWRegion cow_end;
-
- /** Pointer to next L2Meta of the same write request */
- struct QCowL2Meta *next;
-
- QLIST_ENTRY(QCowL2Meta) next_in_flight;
-} QCowL2Meta;
-
-enum {
- QCOW2_CLUSTER_UNALLOCATED,
- QCOW2_CLUSTER_NORMAL,
- QCOW2_CLUSTER_COMPRESSED,
- QCOW2_CLUSTER_ZERO
-};
-
-#define L1E_OFFSET_MASK 0x00ffffffffffff00ULL
-#define L2E_OFFSET_MASK 0x00ffffffffffff00ULL
-#define L2E_COMPRESSED_OFFSET_SIZE_MASK 0x3fffffffffffffffULL
-
-#define REFT_OFFSET_MASK 0xffffffffffffff00ULL
-
-static inline int64_t start_of_cluster(BDRVQcowState *s, int64_t offset)
-{
- return offset & ~(s->cluster_size - 1);
-}
-
-static inline int64_t offset_into_cluster(BDRVQcowState *s, int64_t offset)
-{
- return offset & (s->cluster_size - 1);
-}
-
-static inline int size_to_clusters(BDRVQcowState *s, int64_t size)
-{
- return (size + (s->cluster_size - 1)) >> s->cluster_bits;
-}
-
-static inline int64_t size_to_l1(BDRVQcowState *s, int64_t size)
-{
- int shift = s->cluster_bits + s->l2_bits;
- return (size + (1ULL << shift) - 1) >> shift;
-}
-
-static inline int offset_to_l2_index(BDRVQcowState *s, int64_t offset)
-{
- return (offset >> s->cluster_bits) & (s->l2_size - 1);
-}
-
-static inline int64_t align_offset(int64_t offset, int n)
-{
- offset = (offset + n - 1) & ~(n - 1);
- return offset;
-}
-
-static inline int qcow2_get_cluster_type(uint64_t l2_entry)
-{
- if (l2_entry & QCOW_OFLAG_COMPRESSED) {
- return QCOW2_CLUSTER_COMPRESSED;
- } else if (l2_entry & QCOW_OFLAG_ZERO) {
- return QCOW2_CLUSTER_ZERO;
- } else if (!(l2_entry & L2E_OFFSET_MASK)) {
- return QCOW2_CLUSTER_UNALLOCATED;
- } else {
- return QCOW2_CLUSTER_NORMAL;
- }
-}
-
-/* Check whether refcounts are eager or lazy */
-static inline bool qcow2_need_accurate_refcounts(BDRVQcowState *s)
-{
- return !(s->incompatible_features & QCOW2_INCOMPAT_DIRTY);
-}
-
-static inline uint64_t l2meta_cow_start(QCowL2Meta *m)
-{
- return m->offset + m->cow_start.offset;
-}
-
-static inline uint64_t l2meta_cow_end(QCowL2Meta *m)
-{
- return m->offset + m->cow_end.offset
- + (m->cow_end.nb_sectors << BDRV_SECTOR_BITS);
-}
-
-// FIXME Need qcow2_ prefix to global functions
-
-/* qcow2.c functions */
-int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
- int64_t sector_num, int nb_sectors);
-
-int qcow2_mark_dirty(BlockDriverState *bs);
-int qcow2_update_header(BlockDriverState *bs);
-
-/* qcow2-refcount.c functions */
-int qcow2_refcount_init(BlockDriverState *bs);
-void qcow2_refcount_close(BlockDriverState *bs);
-
-int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size);
-int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
- int nb_clusters);
-int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size);
-void qcow2_free_clusters(BlockDriverState *bs,
- int64_t offset, int64_t size,
- enum qcow2_discard_type type);
-void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t l2_entry,
- int nb_clusters, enum qcow2_discard_type type);
-
-int qcow2_update_snapshot_refcount(BlockDriverState *bs,
- int64_t l1_table_offset, int l1_size, int addend);
-
-int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
- BdrvCheckMode fix);
-
-void qcow2_process_discards(BlockDriverState *bs, int ret);
-
-/* qcow2-cluster.c functions */
-int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
- bool exact_size);
-void qcow2_l2_cache_reset(BlockDriverState *bs);
-int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
-void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
- uint8_t *out_buf, const uint8_t *in_buf,
- int nb_sectors, int enc,
- const AES_KEY *key);
-
-int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
- int *num, uint64_t *cluster_offset);
-int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
- int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m);
-uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
- uint64_t offset,
- int compressed_size);
-
-int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
-int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
- int nb_sectors);
-int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors);
-
-/* qcow2-snapshot.c functions */
-int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
-int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id);
-int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
-int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
-int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name);
-
-void qcow2_free_snapshots(BlockDriverState *bs);
-int qcow2_read_snapshots(BlockDriverState *bs);
-
-/* qcow2-cache.c functions */
-Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables);
-int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
-
-void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
-int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
-int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
- Qcow2Cache *dependency);
-void qcow2_cache_depends_on_flush(Qcow2Cache *c);
-
-int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
- void **table);
-int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
- void **table);
-int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table);
-
-#endif
diff --git a/contrib/qemu/block/qed-check.c b/contrib/qemu/block/qed-check.c
deleted file mode 100644
index b473dcd61f6..00000000000
--- a/contrib/qemu/block/qed-check.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * QEMU Enhanced Disk Format Consistency Check
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qed.h"
-
-typedef struct {
- BDRVQEDState *s;
- BdrvCheckResult *result;
- bool fix; /* whether to fix invalid offsets */
-
- uint64_t nclusters;
- uint32_t *used_clusters; /* referenced cluster bitmap */
-
- QEDRequest request;
-} QEDCheck;
-
-static bool qed_test_bit(uint32_t *bitmap, uint64_t n) {
- return !!(bitmap[n / 32] & (1 << (n % 32)));
-}
-
-static void qed_set_bit(uint32_t *bitmap, uint64_t n) {
- bitmap[n / 32] |= 1 << (n % 32);
-}
-
-/**
- * Set bitmap bits for clusters
- *
- * @check: Check structure
- * @offset: Starting offset in bytes
- * @n: Number of clusters
- */
-static bool qed_set_used_clusters(QEDCheck *check, uint64_t offset,
- unsigned int n)
-{
- uint64_t cluster = qed_bytes_to_clusters(check->s, offset);
- unsigned int corruptions = 0;
-
- while (n-- != 0) {
- /* Clusters should only be referenced once */
- if (qed_test_bit(check->used_clusters, cluster)) {
- corruptions++;
- }
-
- qed_set_bit(check->used_clusters, cluster);
- cluster++;
- }
-
- check->result->corruptions += corruptions;
- return corruptions == 0;
-}
-
-/**
- * Check an L2 table
- *
- * @ret: Number of invalid cluster offsets
- */
-static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
-{
- BDRVQEDState *s = check->s;
- unsigned int i, num_invalid = 0;
- uint64_t last_offset = 0;
-
- for (i = 0; i < s->table_nelems; i++) {
- uint64_t offset = table->offsets[i];
-
- if (qed_offset_is_unalloc_cluster(offset) ||
- qed_offset_is_zero_cluster(offset)) {
- continue;
- }
- check->result->bfi.allocated_clusters++;
- if (last_offset && (last_offset + s->header.cluster_size != offset)) {
- check->result->bfi.fragmented_clusters++;
- }
- last_offset = offset;
-
- /* Detect invalid cluster offset */
- if (!qed_check_cluster_offset(s, offset)) {
- if (check->fix) {
- table->offsets[i] = 0;
- check->result->corruptions_fixed++;
- } else {
- check->result->corruptions++;
- }
-
- num_invalid++;
- continue;
- }
-
- qed_set_used_clusters(check, offset, 1);
- }
-
- return num_invalid;
-}
-
-/**
- * Descend tables and check each cluster is referenced once only
- */
-static int qed_check_l1_table(QEDCheck *check, QEDTable *table)
-{
- BDRVQEDState *s = check->s;
- unsigned int i, num_invalid_l1 = 0;
- int ret, last_error = 0;
-
- /* Mark L1 table clusters used */
- qed_set_used_clusters(check, s->header.l1_table_offset,
- s->header.table_size);
-
- for (i = 0; i < s->table_nelems; i++) {
- unsigned int num_invalid_l2;
- uint64_t offset = table->offsets[i];
-
- if (qed_offset_is_unalloc_cluster(offset)) {
- continue;
- }
-
- /* Detect invalid L2 offset */
- if (!qed_check_table_offset(s, offset)) {
- /* Clear invalid offset */
- if (check->fix) {
- table->offsets[i] = 0;
- check->result->corruptions_fixed++;
- } else {
- check->result->corruptions++;
- }
-
- num_invalid_l1++;
- continue;
- }
-
- if (!qed_set_used_clusters(check, offset, s->header.table_size)) {
- continue; /* skip an invalid table */
- }
-
- ret = qed_read_l2_table_sync(s, &check->request, offset);
- if (ret) {
- check->result->check_errors++;
- last_error = ret;
- continue;
- }
-
- num_invalid_l2 = qed_check_l2_table(check,
- check->request.l2_table->table);
-
- /* Write out fixed L2 table */
- if (num_invalid_l2 > 0 && check->fix) {
- ret = qed_write_l2_table_sync(s, &check->request, 0,
- s->table_nelems, false);
- if (ret) {
- check->result->check_errors++;
- last_error = ret;
- continue;
- }
- }
- }
-
- /* Drop reference to final table */
- qed_unref_l2_cache_entry(check->request.l2_table);
- check->request.l2_table = NULL;
-
- /* Write out fixed L1 table */
- if (num_invalid_l1 > 0 && check->fix) {
- ret = qed_write_l1_table_sync(s, 0, s->table_nelems);
- if (ret) {
- check->result->check_errors++;
- last_error = ret;
- }
- }
-
- return last_error;
-}
-
-/**
- * Check for unreferenced (leaked) clusters
- */
-static void qed_check_for_leaks(QEDCheck *check)
-{
- BDRVQEDState *s = check->s;
- uint64_t i;
-
- for (i = s->header.header_size; i < check->nclusters; i++) {
- if (!qed_test_bit(check->used_clusters, i)) {
- check->result->leaks++;
- }
- }
-}
-
-/**
- * Mark an image clean once it passes check or has been repaired
- */
-static void qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result)
-{
- /* Skip if there were unfixable corruptions or I/O errors */
- if (result->corruptions > 0 || result->check_errors > 0) {
- return;
- }
-
- /* Skip if image is already marked clean */
- if (!(s->header.features & QED_F_NEED_CHECK)) {
- return;
- }
-
- /* Ensure fixes reach storage before clearing check bit */
- bdrv_flush(s->bs);
-
- s->header.features &= ~QED_F_NEED_CHECK;
- qed_write_header_sync(s);
-}
-
-int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
-{
- QEDCheck check = {
- .s = s,
- .result = result,
- .nclusters = qed_bytes_to_clusters(s, s->file_size),
- .request = { .l2_table = NULL },
- .fix = fix,
- };
- int ret;
-
- check.used_clusters = g_malloc0(((check.nclusters + 31) / 32) *
- sizeof(check.used_clusters[0]));
-
- check.result->bfi.total_clusters =
- (s->header.image_size + s->header.cluster_size - 1) /
- s->header.cluster_size;
- ret = qed_check_l1_table(&check, s->l1_table);
- if (ret == 0) {
- /* Only check for leaks if entire image was scanned successfully */
- qed_check_for_leaks(&check);
-
- if (fix) {
- qed_check_mark_clean(s, result);
- }
- }
-
- g_free(check.used_clusters);
- return ret;
-}
diff --git a/contrib/qemu/block/qed-cluster.c b/contrib/qemu/block/qed-cluster.c
deleted file mode 100644
index f64b2af8f7e..00000000000
--- a/contrib/qemu/block/qed-cluster.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * QEMU Enhanced Disk Format Cluster functions
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qed.h"
-
-/**
- * Count the number of contiguous data clusters
- *
- * @s: QED state
- * @table: L2 table
- * @index: First cluster index
- * @n: Maximum number of clusters
- * @offset: Set to first cluster offset
- *
- * This function scans tables for contiguous clusters. A contiguous run of
- * clusters may be allocated, unallocated, or zero.
- */
-static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s,
- QEDTable *table,
- unsigned int index,
- unsigned int n,
- uint64_t *offset)
-{
- unsigned int end = MIN(index + n, s->table_nelems);
- uint64_t last = table->offsets[index];
- unsigned int i;
-
- *offset = last;
-
- for (i = index + 1; i < end; i++) {
- if (qed_offset_is_unalloc_cluster(last)) {
- /* Counting unallocated clusters */
- if (!qed_offset_is_unalloc_cluster(table->offsets[i])) {
- break;
- }
- } else if (qed_offset_is_zero_cluster(last)) {
- /* Counting zero clusters */
- if (!qed_offset_is_zero_cluster(table->offsets[i])) {
- break;
- }
- } else {
- /* Counting allocated clusters */
- if (table->offsets[i] != last + s->header.cluster_size) {
- break;
- }
- last = table->offsets[i];
- }
- }
- return i - index;
-}
-
-typedef struct {
- BDRVQEDState *s;
- uint64_t pos;
- size_t len;
-
- QEDRequest *request;
-
- /* User callback */
- QEDFindClusterFunc *cb;
- void *opaque;
-} QEDFindClusterCB;
-
-static void qed_find_cluster_cb(void *opaque, int ret)
-{
- QEDFindClusterCB *find_cluster_cb = opaque;
- BDRVQEDState *s = find_cluster_cb->s;
- QEDRequest *request = find_cluster_cb->request;
- uint64_t offset = 0;
- size_t len = 0;
- unsigned int index;
- unsigned int n;
-
- if (ret) {
- goto out;
- }
-
- index = qed_l2_index(s, find_cluster_cb->pos);
- n = qed_bytes_to_clusters(s,
- qed_offset_into_cluster(s, find_cluster_cb->pos) +
- find_cluster_cb->len);
- n = qed_count_contiguous_clusters(s, request->l2_table->table,
- index, n, &offset);
-
- if (qed_offset_is_unalloc_cluster(offset)) {
- ret = QED_CLUSTER_L2;
- } else if (qed_offset_is_zero_cluster(offset)) {
- ret = QED_CLUSTER_ZERO;
- } else if (qed_check_cluster_offset(s, offset)) {
- ret = QED_CLUSTER_FOUND;
- } else {
- ret = -EINVAL;
- }
-
- len = MIN(find_cluster_cb->len, n * s->header.cluster_size -
- qed_offset_into_cluster(s, find_cluster_cb->pos));
-
-out:
- find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len);
- g_free(find_cluster_cb);
-}
-
-/**
- * Find the offset of a data cluster
- *
- * @s: QED state
- * @request: L2 cache entry
- * @pos: Byte position in device
- * @len: Number of bytes
- * @cb: Completion function
- * @opaque: User data for completion function
- *
- * This function translates a position in the block device to an offset in the
- * image file. It invokes the cb completion callback to report back the
- * translated offset or unallocated range in the image file.
- *
- * If the L2 table exists, request->l2_table points to the L2 table cache entry
- * and the caller must free the reference when they are finished. The cache
- * entry is exposed in this way to avoid callers having to read the L2 table
- * again later during request processing. If request->l2_table is non-NULL it
- * will be unreferenced before taking on the new cache entry.
- */
-void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
- size_t len, QEDFindClusterFunc *cb, void *opaque)
-{
- QEDFindClusterCB *find_cluster_cb;
- uint64_t l2_offset;
-
- /* Limit length to L2 boundary. Requests are broken up at the L2 boundary
- * so that a request acts on one L2 table at a time.
- */
- len = MIN(len, (((pos >> s->l1_shift) + 1) << s->l1_shift) - pos);
-
- l2_offset = s->l1_table->offsets[qed_l1_index(s, pos)];
- if (qed_offset_is_unalloc_cluster(l2_offset)) {
- cb(opaque, QED_CLUSTER_L1, 0, len);
- return;
- }
- if (!qed_check_table_offset(s, l2_offset)) {
- cb(opaque, -EINVAL, 0, 0);
- return;
- }
-
- find_cluster_cb = g_malloc(sizeof(*find_cluster_cb));
- find_cluster_cb->s = s;
- find_cluster_cb->pos = pos;
- find_cluster_cb->len = len;
- find_cluster_cb->cb = cb;
- find_cluster_cb->opaque = opaque;
- find_cluster_cb->request = request;
-
- qed_read_l2_table(s, request, l2_offset,
- qed_find_cluster_cb, find_cluster_cb);
-}
diff --git a/contrib/qemu/block/qed-gencb.c b/contrib/qemu/block/qed-gencb.c
deleted file mode 100644
index 7d7ac1ffc8e..00000000000
--- a/contrib/qemu/block/qed-gencb.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * QEMU Enhanced Disk Format
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qed.h"
-
-void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque)
-{
- GenericCB *gencb = g_malloc(len);
- gencb->cb = cb;
- gencb->opaque = opaque;
- return gencb;
-}
-
-void gencb_complete(void *opaque, int ret)
-{
- GenericCB *gencb = opaque;
- BlockDriverCompletionFunc *cb = gencb->cb;
- void *user_opaque = gencb->opaque;
-
- g_free(gencb);
- cb(user_opaque, ret);
-}
diff --git a/contrib/qemu/block/qed-l2-cache.c b/contrib/qemu/block/qed-l2-cache.c
deleted file mode 100644
index e9b2aae44d9..00000000000
--- a/contrib/qemu/block/qed-l2-cache.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * QEMU Enhanced Disk Format L2 Cache
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-/*
- * L2 table cache usage is as follows:
- *
- * An open image has one L2 table cache that is used to avoid accessing the
- * image file for recently referenced L2 tables.
- *
- * Cluster offset lookup translates the logical offset within the block device
- * to a cluster offset within the image file. This is done by indexing into
- * the L1 and L2 tables which store cluster offsets. It is here where the L2
- * table cache serves up recently referenced L2 tables.
- *
- * If there is a cache miss, that L2 table is read from the image file and
- * committed to the cache. Subsequent accesses to that L2 table will be served
- * from the cache until the table is evicted from the cache.
- *
- * L2 tables are also committed to the cache when new L2 tables are allocated
- * in the image file. Since the L2 table cache is write-through, the new L2
- * table is first written out to the image file and then committed to the
- * cache.
- *
- * Multiple I/O requests may be using an L2 table cache entry at any given
- * time. That means an entry may be in use across several requests and
- * reference counting is needed to free the entry at the correct time. In
- * particular, an entry evicted from the cache will only be freed once all
- * references are dropped.
- *
- * An in-flight I/O request will hold a reference to a L2 table cache entry for
- * the period during which it needs to access the L2 table. This includes
- * cluster offset lookup, L2 table allocation, and L2 table update when a new
- * data cluster has been allocated.
- *
- * An interesting case occurs when two requests need to access an L2 table that
- * is not in the cache. Since the operation to read the table from the image
- * file takes some time to complete, both requests may see a cache miss and
- * start reading the L2 table from the image file. The first to finish will
- * commit its L2 table into the cache. When the second tries to commit its
- * table will be deleted in favor of the existing cache entry.
- */
-
-#include "trace.h"
-#include "qed.h"
-
-/* Each L2 holds 2GB so this let's us fully cache a 100GB disk */
-#define MAX_L2_CACHE_SIZE 50
-
-/**
- * Initialize the L2 cache
- */
-void qed_init_l2_cache(L2TableCache *l2_cache)
-{
- QTAILQ_INIT(&l2_cache->entries);
- l2_cache->n_entries = 0;
-}
-
-/**
- * Free the L2 cache
- */
-void qed_free_l2_cache(L2TableCache *l2_cache)
-{
- CachedL2Table *entry, *next_entry;
-
- QTAILQ_FOREACH_SAFE(entry, &l2_cache->entries, node, next_entry) {
- qemu_vfree(entry->table);
- g_free(entry);
- }
-}
-
-/**
- * Allocate an uninitialized entry from the cache
- *
- * The returned entry has a reference count of 1 and is owned by the caller.
- * The caller must allocate the actual table field for this entry and it must
- * be freeable using qemu_vfree().
- */
-CachedL2Table *qed_alloc_l2_cache_entry(L2TableCache *l2_cache)
-{
- CachedL2Table *entry;
-
- entry = g_malloc0(sizeof(*entry));
- entry->ref++;
-
- trace_qed_alloc_l2_cache_entry(l2_cache, entry);
-
- return entry;
-}
-
-/**
- * Decrease an entry's reference count and free if necessary when the reference
- * count drops to zero.
- */
-void qed_unref_l2_cache_entry(CachedL2Table *entry)
-{
- if (!entry) {
- return;
- }
-
- entry->ref--;
- trace_qed_unref_l2_cache_entry(entry, entry->ref);
- if (entry->ref == 0) {
- qemu_vfree(entry->table);
- g_free(entry);
- }
-}
-
-/**
- * Find an entry in the L2 cache. This may return NULL and it's up to the
- * caller to satisfy the cache miss.
- *
- * For a cached entry, this function increases the reference count and returns
- * the entry.
- */
-CachedL2Table *qed_find_l2_cache_entry(L2TableCache *l2_cache, uint64_t offset)
-{
- CachedL2Table *entry;
-
- QTAILQ_FOREACH(entry, &l2_cache->entries, node) {
- if (entry->offset == offset) {
- trace_qed_find_l2_cache_entry(l2_cache, entry, offset, entry->ref);
- entry->ref++;
- return entry;
- }
- }
- return NULL;
-}
-
-/**
- * Commit an L2 cache entry into the cache. This is meant to be used as part of
- * the process to satisfy a cache miss. A caller would allocate an entry which
- * is not actually in the L2 cache and then once the entry was valid and
- * present on disk, the entry can be committed into the cache.
- *
- * Since the cache is write-through, it's important that this function is not
- * called until the entry is present on disk and the L1 has been updated to
- * point to the entry.
- *
- * N.B. This function steals a reference to the l2_table from the caller so the
- * caller must obtain a new reference by issuing a call to
- * qed_find_l2_cache_entry().
- */
-void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table)
-{
- CachedL2Table *entry;
-
- entry = qed_find_l2_cache_entry(l2_cache, l2_table->offset);
- if (entry) {
- qed_unref_l2_cache_entry(entry);
- qed_unref_l2_cache_entry(l2_table);
- return;
- }
-
- /* Evict an unused cache entry so we have space. If all entries are in use
- * we can grow the cache temporarily and we try to shrink back down later.
- */
- if (l2_cache->n_entries >= MAX_L2_CACHE_SIZE) {
- CachedL2Table *next;
- QTAILQ_FOREACH_SAFE(entry, &l2_cache->entries, node, next) {
- if (entry->ref > 1) {
- continue;
- }
-
- QTAILQ_REMOVE(&l2_cache->entries, entry, node);
- l2_cache->n_entries--;
- qed_unref_l2_cache_entry(entry);
-
- /* Stop evicting when we've shrunk back to max size */
- if (l2_cache->n_entries < MAX_L2_CACHE_SIZE) {
- break;
- }
- }
- }
-
- l2_cache->n_entries++;
- QTAILQ_INSERT_TAIL(&l2_cache->entries, l2_table, node);
-}
diff --git a/contrib/qemu/block/qed-table.c b/contrib/qemu/block/qed-table.c
deleted file mode 100644
index 76d2dcccf81..00000000000
--- a/contrib/qemu/block/qed-table.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * QEMU Enhanced Disk Format Table I/O
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "trace.h"
-#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
-#include "qed.h"
-
-typedef struct {
- GenericCB gencb;
- BDRVQEDState *s;
- QEDTable *table;
-
- struct iovec iov;
- QEMUIOVector qiov;
-} QEDReadTableCB;
-
-static void qed_read_table_cb(void *opaque, int ret)
-{
- QEDReadTableCB *read_table_cb = opaque;
- QEDTable *table = read_table_cb->table;
- int noffsets = read_table_cb->qiov.size / sizeof(uint64_t);
- int i;
-
- /* Handle I/O error */
- if (ret) {
- goto out;
- }
-
- /* Byteswap offsets */
- for (i = 0; i < noffsets; i++) {
- table->offsets[i] = le64_to_cpu(table->offsets[i]);
- }
-
-out:
- /* Completion */
- trace_qed_read_table_cb(read_table_cb->s, read_table_cb->table, ret);
- gencb_complete(&read_table_cb->gencb, ret);
-}
-
-static void qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- QEDReadTableCB *read_table_cb = gencb_alloc(sizeof(*read_table_cb),
- cb, opaque);
- QEMUIOVector *qiov = &read_table_cb->qiov;
-
- trace_qed_read_table(s, offset, table);
-
- read_table_cb->s = s;
- read_table_cb->table = table;
- read_table_cb->iov.iov_base = table->offsets,
- read_table_cb->iov.iov_len = s->header.cluster_size * s->header.table_size,
-
- qemu_iovec_init_external(qiov, &read_table_cb->iov, 1);
- bdrv_aio_readv(s->bs->file, offset / BDRV_SECTOR_SIZE, qiov,
- qiov->size / BDRV_SECTOR_SIZE,
- qed_read_table_cb, read_table_cb);
-}
-
-typedef struct {
- GenericCB gencb;
- BDRVQEDState *s;
- QEDTable *orig_table;
- QEDTable *table;
- bool flush; /* flush after write? */
-
- struct iovec iov;
- QEMUIOVector qiov;
-} QEDWriteTableCB;
-
-static void qed_write_table_cb(void *opaque, int ret)
-{
- QEDWriteTableCB *write_table_cb = opaque;
-
- trace_qed_write_table_cb(write_table_cb->s,
- write_table_cb->orig_table,
- write_table_cb->flush,
- ret);
-
- if (ret) {
- goto out;
- }
-
- if (write_table_cb->flush) {
- /* We still need to flush first */
- write_table_cb->flush = false;
- bdrv_aio_flush(write_table_cb->s->bs, qed_write_table_cb,
- write_table_cb);
- return;
- }
-
-out:
- qemu_vfree(write_table_cb->table);
- gencb_complete(&write_table_cb->gencb, ret);
-}
-
-/**
- * Write out an updated part or all of a table
- *
- * @s: QED state
- * @offset: Offset of table in image file, in bytes
- * @table: Table
- * @index: Index of first element
- * @n: Number of elements
- * @flush: Whether or not to sync to disk
- * @cb: Completion function
- * @opaque: Argument for completion function
- */
-static void qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
- unsigned int index, unsigned int n, bool flush,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- QEDWriteTableCB *write_table_cb;
- unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
- unsigned int start, end, i;
- size_t len_bytes;
-
- trace_qed_write_table(s, offset, table, index, n);
-
- /* Calculate indices of the first and one after last elements */
- start = index & ~sector_mask;
- end = (index + n + sector_mask) & ~sector_mask;
-
- len_bytes = (end - start) * sizeof(uint64_t);
-
- write_table_cb = gencb_alloc(sizeof(*write_table_cb), cb, opaque);
- write_table_cb->s = s;
- write_table_cb->orig_table = table;
- write_table_cb->flush = flush;
- write_table_cb->table = qemu_blockalign(s->bs, len_bytes);
- write_table_cb->iov.iov_base = write_table_cb->table->offsets;
- write_table_cb->iov.iov_len = len_bytes;
- qemu_iovec_init_external(&write_table_cb->qiov, &write_table_cb->iov, 1);
-
- /* Byteswap table */
- for (i = start; i < end; i++) {
- uint64_t le_offset = cpu_to_le64(table->offsets[i]);
- write_table_cb->table->offsets[i - start] = le_offset;
- }
-
- /* Adjust for offset into table */
- offset += start * sizeof(uint64_t);
-
- bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
- &write_table_cb->qiov,
- write_table_cb->qiov.size / BDRV_SECTOR_SIZE,
- qed_write_table_cb, write_table_cb);
-}
-
-/**
- * Propagate return value from async callback
- */
-static void qed_sync_cb(void *opaque, int ret)
-{
- *(int *)opaque = ret;
-}
-
-int qed_read_l1_table_sync(BDRVQEDState *s)
-{
- int ret = -EINPROGRESS;
-
- qed_read_table(s, s->header.l1_table_offset,
- s->l1_table, qed_sync_cb, &ret);
- while (ret == -EINPROGRESS) {
- qemu_aio_wait();
- }
-
- return ret;
-}
-
-void qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
- qed_write_table(s, s->header.l1_table_offset,
- s->l1_table, index, n, false, cb, opaque);
-}
-
-int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
- unsigned int n)
-{
- int ret = -EINPROGRESS;
-
- qed_write_l1_table(s, index, n, qed_sync_cb, &ret);
- while (ret == -EINPROGRESS) {
- qemu_aio_wait();
- }
-
- return ret;
-}
-
-typedef struct {
- GenericCB gencb;
- BDRVQEDState *s;
- uint64_t l2_offset;
- QEDRequest *request;
-} QEDReadL2TableCB;
-
-static void qed_read_l2_table_cb(void *opaque, int ret)
-{
- QEDReadL2TableCB *read_l2_table_cb = opaque;
- QEDRequest *request = read_l2_table_cb->request;
- BDRVQEDState *s = read_l2_table_cb->s;
- CachedL2Table *l2_table = request->l2_table;
- uint64_t l2_offset = read_l2_table_cb->l2_offset;
-
- if (ret) {
- /* can't trust loaded L2 table anymore */
- qed_unref_l2_cache_entry(l2_table);
- request->l2_table = NULL;
- } else {
- l2_table->offset = l2_offset;
-
- qed_commit_l2_cache_entry(&s->l2_cache, l2_table);
-
- /* This is guaranteed to succeed because we just committed the entry
- * to the cache.
- */
- request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset);
- assert(request->l2_table != NULL);
- }
-
- gencb_complete(&read_l2_table_cb->gencb, ret);
-}
-
-void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- QEDReadL2TableCB *read_l2_table_cb;
-
- qed_unref_l2_cache_entry(request->l2_table);
-
- /* Check for cached L2 entry */
- request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, offset);
- if (request->l2_table) {
- cb(opaque, 0);
- return;
- }
-
- request->l2_table = qed_alloc_l2_cache_entry(&s->l2_cache);
- request->l2_table->table = qed_alloc_table(s);
-
- read_l2_table_cb = gencb_alloc(sizeof(*read_l2_table_cb), cb, opaque);
- read_l2_table_cb->s = s;
- read_l2_table_cb->l2_offset = offset;
- read_l2_table_cb->request = request;
-
- BLKDBG_EVENT(s->bs->file, BLKDBG_L2_LOAD);
- qed_read_table(s, offset, request->l2_table->table,
- qed_read_l2_table_cb, read_l2_table_cb);
-}
-
-int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
-{
- int ret = -EINPROGRESS;
-
- qed_read_l2_table(s, request, offset, qed_sync_cb, &ret);
- while (ret == -EINPROGRESS) {
- qemu_aio_wait();
- }
-
- return ret;
-}
-
-void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
- unsigned int index, unsigned int n, bool flush,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- BLKDBG_EVENT(s->bs->file, BLKDBG_L2_UPDATE);
- qed_write_table(s, request->l2_table->offset,
- request->l2_table->table, index, n, flush, cb, opaque);
-}
-
-int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
- unsigned int index, unsigned int n, bool flush)
-{
- int ret = -EINPROGRESS;
-
- qed_write_l2_table(s, request, index, n, flush, qed_sync_cb, &ret);
- while (ret == -EINPROGRESS) {
- qemu_aio_wait();
- }
-
- return ret;
-}
diff --git a/contrib/qemu/block/qed.c b/contrib/qemu/block/qed.c
deleted file mode 100644
index f767b0528ce..00000000000
--- a/contrib/qemu/block/qed.c
+++ /dev/null
@@ -1,1596 +0,0 @@
-/*
- * QEMU Enhanced Disk Format
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qemu/timer.h"
-#include "trace.h"
-#include "qed.h"
-#include "qapi/qmp/qerror.h"
-#include "migration/migration.h"
-
-static void qed_aio_cancel(BlockDriverAIOCB *blockacb)
-{
- QEDAIOCB *acb = (QEDAIOCB *)blockacb;
- bool finished = false;
-
- /* Wait for the request to finish */
- acb->finished = &finished;
- while (!finished) {
- qemu_aio_wait();
- }
-}
-
-static const AIOCBInfo qed_aiocb_info = {
- .aiocb_size = sizeof(QEDAIOCB),
- .cancel = qed_aio_cancel,
-};
-
-static int bdrv_qed_probe(const uint8_t *buf, int buf_size,
- const char *filename)
-{
- const QEDHeader *header = (const QEDHeader *)buf;
-
- if (buf_size < sizeof(*header)) {
- return 0;
- }
- if (le32_to_cpu(header->magic) != QED_MAGIC) {
- return 0;
- }
- return 100;
-}
-
-/**
- * Check whether an image format is raw
- *
- * @fmt: Backing file format, may be NULL
- */
-static bool qed_fmt_is_raw(const char *fmt)
-{
- return fmt && strcmp(fmt, "raw") == 0;
-}
-
-static void qed_header_le_to_cpu(const QEDHeader *le, QEDHeader *cpu)
-{
- cpu->magic = le32_to_cpu(le->magic);
- cpu->cluster_size = le32_to_cpu(le->cluster_size);
- cpu->table_size = le32_to_cpu(le->table_size);
- cpu->header_size = le32_to_cpu(le->header_size);
- cpu->features = le64_to_cpu(le->features);
- cpu->compat_features = le64_to_cpu(le->compat_features);
- cpu->autoclear_features = le64_to_cpu(le->autoclear_features);
- cpu->l1_table_offset = le64_to_cpu(le->l1_table_offset);
- cpu->image_size = le64_to_cpu(le->image_size);
- cpu->backing_filename_offset = le32_to_cpu(le->backing_filename_offset);
- cpu->backing_filename_size = le32_to_cpu(le->backing_filename_size);
-}
-
-static void qed_header_cpu_to_le(const QEDHeader *cpu, QEDHeader *le)
-{
- le->magic = cpu_to_le32(cpu->magic);
- le->cluster_size = cpu_to_le32(cpu->cluster_size);
- le->table_size = cpu_to_le32(cpu->table_size);
- le->header_size = cpu_to_le32(cpu->header_size);
- le->features = cpu_to_le64(cpu->features);
- le->compat_features = cpu_to_le64(cpu->compat_features);
- le->autoclear_features = cpu_to_le64(cpu->autoclear_features);
- le->l1_table_offset = cpu_to_le64(cpu->l1_table_offset);
- le->image_size = cpu_to_le64(cpu->image_size);
- le->backing_filename_offset = cpu_to_le32(cpu->backing_filename_offset);
- le->backing_filename_size = cpu_to_le32(cpu->backing_filename_size);
-}
-
-int qed_write_header_sync(BDRVQEDState *s)
-{
- QEDHeader le;
- int ret;
-
- qed_header_cpu_to_le(&s->header, &le);
- ret = bdrv_pwrite(s->bs->file, 0, &le, sizeof(le));
- if (ret != sizeof(le)) {
- return ret;
- }
- return 0;
-}
-
-typedef struct {
- GenericCB gencb;
- BDRVQEDState *s;
- struct iovec iov;
- QEMUIOVector qiov;
- int nsectors;
- uint8_t *buf;
-} QEDWriteHeaderCB;
-
-static void qed_write_header_cb(void *opaque, int ret)
-{
- QEDWriteHeaderCB *write_header_cb = opaque;
-
- qemu_vfree(write_header_cb->buf);
- gencb_complete(write_header_cb, ret);
-}
-
-static void qed_write_header_read_cb(void *opaque, int ret)
-{
- QEDWriteHeaderCB *write_header_cb = opaque;
- BDRVQEDState *s = write_header_cb->s;
-
- if (ret) {
- qed_write_header_cb(write_header_cb, ret);
- return;
- }
-
- /* Update header */
- qed_header_cpu_to_le(&s->header, (QEDHeader *)write_header_cb->buf);
-
- bdrv_aio_writev(s->bs->file, 0, &write_header_cb->qiov,
- write_header_cb->nsectors, qed_write_header_cb,
- write_header_cb);
-}
-
-/**
- * Update header in-place (does not rewrite backing filename or other strings)
- *
- * This function only updates known header fields in-place and does not affect
- * extra data after the QED header.
- */
-static void qed_write_header(BDRVQEDState *s, BlockDriverCompletionFunc cb,
- void *opaque)
-{
- /* We must write full sectors for O_DIRECT but cannot necessarily generate
- * the data following the header if an unrecognized compat feature is
- * active. Therefore, first read the sectors containing the header, update
- * them, and write back.
- */
-
- int nsectors = (sizeof(QEDHeader) + BDRV_SECTOR_SIZE - 1) /
- BDRV_SECTOR_SIZE;
- size_t len = nsectors * BDRV_SECTOR_SIZE;
- QEDWriteHeaderCB *write_header_cb = gencb_alloc(sizeof(*write_header_cb),
- cb, opaque);
-
- write_header_cb->s = s;
- write_header_cb->nsectors = nsectors;
- write_header_cb->buf = qemu_blockalign(s->bs, len);
- write_header_cb->iov.iov_base = write_header_cb->buf;
- write_header_cb->iov.iov_len = len;
- qemu_iovec_init_external(&write_header_cb->qiov, &write_header_cb->iov, 1);
-
- bdrv_aio_readv(s->bs->file, 0, &write_header_cb->qiov, nsectors,
- qed_write_header_read_cb, write_header_cb);
-}
-
-static uint64_t qed_max_image_size(uint32_t cluster_size, uint32_t table_size)
-{
- uint64_t table_entries;
- uint64_t l2_size;
-
- table_entries = (table_size * cluster_size) / sizeof(uint64_t);
- l2_size = table_entries * cluster_size;
-
- return l2_size * table_entries;
-}
-
-static bool qed_is_cluster_size_valid(uint32_t cluster_size)
-{
- if (cluster_size < QED_MIN_CLUSTER_SIZE ||
- cluster_size > QED_MAX_CLUSTER_SIZE) {
- return false;
- }
- if (cluster_size & (cluster_size - 1)) {
- return false; /* not power of 2 */
- }
- return true;
-}
-
-static bool qed_is_table_size_valid(uint32_t table_size)
-{
- if (table_size < QED_MIN_TABLE_SIZE ||
- table_size > QED_MAX_TABLE_SIZE) {
- return false;
- }
- if (table_size & (table_size - 1)) {
- return false; /* not power of 2 */
- }
- return true;
-}
-
-static bool qed_is_image_size_valid(uint64_t image_size, uint32_t cluster_size,
- uint32_t table_size)
-{
- if (image_size % BDRV_SECTOR_SIZE != 0) {
- return false; /* not multiple of sector size */
- }
- if (image_size > qed_max_image_size(cluster_size, table_size)) {
- return false; /* image is too large */
- }
- return true;
-}
-
-/**
- * Read a string of known length from the image file
- *
- * @file: Image file
- * @offset: File offset to start of string, in bytes
- * @n: String length in bytes
- * @buf: Destination buffer
- * @buflen: Destination buffer length in bytes
- * @ret: 0 on success, -errno on failure
- *
- * The string is NUL-terminated.
- */
-static int qed_read_string(BlockDriverState *file, uint64_t offset, size_t n,
- char *buf, size_t buflen)
-{
- int ret;
- if (n >= buflen) {
- return -EINVAL;
- }
- ret = bdrv_pread(file, offset, buf, n);
- if (ret < 0) {
- return ret;
- }
- buf[n] = '\0';
- return 0;
-}
-
-/**
- * Allocate new clusters
- *
- * @s: QED state
- * @n: Number of contiguous clusters to allocate
- * @ret: Offset of first allocated cluster
- *
- * This function only produces the offset where the new clusters should be
- * written. It updates BDRVQEDState but does not make any changes to the image
- * file.
- */
-static uint64_t qed_alloc_clusters(BDRVQEDState *s, unsigned int n)
-{
- uint64_t offset = s->file_size;
- s->file_size += n * s->header.cluster_size;
- return offset;
-}
-
-QEDTable *qed_alloc_table(BDRVQEDState *s)
-{
- /* Honor O_DIRECT memory alignment requirements */
- return qemu_blockalign(s->bs,
- s->header.cluster_size * s->header.table_size);
-}
-
-/**
- * Allocate a new zeroed L2 table
- */
-static CachedL2Table *qed_new_l2_table(BDRVQEDState *s)
-{
- CachedL2Table *l2_table = qed_alloc_l2_cache_entry(&s->l2_cache);
-
- l2_table->table = qed_alloc_table(s);
- l2_table->offset = qed_alloc_clusters(s, s->header.table_size);
-
- memset(l2_table->table->offsets, 0,
- s->header.cluster_size * s->header.table_size);
- return l2_table;
-}
-
-static void qed_aio_next_io(void *opaque, int ret);
-
-static void qed_plug_allocating_write_reqs(BDRVQEDState *s)
-{
- assert(!s->allocating_write_reqs_plugged);
-
- s->allocating_write_reqs_plugged = true;
-}
-
-static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
-{
- QEDAIOCB *acb;
-
- assert(s->allocating_write_reqs_plugged);
-
- s->allocating_write_reqs_plugged = false;
-
- acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
- if (acb) {
- qed_aio_next_io(acb, 0);
- }
-}
-
-static void qed_finish_clear_need_check(void *opaque, int ret)
-{
- /* Do nothing */
-}
-
-static void qed_flush_after_clear_need_check(void *opaque, int ret)
-{
- BDRVQEDState *s = opaque;
-
- bdrv_aio_flush(s->bs, qed_finish_clear_need_check, s);
-
- /* No need to wait until flush completes */
- qed_unplug_allocating_write_reqs(s);
-}
-
-static void qed_clear_need_check(void *opaque, int ret)
-{
- BDRVQEDState *s = opaque;
-
- if (ret) {
- qed_unplug_allocating_write_reqs(s);
- return;
- }
-
- s->header.features &= ~QED_F_NEED_CHECK;
- qed_write_header(s, qed_flush_after_clear_need_check, s);
-}
-
-static void qed_need_check_timer_cb(void *opaque)
-{
- BDRVQEDState *s = opaque;
-
- /* The timer should only fire when allocating writes have drained */
- assert(!QSIMPLEQ_FIRST(&s->allocating_write_reqs));
-
- trace_qed_need_check_timer_cb(s);
-
- qed_plug_allocating_write_reqs(s);
-
- /* Ensure writes are on disk before clearing flag */
- bdrv_aio_flush(s->bs, qed_clear_need_check, s);
-}
-
-static void qed_start_need_check_timer(BDRVQEDState *s)
-{
- trace_qed_start_need_check_timer(s);
-
- /* Use vm_clock so we don't alter the image file while suspended for
- * migration.
- */
- qemu_mod_timer(s->need_check_timer, qemu_get_clock_ns(vm_clock) +
- get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT);
-}
-
-/* It's okay to call this multiple times or when no timer is started */
-static void qed_cancel_need_check_timer(BDRVQEDState *s)
-{
- trace_qed_cancel_need_check_timer(s);
- qemu_del_timer(s->need_check_timer);
-}
-
-static void bdrv_qed_rebind(BlockDriverState *bs)
-{
- BDRVQEDState *s = bs->opaque;
- s->bs = bs;
-}
-
-static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags)
-{
- BDRVQEDState *s = bs->opaque;
- QEDHeader le_header;
- int64_t file_size;
- int ret;
-
- s->bs = bs;
- QSIMPLEQ_INIT(&s->allocating_write_reqs);
-
- ret = bdrv_pread(bs->file, 0, &le_header, sizeof(le_header));
- if (ret < 0) {
- return ret;
- }
- qed_header_le_to_cpu(&le_header, &s->header);
-
- if (s->header.magic != QED_MAGIC) {
- return -EMEDIUMTYPE;
- }
- if (s->header.features & ~QED_FEATURE_MASK) {
- /* image uses unsupported feature bits */
- char buf[64];
- snprintf(buf, sizeof(buf), "%" PRIx64,
- s->header.features & ~QED_FEATURE_MASK);
- qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,
- bs->device_name, "QED", buf);
- return -ENOTSUP;
- }
- if (!qed_is_cluster_size_valid(s->header.cluster_size)) {
- return -EINVAL;
- }
-
- /* Round down file size to the last cluster */
- file_size = bdrv_getlength(bs->file);
- if (file_size < 0) {
- return file_size;
- }
- s->file_size = qed_start_of_cluster(s, file_size);
-
- if (!qed_is_table_size_valid(s->header.table_size)) {
- return -EINVAL;
- }
- if (!qed_is_image_size_valid(s->header.image_size,
- s->header.cluster_size,
- s->header.table_size)) {
- return -EINVAL;
- }
- if (!qed_check_table_offset(s, s->header.l1_table_offset)) {
- return -EINVAL;
- }
-
- s->table_nelems = (s->header.cluster_size * s->header.table_size) /
- sizeof(uint64_t);
- s->l2_shift = ffs(s->header.cluster_size) - 1;
- s->l2_mask = s->table_nelems - 1;
- s->l1_shift = s->l2_shift + ffs(s->table_nelems) - 1;
-
- if ((s->header.features & QED_F_BACKING_FILE)) {
- if ((uint64_t)s->header.backing_filename_offset +
- s->header.backing_filename_size >
- s->header.cluster_size * s->header.header_size) {
- return -EINVAL;
- }
-
- ret = qed_read_string(bs->file, s->header.backing_filename_offset,
- s->header.backing_filename_size, bs->backing_file,
- sizeof(bs->backing_file));
- if (ret < 0) {
- return ret;
- }
-
- if (s->header.features & QED_F_BACKING_FORMAT_NO_PROBE) {
- pstrcpy(bs->backing_format, sizeof(bs->backing_format), "raw");
- }
- }
-
- /* Reset unknown autoclear feature bits. This is a backwards
- * compatibility mechanism that allows images to be opened by older
- * programs, which "knock out" unknown feature bits. When an image is
- * opened by a newer program again it can detect that the autoclear
- * feature is no longer valid.
- */
- if ((s->header.autoclear_features & ~QED_AUTOCLEAR_FEATURE_MASK) != 0 &&
- !bdrv_is_read_only(bs->file) && !(flags & BDRV_O_INCOMING)) {
- s->header.autoclear_features &= QED_AUTOCLEAR_FEATURE_MASK;
-
- ret = qed_write_header_sync(s);
- if (ret) {
- return ret;
- }
-
- /* From here on only known autoclear feature bits are valid */
- bdrv_flush(bs->file);
- }
-
- s->l1_table = qed_alloc_table(s);
- qed_init_l2_cache(&s->l2_cache);
-
- ret = qed_read_l1_table_sync(s);
- if (ret) {
- goto out;
- }
-
- /* If image was not closed cleanly, check consistency */
- if (!(flags & BDRV_O_CHECK) && (s->header.features & QED_F_NEED_CHECK)) {
- /* Read-only images cannot be fixed. There is no risk of corruption
- * since write operations are not possible. Therefore, allow
- * potentially inconsistent images to be opened read-only. This can
- * aid data recovery from an otherwise inconsistent image.
- */
- if (!bdrv_is_read_only(bs->file) &&
- !(flags & BDRV_O_INCOMING)) {
- BdrvCheckResult result = {0};
-
- ret = qed_check(s, &result, true);
- if (ret) {
- goto out;
- }
- }
- }
-
- s->need_check_timer = qemu_new_timer_ns(vm_clock,
- qed_need_check_timer_cb, s);
-
-out:
- if (ret) {
- qed_free_l2_cache(&s->l2_cache);
- qemu_vfree(s->l1_table);
- }
- return ret;
-}
-
-/* We have nothing to do for QED reopen, stubs just return
- * success */
-static int bdrv_qed_reopen_prepare(BDRVReopenState *state,
- BlockReopenQueue *queue, Error **errp)
-{
- return 0;
-}
-
-static void bdrv_qed_close(BlockDriverState *bs)
-{
- BDRVQEDState *s = bs->opaque;
-
- qed_cancel_need_check_timer(s);
- qemu_free_timer(s->need_check_timer);
-
- /* Ensure writes reach stable storage */
- bdrv_flush(bs->file);
-
- /* Clean shutdown, no check required on next open */
- if (s->header.features & QED_F_NEED_CHECK) {
- s->header.features &= ~QED_F_NEED_CHECK;
- qed_write_header_sync(s);
- }
-
- qed_free_l2_cache(&s->l2_cache);
- qemu_vfree(s->l1_table);
-}
-
-static int qed_create(const char *filename, uint32_t cluster_size,
- uint64_t image_size, uint32_t table_size,
- const char *backing_file, const char *backing_fmt)
-{
- QEDHeader header = {
- .magic = QED_MAGIC,
- .cluster_size = cluster_size,
- .table_size = table_size,
- .header_size = 1,
- .features = 0,
- .compat_features = 0,
- .l1_table_offset = cluster_size,
- .image_size = image_size,
- };
- QEDHeader le_header;
- uint8_t *l1_table = NULL;
- size_t l1_size = header.cluster_size * header.table_size;
- int ret = 0;
- BlockDriverState *bs = NULL;
-
- ret = bdrv_create_file(filename, NULL);
- if (ret < 0) {
- return ret;
- }
-
- ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB);
- if (ret < 0) {
- return ret;
- }
-
- /* File must start empty and grow, check truncate is supported */
- ret = bdrv_truncate(bs, 0);
- if (ret < 0) {
- goto out;
- }
-
- if (backing_file) {
- header.features |= QED_F_BACKING_FILE;
- header.backing_filename_offset = sizeof(le_header);
- header.backing_filename_size = strlen(backing_file);
-
- if (qed_fmt_is_raw(backing_fmt)) {
- header.features |= QED_F_BACKING_FORMAT_NO_PROBE;
- }
- }
-
- qed_header_cpu_to_le(&header, &le_header);
- ret = bdrv_pwrite(bs, 0, &le_header, sizeof(le_header));
- if (ret < 0) {
- goto out;
- }
- ret = bdrv_pwrite(bs, sizeof(le_header), backing_file,
- header.backing_filename_size);
- if (ret < 0) {
- goto out;
- }
-
- l1_table = g_malloc0(l1_size);
- ret = bdrv_pwrite(bs, header.l1_table_offset, l1_table, l1_size);
- if (ret < 0) {
- goto out;
- }
-
- ret = 0; /* success */
-out:
- g_free(l1_table);
- bdrv_delete(bs);
- return ret;
-}
-
-static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options)
-{
- uint64_t image_size = 0;
- uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
- uint32_t table_size = QED_DEFAULT_TABLE_SIZE;
- const char *backing_file = NULL;
- const char *backing_fmt = NULL;
-
- while (options && options->name) {
- if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
- image_size = options->value.n;
- } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
- backing_file = options->value.s;
- } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
- backing_fmt = options->value.s;
- } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
- if (options->value.n) {
- cluster_size = options->value.n;
- }
- } else if (!strcmp(options->name, BLOCK_OPT_TABLE_SIZE)) {
- if (options->value.n) {
- table_size = options->value.n;
- }
- }
- options++;
- }
-
- if (!qed_is_cluster_size_valid(cluster_size)) {
- fprintf(stderr, "QED cluster size must be within range [%u, %u] and power of 2\n",
- QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE);
- return -EINVAL;
- }
- if (!qed_is_table_size_valid(table_size)) {
- fprintf(stderr, "QED table size must be within range [%u, %u] and power of 2\n",
- QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE);
- return -EINVAL;
- }
- if (!qed_is_image_size_valid(image_size, cluster_size, table_size)) {
- fprintf(stderr, "QED image size must be a non-zero multiple of "
- "cluster size and less than %" PRIu64 " bytes\n",
- qed_max_image_size(cluster_size, table_size));
- return -EINVAL;
- }
-
- return qed_create(filename, cluster_size, image_size, table_size,
- backing_file, backing_fmt);
-}
-
-typedef struct {
- Coroutine *co;
- int is_allocated;
- int *pnum;
-} QEDIsAllocatedCB;
-
-static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t len)
-{
- QEDIsAllocatedCB *cb = opaque;
- *cb->pnum = len / BDRV_SECTOR_SIZE;
- cb->is_allocated = (ret == QED_CLUSTER_FOUND || ret == QED_CLUSTER_ZERO);
- if (cb->co) {
- qemu_coroutine_enter(cb->co, NULL);
- }
-}
-
-static int coroutine_fn bdrv_qed_co_is_allocated(BlockDriverState *bs,
- int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVQEDState *s = bs->opaque;
- uint64_t pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE;
- size_t len = (size_t)nb_sectors * BDRV_SECTOR_SIZE;
- QEDIsAllocatedCB cb = {
- .is_allocated = -1,
- .pnum = pnum,
- };
- QEDRequest request = { .l2_table = NULL };
-
- qed_find_cluster(s, &request, pos, len, qed_is_allocated_cb, &cb);
-
- /* Now sleep if the callback wasn't invoked immediately */
- while (cb.is_allocated == -1) {
- cb.co = qemu_coroutine_self();
- qemu_coroutine_yield();
- }
-
- qed_unref_l2_cache_entry(request.l2_table);
-
- return cb.is_allocated;
-}
-
-static int bdrv_qed_make_empty(BlockDriverState *bs)
-{
- return -ENOTSUP;
-}
-
-static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
-{
- return acb->common.bs->opaque;
-}
-
-/**
- * Read from the backing file or zero-fill if no backing file
- *
- * @s: QED state
- * @pos: Byte position in device
- * @qiov: Destination I/O vector
- * @cb: Completion function
- * @opaque: User data for completion function
- *
- * This function reads qiov->size bytes starting at pos from the backing file.
- * If there is no backing file then zeroes are read.
- */
-static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
- QEMUIOVector *qiov,
- BlockDriverCompletionFunc *cb, void *opaque)
-{
- uint64_t backing_length = 0;
- size_t size;
-
- /* If there is a backing file, get its length. Treat the absence of a
- * backing file like a zero length backing file.
- */
- if (s->bs->backing_hd) {
- int64_t l = bdrv_getlength(s->bs->backing_hd);
- if (l < 0) {
- cb(opaque, l);
- return;
- }
- backing_length = l;
- }
-
- /* Zero all sectors if reading beyond the end of the backing file */
- if (pos >= backing_length ||
- pos + qiov->size > backing_length) {
- qemu_iovec_memset(qiov, 0, 0, qiov->size);
- }
-
- /* Complete now if there are no backing file sectors to read */
- if (pos >= backing_length) {
- cb(opaque, 0);
- return;
- }
-
- /* If the read straddles the end of the backing file, shorten it */
- size = MIN((uint64_t)backing_length - pos, qiov->size);
-
- BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
- bdrv_aio_readv(s->bs->backing_hd, pos / BDRV_SECTOR_SIZE,
- qiov, size / BDRV_SECTOR_SIZE, cb, opaque);
-}
-
-typedef struct {
- GenericCB gencb;
- BDRVQEDState *s;
- QEMUIOVector qiov;
- struct iovec iov;
- uint64_t offset;
-} CopyFromBackingFileCB;
-
-static void qed_copy_from_backing_file_cb(void *opaque, int ret)
-{
- CopyFromBackingFileCB *copy_cb = opaque;
- qemu_vfree(copy_cb->iov.iov_base);
- gencb_complete(&copy_cb->gencb, ret);
-}
-
-static void qed_copy_from_backing_file_write(void *opaque, int ret)
-{
- CopyFromBackingFileCB *copy_cb = opaque;
- BDRVQEDState *s = copy_cb->s;
-
- if (ret) {
- qed_copy_from_backing_file_cb(copy_cb, ret);
- return;
- }
-
- BLKDBG_EVENT(s->bs->file, BLKDBG_COW_WRITE);
- bdrv_aio_writev(s->bs->file, copy_cb->offset / BDRV_SECTOR_SIZE,
- &copy_cb->qiov, copy_cb->qiov.size / BDRV_SECTOR_SIZE,
- qed_copy_from_backing_file_cb, copy_cb);
-}
-
-/**
- * Copy data from backing file into the image
- *
- * @s: QED state
- * @pos: Byte position in device
- * @len: Number of bytes
- * @offset: Byte offset in image file
- * @cb: Completion function
- * @opaque: User data for completion function
- */
-static void qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos,
- uint64_t len, uint64_t offset,
- BlockDriverCompletionFunc *cb,
- void *opaque)
-{
- CopyFromBackingFileCB *copy_cb;
-
- /* Skip copy entirely if there is no work to do */
- if (len == 0) {
- cb(opaque, 0);
- return;
- }
-
- copy_cb = gencb_alloc(sizeof(*copy_cb), cb, opaque);
- copy_cb->s = s;
- copy_cb->offset = offset;
- copy_cb->iov.iov_base = qemu_blockalign(s->bs, len);
- copy_cb->iov.iov_len = len;
- qemu_iovec_init_external(&copy_cb->qiov, &copy_cb->iov, 1);
-
- qed_read_backing_file(s, pos, &copy_cb->qiov,
- qed_copy_from_backing_file_write, copy_cb);
-}
-
-/**
- * Link one or more contiguous clusters into a table
- *
- * @s: QED state
- * @table: L2 table
- * @index: First cluster index
- * @n: Number of contiguous clusters
- * @cluster: First cluster offset
- *
- * The cluster offset may be an allocated byte offset in the image file, the
- * zero cluster marker, or the unallocated cluster marker.
- */
-static void qed_update_l2_table(BDRVQEDState *s, QEDTable *table, int index,
- unsigned int n, uint64_t cluster)
-{
- int i;
- for (i = index; i < index + n; i++) {
- table->offsets[i] = cluster;
- if (!qed_offset_is_unalloc_cluster(cluster) &&
- !qed_offset_is_zero_cluster(cluster)) {
- cluster += s->header.cluster_size;
- }
- }
-}
-
-static void qed_aio_complete_bh(void *opaque)
-{
- QEDAIOCB *acb = opaque;
- BlockDriverCompletionFunc *cb = acb->common.cb;
- void *user_opaque = acb->common.opaque;
- int ret = acb->bh_ret;
- bool *finished = acb->finished;
-
- qemu_bh_delete(acb->bh);
- qemu_aio_release(acb);
-
- /* Invoke callback */
- cb(user_opaque, ret);
-
- /* Signal cancel completion */
- if (finished) {
- *finished = true;
- }
-}
-
-static void qed_aio_complete(QEDAIOCB *acb, int ret)
-{
- BDRVQEDState *s = acb_to_s(acb);
-
- trace_qed_aio_complete(s, acb, ret);
-
- /* Free resources */
- qemu_iovec_destroy(&acb->cur_qiov);
- qed_unref_l2_cache_entry(acb->request.l2_table);
-
- /* Free the buffer we may have allocated for zero writes */
- if (acb->flags & QED_AIOCB_ZERO) {
- qemu_vfree(acb->qiov->iov[0].iov_base);
- acb->qiov->iov[0].iov_base = NULL;
- }
-
- /* Arrange for a bh to invoke the completion function */
- acb->bh_ret = ret;
- acb->bh = qemu_bh_new(qed_aio_complete_bh, acb);
- qemu_bh_schedule(acb->bh);
-
- /* Start next allocating write request waiting behind this one. Note that
- * requests enqueue themselves when they first hit an unallocated cluster
- * but they wait until the entire request is finished before waking up the
- * next request in the queue. This ensures that we don't cycle through
- * requests multiple times but rather finish one at a time completely.
- */
- if (acb == QSIMPLEQ_FIRST(&s->allocating_write_reqs)) {
- QSIMPLEQ_REMOVE_HEAD(&s->allocating_write_reqs, next);
- acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
- if (acb) {
- qed_aio_next_io(acb, 0);
- } else if (s->header.features & QED_F_NEED_CHECK) {
- qed_start_need_check_timer(s);
- }
- }
-}
-
-/**
- * Commit the current L2 table to the cache
- */
-static void qed_commit_l2_update(void *opaque, int ret)
-{
- QEDAIOCB *acb = opaque;
- BDRVQEDState *s = acb_to_s(acb);
- CachedL2Table *l2_table = acb->request.l2_table;
- uint64_t l2_offset = l2_table->offset;
-
- qed_commit_l2_cache_entry(&s->l2_cache, l2_table);
-
- /* This is guaranteed to succeed because we just committed the entry to the
- * cache.
- */
- acb->request.l2_table = qed_find_l2_cache_entry(&s->l2_cache, l2_offset);
- assert(acb->request.l2_table != NULL);
-
- qed_aio_next_io(opaque, ret);
-}
-
-/**
- * Update L1 table with new L2 table offset and write it out
- */
-static void qed_aio_write_l1_update(void *opaque, int ret)
-{
- QEDAIOCB *acb = opaque;
- BDRVQEDState *s = acb_to_s(acb);
- int index;
-
- if (ret) {
- qed_aio_complete(acb, ret);
- return;
- }
-
- index = qed_l1_index(s, acb->cur_pos);
- s->l1_table->offsets[index] = acb->request.l2_table->offset;
-
- qed_write_l1_table(s, index, 1, qed_commit_l2_update, acb);
-}
-
-/**
- * Update L2 table with new cluster offsets and write them out
- */
-static void qed_aio_write_l2_update(QEDAIOCB *acb, int ret, uint64_t offset)
-{
- BDRVQEDState *s = acb_to_s(acb);
- bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1;
- int index;
-
- if (ret) {
- goto err;
- }
-
- if (need_alloc) {
- qed_unref_l2_cache_entry(acb->request.l2_table);
- acb->request.l2_table = qed_new_l2_table(s);
- }
-
- index = qed_l2_index(s, acb->cur_pos);
- qed_update_l2_table(s, acb->request.l2_table->table, index, acb->cur_nclusters,
- offset);
-
- if (need_alloc) {
- /* Write out the whole new L2 table */
- qed_write_l2_table(s, &acb->request, 0, s->table_nelems, true,
- qed_aio_write_l1_update, acb);
- } else {
- /* Write out only the updated part of the L2 table */
- qed_write_l2_table(s, &acb->request, index, acb->cur_nclusters, false,
- qed_aio_next_io, acb);
- }
- return;
-
-err:
- qed_aio_complete(acb, ret);
-}
-
-static void qed_aio_write_l2_update_cb(void *opaque, int ret)
-{
- QEDAIOCB *acb = opaque;
- qed_aio_write_l2_update(acb, ret, acb->cur_cluster);
-}
-
-/**
- * Flush new data clusters before updating the L2 table
- *
- * This flush is necessary when a backing file is in use. A crash during an
- * allocating write could result in empty clusters in the image. If the write
- * only touched a subregion of the cluster, then backing image sectors have
- * been lost in the untouched region. The solution is to flush after writing a
- * new data cluster and before updating the L2 table.
- */
-static void qed_aio_write_flush_before_l2_update(void *opaque, int ret)
-{
- QEDAIOCB *acb = opaque;
- BDRVQEDState *s = acb_to_s(acb);
-
- if (!bdrv_aio_flush(s->bs->file, qed_aio_write_l2_update_cb, opaque)) {
- qed_aio_complete(acb, -EIO);
- }
-}
-
-/**
- * Write data to the image file
- */
-static void qed_aio_write_main(void *opaque, int ret)
-{
- QEDAIOCB *acb = opaque;
- BDRVQEDState *s = acb_to_s(acb);
- uint64_t offset = acb->cur_cluster +
- qed_offset_into_cluster(s, acb->cur_pos);
- BlockDriverCompletionFunc *next_fn;
-
- trace_qed_aio_write_main(s, acb, ret, offset, acb->cur_qiov.size);
-
- if (ret) {
- qed_aio_complete(acb, ret);
- return;
- }
-
- if (acb->find_cluster_ret == QED_CLUSTER_FOUND) {
- next_fn = qed_aio_next_io;
- } else {
- if (s->bs->backing_hd) {
- next_fn = qed_aio_write_flush_before_l2_update;
- } else {
- next_fn = qed_aio_write_l2_update_cb;
- }
- }
-
- BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO);
- bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
- &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,
- next_fn, acb);
-}
-
-/**
- * Populate back untouched region of new data cluster
- */
-static void qed_aio_write_postfill(void *opaque, int ret)
-{
- QEDAIOCB *acb = opaque;
- BDRVQEDState *s = acb_to_s(acb);
- uint64_t start = acb->cur_pos + acb->cur_qiov.size;
- uint64_t len =
- qed_start_of_cluster(s, start + s->header.cluster_size - 1) - start;
- uint64_t offset = acb->cur_cluster +
- qed_offset_into_cluster(s, acb->cur_pos) +
- acb->cur_qiov.size;
-
- if (ret) {
- qed_aio_complete(acb, ret);
- return;
- }
-
- trace_qed_aio_write_postfill(s, acb, start, len, offset);
- qed_copy_from_backing_file(s, start, len, offset,
- qed_aio_write_main, acb);
-}
-
-/**
- * Populate front untouched region of new data cluster
- */
-static void qed_aio_write_prefill(void *opaque, int ret)
-{
- QEDAIOCB *acb = opaque;
- BDRVQEDState *s = acb_to_s(acb);
- uint64_t start = qed_start_of_cluster(s, acb->cur_pos);
- uint64_t len = qed_offset_into_cluster(s, acb->cur_pos);
-
- trace_qed_aio_write_prefill(s, acb, start, len, acb->cur_cluster);
- qed_copy_from_backing_file(s, start, len, acb->cur_cluster,
- qed_aio_write_postfill, acb);
-}
-
-/**
- * Check if the QED_F_NEED_CHECK bit should be set during allocating write
- */
-static bool qed_should_set_need_check(BDRVQEDState *s)
-{
- /* The flush before L2 update path ensures consistency */
- if (s->bs->backing_hd) {
- return false;
- }
-
- return !(s->header.features & QED_F_NEED_CHECK);
-}
-
-static void qed_aio_write_zero_cluster(void *opaque, int ret)
-{
- QEDAIOCB *acb = opaque;
-
- if (ret) {
- qed_aio_complete(acb, ret);
- return;
- }
-
- qed_aio_write_l2_update(acb, 0, 1);
-}
-
-/**
- * Write new data cluster
- *
- * @acb: Write request
- * @len: Length in bytes
- *
- * This path is taken when writing to previously unallocated clusters.
- */
-static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
-{
- BDRVQEDState *s = acb_to_s(acb);
- BlockDriverCompletionFunc *cb;
-
- /* Cancel timer when the first allocating request comes in */
- if (QSIMPLEQ_EMPTY(&s->allocating_write_reqs)) {
- qed_cancel_need_check_timer(s);
- }
-
- /* Freeze this request if another allocating write is in progress */
- if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) {
- QSIMPLEQ_INSERT_TAIL(&s->allocating_write_reqs, acb, next);
- }
- if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs) ||
- s->allocating_write_reqs_plugged) {
- return; /* wait for existing request to finish */
- }
-
- acb->cur_nclusters = qed_bytes_to_clusters(s,
- qed_offset_into_cluster(s, acb->cur_pos) + len);
- qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
-
- if (acb->flags & QED_AIOCB_ZERO) {
- /* Skip ahead if the clusters are already zero */
- if (acb->find_cluster_ret == QED_CLUSTER_ZERO) {
- qed_aio_next_io(acb, 0);
- return;
- }
-
- cb = qed_aio_write_zero_cluster;
- } else {
- cb = qed_aio_write_prefill;
- acb->cur_cluster = qed_alloc_clusters(s, acb->cur_nclusters);
- }
-
- if (qed_should_set_need_check(s)) {
- s->header.features |= QED_F_NEED_CHECK;
- qed_write_header(s, cb, acb);
- } else {
- cb(acb, 0);
- }
-}
-
-/**
- * Write data cluster in place
- *
- * @acb: Write request
- * @offset: Cluster offset in bytes
- * @len: Length in bytes
- *
- * This path is taken when writing to already allocated clusters.
- */
-static void qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
-{
- /* Allocate buffer for zero writes */
- if (acb->flags & QED_AIOCB_ZERO) {
- struct iovec *iov = acb->qiov->iov;
-
- if (!iov->iov_base) {
- iov->iov_base = qemu_blockalign(acb->common.bs, iov->iov_len);
- memset(iov->iov_base, 0, iov->iov_len);
- }
- }
-
- /* Calculate the I/O vector */
- acb->cur_cluster = offset;
- qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
-
- /* Do the actual write */
- qed_aio_write_main(acb, 0);
-}
-
-/**
- * Write data cluster
- *
- * @opaque: Write request
- * @ret: QED_CLUSTER_FOUND, QED_CLUSTER_L2, QED_CLUSTER_L1,
- * or -errno
- * @offset: Cluster offset in bytes
- * @len: Length in bytes
- *
- * Callback from qed_find_cluster().
- */
-static void qed_aio_write_data(void *opaque, int ret,
- uint64_t offset, size_t len)
-{
- QEDAIOCB *acb = opaque;
-
- trace_qed_aio_write_data(acb_to_s(acb), acb, ret, offset, len);
-
- acb->find_cluster_ret = ret;
-
- switch (ret) {
- case QED_CLUSTER_FOUND:
- qed_aio_write_inplace(acb, offset, len);
- break;
-
- case QED_CLUSTER_L2:
- case QED_CLUSTER_L1:
- case QED_CLUSTER_ZERO:
- qed_aio_write_alloc(acb, len);
- break;
-
- default:
- qed_aio_complete(acb, ret);
- break;
- }
-}
-
-/**
- * Read data cluster
- *
- * @opaque: Read request
- * @ret: QED_CLUSTER_FOUND, QED_CLUSTER_L2, QED_CLUSTER_L1,
- * or -errno
- * @offset: Cluster offset in bytes
- * @len: Length in bytes
- *
- * Callback from qed_find_cluster().
- */
-static void qed_aio_read_data(void *opaque, int ret,
- uint64_t offset, size_t len)
-{
- QEDAIOCB *acb = opaque;
- BDRVQEDState *s = acb_to_s(acb);
- BlockDriverState *bs = acb->common.bs;
-
- /* Adjust offset into cluster */
- offset += qed_offset_into_cluster(s, acb->cur_pos);
-
- trace_qed_aio_read_data(s, acb, ret, offset, len);
-
- if (ret < 0) {
- goto err;
- }
-
- qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
-
- /* Handle zero cluster and backing file reads */
- if (ret == QED_CLUSTER_ZERO) {
- qemu_iovec_memset(&acb->cur_qiov, 0, 0, acb->cur_qiov.size);
- qed_aio_next_io(acb, 0);
- return;
- } else if (ret != QED_CLUSTER_FOUND) {
- qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov,
- qed_aio_next_io, acb);
- return;
- }
-
- BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
- bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE,
- &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,
- qed_aio_next_io, acb);
- return;
-
-err:
- qed_aio_complete(acb, ret);
-}
-
-/**
- * Begin next I/O or complete the request
- */
-static void qed_aio_next_io(void *opaque, int ret)
-{
- QEDAIOCB *acb = opaque;
- BDRVQEDState *s = acb_to_s(acb);
- QEDFindClusterFunc *io_fn = (acb->flags & QED_AIOCB_WRITE) ?
- qed_aio_write_data : qed_aio_read_data;
-
- trace_qed_aio_next_io(s, acb, ret, acb->cur_pos + acb->cur_qiov.size);
-
- /* Handle I/O error */
- if (ret) {
- qed_aio_complete(acb, ret);
- return;
- }
-
- acb->qiov_offset += acb->cur_qiov.size;
- acb->cur_pos += acb->cur_qiov.size;
- qemu_iovec_reset(&acb->cur_qiov);
-
- /* Complete request */
- if (acb->cur_pos >= acb->end_pos) {
- qed_aio_complete(acb, 0);
- return;
- }
-
- /* Find next cluster and start I/O */
- qed_find_cluster(s, &acb->request,
- acb->cur_pos, acb->end_pos - acb->cur_pos,
- io_fn, acb);
-}
-
-static BlockDriverAIOCB *qed_aio_setup(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque, int flags)
-{
- QEDAIOCB *acb = qemu_aio_get(&qed_aiocb_info, bs, cb, opaque);
-
- trace_qed_aio_setup(bs->opaque, acb, sector_num, nb_sectors,
- opaque, flags);
-
- acb->flags = flags;
- acb->finished = NULL;
- acb->qiov = qiov;
- acb->qiov_offset = 0;
- acb->cur_pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE;
- acb->end_pos = acb->cur_pos + nb_sectors * BDRV_SECTOR_SIZE;
- acb->request.l2_table = NULL;
- qemu_iovec_init(&acb->cur_qiov, qiov->niov);
-
- /* Start request */
- qed_aio_next_io(acb, 0);
- return &acb->common;
-}
-
-static BlockDriverAIOCB *bdrv_qed_aio_readv(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
-{
- return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
-}
-
-static BlockDriverAIOCB *bdrv_qed_aio_writev(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
-{
- return qed_aio_setup(bs, sector_num, qiov, nb_sectors, cb,
- opaque, QED_AIOCB_WRITE);
-}
-
-typedef struct {
- Coroutine *co;
- int ret;
- bool done;
-} QEDWriteZeroesCB;
-
-static void coroutine_fn qed_co_write_zeroes_cb(void *opaque, int ret)
-{
- QEDWriteZeroesCB *cb = opaque;
-
- cb->done = true;
- cb->ret = ret;
- if (cb->co) {
- qemu_coroutine_enter(cb->co, NULL);
- }
-}
-
-static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs,
- int64_t sector_num,
- int nb_sectors)
-{
- BlockDriverAIOCB *blockacb;
- BDRVQEDState *s = bs->opaque;
- QEDWriteZeroesCB cb = { .done = false };
- QEMUIOVector qiov;
- struct iovec iov;
-
- /* Refuse if there are untouched backing file sectors */
- if (bs->backing_hd) {
- if (qed_offset_into_cluster(s, sector_num * BDRV_SECTOR_SIZE) != 0) {
- return -ENOTSUP;
- }
- if (qed_offset_into_cluster(s, nb_sectors * BDRV_SECTOR_SIZE) != 0) {
- return -ENOTSUP;
- }
- }
-
- /* Zero writes start without an I/O buffer. If a buffer becomes necessary
- * then it will be allocated during request processing.
- */
- iov.iov_base = NULL,
- iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
-
- qemu_iovec_init_external(&qiov, &iov, 1);
- blockacb = qed_aio_setup(bs, sector_num, &qiov, nb_sectors,
- qed_co_write_zeroes_cb, &cb,
- QED_AIOCB_WRITE | QED_AIOCB_ZERO);
- if (!blockacb) {
- return -EIO;
- }
- if (!cb.done) {
- cb.co = qemu_coroutine_self();
- qemu_coroutine_yield();
- }
- assert(cb.done);
- return cb.ret;
-}
-
-static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset)
-{
- BDRVQEDState *s = bs->opaque;
- uint64_t old_image_size;
- int ret;
-
- if (!qed_is_image_size_valid(offset, s->header.cluster_size,
- s->header.table_size)) {
- return -EINVAL;
- }
-
- /* Shrinking is currently not supported */
- if ((uint64_t)offset < s->header.image_size) {
- return -ENOTSUP;
- }
-
- old_image_size = s->header.image_size;
- s->header.image_size = offset;
- ret = qed_write_header_sync(s);
- if (ret < 0) {
- s->header.image_size = old_image_size;
- }
- return ret;
-}
-
-static int64_t bdrv_qed_getlength(BlockDriverState *bs)
-{
- BDRVQEDState *s = bs->opaque;
- return s->header.image_size;
-}
-
-static int bdrv_qed_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
- BDRVQEDState *s = bs->opaque;
-
- memset(bdi, 0, sizeof(*bdi));
- bdi->cluster_size = s->header.cluster_size;
- bdi->is_dirty = s->header.features & QED_F_NEED_CHECK;
- return 0;
-}
-
-static int bdrv_qed_change_backing_file(BlockDriverState *bs,
- const char *backing_file,
- const char *backing_fmt)
-{
- BDRVQEDState *s = bs->opaque;
- QEDHeader new_header, le_header;
- void *buffer;
- size_t buffer_len, backing_file_len;
- int ret;
-
- /* Refuse to set backing filename if unknown compat feature bits are
- * active. If the image uses an unknown compat feature then we may not
- * know the layout of data following the header structure and cannot safely
- * add a new string.
- */
- if (backing_file && (s->header.compat_features &
- ~QED_COMPAT_FEATURE_MASK)) {
- return -ENOTSUP;
- }
-
- memcpy(&new_header, &s->header, sizeof(new_header));
-
- new_header.features &= ~(QED_F_BACKING_FILE |
- QED_F_BACKING_FORMAT_NO_PROBE);
-
- /* Adjust feature flags */
- if (backing_file) {
- new_header.features |= QED_F_BACKING_FILE;
-
- if (qed_fmt_is_raw(backing_fmt)) {
- new_header.features |= QED_F_BACKING_FORMAT_NO_PROBE;
- }
- }
-
- /* Calculate new header size */
- backing_file_len = 0;
-
- if (backing_file) {
- backing_file_len = strlen(backing_file);
- }
-
- buffer_len = sizeof(new_header);
- new_header.backing_filename_offset = buffer_len;
- new_header.backing_filename_size = backing_file_len;
- buffer_len += backing_file_len;
-
- /* Make sure we can rewrite header without failing */
- if (buffer_len > new_header.header_size * new_header.cluster_size) {
- return -ENOSPC;
- }
-
- /* Prepare new header */
- buffer = g_malloc(buffer_len);
-
- qed_header_cpu_to_le(&new_header, &le_header);
- memcpy(buffer, &le_header, sizeof(le_header));
- buffer_len = sizeof(le_header);
-
- if (backing_file) {
- memcpy(buffer + buffer_len, backing_file, backing_file_len);
- buffer_len += backing_file_len;
- }
-
- /* Write new header */
- ret = bdrv_pwrite_sync(bs->file, 0, buffer, buffer_len);
- g_free(buffer);
- if (ret == 0) {
- memcpy(&s->header, &new_header, sizeof(new_header));
- }
- return ret;
-}
-
-static void bdrv_qed_invalidate_cache(BlockDriverState *bs)
-{
- BDRVQEDState *s = bs->opaque;
-
- bdrv_qed_close(bs);
- memset(s, 0, sizeof(BDRVQEDState));
- bdrv_qed_open(bs, NULL, bs->open_flags);
-}
-
-static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
- BdrvCheckMode fix)
-{
- BDRVQEDState *s = bs->opaque;
-
- return qed_check(s, result, !!fix);
-}
-
-static QEMUOptionParameter qed_create_options[] = {
- {
- .name = BLOCK_OPT_SIZE,
- .type = OPT_SIZE,
- .help = "Virtual disk size (in bytes)"
- }, {
- .name = BLOCK_OPT_BACKING_FILE,
- .type = OPT_STRING,
- .help = "File name of a base image"
- }, {
- .name = BLOCK_OPT_BACKING_FMT,
- .type = OPT_STRING,
- .help = "Image format of the base image"
- }, {
- .name = BLOCK_OPT_CLUSTER_SIZE,
- .type = OPT_SIZE,
- .help = "Cluster size (in bytes)",
- .value = { .n = QED_DEFAULT_CLUSTER_SIZE },
- }, {
- .name = BLOCK_OPT_TABLE_SIZE,
- .type = OPT_SIZE,
- .help = "L1/L2 table size (in clusters)"
- },
- { /* end of list */ }
-};
-
-static BlockDriver bdrv_qed = {
- .format_name = "qed",
- .instance_size = sizeof(BDRVQEDState),
- .create_options = qed_create_options,
-
- .bdrv_probe = bdrv_qed_probe,
- .bdrv_rebind = bdrv_qed_rebind,
- .bdrv_open = bdrv_qed_open,
- .bdrv_close = bdrv_qed_close,
- .bdrv_reopen_prepare = bdrv_qed_reopen_prepare,
- .bdrv_create = bdrv_qed_create,
- .bdrv_has_zero_init = bdrv_has_zero_init_1,
- .bdrv_co_is_allocated = bdrv_qed_co_is_allocated,
- .bdrv_make_empty = bdrv_qed_make_empty,
- .bdrv_aio_readv = bdrv_qed_aio_readv,
- .bdrv_aio_writev = bdrv_qed_aio_writev,
- .bdrv_co_write_zeroes = bdrv_qed_co_write_zeroes,
- .bdrv_truncate = bdrv_qed_truncate,
- .bdrv_getlength = bdrv_qed_getlength,
- .bdrv_get_info = bdrv_qed_get_info,
- .bdrv_change_backing_file = bdrv_qed_change_backing_file,
- .bdrv_invalidate_cache = bdrv_qed_invalidate_cache,
- .bdrv_check = bdrv_qed_check,
-};
-
-static void bdrv_qed_init(void)
-{
- bdrv_register(&bdrv_qed);
-}
-
-block_init(bdrv_qed_init);
diff --git a/contrib/qemu/block/qed.h b/contrib/qemu/block/qed.h
deleted file mode 100644
index 2b4ddedf313..00000000000
--- a/contrib/qemu/block/qed.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * QEMU Enhanced Disk Format
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef BLOCK_QED_H
-#define BLOCK_QED_H
-
-#include "block/block_int.h"
-
-/* The layout of a QED file is as follows:
- *
- * +--------+----------+----------+----------+-----+
- * | header | L1 table | cluster0 | cluster1 | ... |
- * +--------+----------+----------+----------+-----+
- *
- * There is a 2-level pagetable for cluster allocation:
- *
- * +----------+
- * | L1 table |
- * +----------+
- * ,------' | '------.
- * +----------+ | +----------+
- * | L2 table | ... | L2 table |
- * +----------+ +----------+
- * ,------' | '------.
- * +----------+ | +----------+
- * | Data | ... | Data |
- * +----------+ +----------+
- *
- * The L1 table is fixed size and always present. L2 tables are allocated on
- * demand. The L1 table size determines the maximum possible image size; it
- * can be influenced using the cluster_size and table_size values.
- *
- * All fields are little-endian on disk.
- */
-
-enum {
- QED_MAGIC = 'Q' | 'E' << 8 | 'D' << 16 | '\0' << 24,
-
- /* The image supports a backing file */
- QED_F_BACKING_FILE = 0x01,
-
- /* The image needs a consistency check before use */
- QED_F_NEED_CHECK = 0x02,
-
- /* The backing file format must not be probed, treat as raw image */
- QED_F_BACKING_FORMAT_NO_PROBE = 0x04,
-
- /* Feature bits must be used when the on-disk format changes */
- QED_FEATURE_MASK = QED_F_BACKING_FILE | /* supported feature bits */
- QED_F_NEED_CHECK |
- QED_F_BACKING_FORMAT_NO_PROBE,
- QED_COMPAT_FEATURE_MASK = 0, /* supported compat feature bits */
- QED_AUTOCLEAR_FEATURE_MASK = 0, /* supported autoclear feature bits */
-
- /* Data is stored in groups of sectors called clusters. Cluster size must
- * be large to avoid keeping too much metadata. I/O requests that have
- * sub-cluster size will require read-modify-write.
- */
- QED_MIN_CLUSTER_SIZE = 4 * 1024, /* in bytes */
- QED_MAX_CLUSTER_SIZE = 64 * 1024 * 1024,
- QED_DEFAULT_CLUSTER_SIZE = 64 * 1024,
-
- /* Allocated clusters are tracked using a 2-level pagetable. Table size is
- * a multiple of clusters so large maximum image sizes can be supported
- * without jacking up the cluster size too much.
- */
- QED_MIN_TABLE_SIZE = 1, /* in clusters */
- QED_MAX_TABLE_SIZE = 16,
- QED_DEFAULT_TABLE_SIZE = 4,
-
- /* Delay to flush and clean image after last allocating write completes */
- QED_NEED_CHECK_TIMEOUT = 5, /* in seconds */
-};
-
-typedef struct {
- uint32_t magic; /* QED\0 */
-
- uint32_t cluster_size; /* in bytes */
- uint32_t table_size; /* for L1 and L2 tables, in clusters */
- uint32_t header_size; /* in clusters */
-
- uint64_t features; /* format feature bits */
- uint64_t compat_features; /* compatible feature bits */
- uint64_t autoclear_features; /* self-resetting feature bits */
-
- uint64_t l1_table_offset; /* in bytes */
- uint64_t image_size; /* total logical image size, in bytes */
-
- /* if (features & QED_F_BACKING_FILE) */
- uint32_t backing_filename_offset; /* in bytes from start of header */
- uint32_t backing_filename_size; /* in bytes */
-} QEDHeader;
-
-typedef struct {
- uint64_t offsets[0]; /* in bytes */
-} QEDTable;
-
-/* The L2 cache is a simple write-through cache for L2 structures */
-typedef struct CachedL2Table {
- QEDTable *table;
- uint64_t offset; /* offset=0 indicates an invalidate entry */
- QTAILQ_ENTRY(CachedL2Table) node;
- int ref;
-} CachedL2Table;
-
-typedef struct {
- QTAILQ_HEAD(, CachedL2Table) entries;
- unsigned int n_entries;
-} L2TableCache;
-
-typedef struct QEDRequest {
- CachedL2Table *l2_table;
-} QEDRequest;
-
-enum {
- QED_AIOCB_WRITE = 0x0001, /* read or write? */
- QED_AIOCB_ZERO = 0x0002, /* zero write, used with QED_AIOCB_WRITE */
-};
-
-typedef struct QEDAIOCB {
- BlockDriverAIOCB common;
- QEMUBH *bh;
- int bh_ret; /* final return status for completion bh */
- QSIMPLEQ_ENTRY(QEDAIOCB) next; /* next request */
- int flags; /* QED_AIOCB_* bits ORed together */
- bool *finished; /* signal for cancel completion */
- uint64_t end_pos; /* request end on block device, in bytes */
-
- /* User scatter-gather list */
- QEMUIOVector *qiov;
- size_t qiov_offset; /* byte count already processed */
-
- /* Current cluster scatter-gather list */
- QEMUIOVector cur_qiov;
- uint64_t cur_pos; /* position on block device, in bytes */
- uint64_t cur_cluster; /* cluster offset in image file */
- unsigned int cur_nclusters; /* number of clusters being accessed */
- int find_cluster_ret; /* used for L1/L2 update */
-
- QEDRequest request;
-} QEDAIOCB;
-
-typedef struct {
- BlockDriverState *bs; /* device */
- uint64_t file_size; /* length of image file, in bytes */
-
- QEDHeader header; /* always cpu-endian */
- QEDTable *l1_table;
- L2TableCache l2_cache; /* l2 table cache */
- uint32_t table_nelems;
- uint32_t l1_shift;
- uint32_t l2_shift;
- uint32_t l2_mask;
-
- /* Allocating write request queue */
- QSIMPLEQ_HEAD(, QEDAIOCB) allocating_write_reqs;
- bool allocating_write_reqs_plugged;
-
- /* Periodic flush and clear need check flag */
- QEMUTimer *need_check_timer;
-} BDRVQEDState;
-
-enum {
- QED_CLUSTER_FOUND, /* cluster found */
- QED_CLUSTER_ZERO, /* zero cluster found */
- QED_CLUSTER_L2, /* cluster missing in L2 */
- QED_CLUSTER_L1, /* cluster missing in L1 */
-};
-
-/**
- * qed_find_cluster() completion callback
- *
- * @opaque: User data for completion callback
- * @ret: QED_CLUSTER_FOUND Success
- * QED_CLUSTER_L2 Data cluster unallocated in L2
- * QED_CLUSTER_L1 L2 unallocated in L1
- * -errno POSIX error occurred
- * @offset: Data cluster offset
- * @len: Contiguous bytes starting from cluster offset
- *
- * This function is invoked when qed_find_cluster() completes.
- *
- * On success ret is QED_CLUSTER_FOUND and offset/len are a contiguous range
- * in the image file.
- *
- * On failure ret is QED_CLUSTER_L2 or QED_CLUSTER_L1 for missing L2 or L1
- * table offset, respectively. len is number of contiguous unallocated bytes.
- */
-typedef void QEDFindClusterFunc(void *opaque, int ret, uint64_t offset, size_t len);
-
-/**
- * Generic callback for chaining async callbacks
- */
-typedef struct {
- BlockDriverCompletionFunc *cb;
- void *opaque;
-} GenericCB;
-
-void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque);
-void gencb_complete(void *opaque, int ret);
-
-/**
- * Header functions
- */
-int qed_write_header_sync(BDRVQEDState *s);
-
-/**
- * L2 cache functions
- */
-void qed_init_l2_cache(L2TableCache *l2_cache);
-void qed_free_l2_cache(L2TableCache *l2_cache);
-CachedL2Table *qed_alloc_l2_cache_entry(L2TableCache *l2_cache);
-void qed_unref_l2_cache_entry(CachedL2Table *entry);
-CachedL2Table *qed_find_l2_cache_entry(L2TableCache *l2_cache, uint64_t offset);
-void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
-
-/**
- * Table I/O functions
- */
-int qed_read_l1_table_sync(BDRVQEDState *s);
-void qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n,
- BlockDriverCompletionFunc *cb, void *opaque);
-int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
- unsigned int n);
-int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
- uint64_t offset);
-void qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset,
- BlockDriverCompletionFunc *cb, void *opaque);
-void qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
- unsigned int index, unsigned int n, bool flush,
- BlockDriverCompletionFunc *cb, void *opaque);
-int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
- unsigned int index, unsigned int n, bool flush);
-
-/**
- * Cluster functions
- */
-void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
- size_t len, QEDFindClusterFunc *cb, void *opaque);
-
-/**
- * Consistency check
- */
-int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
-
-QEDTable *qed_alloc_table(BDRVQEDState *s);
-
-/**
- * Round down to the start of a cluster
- */
-static inline uint64_t qed_start_of_cluster(BDRVQEDState *s, uint64_t offset)
-{
- return offset & ~(uint64_t)(s->header.cluster_size - 1);
-}
-
-static inline uint64_t qed_offset_into_cluster(BDRVQEDState *s, uint64_t offset)
-{
- return offset & (s->header.cluster_size - 1);
-}
-
-static inline uint64_t qed_bytes_to_clusters(BDRVQEDState *s, uint64_t bytes)
-{
- return qed_start_of_cluster(s, bytes + (s->header.cluster_size - 1)) /
- (s->header.cluster_size - 1);
-}
-
-static inline unsigned int qed_l1_index(BDRVQEDState *s, uint64_t pos)
-{
- return pos >> s->l1_shift;
-}
-
-static inline unsigned int qed_l2_index(BDRVQEDState *s, uint64_t pos)
-{
- return (pos >> s->l2_shift) & s->l2_mask;
-}
-
-/**
- * Test if a cluster offset is valid
- */
-static inline bool qed_check_cluster_offset(BDRVQEDState *s, uint64_t offset)
-{
- uint64_t header_size = (uint64_t)s->header.header_size *
- s->header.cluster_size;
-
- if (offset & (s->header.cluster_size - 1)) {
- return false;
- }
- return offset >= header_size && offset < s->file_size;
-}
-
-/**
- * Test if a table offset is valid
- */
-static inline bool qed_check_table_offset(BDRVQEDState *s, uint64_t offset)
-{
- uint64_t end_offset = offset + (s->header.table_size - 1) *
- s->header.cluster_size;
-
- /* Overflow check */
- if (end_offset <= offset) {
- return false;
- }
-
- return qed_check_cluster_offset(s, offset) &&
- qed_check_cluster_offset(s, end_offset);
-}
-
-static inline bool qed_offset_is_cluster_aligned(BDRVQEDState *s,
- uint64_t offset)
-{
- if (qed_offset_into_cluster(s, offset)) {
- return false;
- }
- return true;
-}
-
-static inline bool qed_offset_is_unalloc_cluster(uint64_t offset)
-{
- if (offset == 0) {
- return true;
- }
- return false;
-}
-
-static inline bool qed_offset_is_zero_cluster(uint64_t offset)
-{
- if (offset == 1) {
- return true;
- }
- return false;
-}
-
-#endif /* BLOCK_QED_H */
diff --git a/contrib/qemu/block/snapshot.c b/contrib/qemu/block/snapshot.c
deleted file mode 100644
index 6c6d9deea1f..00000000000
--- a/contrib/qemu/block/snapshot.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Block layer snapshot related functions
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "block/snapshot.h"
-#include "block/block_int.h"
-
-int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
- const char *name)
-{
- QEMUSnapshotInfo *sn_tab, *sn;
- int nb_sns, i, ret;
-
- ret = -ENOENT;
- nb_sns = bdrv_snapshot_list(bs, &sn_tab);
- if (nb_sns < 0) {
- return ret;
- }
- for (i = 0; i < nb_sns; i++) {
- sn = &sn_tab[i];
- if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
- *sn_info = *sn;
- ret = 0;
- break;
- }
- }
- g_free(sn_tab);
- return ret;
-}
-
-int bdrv_can_snapshot(BlockDriverState *bs)
-{
- BlockDriver *drv = bs->drv;
- if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
- return 0;
- }
-
- if (!drv->bdrv_snapshot_create) {
- if (bs->file != NULL) {
- return bdrv_can_snapshot(bs->file);
- }
- return 0;
- }
-
- return 1;
-}
-
-int bdrv_snapshot_create(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info)
-{
- BlockDriver *drv = bs->drv;
- if (!drv) {
- return -ENOMEDIUM;
- }
- if (drv->bdrv_snapshot_create) {
- return drv->bdrv_snapshot_create(bs, sn_info);
- }
- if (bs->file) {
- return bdrv_snapshot_create(bs->file, sn_info);
- }
- return -ENOTSUP;
-}
-
-int bdrv_snapshot_goto(BlockDriverState *bs,
- const char *snapshot_id)
-{
- BlockDriver *drv = bs->drv;
- int ret, open_ret;
-
- if (!drv) {
- return -ENOMEDIUM;
- }
- if (drv->bdrv_snapshot_goto) {
- return drv->bdrv_snapshot_goto(bs, snapshot_id);
- }
-
- if (bs->file) {
- drv->bdrv_close(bs);
- ret = bdrv_snapshot_goto(bs->file, snapshot_id);
- open_ret = drv->bdrv_open(bs, NULL, bs->open_flags);
- if (open_ret < 0) {
- bdrv_delete(bs->file);
- bs->drv = NULL;
- return open_ret;
- }
- return ret;
- }
-
- return -ENOTSUP;
-}
-
-int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
-{
- BlockDriver *drv = bs->drv;
- if (!drv) {
- return -ENOMEDIUM;
- }
- if (drv->bdrv_snapshot_delete) {
- return drv->bdrv_snapshot_delete(bs, snapshot_id);
- }
- if (bs->file) {
- return bdrv_snapshot_delete(bs->file, snapshot_id);
- }
- return -ENOTSUP;
-}
-
-int bdrv_snapshot_list(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info)
-{
- BlockDriver *drv = bs->drv;
- if (!drv) {
- return -ENOMEDIUM;
- }
- if (drv->bdrv_snapshot_list) {
- return drv->bdrv_snapshot_list(bs, psn_info);
- }
- if (bs->file) {
- return bdrv_snapshot_list(bs->file, psn_info);
- }
- return -ENOTSUP;
-}
-
-int bdrv_snapshot_load_tmp(BlockDriverState *bs,
- const char *snapshot_name)
-{
- BlockDriver *drv = bs->drv;
- if (!drv) {
- return -ENOMEDIUM;
- }
- if (!bs->read_only) {
- return -EINVAL;
- }
- if (drv->bdrv_snapshot_load_tmp) {
- return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
- }
- return -ENOTSUP;
-}
diff --git a/contrib/qemu/config-host.h b/contrib/qemu/config-host.h
deleted file mode 100644
index 6b5c8da1243..00000000000
--- a/contrib/qemu/config-host.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Automatically generated by create_config - do not modify */
-#define CONFIG_QEMU_CONFDIR "/usr/local/etc/qemu"
-#define CONFIG_QEMU_DATADIR "/usr/local/share/qemu"
-#define CONFIG_QEMU_DOCDIR "/usr/local/share/doc/qemu"
-#define CONFIG_QEMU_LOCALSTATEDIR "/usr/local/var"
-#define CONFIG_QEMU_HELPERDIR "/usr/local/libexec"
-#define CONFIG_QEMU_LOCALEDIR "/usr/local/share/locale"
-#define HOST_X86_64 1
-#define CONFIG_QEMU_LDST_OPTIMIZATION 1
-#define CONFIG_POSIX 1
-#define CONFIG_LINUX 1
-#define CONFIG_SLIRP 1
-#define CONFIG_SMBD_COMMAND "/usr/sbin/smbd"
-#define CONFIG_AUDIO_DRIVERS \
- &oss_audio_driver,\
-
-#define CONFIG_OSS 1
-#define CONFIG_BDRV_RW_WHITELIST\
- NULL
-#define CONFIG_BDRV_RO_WHITELIST\
- NULL
-#define CONFIG_VNC 1
-#define CONFIG_VNC_TLS 1
-#define CONFIG_VNC_SASL 1
-#define CONFIG_VNC_WS 1
-#define CONFIG_FNMATCH 1
-#define CONFIG_UUID 1
-#define CONFIG_XFS 1
-#define QEMU_VERSION "1.5.50"
-#define QEMU_PKGVERSION ""
-#define CONFIG_CURSES 1
-#define CONFIG_UTIMENSAT 1
-#define CONFIG_PIPE2 1
-#define CONFIG_ACCEPT4 1
-#define CONFIG_SPLICE 1
-#define CONFIG_EVENTFD 1
-#define CONFIG_FALLOCATE 1
-#define CONFIG_FALLOCATE_PUNCH_HOLE 1
-#define CONFIG_SYNC_FILE_RANGE 1
-#define CONFIG_FIEMAP 1
-#define CONFIG_DUP3 1
-#define CONFIG_EPOLL 1
-#define CONFIG_EPOLL_CREATE1 1
-#define CONFIG_EPOLL_PWAIT 1
-#define CONFIG_SENDFILE 1
-#define CONFIG_INOTIFY 1
-#define CONFIG_INOTIFY1 1
-#define CONFIG_BYTESWAP_H 1
-#define CONFIG_CURL 1
-#define CONFIG_LINUX_AIO 1
-#define CONFIG_ATTR 1
-#define CONFIG_VHOST_SCSI 1
-#define CONFIG_IOVEC 1
-#define CONFIG_PREADV 1
-#define CONFIG_FDT 1
-#define CONFIG_SIGNALFD 1
-#define CONFIG_FDATASYNC 1
-#define CONFIG_MADVISE 1
-#define CONFIG_POSIX_MADVISE 1
-#define CONFIG_SIGEV_THREAD_ID 1
-#define CONFIG_UNAME_RELEASE ""
-#define CONFIG_QOM_CAST_DEBUG 1
-#define CONFIG_COROUTINE_BACKEND ucontext
-#define CONFIG_OPEN_BY_HANDLE 1
-#define CONFIG_LINUX_MAGIC_H 1
-#define CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE 1
-#define CONFIG_HAS_ENVIRON 1
-#define CONFIG_CPUID_H 1
-#define CONFIG_VIRTIO_BLK_DATA_PLANE $(CONFIG_VIRTIO)
-#define CONFIG_TRACE_NOP 1
-#define CONFIG_TRACE_FILE trace
-#define CONFIG_TRACE_DEFAULT 1
diff --git a/contrib/qemu/coroutine-ucontext.c b/contrib/qemu/coroutine-ucontext.c
deleted file mode 100644
index 4bf2cde279b..00000000000
--- a/contrib/qemu/coroutine-ucontext.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * ucontext coroutine initialization code
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2011 Kevin Wolf <kwolf@redhat.com>
- *
- * 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 2.0 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, see <http://www.gnu.org/licenses/>.
- */
-
-/* XXX Is there a nicer way to disable glibc's stack check for longjmp? */
-#ifdef _FORTIFY_SOURCE
-#undef _FORTIFY_SOURCE
-#endif
-#include <stdlib.h>
-#include <setjmp.h>
-#include <stdint.h>
-#include <pthread.h>
-#include <ucontext.h>
-#include "qemu-common.h"
-#include "block/coroutine_int.h"
-
-#ifdef CONFIG_VALGRIND_H
-#include <valgrind/valgrind.h>
-#endif
-
-typedef struct {
- Coroutine base;
- void *stack;
- sigjmp_buf env;
-
-#ifdef CONFIG_VALGRIND_H
- unsigned int valgrind_stack_id;
-#endif
-
-} CoroutineUContext;
-
-/**
- * Per-thread coroutine bookkeeping
- */
-typedef struct {
- /** Currently executing coroutine */
- Coroutine *current;
-
- /** The default coroutine */
- CoroutineUContext leader;
-} CoroutineThreadState;
-
-static pthread_key_t thread_state_key;
-
-/*
- * va_args to makecontext() must be type 'int', so passing
- * the pointer we need may require several int args. This
- * union is a quick hack to let us do that
- */
-union cc_arg {
- void *p;
- int i[2];
-};
-
-static CoroutineThreadState *coroutine_get_thread_state(void)
-{
- CoroutineThreadState *s = pthread_getspecific(thread_state_key);
-
- if (!s) {
- s = g_malloc0(sizeof(*s));
- s->current = &s->leader.base;
- pthread_setspecific(thread_state_key, s);
- }
- return s;
-}
-
-static void qemu_coroutine_thread_cleanup(void *opaque)
-{
- CoroutineThreadState *s = opaque;
-
- g_free(s);
-}
-
-static void __attribute__((constructor)) coroutine_init(void)
-{
- int ret;
-
- ret = pthread_key_create(&thread_state_key, qemu_coroutine_thread_cleanup);
- if (ret != 0) {
- fprintf(stderr, "unable to create leader key: %s\n", strerror(errno));
- abort();
- }
-}
-
-static void coroutine_trampoline(int i0, int i1)
-{
- union cc_arg arg;
- CoroutineUContext *self;
- Coroutine *co;
-
- arg.i[0] = i0;
- arg.i[1] = i1;
- self = arg.p;
- co = &self->base;
-
- /* Initialize longjmp environment and switch back the caller */
- if (!sigsetjmp(self->env, 0)) {
- siglongjmp(*(sigjmp_buf *)co->entry_arg, 1);
- }
-
- while (true) {
- co->entry(co->entry_arg);
- qemu_coroutine_switch(co, co->caller, COROUTINE_TERMINATE);
- }
-}
-
-Coroutine *qemu_coroutine_new(void)
-{
- const size_t stack_size = 1 << 20;
- CoroutineUContext *co;
- ucontext_t old_uc, uc;
- sigjmp_buf old_env;
- union cc_arg arg = {0};
-
- /* The ucontext functions preserve signal masks which incurs a
- * system call overhead. sigsetjmp(buf, 0)/siglongjmp() does not
- * preserve signal masks but only works on the current stack.
- * Since we need a way to create and switch to a new stack, use
- * the ucontext functions for that but sigsetjmp()/siglongjmp() for
- * everything else.
- */
-
- if (getcontext(&uc) == -1) {
- abort();
- }
-
- co = g_malloc0(sizeof(*co));
- co->stack = g_malloc(stack_size);
- co->base.entry_arg = &old_env; /* stash away our jmp_buf */
-
- uc.uc_link = &old_uc;
- uc.uc_stack.ss_sp = co->stack;
- uc.uc_stack.ss_size = stack_size;
- uc.uc_stack.ss_flags = 0;
-
-#ifdef CONFIG_VALGRIND_H
- co->valgrind_stack_id =
- VALGRIND_STACK_REGISTER(co->stack, co->stack + stack_size);
-#endif
-
- arg.p = co;
-
- makecontext(&uc, (void (*)(void))coroutine_trampoline,
- 2, arg.i[0], arg.i[1]);
-
- /* swapcontext() in, siglongjmp() back out */
- if (!sigsetjmp(old_env, 0)) {
- swapcontext(&old_uc, &uc);
- }
- return &co->base;
-}
-
-#ifdef CONFIG_VALGRIND_H
-#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
-/* Work around an unused variable in the valgrind.h macro... */
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
-#endif
-static inline void valgrind_stack_deregister(CoroutineUContext *co)
-{
- VALGRIND_STACK_DEREGISTER(co->valgrind_stack_id);
-}
-#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
-#pragma GCC diagnostic pop
-#endif
-#endif
-
-void qemu_coroutine_delete(Coroutine *co_)
-{
- CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
-
-#ifdef CONFIG_VALGRIND_H
- valgrind_stack_deregister(co);
-#endif
-
- g_free(co->stack);
- g_free(co);
-}
-
-CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
- CoroutineAction action)
-{
- CoroutineUContext *from = DO_UPCAST(CoroutineUContext, base, from_);
- CoroutineUContext *to = DO_UPCAST(CoroutineUContext, base, to_);
- CoroutineThreadState *s = coroutine_get_thread_state();
- int ret;
-
- s->current = to_;
-
- ret = sigsetjmp(from->env, 0);
- if (ret == 0) {
- siglongjmp(to->env, action);
- }
- return ret;
-}
-
-Coroutine *qemu_coroutine_self(void)
-{
- CoroutineThreadState *s = coroutine_get_thread_state();
-
- return s->current;
-}
-
-bool qemu_in_coroutine(void)
-{
- CoroutineThreadState *s = pthread_getspecific(thread_state_key);
-
- return s && s->current->caller;
-}
diff --git a/contrib/qemu/include/block/aio.h b/contrib/qemu/include/block/aio.h
deleted file mode 100644
index 183679374fa..00000000000
--- a/contrib/qemu/include/block/aio.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * QEMU aio implementation
- *
- * Copyright IBM, Corp. 2008
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_AIO_H
-#define QEMU_AIO_H
-
-#include "qemu-common.h"
-#include "qemu/queue.h"
-#include "qemu/event_notifier.h"
-
-typedef struct BlockDriverAIOCB BlockDriverAIOCB;
-typedef void BlockDriverCompletionFunc(void *opaque, int ret);
-
-typedef struct AIOCBInfo {
- void (*cancel)(BlockDriverAIOCB *acb);
- size_t aiocb_size;
-} AIOCBInfo;
-
-struct BlockDriverAIOCB {
- const AIOCBInfo *aiocb_info;
- BlockDriverState *bs;
- BlockDriverCompletionFunc *cb;
- void *opaque;
-};
-
-void *qemu_aio_get(const AIOCBInfo *aiocb_info, BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque);
-void qemu_aio_release(void *p);
-
-typedef struct AioHandler AioHandler;
-typedef void QEMUBHFunc(void *opaque);
-typedef void IOHandler(void *opaque);
-
-typedef struct AioContext {
- GSource source;
-
- /* The list of registered AIO handlers */
- QLIST_HEAD(, AioHandler) aio_handlers;
-
- /* This is a simple lock used to protect the aio_handlers list.
- * Specifically, it's used to ensure that no callbacks are removed while
- * we're walking and dispatching callbacks.
- */
- int walking_handlers;
-
- /* Anchor of the list of Bottom Halves belonging to the context */
- struct QEMUBH *first_bh;
-
- /* A simple lock used to protect the first_bh list, and ensure that
- * no callbacks are removed while we're walking and dispatching callbacks.
- */
- int walking_bh;
-
- /* Used for aio_notify. */
- EventNotifier notifier;
-
- /* GPollFDs for aio_poll() */
- GArray *pollfds;
-
- /* Thread pool for performing work and receiving completion callbacks */
- struct ThreadPool *thread_pool;
-} AioContext;
-
-/* Returns 1 if there are still outstanding AIO requests; 0 otherwise */
-typedef int (AioFlushEventNotifierHandler)(EventNotifier *e);
-
-/**
- * aio_context_new: Allocate a new AioContext.
- *
- * AioContext provide a mini event-loop that can be waited on synchronously.
- * They also provide bottom halves, a service to execute a piece of code
- * as soon as possible.
- */
-AioContext *aio_context_new(void);
-
-/**
- * aio_context_ref:
- * @ctx: The AioContext to operate on.
- *
- * Add a reference to an AioContext.
- */
-void aio_context_ref(AioContext *ctx);
-
-/**
- * aio_context_unref:
- * @ctx: The AioContext to operate on.
- *
- * Drop a reference to an AioContext.
- */
-void aio_context_unref(AioContext *ctx);
-
-/**
- * aio_bh_new: Allocate a new bottom half structure.
- *
- * Bottom halves are lightweight callbacks whose invocation is guaranteed
- * to be wait-free, thread-safe and signal-safe. The #QEMUBH structure
- * is opaque and must be allocated prior to its use.
- */
-QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque);
-
-/**
- * aio_notify: Force processing of pending events.
- *
- * Similar to signaling a condition variable, aio_notify forces
- * aio_wait to exit, so that the next call will re-examine pending events.
- * The caller of aio_notify will usually call aio_wait again very soon,
- * or go through another iteration of the GLib main loop. Hence, aio_notify
- * also has the side effect of recalculating the sets of file descriptors
- * that the main loop waits for.
- *
- * Calling aio_notify is rarely necessary, because for example scheduling
- * a bottom half calls it already.
- */
-void aio_notify(AioContext *ctx);
-
-/**
- * aio_bh_poll: Poll bottom halves for an AioContext.
- *
- * These are internal functions used by the QEMU main loop.
- */
-int aio_bh_poll(AioContext *ctx);
-
-/**
- * qemu_bh_schedule: Schedule a bottom half.
- *
- * Scheduling a bottom half interrupts the main loop and causes the
- * execution of the callback that was passed to qemu_bh_new.
- *
- * Bottom halves that are scheduled from a bottom half handler are instantly
- * invoked. This can create an infinite loop if a bottom half handler
- * schedules itself.
- *
- * @bh: The bottom half to be scheduled.
- */
-void qemu_bh_schedule(QEMUBH *bh);
-
-/**
- * qemu_bh_cancel: Cancel execution of a bottom half.
- *
- * Canceling execution of a bottom half undoes the effect of calls to
- * qemu_bh_schedule without freeing its resources yet. While cancellation
- * itself is also wait-free and thread-safe, it can of course race with the
- * loop that executes bottom halves unless you are holding the iothread
- * mutex. This makes it mostly useless if you are not holding the mutex.
- *
- * @bh: The bottom half to be canceled.
- */
-void qemu_bh_cancel(QEMUBH *bh);
-
-/**
- *qemu_bh_delete: Cancel execution of a bottom half and free its resources.
- *
- * Deleting a bottom half frees the memory that was allocated for it by
- * qemu_bh_new. It also implies canceling the bottom half if it was
- * scheduled.
- *
- * @bh: The bottom half to be deleted.
- */
-void qemu_bh_delete(QEMUBH *bh);
-
-/* Return whether there are any pending callbacks from the GSource
- * attached to the AioContext.
- *
- * This is used internally in the implementation of the GSource.
- */
-bool aio_pending(AioContext *ctx);
-
-/* Progress in completing AIO work to occur. This can issue new pending
- * aio as a result of executing I/O completion or bh callbacks.
- *
- * If there is no pending AIO operation or completion (bottom half),
- * return false. If there are pending AIO operations of bottom halves,
- * return true.
- *
- * If there are no pending bottom halves, but there are pending AIO
- * operations, it may not be possible to make any progress without
- * blocking. If @blocking is true, this function will wait until one
- * or more AIO events have completed, to ensure something has moved
- * before returning.
- */
-bool aio_poll(AioContext *ctx, bool blocking);
-
-#ifdef CONFIG_POSIX
-/* Returns 1 if there are still outstanding AIO requests; 0 otherwise */
-typedef int (AioFlushHandler)(void *opaque);
-
-/* Register a file descriptor and associated callbacks. Behaves very similarly
- * to qemu_set_fd_handler2. Unlike qemu_set_fd_handler2, these callbacks will
- * be invoked when using qemu_aio_wait().
- *
- * Code that invokes AIO completion functions should rely on this function
- * instead of qemu_set_fd_handler[2].
- */
-void aio_set_fd_handler(AioContext *ctx,
- int fd,
- IOHandler *io_read,
- IOHandler *io_write,
- AioFlushHandler *io_flush,
- void *opaque);
-#endif
-
-/* Register an event notifier and associated callbacks. Behaves very similarly
- * to event_notifier_set_handler. Unlike event_notifier_set_handler, these callbacks
- * will be invoked when using qemu_aio_wait().
- *
- * Code that invokes AIO completion functions should rely on this function
- * instead of event_notifier_set_handler.
- */
-void aio_set_event_notifier(AioContext *ctx,
- EventNotifier *notifier,
- EventNotifierHandler *io_read,
- AioFlushEventNotifierHandler *io_flush);
-
-/* Return a GSource that lets the main loop poll the file descriptors attached
- * to this AioContext.
- */
-GSource *aio_get_g_source(AioContext *ctx);
-
-/* Return the ThreadPool bound to this AioContext */
-struct ThreadPool *aio_get_thread_pool(AioContext *ctx);
-
-/* Functions to operate on the main QEMU AioContext. */
-
-bool qemu_aio_wait(void);
-void qemu_aio_set_event_notifier(EventNotifier *notifier,
- EventNotifierHandler *io_read,
- AioFlushEventNotifierHandler *io_flush);
-
-#ifdef CONFIG_POSIX
-void qemu_aio_set_fd_handler(int fd,
- IOHandler *io_read,
- IOHandler *io_write,
- AioFlushHandler *io_flush,
- void *opaque);
-#endif
-
-#endif
diff --git a/contrib/qemu/include/block/block.h b/contrib/qemu/include/block/block.h
deleted file mode 100644
index b6b9014a9ce..00000000000
--- a/contrib/qemu/include/block/block.h
+++ /dev/null
@@ -1,443 +0,0 @@
-#ifndef BLOCK_H
-#define BLOCK_H
-
-#include "block/aio.h"
-#include "qemu-common.h"
-#include "qemu/option.h"
-#include "block/coroutine.h"
-#include "qapi/qmp/qobject.h"
-#include "qapi-types.h"
-
-/* block.c */
-typedef struct BlockDriver BlockDriver;
-typedef struct BlockJob BlockJob;
-
-typedef struct BlockDriverInfo {
- /* in bytes, 0 if irrelevant */
- int cluster_size;
- /* offset at which the VM state can be saved (0 if not possible) */
- int64_t vm_state_offset;
- bool is_dirty;
-} BlockDriverInfo;
-
-typedef struct BlockFragInfo {
- uint64_t allocated_clusters;
- uint64_t total_clusters;
- uint64_t fragmented_clusters;
- uint64_t compressed_clusters;
-} BlockFragInfo;
-
-/* Callbacks for block device models */
-typedef struct BlockDevOps {
- /*
- * Runs when virtual media changed (monitor commands eject, change)
- * Argument load is true on load and false on eject.
- * Beware: doesn't run when a host device's physical media
- * changes. Sure would be useful if it did.
- * Device models with removable media must implement this callback.
- */
- void (*change_media_cb)(void *opaque, bool load);
- /*
- * Runs when an eject request is issued from the monitor, the tray
- * is closed, and the medium is locked.
- * Device models that do not implement is_medium_locked will not need
- * this callback. Device models that can lock the medium or tray might
- * want to implement the callback and unlock the tray when "force" is
- * true, even if they do not support eject requests.
- */
- void (*eject_request_cb)(void *opaque, bool force);
- /*
- * Is the virtual tray open?
- * Device models implement this only when the device has a tray.
- */
- bool (*is_tray_open)(void *opaque);
- /*
- * Is the virtual medium locked into the device?
- * Device models implement this only when device has such a lock.
- */
- bool (*is_medium_locked)(void *opaque);
- /*
- * Runs when the size changed (e.g. monitor command block_resize)
- */
- void (*resize_cb)(void *opaque);
-} BlockDevOps;
-
-#define BDRV_O_RDWR 0x0002
-#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save writes in a snapshot */
-#define BDRV_O_NOCACHE 0x0020 /* do not use the host page cache */
-#define BDRV_O_CACHE_WB 0x0040 /* use write-back caching */
-#define BDRV_O_NATIVE_AIO 0x0080 /* use native AIO instead of the thread pool */
-#define BDRV_O_NO_BACKING 0x0100 /* don't open the backing file */
-#define BDRV_O_NO_FLUSH 0x0200 /* disable flushing on this disk */
-#define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
-#define BDRV_O_INCOMING 0x0800 /* consistency hint for incoming migration */
-#define BDRV_O_CHECK 0x1000 /* open solely for consistency check */
-#define BDRV_O_ALLOW_RDWR 0x2000 /* allow reopen to change from r/o to r/w */
-#define BDRV_O_UNMAP 0x4000 /* execute guest UNMAP/TRIM operations */
-
-#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)
-
-#define BDRV_SECTOR_BITS 9
-#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
-#define BDRV_SECTOR_MASK ~(BDRV_SECTOR_SIZE - 1)
-
-typedef enum {
- BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
-} BlockErrorAction;
-
-typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
-
-typedef struct BDRVReopenState {
- BlockDriverState *bs;
- int flags;
- void *opaque;
-} BDRVReopenState;
-
-
-void bdrv_iostatus_enable(BlockDriverState *bs);
-void bdrv_iostatus_reset(BlockDriverState *bs);
-void bdrv_iostatus_disable(BlockDriverState *bs);
-bool bdrv_iostatus_is_enabled(const BlockDriverState *bs);
-void bdrv_iostatus_set_err(BlockDriverState *bs, int error);
-void bdrv_info_print(Monitor *mon, const QObject *data);
-void bdrv_info(Monitor *mon, QObject **ret_data);
-void bdrv_stats_print(Monitor *mon, const QObject *data);
-void bdrv_info_stats(Monitor *mon, QObject **ret_data);
-
-/* disk I/O throttling */
-void bdrv_io_limits_enable(BlockDriverState *bs);
-void bdrv_io_limits_disable(BlockDriverState *bs);
-bool bdrv_io_limits_enabled(BlockDriverState *bs);
-
-void bdrv_init(void);
-void bdrv_init_with_whitelist(void);
-BlockDriver *bdrv_find_protocol(const char *filename,
- bool allow_protocol_prefix);
-BlockDriver *bdrv_find_format(const char *format_name);
-BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
- bool readonly);
-int bdrv_create(BlockDriver *drv, const char* filename,
- QEMUOptionParameter *options);
-int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
-BlockDriverState *bdrv_new(const char *device_name);
-void bdrv_make_anon(BlockDriverState *bs);
-void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
-void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top);
-void bdrv_delete(BlockDriverState *bs);
-int bdrv_parse_cache_flags(const char *mode, int *flags);
-int bdrv_parse_discard_flags(const char *mode, int *flags);
-int bdrv_file_open(BlockDriverState **pbs, const char *filename,
- QDict *options, int flags);
-int bdrv_open_backing_file(BlockDriverState *bs, QDict *options);
-int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
- int flags, BlockDriver *drv);
-BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
- BlockDriverState *bs, int flags);
-int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
-int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp);
-int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
- BlockReopenQueue *queue, Error **errp);
-void bdrv_reopen_commit(BDRVReopenState *reopen_state);
-void bdrv_reopen_abort(BDRVReopenState *reopen_state);
-void bdrv_close(BlockDriverState *bs);
-void bdrv_add_close_notifier(BlockDriverState *bs, Notifier *notify);
-int bdrv_attach_dev(BlockDriverState *bs, void *dev);
-void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev);
-void bdrv_detach_dev(BlockDriverState *bs, void *dev);
-void *bdrv_get_attached_dev(BlockDriverState *bs);
-void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
- void *opaque);
-void bdrv_dev_eject_request(BlockDriverState *bs, bool force);
-bool bdrv_dev_has_removable_media(BlockDriverState *bs);
-bool bdrv_dev_is_tray_open(BlockDriverState *bs);
-bool bdrv_dev_is_medium_locked(BlockDriverState *bs);
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov);
-int bdrv_pread(BlockDriverState *bs, int64_t offset,
- void *buf, int count);
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
- const void *buf, int count);
-int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov);
-int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
- const void *buf, int count);
-int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov);
-int coroutine_fn bdrv_co_copy_on_readv(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
-int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov);
-/*
- * Efficiently zero a region of the disk image. Note that this is a regular
- * I/O request like read or write and should have a reasonable size. This
- * function is not suitable for zeroing the entire image in a single request
- * because it may allocate memory for the entire region.
- */
-int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors);
-int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum);
-int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
- BlockDriverState *base,
- int64_t sector_num,
- int nb_sectors, int *pnum);
-BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
- const char *backing_file);
-int bdrv_get_backing_file_depth(BlockDriverState *bs);
-int bdrv_truncate(BlockDriverState *bs, int64_t offset);
-int64_t bdrv_getlength(BlockDriverState *bs);
-int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
-void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
-int bdrv_commit(BlockDriverState *bs);
-int bdrv_commit_all(void);
-int bdrv_change_backing_file(BlockDriverState *bs,
- const char *backing_file, const char *backing_fmt);
-void bdrv_register(BlockDriver *bdrv);
-int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
- BlockDriverState *base);
-BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
- BlockDriverState *bs);
-BlockDriverState *bdrv_find_base(BlockDriverState *bs);
-
-
-typedef struct BdrvCheckResult {
- int corruptions;
- int leaks;
- int check_errors;
- int corruptions_fixed;
- int leaks_fixed;
- int64_t image_end_offset;
- BlockFragInfo bfi;
-} BdrvCheckResult;
-
-typedef enum {
- BDRV_FIX_LEAKS = 1,
- BDRV_FIX_ERRORS = 2,
-} BdrvCheckMode;
-
-int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
-
-/* async block I/O */
-typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
- int sector_num);
-BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
- QEMUIOVector *iov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
- QEMUIOVector *iov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque);
-BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-void bdrv_aio_cancel(BlockDriverAIOCB *acb);
-
-typedef struct BlockRequest {
- /* Fields to be filled by multiwrite caller */
- int64_t sector;
- int nb_sectors;
- QEMUIOVector *qiov;
- BlockDriverCompletionFunc *cb;
- void *opaque;
-
- /* Filled by multiwrite implementation */
- int error;
-} BlockRequest;
-
-int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs,
- int num_reqs);
-
-/* sg packet commands */
-int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf);
-BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
- unsigned long int req, void *buf,
- BlockDriverCompletionFunc *cb, void *opaque);
-
-/* Invalidate any cached metadata used by image formats */
-void bdrv_invalidate_cache(BlockDriverState *bs);
-void bdrv_invalidate_cache_all(void);
-
-void bdrv_clear_incoming_migration_all(void);
-
-/* Ensure contents are flushed to disk. */
-int bdrv_flush(BlockDriverState *bs);
-int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
-int bdrv_flush_all(void);
-void bdrv_close_all(void);
-void bdrv_drain_all(void);
-
-int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
-int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
-int bdrv_has_zero_init_1(BlockDriverState *bs);
-int bdrv_has_zero_init(BlockDriverState *bs);
-int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
- int *pnum);
-int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
- int64_t sector_num, int nb_sectors, int *pnum);
-
-void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error,
- BlockdevOnError on_write_error);
-BlockdevOnError bdrv_get_on_error(BlockDriverState *bs, bool is_read);
-BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int error);
-void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
- bool is_read, int error);
-int bdrv_is_read_only(BlockDriverState *bs);
-int bdrv_is_sg(BlockDriverState *bs);
-int bdrv_enable_write_cache(BlockDriverState *bs);
-void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce);
-int bdrv_is_inserted(BlockDriverState *bs);
-int bdrv_media_changed(BlockDriverState *bs);
-void bdrv_lock_medium(BlockDriverState *bs, bool locked);
-void bdrv_eject(BlockDriverState *bs, bool eject_flag);
-const char *bdrv_get_format_name(BlockDriverState *bs);
-BlockDriverState *bdrv_find(const char *name);
-BlockDriverState *bdrv_next(BlockDriverState *bs);
-void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs),
- void *opaque);
-int bdrv_is_encrypted(BlockDriverState *bs);
-int bdrv_key_required(BlockDriverState *bs);
-int bdrv_set_key(BlockDriverState *bs, const char *key);
-int bdrv_query_missing_keys(void);
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
- void *opaque);
-const char *bdrv_get_device_name(BlockDriverState *bs);
-int bdrv_get_flags(BlockDriverState *bs);
-int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
-void bdrv_round_to_clusters(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- int64_t *cluster_sector_num,
- int *cluster_nb_sectors);
-
-const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
-void bdrv_get_backing_filename(BlockDriverState *bs,
- char *filename, int filename_size);
-void bdrv_get_full_backing_filename(BlockDriverState *bs,
- char *dest, size_t sz);
-int bdrv_is_snapshot(BlockDriverState *bs);
-
-int path_is_absolute(const char *path);
-void path_combine(char *dest, int dest_size,
- const char *base_path,
- const char *filename);
-
-int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
-int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
- int64_t pos, int size);
-
-int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
- int64_t pos, int size);
-
-void bdrv_img_create(const char *filename, const char *fmt,
- const char *base_filename, const char *base_fmt,
- char *options, uint64_t img_size, int flags,
- Error **errp, bool quiet);
-
-void bdrv_set_buffer_alignment(BlockDriverState *bs, int align);
-void *qemu_blockalign(BlockDriverState *bs, size_t size);
-bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
-
-struct HBitmapIter;
-void bdrv_set_dirty_tracking(BlockDriverState *bs, int granularity);
-int bdrv_get_dirty(BlockDriverState *bs, int64_t sector);
-void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
-void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors);
-void bdrv_dirty_iter_init(BlockDriverState *bs, struct HBitmapIter *hbi);
-int64_t bdrv_get_dirty_count(BlockDriverState *bs);
-
-void bdrv_enable_copy_on_read(BlockDriverState *bs);
-void bdrv_disable_copy_on_read(BlockDriverState *bs);
-
-void bdrv_set_in_use(BlockDriverState *bs, int in_use);
-int bdrv_in_use(BlockDriverState *bs);
-
-#ifdef CONFIG_LINUX_AIO
-int raw_get_aio_fd(BlockDriverState *bs);
-#else
-static inline int raw_get_aio_fd(BlockDriverState *bs)
-{
- return -ENOTSUP;
-}
-#endif
-
-enum BlockAcctType {
- BDRV_ACCT_READ,
- BDRV_ACCT_WRITE,
- BDRV_ACCT_FLUSH,
- BDRV_MAX_IOTYPE,
-};
-
-typedef struct BlockAcctCookie {
- int64_t bytes;
- int64_t start_time_ns;
- enum BlockAcctType type;
-} BlockAcctCookie;
-
-void bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
- int64_t bytes, enum BlockAcctType type);
-void bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie);
-
-typedef enum {
- BLKDBG_L1_UPDATE,
-
- BLKDBG_L1_GROW_ALLOC_TABLE,
- BLKDBG_L1_GROW_WRITE_TABLE,
- BLKDBG_L1_GROW_ACTIVATE_TABLE,
-
- BLKDBG_L2_LOAD,
- BLKDBG_L2_UPDATE,
- BLKDBG_L2_UPDATE_COMPRESSED,
- BLKDBG_L2_ALLOC_COW_READ,
- BLKDBG_L2_ALLOC_WRITE,
-
- BLKDBG_READ_AIO,
- BLKDBG_READ_BACKING_AIO,
- BLKDBG_READ_COMPRESSED,
-
- BLKDBG_WRITE_AIO,
- BLKDBG_WRITE_COMPRESSED,
-
- BLKDBG_VMSTATE_LOAD,
- BLKDBG_VMSTATE_SAVE,
-
- BLKDBG_COW_READ,
- BLKDBG_COW_WRITE,
-
- BLKDBG_REFTABLE_LOAD,
- BLKDBG_REFTABLE_GROW,
-
- BLKDBG_REFBLOCK_LOAD,
- BLKDBG_REFBLOCK_UPDATE,
- BLKDBG_REFBLOCK_UPDATE_PART,
- BLKDBG_REFBLOCK_ALLOC,
- BLKDBG_REFBLOCK_ALLOC_HOOKUP,
- BLKDBG_REFBLOCK_ALLOC_WRITE,
- BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS,
- BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE,
- BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE,
-
- BLKDBG_CLUSTER_ALLOC,
- BLKDBG_CLUSTER_ALLOC_BYTES,
- BLKDBG_CLUSTER_FREE,
-
- BLKDBG_FLUSH_TO_OS,
- BLKDBG_FLUSH_TO_DISK,
-
- BLKDBG_EVENT_MAX,
-} BlkDebugEvent;
-
-#define BLKDBG_EVENT(bs, evt) bdrv_debug_event(bs, evt)
-void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event);
-
-int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
- const char *tag);
-int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
-bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
-
-#endif
diff --git a/contrib/qemu/include/block/block_int.h b/contrib/qemu/include/block/block_int.h
deleted file mode 100644
index c6ac871e210..00000000000
--- a/contrib/qemu/include/block/block_int.h
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * QEMU System Emulator block driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef BLOCK_INT_H
-#define BLOCK_INT_H
-
-#include "block/block.h"
-#include "qemu/option.h"
-#include "qemu/queue.h"
-#include "block/coroutine.h"
-#include "qemu/timer.h"
-#include "qapi-types.h"
-#include "qapi/qmp/qerror.h"
-#include "monitor/monitor.h"
-#include "qemu/hbitmap.h"
-#include "block/snapshot.h"
-
-#define BLOCK_FLAG_ENCRYPT 1
-#define BLOCK_FLAG_COMPAT6 4
-#define BLOCK_FLAG_LAZY_REFCOUNTS 8
-
-#define BLOCK_IO_LIMIT_READ 0
-#define BLOCK_IO_LIMIT_WRITE 1
-#define BLOCK_IO_LIMIT_TOTAL 2
-
-#define BLOCK_IO_SLICE_TIME 100000000
-#define NANOSECONDS_PER_SECOND 1000000000.0
-
-#define BLOCK_OPT_SIZE "size"
-#define BLOCK_OPT_ENCRYPT "encryption"
-#define BLOCK_OPT_COMPAT6 "compat6"
-#define BLOCK_OPT_BACKING_FILE "backing_file"
-#define BLOCK_OPT_BACKING_FMT "backing_fmt"
-#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"
-#define BLOCK_OPT_TABLE_SIZE "table_size"
-#define BLOCK_OPT_PREALLOC "preallocation"
-#define BLOCK_OPT_SUBFMT "subformat"
-#define BLOCK_OPT_COMPAT_LEVEL "compat"
-#define BLOCK_OPT_LAZY_REFCOUNTS "lazy_refcounts"
-#define BLOCK_OPT_ADAPTER_TYPE "adapter_type"
-
-typedef struct BdrvTrackedRequest {
- BlockDriverState *bs;
- int64_t sector_num;
- int nb_sectors;
- bool is_write;
- QLIST_ENTRY(BdrvTrackedRequest) list;
- Coroutine *co; /* owner, used for deadlock detection */
- CoQueue wait_queue; /* coroutines blocked on this request */
-} BdrvTrackedRequest;
-
-
-typedef struct BlockIOLimit {
- int64_t bps[3];
- int64_t iops[3];
-} BlockIOLimit;
-
-typedef struct BlockIOBaseValue {
- uint64_t bytes[2];
- uint64_t ios[2];
-} BlockIOBaseValue;
-
-struct BlockDriver {
- const char *format_name;
- int instance_size;
- int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
- int (*bdrv_probe_device)(const char *filename);
-
- /* Any driver implementing this callback is expected to be able to handle
- * NULL file names in its .bdrv_open() implementation */
- void (*bdrv_parse_filename)(const char *filename, QDict *options, Error **errp);
-
- /* For handling image reopen for split or non-split files */
- int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
- BlockReopenQueue *queue, Error **errp);
- void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
- void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
-
- int (*bdrv_open)(BlockDriverState *bs, QDict *options, int flags);
- int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags);
- int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
- int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
- void (*bdrv_close)(BlockDriverState *bs);
- void (*bdrv_rebind)(BlockDriverState *bs);
- int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
- int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
- int (*bdrv_make_empty)(BlockDriverState *bs);
- /* aio */
- BlockDriverAIOCB *(*bdrv_aio_readv)(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
- BlockDriverAIOCB *(*bdrv_aio_writev)(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
- BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
- BlockDriverCompletionFunc *cb, void *opaque);
- BlockDriverAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors,
- BlockDriverCompletionFunc *cb, void *opaque);
-
- int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
- int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
- /*
- * Efficiently zero a region of the disk image. Typically an image format
- * would use a compact metadata representation to implement this. This
- * function pointer may be NULL and .bdrv_co_writev() will be called
- * instead.
- */
- int coroutine_fn (*bdrv_co_write_zeroes)(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors);
- int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors);
- int coroutine_fn (*bdrv_co_is_allocated)(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, int *pnum);
-
- /*
- * Invalidate any cached meta-data.
- */
- void (*bdrv_invalidate_cache)(BlockDriverState *bs);
-
- /*
- * Flushes all data that was already written to the OS all the way down to
- * the disk (for example raw-posix calls fsync()).
- */
- int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs);
-
- /*
- * Flushes all internal caches to the OS. The data may still sit in a
- * writeback cache of the host OS, but it will survive a crash of the qemu
- * process.
- */
- int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
-
- const char *protocol_name;
- int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
- int64_t (*bdrv_getlength)(BlockDriverState *bs);
- int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs);
- int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-
- int (*bdrv_snapshot_create)(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info);
- int (*bdrv_snapshot_goto)(BlockDriverState *bs,
- const char *snapshot_id);
- int (*bdrv_snapshot_delete)(BlockDriverState *bs, const char *snapshot_id);
- int (*bdrv_snapshot_list)(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info);
- int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
- const char *snapshot_name);
- int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
-
- int (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov,
- int64_t pos);
- int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf,
- int64_t pos, int size);
-
- int (*bdrv_change_backing_file)(BlockDriverState *bs,
- const char *backing_file, const char *backing_fmt);
-
- /* removable device specific */
- int (*bdrv_is_inserted)(BlockDriverState *bs);
- int (*bdrv_media_changed)(BlockDriverState *bs);
- void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag);
- void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked);
-
- /* to control generic scsi devices */
- int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf);
- BlockDriverAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
- unsigned long int req, void *buf,
- BlockDriverCompletionFunc *cb, void *opaque);
-
- /* List of options for creating images, terminated by name == NULL */
- QEMUOptionParameter *create_options;
-
-
- /*
- * Returns 0 for completed check, -errno for internal errors.
- * The check results are stored in result.
- */
- int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result,
- BdrvCheckMode fix);
-
- void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
-
- /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
- int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
- const char *tag);
- int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
- bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
-
- /*
- * Returns 1 if newly created images are guaranteed to contain only
- * zeros, 0 otherwise.
- */
- int (*bdrv_has_zero_init)(BlockDriverState *bs);
-
- QLIST_ENTRY(BlockDriver) list;
-};
-
-/*
- * Note: the function bdrv_append() copies and swaps contents of
- * BlockDriverStates, so if you add new fields to this struct, please
- * inspect bdrv_append() to determine if the new fields need to be
- * copied as well.
- */
-struct BlockDriverState {
- int64_t total_sectors; /* if we are reading a disk image, give its
- size in sectors */
- int read_only; /* if true, the media is read only */
- int open_flags; /* flags used to open the file, re-used for re-open */
- int encrypted; /* if true, the media is encrypted */
- int valid_key; /* if true, a valid encryption key has been set */
- int sg; /* if true, the device is a /dev/sg* */
- int copy_on_read; /* if true, copy read backing sectors into image
- note this is a reference count */
-
- BlockDriver *drv; /* NULL means no media */
- void *opaque;
-
- void *dev; /* attached device model, if any */
- /* TODO change to DeviceState when all users are qdevified */
- const BlockDevOps *dev_ops;
- void *dev_opaque;
-
- char filename[1024];
- char backing_file[1024]; /* if non zero, the image is a diff of
- this file image */
- char backing_format[16]; /* if non-zero and backing_file exists */
- int is_temporary;
-
- BlockDriverState *backing_hd;
- BlockDriverState *file;
-
- NotifierList close_notifiers;
-
- /* Callback before write request is processed */
- NotifierWithReturnList before_write_notifiers;
-
- /* number of in-flight copy-on-read requests */
- unsigned int copy_on_read_in_flight;
-
- /* the time for latest disk I/O */
- int64_t slice_start;
- int64_t slice_end;
- BlockIOLimit io_limits;
- BlockIOBaseValue slice_submitted;
- CoQueue throttled_reqs;
- QEMUTimer *block_timer;
- bool io_limits_enabled;
-
- /* I/O stats (display with "info blockstats"). */
- uint64_t nr_bytes[BDRV_MAX_IOTYPE];
- uint64_t nr_ops[BDRV_MAX_IOTYPE];
- uint64_t total_time_ns[BDRV_MAX_IOTYPE];
- uint64_t wr_highest_sector;
-
- /* Whether the disk can expand beyond total_sectors */
- int growable;
-
- /* the memory alignment required for the buffers handled by this driver */
- int buffer_alignment;
-
- /* do we need to tell the quest if we have a volatile write cache? */
- int enable_write_cache;
-
- /* NOTE: the following infos are only hints for real hardware
- drivers. They are not used by the block driver */
- BlockdevOnError on_read_error, on_write_error;
- bool iostatus_enabled;
- BlockDeviceIoStatus iostatus;
- char device_name[32];
- HBitmap *dirty_bitmap;
- int in_use; /* users other than guest access, eg. block migration */
- QTAILQ_ENTRY(BlockDriverState) list;
-
- QLIST_HEAD(, BdrvTrackedRequest) tracked_requests;
-
- /* long-running background operation */
- BlockJob *job;
-
- QDict *options;
-};
-
-int get_tmp_filename(char *filename, int size);
-
-void bdrv_set_io_limits(BlockDriverState *bs,
- BlockIOLimit *io_limits);
-
-/**
- * bdrv_add_before_write_notifier:
- *
- * Register a callback that is invoked before write requests are processed but
- * after any throttling or waiting for overlapping requests.
- */
-void bdrv_add_before_write_notifier(BlockDriverState *bs,
- NotifierWithReturn *notifier);
-
-/**
- * bdrv_get_aio_context:
- *
- * Returns: the currently bound #AioContext
- */
-AioContext *bdrv_get_aio_context(BlockDriverState *bs);
-
-#ifdef _WIN32
-int is_windows_drive(const char *filename);
-#endif
-void bdrv_emit_qmp_error_event(const BlockDriverState *bdrv,
- enum MonitorEvent ev,
- BlockErrorAction action, bool is_read);
-
-/**
- * stream_start:
- * @bs: Block device to operate on.
- * @base: Block device that will become the new base, or %NULL to
- * flatten the whole backing file chain onto @bs.
- * @base_id: The file name that will be written to @bs as the new
- * backing file if the job completes. Ignored if @base is %NULL.
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
- * @on_error: The action to take upon error.
- * @cb: Completion function for the job.
- * @opaque: Opaque pointer value passed to @cb.
- * @errp: Error object.
- *
- * Start a streaming operation on @bs. Clusters that are unallocated
- * in @bs, but allocated in any image between @base and @bs (both
- * exclusive) will be written to @bs. At the end of a successful
- * streaming job, the backing file of @bs will be changed to
- * @base_id in the written image and to @base in the live BlockDriverState.
- */
-void stream_start(BlockDriverState *bs, BlockDriverState *base,
- const char *base_id, int64_t speed, BlockdevOnError on_error,
- BlockDriverCompletionFunc *cb,
- void *opaque, Error **errp);
-
-/**
- * commit_start:
- * @bs: Top Block device
- * @base: Block device that will be written into, and become the new top
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
- * @on_error: The action to take upon error.
- * @cb: Completion function for the job.
- * @opaque: Opaque pointer value passed to @cb.
- * @errp: Error object.
- *
- */
-void commit_start(BlockDriverState *bs, BlockDriverState *base,
- BlockDriverState *top, int64_t speed,
- BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
- void *opaque, Error **errp);
-
-/*
- * mirror_start:
- * @bs: Block device to operate on.
- * @target: Block device to write to.
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
- * @granularity: The chosen granularity for the dirty bitmap.
- * @buf_size: The amount of data that can be in flight at one time.
- * @mode: Whether to collapse all images in the chain to the target.
- * @on_source_error: The action to take upon error reading from the source.
- * @on_target_error: The action to take upon error writing to the target.
- * @cb: Completion function for the job.
- * @opaque: Opaque pointer value passed to @cb.
- * @errp: Error object.
- *
- * Start a mirroring operation on @bs. Clusters that are allocated
- * in @bs will be written to @bs until the job is cancelled or
- * manually completed. At the end of a successful mirroring job,
- * @bs will be switched to read from @target.
- */
-void mirror_start(BlockDriverState *bs, BlockDriverState *target,
- int64_t speed, int64_t granularity, int64_t buf_size,
- MirrorSyncMode mode, BlockdevOnError on_source_error,
- BlockdevOnError on_target_error,
- BlockDriverCompletionFunc *cb,
- void *opaque, Error **errp);
-
-/*
- * backup_start:
- * @bs: Block device to operate on.
- * @target: Block device to write to.
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
- * @on_source_error: The action to take upon error reading from the source.
- * @on_target_error: The action to take upon error writing to the target.
- * @cb: Completion function for the job.
- * @opaque: Opaque pointer value passed to @cb.
- *
- * Start a backup operation on @bs. Clusters in @bs are written to @target
- * until the job is cancelled or manually completed.
- */
-void backup_start(BlockDriverState *bs, BlockDriverState *target,
- int64_t speed, BlockdevOnError on_source_error,
- BlockdevOnError on_target_error,
- BlockDriverCompletionFunc *cb, void *opaque,
- Error **errp);
-
-#endif /* BLOCK_INT_H */
diff --git a/contrib/qemu/include/block/blockjob.h b/contrib/qemu/include/block/blockjob.h
deleted file mode 100644
index c290d07bba0..00000000000
--- a/contrib/qemu/include/block/blockjob.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Declarations for long-running block device operations
- *
- * Copyright (c) 2011 IBM Corp.
- * Copyright (c) 2012 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef BLOCKJOB_H
-#define BLOCKJOB_H 1
-
-#include "block/block.h"
-
-/**
- * BlockJobType:
- *
- * A class type for block job objects.
- */
-typedef struct BlockJobType {
- /** Derived BlockJob struct size */
- size_t instance_size;
-
- /** String describing the operation, part of query-block-jobs QMP API */
- const char *job_type;
-
- /** Optional callback for job types that support setting a speed limit */
- void (*set_speed)(BlockJob *job, int64_t speed, Error **errp);
-
- /** Optional callback for job types that need to forward I/O status reset */
- void (*iostatus_reset)(BlockJob *job);
-
- /**
- * Optional callback for job types whose completion must be triggered
- * manually.
- */
- void (*complete)(BlockJob *job, Error **errp);
-} BlockJobType;
-
-/**
- * BlockJob:
- *
- * Long-running operation on a BlockDriverState.
- */
-struct BlockJob {
- /** The job type, including the job vtable. */
- const BlockJobType *job_type;
-
- /** The block device on which the job is operating. */
- BlockDriverState *bs;
-
- /**
- * The coroutine that executes the job. If not NULL, it is
- * reentered when busy is false and the job is cancelled.
- */
- Coroutine *co;
-
- /**
- * Set to true if the job should cancel itself. The flag must
- * always be tested just before toggling the busy flag from false
- * to true. After a job has been cancelled, it should only yield
- * if #qemu_aio_wait will ("sooner or later") reenter the coroutine.
- */
- bool cancelled;
-
- /**
- * Set to true if the job is either paused, or will pause itself
- * as soon as possible (if busy == true).
- */
- bool paused;
-
- /**
- * Set to false by the job while it is in a quiescent state, where
- * no I/O is pending and the job has yielded on any condition
- * that is not detected by #qemu_aio_wait, such as a timer.
- */
- bool busy;
-
- /** Status that is published by the query-block-jobs QMP API */
- BlockDeviceIoStatus iostatus;
-
- /** Offset that is published by the query-block-jobs QMP API */
- int64_t offset;
-
- /** Length that is published by the query-block-jobs QMP API */
- int64_t len;
-
- /** Speed that was set with @block_job_set_speed. */
- int64_t speed;
-
- /** The completion function that will be called when the job completes. */
- BlockDriverCompletionFunc *cb;
-
- /** The opaque value that is passed to the completion function. */
- void *opaque;
-};
-
-/**
- * block_job_create:
- * @job_type: The class object for the newly-created job.
- * @bs: The block
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
- * @cb: Completion function for the job.
- * @opaque: Opaque pointer value passed to @cb.
- * @errp: Error object.
- *
- * Create a new long-running block device job and return it. The job
- * will call @cb asynchronously when the job completes. Note that
- * @bs may have been closed at the time the @cb it is called. If
- * this is the case, the job may be reported as either cancelled or
- * completed.
- *
- * This function is not part of the public job interface; it should be
- * called from a wrapper that is specific to the job type.
- */
-void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
- int64_t speed, BlockDriverCompletionFunc *cb,
- void *opaque, Error **errp);
-
-/**
- * block_job_sleep_ns:
- * @job: The job that calls the function.
- * @clock: The clock to sleep on.
- * @ns: How many nanoseconds to stop for.
- *
- * Put the job to sleep (assuming that it wasn't canceled) for @ns
- * nanoseconds. Canceling the job will interrupt the wait immediately.
- */
-void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns);
-
-/**
- * block_job_completed:
- * @job: The job being completed.
- * @ret: The status code.
- *
- * Call the completion function that was registered at creation time, and
- * free @job.
- */
-void block_job_completed(BlockJob *job, int ret);
-
-/**
- * block_job_set_speed:
- * @job: The job to set the speed for.
- * @speed: The new value
- * @errp: Error object.
- *
- * Set a rate-limiting parameter for the job; the actual meaning may
- * vary depending on the job type.
- */
-void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp);
-
-/**
- * block_job_cancel:
- * @job: The job to be canceled.
- *
- * Asynchronously cancel the specified job.
- */
-void block_job_cancel(BlockJob *job);
-
-/**
- * block_job_complete:
- * @job: The job to be completed.
- * @errp: Error object.
- *
- * Asynchronously complete the specified job.
- */
-void block_job_complete(BlockJob *job, Error **errp);
-
-/**
- * block_job_is_cancelled:
- * @job: The job being queried.
- *
- * Returns whether the job is scheduled for cancellation.
- */
-bool block_job_is_cancelled(BlockJob *job);
-
-/**
- * block_job_query:
- * @job: The job to get information about.
- *
- * Return information about a job.
- */
-BlockJobInfo *block_job_query(BlockJob *job);
-
-/**
- * block_job_pause:
- * @job: The job to be paused.
- *
- * Asynchronously pause the specified job.
- */
-void block_job_pause(BlockJob *job);
-
-/**
- * block_job_resume:
- * @job: The job to be resumed.
- *
- * Resume the specified job.
- */
-void block_job_resume(BlockJob *job);
-
-/**
- * qobject_from_block_job:
- * @job: The job whose information is requested.
- *
- * Return a QDict corresponding to @job's query-block-jobs entry.
- */
-QObject *qobject_from_block_job(BlockJob *job);
-
-/**
- * block_job_ready:
- * @job: The job which is now ready to complete.
- *
- * Send a BLOCK_JOB_READY event for the specified job.
- */
-void block_job_ready(BlockJob *job);
-
-/**
- * block_job_is_paused:
- * @job: The job being queried.
- *
- * Returns whether the job is currently paused, or will pause
- * as soon as it reaches a sleeping point.
- */
-bool block_job_is_paused(BlockJob *job);
-
-/**
- * block_job_cancel_sync:
- * @job: The job to be canceled.
- *
- * Synchronously cancel the job. The completion callback is called
- * before the function returns. The job may actually complete
- * instead of canceling itself; the circumstances under which this
- * happens depend on the kind of job that is active.
- *
- * Returns the return value from the job if the job actually completed
- * during the call, or -ECANCELED if it was canceled.
- */
-int block_job_cancel_sync(BlockJob *job);
-
-/**
- * block_job_iostatus_reset:
- * @job: The job whose I/O status should be reset.
- *
- * Reset I/O status on @job and on BlockDriverState objects it uses,
- * other than job->bs.
- */
-void block_job_iostatus_reset(BlockJob *job);
-
-/**
- * block_job_error_action:
- * @job: The job to signal an error for.
- * @bs: The block device on which to set an I/O error.
- * @on_err: The error action setting.
- * @is_read: Whether the operation was a read.
- * @error: The error that was reported.
- *
- * Report an I/O error for a block job and possibly stop the VM. Return the
- * action that was selected based on @on_err and @error.
- */
-BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
- BlockdevOnError on_err,
- int is_read, int error);
-#endif
diff --git a/contrib/qemu/include/block/coroutine.h b/contrib/qemu/include/block/coroutine.h
deleted file mode 100644
index 377805a3b08..00000000000
--- a/contrib/qemu/include/block/coroutine.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * QEMU coroutine implementation
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
- * Kevin Wolf <kwolf@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QEMU_COROUTINE_H
-#define QEMU_COROUTINE_H
-
-#include <stdbool.h>
-#include "qemu/queue.h"
-#include "qemu/timer.h"
-
-/**
- * Coroutines are a mechanism for stack switching and can be used for
- * cooperative userspace threading. These functions provide a simple but
- * useful flavor of coroutines that is suitable for writing sequential code,
- * rather than callbacks, for operations that need to give up control while
- * waiting for events to complete.
- *
- * These functions are re-entrant and may be used outside the global mutex.
- */
-
-/**
- * Mark a function that executes in coroutine context
- *
- * Functions that execute in coroutine context cannot be called directly from
- * normal functions. In the future it would be nice to enable compiler or
- * static checker support for catching such errors. This annotation might make
- * it possible and in the meantime it serves as documentation.
- *
- * For example:
- *
- * static void coroutine_fn foo(void) {
- * ....
- * }
- */
-#define coroutine_fn
-
-typedef struct Coroutine Coroutine;
-
-/**
- * Coroutine entry point
- *
- * When the coroutine is entered for the first time, opaque is passed in as an
- * argument.
- *
- * When this function returns, the coroutine is destroyed automatically and
- * execution continues in the caller who last entered the coroutine.
- */
-typedef void coroutine_fn CoroutineEntry(void *opaque);
-
-/**
- * Create a new coroutine
- *
- * Use qemu_coroutine_enter() to actually transfer control to the coroutine.
- */
-Coroutine *qemu_coroutine_create(CoroutineEntry *entry);
-
-/**
- * Transfer control to a coroutine
- *
- * The opaque argument is passed as the argument to the entry point when
- * entering the coroutine for the first time. It is subsequently ignored.
- */
-void qemu_coroutine_enter(Coroutine *coroutine, void *opaque);
-
-/**
- * Transfer control back to a coroutine's caller
- *
- * This function does not return until the coroutine is re-entered using
- * qemu_coroutine_enter().
- */
-void coroutine_fn qemu_coroutine_yield(void);
-
-/**
- * Get the currently executing coroutine
- */
-Coroutine *coroutine_fn qemu_coroutine_self(void);
-
-/**
- * Return whether or not currently inside a coroutine
- *
- * This can be used to write functions that work both when in coroutine context
- * and when not in coroutine context. Note that such functions cannot use the
- * coroutine_fn annotation since they work outside coroutine context.
- */
-bool qemu_in_coroutine(void);
-
-
-
-/**
- * CoQueues are a mechanism to queue coroutines in order to continue executing
- * them later. They provide the fundamental primitives on which coroutine locks
- * are built.
- */
-typedef struct CoQueue {
- QTAILQ_HEAD(, Coroutine) entries;
- AioContext *ctx;
-} CoQueue;
-
-/**
- * Initialise a CoQueue. This must be called before any other operation is used
- * on the CoQueue.
- */
-void qemu_co_queue_init(CoQueue *queue);
-
-/**
- * Adds the current coroutine to the CoQueue and transfers control to the
- * caller of the coroutine.
- */
-void coroutine_fn qemu_co_queue_wait(CoQueue *queue);
-
-/**
- * Adds the current coroutine to the head of the CoQueue and transfers control to the
- * caller of the coroutine.
- */
-void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue);
-
-/**
- * Restarts the next coroutine in the CoQueue and removes it from the queue.
- *
- * Returns true if a coroutine was restarted, false if the queue is empty.
- */
-bool qemu_co_queue_next(CoQueue *queue);
-
-/**
- * Restarts all coroutines in the CoQueue and leaves the queue empty.
- */
-void qemu_co_queue_restart_all(CoQueue *queue);
-
-/**
- * Checks if the CoQueue is empty.
- */
-bool qemu_co_queue_empty(CoQueue *queue);
-
-
-/**
- * Provides a mutex that can be used to synchronise coroutines
- */
-typedef struct CoMutex {
- bool locked;
- CoQueue queue;
-} CoMutex;
-
-/**
- * Initialises a CoMutex. This must be called before any other operation is used
- * on the CoMutex.
- */
-void qemu_co_mutex_init(CoMutex *mutex);
-
-/**
- * Locks the mutex. If the lock cannot be taken immediately, control is
- * transferred to the caller of the current coroutine.
- */
-void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
-
-/**
- * Unlocks the mutex and schedules the next coroutine that was waiting for this
- * lock to be run.
- */
-void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
-
-typedef struct CoRwlock {
- bool writer;
- int reader;
- CoQueue queue;
-} CoRwlock;
-
-/**
- * Initialises a CoRwlock. This must be called before any other operation
- * is used on the CoRwlock
- */
-void qemu_co_rwlock_init(CoRwlock *lock);
-
-/**
- * Read locks the CoRwlock. If the lock cannot be taken immediately because
- * of a parallel writer, control is transferred to the caller of the current
- * coroutine.
- */
-void qemu_co_rwlock_rdlock(CoRwlock *lock);
-
-/**
- * Write Locks the mutex. If the lock cannot be taken immediately because
- * of a parallel reader, control is transferred to the caller of the current
- * coroutine.
- */
-void qemu_co_rwlock_wrlock(CoRwlock *lock);
-
-/**
- * Unlocks the read/write lock and schedules the next coroutine that was
- * waiting for this lock to be run.
- */
-void qemu_co_rwlock_unlock(CoRwlock *lock);
-
-/**
- * Yield the coroutine for a given duration
- *
- * Note this function uses timers and hence only works when a main loop is in
- * use. See main-loop.h and do not use from qemu-tool programs.
- */
-void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns);
-
-/**
- * Yield until a file descriptor becomes readable
- *
- * Note that this function clobbers the handlers for the file descriptor.
- */
-void coroutine_fn yield_until_fd_readable(int fd);
-#endif /* QEMU_COROUTINE_H */
diff --git a/contrib/qemu/include/block/coroutine_int.h b/contrib/qemu/include/block/coroutine_int.h
deleted file mode 100644
index f133d65af86..00000000000
--- a/contrib/qemu/include/block/coroutine_int.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Coroutine internals
- *
- * Copyright (c) 2011 Kevin Wolf <kwolf@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef QEMU_COROUTINE_INT_H
-#define QEMU_COROUTINE_INT_H
-
-#include "qemu/queue.h"
-#include "block/coroutine.h"
-
-typedef enum {
- COROUTINE_YIELD = 1,
- COROUTINE_TERMINATE = 2,
-} CoroutineAction;
-
-struct Coroutine {
- CoroutineEntry *entry;
- void *entry_arg;
- Coroutine *caller;
- QSLIST_ENTRY(Coroutine) pool_next;
-
- /* Coroutines that should be woken up when we yield or terminate */
- QTAILQ_HEAD(, Coroutine) co_queue_wakeup;
- QTAILQ_ENTRY(Coroutine) co_queue_next;
-};
-
-Coroutine *qemu_coroutine_new(void);
-void qemu_coroutine_delete(Coroutine *co);
-CoroutineAction qemu_coroutine_switch(Coroutine *from, Coroutine *to,
- CoroutineAction action);
-void coroutine_fn qemu_co_queue_run_restart(Coroutine *co);
-
-#endif
diff --git a/contrib/qemu/include/block/snapshot.h b/contrib/qemu/include/block/snapshot.h
deleted file mode 100644
index eaf61f0326e..00000000000
--- a/contrib/qemu/include/block/snapshot.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Block layer snapshot related functions
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef SNAPSHOT_H
-#define SNAPSHOT_H
-
-#include "qemu-common.h"
-
-typedef struct QEMUSnapshotInfo {
- char id_str[128]; /* unique snapshot id */
- /* the following fields are informative. They are not needed for
- the consistency of the snapshot */
- char name[256]; /* user chosen name */
- uint64_t vm_state_size; /* VM state info size */
- uint32_t date_sec; /* UTC date of the snapshot */
- uint32_t date_nsec;
- uint64_t vm_clock_nsec; /* VM clock relative to boot */
-} QEMUSnapshotInfo;
-
-int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
- const char *name);
-int bdrv_can_snapshot(BlockDriverState *bs);
-int bdrv_snapshot_create(BlockDriverState *bs,
- QEMUSnapshotInfo *sn_info);
-int bdrv_snapshot_goto(BlockDriverState *bs,
- const char *snapshot_id);
-int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
-int bdrv_snapshot_list(BlockDriverState *bs,
- QEMUSnapshotInfo **psn_info);
-int bdrv_snapshot_load_tmp(BlockDriverState *bs,
- const char *snapshot_name);
-#endif
diff --git a/contrib/qemu/include/config.h b/contrib/qemu/include/config.h
deleted file mode 100644
index e20f78696a1..00000000000
--- a/contrib/qemu/include/config.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "config-host.h"
-#include "config-target.h"
diff --git a/contrib/qemu/include/exec/cpu-common.h b/contrib/qemu/include/exec/cpu-common.h
deleted file mode 100644
index e4996e19c32..00000000000
--- a/contrib/qemu/include/exec/cpu-common.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef CPU_COMMON_H
-#define CPU_COMMON_H 1
-
-/* CPU interfaces that are target independent. */
-
-#ifndef CONFIG_USER_ONLY
-#include "exec/hwaddr.h"
-#endif
-
-#ifndef NEED_CPU_H
-#include "exec/poison.h"
-#endif
-
-#include "qemu/bswap.h"
-#include "qemu/queue.h"
-
-/**
- * CPUListState:
- * @cpu_fprintf: Print function.
- * @file: File to print to using @cpu_fprint.
- *
- * State commonly used for iterating over CPU models.
- */
-typedef struct CPUListState {
- fprintf_function cpu_fprintf;
- FILE *file;
-} CPUListState;
-
-#if !defined(CONFIG_USER_ONLY)
-
-enum device_endian {
- DEVICE_NATIVE_ENDIAN,
- DEVICE_BIG_ENDIAN,
- DEVICE_LITTLE_ENDIAN,
-};
-
-/* address in the RAM (different from a physical address) */
-#if defined(CONFIG_XEN_BACKEND)
-typedef uint64_t ram_addr_t;
-# define RAM_ADDR_MAX UINT64_MAX
-# define RAM_ADDR_FMT "%" PRIx64
-#else
-typedef uintptr_t ram_addr_t;
-# define RAM_ADDR_MAX UINTPTR_MAX
-# define RAM_ADDR_FMT "%" PRIxPTR
-#endif
-
-/* memory API */
-
-typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
-typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
-
-void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
-/* This should not be used by devices. */
-MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
-void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev);
-
-void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
- int len, int is_write);
-static inline void cpu_physical_memory_read(hwaddr addr,
- void *buf, int len)
-{
- cpu_physical_memory_rw(addr, buf, len, 0);
-}
-static inline void cpu_physical_memory_write(hwaddr addr,
- const void *buf, int len)
-{
- cpu_physical_memory_rw(addr, (void *)buf, len, 1);
-}
-void *cpu_physical_memory_map(hwaddr addr,
- hwaddr *plen,
- int is_write);
-void cpu_physical_memory_unmap(void *buffer, hwaddr len,
- int is_write, hwaddr access_len);
-void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque));
-
-bool cpu_physical_memory_is_io(hwaddr phys_addr);
-
-/* Coalesced MMIO regions are areas where write operations can be reordered.
- * This usually implies that write operations are side-effect free. This allows
- * batching which can make a major impact on performance when using
- * virtualization.
- */
-void qemu_flush_coalesced_mmio_buffer(void);
-
-uint32_t ldub_phys(hwaddr addr);
-uint32_t lduw_le_phys(hwaddr addr);
-uint32_t lduw_be_phys(hwaddr addr);
-uint32_t ldl_le_phys(hwaddr addr);
-uint32_t ldl_be_phys(hwaddr addr);
-uint64_t ldq_le_phys(hwaddr addr);
-uint64_t ldq_be_phys(hwaddr addr);
-void stb_phys(hwaddr addr, uint32_t val);
-void stw_le_phys(hwaddr addr, uint32_t val);
-void stw_be_phys(hwaddr addr, uint32_t val);
-void stl_le_phys(hwaddr addr, uint32_t val);
-void stl_be_phys(hwaddr addr, uint32_t val);
-void stq_le_phys(hwaddr addr, uint64_t val);
-void stq_be_phys(hwaddr addr, uint64_t val);
-
-#ifdef NEED_CPU_H
-uint32_t lduw_phys(hwaddr addr);
-uint32_t ldl_phys(hwaddr addr);
-uint64_t ldq_phys(hwaddr addr);
-void stl_phys_notdirty(hwaddr addr, uint32_t val);
-void stw_phys(hwaddr addr, uint32_t val);
-void stl_phys(hwaddr addr, uint32_t val);
-void stq_phys(hwaddr addr, uint64_t val);
-#endif
-
-void cpu_physical_memory_write_rom(hwaddr addr,
- const uint8_t *buf, int len);
-
-extern struct MemoryRegion io_mem_rom;
-extern struct MemoryRegion io_mem_notdirty;
-
-typedef void (RAMBlockIterFunc)(void *host_addr,
- ram_addr_t offset, ram_addr_t length, void *opaque);
-
-void qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque);
-
-#endif
-
-#endif /* !CPU_COMMON_H */
diff --git a/contrib/qemu/include/exec/hwaddr.h b/contrib/qemu/include/exec/hwaddr.h
deleted file mode 100644
index c9eb78fba18..00000000000
--- a/contrib/qemu/include/exec/hwaddr.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Define hwaddr if it exists. */
-
-#ifndef HWADDR_H
-#define HWADDR_H
-
-#define HWADDR_BITS 64
-/* hwaddr is the type of a physical address (its size can
- be different from 'target_ulong'). */
-
-typedef uint64_t hwaddr;
-#define HWADDR_MAX UINT64_MAX
-#define TARGET_FMT_plx "%016" PRIx64
-#define HWADDR_PRId PRId64
-#define HWADDR_PRIi PRIi64
-#define HWADDR_PRIo PRIo64
-#define HWADDR_PRIu PRIu64
-#define HWADDR_PRIx PRIx64
-#define HWADDR_PRIX PRIX64
-
-#endif
diff --git a/contrib/qemu/include/exec/poison.h b/contrib/qemu/include/exec/poison.h
deleted file mode 100644
index 2341a750413..00000000000
--- a/contrib/qemu/include/exec/poison.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Poison identifiers that should not be used when building
- target independent device code. */
-
-#ifndef HW_POISON_H
-#define HW_POISON_H
-#ifdef __GNUC__
-
-#pragma GCC poison TARGET_I386
-#pragma GCC poison TARGET_X86_64
-#pragma GCC poison TARGET_ALPHA
-#pragma GCC poison TARGET_ARM
-#pragma GCC poison TARGET_CRIS
-#pragma GCC poison TARGET_LM32
-#pragma GCC poison TARGET_M68K
-#pragma GCC poison TARGET_MIPS
-#pragma GCC poison TARGET_MIPS64
-#pragma GCC poison TARGET_OPENRISC
-#pragma GCC poison TARGET_PPC
-#pragma GCC poison TARGET_PPCEMB
-#pragma GCC poison TARGET_PPC64
-#pragma GCC poison TARGET_ABI32
-#pragma GCC poison TARGET_SH4
-#pragma GCC poison TARGET_SPARC
-#pragma GCC poison TARGET_SPARC64
-
-#pragma GCC poison TARGET_WORDS_BIGENDIAN
-#pragma GCC poison BSWAP_NEEDED
-
-#pragma GCC poison TARGET_LONG_BITS
-#pragma GCC poison TARGET_FMT_lx
-#pragma GCC poison TARGET_FMT_ld
-
-#pragma GCC poison TARGET_PAGE_SIZE
-#pragma GCC poison TARGET_PAGE_MASK
-#pragma GCC poison TARGET_PAGE_BITS
-#pragma GCC poison TARGET_PAGE_ALIGN
-
-#pragma GCC poison CPUArchState
-#pragma GCC poison env
-
-#pragma GCC poison lduw_phys
-#pragma GCC poison ldl_phys
-#pragma GCC poison ldq_phys
-#pragma GCC poison stl_phys_notdirty
-#pragma GCC poison stw_phys
-#pragma GCC poison stl_phys
-#pragma GCC poison stq_phys
-
-#pragma GCC poison CPU_INTERRUPT_HARD
-#pragma GCC poison CPU_INTERRUPT_EXITTB
-#pragma GCC poison CPU_INTERRUPT_HALT
-#pragma GCC poison CPU_INTERRUPT_DEBUG
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_0
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_1
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_2
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_3
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_4
-#pragma GCC poison CPU_INTERRUPT_TGT_INT_0
-#pragma GCC poison CPU_INTERRUPT_TGT_INT_1
-#pragma GCC poison CPU_INTERRUPT_TGT_INT_2
-
-#endif
-#endif
diff --git a/contrib/qemu/include/fpu/softfloat.h b/contrib/qemu/include/fpu/softfloat.h
deleted file mode 100644
index f3927e2419f..00000000000
--- a/contrib/qemu/include/fpu/softfloat.h
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * QEMU float support
- *
- * Derived from SoftFloat.
- */
-
-/*============================================================================
-
-This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-#ifndef SOFTFLOAT_H
-#define SOFTFLOAT_H
-
-#if defined(CONFIG_SOLARIS) && defined(CONFIG_NEEDS_LIBSUNMATH)
-#include <sunmath.h>
-#endif
-
-#include <inttypes.h>
-#include "config-host.h"
-#include "qemu/osdep.h"
-
-/*----------------------------------------------------------------------------
-| Each of the following `typedef's defines the most convenient type that holds
-| integers of at least as many bits as specified. For example, `uint8' should
-| be the most convenient type that can hold unsigned integers of as many as
-| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most
-| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
-| to the same as `int'.
-*----------------------------------------------------------------------------*/
-typedef uint8_t flag;
-typedef uint8_t uint8;
-typedef int8_t int8;
-typedef unsigned int uint32;
-typedef signed int int32;
-typedef uint64_t uint64;
-typedef int64_t int64;
-
-#define LIT64( a ) a##LL
-#define INLINE static inline
-
-#define STATUS_PARAM , float_status *status
-#define STATUS(field) status->field
-#define STATUS_VAR , status
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point ordering relations
-*----------------------------------------------------------------------------*/
-enum {
- float_relation_less = -1,
- float_relation_equal = 0,
- float_relation_greater = 1,
- float_relation_unordered = 2
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point types.
-*----------------------------------------------------------------------------*/
-/* Use structures for soft-float types. This prevents accidentally mixing
- them with native int/float types. A sufficiently clever compiler and
- sane ABI should be able to see though these structs. However
- x86/gcc 3.x seems to struggle a bit, so leave them disabled by default. */
-//#define USE_SOFTFLOAT_STRUCT_TYPES
-#ifdef USE_SOFTFLOAT_STRUCT_TYPES
-typedef struct {
- uint16_t v;
-} float16;
-#define float16_val(x) (((float16)(x)).v)
-#define make_float16(x) __extension__ ({ float16 f16_val = {x}; f16_val; })
-#define const_float16(x) { x }
-typedef struct {
- uint32_t v;
-} float32;
-/* The cast ensures an error if the wrong type is passed. */
-#define float32_val(x) (((float32)(x)).v)
-#define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; })
-#define const_float32(x) { x }
-typedef struct {
- uint64_t v;
-} float64;
-#define float64_val(x) (((float64)(x)).v)
-#define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; })
-#define const_float64(x) { x }
-#else
-typedef uint16_t float16;
-typedef uint32_t float32;
-typedef uint64_t float64;
-#define float16_val(x) (x)
-#define float32_val(x) (x)
-#define float64_val(x) (x)
-#define make_float16(x) (x)
-#define make_float32(x) (x)
-#define make_float64(x) (x)
-#define const_float16(x) (x)
-#define const_float32(x) (x)
-#define const_float64(x) (x)
-#endif
-typedef struct {
- uint64_t low;
- uint16_t high;
-} floatx80;
-#define make_floatx80(exp, mant) ((floatx80) { mant, exp })
-#define make_floatx80_init(exp, mant) { .low = mant, .high = exp }
-typedef struct {
-#ifdef HOST_WORDS_BIGENDIAN
- uint64_t high, low;
-#else
- uint64_t low, high;
-#endif
-} float128;
-#define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ })
-#define make_float128_init(high_, low_) { .high = high_, .low = low_ }
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point underflow tininess-detection mode.
-*----------------------------------------------------------------------------*/
-enum {
- float_tininess_after_rounding = 0,
- float_tininess_before_rounding = 1
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point rounding mode.
-*----------------------------------------------------------------------------*/
-enum {
- float_round_nearest_even = 0,
- float_round_down = 1,
- float_round_up = 2,
- float_round_to_zero = 3
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point exception flags.
-*----------------------------------------------------------------------------*/
-enum {
- float_flag_invalid = 1,
- float_flag_divbyzero = 4,
- float_flag_overflow = 8,
- float_flag_underflow = 16,
- float_flag_inexact = 32,
- float_flag_input_denormal = 64,
- float_flag_output_denormal = 128
-};
-
-typedef struct float_status {
- signed char float_detect_tininess;
- signed char float_rounding_mode;
- signed char float_exception_flags;
- signed char floatx80_rounding_precision;
- /* should denormalised results go to zero and set the inexact flag? */
- flag flush_to_zero;
- /* should denormalised inputs go to zero and set the input_denormal flag? */
- flag flush_inputs_to_zero;
- flag default_nan_mode;
-} float_status;
-
-void set_float_rounding_mode(int val STATUS_PARAM);
-void set_float_exception_flags(int val STATUS_PARAM);
-INLINE void set_float_detect_tininess(int val STATUS_PARAM)
-{
- STATUS(float_detect_tininess) = val;
-}
-INLINE void set_flush_to_zero(flag val STATUS_PARAM)
-{
- STATUS(flush_to_zero) = val;
-}
-INLINE void set_flush_inputs_to_zero(flag val STATUS_PARAM)
-{
- STATUS(flush_inputs_to_zero) = val;
-}
-INLINE void set_default_nan_mode(flag val STATUS_PARAM)
-{
- STATUS(default_nan_mode) = val;
-}
-INLINE int get_float_exception_flags(float_status *status)
-{
- return STATUS(float_exception_flags);
-}
-void set_floatx80_rounding_precision(int val STATUS_PARAM);
-
-/*----------------------------------------------------------------------------
-| Routine to raise any or all of the software IEC/IEEE floating-point
-| exception flags.
-*----------------------------------------------------------------------------*/
-void float_raise( int8 flags STATUS_PARAM);
-
-/*----------------------------------------------------------------------------
-| Options to indicate which negations to perform in float*_muladd()
-| Using these differs from negating an input or output before calling
-| the muladd function in that this means that a NaN doesn't have its
-| sign bit inverted before it is propagated.
-*----------------------------------------------------------------------------*/
-enum {
- float_muladd_negate_c = 1,
- float_muladd_negate_product = 2,
- float_muladd_negate_result = 4,
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32( int32 STATUS_PARAM );
-float64 int32_to_float64( int32 STATUS_PARAM );
-float32 uint32_to_float32( uint32 STATUS_PARAM );
-float64 uint32_to_float64( uint32 STATUS_PARAM );
-floatx80 int32_to_floatx80( int32 STATUS_PARAM );
-float128 int32_to_float128( int32 STATUS_PARAM );
-float32 int64_to_float32( int64 STATUS_PARAM );
-float32 uint64_to_float32( uint64 STATUS_PARAM );
-float64 int64_to_float64( int64 STATUS_PARAM );
-float64 uint64_to_float64( uint64 STATUS_PARAM );
-floatx80 int64_to_floatx80( int64 STATUS_PARAM );
-float128 int64_to_float128( int64 STATUS_PARAM );
-float128 uint64_to_float128( uint64 STATUS_PARAM );
-
-/*----------------------------------------------------------------------------
-| Software half-precision conversion routines.
-*----------------------------------------------------------------------------*/
-float16 float32_to_float16( float32, flag STATUS_PARAM );
-float32 float16_to_float32( float16, flag STATUS_PARAM );
-
-/*----------------------------------------------------------------------------
-| Software half-precision operations.
-*----------------------------------------------------------------------------*/
-int float16_is_quiet_nan( float16 );
-int float16_is_signaling_nan( float16 );
-float16 float16_maybe_silence_nan( float16 );
-
-INLINE int float16_is_any_nan(float16 a)
-{
- return ((float16_val(a) & ~0x8000) > 0x7c00);
-}
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated half-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float16 float16_default_nan;
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int_fast16_t float32_to_int16_round_to_zero(float32 STATUS_PARAM);
-uint_fast16_t float32_to_uint16_round_to_zero(float32 STATUS_PARAM);
-int32 float32_to_int32( float32 STATUS_PARAM );
-int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM );
-uint32 float32_to_uint32( float32 STATUS_PARAM );
-uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
-int64 float32_to_int64( float32 STATUS_PARAM );
-int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM );
-float64 float32_to_float64( float32 STATUS_PARAM );
-floatx80 float32_to_floatx80( float32 STATUS_PARAM );
-float128 float32_to_float128( float32 STATUS_PARAM );
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int( float32 STATUS_PARAM );
-float32 float32_add( float32, float32 STATUS_PARAM );
-float32 float32_sub( float32, float32 STATUS_PARAM );
-float32 float32_mul( float32, float32 STATUS_PARAM );
-float32 float32_div( float32, float32 STATUS_PARAM );
-float32 float32_rem( float32, float32 STATUS_PARAM );
-float32 float32_muladd(float32, float32, float32, int STATUS_PARAM);
-float32 float32_sqrt( float32 STATUS_PARAM );
-float32 float32_exp2( float32 STATUS_PARAM );
-float32 float32_log2( float32 STATUS_PARAM );
-int float32_eq( float32, float32 STATUS_PARAM );
-int float32_le( float32, float32 STATUS_PARAM );
-int float32_lt( float32, float32 STATUS_PARAM );
-int float32_unordered( float32, float32 STATUS_PARAM );
-int float32_eq_quiet( float32, float32 STATUS_PARAM );
-int float32_le_quiet( float32, float32 STATUS_PARAM );
-int float32_lt_quiet( float32, float32 STATUS_PARAM );
-int float32_unordered_quiet( float32, float32 STATUS_PARAM );
-int float32_compare( float32, float32 STATUS_PARAM );
-int float32_compare_quiet( float32, float32 STATUS_PARAM );
-float32 float32_min(float32, float32 STATUS_PARAM);
-float32 float32_max(float32, float32 STATUS_PARAM);
-int float32_is_quiet_nan( float32 );
-int float32_is_signaling_nan( float32 );
-float32 float32_maybe_silence_nan( float32 );
-float32 float32_scalbn( float32, int STATUS_PARAM );
-
-INLINE float32 float32_abs(float32 a)
-{
- /* Note that abs does *not* handle NaN specially, nor does
- * it flush denormal inputs to zero.
- */
- return make_float32(float32_val(a) & 0x7fffffff);
-}
-
-INLINE float32 float32_chs(float32 a)
-{
- /* Note that chs does *not* handle NaN specially, nor does
- * it flush denormal inputs to zero.
- */
- return make_float32(float32_val(a) ^ 0x80000000);
-}
-
-INLINE int float32_is_infinity(float32 a)
-{
- return (float32_val(a) & 0x7fffffff) == 0x7f800000;
-}
-
-INLINE int float32_is_neg(float32 a)
-{
- return float32_val(a) >> 31;
-}
-
-INLINE int float32_is_zero(float32 a)
-{
- return (float32_val(a) & 0x7fffffff) == 0;
-}
-
-INLINE int float32_is_any_nan(float32 a)
-{
- return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL);
-}
-
-INLINE int float32_is_zero_or_denormal(float32 a)
-{
- return (float32_val(a) & 0x7f800000) == 0;
-}
-
-INLINE float32 float32_set_sign(float32 a, int sign)
-{
- return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
-}
-
-#define float32_zero make_float32(0)
-#define float32_one make_float32(0x3f800000)
-#define float32_ln2 make_float32(0x3f317218)
-#define float32_pi make_float32(0x40490fdb)
-#define float32_half make_float32(0x3f000000)
-#define float32_infinity make_float32(0x7f800000)
-
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated single-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float32 float32_default_nan;
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int_fast16_t float64_to_int16_round_to_zero(float64 STATUS_PARAM);
-uint_fast16_t float64_to_uint16_round_to_zero(float64 STATUS_PARAM);
-int32 float64_to_int32( float64 STATUS_PARAM );
-int32 float64_to_int32_round_to_zero( float64 STATUS_PARAM );
-uint32 float64_to_uint32( float64 STATUS_PARAM );
-uint32 float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
-int64 float64_to_int64( float64 STATUS_PARAM );
-int64 float64_to_int64_round_to_zero( float64 STATUS_PARAM );
-uint64 float64_to_uint64 (float64 a STATUS_PARAM);
-uint64 float64_to_uint64_round_to_zero (float64 a STATUS_PARAM);
-float32 float64_to_float32( float64 STATUS_PARAM );
-floatx80 float64_to_floatx80( float64 STATUS_PARAM );
-float128 float64_to_float128( float64 STATUS_PARAM );
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-float64 float64_round_to_int( float64 STATUS_PARAM );
-float64 float64_trunc_to_int( float64 STATUS_PARAM );
-float64 float64_add( float64, float64 STATUS_PARAM );
-float64 float64_sub( float64, float64 STATUS_PARAM );
-float64 float64_mul( float64, float64 STATUS_PARAM );
-float64 float64_div( float64, float64 STATUS_PARAM );
-float64 float64_rem( float64, float64 STATUS_PARAM );
-float64 float64_muladd(float64, float64, float64, int STATUS_PARAM);
-float64 float64_sqrt( float64 STATUS_PARAM );
-float64 float64_log2( float64 STATUS_PARAM );
-int float64_eq( float64, float64 STATUS_PARAM );
-int float64_le( float64, float64 STATUS_PARAM );
-int float64_lt( float64, float64 STATUS_PARAM );
-int float64_unordered( float64, float64 STATUS_PARAM );
-int float64_eq_quiet( float64, float64 STATUS_PARAM );
-int float64_le_quiet( float64, float64 STATUS_PARAM );
-int float64_lt_quiet( float64, float64 STATUS_PARAM );
-int float64_unordered_quiet( float64, float64 STATUS_PARAM );
-int float64_compare( float64, float64 STATUS_PARAM );
-int float64_compare_quiet( float64, float64 STATUS_PARAM );
-float64 float64_min(float64, float64 STATUS_PARAM);
-float64 float64_max(float64, float64 STATUS_PARAM);
-int float64_is_quiet_nan( float64 a );
-int float64_is_signaling_nan( float64 );
-float64 float64_maybe_silence_nan( float64 );
-float64 float64_scalbn( float64, int STATUS_PARAM );
-
-INLINE float64 float64_abs(float64 a)
-{
- /* Note that abs does *not* handle NaN specially, nor does
- * it flush denormal inputs to zero.
- */
- return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
-}
-
-INLINE float64 float64_chs(float64 a)
-{
- /* Note that chs does *not* handle NaN specially, nor does
- * it flush denormal inputs to zero.
- */
- return make_float64(float64_val(a) ^ 0x8000000000000000LL);
-}
-
-INLINE int float64_is_infinity(float64 a)
-{
- return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL;
-}
-
-INLINE int float64_is_neg(float64 a)
-{
- return float64_val(a) >> 63;
-}
-
-INLINE int float64_is_zero(float64 a)
-{
- return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
-}
-
-INLINE int float64_is_any_nan(float64 a)
-{
- return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);
-}
-
-INLINE int float64_is_zero_or_denormal(float64 a)
-{
- return (float64_val(a) & 0x7ff0000000000000LL) == 0;
-}
-
-INLINE float64 float64_set_sign(float64 a, int sign)
-{
- return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
- | ((int64_t)sign << 63));
-}
-
-#define float64_zero make_float64(0)
-#define float64_one make_float64(0x3ff0000000000000LL)
-#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
-#define float64_pi make_float64(0x400921fb54442d18LL)
-#define float64_half make_float64(0x3fe0000000000000LL)
-#define float64_infinity make_float64(0x7ff0000000000000LL)
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated double-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float64 float64_default_nan;
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int32 floatx80_to_int32( floatx80 STATUS_PARAM );
-int32 floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
-int64 floatx80_to_int64( floatx80 STATUS_PARAM );
-int64 floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM );
-float32 floatx80_to_float32( floatx80 STATUS_PARAM );
-float64 floatx80_to_float64( floatx80 STATUS_PARAM );
-float128 floatx80_to_float128( floatx80 STATUS_PARAM );
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
-floatx80 floatx80_add( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_sub( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
-floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
-int floatx80_eq( floatx80, floatx80 STATUS_PARAM );
-int floatx80_le( floatx80, floatx80 STATUS_PARAM );
-int floatx80_lt( floatx80, floatx80 STATUS_PARAM );
-int floatx80_unordered( floatx80, floatx80 STATUS_PARAM );
-int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
-int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
-int floatx80_is_quiet_nan( floatx80 );
-int floatx80_is_signaling_nan( floatx80 );
-floatx80 floatx80_maybe_silence_nan( floatx80 );
-floatx80 floatx80_scalbn( floatx80, int STATUS_PARAM );
-
-INLINE floatx80 floatx80_abs(floatx80 a)
-{
- a.high &= 0x7fff;
- return a;
-}
-
-INLINE floatx80 floatx80_chs(floatx80 a)
-{
- a.high ^= 0x8000;
- return a;
-}
-
-INLINE int floatx80_is_infinity(floatx80 a)
-{
- return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL;
-}
-
-INLINE int floatx80_is_neg(floatx80 a)
-{
- return a.high >> 15;
-}
-
-INLINE int floatx80_is_zero(floatx80 a)
-{
- return (a.high & 0x7fff) == 0 && a.low == 0;
-}
-
-INLINE int floatx80_is_zero_or_denormal(floatx80 a)
-{
- return (a.high & 0x7fff) == 0;
-}
-
-INLINE int floatx80_is_any_nan(floatx80 a)
-{
- return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
-}
-
-#define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
-#define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
-#define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
-#define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
-#define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
-#define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const floatx80 floatx80_default_nan;
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int32 float128_to_int32( float128 STATUS_PARAM );
-int32 float128_to_int32_round_to_zero( float128 STATUS_PARAM );
-int64 float128_to_int64( float128 STATUS_PARAM );
-int64 float128_to_int64_round_to_zero( float128 STATUS_PARAM );
-float32 float128_to_float32( float128 STATUS_PARAM );
-float64 float128_to_float64( float128 STATUS_PARAM );
-floatx80 float128_to_floatx80( float128 STATUS_PARAM );
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision operations.
-*----------------------------------------------------------------------------*/
-float128 float128_round_to_int( float128 STATUS_PARAM );
-float128 float128_add( float128, float128 STATUS_PARAM );
-float128 float128_sub( float128, float128 STATUS_PARAM );
-float128 float128_mul( float128, float128 STATUS_PARAM );
-float128 float128_div( float128, float128 STATUS_PARAM );
-float128 float128_rem( float128, float128 STATUS_PARAM );
-float128 float128_sqrt( float128 STATUS_PARAM );
-int float128_eq( float128, float128 STATUS_PARAM );
-int float128_le( float128, float128 STATUS_PARAM );
-int float128_lt( float128, float128 STATUS_PARAM );
-int float128_unordered( float128, float128 STATUS_PARAM );
-int float128_eq_quiet( float128, float128 STATUS_PARAM );
-int float128_le_quiet( float128, float128 STATUS_PARAM );
-int float128_lt_quiet( float128, float128 STATUS_PARAM );
-int float128_unordered_quiet( float128, float128 STATUS_PARAM );
-int float128_compare( float128, float128 STATUS_PARAM );
-int float128_compare_quiet( float128, float128 STATUS_PARAM );
-int float128_is_quiet_nan( float128 );
-int float128_is_signaling_nan( float128 );
-float128 float128_maybe_silence_nan( float128 );
-float128 float128_scalbn( float128, int STATUS_PARAM );
-
-INLINE float128 float128_abs(float128 a)
-{
- a.high &= 0x7fffffffffffffffLL;
- return a;
-}
-
-INLINE float128 float128_chs(float128 a)
-{
- a.high ^= 0x8000000000000000LL;
- return a;
-}
-
-INLINE int float128_is_infinity(float128 a)
-{
- return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0;
-}
-
-INLINE int float128_is_neg(float128 a)
-{
- return a.high >> 63;
-}
-
-INLINE int float128_is_zero(float128 a)
-{
- return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
-}
-
-INLINE int float128_is_zero_or_denormal(float128 a)
-{
- return (a.high & 0x7fff000000000000LL) == 0;
-}
-
-INLINE int float128_is_any_nan(float128 a)
-{
- return ((a.high >> 48) & 0x7fff) == 0x7fff &&
- ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
-}
-
-#define float128_zero make_float128(0, 0)
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float128 float128_default_nan;
-
-#endif /* !SOFTFLOAT_H */
diff --git a/contrib/qemu/include/glib-compat.h b/contrib/qemu/include/glib-compat.h
deleted file mode 100644
index 8aa77afd626..00000000000
--- a/contrib/qemu/include/glib-compat.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * GLIB Compatibility Functions
- *
- * Copyright IBM, Corp. 2013
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_GLIB_COMPAT_H
-#define QEMU_GLIB_COMPAT_H
-
-#include <glib.h>
-
-#if !GLIB_CHECK_VERSION(2, 14, 0)
-static inline guint g_timeout_add_seconds(guint interval, GSourceFunc function,
- gpointer data)
-{
- return g_timeout_add(interval * 1000, function, data);
-}
-#endif
-
-#endif
diff --git a/contrib/qemu/include/migration/migration.h b/contrib/qemu/include/migration/migration.h
deleted file mode 100644
index bc9fde0b2ab..00000000000
--- a/contrib/qemu/include/migration/migration.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * QEMU live migration
- *
- * Copyright IBM, Corp. 2008
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_MIGRATION_H
-#define QEMU_MIGRATION_H
-
-#include "qapi/qmp/qdict.h"
-#include "qemu-common.h"
-#include "qemu/thread.h"
-#include "qemu/notify.h"
-#include "qapi/error.h"
-#include "migration/vmstate.h"
-#include "qapi-types.h"
-#include "exec/cpu-common.h"
-
-struct MigrationParams {
- bool blk;
- bool shared;
-};
-
-typedef struct MigrationState MigrationState;
-
-struct MigrationState
-{
- int64_t bandwidth_limit;
- size_t bytes_xfer;
- size_t xfer_limit;
- QemuThread thread;
- QEMUBH *cleanup_bh;
- QEMUFile *file;
-
- int state;
- MigrationParams params;
- double mbps;
- int64_t total_time;
- int64_t downtime;
- int64_t expected_downtime;
- int64_t dirty_pages_rate;
- int64_t dirty_bytes_rate;
- bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
- int64_t xbzrle_cache_size;
-};
-
-void process_incoming_migration(QEMUFile *f);
-
-void qemu_start_incoming_migration(const char *uri, Error **errp);
-
-uint64_t migrate_max_downtime(void);
-
-void do_info_migrate_print(Monitor *mon, const QObject *data);
-
-void do_info_migrate(Monitor *mon, QObject **ret_data);
-
-void exec_start_incoming_migration(const char *host_port, Error **errp);
-
-void exec_start_outgoing_migration(MigrationState *s, const char *host_port, Error **errp);
-
-void tcp_start_incoming_migration(const char *host_port, Error **errp);
-
-void tcp_start_outgoing_migration(MigrationState *s, const char *host_port, Error **errp);
-
-void unix_start_incoming_migration(const char *path, Error **errp);
-
-void unix_start_outgoing_migration(MigrationState *s, const char *path, Error **errp);
-
-void fd_start_incoming_migration(const char *path, Error **errp);
-
-void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp);
-
-void migrate_fd_error(MigrationState *s);
-
-void migrate_fd_connect(MigrationState *s);
-
-int migrate_fd_close(MigrationState *s);
-
-void add_migration_state_change_notifier(Notifier *notify);
-void remove_migration_state_change_notifier(Notifier *notify);
-bool migration_is_active(MigrationState *);
-bool migration_has_finished(MigrationState *);
-bool migration_has_failed(MigrationState *);
-MigrationState *migrate_get_current(void);
-
-uint64_t ram_bytes_remaining(void);
-uint64_t ram_bytes_transferred(void);
-uint64_t ram_bytes_total(void);
-
-void acct_update_position(QEMUFile *f, size_t size, bool zero);
-
-extern SaveVMHandlers savevm_ram_handlers;
-
-uint64_t dup_mig_bytes_transferred(void);
-uint64_t dup_mig_pages_transferred(void);
-uint64_t skipped_mig_bytes_transferred(void);
-uint64_t skipped_mig_pages_transferred(void);
-uint64_t norm_mig_bytes_transferred(void);
-uint64_t norm_mig_pages_transferred(void);
-uint64_t xbzrle_mig_bytes_transferred(void);
-uint64_t xbzrle_mig_pages_transferred(void);
-uint64_t xbzrle_mig_pages_overflow(void);
-uint64_t xbzrle_mig_pages_cache_miss(void);
-
-/**
- * @migrate_add_blocker - prevent migration from proceeding
- *
- * @reason - an error to be returned whenever migration is attempted
- */
-void migrate_add_blocker(Error *reason);
-
-/**
- * @migrate_del_blocker - remove a blocking error from migration
- *
- * @reason - the error blocking migration
- */
-void migrate_del_blocker(Error *reason);
-
-bool migrate_rdma_pin_all(void);
-
-bool migrate_auto_converge(void);
-
-int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,
- uint8_t *dst, int dlen);
-int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen);
-
-int migrate_use_xbzrle(void);
-int64_t migrate_xbzrle_cache_size(void);
-
-int64_t xbzrle_cache_resize(int64_t new_size);
-
-void ram_control_before_iterate(QEMUFile *f, uint64_t flags);
-void ram_control_after_iterate(QEMUFile *f, uint64_t flags);
-void ram_control_load_hook(QEMUFile *f, uint64_t flags);
-
-/* Whenever this is found in the data stream, the flags
- * will be passed to ram_control_load_hook in the incoming-migration
- * side. This lets before_ram_iterate/after_ram_iterate add
- * transport-specific sections to the RAM migration data.
- */
-#define RAM_SAVE_FLAG_HOOK 0x80
-
-#define RAM_SAVE_CONTROL_NOT_SUPP -1000
-#define RAM_SAVE_CONTROL_DELAYED -2000
-
-size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
- ram_addr_t offset, size_t size,
- int *bytes_sent);
-
-#endif
diff --git a/contrib/qemu/include/migration/qemu-file.h b/contrib/qemu/include/migration/qemu-file.h
deleted file mode 100644
index 0f757fbeb63..00000000000
--- a/contrib/qemu/include/migration/qemu-file.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_FILE_H
-#define QEMU_FILE_H 1
-#include "exec/cpu-common.h"
-
-/* This function writes a chunk of data to a file at the given position.
- * The pos argument can be ignored if the file is only being used for
- * streaming. The handler should try to write all of the data it can.
- */
-typedef int (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf,
- int64_t pos, int size);
-
-/* Read a chunk of data from a file at the given position. The pos argument
- * can be ignored if the file is only be used for streaming. The number of
- * bytes actually read should be returned.
- */
-typedef int (QEMUFileGetBufferFunc)(void *opaque, uint8_t *buf,
- int64_t pos, int size);
-
-/* Close a file
- *
- * Return negative error number on error, 0 or positive value on success.
- *
- * The meaning of return value on success depends on the specific back-end being
- * used.
- */
-typedef int (QEMUFileCloseFunc)(void *opaque);
-
-/* Called to return the OS file descriptor associated to the QEMUFile.
- */
-typedef int (QEMUFileGetFD)(void *opaque);
-
-/*
- * This function writes an iovec to file.
- */
-typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
- int iovcnt, int64_t pos);
-
-/*
- * This function provides hooks around different
- * stages of RAM migration.
- */
-typedef int (QEMURamHookFunc)(QEMUFile *f, void *opaque, uint64_t flags);
-
-/*
- * Constants used by ram_control_* hooks
- */
-#define RAM_CONTROL_SETUP 0
-#define RAM_CONTROL_ROUND 1
-#define RAM_CONTROL_HOOK 2
-#define RAM_CONTROL_FINISH 3
-
-/*
- * This function allows override of where the RAM page
- * is saved (such as RDMA, for example.)
- */
-typedef size_t (QEMURamSaveFunc)(QEMUFile *f, void *opaque,
- ram_addr_t block_offset,
- ram_addr_t offset,
- size_t size,
- int *bytes_sent);
-
-typedef struct QEMUFileOps {
- QEMUFilePutBufferFunc *put_buffer;
- QEMUFileGetBufferFunc *get_buffer;
- QEMUFileCloseFunc *close;
- QEMUFileGetFD *get_fd;
- QEMUFileWritevBufferFunc *writev_buffer;
- QEMURamHookFunc *before_ram_iterate;
- QEMURamHookFunc *after_ram_iterate;
- QEMURamHookFunc *hook_ram_load;
- QEMURamSaveFunc *save_page;
-} QEMUFileOps;
-
-QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops);
-QEMUFile *qemu_fopen(const char *filename, const char *mode);
-QEMUFile *qemu_fdopen(int fd, const char *mode);
-QEMUFile *qemu_fopen_socket(int fd, const char *mode);
-QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
-int qemu_get_fd(QEMUFile *f);
-int qemu_fclose(QEMUFile *f);
-int64_t qemu_ftell(QEMUFile *f);
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
-void qemu_put_byte(QEMUFile *f, int v);
-/*
- * put_buffer without copying the buffer.
- * The buffer should be available till it is sent asynchronously.
- */
-void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size);
-bool qemu_file_mode_is_not_valid(const char *mode);
-
-static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v)
-{
- qemu_put_byte(f, (int)v);
-}
-
-#define qemu_put_sbyte qemu_put_byte
-
-void qemu_put_be16(QEMUFile *f, unsigned int v);
-void qemu_put_be32(QEMUFile *f, unsigned int v);
-void qemu_put_be64(QEMUFile *f, uint64_t v);
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
-int qemu_get_byte(QEMUFile *f);
-void qemu_update_position(QEMUFile *f, size_t size);
-
-static inline unsigned int qemu_get_ubyte(QEMUFile *f)
-{
- return (unsigned int)qemu_get_byte(f);
-}
-
-#define qemu_get_sbyte qemu_get_byte
-
-unsigned int qemu_get_be16(QEMUFile *f);
-unsigned int qemu_get_be32(QEMUFile *f);
-uint64_t qemu_get_be64(QEMUFile *f);
-
-int qemu_file_rate_limit(QEMUFile *f);
-void qemu_file_reset_rate_limit(QEMUFile *f);
-void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate);
-int64_t qemu_file_get_rate_limit(QEMUFile *f);
-int qemu_file_get_error(QEMUFile *f);
-void qemu_fflush(QEMUFile *f);
-
-static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
-{
- qemu_put_be64(f, *pv);
-}
-
-static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
-{
- qemu_put_be32(f, *pv);
-}
-
-static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
-{
- qemu_put_be16(f, *pv);
-}
-
-static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
-{
- qemu_put_byte(f, *pv);
-}
-
-static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
-{
- *pv = qemu_get_be64(f);
-}
-
-static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
-{
- *pv = qemu_get_be32(f);
-}
-
-static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
-{
- *pv = qemu_get_be16(f);
-}
-
-static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
-{
- *pv = qemu_get_byte(f);
-}
-
-// Signed versions for type safety
-static inline void qemu_put_sbuffer(QEMUFile *f, const int8_t *buf, int size)
-{
- qemu_put_buffer(f, (const uint8_t *)buf, size);
-}
-
-static inline void qemu_put_sbe16(QEMUFile *f, int v)
-{
- qemu_put_be16(f, (unsigned int)v);
-}
-
-static inline void qemu_put_sbe32(QEMUFile *f, int v)
-{
- qemu_put_be32(f, (unsigned int)v);
-}
-
-static inline void qemu_put_sbe64(QEMUFile *f, int64_t v)
-{
- qemu_put_be64(f, (uint64_t)v);
-}
-
-static inline size_t qemu_get_sbuffer(QEMUFile *f, int8_t *buf, int size)
-{
- return qemu_get_buffer(f, (uint8_t *)buf, size);
-}
-
-static inline int qemu_get_sbe16(QEMUFile *f)
-{
- return (int)qemu_get_be16(f);
-}
-
-static inline int qemu_get_sbe32(QEMUFile *f)
-{
- return (int)qemu_get_be32(f);
-}
-
-static inline int64_t qemu_get_sbe64(QEMUFile *f)
-{
- return (int64_t)qemu_get_be64(f);
-}
-
-static inline void qemu_put_s8s(QEMUFile *f, const int8_t *pv)
-{
- qemu_put_8s(f, (const uint8_t *)pv);
-}
-
-static inline void qemu_put_sbe16s(QEMUFile *f, const int16_t *pv)
-{
- qemu_put_be16s(f, (const uint16_t *)pv);
-}
-
-static inline void qemu_put_sbe32s(QEMUFile *f, const int32_t *pv)
-{
- qemu_put_be32s(f, (const uint32_t *)pv);
-}
-
-static inline void qemu_put_sbe64s(QEMUFile *f, const int64_t *pv)
-{
- qemu_put_be64s(f, (const uint64_t *)pv);
-}
-
-static inline void qemu_get_s8s(QEMUFile *f, int8_t *pv)
-{
- qemu_get_8s(f, (uint8_t *)pv);
-}
-
-static inline void qemu_get_sbe16s(QEMUFile *f, int16_t *pv)
-{
- qemu_get_be16s(f, (uint16_t *)pv);
-}
-
-static inline void qemu_get_sbe32s(QEMUFile *f, int32_t *pv)
-{
- qemu_get_be32s(f, (uint32_t *)pv);
-}
-
-static inline void qemu_get_sbe64s(QEMUFile *f, int64_t *pv)
-{
- qemu_get_be64s(f, (uint64_t *)pv);
-}
-#endif
diff --git a/contrib/qemu/include/migration/vmstate.h b/contrib/qemu/include/migration/vmstate.h
deleted file mode 100644
index 1c31b5d6fb5..00000000000
--- a/contrib/qemu/include/migration/vmstate.h
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * QEMU migration/snapshot declarations
- *
- * Copyright (c) 2009-2011 Red Hat, Inc.
- *
- * Original author: Juan Quintela <quintela@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_VMSTATE_H
-#define QEMU_VMSTATE_H 1
-
-#ifndef CONFIG_USER_ONLY
-#include <migration/qemu-file.h>
-#endif
-
-typedef void SaveStateHandler(QEMUFile *f, void *opaque);
-typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
-
-typedef struct SaveVMHandlers {
- /* This runs inside the iothread lock. */
- void (*set_params)(const MigrationParams *params, void * opaque);
- SaveStateHandler *save_state;
-
- void (*cancel)(void *opaque);
- int (*save_live_complete)(QEMUFile *f, void *opaque);
-
- /* This runs both outside and inside the iothread lock. */
- bool (*is_active)(void *opaque);
-
- /* This runs outside the iothread lock in the migration case, and
- * within the lock in the savevm case. The callback had better only
- * use data that is local to the migration thread or protected
- * by other locks.
- */
- int (*save_live_iterate)(QEMUFile *f, void *opaque);
-
- /* This runs outside the iothread lock! */
- int (*save_live_setup)(QEMUFile *f, void *opaque);
- uint64_t (*save_live_pending)(QEMUFile *f, void *opaque, uint64_t max_size);
-
- LoadStateHandler *load_state;
-} SaveVMHandlers;
-
-int register_savevm(DeviceState *dev,
- const char *idstr,
- int instance_id,
- int version_id,
- SaveStateHandler *save_state,
- LoadStateHandler *load_state,
- void *opaque);
-
-int register_savevm_live(DeviceState *dev,
- const char *idstr,
- int instance_id,
- int version_id,
- SaveVMHandlers *ops,
- void *opaque);
-
-void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque);
-void register_device_unmigratable(DeviceState *dev, const char *idstr,
- void *opaque);
-
-
-typedef struct VMStateInfo VMStateInfo;
-typedef struct VMStateDescription VMStateDescription;
-
-struct VMStateInfo {
- const char *name;
- int (*get)(QEMUFile *f, void *pv, size_t size);
- void (*put)(QEMUFile *f, void *pv, size_t size);
-};
-
-enum VMStateFlags {
- VMS_SINGLE = 0x001,
- VMS_POINTER = 0x002,
- VMS_ARRAY = 0x004,
- VMS_STRUCT = 0x008,
- VMS_VARRAY_INT32 = 0x010, /* Array with size in int32_t field*/
- VMS_BUFFER = 0x020, /* static sized buffer */
- VMS_ARRAY_OF_POINTER = 0x040,
- VMS_VARRAY_UINT16 = 0x080, /* Array with size in uint16_t field */
- VMS_VBUFFER = 0x100, /* Buffer with size in int32_t field */
- VMS_MULTIPLY = 0x200, /* multiply "size" field by field_size */
- VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/
- VMS_VARRAY_UINT32 = 0x800, /* Array with size in uint32_t field*/
-};
-
-typedef struct {
- const char *name;
- size_t offset;
- size_t size;
- size_t start;
- int num;
- size_t num_offset;
- size_t size_offset;
- const VMStateInfo *info;
- enum VMStateFlags flags;
- const VMStateDescription *vmsd;
- int version_id;
- bool (*field_exists)(void *opaque, int version_id);
-} VMStateField;
-
-typedef struct VMStateSubsection {
- const VMStateDescription *vmsd;
- bool (*needed)(void *opaque);
-} VMStateSubsection;
-
-struct VMStateDescription {
- const char *name;
- int unmigratable;
- int version_id;
- int minimum_version_id;
- int minimum_version_id_old;
- LoadStateHandler *load_state_old;
- int (*pre_load)(void *opaque);
- int (*post_load)(void *opaque, int version_id);
- void (*pre_save)(void *opaque);
- VMStateField *fields;
- const VMStateSubsection *subsections;
-};
-
-#ifdef CONFIG_USER_ONLY
-extern const VMStateDescription vmstate_dummy;
-#endif
-
-extern const VMStateInfo vmstate_info_bool;
-
-extern const VMStateInfo vmstate_info_int8;
-extern const VMStateInfo vmstate_info_int16;
-extern const VMStateInfo vmstate_info_int32;
-extern const VMStateInfo vmstate_info_int64;
-
-extern const VMStateInfo vmstate_info_uint8_equal;
-extern const VMStateInfo vmstate_info_uint16_equal;
-extern const VMStateInfo vmstate_info_int32_equal;
-extern const VMStateInfo vmstate_info_uint32_equal;
-extern const VMStateInfo vmstate_info_uint64_equal;
-extern const VMStateInfo vmstate_info_int32_le;
-
-extern const VMStateInfo vmstate_info_uint8;
-extern const VMStateInfo vmstate_info_uint16;
-extern const VMStateInfo vmstate_info_uint32;
-extern const VMStateInfo vmstate_info_uint64;
-
-extern const VMStateInfo vmstate_info_float64;
-
-extern const VMStateInfo vmstate_info_timer;
-extern const VMStateInfo vmstate_info_buffer;
-extern const VMStateInfo vmstate_info_unused_buffer;
-extern const VMStateInfo vmstate_info_bitmap;
-
-#define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0)
-#define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0)
-#define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0)
-
-#define vmstate_offset_value(_state, _field, _type) \
- (offsetof(_state, _field) + \
- type_check(_type, typeof_field(_state, _field)))
-
-#define vmstate_offset_pointer(_state, _field, _type) \
- (offsetof(_state, _field) + \
- type_check_pointer(_type, typeof_field(_state, _field)))
-
-#define vmstate_offset_array(_state, _field, _type, _num) \
- (offsetof(_state, _field) + \
- type_check_array(_type, typeof_field(_state, _field), _num))
-
-#define vmstate_offset_2darray(_state, _field, _type, _n1, _n2) \
- (offsetof(_state, _field) + \
- type_check_2darray(_type, typeof_field(_state, _field), _n1, _n2))
-
-#define vmstate_offset_sub_array(_state, _field, _type, _start) \
- (offsetof(_state, _field[_start]))
-
-#define vmstate_offset_buffer(_state, _field) \
- vmstate_offset_array(_state, _field, uint8_t, \
- sizeof(typeof_field(_state, _field)))
-
-#define VMSTATE_SINGLE_TEST(_field, _state, _test, _version, _info, _type) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .field_exists = (_test), \
- .size = sizeof(_type), \
- .info = &(_info), \
- .flags = VMS_SINGLE, \
- .offset = vmstate_offset_value(_state, _field, _type), \
-}
-
-#define VMSTATE_POINTER(_field, _state, _version, _info, _type) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_SINGLE|VMS_POINTER, \
- .offset = vmstate_offset_value(_state, _field, _type), \
-}
-
-#define VMSTATE_POINTER_TEST(_field, _state, _test, _info, _type) { \
- .name = (stringify(_field)), \
- .info = &(_info), \
- .field_exists = (_test), \
- .size = sizeof(_type), \
- .flags = VMS_SINGLE|VMS_POINTER, \
- .offset = vmstate_offset_value(_state, _field, _type), \
-}
-
-#define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) {\
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .num = (_num), \
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_ARRAY, \
- .offset = vmstate_offset_array(_state, _field, _type, _num), \
-}
-
-#define VMSTATE_2DARRAY(_field, _state, _n1, _n2, _version, _info, _type) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .num = (_n1) * (_n2), \
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_ARRAY, \
- .offset = vmstate_offset_2darray(_state, _field, _type, _n1, _n2), \
-}
-
-#define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\
- .name = (stringify(_field)), \
- .field_exists = (_test), \
- .num = (_num), \
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_ARRAY, \
- .offset = vmstate_offset_array(_state, _field, _type, _num),\
-}
-
-#define VMSTATE_SUB_ARRAY(_field, _state, _start, _num, _version, _info, _type) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .num = (_num), \
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_ARRAY, \
- .offset = vmstate_offset_sub_array(_state, _field, _type, _start), \
-}
-
-#define VMSTATE_ARRAY_INT32_UNSAFE(_field, _state, _field_num, _info, _type) {\
- .name = (stringify(_field)), \
- .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_VARRAY_INT32, \
- .offset = offsetof(_state, _field), \
-}
-
-#define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_VARRAY_INT32|VMS_POINTER, \
- .offset = vmstate_offset_pointer(_state, _field, _type), \
-}
-
-#define VMSTATE_VARRAY_UINT32(_field, _state, _field_num, _version, _info, _type) {\
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_VARRAY_UINT32|VMS_POINTER, \
- .offset = vmstate_offset_pointer(_state, _field, _type), \
-}
-
-#define VMSTATE_VARRAY_UINT16_UNSAFE(_field, _state, _field_num, _version, _info, _type) {\
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_VARRAY_UINT16, \
- .offset = offsetof(_state, _field), \
-}
-
-#define VMSTATE_STRUCT_TEST(_field, _state, _test, _version, _vmsd, _type) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .field_exists = (_test), \
- .vmsd = &(_vmsd), \
- .size = sizeof(_type), \
- .flags = VMS_STRUCT, \
- .offset = vmstate_offset_value(_state, _field, _type), \
-}
-
-#define VMSTATE_STRUCT_POINTER_TEST(_field, _state, _test, _vmsd, _type) { \
- .name = (stringify(_field)), \
- .field_exists = (_test), \
- .vmsd = &(_vmsd), \
- .size = sizeof(_type), \
- .flags = VMS_STRUCT|VMS_POINTER, \
- .offset = vmstate_offset_value(_state, _field, _type), \
-}
-
-#define VMSTATE_ARRAY_OF_POINTER(_field, _state, _num, _version, _info, _type) {\
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .num = (_num), \
- .info = &(_info), \
- .size = sizeof(_type), \
- .flags = VMS_ARRAY|VMS_ARRAY_OF_POINTER, \
- .offset = vmstate_offset_array(_state, _field, _type, _num), \
-}
-
-#define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, _vmsd, _type) { \
- .name = (stringify(_field)), \
- .num = (_num), \
- .field_exists = (_test), \
- .version_id = (_version), \
- .vmsd = &(_vmsd), \
- .size = sizeof(_type), \
- .flags = VMS_STRUCT|VMS_ARRAY, \
- .offset = vmstate_offset_array(_state, _field, _type, _num),\
-}
-
-#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \
- .name = (stringify(_field)), \
- .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \
- .version_id = (_version), \
- .vmsd = &(_vmsd), \
- .size = sizeof(_type), \
- .flags = VMS_STRUCT|VMS_VARRAY_UINT8, \
- .offset = offsetof(_state, _field), \
-}
-
-#define VMSTATE_STRUCT_VARRAY_POINTER_INT32(_field, _state, _field_num, _vmsd, _type) { \
- .name = (stringify(_field)), \
- .version_id = 0, \
- .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
- .size = sizeof(_type), \
- .vmsd = &(_vmsd), \
- .flags = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT, \
- .offset = vmstate_offset_pointer(_state, _field, _type), \
-}
-
-#define VMSTATE_STRUCT_VARRAY_POINTER_UINT32(_field, _state, _field_num, _vmsd, _type) { \
- .name = (stringify(_field)), \
- .version_id = 0, \
- .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\
- .size = sizeof(_type), \
- .vmsd = &(_vmsd), \
- .flags = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT, \
- .offset = vmstate_offset_pointer(_state, _field, _type), \
-}
-
-#define VMSTATE_STRUCT_VARRAY_POINTER_UINT16(_field, _state, _field_num, _vmsd, _type) { \
- .name = (stringify(_field)), \
- .version_id = 0, \
- .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\
- .size = sizeof(_type), \
- .vmsd = &(_vmsd), \
- .flags = VMS_POINTER | VMS_VARRAY_UINT16 | VMS_STRUCT, \
- .offset = vmstate_offset_pointer(_state, _field, _type), \
-}
-
-#define VMSTATE_STRUCT_VARRAY_INT32(_field, _state, _field_num, _version, _vmsd, _type) { \
- .name = (stringify(_field)), \
- .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
- .version_id = (_version), \
- .vmsd = &(_vmsd), \
- .size = sizeof(_type), \
- .flags = VMS_STRUCT|VMS_VARRAY_INT32, \
- .offset = offsetof(_state, _field), \
-}
-
-#define VMSTATE_STRUCT_VARRAY_UINT32(_field, _state, _field_num, _version, _vmsd, _type) { \
- .name = (stringify(_field)), \
- .num_offset = vmstate_offset_value(_state, _field_num, uint32_t), \
- .version_id = (_version), \
- .vmsd = &(_vmsd), \
- .size = sizeof(_type), \
- .flags = VMS_STRUCT|VMS_VARRAY_UINT32, \
- .offset = offsetof(_state, _field), \
-}
-
-#define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .field_exists = (_test), \
- .size = (_size - _start), \
- .info = &vmstate_info_buffer, \
- .flags = VMS_BUFFER, \
- .offset = vmstate_offset_buffer(_state, _field) + _start, \
-}
-
-#define VMSTATE_VBUFFER_MULTIPLY(_field, _state, _version, _test, _start, _field_size, _multiply) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .field_exists = (_test), \
- .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\
- .size = (_multiply), \
- .info = &vmstate_info_buffer, \
- .flags = VMS_VBUFFER|VMS_POINTER|VMS_MULTIPLY, \
- .offset = offsetof(_state, _field), \
- .start = (_start), \
-}
-
-#define VMSTATE_VBUFFER(_field, _state, _version, _test, _start, _field_size) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .field_exists = (_test), \
- .size_offset = vmstate_offset_value(_state, _field_size, int32_t),\
- .info = &vmstate_info_buffer, \
- .flags = VMS_VBUFFER|VMS_POINTER, \
- .offset = offsetof(_state, _field), \
- .start = (_start), \
-}
-
-#define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _start, _field_size) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .field_exists = (_test), \
- .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\
- .info = &vmstate_info_buffer, \
- .flags = VMS_VBUFFER|VMS_POINTER, \
- .offset = offsetof(_state, _field), \
- .start = (_start), \
-}
-
-#define VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, _info, _size) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .size = (_size), \
- .info = &(_info), \
- .flags = VMS_BUFFER, \
- .offset = offsetof(_state, _field), \
-}
-
-#define VMSTATE_BUFFER_POINTER_UNSAFE(_field, _state, _version, _size) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .size = (_size), \
- .info = &vmstate_info_buffer, \
- .flags = VMS_BUFFER|VMS_POINTER, \
- .offset = offsetof(_state, _field), \
-}
-
-#define VMSTATE_UNUSED_BUFFER(_test, _version, _size) { \
- .name = "unused", \
- .field_exists = (_test), \
- .version_id = (_version), \
- .size = (_size), \
- .info = &vmstate_info_unused_buffer, \
- .flags = VMS_BUFFER, \
-}
-
-/* _field_size should be a int32_t field in the _state struct giving the
- * size of the bitmap _field in bits.
- */
-#define VMSTATE_BITMAP(_field, _state, _version, _field_size) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .size_offset = vmstate_offset_value(_state, _field_size, int32_t),\
- .info = &vmstate_info_bitmap, \
- .flags = VMS_VBUFFER|VMS_POINTER, \
- .offset = offsetof(_state, _field), \
-}
-
-/* _f : field name
- _f_n : num of elements field_name
- _n : num of elements
- _s : struct state name
- _v : version
-*/
-
-#define VMSTATE_SINGLE(_field, _state, _version, _info, _type) \
- VMSTATE_SINGLE_TEST(_field, _state, NULL, _version, _info, _type)
-
-#define VMSTATE_STRUCT(_field, _state, _version, _vmsd, _type) \
- VMSTATE_STRUCT_TEST(_field, _state, NULL, _version, _vmsd, _type)
-
-#define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type) \
- VMSTATE_STRUCT_POINTER_TEST(_field, _state, NULL, _vmsd, _type)
-
-#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) \
- VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version, \
- _vmsd, _type)
-
-#define VMSTATE_BOOL_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_bool, bool)
-
-#define VMSTATE_INT8_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int8, int8_t)
-#define VMSTATE_INT16_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int16, int16_t)
-#define VMSTATE_INT32_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int32, int32_t)
-#define VMSTATE_INT64_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int64, int64_t)
-
-#define VMSTATE_UINT8_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint8, uint8_t)
-#define VMSTATE_UINT16_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16, uint16_t)
-#define VMSTATE_UINT32_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32, uint32_t)
-#define VMSTATE_UINT64_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64, uint64_t)
-
-#define VMSTATE_BOOL(_f, _s) \
- VMSTATE_BOOL_V(_f, _s, 0)
-
-#define VMSTATE_INT8(_f, _s) \
- VMSTATE_INT8_V(_f, _s, 0)
-#define VMSTATE_INT16(_f, _s) \
- VMSTATE_INT16_V(_f, _s, 0)
-#define VMSTATE_INT32(_f, _s) \
- VMSTATE_INT32_V(_f, _s, 0)
-#define VMSTATE_INT64(_f, _s) \
- VMSTATE_INT64_V(_f, _s, 0)
-
-#define VMSTATE_UINT8(_f, _s) \
- VMSTATE_UINT8_V(_f, _s, 0)
-#define VMSTATE_UINT16(_f, _s) \
- VMSTATE_UINT16_V(_f, _s, 0)
-#define VMSTATE_UINT32(_f, _s) \
- VMSTATE_UINT32_V(_f, _s, 0)
-#define VMSTATE_UINT64(_f, _s) \
- VMSTATE_UINT64_V(_f, _s, 0)
-
-#define VMSTATE_UINT8_EQUAL(_f, _s) \
- VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint8_equal, uint8_t)
-
-#define VMSTATE_UINT16_EQUAL(_f, _s) \
- VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint16_equal, uint16_t)
-
-#define VMSTATE_UINT16_EQUAL_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16_equal, uint16_t)
-
-#define VMSTATE_INT32_EQUAL(_f, _s) \
- VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_equal, int32_t)
-
-#define VMSTATE_UINT32_EQUAL_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32_equal, uint32_t)
-
-#define VMSTATE_UINT32_EQUAL(_f, _s) \
- VMSTATE_UINT32_EQUAL_V(_f, _s, 0)
-
-#define VMSTATE_UINT64_EQUAL_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64_equal, uint64_t)
-
-#define VMSTATE_UINT64_EQUAL(_f, _s) \
- VMSTATE_UINT64_EQUAL_V(_f, _s, 0)
-
-#define VMSTATE_INT32_LE(_f, _s) \
- VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
-
-#define VMSTATE_UINT8_TEST(_f, _s, _t) \
- VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t)
-
-#define VMSTATE_UINT16_TEST(_f, _s, _t) \
- VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t)
-
-#define VMSTATE_UINT32_TEST(_f, _s, _t) \
- VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint32, uint32_t)
-
-
-#define VMSTATE_FLOAT64_V(_f, _s, _v) \
- VMSTATE_SINGLE(_f, _s, _v, vmstate_info_float64, float64)
-
-#define VMSTATE_FLOAT64(_f, _s) \
- VMSTATE_FLOAT64_V(_f, _s, 0)
-
-#define VMSTATE_TIMER_TEST(_f, _s, _test) \
- VMSTATE_POINTER_TEST(_f, _s, _test, vmstate_info_timer, QEMUTimer *)
-
-#define VMSTATE_TIMER_V(_f, _s, _v) \
- VMSTATE_POINTER(_f, _s, _v, vmstate_info_timer, QEMUTimer *)
-
-#define VMSTATE_TIMER(_f, _s) \
- VMSTATE_TIMER_V(_f, _s, 0)
-
-#define VMSTATE_TIMER_ARRAY(_f, _s, _n) \
- VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *)
-
-#define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool)
-
-#define VMSTATE_BOOL_ARRAY(_f, _s, _n) \
- VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
-
-#define VMSTATE_UINT16_2DARRAY_V(_f, _s, _n1, _n2, _v) \
- VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint16, uint16_t)
-
-#define VMSTATE_UINT16_ARRAY(_f, _s, _n) \
- VMSTATE_UINT16_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_UINT16_2DARRAY(_f, _s, _n1, _n2) \
- VMSTATE_UINT16_2DARRAY_V(_f, _s, _n1, _n2, 0)
-
-#define VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, _v) \
- VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint8, uint8_t)
-
-#define VMSTATE_UINT8_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint8, uint8_t)
-
-#define VMSTATE_UINT8_ARRAY(_f, _s, _n) \
- VMSTATE_UINT8_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_UINT8_2DARRAY(_f, _s, _n1, _n2) \
- VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, 0)
-
-#define VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint32, uint32_t)
-
-#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \
- VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint64, uint64_t)
-
-#define VMSTATE_UINT64_ARRAY(_f, _s, _n) \
- VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_INT16_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int16, int16_t)
-
-#define VMSTATE_INT16_ARRAY(_f, _s, _n) \
- VMSTATE_INT16_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_INT32_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int32, int32_t)
-
-#define VMSTATE_INT32_ARRAY(_f, _s, _n) \
- VMSTATE_INT32_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
- VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
-
-#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \
- VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t)
-
-#define VMSTATE_INT64_ARRAY(_f, _s, _n) \
- VMSTATE_INT64_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_FLOAT64_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_float64, float64)
-
-#define VMSTATE_FLOAT64_ARRAY(_f, _s, _n) \
- VMSTATE_FLOAT64_ARRAY_V(_f, _s, _n, 0)
-
-#define VMSTATE_BUFFER_V(_f, _s, _v) \
- VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f)))
-
-#define VMSTATE_BUFFER(_f, _s) \
- VMSTATE_BUFFER_V(_f, _s, 0)
-
-#define VMSTATE_PARTIAL_BUFFER(_f, _s, _size) \
- VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, 0, _size)
-
-#define VMSTATE_BUFFER_START_MIDDLE(_f, _s, _start) \
- VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, _start, sizeof(typeof_field(_s, _f)))
-
-#define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size) \
- VMSTATE_VBUFFER(_f, _s, 0, NULL, 0, _size)
-
-#define VMSTATE_PARTIAL_VBUFFER_UINT32(_f, _s, _size) \
- VMSTATE_VBUFFER_UINT32(_f, _s, 0, NULL, 0, _size)
-
-#define VMSTATE_SUB_VBUFFER(_f, _s, _start, _size) \
- VMSTATE_VBUFFER(_f, _s, 0, NULL, _start, _size)
-
-#define VMSTATE_BUFFER_TEST(_f, _s, _test) \
- VMSTATE_STATIC_BUFFER(_f, _s, 0, _test, 0, sizeof(typeof_field(_s, _f)))
-
-#define VMSTATE_BUFFER_UNSAFE(_field, _state, _version, _size) \
- VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, vmstate_info_buffer, _size)
-
-#define VMSTATE_UNUSED_V(_v, _size) \
- VMSTATE_UNUSED_BUFFER(NULL, _v, _size)
-
-#define VMSTATE_UNUSED(_size) \
- VMSTATE_UNUSED_V(0, _size)
-
-#define VMSTATE_UNUSED_TEST(_test, _size) \
- VMSTATE_UNUSED_BUFFER(_test, 0, _size)
-
-#define VMSTATE_END_OF_LIST() \
- {}
-
-int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, int version_id);
-void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque);
-
-int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
- const VMStateDescription *vmsd,
- void *base, int alias_id,
- int required_for_version);
-
-static inline int vmstate_register(DeviceState *dev, int instance_id,
- const VMStateDescription *vmsd,
- void *opaque)
-{
- return vmstate_register_with_alias_id(dev, instance_id, vmsd,
- opaque, -1, 0);
-}
-
-void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
- void *opaque);
-
-struct MemoryRegion;
-void vmstate_register_ram(struct MemoryRegion *memory, DeviceState *dev);
-void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *dev);
-void vmstate_register_ram_global(struct MemoryRegion *memory);
-
-#endif
diff --git a/contrib/qemu/include/monitor/monitor.h b/contrib/qemu/include/monitor/monitor.h
deleted file mode 100644
index 1942cc42fe2..00000000000
--- a/contrib/qemu/include/monitor/monitor.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef MONITOR_H
-#define MONITOR_H
-
-#include "qemu-common.h"
-#include "qapi/qmp/qerror.h"
-#include "qapi/qmp/qdict.h"
-#include "block/block.h"
-#include "monitor/readline.h"
-
-extern Monitor *cur_mon;
-extern Monitor *default_mon;
-
-/* flags for monitor_init */
-#define MONITOR_IS_DEFAULT 0x01
-#define MONITOR_USE_READLINE 0x02
-#define MONITOR_USE_CONTROL 0x04
-#define MONITOR_USE_PRETTY 0x08
-
-/* flags for monitor commands */
-#define MONITOR_CMD_ASYNC 0x0001
-
-/* QMP events */
-typedef enum MonitorEvent {
- QEVENT_SHUTDOWN,
- QEVENT_RESET,
- QEVENT_POWERDOWN,
- QEVENT_STOP,
- QEVENT_RESUME,
- QEVENT_VNC_CONNECTED,
- QEVENT_VNC_INITIALIZED,
- QEVENT_VNC_DISCONNECTED,
- QEVENT_BLOCK_IO_ERROR,
- QEVENT_RTC_CHANGE,
- QEVENT_WATCHDOG,
- QEVENT_SPICE_CONNECTED,
- QEVENT_SPICE_INITIALIZED,
- QEVENT_SPICE_DISCONNECTED,
- QEVENT_BLOCK_JOB_COMPLETED,
- QEVENT_BLOCK_JOB_CANCELLED,
- QEVENT_BLOCK_JOB_ERROR,
- QEVENT_BLOCK_JOB_READY,
- QEVENT_DEVICE_DELETED,
- QEVENT_DEVICE_TRAY_MOVED,
- QEVENT_NIC_RX_FILTER_CHANGED,
- QEVENT_SUSPEND,
- QEVENT_SUSPEND_DISK,
- QEVENT_WAKEUP,
- QEVENT_BALLOON_CHANGE,
- QEVENT_SPICE_MIGRATE_COMPLETED,
- QEVENT_GUEST_PANICKED,
-
- /* Add to 'monitor_event_names' array in monitor.c when
- * defining new events here */
-
- QEVENT_MAX,
-} MonitorEvent;
-
-int monitor_cur_is_qmp(void);
-
-void monitor_protocol_event(MonitorEvent event, QObject *data);
-void monitor_init(CharDriverState *chr, int flags);
-
-int monitor_suspend(Monitor *mon);
-void monitor_resume(Monitor *mon);
-
-int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
- BlockDriverCompletionFunc *completion_cb,
- void *opaque);
-int monitor_read_block_device_key(Monitor *mon, const char *device,
- BlockDriverCompletionFunc *completion_cb,
- void *opaque);
-
-int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
-int monitor_handle_fd_param(Monitor *mon, const char *fdname);
-
-void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
- GCC_FMT_ATTR(2, 0);
-void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
-void monitor_print_filename(Monitor *mon, const char *filename);
-void monitor_flush(Monitor *mon);
-int monitor_set_cpu(int cpu_index);
-int monitor_get_cpu_index(void);
-
-typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
-
-void monitor_set_error(Monitor *mon, QError *qerror);
-void monitor_read_command(Monitor *mon, int show_prompt);
-ReadLineState *monitor_get_rs(Monitor *mon);
-int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
- void *opaque);
-
-int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret);
-
-int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret);
-
-AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
- bool has_opaque, const char *opaque,
- Error **errp);
-int monitor_fdset_get_fd(int64_t fdset_id, int flags);
-int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd);
-int monitor_fdset_dup_fd_remove(int dup_fd);
-int monitor_fdset_dup_fd_find(int dup_fd);
-
-#endif /* !MONITOR_H */
diff --git a/contrib/qemu/include/monitor/readline.h b/contrib/qemu/include/monitor/readline.h
deleted file mode 100644
index fc9806ecf1a..00000000000
--- a/contrib/qemu/include/monitor/readline.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef READLINE_H
-#define READLINE_H
-
-#include "qemu-common.h"
-
-#define READLINE_CMD_BUF_SIZE 4095
-#define READLINE_MAX_CMDS 64
-#define READLINE_MAX_COMPLETIONS 256
-
-typedef void ReadLineFunc(Monitor *mon, const char *str, void *opaque);
-typedef void ReadLineCompletionFunc(const char *cmdline);
-
-typedef struct ReadLineState {
- char cmd_buf[READLINE_CMD_BUF_SIZE + 1];
- int cmd_buf_index;
- int cmd_buf_size;
-
- char last_cmd_buf[READLINE_CMD_BUF_SIZE + 1];
- int last_cmd_buf_index;
- int last_cmd_buf_size;
-
- int esc_state;
- int esc_param;
-
- char *history[READLINE_MAX_CMDS];
- int hist_entry;
-
- ReadLineCompletionFunc *completion_finder;
- char *completions[READLINE_MAX_COMPLETIONS];
- int nb_completions;
- int completion_index;
-
- ReadLineFunc *readline_func;
- void *readline_opaque;
- int read_password;
- char prompt[256];
- Monitor *mon;
-} ReadLineState;
-
-void readline_add_completion(ReadLineState *rs, const char *str);
-void readline_set_completion_index(ReadLineState *rs, int completion_index);
-
-const char *readline_get_history(ReadLineState *rs, unsigned int index);
-
-void readline_handle_byte(ReadLineState *rs, int ch);
-
-void readline_start(ReadLineState *rs, const char *prompt, int read_password,
- ReadLineFunc *readline_func, void *opaque);
-void readline_restart(ReadLineState *rs);
-void readline_show_prompt(ReadLineState *rs);
-
-ReadLineState *readline_init(Monitor *mon,
- ReadLineCompletionFunc *completion_finder);
-
-#endif /* !READLINE_H */
diff --git a/contrib/qemu/include/qapi/error.h b/contrib/qemu/include/qapi/error.h
deleted file mode 100644
index ffd1cea4772..00000000000
--- a/contrib/qemu/include/qapi/error.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * QEMU Error Objects
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2. See
- * the COPYING.LIB file in the top-level directory.
- */
-#ifndef ERROR_H
-#define ERROR_H
-
-#include "qemu/compiler.h"
-#include "qapi-types.h"
-#include <stdbool.h>
-
-/**
- * A class representing internal errors within QEMU. An error has a ErrorClass
- * code and a human message.
- */
-typedef struct Error Error;
-
-/**
- * Set an indirect pointer to an error given a ErrorClass value and a
- * printf-style human message. This function is not meant to be used outside
- * of QEMU.
- */
-void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(3, 4);
-
-/**
- * Set an indirect pointer to an error given a ErrorClass value and a
- * printf-style human message, followed by a strerror() string if
- * @os_error is not zero.
- */
-void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5);
-
-/**
- * Same as error_set(), but sets a generic error
- */
-#define error_setg(err, fmt, ...) \
- error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
-#define error_setg_errno(err, os_error, fmt, ...) \
- error_set_errno(err, os_error, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
-
-/**
- * Helper for open() errors
- */
-void error_setg_file_open(Error **errp, int os_errno, const char *filename);
-
-/**
- * Returns true if an indirect pointer to an error is pointing to a valid
- * error object.
- */
-bool error_is_set(Error **err);
-
-/*
- * Get the error class of an error object.
- */
-ErrorClass error_get_class(const Error *err);
-
-/**
- * Returns an exact copy of the error passed as an argument.
- */
-Error *error_copy(const Error *err);
-
-/**
- * Get a human readable representation of an error object.
- */
-const char *error_get_pretty(Error *err);
-
-/**
- * Propagate an error to an indirect pointer to an error. This function will
- * always transfer ownership of the error reference and handles the case where
- * dst_err is NULL correctly. Errors after the first are discarded.
- */
-void error_propagate(Error **dst_err, Error *local_err);
-
-/**
- * Free an error object.
- */
-void error_free(Error *err);
-
-#endif
diff --git a/contrib/qemu/include/qapi/qmp/json-lexer.h b/contrib/qemu/include/qapi/qmp/json-lexer.h
deleted file mode 100644
index cdff0460a83..00000000000
--- a/contrib/qemu/include/qapi/qmp/json-lexer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * JSON lexer
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QEMU_JSON_LEXER_H
-#define QEMU_JSON_LEXER_H
-
-#include "qapi/qmp/qstring.h"
-#include "qapi/qmp/qlist.h"
-
-typedef enum json_token_type {
- JSON_OPERATOR = 100,
- JSON_INTEGER,
- JSON_FLOAT,
- JSON_KEYWORD,
- JSON_STRING,
- JSON_ESCAPE,
- JSON_SKIP,
- JSON_ERROR,
-} JSONTokenType;
-
-typedef struct JSONLexer JSONLexer;
-
-typedef void (JSONLexerEmitter)(JSONLexer *, QString *, JSONTokenType, int x, int y);
-
-struct JSONLexer
-{
- JSONLexerEmitter *emit;
- int state;
- QString *token;
- int x, y;
-};
-
-void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func);
-
-int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size);
-
-int json_lexer_flush(JSONLexer *lexer);
-
-void json_lexer_destroy(JSONLexer *lexer);
-
-#endif
diff --git a/contrib/qemu/include/qapi/qmp/json-parser.h b/contrib/qemu/include/qapi/qmp/json-parser.h
deleted file mode 100644
index 44d88f34685..00000000000
--- a/contrib/qemu/include/qapi/qmp/json-parser.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * JSON Parser
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QEMU_JSON_PARSER_H
-#define QEMU_JSON_PARSER_H
-
-#include "qemu-common.h"
-#include "qapi/qmp/qlist.h"
-#include "qapi/error.h"
-
-QObject *json_parser_parse(QList *tokens, va_list *ap);
-QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp);
-
-#endif
diff --git a/contrib/qemu/include/qapi/qmp/json-streamer.h b/contrib/qemu/include/qapi/qmp/json-streamer.h
deleted file mode 100644
index 823f7d7fa42..00000000000
--- a/contrib/qemu/include/qapi/qmp/json-streamer.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * JSON streaming support
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QEMU_JSON_STREAMER_H
-#define QEMU_JSON_STREAMER_H
-
-#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/json-lexer.h"
-
-typedef struct JSONMessageParser
-{
- void (*emit)(struct JSONMessageParser *parser, QList *tokens);
- JSONLexer lexer;
- int brace_count;
- int bracket_count;
- QList *tokens;
- uint64_t token_size;
-} JSONMessageParser;
-
-void json_message_parser_init(JSONMessageParser *parser,
- void (*func)(JSONMessageParser *, QList *));
-
-int json_message_parser_feed(JSONMessageParser *parser,
- const char *buffer, size_t size);
-
-int json_message_parser_flush(JSONMessageParser *parser);
-
-void json_message_parser_destroy(JSONMessageParser *parser);
-
-#endif
diff --git a/contrib/qemu/include/qapi/qmp/qbool.h b/contrib/qemu/include/qapi/qmp/qbool.h
deleted file mode 100644
index c4eaab9bb9f..00000000000
--- a/contrib/qemu/include/qapi/qmp/qbool.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * QBool Module
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QBOOL_H
-#define QBOOL_H
-
-#include <stdint.h>
-#include "qapi/qmp/qobject.h"
-
-typedef struct QBool {
- QObject_HEAD;
- int value;
-} QBool;
-
-QBool *qbool_from_int(int value);
-int qbool_get_int(const QBool *qb);
-QBool *qobject_to_qbool(const QObject *obj);
-
-#endif /* QBOOL_H */
diff --git a/contrib/qemu/include/qapi/qmp/qdict.h b/contrib/qemu/include/qapi/qmp/qdict.h
deleted file mode 100644
index 685b2e3fcbb..00000000000
--- a/contrib/qemu/include/qapi/qmp/qdict.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * QDict Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef QDICT_H
-#define QDICT_H
-
-#include "qapi/qmp/qobject.h"
-#include "qapi/qmp/qlist.h"
-#include "qemu/queue.h"
-#include <stdint.h>
-
-#define QDICT_BUCKET_MAX 512
-
-typedef struct QDictEntry {
- char *key;
- QObject *value;
- QLIST_ENTRY(QDictEntry) next;
-} QDictEntry;
-
-typedef struct QDict {
- QObject_HEAD;
- size_t size;
- QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX];
-} QDict;
-
-/* Object API */
-QDict *qdict_new(void);
-const char *qdict_entry_key(const QDictEntry *entry);
-QObject *qdict_entry_value(const QDictEntry *entry);
-size_t qdict_size(const QDict *qdict);
-void qdict_put_obj(QDict *qdict, const char *key, QObject *value);
-void qdict_del(QDict *qdict, const char *key);
-int qdict_haskey(const QDict *qdict, const char *key);
-QObject *qdict_get(const QDict *qdict, const char *key);
-QDict *qobject_to_qdict(const QObject *obj);
-void qdict_iter(const QDict *qdict,
- void (*iter)(const char *key, QObject *obj, void *opaque),
- void *opaque);
-const QDictEntry *qdict_first(const QDict *qdict);
-const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry);
-
-/* Helper to qdict_put_obj(), accepts any object */
-#define qdict_put(qdict, key, obj) \
- qdict_put_obj(qdict, key, QOBJECT(obj))
-
-/* High level helpers */
-double qdict_get_double(const QDict *qdict, const char *key);
-int64_t qdict_get_int(const QDict *qdict, const char *key);
-int qdict_get_bool(const QDict *qdict, const char *key);
-QList *qdict_get_qlist(const QDict *qdict, const char *key);
-QDict *qdict_get_qdict(const QDict *qdict, const char *key);
-const char *qdict_get_str(const QDict *qdict, const char *key);
-int64_t qdict_get_try_int(const QDict *qdict, const char *key,
- int64_t def_value);
-int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value);
-const char *qdict_get_try_str(const QDict *qdict, const char *key);
-
-QDict *qdict_clone_shallow(const QDict *src);
-
-#endif /* QDICT_H */
diff --git a/contrib/qemu/include/qapi/qmp/qerror.h b/contrib/qemu/include/qapi/qmp/qerror.h
deleted file mode 100644
index c30c2f6d7a3..00000000000
--- a/contrib/qemu/include/qapi/qmp/qerror.h
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * QError Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-#ifndef QERROR_H
-#define QERROR_H
-
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
-#include "qapi-types.h"
-#include <stdarg.h>
-
-typedef struct QError {
- QObject_HEAD;
- Location loc;
- char *err_msg;
- ErrorClass err_class;
-} QError;
-
-QString *qerror_human(const QError *qerror);
-void qerror_report(ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
-void qerror_report_err(Error *err);
-void assert_no_error(Error *err);
-
-/*
- * QError class list
- * Please keep the definitions in alphabetical order.
- * Use scripts/check-qerror.sh to check.
- */
-#define QERR_ADD_CLIENT_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Could not add client"
-
-#define QERR_AMBIGUOUS_PATH \
- ERROR_CLASS_GENERIC_ERROR, "Path '%s' does not uniquely identify an object"
-
-#define QERR_BAD_BUS_FOR_DEVICE \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' can't go on a %s bus"
-
-#define QERR_BASE_NOT_FOUND \
- ERROR_CLASS_GENERIC_ERROR, "Base '%s' not found"
-
-#define QERR_BLOCK_JOB_NOT_ACTIVE \
- ERROR_CLASS_DEVICE_NOT_ACTIVE, "No active block job on device '%s'"
-
-#define QERR_BLOCK_JOB_PAUSED \
- ERROR_CLASS_GENERIC_ERROR, "The block job for device '%s' is currently paused"
-
-#define QERR_BLOCK_JOB_NOT_READY \
- ERROR_CLASS_GENERIC_ERROR, "The active block job for device '%s' cannot be completed"
-
-#define QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED \
- ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by device '%s' does not support feature '%s'"
-
-#define QERR_BUFFER_OVERRUN \
- ERROR_CLASS_GENERIC_ERROR, "An internal buffer overran"
-
-#define QERR_BUS_NO_HOTPLUG \
- ERROR_CLASS_GENERIC_ERROR, "Bus '%s' does not support hotplugging"
-
-#define QERR_BUS_NOT_FOUND \
- ERROR_CLASS_GENERIC_ERROR, "Bus '%s' not found"
-
-#define QERR_COMMAND_DISABLED \
- ERROR_CLASS_GENERIC_ERROR, "The command %s has been disabled for this instance"
-
-#define QERR_COMMAND_NOT_FOUND \
- ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found"
-
-#define QERR_DEVICE_ENCRYPTED \
- ERROR_CLASS_DEVICE_ENCRYPTED, "'%s' (%s) is encrypted"
-
-#define QERR_DEVICE_FEATURE_BLOCKS_MIGRATION \
- ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when using feature '%s' in device '%s'"
-
-#define QERR_DEVICE_HAS_NO_MEDIUM \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no medium"
-
-#define QERR_DEVICE_INIT_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' could not be initialized"
-
-#define QERR_DEVICE_IN_USE \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' is in use"
-
-#define QERR_DEVICE_IS_READ_ONLY \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' is read only"
-
-#define QERR_DEVICE_LOCKED \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' is locked"
-
-#define QERR_DEVICE_MULTIPLE_BUSSES \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' has multiple child busses"
-
-#define QERR_DEVICE_NO_BUS \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no child bus"
-
-#define QERR_DEVICE_NO_HOTPLUG \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' does not support hotplugging"
-
-#define QERR_DEVICE_NOT_ACTIVE \
- ERROR_CLASS_DEVICE_NOT_ACTIVE, "Device '%s' has not been activated"
-
-#define QERR_DEVICE_NOT_ENCRYPTED \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not encrypted"
-
-#define QERR_DEVICE_NOT_FOUND \
- ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found"
-
-#define QERR_DEVICE_NOT_REMOVABLE \
- ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not removable"
-
-#define QERR_DUPLICATE_ID \
- ERROR_CLASS_GENERIC_ERROR, "Duplicate ID '%s' for %s"
-
-#define QERR_FD_NOT_FOUND \
- ERROR_CLASS_GENERIC_ERROR, "File descriptor named '%s' not found"
-
-#define QERR_FD_NOT_SUPPLIED \
- ERROR_CLASS_GENERIC_ERROR, "No file descriptor supplied via SCM_RIGHTS"
-
-#define QERR_FEATURE_DISABLED \
- ERROR_CLASS_GENERIC_ERROR, "The feature '%s' is not enabled"
-
-#define QERR_INVALID_BLOCK_FORMAT \
- ERROR_CLASS_GENERIC_ERROR, "Invalid block format '%s'"
-
-#define QERR_INVALID_OPTION_GROUP \
- ERROR_CLASS_GENERIC_ERROR, "There is no option group '%s'"
-
-#define QERR_INVALID_PARAMETER \
- ERROR_CLASS_GENERIC_ERROR, "Invalid parameter '%s'"
-
-#define QERR_INVALID_PARAMETER_COMBINATION \
- ERROR_CLASS_GENERIC_ERROR, "Invalid parameter combination"
-
-#define QERR_INVALID_PARAMETER_TYPE \
- ERROR_CLASS_GENERIC_ERROR, "Invalid parameter type for '%s', expected: %s"
-
-#define QERR_INVALID_PARAMETER_VALUE \
- ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' expects %s"
-
-#define QERR_INVALID_PASSWORD \
- ERROR_CLASS_GENERIC_ERROR, "Password incorrect"
-
-#define QERR_IO_ERROR \
- ERROR_CLASS_GENERIC_ERROR, "An IO error has occurred"
-
-#define QERR_JSON_PARSE_ERROR \
- ERROR_CLASS_GENERIC_ERROR, "JSON parse error, %s"
-
-#define QERR_JSON_PARSING \
- ERROR_CLASS_GENERIC_ERROR, "Invalid JSON syntax"
-
-#define QERR_KVM_MISSING_CAP \
- ERROR_CLASS_K_V_M_MISSING_CAP, "Using KVM without %s, %s unavailable"
-
-#define QERR_MIGRATION_ACTIVE \
- ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress"
-
-#define QERR_MIGRATION_NOT_SUPPORTED \
- ERROR_CLASS_GENERIC_ERROR, "State blocked by non-migratable device '%s'"
-
-#define QERR_MISSING_PARAMETER \
- ERROR_CLASS_GENERIC_ERROR, "Parameter '%s' is missing"
-
-#define QERR_NO_BUS_FOR_DEVICE \
- ERROR_CLASS_GENERIC_ERROR, "No '%s' bus found for device '%s'"
-
-#define QERR_NOT_SUPPORTED \
- ERROR_CLASS_GENERIC_ERROR, "Not supported"
-
-#define QERR_PERMISSION_DENIED \
- ERROR_CLASS_GENERIC_ERROR, "Insufficient permission to perform this operation"
-
-#define QERR_PROPERTY_NOT_FOUND \
- ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' not found"
-
-#define QERR_PROPERTY_VALUE_BAD \
- ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' doesn't take value '%s'"
-
-#define QERR_PROPERTY_VALUE_IN_USE \
- ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't take value '%s', it's in use"
-
-#define QERR_PROPERTY_VALUE_NOT_FOUND \
- ERROR_CLASS_GENERIC_ERROR, "Property '%s.%s' can't find value '%s'"
-
-#define QERR_PROPERTY_VALUE_NOT_POWER_OF_2 \
- ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2"
-
-#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
- ERROR_CLASS_GENERIC_ERROR, "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")"
-
-#define QERR_QGA_COMMAND_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Guest agent command failed, error was '%s'"
-
-#define QERR_QGA_LOGGING_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Guest agent failed to log non-optional log statement"
-
-#define QERR_QMP_BAD_INPUT_OBJECT \
- ERROR_CLASS_GENERIC_ERROR, "Expected '%s' in QMP input"
-
-#define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \
- ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' expects '%s'"
-
-#define QERR_QMP_EXTRA_MEMBER \
- ERROR_CLASS_GENERIC_ERROR, "QMP input object member '%s' is unexpected"
-
-#define QERR_RESET_REQUIRED \
- ERROR_CLASS_GENERIC_ERROR, "Resetting the Virtual Machine is required"
-
-#define QERR_SET_PASSWD_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Could not set password"
-
-#define QERR_TOO_MANY_FILES \
- ERROR_CLASS_GENERIC_ERROR, "Too many open files"
-
-#define QERR_UNDEFINED_ERROR \
- ERROR_CLASS_GENERIC_ERROR, "An undefined error has occurred"
-
-#define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
- ERROR_CLASS_GENERIC_ERROR, "'%s' uses a %s feature which is not supported by this qemu version: %s"
-
-#define QERR_UNSUPPORTED \
- ERROR_CLASS_GENERIC_ERROR, "this feature or command is not currently supported"
-
-#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
- ERROR_CLASS_GENERIC_ERROR, "Migration is disabled when VirtFS export path '%s' is mounted in the guest using mount_tag '%s'"
-
-#define QERR_SOCKET_CONNECT_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Failed to connect to socket"
-
-#define QERR_SOCKET_LISTEN_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Failed to set socket to listening mode"
-
-#define QERR_SOCKET_BIND_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Failed to bind socket"
-
-#define QERR_SOCKET_CREATE_FAILED \
- ERROR_CLASS_GENERIC_ERROR, "Failed to create socket"
-
-#endif /* QERROR_H */
diff --git a/contrib/qemu/include/qapi/qmp/qfloat.h b/contrib/qemu/include/qapi/qmp/qfloat.h
deleted file mode 100644
index a8658443dc2..00000000000
--- a/contrib/qemu/include/qapi/qmp/qfloat.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * QFloat Module
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QFLOAT_H
-#define QFLOAT_H
-
-#include <stdint.h>
-#include "qapi/qmp/qobject.h"
-
-typedef struct QFloat {
- QObject_HEAD;
- double value;
-} QFloat;
-
-QFloat *qfloat_from_double(double value);
-double qfloat_get_double(const QFloat *qi);
-QFloat *qobject_to_qfloat(const QObject *obj);
-
-#endif /* QFLOAT_H */
diff --git a/contrib/qemu/include/qapi/qmp/qint.h b/contrib/qemu/include/qapi/qmp/qint.h
deleted file mode 100644
index 48a41b0f2ae..00000000000
--- a/contrib/qemu/include/qapi/qmp/qint.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * QInt Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef QINT_H
-#define QINT_H
-
-#include <stdint.h>
-#include "qapi/qmp/qobject.h"
-
-typedef struct QInt {
- QObject_HEAD;
- int64_t value;
-} QInt;
-
-QInt *qint_from_int(int64_t value);
-int64_t qint_get_int(const QInt *qi);
-QInt *qobject_to_qint(const QObject *obj);
-
-#endif /* QINT_H */
diff --git a/contrib/qemu/include/qapi/qmp/qjson.h b/contrib/qemu/include/qapi/qmp/qjson.h
deleted file mode 100644
index 73351ed6d68..00000000000
--- a/contrib/qemu/include/qapi/qmp/qjson.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * QObject JSON integration
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QJSON_H
-#define QJSON_H
-
-#include <stdarg.h>
-#include "qemu/compiler.h"
-#include "qapi/qmp/qobject.h"
-#include "qapi/qmp/qstring.h"
-
-QObject *qobject_from_json(const char *string) GCC_FMT_ATTR(1, 0);
-QObject *qobject_from_jsonf(const char *string, ...) GCC_FMT_ATTR(1, 2);
-QObject *qobject_from_jsonv(const char *string, va_list *ap) GCC_FMT_ATTR(1, 0);
-
-QString *qobject_to_json(const QObject *obj);
-QString *qobject_to_json_pretty(const QObject *obj);
-
-#endif /* QJSON_H */
diff --git a/contrib/qemu/include/qapi/qmp/qlist.h b/contrib/qemu/include/qapi/qmp/qlist.h
deleted file mode 100644
index 6cc4831df3e..00000000000
--- a/contrib/qemu/include/qapi/qmp/qlist.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * QList Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef QLIST_H
-#define QLIST_H
-
-#include "qapi/qmp/qobject.h"
-#include "qemu/queue.h"
-
-typedef struct QListEntry {
- QObject *value;
- QTAILQ_ENTRY(QListEntry) next;
-} QListEntry;
-
-typedef struct QList {
- QObject_HEAD;
- QTAILQ_HEAD(,QListEntry) head;
-} QList;
-
-#define qlist_append(qlist, obj) \
- qlist_append_obj(qlist, QOBJECT(obj))
-
-#define QLIST_FOREACH_ENTRY(qlist, var) \
- for ((var) = ((qlist)->head.tqh_first); \
- (var); \
- (var) = ((var)->next.tqe_next))
-
-static inline QObject *qlist_entry_obj(const QListEntry *entry)
-{
- return entry->value;
-}
-
-QList *qlist_new(void);
-QList *qlist_copy(QList *src);
-void qlist_append_obj(QList *qlist, QObject *obj);
-void qlist_iter(const QList *qlist,
- void (*iter)(QObject *obj, void *opaque), void *opaque);
-QObject *qlist_pop(QList *qlist);
-QObject *qlist_peek(QList *qlist);
-int qlist_empty(const QList *qlist);
-size_t qlist_size(const QList *qlist);
-QList *qobject_to_qlist(const QObject *obj);
-
-static inline const QListEntry *qlist_first(const QList *qlist)
-{
- return QTAILQ_FIRST(&qlist->head);
-}
-
-static inline const QListEntry *qlist_next(const QListEntry *entry)
-{
- return QTAILQ_NEXT(entry, next);
-}
-
-#endif /* QLIST_H */
diff --git a/contrib/qemu/include/qapi/qmp/qobject.h b/contrib/qemu/include/qapi/qmp/qobject.h
deleted file mode 100644
index 9124649ed20..00000000000
--- a/contrib/qemu/include/qapi/qmp/qobject.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * QEMU Object Model.
- *
- * Based on ideas by Avi Kivity <avi@redhat.com>
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- * QObject Reference Counts Terminology
- * ------------------------------------
- *
- * - Returning references: A function that returns an object may
- * return it as either a weak or a strong reference. If the reference
- * is strong, you are responsible for calling QDECREF() on the reference
- * when you are done.
- *
- * If the reference is weak, the owner of the reference may free it at
- * any time in the future. Before storing the reference anywhere, you
- * should call QINCREF() to make the reference strong.
- *
- * - Transferring ownership: when you transfer ownership of a reference
- * by calling a function, you are no longer responsible for calling
- * QDECREF() when the reference is no longer needed. In other words,
- * when the function returns you must behave as if the reference to the
- * passed object was weak.
- */
-#ifndef QOBJECT_H
-#define QOBJECT_H
-
-#include <stddef.h>
-#include <assert.h>
-
-typedef enum {
- QTYPE_NONE,
- QTYPE_QINT,
- QTYPE_QSTRING,
- QTYPE_QDICT,
- QTYPE_QLIST,
- QTYPE_QFLOAT,
- QTYPE_QBOOL,
- QTYPE_QERROR,
-} qtype_code;
-
-struct QObject;
-
-typedef struct QType {
- qtype_code code;
- void (*destroy)(struct QObject *);
-} QType;
-
-typedef struct QObject {
- const QType *type;
- size_t refcnt;
-} QObject;
-
-/* Objects definitions must include this */
-#define QObject_HEAD \
- QObject base
-
-/* Get the 'base' part of an object */
-#define QOBJECT(obj) (&(obj)->base)
-
-/* High-level interface for qobject_incref() */
-#define QINCREF(obj) \
- qobject_incref(QOBJECT(obj))
-
-/* High-level interface for qobject_decref() */
-#define QDECREF(obj) \
- qobject_decref(obj ? QOBJECT(obj) : NULL)
-
-/* Initialize an object to default values */
-#define QOBJECT_INIT(obj, qtype_type) \
- obj->base.refcnt = 1; \
- obj->base.type = qtype_type
-
-/**
- * qobject_incref(): Increment QObject's reference count
- */
-static inline void qobject_incref(QObject *obj)
-{
- if (obj)
- obj->refcnt++;
-}
-
-/**
- * qobject_decref(): Decrement QObject's reference count, deallocate
- * when it reaches zero
- */
-static inline void qobject_decref(QObject *obj)
-{
- if (obj && --obj->refcnt == 0) {
- assert(obj->type != NULL);
- assert(obj->type->destroy != NULL);
- obj->type->destroy(obj);
- }
-}
-
-/**
- * qobject_type(): Return the QObject's type
- */
-static inline qtype_code qobject_type(const QObject *obj)
-{
- assert(obj->type != NULL);
- return obj->type->code;
-}
-
-#endif /* QOBJECT_H */
diff --git a/contrib/qemu/include/qapi/qmp/qstring.h b/contrib/qemu/include/qapi/qmp/qstring.h
deleted file mode 100644
index 1bc3666107c..00000000000
--- a/contrib/qemu/include/qapi/qmp/qstring.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * QString Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef QSTRING_H
-#define QSTRING_H
-
-#include <stdint.h>
-#include "qapi/qmp/qobject.h"
-
-typedef struct QString {
- QObject_HEAD;
- char *string;
- size_t length;
- size_t capacity;
-} QString;
-
-QString *qstring_new(void);
-QString *qstring_from_str(const char *str);
-QString *qstring_from_substr(const char *str, int start, int end);
-size_t qstring_get_length(const QString *qstring);
-const char *qstring_get_str(const QString *qstring);
-void qstring_append_int(QString *qstring, int64_t value);
-void qstring_append(QString *qstring, const char *str);
-void qstring_append_chr(QString *qstring, int c);
-QString *qobject_to_qstring(const QObject *obj);
-
-#endif /* QSTRING_H */
diff --git a/contrib/qemu/include/qapi/qmp/types.h b/contrib/qemu/include/qapi/qmp/types.h
deleted file mode 100644
index 7782ec5a602..00000000000
--- a/contrib/qemu/include/qapi/qmp/types.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Include all QEMU objects.
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef QEMU_OBJECTS_H
-#define QEMU_OBJECTS_H
-
-#include "qapi/qmp/qobject.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qfloat.h"
-#include "qapi/qmp/qbool.h"
-#include "qapi/qmp/qstring.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qjson.h"
-
-#endif /* QEMU_OBJECTS_H */
diff --git a/contrib/qemu/include/qemu-common.h b/contrib/qemu/include/qemu-common.h
deleted file mode 100644
index 6948bb91774..00000000000
--- a/contrib/qemu/include/qemu-common.h
+++ /dev/null
@@ -1,478 +0,0 @@
-
-/* Common header file that is included by all of QEMU.
- *
- * This file is supposed to be included only by .c files. No header file should
- * depend on qemu-common.h, as this would easily lead to circular header
- * dependencies.
- *
- * If a header file uses a definition from qemu-common.h, that definition
- * must be moved to a separate header file, and the header that uses it
- * must include that header.
- */
-#ifndef QEMU_COMMON_H
-#define QEMU_COMMON_H
-
-#include "qemu/compiler.h"
-#include "config-host.h"
-#include "qemu/typedefs.h"
-
-#if defined(__arm__) || defined(__sparc__) || defined(__mips__) || defined(__hppa__) || defined(__ia64__)
-#define WORDS_ALIGNED
-#endif
-
-#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
-
-/* we put basic includes here to avoid repeating them in device drivers */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <string.h>
-#include <strings.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <time.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <assert.h>
-#include <signal.h>
-#include "glib-compat.h"
-
-#ifdef _WIN32
-#include "sysemu/os-win32.h"
-#endif
-
-#ifdef CONFIG_POSIX
-#include "sysemu/os-posix.h"
-#endif
-
-#ifndef O_LARGEFILE
-#define O_LARGEFILE 0
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-#ifndef ENOMEDIUM
-#define ENOMEDIUM ENODEV
-#endif
-#if !defined(ENOTSUP)
-#define ENOTSUP 4096
-#endif
-#if !defined(ECANCELED)
-#define ECANCELED 4097
-#endif
-#if !defined(EMEDIUMTYPE)
-#define EMEDIUMTYPE 4098
-#endif
-#ifndef TIME_MAX
-#define TIME_MAX LONG_MAX
-#endif
-
-/* HOST_LONG_BITS is the size of a native pointer in bits. */
-#if UINTPTR_MAX == UINT32_MAX
-# define HOST_LONG_BITS 32
-#elif UINTPTR_MAX == UINT64_MAX
-# define HOST_LONG_BITS 64
-#else
-# error Unknown pointer size
-#endif
-
-typedef int (*fprintf_function)(FILE *f, const char *fmt, ...)
- GCC_FMT_ATTR(2, 3);
-
-#ifdef _WIN32
-#define fsync _commit
-#if !defined(lseek)
-# define lseek _lseeki64
-#endif
-int qemu_ftruncate64(int, int64_t);
-#if !defined(ftruncate)
-# define ftruncate qemu_ftruncate64
-#endif
-
-static inline char *realpath(const char *path, char *resolved_path)
-{
- _fullpath(resolved_path, path, _MAX_PATH);
- return resolved_path;
-}
-#endif
-
-/* icount */
-void configure_icount(const char *option);
-extern int use_icount;
-
-#include "qemu/osdep.h"
-#include "qemu/bswap.h"
-
-/* FIXME: Remove NEED_CPU_H. */
-#ifdef NEED_CPU_H
-#include "cpu.h"
-#endif /* !defined(NEED_CPU_H) */
-
-/* main function, renamed */
-#if defined(CONFIG_COCOA)
-int qemu_main(int argc, char **argv, char **envp);
-#endif
-
-void qemu_get_timedate(struct tm *tm, int offset);
-int qemu_timedate_diff(struct tm *tm);
-
-#if !GLIB_CHECK_VERSION(2, 20, 0)
-/*
- * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly
- * on older systems.
- */
-static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout)
-{
- GMainContext *ctx = g_main_context_default();
- return g_main_context_get_poll_func(ctx)(fds, nfds, timeout);
-}
-#endif
-
-/**
- * is_help_option:
- * @s: string to test
- *
- * Check whether @s is one of the standard strings which indicate
- * that the user is asking for a list of the valid values for a
- * command option like -cpu or -M. The current accepted strings
- * are 'help' and '?'. '?' is deprecated (it is a shell wildcard
- * which makes it annoying to use in a reliable way) but provided
- * for backwards compatibility.
- *
- * Returns: true if @s is a request for a list.
- */
-static inline bool is_help_option(const char *s)
-{
- return !strcmp(s, "?") || !strcmp(s, "help");
-}
-
-/* cutils.c */
-void pstrcpy(char *buf, int buf_size, const char *str);
-void strpadcpy(char *buf, int buf_size, const char *str, char pad);
-char *pstrcat(char *buf, int buf_size, const char *s);
-int strstart(const char *str, const char *val, const char **ptr);
-int stristart(const char *str, const char *val, const char **ptr);
-int qemu_strnlen(const char *s, int max_len);
-char *qemu_strsep(char **input, const char *delim);
-time_t mktimegm(struct tm *tm);
-int qemu_fls(int i);
-int qemu_fdatasync(int fd);
-int fcntl_setfl(int fd, int flag);
-int qemu_parse_fd(const char *param);
-
-int parse_uint(const char *s, unsigned long long *value, char **endptr,
- int base);
-int parse_uint_full(const char *s, unsigned long long *value, int base);
-
-/*
- * strtosz() suffixes used to specify the default treatment of an
- * argument passed to strtosz() without an explicit suffix.
- * These should be defined using upper case characters in the range
- * A-Z, as strtosz() will use qemu_toupper() on the given argument
- * prior to comparison.
- */
-#define STRTOSZ_DEFSUFFIX_EB 'E'
-#define STRTOSZ_DEFSUFFIX_PB 'P'
-#define STRTOSZ_DEFSUFFIX_TB 'T'
-#define STRTOSZ_DEFSUFFIX_GB 'G'
-#define STRTOSZ_DEFSUFFIX_MB 'M'
-#define STRTOSZ_DEFSUFFIX_KB 'K'
-#define STRTOSZ_DEFSUFFIX_B 'B'
-int64_t strtosz(const char *nptr, char **end);
-int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix);
-int64_t strtosz_suffix_unit(const char *nptr, char **end,
- const char default_suffix, int64_t unit);
-
-/* path.c */
-void init_paths(const char *prefix);
-const char *path(const char *pathname);
-
-#define qemu_isalnum(c) isalnum((unsigned char)(c))
-#define qemu_isalpha(c) isalpha((unsigned char)(c))
-#define qemu_iscntrl(c) iscntrl((unsigned char)(c))
-#define qemu_isdigit(c) isdigit((unsigned char)(c))
-#define qemu_isgraph(c) isgraph((unsigned char)(c))
-#define qemu_islower(c) islower((unsigned char)(c))
-#define qemu_isprint(c) isprint((unsigned char)(c))
-#define qemu_ispunct(c) ispunct((unsigned char)(c))
-#define qemu_isspace(c) isspace((unsigned char)(c))
-#define qemu_isupper(c) isupper((unsigned char)(c))
-#define qemu_isxdigit(c) isxdigit((unsigned char)(c))
-#define qemu_tolower(c) tolower((unsigned char)(c))
-#define qemu_toupper(c) toupper((unsigned char)(c))
-#define qemu_isascii(c) isascii((unsigned char)(c))
-#define qemu_toascii(c) toascii((unsigned char)(c))
-
-void *qemu_oom_check(void *ptr);
-
-ssize_t qemu_write_full(int fd, const void *buf, size_t count)
- QEMU_WARN_UNUSED_RESULT;
-ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags)
- QEMU_WARN_UNUSED_RESULT;
-ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
- QEMU_WARN_UNUSED_RESULT;
-
-#ifndef _WIN32
-int qemu_pipe(int pipefd[2]);
-/* like openpty() but also makes it raw; return master fd */
-int qemu_openpty_raw(int *aslave, char *pty_name);
-#endif
-
-#ifdef _WIN32
-/* MinGW needs type casts for the 'buf' and 'optval' arguments. */
-#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \
- getsockopt(sockfd, level, optname, (void *)optval, optlen)
-#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \
- setsockopt(sockfd, level, optname, (const void *)optval, optlen)
-#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
-#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
- sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
-#else
-#define qemu_getsockopt(sockfd, level, optname, optval, optlen) \
- getsockopt(sockfd, level, optname, optval, optlen)
-#define qemu_setsockopt(sockfd, level, optname, optval, optlen) \
- setsockopt(sockfd, level, optname, optval, optlen)
-#define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags)
-#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
- sendto(sockfd, buf, len, flags, destaddr, addrlen)
-#endif
-
-/* Error handling. */
-
-void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-
-struct ParallelIOArg {
- void *buffer;
- int count;
-};
-
-typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
-
-typedef uint64_t pcibus_t;
-
-typedef enum LostTickPolicy {
- LOST_TICK_DISCARD,
- LOST_TICK_DELAY,
- LOST_TICK_MERGE,
- LOST_TICK_SLEW,
- LOST_TICK_MAX
-} LostTickPolicy;
-
-typedef struct PCIHostDeviceAddress {
- unsigned int domain;
- unsigned int bus;
- unsigned int slot;
- unsigned int function;
-} PCIHostDeviceAddress;
-
-void tcg_exec_init(unsigned long tb_size);
-bool tcg_enabled(void);
-
-void cpu_exec_init_all(void);
-
-/* CPU save/load. */
-#ifdef CPU_SAVE_VERSION
-void cpu_save(QEMUFile *f, void *opaque);
-int cpu_load(QEMUFile *f, void *opaque, int version_id);
-#endif
-
-/* Unblock cpu */
-void qemu_cpu_kick_self(void);
-
-/* work queue */
-struct qemu_work_item {
- struct qemu_work_item *next;
- void (*func)(void *data);
- void *data;
- int done;
- bool free;
-};
-
-
-/**
- * Sends a (part of) iovec down a socket, yielding when the socket is full, or
- * Receives data into a (part of) iovec from a socket,
- * yielding when there is no data in the socket.
- * The same interface as qemu_sendv_recvv(), with added yielding.
- * XXX should mark these as coroutine_fn
- */
-ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
- size_t offset, size_t bytes, bool do_send);
-#define qemu_co_recvv(sockfd, iov, iov_cnt, offset, bytes) \
- qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, false)
-#define qemu_co_sendv(sockfd, iov, iov_cnt, offset, bytes) \
- qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, true)
-
-/**
- * The same as above, but with just a single buffer
- */
-ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send);
-#define qemu_co_recv(sockfd, buf, bytes) \
- qemu_co_send_recv(sockfd, buf, bytes, false)
-#define qemu_co_send(sockfd, buf, bytes) \
- qemu_co_send_recv(sockfd, buf, bytes, true)
-
-typedef struct QEMUIOVector {
- struct iovec *iov;
- int niov;
- int nalloc;
- size_t size;
-} QEMUIOVector;
-
-void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
-void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov);
-void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
-void qemu_iovec_concat(QEMUIOVector *dst,
- QEMUIOVector *src, size_t soffset, size_t sbytes);
-void qemu_iovec_concat_iov(QEMUIOVector *dst,
- struct iovec *src_iov, unsigned int src_cnt,
- size_t soffset, size_t sbytes);
-void qemu_iovec_destroy(QEMUIOVector *qiov);
-void qemu_iovec_reset(QEMUIOVector *qiov);
-size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset,
- void *buf, size_t bytes);
-size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
- const void *buf, size_t bytes);
-size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
- int fillc, size_t bytes);
-
-bool buffer_is_zero(const void *buf, size_t len);
-
-void qemu_progress_init(int enabled, float min_skip);
-void qemu_progress_end(void);
-void qemu_progress_print(float delta, int max);
-const char *qemu_get_vm_name(void);
-
-#define QEMU_FILE_TYPE_BIOS 0
-#define QEMU_FILE_TYPE_KEYMAP 1
-char *qemu_find_file(int type, const char *name);
-
-/* OS specific functions */
-void os_setup_early_signal_handling(void);
-char *os_find_datadir(const char *argv0);
-void os_parse_cmd_args(int index, const char *optarg);
-void os_pidfile_error(void);
-
-/* Convert a byte between binary and BCD. */
-static inline uint8_t to_bcd(uint8_t val)
-{
- return ((val / 10) << 4) | (val % 10);
-}
-
-static inline uint8_t from_bcd(uint8_t val)
-{
- return ((val >> 4) * 10) + (val & 0x0f);
-}
-
-/* compute with 96 bit intermediate result: (a*b)/c */
-static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
- union {
- uint64_t ll;
- struct {
-#ifdef HOST_WORDS_BIGENDIAN
- uint32_t high, low;
-#else
- uint32_t low, high;
-#endif
- } l;
- } u, res;
- uint64_t rl, rh;
-
- u.ll = a;
- rl = (uint64_t)u.l.low * (uint64_t)b;
- rh = (uint64_t)u.l.high * (uint64_t)b;
- rh += (rl >> 32);
- res.l.high = rh / c;
- res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
- return res.ll;
-}
-
-/* Round number down to multiple */
-#define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
-
-/* Round number up to multiple */
-#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
-
-static inline bool is_power_of_2(uint64_t value)
-{
- if (!value) {
- return 0;
- }
-
- return !(value & (value - 1));
-}
-
-/* round down to the nearest power of 2*/
-int64_t pow2floor(int64_t value);
-
-#include "qemu/module.h"
-
-/*
- * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128)
- * Input is limited to 14-bit numbers
- */
-
-int uleb128_encode_small(uint8_t *out, uint32_t n);
-int uleb128_decode_small(const uint8_t *in, uint32_t *n);
-
-/* unicode.c */
-int mod_utf8_codepoint(const char *s, size_t n, char **end);
-
-/*
- * Hexdump a buffer to a file. An optional string prefix is added to every line
- */
-
-void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size);
-
-/* vector definitions */
-#ifdef __ALTIVEC__
-#include <altivec.h>
-/* The altivec.h header says we're allowed to undef these for
- * C++ compatibility. Here we don't care about C++, but we
- * undef them anyway to avoid namespace pollution.
- */
-#undef vector
-#undef pixel
-#undef bool
-#define VECTYPE __vector unsigned char
-#define SPLAT(p) vec_splat(vec_ld(0, p), 0)
-#define ALL_EQ(v1, v2) vec_all_eq(v1, v2)
-/* altivec.h may redefine the bool macro as vector type.
- * Reset it to POSIX semantics. */
-#define bool _Bool
-#elif defined __SSE2__
-#include <emmintrin.h>
-#define VECTYPE __m128i
-#define SPLAT(p) _mm_set1_epi8(*(p))
-#define ALL_EQ(v1, v2) (_mm_movemask_epi8(_mm_cmpeq_epi8(v1, v2)) == 0xFFFF)
-#else
-#define VECTYPE unsigned long
-#define SPLAT(p) (*(p) * (~0UL / 255))
-#define ALL_EQ(v1, v2) ((v1) == (v2))
-#endif
-
-#define BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR 8
-static inline bool
-can_use_buffer_find_nonzero_offset(const void *buf, size_t len)
-{
- return (len % (BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR
- * sizeof(VECTYPE)) == 0
- && ((uintptr_t) buf) % sizeof(VECTYPE) == 0);
-}
-size_t buffer_find_nonzero_offset(const void *buf, size_t len);
-
-/*
- * helper to parse debug environment variables
- */
-int parse_debug_env(const char *name, int max, int initial);
-
-#endif
diff --git a/contrib/qemu/include/qemu/aes.h b/contrib/qemu/include/qemu/aes.h
deleted file mode 100644
index e79c707436f..00000000000
--- a/contrib/qemu/include/qemu/aes.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef QEMU_AES_H
-#define QEMU_AES_H
-
-#define AES_MAXNR 14
-#define AES_BLOCK_SIZE 16
-
-struct aes_key_st {
- uint32_t rd_key[4 *(AES_MAXNR + 1)];
- int rounds;
-};
-typedef struct aes_key_st AES_KEY;
-
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
-
-void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
-void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc);
-
-/*
-AES_Te0[x] = S [x].[02, 01, 01, 03];
-AES_Te1[x] = S [x].[03, 02, 01, 01];
-AES_Te2[x] = S [x].[01, 03, 02, 01];
-AES_Te3[x] = S [x].[01, 01, 03, 02];
-AES_Te4[x] = S [x].[01, 01, 01, 01];
-
-AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
-AES_Td1[x] = Si[x].[0b, 0e, 09, 0d];
-AES_Td2[x] = Si[x].[0d, 0b, 0e, 09];
-AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
-AES_Td4[x] = Si[x].[01, 01, 01, 01];
-*/
-
-extern const uint32_t AES_Te0[256], AES_Te1[256], AES_Te2[256],
- AES_Te3[256], AES_Te4[256];
-extern const uint32_t AES_Td0[256], AES_Td1[256], AES_Td2[256],
- AES_Td3[256], AES_Td4[256];
-
-#endif
diff --git a/contrib/qemu/include/qemu/atomic.h b/contrib/qemu/include/qemu/atomic.h
deleted file mode 100644
index 0aa89133018..00000000000
--- a/contrib/qemu/include/qemu/atomic.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Simple interface for atomic operations.
- *
- * Copyright (C) 2013 Red Hat, Inc.
- *
- * Author: Paolo Bonzini <pbonzini@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef __QEMU_ATOMIC_H
-#define __QEMU_ATOMIC_H 1
-
-#include "qemu/compiler.h"
-
-/* For C11 atomic ops */
-
-/* Compiler barrier */
-#define barrier() ({ asm volatile("" ::: "memory"); (void)0; })
-
-#ifndef __ATOMIC_RELAXED
-
-/*
- * We use GCC builtin if it's available, as that can use mfence on
- * 32-bit as well, e.g. if built with -march=pentium-m. However, on
- * i386 the spec is buggy, and the implementation followed it until
- * 4.3 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36793).
- */
-#if defined(__i386__) || defined(__x86_64__)
-#if !QEMU_GNUC_PREREQ(4, 4)
-#if defined __x86_64__
-#define smp_mb() ({ asm volatile("mfence" ::: "memory"); (void)0; })
-#else
-#define smp_mb() ({ asm volatile("lock; addl $0,0(%%esp) " ::: "memory"); (void)0; })
-#endif
-#endif
-#endif
-
-
-#ifdef __alpha__
-#define smp_read_barrier_depends() asm volatile("mb":::"memory")
-#endif
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__s390x__)
-
-/*
- * Because of the strongly ordered storage model, wmb() and rmb() are nops
- * here (a compiler barrier only). QEMU doesn't do accesses to write-combining
- * qemu memory or non-temporal load/stores from C code.
- */
-#define smp_wmb() barrier()
-#define smp_rmb() barrier()
-
-/*
- * __sync_lock_test_and_set() is documented to be an acquire barrier only,
- * but it is a full barrier at the hardware level. Add a compiler barrier
- * to make it a full barrier also at the compiler level.
- */
-#define atomic_xchg(ptr, i) (barrier(), __sync_lock_test_and_set(ptr, i))
-
-/*
- * Load/store with Java volatile semantics.
- */
-#define atomic_mb_set(ptr, i) ((void)atomic_xchg(ptr, i))
-
-#elif defined(_ARCH_PPC)
-
-/*
- * We use an eieio() for wmb() on powerpc. This assumes we don't
- * need to order cacheable and non-cacheable stores with respect to
- * each other.
- *
- * smp_mb has the same problem as on x86 for not-very-new GCC
- * (http://patchwork.ozlabs.org/patch/126184/, Nov 2011).
- */
-#define smp_wmb() ({ asm volatile("eieio" ::: "memory"); (void)0; })
-#if defined(__powerpc64__)
-#define smp_rmb() ({ asm volatile("lwsync" ::: "memory"); (void)0; })
-#else
-#define smp_rmb() ({ asm volatile("sync" ::: "memory"); (void)0; })
-#endif
-#define smp_mb() ({ asm volatile("sync" ::: "memory"); (void)0; })
-
-#endif /* _ARCH_PPC */
-
-#endif /* C11 atomics */
-
-/*
- * For (host) platforms we don't have explicit barrier definitions
- * for, we use the gcc __sync_synchronize() primitive to generate a
- * full barrier. This should be safe on all platforms, though it may
- * be overkill for smp_wmb() and smp_rmb().
- */
-#ifndef smp_mb
-#define smp_mb() __sync_synchronize()
-#endif
-
-#ifndef smp_wmb
-#ifdef __ATOMIC_RELEASE
-#define smp_wmb() __atomic_thread_fence(__ATOMIC_RELEASE)
-#else
-#define smp_wmb() __sync_synchronize()
-#endif
-#endif
-
-#ifndef smp_rmb
-#ifdef __ATOMIC_ACQUIRE
-#define smp_rmb() __atomic_thread_fence(__ATOMIC_ACQUIRE)
-#else
-#define smp_rmb() __sync_synchronize()
-#endif
-#endif
-
-#ifndef smp_read_barrier_depends
-#ifdef __ATOMIC_CONSUME
-#define smp_read_barrier_depends() __atomic_thread_fence(__ATOMIC_CONSUME)
-#else
-#define smp_read_barrier_depends() barrier()
-#endif
-#endif
-
-#ifndef atomic_read
-#define atomic_read(ptr) (*(__typeof__(*ptr) *volatile) (ptr))
-#endif
-
-#ifndef atomic_set
-#define atomic_set(ptr, i) ((*(__typeof__(*ptr) *volatile) (ptr)) = (i))
-#endif
-
-/* These have the same semantics as Java volatile variables.
- * See http://gee.cs.oswego.edu/dl/jmm/cookbook.html:
- * "1. Issue a StoreStore barrier (wmb) before each volatile store."
- * 2. Issue a StoreLoad barrier after each volatile store.
- * Note that you could instead issue one before each volatile load, but
- * this would be slower for typical programs using volatiles in which
- * reads greatly outnumber writes. Alternatively, if available, you
- * can implement volatile store as an atomic instruction (for example
- * XCHG on x86) and omit the barrier. This may be more efficient if
- * atomic instructions are cheaper than StoreLoad barriers.
- * 3. Issue LoadLoad and LoadStore barriers after each volatile load."
- *
- * If you prefer to think in terms of "pairing" of memory barriers,
- * an atomic_mb_read pairs with an atomic_mb_set.
- *
- * And for the few ia64 lovers that exist, an atomic_mb_read is a ld.acq,
- * while an atomic_mb_set is a st.rel followed by a memory barrier.
- *
- * These are a bit weaker than __atomic_load/store with __ATOMIC_SEQ_CST
- * (see docs/atomics.txt), and I'm not sure that __ATOMIC_ACQ_REL is enough.
- * Just always use the barriers manually by the rules above.
- */
-#ifndef atomic_mb_read
-#define atomic_mb_read(ptr) ({ \
- typeof(*ptr) _val = atomic_read(ptr); \
- smp_rmb(); \
- _val; \
-})
-#endif
-
-#ifndef atomic_mb_set
-#define atomic_mb_set(ptr, i) do { \
- smp_wmb(); \
- atomic_set(ptr, i); \
- smp_mb(); \
-} while (0)
-#endif
-
-#ifndef atomic_xchg
-#ifdef __ATOMIC_SEQ_CST
-#define atomic_xchg(ptr, i) ({ \
- typeof(*ptr) _new = (i), _old; \
- __atomic_exchange(ptr, &_new, &_old, __ATOMIC_SEQ_CST); \
- _old; \
-})
-#elif defined __clang__
-#define atomic_xchg(ptr, i) __sync_exchange(ptr, i)
-#else
-/* __sync_lock_test_and_set() is documented to be an acquire barrier only. */
-#define atomic_xchg(ptr, i) (smp_mb(), __sync_lock_test_and_set(ptr, i))
-#endif
-#endif
-
-/* Provide shorter names for GCC atomic builtins. */
-#define atomic_fetch_inc(ptr) __sync_fetch_and_add(ptr, 1)
-#define atomic_fetch_dec(ptr) __sync_fetch_and_add(ptr, -1)
-#define atomic_fetch_add __sync_fetch_and_add
-#define atomic_fetch_sub __sync_fetch_and_sub
-#define atomic_fetch_and __sync_fetch_and_and
-#define atomic_fetch_or __sync_fetch_and_or
-#define atomic_cmpxchg __sync_val_compare_and_swap
-
-/* And even shorter names that return void. */
-#define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1))
-#define atomic_dec(ptr) ((void) __sync_fetch_and_add(ptr, -1))
-#define atomic_add(ptr, n) ((void) __sync_fetch_and_add(ptr, n))
-#define atomic_sub(ptr, n) ((void) __sync_fetch_and_sub(ptr, n))
-#define atomic_and(ptr, n) ((void) __sync_fetch_and_and(ptr, n))
-#define atomic_or(ptr, n) ((void) __sync_fetch_and_or(ptr, n))
-
-#endif
diff --git a/contrib/qemu/include/qemu/bitmap.h b/contrib/qemu/include/qemu/bitmap.h
deleted file mode 100644
index 308bbb71e9b..00000000000
--- a/contrib/qemu/include/qemu/bitmap.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Bitmap Module
- *
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef BITMAP_H
-#define BITMAP_H
-
-#include "qemu-common.h"
-#include "qemu/bitops.h"
-
-/*
- * The available bitmap operations and their rough meaning in the
- * case that the bitmap is a single unsigned long are thus:
- *
- * Note that nbits should be always a compile time evaluable constant.
- * Otherwise many inlines will generate horrible code.
- *
- * bitmap_zero(dst, nbits) *dst = 0UL
- * bitmap_fill(dst, nbits) *dst = ~0UL
- * bitmap_copy(dst, src, nbits) *dst = *src
- * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2
- * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2
- * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2
- * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2)
- * bitmap_complement(dst, src, nbits) *dst = ~(*src)
- * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal?
- * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap?
- * bitmap_empty(src, nbits) Are all bits zero in *src?
- * bitmap_full(src, nbits) Are all bits set in *src?
- * bitmap_set(dst, pos, nbits) Set specified bit area
- * bitmap_clear(dst, pos, nbits) Clear specified bit area
- * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
- */
-
-/*
- * Also the following operations apply to bitmaps.
- *
- * set_bit(bit, addr) *addr |= bit
- * clear_bit(bit, addr) *addr &= ~bit
- * change_bit(bit, addr) *addr ^= bit
- * test_bit(bit, addr) Is bit set in *addr?
- * test_and_set_bit(bit, addr) Set bit and return old value
- * test_and_clear_bit(bit, addr) Clear bit and return old value
- * test_and_change_bit(bit, addr) Change bit and return old value
- * find_first_zero_bit(addr, nbits) Position first zero bit in *addr
- * find_first_bit(addr, nbits) Position first set bit in *addr
- * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit
- * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit
- */
-
-#define BITMAP_LAST_WORD_MASK(nbits) \
- ( \
- ((nbits) % BITS_PER_LONG) ? \
- (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \
- )
-
-#define DECLARE_BITMAP(name,bits) \
- unsigned long name[BITS_TO_LONGS(bits)]
-
-#define small_nbits(nbits) \
- ((nbits) <= BITS_PER_LONG)
-
-int slow_bitmap_empty(const unsigned long *bitmap, int bits);
-int slow_bitmap_full(const unsigned long *bitmap, int bits);
-int slow_bitmap_equal(const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits);
-void slow_bitmap_complement(unsigned long *dst, const unsigned long *src,
- int bits);
-void slow_bitmap_shift_right(unsigned long *dst,
- const unsigned long *src, int shift, int bits);
-void slow_bitmap_shift_left(unsigned long *dst,
- const unsigned long *src, int shift, int bits);
-int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits);
-void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits);
-void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits);
-int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits);
-int slow_bitmap_intersects(const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits);
-
-static inline unsigned long *bitmap_new(int nbits)
-{
- int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
- return g_malloc0(len);
-}
-
-static inline void bitmap_zero(unsigned long *dst, int nbits)
-{
- if (small_nbits(nbits)) {
- *dst = 0UL;
- } else {
- int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
- memset(dst, 0, len);
- }
-}
-
-static inline void bitmap_fill(unsigned long *dst, int nbits)
-{
- size_t nlongs = BITS_TO_LONGS(nbits);
- if (!small_nbits(nbits)) {
- int len = (nlongs - 1) * sizeof(unsigned long);
- memset(dst, 0xff, len);
- }
- dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
-}
-
-static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
- int nbits)
-{
- if (small_nbits(nbits)) {
- *dst = *src;
- } else {
- int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
- memcpy(dst, src, len);
- }
-}
-
-static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
- const unsigned long *src2, int nbits)
-{
- if (small_nbits(nbits)) {
- return (*dst = *src1 & *src2) != 0;
- }
- return slow_bitmap_and(dst, src1, src2, nbits);
-}
-
-static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
- const unsigned long *src2, int nbits)
-{
- if (small_nbits(nbits)) {
- *dst = *src1 | *src2;
- } else {
- slow_bitmap_or(dst, src1, src2, nbits);
- }
-}
-
-static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
- const unsigned long *src2, int nbits)
-{
- if (small_nbits(nbits)) {
- *dst = *src1 ^ *src2;
- } else {
- slow_bitmap_xor(dst, src1, src2, nbits);
- }
-}
-
-static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
- const unsigned long *src2, int nbits)
-{
- if (small_nbits(nbits)) {
- return (*dst = *src1 & ~(*src2)) != 0;
- }
- return slow_bitmap_andnot(dst, src1, src2, nbits);
-}
-
-static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
- int nbits)
-{
- if (small_nbits(nbits)) {
- *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits);
- } else {
- slow_bitmap_complement(dst, src, nbits);
- }
-}
-
-static inline int bitmap_equal(const unsigned long *src1,
- const unsigned long *src2, int nbits)
-{
- if (small_nbits(nbits)) {
- return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
- } else {
- return slow_bitmap_equal(src1, src2, nbits);
- }
-}
-
-static inline int bitmap_empty(const unsigned long *src, int nbits)
-{
- if (small_nbits(nbits)) {
- return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
- } else {
- return slow_bitmap_empty(src, nbits);
- }
-}
-
-static inline int bitmap_full(const unsigned long *src, int nbits)
-{
- if (small_nbits(nbits)) {
- return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
- } else {
- return slow_bitmap_full(src, nbits);
- }
-}
-
-static inline int bitmap_intersects(const unsigned long *src1,
- const unsigned long *src2, int nbits)
-{
- if (small_nbits(nbits)) {
- return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
- } else {
- return slow_bitmap_intersects(src1, src2, nbits);
- }
-}
-
-void bitmap_set(unsigned long *map, int i, int len);
-void bitmap_clear(unsigned long *map, int start, int nr);
-unsigned long bitmap_find_next_zero_area(unsigned long *map,
- unsigned long size,
- unsigned long start,
- unsigned int nr,
- unsigned long align_mask);
-
-#endif /* BITMAP_H */
diff --git a/contrib/qemu/include/qemu/bitops.h b/contrib/qemu/include/qemu/bitops.h
deleted file mode 100644
index affcc969dcf..00000000000
--- a/contrib/qemu/include/qemu/bitops.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Bitops Module
- *
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#ifndef BITOPS_H
-#define BITOPS_H
-
-#include "qemu-common.h"
-#include "host-utils.h"
-
-#define BITS_PER_BYTE CHAR_BIT
-#define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE)
-
-#define BIT(nr) (1UL << (nr))
-#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
-#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
-#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
-
-/**
- * set_bit - Set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- */
-static inline void set_bit(int nr, unsigned long *addr)
-{
- unsigned long mask = BIT_MASK(nr);
- unsigned long *p = addr + BIT_WORD(nr);
-
- *p |= mask;
-}
-
-/**
- * clear_bit - Clears a bit in memory
- * @nr: Bit to clear
- * @addr: Address to start counting from
- */
-static inline void clear_bit(int nr, unsigned long *addr)
-{
- unsigned long mask = BIT_MASK(nr);
- unsigned long *p = addr + BIT_WORD(nr);
-
- *p &= ~mask;
-}
-
-/**
- * change_bit - Toggle a bit in memory
- * @nr: Bit to change
- * @addr: Address to start counting from
- */
-static inline void change_bit(int nr, unsigned long *addr)
-{
- unsigned long mask = BIT_MASK(nr);
- unsigned long *p = addr + BIT_WORD(nr);
-
- *p ^= mask;
-}
-
-/**
- * test_and_set_bit - Set a bit and return its old value
- * @nr: Bit to set
- * @addr: Address to count from
- */
-static inline int test_and_set_bit(int nr, unsigned long *addr)
-{
- unsigned long mask = BIT_MASK(nr);
- unsigned long *p = addr + BIT_WORD(nr);
- unsigned long old = *p;
-
- *p = old | mask;
- return (old & mask) != 0;
-}
-
-/**
- * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- */
-static inline int test_and_clear_bit(int nr, unsigned long *addr)
-{
- unsigned long mask = BIT_MASK(nr);
- unsigned long *p = addr + BIT_WORD(nr);
- unsigned long old = *p;
-
- *p = old & ~mask;
- return (old & mask) != 0;
-}
-
-/**
- * test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to change
- * @addr: Address to count from
- */
-static inline int test_and_change_bit(int nr, unsigned long *addr)
-{
- unsigned long mask = BIT_MASK(nr);
- unsigned long *p = addr + BIT_WORD(nr);
- unsigned long old = *p;
-
- *p = old ^ mask;
- return (old & mask) != 0;
-}
-
-/**
- * test_bit - Determine whether a bit is set
- * @nr: bit number to test
- * @addr: Address to start counting from
- */
-static inline int test_bit(int nr, const unsigned long *addr)
-{
- return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
-}
-
-/**
- * find_last_bit - find the last set bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
- *
- * Returns the bit number of the first set bit, or size.
- */
-unsigned long find_last_bit(const unsigned long *addr,
- unsigned long size);
-
-/**
- * find_next_bit - find the next set bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The bitmap size in bits
- */
-unsigned long find_next_bit(const unsigned long *addr,
- unsigned long size, unsigned long offset);
-
-/**
- * find_next_zero_bit - find the next cleared bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The bitmap size in bits
- */
-
-unsigned long find_next_zero_bit(const unsigned long *addr,
- unsigned long size,
- unsigned long offset);
-
-/**
- * find_first_bit - find the first set bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
- *
- * Returns the bit number of the first set bit.
- */
-static inline unsigned long find_first_bit(const unsigned long *addr,
- unsigned long size)
-{
- return find_next_bit(addr, size, 0);
-}
-
-/**
- * find_first_zero_bit - find the first cleared bit in a memory region
- * @addr: The address to start the search at
- * @size: The maximum size to search
- *
- * Returns the bit number of the first cleared bit.
- */
-static inline unsigned long find_first_zero_bit(const unsigned long *addr,
- unsigned long size)
-{
- return find_next_zero_bit(addr, size, 0);
-}
-
-static inline unsigned long hweight_long(unsigned long w)
-{
- unsigned long count;
-
- for (count = 0; w; w >>= 1) {
- count += w & 1;
- }
- return count;
-}
-
-/**
- * extract32:
- * @value: the value to extract the bit field from
- * @start: the lowest bit in the bit field (numbered from 0)
- * @length: the length of the bit field
- *
- * Extract from the 32 bit input @value the bit field specified by the
- * @start and @length parameters, and return it. The bit field must
- * lie entirely within the 32 bit word. It is valid to request that
- * all 32 bits are returned (ie @length 32 and @start 0).
- *
- * Returns: the value of the bit field extracted from the input value.
- */
-static inline uint32_t extract32(uint32_t value, int start, int length)
-{
- assert(start >= 0 && length > 0 && length <= 32 - start);
- return (value >> start) & (~0U >> (32 - length));
-}
-
-/**
- * extract64:
- * @value: the value to extract the bit field from
- * @start: the lowest bit in the bit field (numbered from 0)
- * @length: the length of the bit field
- *
- * Extract from the 64 bit input @value the bit field specified by the
- * @start and @length parameters, and return it. The bit field must
- * lie entirely within the 64 bit word. It is valid to request that
- * all 64 bits are returned (ie @length 64 and @start 0).
- *
- * Returns: the value of the bit field extracted from the input value.
- */
-static inline uint64_t extract64(uint64_t value, int start, int length)
-{
- assert(start >= 0 && length > 0 && length <= 64 - start);
- return (value >> start) & (~0ULL >> (64 - length));
-}
-
-/**
- * deposit32:
- * @value: initial value to insert bit field into
- * @start: the lowest bit in the bit field (numbered from 0)
- * @length: the length of the bit field
- * @fieldval: the value to insert into the bit field
- *
- * Deposit @fieldval into the 32 bit @value at the bit field specified
- * by the @start and @length parameters, and return the modified
- * @value. Bits of @value outside the bit field are not modified.
- * Bits of @fieldval above the least significant @length bits are
- * ignored. The bit field must lie entirely within the 32 bit word.
- * It is valid to request that all 32 bits are modified (ie @length
- * 32 and @start 0).
- *
- * Returns: the modified @value.
- */
-static inline uint32_t deposit32(uint32_t value, int start, int length,
- uint32_t fieldval)
-{
- uint32_t mask;
- assert(start >= 0 && length > 0 && length <= 32 - start);
- mask = (~0U >> (32 - length)) << start;
- return (value & ~mask) | ((fieldval << start) & mask);
-}
-
-/**
- * deposit64:
- * @value: initial value to insert bit field into
- * @start: the lowest bit in the bit field (numbered from 0)
- * @length: the length of the bit field
- * @fieldval: the value to insert into the bit field
- *
- * Deposit @fieldval into the 64 bit @value at the bit field specified
- * by the @start and @length parameters, and return the modified
- * @value. Bits of @value outside the bit field are not modified.
- * Bits of @fieldval above the least significant @length bits are
- * ignored. The bit field must lie entirely within the 64 bit word.
- * It is valid to request that all 64 bits are modified (ie @length
- * 64 and @start 0).
- *
- * Returns: the modified @value.
- */
-static inline uint64_t deposit64(uint64_t value, int start, int length,
- uint64_t fieldval)
-{
- uint64_t mask;
- assert(start >= 0 && length > 0 && length <= 64 - start);
- mask = (~0ULL >> (64 - length)) << start;
- return (value & ~mask) | ((fieldval << start) & mask);
-}
-
-#endif
diff --git a/contrib/qemu/include/qemu/bswap.h b/contrib/qemu/include/qemu/bswap.h
deleted file mode 100644
index bf6457b8c46..00000000000
--- a/contrib/qemu/include/qemu/bswap.h
+++ /dev/null
@@ -1,487 +0,0 @@
-#ifndef BSWAP_H
-#define BSWAP_H
-
-#include "config-host.h"
-#include <inttypes.h>
-#include <limits.h>
-#include <string.h>
-#include "fpu/softfloat.h"
-
-#ifdef CONFIG_MACHINE_BSWAP_H
-# include <sys/endian.h>
-# include <sys/types.h>
-# include <machine/bswap.h>
-#elif defined(__FreeBSD__)
-# include <sys/endian.h>
-#elif defined(CONFIG_BYTESWAP_H)
-#ifdef GF_DARWIN_HOST_OS
-# include <libkern/OSByteOrder.h>
-#define bswap_16(x) OSSwapInt16(x)
-#define bswap_32(x) OSSwapInt32(x)
-#define bswap_64(x) OSSwapInt64(x)
-#else
-# include <byteswap.h>
-#endif
-
-static inline uint16_t bswap16(uint16_t x)
-{
- return bswap_16(x);
-}
-
-static inline uint32_t bswap32(uint32_t x)
-{
- return bswap_32(x);
-}
-
-static inline uint64_t bswap64(uint64_t x)
-{
- return bswap_64(x);
-}
-# else
-static inline uint16_t bswap16(uint16_t x)
-{
- return (((x & 0x00ff) << 8) |
- ((x & 0xff00) >> 8));
-}
-
-static inline uint32_t bswap32(uint32_t x)
-{
- return (((x & 0x000000ffU) << 24) |
- ((x & 0x0000ff00U) << 8) |
- ((x & 0x00ff0000U) >> 8) |
- ((x & 0xff000000U) >> 24));
-}
-
-static inline uint64_t bswap64(uint64_t x)
-{
- return (((x & 0x00000000000000ffULL) << 56) |
- ((x & 0x000000000000ff00ULL) << 40) |
- ((x & 0x0000000000ff0000ULL) << 24) |
- ((x & 0x00000000ff000000ULL) << 8) |
- ((x & 0x000000ff00000000ULL) >> 8) |
- ((x & 0x0000ff0000000000ULL) >> 24) |
- ((x & 0x00ff000000000000ULL) >> 40) |
- ((x & 0xff00000000000000ULL) >> 56));
-}
-#endif /* ! CONFIG_MACHINE_BSWAP_H */
-
-static inline void bswap16s(uint16_t *s)
-{
- *s = bswap16(*s);
-}
-
-static inline void bswap32s(uint32_t *s)
-{
- *s = bswap32(*s);
-}
-
-static inline void bswap64s(uint64_t *s)
-{
- *s = bswap64(*s);
-}
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define be_bswap(v, size) (v)
-#define le_bswap(v, size) glue(bswap, size)(v)
-#define be_bswaps(v, size)
-#define le_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
-#else
-#define le_bswap(v, size) (v)
-#define be_bswap(v, size) glue(bswap, size)(v)
-#define le_bswaps(v, size)
-#define be_bswaps(p, size) do { *p = glue(bswap, size)(*p); } while(0)
-#endif
-
-#define CPU_CONVERT(endian, size, type)\
-static inline type endian ## size ## _to_cpu(type v)\
-{\
- return glue(endian, _bswap)(v, size);\
-}\
-\
-static inline type cpu_to_ ## endian ## size(type v)\
-{\
- return glue(endian, _bswap)(v, size);\
-}\
-\
-static inline void endian ## size ## _to_cpus(type *p)\
-{\
- glue(endian, _bswaps)(p, size);\
-}\
-\
-static inline void cpu_to_ ## endian ## size ## s(type *p)\
-{\
- glue(endian, _bswaps)(p, size);\
-}\
-\
-static inline type endian ## size ## _to_cpup(const type *p)\
-{\
- return glue(glue(endian, size), _to_cpu)(*p);\
-}\
-\
-static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
-{\
- *p = glue(glue(cpu_to_, endian), size)(v);\
-}
-
-CPU_CONVERT(be, 16, uint16_t)
-CPU_CONVERT(be, 32, uint32_t)
-CPU_CONVERT(be, 64, uint64_t)
-
-CPU_CONVERT(le, 16, uint16_t)
-CPU_CONVERT(le, 32, uint32_t)
-CPU_CONVERT(le, 64, uint64_t)
-
-/* len must be one of 1, 2, 4 */
-static inline uint32_t qemu_bswap_len(uint32_t value, int len)
-{
- return bswap32(value) >> (32 - 8 * len);
-}
-
-/* Unions for reinterpreting between floats and integers. */
-
-typedef union {
- float32 f;
- uint32_t l;
-} CPU_FloatU;
-
-typedef union {
- float64 d;
-#if defined(HOST_WORDS_BIGENDIAN)
- struct {
- uint32_t upper;
- uint32_t lower;
- } l;
-#else
- struct {
- uint32_t lower;
- uint32_t upper;
- } l;
-#endif
- uint64_t ll;
-} CPU_DoubleU;
-
-typedef union {
- floatx80 d;
- struct {
- uint64_t lower;
- uint16_t upper;
- } l;
-} CPU_LDoubleU;
-
-typedef union {
- float128 q;
-#if defined(HOST_WORDS_BIGENDIAN)
- struct {
- uint32_t upmost;
- uint32_t upper;
- uint32_t lower;
- uint32_t lowest;
- } l;
- struct {
- uint64_t upper;
- uint64_t lower;
- } ll;
-#else
- struct {
- uint32_t lowest;
- uint32_t lower;
- uint32_t upper;
- uint32_t upmost;
- } l;
- struct {
- uint64_t lower;
- uint64_t upper;
- } ll;
-#endif
-} CPU_QuadU;
-
-/* unaligned/endian-independent pointer access */
-
-/*
- * the generic syntax is:
- *
- * load: ld{type}{sign}{size}{endian}_p(ptr)
- *
- * store: st{type}{size}{endian}_p(ptr, val)
- *
- * Note there are small differences with the softmmu access API!
- *
- * type is:
- * (empty): integer access
- * f : float access
- *
- * sign is:
- * (empty): for floats or 32 bit size
- * u : unsigned
- * s : signed
- *
- * size is:
- * b: 8 bits
- * w: 16 bits
- * l: 32 bits
- * q: 64 bits
- *
- * endian is:
- * (empty): host endian
- * be : big endian
- * le : little endian
- */
-
-static inline int ldub_p(const void *ptr)
-{
- return *(uint8_t *)ptr;
-}
-
-static inline int ldsb_p(const void *ptr)
-{
- return *(int8_t *)ptr;
-}
-
-static inline void stb_p(void *ptr, int v)
-{
- *(uint8_t *)ptr = v;
-}
-
-/* Any compiler worth its salt will turn these memcpy into native unaligned
- operations. Thus we don't need to play games with packed attributes, or
- inline byte-by-byte stores. */
-
-static inline int lduw_p(const void *ptr)
-{
- uint16_t r;
- memcpy(&r, ptr, sizeof(r));
- return r;
-}
-
-static inline int ldsw_p(const void *ptr)
-{
- int16_t r;
- memcpy(&r, ptr, sizeof(r));
- return r;
-}
-
-static inline void stw_p(void *ptr, uint16_t v)
-{
- memcpy(ptr, &v, sizeof(v));
-}
-
-static inline int ldl_p(const void *ptr)
-{
- int32_t r;
- memcpy(&r, ptr, sizeof(r));
- return r;
-}
-
-static inline void stl_p(void *ptr, uint32_t v)
-{
- memcpy(ptr, &v, sizeof(v));
-}
-
-static inline uint64_t ldq_p(const void *ptr)
-{
- uint64_t r;
- memcpy(&r, ptr, sizeof(r));
- return r;
-}
-
-static inline void stq_p(void *ptr, uint64_t v)
-{
- memcpy(ptr, &v, sizeof(v));
-}
-
-static inline int lduw_le_p(const void *ptr)
-{
- return (uint16_t)le_bswap(lduw_p(ptr), 16);
-}
-
-static inline int ldsw_le_p(const void *ptr)
-{
- return (int16_t)le_bswap(lduw_p(ptr), 16);
-}
-
-static inline int ldl_le_p(const void *ptr)
-{
- return le_bswap(ldl_p(ptr), 32);
-}
-
-static inline uint64_t ldq_le_p(const void *ptr)
-{
- return le_bswap(ldq_p(ptr), 64);
-}
-
-static inline void stw_le_p(void *ptr, int v)
-{
- stw_p(ptr, le_bswap(v, 16));
-}
-
-static inline void stl_le_p(void *ptr, int v)
-{
- stl_p(ptr, le_bswap(v, 32));
-}
-
-static inline void stq_le_p(void *ptr, uint64_t v)
-{
- stq_p(ptr, le_bswap(v, 64));
-}
-
-/* float access */
-
-static inline float32 ldfl_le_p(const void *ptr)
-{
- CPU_FloatU u;
- u.l = ldl_le_p(ptr);
- return u.f;
-}
-
-static inline void stfl_le_p(void *ptr, float32 v)
-{
- CPU_FloatU u;
- u.f = v;
- stl_le_p(ptr, u.l);
-}
-
-static inline float64 ldfq_le_p(const void *ptr)
-{
- CPU_DoubleU u;
- u.ll = ldq_le_p(ptr);
- return u.d;
-}
-
-static inline void stfq_le_p(void *ptr, float64 v)
-{
- CPU_DoubleU u;
- u.d = v;
- stq_le_p(ptr, u.ll);
-}
-
-static inline int lduw_be_p(const void *ptr)
-{
- return (uint16_t)be_bswap(lduw_p(ptr), 16);
-}
-
-static inline int ldsw_be_p(const void *ptr)
-{
- return (int16_t)be_bswap(lduw_p(ptr), 16);
-}
-
-static inline int ldl_be_p(const void *ptr)
-{
- return be_bswap(ldl_p(ptr), 32);
-}
-
-static inline uint64_t ldq_be_p(const void *ptr)
-{
- return be_bswap(ldq_p(ptr), 64);
-}
-
-static inline void stw_be_p(void *ptr, int v)
-{
- stw_p(ptr, be_bswap(v, 16));
-}
-
-static inline void stl_be_p(void *ptr, int v)
-{
- stl_p(ptr, be_bswap(v, 32));
-}
-
-static inline void stq_be_p(void *ptr, uint64_t v)
-{
- stq_p(ptr, be_bswap(v, 64));
-}
-
-/* float access */
-
-static inline float32 ldfl_be_p(const void *ptr)
-{
- CPU_FloatU u;
- u.l = ldl_be_p(ptr);
- return u.f;
-}
-
-static inline void stfl_be_p(void *ptr, float32 v)
-{
- CPU_FloatU u;
- u.f = v;
- stl_be_p(ptr, u.l);
-}
-
-static inline float64 ldfq_be_p(const void *ptr)
-{
- CPU_DoubleU u;
- u.ll = ldq_be_p(ptr);
- return u.d;
-}
-
-static inline void stfq_be_p(void *ptr, float64 v)
-{
- CPU_DoubleU u;
- u.d = v;
- stq_be_p(ptr, u.ll);
-}
-
-/* Legacy unaligned versions. Note that we never had a complete set. */
-
-static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
-{
- stw_le_p(p, v);
-}
-
-static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
-{
- stl_le_p(p, v);
-}
-
-static inline uint16_t le16_to_cpupu(const uint16_t *p)
-{
- return lduw_le_p(p);
-}
-
-static inline uint32_t le32_to_cpupu(const uint32_t *p)
-{
- return ldl_le_p(p);
-}
-
-static inline uint32_t be32_to_cpupu(const uint32_t *p)
-{
- return ldl_be_p(p);
-}
-
-static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
-{
- stw_be_p(p, v);
-}
-
-static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
-{
- stl_be_p(p, v);
-}
-
-static inline void cpu_to_be64wu(uint64_t *p, uint64_t v)
-{
- stq_be_p(p, v);
-}
-
-static inline void cpu_to_32wu(uint32_t *p, uint32_t v)
-{
- stl_p(p, v);
-}
-
-static inline unsigned long leul_to_cpu(unsigned long v)
-{
- /* In order to break an include loop between here and
- qemu-common.h, don't rely on HOST_LONG_BITS. */
-#if ULONG_MAX == UINT32_MAX
- return le_bswap(v, 32);
-#elif ULONG_MAX == UINT64_MAX
- return le_bswap(v, 64);
-#else
-# error Unknown sizeof long
-#endif
-}
-
-#undef le_bswap
-#undef be_bswap
-#undef le_bswaps
-#undef be_bswaps
-
-#endif /* BSWAP_H */
diff --git a/contrib/qemu/include/qemu/compiler.h b/contrib/qemu/include/qemu/compiler.h
deleted file mode 100644
index 155b358964a..00000000000
--- a/contrib/qemu/include/qemu/compiler.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* public domain */
-
-#ifndef COMPILER_H
-#define COMPILER_H
-
-#include "config-host.h"
-
-/*----------------------------------------------------------------------------
-| The macro QEMU_GNUC_PREREQ tests for minimum version of the GNU C compiler.
-| The code is a copy of SOFTFLOAT_GNUC_PREREQ, see softfloat-macros.h.
-*----------------------------------------------------------------------------*/
-#if defined(__GNUC__) && defined(__GNUC_MINOR__)
-# define QEMU_GNUC_PREREQ(maj, min) \
- ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
-#else
-# define QEMU_GNUC_PREREQ(maj, min) 0
-#endif
-
-#define QEMU_NORETURN __attribute__ ((__noreturn__))
-
-#if QEMU_GNUC_PREREQ(3, 4)
-#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
-#else
-#define QEMU_WARN_UNUSED_RESULT
-#endif
-
-#if defined(_WIN32)
-# define QEMU_PACKED __attribute__((gcc_struct, packed))
-#else
-# define QEMU_PACKED __attribute__((packed))
-#endif
-
-#define cat(x,y) x ## y
-#define cat2(x,y) cat(x,y)
-#define QEMU_BUILD_BUG_ON(x) \
- typedef char cat2(qemu_build_bug_on__,__LINE__)[(x)?-1:1] __attribute__((unused));
-
-#if defined __GNUC__
-# if !QEMU_GNUC_PREREQ(4, 4)
- /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */
-# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m)))
-# else
- /* Use gnu_printf when supported (qemu uses standard format strings). */
-# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
-# if defined(_WIN32)
- /* Map __printf__ to __gnu_printf__ because we want standard format strings
- * even when MinGW or GLib include files use __printf__. */
-# define __printf__ __gnu_printf__
-# endif
-# endif
-#else
-#define GCC_FMT_ATTR(n, m)
-#endif
-
-#endif /* COMPILER_H */
diff --git a/contrib/qemu/include/qemu/error-report.h b/contrib/qemu/include/qemu/error-report.h
deleted file mode 100644
index 3b098a91730..00000000000
--- a/contrib/qemu/include/qemu/error-report.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Error reporting
- *
- * Copyright (C) 2010 Red Hat Inc.
- *
- * Authors:
- * Markus Armbruster <armbru@redhat.com>,
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef QEMU_ERROR_H
-#define QEMU_ERROR_H
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include "qemu/compiler.h"
-
-typedef struct Location {
- /* all members are private to qemu-error.c */
- enum { LOC_NONE, LOC_CMDLINE, LOC_FILE } kind;
- int num;
- const void *ptr;
- struct Location *prev;
-} Location;
-
-Location *loc_push_restore(Location *loc);
-Location *loc_push_none(Location *loc);
-Location *loc_pop(Location *loc);
-Location *loc_save(Location *loc);
-void loc_restore(Location *loc);
-void loc_set_none(void);
-void loc_set_cmdline(char **argv, int idx, int cnt);
-void loc_set_file(const char *fname, int lno);
-
-void error_vprintf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
-void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-void error_print_loc(void);
-void error_set_progname(const char *argv0);
-void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-const char *error_get_progname(void);
-extern bool enable_timestamp_msg;
-
-#endif
diff --git a/contrib/qemu/include/qemu/event_notifier.h b/contrib/qemu/include/qemu/event_notifier.h
deleted file mode 100644
index 88b57af7ce8..00000000000
--- a/contrib/qemu/include/qemu/event_notifier.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * event notifier support
- *
- * Copyright Red Hat, Inc. 2010
- *
- * Authors:
- * Michael S. Tsirkin <mst@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef QEMU_EVENT_NOTIFIER_H
-#define QEMU_EVENT_NOTIFIER_H
-
-#include "qemu-common.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-struct EventNotifier {
-#ifdef _WIN32
- HANDLE event;
-#else
- int rfd;
- int wfd;
-#endif
-};
-
-typedef void EventNotifierHandler(EventNotifier *);
-
-int event_notifier_init(EventNotifier *, int active);
-void event_notifier_cleanup(EventNotifier *);
-int event_notifier_set(EventNotifier *);
-int event_notifier_test_and_clear(EventNotifier *);
-int event_notifier_set_handler(EventNotifier *, EventNotifierHandler *);
-
-#ifdef CONFIG_POSIX
-void event_notifier_init_fd(EventNotifier *, int fd);
-int event_notifier_get_fd(EventNotifier *);
-#else
-HANDLE event_notifier_get_handle(EventNotifier *);
-#endif
-
-#endif
diff --git a/contrib/qemu/include/qemu/hbitmap.h b/contrib/qemu/include/qemu/hbitmap.h
deleted file mode 100644
index 550d7ce2c39..00000000000
--- a/contrib/qemu/include/qemu/hbitmap.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Hierarchical Bitmap Data Type
- *
- * Copyright Red Hat, Inc., 2012
- *
- * Author: Paolo Bonzini <pbonzini@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * later. See the COPYING file in the top-level directory.
- */
-
-#ifndef HBITMAP_H
-#define HBITMAP_H 1
-
-#include <limits.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include "bitops.h"
-#include "host-utils.h"
-
-typedef struct HBitmap HBitmap;
-typedef struct HBitmapIter HBitmapIter;
-
-#define BITS_PER_LEVEL (BITS_PER_LONG == 32 ? 5 : 6)
-
-/* For 32-bit, the largest that fits in a 4 GiB address space.
- * For 64-bit, the number of sectors in 1 PiB. Good luck, in
- * either case... :)
- */
-#define HBITMAP_LOG_MAX_SIZE (BITS_PER_LONG == 32 ? 34 : 41)
-
-/* We need to place a sentinel in level 0 to speed up iteration. Thus,
- * we do this instead of HBITMAP_LOG_MAX_SIZE / BITS_PER_LEVEL. The
- * difference is that it allocates an extra level when HBITMAP_LOG_MAX_SIZE
- * is an exact multiple of BITS_PER_LEVEL.
- */
-#define HBITMAP_LEVELS ((HBITMAP_LOG_MAX_SIZE / BITS_PER_LEVEL) + 1)
-
-struct HBitmapIter {
- const HBitmap *hb;
-
- /* Copied from hb for access in the inline functions (hb is opaque). */
- int granularity;
-
- /* Entry offset into the last-level array of longs. */
- size_t pos;
-
- /* The currently-active path in the tree. Each item of cur[i] stores
- * the bits (i.e. the subtrees) yet to be processed under that node.
- */
- unsigned long cur[HBITMAP_LEVELS];
-};
-
-/**
- * hbitmap_alloc:
- * @size: Number of bits in the bitmap.
- * @granularity: Granularity of the bitmap. Aligned groups of 2^@granularity
- * bits will be represented by a single bit. Each operation on a
- * range of bits first rounds the bits to determine which group they land
- * in, and then affect the entire set; iteration will only visit the first
- * bit of each group.
- *
- * Allocate a new HBitmap.
- */
-HBitmap *hbitmap_alloc(uint64_t size, int granularity);
-
-/**
- * hbitmap_empty:
- * @hb: HBitmap to operate on.
- *
- * Return whether the bitmap is empty.
- */
-bool hbitmap_empty(const HBitmap *hb);
-
-/**
- * hbitmap_granularity:
- * @hb: HBitmap to operate on.
- *
- * Return the granularity of the HBitmap.
- */
-int hbitmap_granularity(const HBitmap *hb);
-
-/**
- * hbitmap_count:
- * @hb: HBitmap to operate on.
- *
- * Return the number of bits set in the HBitmap.
- */
-uint64_t hbitmap_count(const HBitmap *hb);
-
-/**
- * hbitmap_set:
- * @hb: HBitmap to operate on.
- * @start: First bit to set (0-based).
- * @count: Number of bits to set.
- *
- * Set a consecutive range of bits in an HBitmap.
- */
-void hbitmap_set(HBitmap *hb, uint64_t start, uint64_t count);
-
-/**
- * hbitmap_reset:
- * @hb: HBitmap to operate on.
- * @start: First bit to reset (0-based).
- * @count: Number of bits to reset.
- *
- * Reset a consecutive range of bits in an HBitmap.
- */
-void hbitmap_reset(HBitmap *hb, uint64_t start, uint64_t count);
-
-/**
- * hbitmap_get:
- * @hb: HBitmap to operate on.
- * @item: Bit to query (0-based).
- *
- * Return whether the @item-th bit in an HBitmap is set.
- */
-bool hbitmap_get(const HBitmap *hb, uint64_t item);
-
-/**
- * hbitmap_free:
- * @hb: HBitmap to operate on.
- *
- * Free an HBitmap and all of its associated memory.
- */
-void hbitmap_free(HBitmap *hb);
-
-/**
- * hbitmap_iter_init:
- * @hbi: HBitmapIter to initialize.
- * @hb: HBitmap to iterate on.
- * @first: First bit to visit (0-based, must be strictly less than the
- * size of the bitmap).
- *
- * Set up @hbi to iterate on the HBitmap @hb. hbitmap_iter_next will return
- * the lowest-numbered bit that is set in @hb, starting at @first.
- *
- * Concurrent setting of bits is acceptable, and will at worst cause the
- * iteration to miss some of those bits. Resetting bits before the current
- * position of the iterator is also okay. However, concurrent resetting of
- * bits can lead to unexpected behavior if the iterator has not yet reached
- * those bits.
- */
-void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first);
-
-/* hbitmap_iter_skip_words:
- * @hbi: HBitmapIter to operate on.
- *
- * Internal function used by hbitmap_iter_next and hbitmap_iter_next_word.
- */
-unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi);
-
-/**
- * hbitmap_iter_next:
- * @hbi: HBitmapIter to operate on.
- *
- * Return the next bit that is set in @hbi's associated HBitmap,
- * or -1 if all remaining bits are zero.
- */
-static inline int64_t hbitmap_iter_next(HBitmapIter *hbi)
-{
- unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1];
- int64_t item;
-
- if (cur == 0) {
- cur = hbitmap_iter_skip_words(hbi);
- if (cur == 0) {
- return -1;
- }
- }
-
- /* The next call will resume work from the next bit. */
- hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1);
- item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur);
-
- return item << hbi->granularity;
-}
-
-/**
- * hbitmap_iter_next_word:
- * @hbi: HBitmapIter to operate on.
- * @p_cur: Location where to store the next non-zero word.
- *
- * Return the index of the next nonzero word that is set in @hbi's
- * associated HBitmap, and set *p_cur to the content of that word
- * (bits before the index that was passed to hbitmap_iter_init are
- * trimmed on the first call). Return -1, and set *p_cur to zero,
- * if all remaining words are zero.
- */
-static inline size_t hbitmap_iter_next_word(HBitmapIter *hbi, unsigned long *p_cur)
-{
- unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1];
-
- if (cur == 0) {
- cur = hbitmap_iter_skip_words(hbi);
- if (cur == 0) {
- *p_cur = 0;
- return -1;
- }
- }
-
- /* The next call will resume work from the next word. */
- hbi->cur[HBITMAP_LEVELS - 1] = 0;
- *p_cur = cur;
- return hbi->pos;
-}
-
-
-#endif
diff --git a/contrib/qemu/include/qemu/host-utils.h b/contrib/qemu/include/qemu/host-utils.h
deleted file mode 100644
index 0f688c1c00a..00000000000
--- a/contrib/qemu/include/qemu/host-utils.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Utility compute operations used by translated code.
- *
- * Copyright (c) 2007 Thiemo Seufer
- * Copyright (c) 2007 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef HOST_UTILS_H
-#define HOST_UTILS_H 1
-
-#include "qemu/compiler.h" /* QEMU_GNUC_PREREQ */
-#include <limits.h>
-
-#ifdef CONFIG_INT128
-static inline void mulu64(uint64_t *plow, uint64_t *phigh,
- uint64_t a, uint64_t b)
-{
- __uint128_t r = (__uint128_t)a * b;
- *plow = r;
- *phigh = r >> 64;
-}
-
-static inline void muls64(uint64_t *plow, uint64_t *phigh,
- int64_t a, int64_t b)
-{
- __int128_t r = (__int128_t)a * b;
- *plow = r;
- *phigh = r >> 64;
-}
-#else
-void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
-void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
-#endif
-
-/**
- * clz32 - count leading zeros in a 32-bit value.
- * @val: The value to search
- *
- * Returns 32 if the value is zero. Note that the GCC builtin is
- * undefined if the value is zero.
- */
-static inline int clz32(uint32_t val)
-{
-#if QEMU_GNUC_PREREQ(3, 4)
- return val ? __builtin_clz(val) : 32;
-#else
- /* Binary search for the leading one bit. */
- int cnt = 0;
-
- if (!(val & 0xFFFF0000U)) {
- cnt += 16;
- val <<= 16;
- }
- if (!(val & 0xFF000000U)) {
- cnt += 8;
- val <<= 8;
- }
- if (!(val & 0xF0000000U)) {
- cnt += 4;
- val <<= 4;
- }
- if (!(val & 0xC0000000U)) {
- cnt += 2;
- val <<= 2;
- }
- if (!(val & 0x80000000U)) {
- cnt++;
- val <<= 1;
- }
- if (!(val & 0x80000000U)) {
- cnt++;
- }
- return cnt;
-#endif
-}
-
-/**
- * clo32 - count leading ones in a 32-bit value.
- * @val: The value to search
- *
- * Returns 32 if the value is -1.
- */
-static inline int clo32(uint32_t val)
-{
- return clz32(~val);
-}
-
-/**
- * clz64 - count leading zeros in a 64-bit value.
- * @val: The value to search
- *
- * Returns 64 if the value is zero. Note that the GCC builtin is
- * undefined if the value is zero.
- */
-static inline int clz64(uint64_t val)
-{
-#if QEMU_GNUC_PREREQ(3, 4)
- return val ? __builtin_clzll(val) : 64;
-#else
- int cnt = 0;
-
- if (!(val >> 32)) {
- cnt += 32;
- } else {
- val >>= 32;
- }
-
- return cnt + clz32(val);
-#endif
-}
-
-/**
- * clo64 - count leading ones in a 64-bit value.
- * @val: The value to search
- *
- * Returns 64 if the value is -1.
- */
-static inline int clo64(uint64_t val)
-{
- return clz64(~val);
-}
-
-/**
- * ctz32 - count trailing zeros in a 32-bit value.
- * @val: The value to search
- *
- * Returns 32 if the value is zero. Note that the GCC builtin is
- * undefined if the value is zero.
- */
-static inline int ctz32(uint32_t val)
-{
-#if QEMU_GNUC_PREREQ(3, 4)
- return val ? __builtin_ctz(val) : 32;
-#else
- /* Binary search for the trailing one bit. */
- int cnt;
-
- cnt = 0;
- if (!(val & 0x0000FFFFUL)) {
- cnt += 16;
- val >>= 16;
- }
- if (!(val & 0x000000FFUL)) {
- cnt += 8;
- val >>= 8;
- }
- if (!(val & 0x0000000FUL)) {
- cnt += 4;
- val >>= 4;
- }
- if (!(val & 0x00000003UL)) {
- cnt += 2;
- val >>= 2;
- }
- if (!(val & 0x00000001UL)) {
- cnt++;
- val >>= 1;
- }
- if (!(val & 0x00000001UL)) {
- cnt++;
- }
-
- return cnt;
-#endif
-}
-
-/**
- * cto32 - count trailing ones in a 32-bit value.
- * @val: The value to search
- *
- * Returns 32 if the value is -1.
- */
-static inline int cto32(uint32_t val)
-{
- return ctz32(~val);
-}
-
-/**
- * ctz64 - count trailing zeros in a 64-bit value.
- * @val: The value to search
- *
- * Returns 64 if the value is zero. Note that the GCC builtin is
- * undefined if the value is zero.
- */
-static inline int ctz64(uint64_t val)
-{
-#if QEMU_GNUC_PREREQ(3, 4)
- return val ? __builtin_ctzll(val) : 64;
-#else
- int cnt;
-
- cnt = 0;
- if (!((uint32_t)val)) {
- cnt += 32;
- val >>= 32;
- }
-
- return cnt + ctz32(val);
-#endif
-}
-
-/**
- * ctz64 - count trailing ones in a 64-bit value.
- * @val: The value to search
- *
- * Returns 64 if the value is -1.
- */
-static inline int cto64(uint64_t val)
-{
- return ctz64(~val);
-}
-
-/**
- * ctpop8 - count the population of one bits in an 8-bit value.
- * @val: The value to search
- */
-static inline int ctpop8(uint8_t val)
-{
-#if QEMU_GNUC_PREREQ(3, 4)
- return __builtin_popcount(val);
-#else
- val = (val & 0x55) + ((val >> 1) & 0x55);
- val = (val & 0x33) + ((val >> 2) & 0x33);
- val = (val & 0x0f) + ((val >> 4) & 0x0f);
-
- return val;
-#endif
-}
-
-/**
- * ctpop16 - count the population of one bits in a 16-bit value.
- * @val: The value to search
- */
-static inline int ctpop16(uint16_t val)
-{
-#if QEMU_GNUC_PREREQ(3, 4)
- return __builtin_popcount(val);
-#else
- val = (val & 0x5555) + ((val >> 1) & 0x5555);
- val = (val & 0x3333) + ((val >> 2) & 0x3333);
- val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
- val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
-
- return val;
-#endif
-}
-
-/**
- * ctpop32 - count the population of one bits in a 32-bit value.
- * @val: The value to search
- */
-static inline int ctpop32(uint32_t val)
-{
-#if QEMU_GNUC_PREREQ(3, 4)
- return __builtin_popcount(val);
-#else
- val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
- val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
- val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
- val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff);
- val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
-
- return val;
-#endif
-}
-
-/**
- * ctpop64 - count the population of one bits in a 64-bit value.
- * @val: The value to search
- */
-static inline int ctpop64(uint64_t val)
-{
-#if QEMU_GNUC_PREREQ(3, 4)
- return __builtin_popcountll(val);
-#else
- val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL);
- val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
- val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL);
- val = (val & 0x00ff00ff00ff00ffULL) + ((val >> 8) & 0x00ff00ff00ff00ffULL);
- val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
- val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
-
- return val;
-#endif
-}
-
-/* Host type specific sizes of these routines. */
-
-#if ULONG_MAX == UINT32_MAX
-# define clzl clz32
-# define ctzl ctz32
-# define clol clo32
-# define ctol cto32
-# define ctpopl ctpop32
-#elif ULONG_MAX == UINT64_MAX
-# define clzl clz64
-# define ctzl ctz64
-# define clol clo64
-# define ctol cto64
-# define ctpopl ctpop64
-#else
-# error Unknown sizeof long
-#endif
-
-#endif
diff --git a/contrib/qemu/include/qemu/iov.h b/contrib/qemu/include/qemu/iov.h
deleted file mode 100644
index 68d25f29b76..00000000000
--- a/contrib/qemu/include/qemu/iov.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Helpers for using (partial) iovecs.
- *
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * Author(s):
- * Amit Shah <amit.shah@redhat.com>
- * Michael Tokarev <mjt@tls.msk.ru>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- */
-
-#ifndef IOV_H
-#define IOV_H
-
-#include "qemu-common.h"
-
-/**
- * count and return data size, in bytes, of an iovec
- * starting at `iov' of `iov_cnt' number of elements.
- */
-size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
-
-/**
- * Copy from single continuous buffer to scatter-gather vector of buffers
- * (iovec) and back like memcpy() between two continuous memory regions.
- * Data in single continuous buffer starting at address `buf' and
- * `bytes' bytes long will be copied to/from an iovec `iov' with
- * `iov_cnt' number of elements, starting at byte position `offset'
- * within the iovec. If the iovec does not contain enough space,
- * only part of data will be copied, up to the end of the iovec.
- * Number of bytes actually copied will be returned, which is
- * min(bytes, iov_size(iov)-offset)
- * `Offset' must point to the inside of iovec.
- * It is okay to use very large value for `bytes' since we're
- * limited by the size of the iovec anyway, provided that the
- * buffer pointed to by buf has enough space. One possible
- * such "large" value is -1 (sinice size_t is unsigned),
- * so specifying `-1' as `bytes' means 'up to the end of iovec'.
- */
-size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
- size_t offset, const void *buf, size_t bytes);
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
- size_t offset, void *buf, size_t bytes);
-
-/**
- * Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
- * starting at byte offset `start', to value `fillc', repeating it
- * `bytes' number of times. `Offset' must point to the inside of iovec.
- * If `bytes' is large enough, only last bytes portion of iovec,
- * up to the end of it, will be filled with the specified value.
- * Function return actual number of bytes processed, which is
- * min(size, iov_size(iov) - offset).
- * Again, it is okay to use large value for `bytes' to mean "up to the end".
- */
-size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
- size_t offset, int fillc, size_t bytes);
-
-/*
- * Send/recv data from/to iovec buffers directly
- *
- * `offset' bytes in the beginning of iovec buffer are skipped and
- * next `bytes' bytes are used, which must be within data of iovec.
- *
- * r = iov_send_recv(sockfd, iov, iovcnt, offset, bytes, true);
- *
- * is logically equivalent to
- *
- * char *buf = malloc(bytes);
- * iov_to_buf(iov, iovcnt, offset, buf, bytes);
- * r = send(sockfd, buf, bytes, 0);
- * free(buf);
- *
- * For iov_send_recv() _whole_ area being sent or received
- * should be within the iovec, not only beginning of it.
- */
-ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt,
- size_t offset, size_t bytes, bool do_send);
-#define iov_recv(sockfd, iov, iov_cnt, offset, bytes) \
- iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, false)
-#define iov_send(sockfd, iov, iov_cnt, offset, bytes) \
- iov_send_recv(sockfd, iov, iov_cnt, offset, bytes, true)
-
-/**
- * Produce a text hexdump of iovec `iov' with `iov_cnt' number of elements
- * in file `fp', prefixing each line with `prefix' and processing not more
- * than `limit' data bytes.
- */
-void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
- FILE *fp, const char *prefix, size_t limit);
-
-/*
- * Partial copy of vector from iov to dst_iov (data is not copied).
- * dst_iov overlaps iov at a specified offset.
- * size of dst_iov is at most bytes. dst vector count is returned.
- */
-unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
- const struct iovec *iov, unsigned int iov_cnt,
- size_t offset, size_t bytes);
-
-/*
- * Remove a given number of bytes from the front or back of a vector.
- * This may update iov and/or iov_cnt to exclude iovec elements that are
- * no longer required.
- *
- * The number of bytes actually discarded is returned. This number may be
- * smaller than requested if the vector is too small.
- */
-size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
- size_t bytes);
-size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
- size_t bytes);
-
-#endif
diff --git a/contrib/qemu/include/qemu/main-loop.h b/contrib/qemu/include/qemu/main-loop.h
deleted file mode 100644
index 6f0200a7acc..00000000000
--- a/contrib/qemu/include/qemu/main-loop.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef QEMU_MAIN_LOOP_H
-#define QEMU_MAIN_LOOP_H 1
-
-#include "block/aio.h"
-
-#define SIG_IPI SIGUSR1
-
-/**
- * qemu_init_main_loop: Set up the process so that it can run the main loop.
- *
- * This includes setting up signal handlers. It should be called before
- * any other threads are created. In addition, threads other than the
- * main one should block signals that are trapped by the main loop.
- * For simplicity, you can consider these signals to be safe: SIGUSR1,
- * SIGUSR2, thread signals (SIGFPE, SIGILL, SIGSEGV, SIGBUS) and real-time
- * signals if available. Remember that Windows in practice does not have
- * signals, though.
- *
- * In the case of QEMU tools, this will also start/initialize timers.
- */
-int qemu_init_main_loop(void);
-
-/**
- * main_loop_wait: Run one iteration of the main loop.
- *
- * If @nonblocking is true, poll for events, otherwise suspend until
- * one actually occurs. The main loop usually consists of a loop that
- * repeatedly calls main_loop_wait(false).
- *
- * Main loop services include file descriptor callbacks, bottom halves
- * and timers (defined in qemu-timer.h). Bottom halves are similar to timers
- * that execute immediately, but have a lower overhead and scheduling them
- * is wait-free, thread-safe and signal-safe.
- *
- * It is sometimes useful to put a whole program in a coroutine. In this
- * case, the coroutine actually should be started from within the main loop,
- * so that the main loop can run whenever the coroutine yields. To do this,
- * you can use a bottom half to enter the coroutine as soon as the main loop
- * starts:
- *
- * void enter_co_bh(void *opaque) {
- * QEMUCoroutine *co = opaque;
- * qemu_coroutine_enter(co, NULL);
- * }
- *
- * ...
- * QEMUCoroutine *co = qemu_coroutine_create(coroutine_entry);
- * QEMUBH *start_bh = qemu_bh_new(enter_co_bh, co);
- * qemu_bh_schedule(start_bh);
- * while (...) {
- * main_loop_wait(false);
- * }
- *
- * (In the future we may provide a wrapper for this).
- *
- * @nonblocking: Whether the caller should block until an event occurs.
- */
-int main_loop_wait(int nonblocking);
-
-/**
- * qemu_get_aio_context: Return the main loop's AioContext
- */
-AioContext *qemu_get_aio_context(void);
-
-/**
- * qemu_notify_event: Force processing of pending events.
- *
- * Similar to signaling a condition variable, qemu_notify_event forces
- * main_loop_wait to look at pending events and exit. The caller of
- * main_loop_wait will usually call it again very soon, so qemu_notify_event
- * also has the side effect of recalculating the sets of file descriptors
- * that the main loop waits for.
- *
- * Calling qemu_notify_event is rarely necessary, because main loop
- * services (bottom halves and timers) call it themselves. One notable
- * exception occurs when using qemu_set_fd_handler2 (see below).
- */
-void qemu_notify_event(void);
-
-#ifdef _WIN32
-/* return TRUE if no sleep should be done afterwards */
-typedef int PollingFunc(void *opaque);
-
-/**
- * qemu_add_polling_cb: Register a Windows-specific polling callback
- *
- * Currently, under Windows some events are polled rather than waited for.
- * Polling callbacks do not ensure that @func is called timely, because
- * the main loop might wait for an arbitrarily long time. If possible,
- * you should instead create a separate thread that does a blocking poll
- * and set a Win32 event object. The event can then be passed to
- * qemu_add_wait_object.
- *
- * Polling callbacks really have nothing Windows specific in them, but
- * as they are a hack and are currently not necessary under POSIX systems,
- * they are only available when QEMU is running under Windows.
- *
- * @func: The function that does the polling, and returns 1 to force
- * immediate completion of main_loop_wait.
- * @opaque: A pointer-size value that is passed to @func.
- */
-int qemu_add_polling_cb(PollingFunc *func, void *opaque);
-
-/**
- * qemu_del_polling_cb: Unregister a Windows-specific polling callback
- *
- * This function removes a callback that was registered with
- * qemu_add_polling_cb.
- *
- * @func: The function that was passed to qemu_add_polling_cb.
- * @opaque: A pointer-size value that was passed to qemu_add_polling_cb.
- */
-void qemu_del_polling_cb(PollingFunc *func, void *opaque);
-
-/* Wait objects handling */
-typedef void WaitObjectFunc(void *opaque);
-
-/**
- * qemu_add_wait_object: Register a callback for a Windows handle
- *
- * Under Windows, the iohandler mechanism can only be used with sockets.
- * QEMU must use the WaitForMultipleObjects API to wait on other handles.
- * This function registers a #HANDLE with QEMU, so that it will be included
- * in the main loop's calls to WaitForMultipleObjects. When the handle
- * is in a signaled state, QEMU will call @func.
- *
- * @handle: The Windows handle to be observed.
- * @func: A function to be called when @handle is in a signaled state.
- * @opaque: A pointer-size value that is passed to @func.
- */
-int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
-
-/**
- * qemu_del_wait_object: Unregister a callback for a Windows handle
- *
- * This function removes a callback that was registered with
- * qemu_add_wait_object.
- *
- * @func: The function that was passed to qemu_add_wait_object.
- * @opaque: A pointer-size value that was passed to qemu_add_wait_object.
- */
-void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
-#endif
-
-/* async I/O support */
-
-typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
-typedef int IOCanReadHandler(void *opaque);
-
-/**
- * qemu_set_fd_handler2: Register a file descriptor with the main loop
- *
- * This function tells the main loop to wake up whenever one of the
- * following conditions is true:
- *
- * 1) if @fd_write is not %NULL, when the file descriptor is writable;
- *
- * 2) if @fd_read is not %NULL, when the file descriptor is readable.
- *
- * @fd_read_poll can be used to disable the @fd_read callback temporarily.
- * This is useful to avoid calling qemu_set_fd_handler2 every time the
- * client becomes interested in reading (or dually, stops being interested).
- * A typical example is when @fd is a listening socket and you want to bound
- * the number of active clients. Remember to call qemu_notify_event whenever
- * the condition may change from %false to %true.
- *
- * The callbacks that are set up by qemu_set_fd_handler2 are level-triggered.
- * If @fd_read does not read from @fd, or @fd_write does not write to @fd
- * until its buffers are full, they will be called again on the next
- * iteration.
- *
- * @fd: The file descriptor to be observed. Under Windows it must be
- * a #SOCKET.
- *
- * @fd_read_poll: A function that returns 1 if the @fd_read callback
- * should be fired. If the function returns 0, the main loop will not
- * end its iteration even if @fd becomes readable.
- *
- * @fd_read: A level-triggered callback that is fired if @fd is readable
- * at the beginning of a main loop iteration, or if it becomes readable
- * during one.
- *
- * @fd_write: A level-triggered callback that is fired when @fd is writable
- * at the beginning of a main loop iteration, or if it becomes writable
- * during one.
- *
- * @opaque: A pointer-sized value that is passed to @fd_read_poll,
- * @fd_read and @fd_write.
- */
-int qemu_set_fd_handler2(int fd,
- IOCanReadHandler *fd_read_poll,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque);
-
-/**
- * qemu_set_fd_handler: Register a file descriptor with the main loop
- *
- * This function tells the main loop to wake up whenever one of the
- * following conditions is true:
- *
- * 1) if @fd_write is not %NULL, when the file descriptor is writable;
- *
- * 2) if @fd_read is not %NULL, when the file descriptor is readable.
- *
- * The callbacks that are set up by qemu_set_fd_handler are level-triggered.
- * If @fd_read does not read from @fd, or @fd_write does not write to @fd
- * until its buffers are full, they will be called again on the next
- * iteration.
- *
- * @fd: The file descriptor to be observed. Under Windows it must be
- * a #SOCKET.
- *
- * @fd_read: A level-triggered callback that is fired if @fd is readable
- * at the beginning of a main loop iteration, or if it becomes readable
- * during one.
- *
- * @fd_write: A level-triggered callback that is fired when @fd is writable
- * at the beginning of a main loop iteration, or if it becomes writable
- * during one.
- *
- * @opaque: A pointer-sized value that is passed to @fd_read and @fd_write.
- */
-int qemu_set_fd_handler(int fd,
- IOHandler *fd_read,
- IOHandler *fd_write,
- void *opaque);
-
-#ifdef CONFIG_POSIX
-/**
- * qemu_add_child_watch: Register a child process for reaping.
- *
- * Under POSIX systems, a parent process must read the exit status of
- * its child processes using waitpid, or the operating system will not
- * free some of the resources attached to that process.
- *
- * This function directs the QEMU main loop to observe a child process
- * and call waitpid as soon as it exits; the watch is then removed
- * automatically. It is useful whenever QEMU forks a child process
- * but will find out about its termination by other means such as a
- * "broken pipe".
- *
- * @pid: The pid that QEMU should observe.
- */
-int qemu_add_child_watch(pid_t pid);
-#endif
-
-/**
- * qemu_mutex_lock_iothread: Lock the main loop mutex.
- *
- * This function locks the main loop mutex. The mutex is taken by
- * qemu_init_main_loop and always taken except while waiting on
- * external events (such as with select). The mutex should be taken
- * by threads other than the main loop thread when calling
- * qemu_bh_new(), qemu_set_fd_handler() and basically all other
- * functions documented in this file.
- *
- * NOTE: tools currently are single-threaded and qemu_mutex_lock_iothread
- * is a no-op there.
- */
-void qemu_mutex_lock_iothread(void);
-
-/**
- * qemu_mutex_unlock_iothread: Unlock the main loop mutex.
- *
- * This function unlocks the main loop mutex. The mutex is taken by
- * qemu_init_main_loop and always taken except while waiting on
- * external events (such as with select). The mutex should be unlocked
- * as soon as possible by threads other than the main loop thread,
- * because it prevents the main loop from processing callbacks,
- * including timers and bottom halves.
- *
- * NOTE: tools currently are single-threaded and qemu_mutex_unlock_iothread
- * is a no-op there.
- */
-void qemu_mutex_unlock_iothread(void);
-
-/* internal interfaces */
-
-void qemu_fd_register(int fd);
-void qemu_iohandler_fill(GArray *pollfds);
-void qemu_iohandler_poll(GArray *pollfds, int rc);
-
-QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
-void qemu_bh_schedule_idle(QEMUBH *bh);
-
-#endif
diff --git a/contrib/qemu/include/qemu/module.h b/contrib/qemu/include/qemu/module.h
deleted file mode 100644
index c4ccd571664..00000000000
--- a/contrib/qemu/include/qemu/module.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * QEMU Module Infrastructure
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_MODULE_H
-#define QEMU_MODULE_H
-
-/* This should not be used directly. Use block_init etc. instead. */
-#define module_init(function, type) \
-static void __attribute__((constructor)) do_qemu_init_ ## function(void) { \
- register_module_init(function, type); \
-}
-
-typedef enum {
- MODULE_INIT_BLOCK,
- MODULE_INIT_MACHINE,
- MODULE_INIT_QAPI,
- MODULE_INIT_QOM,
- MODULE_INIT_MAX
-} module_init_type;
-
-#define block_init(function) module_init(function, MODULE_INIT_BLOCK)
-#define machine_init(function) module_init(function, MODULE_INIT_MACHINE)
-#define qapi_init(function) module_init(function, MODULE_INIT_QAPI)
-#define type_init(function) module_init(function, MODULE_INIT_QOM)
-
-void register_module_init(void (*fn)(void), module_init_type type);
-
-void module_call_init(module_init_type type);
-
-#endif
diff --git a/contrib/qemu/include/qemu/notify.h b/contrib/qemu/include/qemu/notify.h
deleted file mode 100644
index a3d73e4bc76..00000000000
--- a/contrib/qemu/include/qemu/notify.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Notifier lists
- *
- * Copyright IBM, Corp. 2010
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef QEMU_NOTIFY_H
-#define QEMU_NOTIFY_H
-
-#include "qemu/queue.h"
-
-typedef struct Notifier Notifier;
-
-struct Notifier
-{
- void (*notify)(Notifier *notifier, void *data);
- QLIST_ENTRY(Notifier) node;
-};
-
-typedef struct NotifierList
-{
- QLIST_HEAD(, Notifier) notifiers;
-} NotifierList;
-
-#define NOTIFIER_LIST_INITIALIZER(head) \
- { QLIST_HEAD_INITIALIZER((head).notifiers) }
-
-void notifier_list_init(NotifierList *list);
-
-void notifier_list_add(NotifierList *list, Notifier *notifier);
-
-void notifier_remove(Notifier *notifier);
-
-void notifier_list_notify(NotifierList *list, void *data);
-
-/* Same as Notifier but allows .notify() to return errors */
-typedef struct NotifierWithReturn NotifierWithReturn;
-
-struct NotifierWithReturn {
- /**
- * Return 0 on success (next notifier will be invoked), otherwise
- * notifier_with_return_list_notify() will stop and return the value.
- */
- int (*notify)(NotifierWithReturn *notifier, void *data);
- QLIST_ENTRY(NotifierWithReturn) node;
-};
-
-typedef struct NotifierWithReturnList {
- QLIST_HEAD(, NotifierWithReturn) notifiers;
-} NotifierWithReturnList;
-
-#define NOTIFIER_WITH_RETURN_LIST_INITIALIZER(head) \
- { QLIST_HEAD_INITIALIZER((head).notifiers) }
-
-void notifier_with_return_list_init(NotifierWithReturnList *list);
-
-void notifier_with_return_list_add(NotifierWithReturnList *list,
- NotifierWithReturn *notifier);
-
-void notifier_with_return_remove(NotifierWithReturn *notifier);
-
-int notifier_with_return_list_notify(NotifierWithReturnList *list,
- void *data);
-
-#endif
diff --git a/contrib/qemu/include/qemu/option.h b/contrib/qemu/include/qemu/option.h
deleted file mode 100644
index a83c700323e..00000000000
--- a/contrib/qemu/include/qemu/option.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Commandline option parsing functions
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef QEMU_OPTIONS_H
-#define QEMU_OPTIONS_H
-
-#include <stdint.h>
-#include "qemu/queue.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qdict.h"
-
-enum QEMUOptionParType {
- OPT_FLAG,
- OPT_NUMBER,
- OPT_SIZE,
- OPT_STRING,
-};
-
-typedef struct QEMUOptionParameter {
- const char *name;
- enum QEMUOptionParType type;
- union {
- uint64_t n;
- char* s;
- } value;
- const char *help;
-} QEMUOptionParameter;
-
-
-const char *get_opt_name(char *buf, int buf_size, const char *p, char delim);
-const char *get_opt_value(char *buf, int buf_size, const char *p);
-int get_next_param_value(char *buf, int buf_size,
- const char *tag, const char **pstr);
-int get_param_value(char *buf, int buf_size,
- const char *tag, const char *str);
-
-
-/*
- * The following functions take a parameter list as input. This is a pointer to
- * the first element of a QEMUOptionParameter array which is terminated by an
- * entry with entry->name == NULL.
- */
-
-QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
- const char *name);
-int set_option_parameter(QEMUOptionParameter *list, const char *name,
- const char *value);
-int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
- uint64_t value);
-QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
- QEMUOptionParameter *list);
-QEMUOptionParameter *parse_option_parameters(const char *param,
- QEMUOptionParameter *list, QEMUOptionParameter *dest);
-void free_option_parameters(QEMUOptionParameter *list);
-void print_option_parameters(QEMUOptionParameter *list);
-void print_option_help(QEMUOptionParameter *list);
-
-/* ------------------------------------------------------------------ */
-
-typedef struct QemuOpt QemuOpt;
-typedef struct QemuOpts QemuOpts;
-typedef struct QemuOptsList QemuOptsList;
-
-enum QemuOptType {
- QEMU_OPT_STRING = 0, /* no parsing (use string as-is) */
- QEMU_OPT_BOOL, /* on/off */
- QEMU_OPT_NUMBER, /* simple number */
- QEMU_OPT_SIZE, /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
-};
-
-typedef struct QemuOptDesc {
- const char *name;
- enum QemuOptType type;
- const char *help;
-} QemuOptDesc;
-
-struct QemuOptsList {
- const char *name;
- const char *implied_opt_name;
- bool merge_lists; /* Merge multiple uses of option into a single list? */
- QTAILQ_HEAD(, QemuOpts) head;
- QemuOptDesc desc[];
-};
-
-const char *qemu_opt_get(QemuOpts *opts, const char *name);
-/**
- * qemu_opt_has_help_opt:
- * @opts: options to search for a help request
- *
- * Check whether the options specified by @opts include one of the
- * standard strings which indicate that the user is asking for a
- * list of the valid values for a command line option (as defined
- * by is_help_option()).
- *
- * Returns: true if @opts includes 'help' or equivalent.
- */
-bool qemu_opt_has_help_opt(QemuOpts *opts);
-bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval);
-uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
-uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
-int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
-void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
- Error **errp);
-int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val);
-int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val);
-typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque);
-int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
- int abort_on_failure);
-
-QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id);
-QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
- int fail_if_exists, Error **errp);
-QemuOpts *qemu_opts_create_nofail(QemuOptsList *list);
-void qemu_opts_reset(QemuOptsList *list);
-void qemu_opts_loc_restore(QemuOpts *opts);
-int qemu_opts_set(QemuOptsList *list, const char *id,
- const char *name, const char *value);
-const char *qemu_opts_id(QemuOpts *opts);
-void qemu_opts_del(QemuOpts *opts);
-void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
-int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
-QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int permit_abbrev);
-void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
- int permit_abbrev);
-QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
- Error **errp);
-QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
-void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
-
-typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
-int qemu_opts_print(QemuOpts *opts, void *dummy);
-int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
- int abort_on_failure);
-
-#endif
diff --git a/contrib/qemu/include/qemu/option_int.h b/contrib/qemu/include/qemu/option_int.h
deleted file mode 100644
index 8212fa4a485..00000000000
--- a/contrib/qemu/include/qemu/option_int.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Commandline option parsing functions
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef QEMU_OPTIONS_INTERNAL_H
-#define QEMU_OPTIONS_INTERNAL_H
-
-#include "qemu/option.h"
-#include "qemu/error-report.h"
-
-struct QemuOpt {
- const char *name;
- const char *str;
-
- const QemuOptDesc *desc;
- union {
- bool boolean;
- uint64_t uint;
- } value;
-
- QemuOpts *opts;
- QTAILQ_ENTRY(QemuOpt) next;
-};
-
-struct QemuOpts {
- char *id;
- QemuOptsList *list;
- Location loc;
- QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
- QTAILQ_ENTRY(QemuOpts) next;
-};
-
-#endif
diff --git a/contrib/qemu/include/qemu/osdep.h b/contrib/qemu/include/qemu/osdep.h
deleted file mode 100644
index 26136f16ecd..00000000000
--- a/contrib/qemu/include/qemu/osdep.h
+++ /dev/null
@@ -1,218 +0,0 @@
-#ifndef QEMU_OSDEP_H
-#define QEMU_OSDEP_H
-
-#include "config-host.h"
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#ifdef __OpenBSD__
-#include <sys/signal.h>
-#endif
-
-#ifndef _WIN32
-#include <sys/wait.h>
-#else
-#define WIFEXITED(x) 1
-#define WEXITSTATUS(x) (x)
-#endif
-
-#include <sys/time.h>
-
-#if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10
-/* [u]int_fast*_t not in <sys/int_types.h> */
-typedef unsigned char uint_fast8_t;
-typedef unsigned int uint_fast16_t;
-typedef signed int int_fast16_t;
-#endif
-
-#ifndef glue
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-#endif
-
-#ifndef likely
-#if __GNUC__ < 3
-#define __builtin_expect(x, n) (x)
-#endif
-
-#define likely(x) __builtin_expect(!!(x), 1)
-#define unlikely(x) __builtin_expect(!!(x), 0)
-#endif
-
-#ifndef container_of
-#define container_of(ptr, type, member) ({ \
- const typeof(((type *) 0)->member) *__mptr = (ptr); \
- (type *) ((char *) __mptr - offsetof(type, member));})
-#endif
-
-/* Convert from a base type to a parent type, with compile time checking. */
-#ifdef __GNUC__
-#define DO_UPCAST(type, field, dev) ( __extension__ ( { \
- char __attribute__((unused)) offset_must_be_zero[ \
- -offsetof(type, field)]; \
- container_of(dev, type, field);}))
-#else
-#define DO_UPCAST(type, field, dev) container_of(dev, type, field)
-#endif
-
-#define typeof_field(type, field) typeof(((type *)0)->field)
-#define type_check(t1,t2) ((t1*)0 - (t2*)0)
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef ROUND_UP
-#define ROUND_UP(n,d) (((n) + (d) - 1) & -(d))
-#endif
-
-#ifndef DIV_ROUND_UP
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-#endif
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-#endif
-
-#ifndef always_inline
-#if !((__GNUC__ < 3) || defined(__APPLE__))
-#ifdef __OPTIMIZE__
-#undef inline
-#define inline __attribute__ (( always_inline )) __inline__
-#endif
-#endif
-#else
-#undef inline
-#define inline always_inline
-#endif
-
-#define qemu_printf printf
-
-int qemu_daemon(int nochdir, int noclose);
-void *qemu_memalign(size_t alignment, size_t size);
-void *qemu_anon_ram_alloc(size_t size);
-void qemu_vfree(void *ptr);
-void qemu_anon_ram_free(void *ptr, size_t size);
-
-#define QEMU_MADV_INVALID -1
-
-#if defined(CONFIG_MADVISE)
-
-#define QEMU_MADV_WILLNEED MADV_WILLNEED
-#define QEMU_MADV_DONTNEED MADV_DONTNEED
-#ifdef MADV_DONTFORK
-#define QEMU_MADV_DONTFORK MADV_DONTFORK
-#else
-#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
-#endif
-#ifdef MADV_MERGEABLE
-#define QEMU_MADV_MERGEABLE MADV_MERGEABLE
-#else
-#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
-#endif
-#ifdef MADV_DONTDUMP
-#define QEMU_MADV_DONTDUMP MADV_DONTDUMP
-#else
-#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
-#endif
-#ifdef MADV_HUGEPAGE
-#define QEMU_MADV_HUGEPAGE MADV_HUGEPAGE
-#else
-#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID
-#endif
-
-#elif defined(CONFIG_POSIX_MADVISE)
-
-#define QEMU_MADV_WILLNEED POSIX_MADV_WILLNEED
-#define QEMU_MADV_DONTNEED POSIX_MADV_DONTNEED
-#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
-#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
-#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
-#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID
-
-#else /* no-op */
-
-#define QEMU_MADV_WILLNEED QEMU_MADV_INVALID
-#define QEMU_MADV_DONTNEED QEMU_MADV_INVALID
-#define QEMU_MADV_DONTFORK QEMU_MADV_INVALID
-#define QEMU_MADV_MERGEABLE QEMU_MADV_INVALID
-#define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
-#define QEMU_MADV_HUGEPAGE QEMU_MADV_INVALID
-
-#endif
-
-int qemu_madvise(void *addr, size_t len, int advice);
-
-int qemu_open(const char *name, int flags, ...);
-int qemu_close(int fd);
-
-#if defined(__HAIKU__) && defined(__i386__)
-#define FMT_pid "%ld"
-#elif defined(WIN64)
-#define FMT_pid "%" PRId64
-#else
-#define FMT_pid "%d"
-#endif
-
-int qemu_create_pidfile(const char *filename);
-int qemu_get_thread_id(void);
-
-#ifndef CONFIG_IOVEC
-struct iovec {
- void *iov_base;
- size_t iov_len;
-};
-/*
- * Use the same value as Linux for now.
- */
-#define IOV_MAX 1024
-
-ssize_t readv(int fd, const struct iovec *iov, int iov_cnt);
-ssize_t writev(int fd, const struct iovec *iov, int iov_cnt);
-#else
-#include <sys/uio.h>
-#endif
-
-#ifdef _WIN32
-static inline void qemu_timersub(const struct timeval *val1,
- const struct timeval *val2,
- struct timeval *res)
-{
- res->tv_sec = val1->tv_sec - val2->tv_sec;
- if (val1->tv_usec < val2->tv_usec) {
- res->tv_sec--;
- res->tv_usec = val1->tv_usec - val2->tv_usec + 1000 * 1000;
- } else {
- res->tv_usec = val1->tv_usec - val2->tv_usec;
- }
-}
-#else
-#define qemu_timersub timersub
-#endif
-
-void qemu_set_cloexec(int fd);
-
-void qemu_set_version(const char *);
-const char *qemu_get_version(void);
-
-void fips_set_state(bool requested);
-bool fips_get_state(void);
-
-/* Return a dynamically allocated pathname denoting a file or directory that is
- * appropriate for storing local state.
- *
- * @relative_pathname need not start with a directory separator; one will be
- * added automatically.
- *
- * The caller is responsible for releasing the value returned with g_free()
- * after use.
- */
-char *qemu_get_local_state_pathname(const char *relative_pathname);
-
-#endif
diff --git a/contrib/qemu/include/qemu/queue.h b/contrib/qemu/include/qemu/queue.h
deleted file mode 100644
index d433b9017ce..00000000000
--- a/contrib/qemu/include/qemu/queue.h
+++ /dev/null
@@ -1,414 +0,0 @@
-/* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
-
-/*
- * QEMU version: Copy from netbsd, removed debug code, removed some of
- * the implementations. Left in singly-linked lists, lists, simple
- * queues, and tail queues.
- */
-
-/*
- * Copyright (c) 1991, 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. 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.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- */
-
-#ifndef QEMU_SYS_QUEUE_H_
-#define QEMU_SYS_QUEUE_H_
-
-/*
- * This file defines four types of data structures: singly-linked lists,
- * lists, simple queues, and tail queues.
- *
- * A singly-linked list is headed by a single forward pointer. The
- * elements are singly linked for minimum space and pointer manipulation
- * overhead at the expense of O(n) removal for arbitrary elements. New
- * elements can be added to the list after an existing element or at the
- * head of the list. Elements being removed from the head of the list
- * should use the explicit macro for this purpose for optimum
- * efficiency. A singly-linked list may only be traversed in the forward
- * direction. Singly-linked lists are ideal for applications with large
- * datasets and few or no removals or for implementing a LIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A simple queue is headed by a pair of pointers, one the head of the
- * list and the other to the tail of the list. The elements are singly
- * linked to save space, so elements can only be removed from the
- * head of the list. New elements can be added to the list after
- * an existing element, at the head of the list, or at the end of the
- * list. A simple queue may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-#include "qemu/atomic.h" /* for smp_wmb() */
-
-/*
- * List definitions.
- */
-#define QLIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define QLIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define QLIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List functions.
- */
-#define QLIST_INIT(head) do { \
- (head)->lh_first = NULL; \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_INSERT_AFTER(listelm, elm, field) do { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- (elm)->field.le_next = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &(elm)->field.le_next; \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_INSERT_HEAD_RCU(head, elm, field) do { \
- (elm)->field.le_prev = &(head)->lh_first; \
- (elm)->field.le_next = (head)->lh_first; \
- smp_wmb(); /* fill elm before linking it */ \
- if ((head)->lh_first != NULL) { \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next; \
- } \
- (head)->lh_first = (elm); \
- smp_wmb(); \
-} while (/* CONSTCOND*/0)
-
-#define QLIST_REMOVE(elm, field) do { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_FOREACH(var, head, field) \
- for ((var) = ((head)->lh_first); \
- (var); \
- (var) = ((var)->field.le_next))
-
-#define QLIST_FOREACH_SAFE(var, head, field, next_var) \
- for ((var) = ((head)->lh_first); \
- (var) && ((next_var) = ((var)->field.le_next), 1); \
- (var) = (next_var))
-
-/*
- * List access methods.
- */
-#define QLIST_EMPTY(head) ((head)->lh_first == NULL)
-#define QLIST_FIRST(head) ((head)->lh_first)
-#define QLIST_NEXT(elm, field) ((elm)->field.le_next)
-
-
-/*
- * Singly-linked List definitions.
- */
-#define QSLIST_HEAD(name, type) \
-struct name { \
- struct type *slh_first; /* first element */ \
-}
-
-#define QSLIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define QSLIST_ENTRY(type) \
-struct { \
- struct type *sle_next; /* next element */ \
-}
-
-/*
- * Singly-linked List functions.
- */
-#define QSLIST_INIT(head) do { \
- (head)->slh_first = NULL; \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_INSERT_AFTER(slistelm, elm, field) do { \
- (elm)->field.sle_next = (slistelm)->field.sle_next; \
- (slistelm)->field.sle_next = (elm); \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.sle_next = (head)->slh_first; \
- (head)->slh_first = (elm); \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_REMOVE_HEAD(head, field) do { \
- (head)->slh_first = (head)->slh_first->field.sle_next; \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_REMOVE_AFTER(slistelm, field) do { \
- (slistelm)->field.sle_next = \
- QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_FOREACH(var, head, field) \
- for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
-
-#define QSLIST_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = QSLIST_FIRST((head)); \
- (var) && ((tvar) = QSLIST_NEXT((var), field), 1); \
- (var) = (tvar))
-
-/*
- * Singly-linked List access methods.
- */
-#define QSLIST_EMPTY(head) ((head)->slh_first == NULL)
-#define QSLIST_FIRST(head) ((head)->slh_first)
-#define QSLIST_NEXT(elm, field) ((elm)->field.sle_next)
-
-
-/*
- * Simple queue definitions.
- */
-#define QSIMPLEQ_HEAD(name, type) \
-struct name { \
- struct type *sqh_first; /* first element */ \
- struct type **sqh_last; /* addr of last next element */ \
-}
-
-#define QSIMPLEQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).sqh_first }
-
-#define QSIMPLEQ_ENTRY(type) \
-struct { \
- struct type *sqe_next; /* next element */ \
-}
-
-/*
- * Simple queue functions.
- */
-#define QSIMPLEQ_INIT(head) do { \
- (head)->sqh_first = NULL; \
- (head)->sqh_last = &(head)->sqh_first; \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
- (head)->sqh_last = &(elm)->field.sqe_next; \
- (head)->sqh_first = (elm); \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.sqe_next = NULL; \
- *(head)->sqh_last = (elm); \
- (head)->sqh_last = &(elm)->field.sqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \
- (head)->sqh_last = &(elm)->field.sqe_next; \
- (listelm)->field.sqe_next = (elm); \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_REMOVE_HEAD(head, field) do { \
- if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\
- (head)->sqh_last = &(head)->sqh_first; \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \
- if ((head)->sqh_first == (elm)) { \
- QSIMPLEQ_REMOVE_HEAD((head), field); \
- } else { \
- struct type *curelm = (head)->sqh_first; \
- while (curelm->field.sqe_next != (elm)) \
- curelm = curelm->field.sqe_next; \
- if ((curelm->field.sqe_next = \
- curelm->field.sqe_next->field.sqe_next) == NULL) \
- (head)->sqh_last = &(curelm)->field.sqe_next; \
- } \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_FOREACH(var, head, field) \
- for ((var) = ((head)->sqh_first); \
- (var); \
- (var) = ((var)->field.sqe_next))
-
-#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \
- for ((var) = ((head)->sqh_first); \
- (var) && ((next = ((var)->field.sqe_next)), 1); \
- (var) = (next))
-
-#define QSIMPLEQ_CONCAT(head1, head2) do { \
- if (!QSIMPLEQ_EMPTY((head2))) { \
- *(head1)->sqh_last = (head2)->sqh_first; \
- (head1)->sqh_last = (head2)->sqh_last; \
- QSIMPLEQ_INIT((head2)); \
- } \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_LAST(head, type, field) \
- (QSIMPLEQ_EMPTY((head)) ? \
- NULL : \
- ((struct type *)(void *) \
- ((char *)((head)->sqh_last) - offsetof(struct type, field))))
-
-/*
- * Simple queue access methods.
- */
-#define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
-#define QSIMPLEQ_FIRST(head) ((head)->sqh_first)
-#define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
-
-
-/*
- * Tail queue definitions.
- */
-#define Q_TAILQ_HEAD(name, type, qual) \
-struct name { \
- qual type *tqh_first; /* first element */ \
- qual type *qual *tqh_last; /* addr of last next element */ \
-}
-#define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type,)
-
-#define QTAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).tqh_first }
-
-#define Q_TAILQ_ENTRY(type, qual) \
-struct { \
- qual type *tqe_next; /* next element */ \
- qual type *qual *tqe_prev; /* address of previous next element */\
-}
-#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type,)
-
-/*
- * Tail queue functions.
- */
-#define QTAILQ_INIT(head) do { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (head)->tqh_first->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
- (elm)->field.tqe_next = (listelm); \
- *(listelm)->field.tqe_prev = (elm); \
- (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_REMOVE(head, elm, field) do { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_FOREACH(var, head, field) \
- for ((var) = ((head)->tqh_first); \
- (var); \
- (var) = ((var)->field.tqe_next))
-
-#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \
- for ((var) = ((head)->tqh_first); \
- (var) && ((next_var) = ((var)->field.tqe_next), 1); \
- (var) = (next_var))
-
-#define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \
- for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
- (var); \
- (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
-
-/*
- * Tail queue access methods.
- */
-#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL)
-#define QTAILQ_FIRST(head) ((head)->tqh_first)
-#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-
-#define QTAILQ_LAST(head, headname) \
- (*(((struct headname *)((head)->tqh_last))->tqh_last))
-#define QTAILQ_PREV(elm, headname, field) \
- (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-#endif /* !QEMU_SYS_QUEUE_H_ */
diff --git a/contrib/qemu/include/qemu/sockets.h b/contrib/qemu/include/qemu/sockets.h
deleted file mode 100644
index c5174d76a70..00000000000
--- a/contrib/qemu/include/qemu/sockets.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* headers to use the BSD sockets */
-#ifndef QEMU_SOCKET_H
-#define QEMU_SOCKET_H
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#define socket_error() WSAGetLastError()
-
-int inet_aton(const char *cp, struct in_addr *ia);
-
-#else
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/un.h>
-
-#define socket_error() errno
-#define closesocket(s) close(s)
-
-#endif /* !_WIN32 */
-
-#include "qemu/option.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qerror.h"
-
-extern QemuOptsList socket_optslist;
-
-/* misc helpers */
-int qemu_socket(int domain, int type, int protocol);
-int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
-int socket_set_cork(int fd, int v);
-int socket_set_nodelay(int fd);
-void qemu_set_block(int fd);
-void qemu_set_nonblock(int fd);
-int send_all(int fd, const void *buf, int len1);
-int recv_all(int fd, void *buf, int len1, bool single_read);
-
-/* callback function for nonblocking connect
- * valid fd on success, negative error code on failure
- */
-typedef void NonBlockingConnectHandler(int fd, void *opaque);
-
-InetSocketAddress *inet_parse(const char *str, Error **errp);
-int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp);
-int inet_listen(const char *str, char *ostr, int olen,
- int socktype, int port_offset, Error **errp);
-int inet_connect_opts(QemuOpts *opts, Error **errp,
- NonBlockingConnectHandler *callback, void *opaque);
-int inet_connect(const char *str, Error **errp);
-int inet_nonblocking_connect(const char *str,
- NonBlockingConnectHandler *callback,
- void *opaque, Error **errp);
-
-int inet_dgram_opts(QemuOpts *opts, Error **errp);
-const char *inet_strfamily(int family);
-
-int unix_listen_opts(QemuOpts *opts, Error **errp);
-int unix_listen(const char *path, char *ostr, int olen, Error **errp);
-int unix_connect_opts(QemuOpts *opts, Error **errp,
- NonBlockingConnectHandler *callback, void *opaque);
-int unix_connect(const char *path, Error **errp);
-int unix_nonblocking_connect(const char *str,
- NonBlockingConnectHandler *callback,
- void *opaque, Error **errp);
-
-SocketAddress *socket_parse(const char *str, Error **errp);
-int socket_connect(SocketAddress *addr, Error **errp,
- NonBlockingConnectHandler *callback, void *opaque);
-int socket_listen(SocketAddress *addr, Error **errp);
-int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp);
-
-/* Old, ipv4 only bits. Don't use for new code. */
-int parse_host_port(struct sockaddr_in *saddr, const char *str);
-int socket_init(void);
-
-#endif /* QEMU_SOCKET_H */
diff --git a/contrib/qemu/include/qemu/thread-posix.h b/contrib/qemu/include/qemu/thread-posix.h
deleted file mode 100644
index 0f30dccb53c..00000000000
--- a/contrib/qemu/include/qemu/thread-posix.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef __QEMU_THREAD_POSIX_H
-#define __QEMU_THREAD_POSIX_H 1
-#include "pthread.h"
-#include <semaphore.h>
-
-struct QemuMutex {
- pthread_mutex_t lock;
-};
-
-struct QemuCond {
- pthread_cond_t cond;
-};
-
-struct QemuSemaphore {
-#if defined(__APPLE__) || defined(__NetBSD__)
- pthread_mutex_t lock;
- pthread_cond_t cond;
- int count;
-#else
- sem_t sem;
-#endif
-};
-
-struct QemuThread {
- pthread_t thread;
-};
-
-#endif
diff --git a/contrib/qemu/include/qemu/thread.h b/contrib/qemu/include/qemu/thread.h
deleted file mode 100644
index c02404b9fbf..00000000000
--- a/contrib/qemu/include/qemu/thread.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __QEMU_THREAD_H
-#define __QEMU_THREAD_H 1
-
-#include <inttypes.h>
-#include <stdbool.h>
-
-typedef struct QemuMutex QemuMutex;
-typedef struct QemuCond QemuCond;
-typedef struct QemuSemaphore QemuSemaphore;
-typedef struct QemuThread QemuThread;
-
-#ifdef _WIN32
-#include "qemu/thread-win32.h"
-#else
-#include "qemu/thread-posix.h"
-#endif
-
-#define QEMU_THREAD_JOINABLE 0
-#define QEMU_THREAD_DETACHED 1
-
-void qemu_mutex_init(QemuMutex *mutex);
-void qemu_mutex_destroy(QemuMutex *mutex);
-void qemu_mutex_lock(QemuMutex *mutex);
-int qemu_mutex_trylock(QemuMutex *mutex);
-void qemu_mutex_unlock(QemuMutex *mutex);
-
-#define rcu_read_lock() do { } while (0)
-#define rcu_read_unlock() do { } while (0)
-
-void qemu_cond_init(QemuCond *cond);
-void qemu_cond_destroy(QemuCond *cond);
-
-/*
- * IMPORTANT: The implementation does not guarantee that pthread_cond_signal
- * and pthread_cond_broadcast can be called except while the same mutex is
- * held as in the corresponding pthread_cond_wait calls!
- */
-void qemu_cond_signal(QemuCond *cond);
-void qemu_cond_broadcast(QemuCond *cond);
-void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex);
-
-void qemu_sem_init(QemuSemaphore *sem, int init);
-void qemu_sem_post(QemuSemaphore *sem);
-void qemu_sem_wait(QemuSemaphore *sem);
-int qemu_sem_timedwait(QemuSemaphore *sem, int ms);
-void qemu_sem_destroy(QemuSemaphore *sem);
-
-void qemu_thread_create(QemuThread *thread,
- void *(*start_routine)(void *),
- void *arg, int mode);
-void *qemu_thread_join(QemuThread *thread);
-void qemu_thread_get_self(QemuThread *thread);
-bool qemu_thread_is_self(QemuThread *thread);
-void qemu_thread_exit(void *retval);
-
-#endif
diff --git a/contrib/qemu/include/qemu/timer.h b/contrib/qemu/include/qemu/timer.h
deleted file mode 100644
index 9dd206ce7f4..00000000000
--- a/contrib/qemu/include/qemu/timer.h
+++ /dev/null
@@ -1,305 +0,0 @@
-#ifndef QEMU_TIMER_H
-#define QEMU_TIMER_H
-
-#include "qemu-common.h"
-#include "qemu/main-loop.h"
-#include "qemu/notify.h"
-
-/* timers */
-
-#define SCALE_MS 1000000
-#define SCALE_US 1000
-#define SCALE_NS 1
-
-typedef struct QEMUClock QEMUClock;
-typedef void QEMUTimerCB(void *opaque);
-
-/* The real time clock should be used only for stuff which does not
- change the virtual machine state, as it is run even if the virtual
- machine is stopped. The real time clock has a frequency of 1000
- Hz. */
-extern QEMUClock *rt_clock;
-
-/* The virtual clock is only run during the emulation. It is stopped
- when the virtual machine is stopped. Virtual timers use a high
- precision clock, usually cpu cycles (use ticks_per_sec). */
-extern QEMUClock *vm_clock;
-
-/* The host clock should be use for device models that emulate accurate
- real time sources. It will continue to run when the virtual machine
- is suspended, and it will reflect system time changes the host may
- undergo (e.g. due to NTP). The host clock has the same precision as
- the virtual clock. */
-extern QEMUClock *host_clock;
-
-int64_t qemu_get_clock_ns(QEMUClock *clock);
-int64_t qemu_clock_has_timers(QEMUClock *clock);
-int64_t qemu_clock_expired(QEMUClock *clock);
-int64_t qemu_clock_deadline(QEMUClock *clock);
-void qemu_clock_enable(QEMUClock *clock, bool enabled);
-void qemu_clock_warp(QEMUClock *clock);
-
-void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier);
-void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
- Notifier *notifier);
-
-QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
- QEMUTimerCB *cb, void *opaque);
-void qemu_free_timer(QEMUTimer *ts);
-void qemu_del_timer(QEMUTimer *ts);
-void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
-bool qemu_timer_pending(QEMUTimer *ts);
-bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
-uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts);
-
-void qemu_run_timers(QEMUClock *clock);
-void qemu_run_all_timers(void);
-void configure_alarms(char const *opt);
-void init_clocks(void);
-int init_timer_alarm(void);
-
-int64_t cpu_get_ticks(void);
-void cpu_enable_ticks(void);
-void cpu_disable_ticks(void);
-
-static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
- void *opaque)
-{
- return qemu_new_timer(clock, SCALE_NS, cb, opaque);
-}
-
-static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock, QEMUTimerCB *cb,
- void *opaque)
-{
- return qemu_new_timer(clock, SCALE_MS, cb, opaque);
-}
-
-static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
-{
- return qemu_get_clock_ns(clock) / SCALE_MS;
-}
-
-static inline int64_t get_ticks_per_sec(void)
-{
- return 1000000000LL;
-}
-
-/* real time host monotonic timer */
-static inline int64_t get_clock_realtime(void)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
-}
-
-/* Warning: don't insert tracepoints into these functions, they are
- also used by simpletrace backend and tracepoints would cause
- an infinite recursion! */
-#ifdef _WIN32
-extern int64_t clock_freq;
-
-static inline int64_t get_clock(void)
-{
- LARGE_INTEGER ti;
- QueryPerformanceCounter(&ti);
- return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
-}
-
-#else
-
-extern int use_rt_clock;
-
-static inline int64_t get_clock(void)
-{
-#ifdef CLOCK_MONOTONIC
- if (use_rt_clock) {
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return ts.tv_sec * 1000000000LL + ts.tv_nsec;
- } else
-#endif
- {
- /* XXX: using gettimeofday leads to problems if the date
- changes, so it should be avoided. */
- return get_clock_realtime();
- }
-}
-#endif
-
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
-
-/* icount */
-int64_t cpu_get_icount(void);
-int64_t cpu_get_clock(void);
-
-/*******************************************/
-/* host CPU ticks (if available) */
-
-#if defined(_ARCH_PPC)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t retval;
-#ifdef _ARCH_PPC64
- /* This reads timebase in one 64bit go and includes Cell workaround from:
- http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
- */
- __asm__ __volatile__ ("mftb %0\n\t"
- "cmpwi %0,0\n\t"
- "beq- $-8"
- : "=r" (retval));
-#else
- /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
- unsigned long junk;
- __asm__ __volatile__ ("mfspr %1,269\n\t" /* mftbu */
- "mfspr %L0,268\n\t" /* mftb */
- "mfspr %0,269\n\t" /* mftbu */
- "cmpw %0,%1\n\t"
- "bne $-16"
- : "=r" (retval), "=r" (junk));
-#endif
- return retval;
-}
-
-#elif defined(__i386__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("rdtsc" : "=A" (val));
- return val;
-}
-
-#elif defined(__x86_64__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- uint32_t low,high;
- int64_t val;
- asm volatile("rdtsc" : "=a" (low), "=d" (high));
- val = high;
- val <<= 32;
- val |= low;
- return val;
-}
-
-#elif defined(__hppa__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int val;
- asm volatile ("mfctl %%cr16, %0" : "=r"(val));
- return val;
-}
-
-#elif defined(__ia64)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
- return val;
-}
-
-#elif defined(__s390__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
- return val;
-}
-
-#elif defined(__sparc__)
-
-static inline int64_t cpu_get_real_ticks (void)
-{
-#if defined(_LP64)
- uint64_t rval;
- asm volatile("rd %%tick,%0" : "=r"(rval));
- return rval;
-#else
- /* We need an %o or %g register for this. For recent enough gcc
- there is an "h" constraint for that. Don't bother with that. */
- union {
- uint64_t i64;
- struct {
- uint32_t high;
- uint32_t low;
- } i32;
- } rval;
- asm volatile("rd %%tick,%%g1; srlx %%g1,32,%0; mov %%g1,%1"
- : "=r"(rval.i32.high), "=r"(rval.i32.low) : : "g1");
- return rval.i64;
-#endif
-}
-
-#elif defined(__mips__) && \
- ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
-/*
- * binutils wants to use rdhwr only on mips32r2
- * but as linux kernel emulate it, it's fine
- * to use it.
- *
- */
-#define MIPS_RDHWR(rd, value) { \
- __asm__ __volatile__ (".set push\n\t" \
- ".set mips32r2\n\t" \
- "rdhwr %0, "rd"\n\t" \
- ".set pop" \
- : "=r" (value)); \
- }
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
- uint32_t count;
- static uint32_t cyc_per_count = 0;
-
- if (!cyc_per_count) {
- MIPS_RDHWR("$3", cyc_per_count);
- }
-
- MIPS_RDHWR("$2", count);
- return (int64_t)(count * cyc_per_count);
-}
-
-#elif defined(__alpha__)
-
-static inline int64_t cpu_get_real_ticks(void)
-{
- uint64_t cc;
- uint32_t cur, ofs;
-
- asm volatile("rpcc %0" : "=r"(cc));
- cur = cc;
- ofs = cc >> 32;
- return cur - ofs;
-}
-
-#else
-/* The host CPU doesn't have an easily accessible cycle counter.
- Just return a monotonically increasing value. This will be
- totally wrong, but hopefully better than nothing. */
-static inline int64_t cpu_get_real_ticks (void)
-{
- static int64_t ticks = 0;
- return ticks++;
-}
-#endif
-
-#ifdef CONFIG_PROFILER
-static inline int64_t profile_getclock(void)
-{
- return cpu_get_real_ticks();
-}
-
-extern int64_t qemu_time, qemu_time_start;
-extern int64_t tlb_flush_time;
-extern int64_t dev_time;
-#endif
-
-#endif
diff --git a/contrib/qemu/include/qemu/typedefs.h b/contrib/qemu/include/qemu/typedefs.h
deleted file mode 100644
index ac9f8d41a35..00000000000
--- a/contrib/qemu/include/qemu/typedefs.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef QEMU_TYPEDEFS_H
-#define QEMU_TYPEDEFS_H
-
-/* A load of opaque types so that device init declarations don't have to
- pull in all the real definitions. */
-typedef struct QEMUTimer QEMUTimer;
-typedef struct QEMUFile QEMUFile;
-typedef struct QEMUBH QEMUBH;
-
-struct Monitor;
-typedef struct Monitor Monitor;
-typedef struct MigrationParams MigrationParams;
-
-typedef struct Property Property;
-typedef struct PropertyInfo PropertyInfo;
-typedef struct CompatProperty CompatProperty;
-typedef struct DeviceState DeviceState;
-typedef struct BusState BusState;
-typedef struct BusClass BusClass;
-
-typedef struct AddressSpace AddressSpace;
-typedef struct MemoryRegion MemoryRegion;
-typedef struct MemoryRegionSection MemoryRegionSection;
-
-typedef struct MemoryMappingList MemoryMappingList;
-
-typedef struct NICInfo NICInfo;
-typedef struct HCIInfo HCIInfo;
-typedef struct AudioState AudioState;
-typedef struct BlockDriverState BlockDriverState;
-typedef struct DriveInfo DriveInfo;
-typedef struct DisplayState DisplayState;
-typedef struct DisplayChangeListener DisplayChangeListener;
-typedef struct DisplaySurface DisplaySurface;
-typedef struct PixelFormat PixelFormat;
-typedef struct QemuConsole QemuConsole;
-typedef struct CharDriverState CharDriverState;
-typedef struct MACAddr MACAddr;
-typedef struct NetClientState NetClientState;
-typedef struct i2c_bus i2c_bus;
-typedef struct ISABus ISABus;
-typedef struct ISADevice ISADevice;
-typedef struct SMBusDevice SMBusDevice;
-typedef struct PCIHostState PCIHostState;
-typedef struct PCIExpressHost PCIExpressHost;
-typedef struct PCIBus PCIBus;
-typedef struct PCIDevice PCIDevice;
-typedef struct PCIExpressDevice PCIExpressDevice;
-typedef struct PCIBridge PCIBridge;
-typedef struct PCIEAERMsg PCIEAERMsg;
-typedef struct PCIEAERLog PCIEAERLog;
-typedef struct PCIEAERErr PCIEAERErr;
-typedef struct PCIEPort PCIEPort;
-typedef struct PCIESlot PCIESlot;
-typedef struct MSIMessage MSIMessage;
-typedef struct SerialState SerialState;
-typedef struct PCMCIACardState PCMCIACardState;
-typedef struct MouseTransformInfo MouseTransformInfo;
-typedef struct uWireSlave uWireSlave;
-typedef struct I2SCodec I2SCodec;
-typedef struct SSIBus SSIBus;
-typedef struct EventNotifier EventNotifier;
-typedef struct VirtIODevice VirtIODevice;
-typedef struct QEMUSGList QEMUSGList;
-typedef struct SHPCDevice SHPCDevice;
-typedef struct FWCfgState FWCfgState;
-typedef struct PcGuestInfo PcGuestInfo;
-
-#endif /* QEMU_TYPEDEFS_H */
diff --git a/contrib/qemu/include/sysemu/os-posix.h b/contrib/qemu/include/sysemu/os-posix.h
deleted file mode 100644
index ac4a80e6d8c..00000000000
--- a/contrib/qemu/include/sysemu/os-posix.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * posix specific declarations
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- * Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef QEMU_OS_POSIX_H
-#define QEMU_OS_POSIX_H
-
-void os_set_line_buffering(void);
-void os_set_proc_name(const char *s);
-void os_setup_signal_handling(void);
-void os_daemonize(void);
-void os_setup_post(void);
-int os_mlock(void);
-
-typedef struct timeval qemu_timeval;
-#define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
-
-#if !defined(CONFIG_UTIMENSAT) || defined(__FreeBSD__) || defined(__APPLE__)
-#ifndef UTIME_NOW
-# define UTIME_NOW ((1l << 30) - 1l)
-#endif
-#ifndef UTIME_OMIT
-# define UTIME_OMIT ((1l << 30) - 2l)
-#endif
-#endif
-typedef struct timespec qemu_timespec;
-int qemu_utimens(const char *path, const qemu_timespec *times);
-
-bool is_daemonized(void);
-
-#endif
diff --git a/contrib/qemu/include/sysemu/sysemu.h b/contrib/qemu/include/sysemu/sysemu.h
deleted file mode 100644
index 3caeb66eb2f..00000000000
--- a/contrib/qemu/include/sysemu/sysemu.h
+++ /dev/null
@@ -1,200 +0,0 @@
-#ifndef SYSEMU_H
-#define SYSEMU_H
-/* Misc. things related to the system emulator. */
-
-#include "qemu/typedefs.h"
-#include "qemu/option.h"
-#include "qemu/queue.h"
-#include "qemu/timer.h"
-#include "qapi-types.h"
-#include "qemu/notify.h"
-#include "qemu/main-loop.h"
-
-/* vl.c */
-
-extern const char *bios_name;
-
-extern const char *qemu_name;
-extern uint8_t qemu_uuid[];
-int qemu_uuid_parse(const char *str, uint8_t *uuid);
-#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
-
-bool runstate_check(RunState state);
-void runstate_set(RunState new_state);
-int runstate_is_running(void);
-bool runstate_needs_reset(void);
-typedef struct vm_change_state_entry VMChangeStateEntry;
-typedef void VMChangeStateHandler(void *opaque, int running, RunState state);
-
-VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
- void *opaque);
-void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
-void vm_state_notify(int running, RunState state);
-
-#define VMRESET_SILENT false
-#define VMRESET_REPORT true
-
-void vm_start(void);
-int vm_stop(RunState state);
-int vm_stop_force_state(RunState state);
-
-typedef enum WakeupReason {
- QEMU_WAKEUP_REASON_OTHER = 0,
- QEMU_WAKEUP_REASON_RTC,
- QEMU_WAKEUP_REASON_PMTIMER,
-} WakeupReason;
-
-void qemu_system_reset_request(void);
-void qemu_system_suspend_request(void);
-void qemu_register_suspend_notifier(Notifier *notifier);
-void qemu_system_wakeup_request(WakeupReason reason);
-void qemu_system_wakeup_enable(WakeupReason reason, bool enabled);
-void qemu_register_wakeup_notifier(Notifier *notifier);
-void qemu_system_shutdown_request(void);
-void qemu_system_powerdown_request(void);
-void qemu_register_powerdown_notifier(Notifier *notifier);
-void qemu_system_debug_request(void);
-void qemu_system_vmstop_request(RunState reason);
-int qemu_shutdown_requested_get(void);
-int qemu_reset_requested_get(void);
-void qemu_system_killed(int signal, pid_t pid);
-void qemu_devices_reset(void);
-void qemu_system_reset(bool report);
-
-void qemu_add_exit_notifier(Notifier *notify);
-void qemu_remove_exit_notifier(Notifier *notify);
-
-void qemu_add_machine_init_done_notifier(Notifier *notify);
-
-void do_savevm(Monitor *mon, const QDict *qdict);
-int load_vmstate(const char *name);
-void do_delvm(Monitor *mon, const QDict *qdict);
-void do_info_snapshots(Monitor *mon, const QDict *qdict);
-
-void qemu_announce_self(void);
-
-bool qemu_savevm_state_blocked(Error **errp);
-void qemu_savevm_state_begin(QEMUFile *f,
- const MigrationParams *params);
-int qemu_savevm_state_iterate(QEMUFile *f);
-void qemu_savevm_state_complete(QEMUFile *f);
-void qemu_savevm_state_cancel(void);
-uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size);
-int qemu_loadvm_state(QEMUFile *f);
-
-/* SLIRP */
-void do_info_slirp(Monitor *mon);
-
-typedef enum DisplayType
-{
- DT_DEFAULT,
- DT_CURSES,
- DT_SDL,
- DT_GTK,
- DT_NOGRAPHIC,
- DT_NONE,
-} DisplayType;
-
-extern int autostart;
-
-typedef enum {
- VGA_NONE, VGA_STD, VGA_CIRRUS, VGA_VMWARE, VGA_XENFB, VGA_QXL,
-} VGAInterfaceType;
-
-extern int vga_interface_type;
-#define xenfb_enabled (vga_interface_type == VGA_XENFB)
-#define qxl_enabled (vga_interface_type == VGA_QXL)
-
-extern int graphic_width;
-extern int graphic_height;
-extern int graphic_depth;
-extern DisplayType display_type;
-extern const char *keyboard_layout;
-extern int win2k_install_hack;
-extern int alt_grab;
-extern int ctrl_grab;
-extern int smp_cpus;
-extern int max_cpus;
-extern int cursor_hide;
-extern int graphic_rotate;
-extern int no_quit;
-extern int no_shutdown;
-extern int semihosting_enabled;
-extern int old_param;
-extern int boot_menu;
-extern uint8_t *boot_splash_filedata;
-extern size_t boot_splash_filedata_size;
-extern uint8_t qemu_extra_params_fw[2];
-extern QEMUClock *rtc_clock;
-
-#define MAX_NODES 64
-#define MAX_CPUMASK_BITS 255
-extern int nb_numa_nodes;
-extern uint64_t node_mem[MAX_NODES];
-extern unsigned long *node_cpumask[MAX_NODES];
-
-#define MAX_OPTION_ROMS 16
-typedef struct QEMUOptionRom {
- const char *name;
- int32_t bootindex;
-} QEMUOptionRom;
-extern QEMUOptionRom option_rom[MAX_OPTION_ROMS];
-extern int nb_option_roms;
-
-#define MAX_PROM_ENVS 128
-extern const char *prom_envs[MAX_PROM_ENVS];
-extern unsigned int nb_prom_envs;
-
-/* pci-hotplug */
-void pci_device_hot_add(Monitor *mon, const QDict *qdict);
-int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo);
-void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
-
-/* generic hotplug */
-void drive_hot_add(Monitor *mon, const QDict *qdict);
-
-/* CPU hotplug */
-void qemu_register_cpu_added_notifier(Notifier *notifier);
-
-/* pcie aer error injection */
-void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
-int do_pcie_aer_inject_error(Monitor *mon,
- const QDict *qdict, QObject **ret_data);
-
-/* serial ports */
-
-#define MAX_SERIAL_PORTS 4
-
-extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
-
-/* parallel ports */
-
-#define MAX_PARALLEL_PORTS 3
-
-extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
-
-void do_usb_add(Monitor *mon, const QDict *qdict);
-void do_usb_del(Monitor *mon, const QDict *qdict);
-void usb_info(Monitor *mon, const QDict *qdict);
-
-void rtc_change_mon_event(struct tm *tm);
-
-void add_boot_device_path(int32_t bootindex, DeviceState *dev,
- const char *suffix);
-char *get_boot_devices_list(size_t *size);
-
-DeviceState *get_boot_device(uint32_t position);
-
-QemuOpts *qemu_get_machine_opts(void);
-
-bool usb_enabled(bool default_usb);
-
-extern QemuOptsList qemu_drive_opts;
-extern QemuOptsList qemu_chardev_opts;
-extern QemuOptsList qemu_device_opts;
-extern QemuOptsList qemu_netdev_opts;
-extern QemuOptsList qemu_net_opts;
-extern QemuOptsList qemu_global_opts;
-extern QemuOptsList qemu_mon_opts;
-
-#endif
diff --git a/contrib/qemu/include/trace.h b/contrib/qemu/include/trace.h
deleted file mode 100644
index c15f4981280..00000000000
--- a/contrib/qemu/include/trace.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef TRACE_H
-#define TRACE_H
-
-#include "trace/generated-tracers.h"
-
-#endif /* TRACE_H */
diff --git a/contrib/qemu/nop-symbols.c b/contrib/qemu/nop-symbols.c
deleted file mode 100644
index ae93a3d3bef..00000000000
--- a/contrib/qemu/nop-symbols.c
+++ /dev/null
@@ -1,12 +0,0 @@
-int notifier_with_return_list_init () { return 0; }
-int notifier_with_return_list_notify () { return 0; }
-int notifier_with_return_list_add () { return 0; }
-int notifier_list_init () { return 0; }
-int notifier_list_notify () { return 0; }
-int notifier_list_add () { return 0; }
-int monitor_protocol_event () { return 0; }
-int block_job_cancel_sync () { return 0; }
-int block_job_iostatus_reset () { return 0; }
-int vm_stop () { return 0; }
-int qemu_get_aio_context () { return 0; }
-
diff --git a/contrib/qemu/qapi-types.h b/contrib/qemu/qapi-types.h
deleted file mode 100644
index 082b06d1c2b..00000000000
--- a/contrib/qemu/qapi-types.h
+++ /dev/null
@@ -1,2746 +0,0 @@
-/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
-
-/*
- * schema-defined QAPI types
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QAPI_TYPES_H
-#define QAPI_TYPES_H
-
-#include <stdbool.h>
-#include <stdint.h>
-
-
-#ifndef QAPI_TYPES_BUILTIN_STRUCT_DECL_H
-#define QAPI_TYPES_BUILTIN_STRUCT_DECL_H
-
-
-typedef struct strList
-{
- union {
- char * value;
- uint64_t padding;
- };
- struct strList *next;
-} strList;
-
-typedef struct intList
-{
- union {
- int64_t value;
- uint64_t padding;
- };
- struct intList *next;
-} intList;
-
-typedef struct numberList
-{
- union {
- double value;
- uint64_t padding;
- };
- struct numberList *next;
-} numberList;
-
-typedef struct boolList
-{
- union {
- bool value;
- uint64_t padding;
- };
- struct boolList *next;
-} boolList;
-
-typedef struct int8List
-{
- union {
- int8_t value;
- uint64_t padding;
- };
- struct int8List *next;
-} int8List;
-
-typedef struct int16List
-{
- union {
- int16_t value;
- uint64_t padding;
- };
- struct int16List *next;
-} int16List;
-
-typedef struct int32List
-{
- union {
- int32_t value;
- uint64_t padding;
- };
- struct int32List *next;
-} int32List;
-
-typedef struct int64List
-{
- union {
- int64_t value;
- uint64_t padding;
- };
- struct int64List *next;
-} int64List;
-
-typedef struct uint8List
-{
- union {
- uint8_t value;
- uint64_t padding;
- };
- struct uint8List *next;
-} uint8List;
-
-typedef struct uint16List
-{
- union {
- uint16_t value;
- uint64_t padding;
- };
- struct uint16List *next;
-} uint16List;
-
-typedef struct uint32List
-{
- union {
- uint32_t value;
- uint64_t padding;
- };
- struct uint32List *next;
-} uint32List;
-
-typedef struct uint64List
-{
- union {
- uint64_t value;
- uint64_t padding;
- };
- struct uint64List *next;
-} uint64List;
-
-#endif /* QAPI_TYPES_BUILTIN_STRUCT_DECL_H */
-
-
-extern const char *ErrorClass_lookup[];
-typedef enum ErrorClass
-{
- ERROR_CLASS_GENERIC_ERROR = 0,
- ERROR_CLASS_COMMAND_NOT_FOUND = 1,
- ERROR_CLASS_DEVICE_ENCRYPTED = 2,
- ERROR_CLASS_DEVICE_NOT_ACTIVE = 3,
- ERROR_CLASS_DEVICE_NOT_FOUND = 4,
- ERROR_CLASS_K_V_M_MISSING_CAP = 5,
- ERROR_CLASS_MAX = 6,
-} ErrorClass;
-
-typedef struct ErrorClassList
-{
- ErrorClass value;
- struct ErrorClassList *next;
-} ErrorClassList;
-
-
-typedef struct NameInfo NameInfo;
-
-typedef struct NameInfoList
-{
- union {
- NameInfo *value;
- uint64_t padding;
- };
- struct NameInfoList *next;
-} NameInfoList;
-
-
-typedef struct VersionInfo VersionInfo;
-
-typedef struct VersionInfoList
-{
- union {
- VersionInfo *value;
- uint64_t padding;
- };
- struct VersionInfoList *next;
-} VersionInfoList;
-
-
-typedef struct KvmInfo KvmInfo;
-
-typedef struct KvmInfoList
-{
- union {
- KvmInfo *value;
- uint64_t padding;
- };
- struct KvmInfoList *next;
-} KvmInfoList;
-
-extern const char *RunState_lookup[];
-typedef enum RunState
-{
- RUN_STATE_DEBUG = 0,
- RUN_STATE_INMIGRATE = 1,
- RUN_STATE_INTERNAL_ERROR = 2,
- RUN_STATE_IO_ERROR = 3,
- RUN_STATE_PAUSED = 4,
- RUN_STATE_POSTMIGRATE = 5,
- RUN_STATE_PRELAUNCH = 6,
- RUN_STATE_FINISH_MIGRATE = 7,
- RUN_STATE_RESTORE_VM = 8,
- RUN_STATE_RUNNING = 9,
- RUN_STATE_SAVE_VM = 10,
- RUN_STATE_SHUTDOWN = 11,
- RUN_STATE_SUSPENDED = 12,
- RUN_STATE_WATCHDOG = 13,
- RUN_STATE_GUEST_PANICKED = 14,
- RUN_STATE_MAX = 15,
-} RunState;
-
-typedef struct RunStateList
-{
- RunState value;
- struct RunStateList *next;
-} RunStateList;
-
-
-typedef struct SnapshotInfo SnapshotInfo;
-
-typedef struct SnapshotInfoList
-{
- union {
- SnapshotInfo *value;
- uint64_t padding;
- };
- struct SnapshotInfoList *next;
-} SnapshotInfoList;
-
-
-typedef struct ImageInfo ImageInfo;
-
-typedef struct ImageInfoList
-{
- union {
- ImageInfo *value;
- uint64_t padding;
- };
- struct ImageInfoList *next;
-} ImageInfoList;
-
-
-typedef struct ImageCheck ImageCheck;
-
-typedef struct ImageCheckList
-{
- union {
- ImageCheck *value;
- uint64_t padding;
- };
- struct ImageCheckList *next;
-} ImageCheckList;
-
-
-typedef struct StatusInfo StatusInfo;
-
-typedef struct StatusInfoList
-{
- union {
- StatusInfo *value;
- uint64_t padding;
- };
- struct StatusInfoList *next;
-} StatusInfoList;
-
-
-typedef struct UuidInfo UuidInfo;
-
-typedef struct UuidInfoList
-{
- union {
- UuidInfo *value;
- uint64_t padding;
- };
- struct UuidInfoList *next;
-} UuidInfoList;
-
-
-typedef struct ChardevInfo ChardevInfo;
-
-typedef struct ChardevInfoList
-{
- union {
- ChardevInfo *value;
- uint64_t padding;
- };
- struct ChardevInfoList *next;
-} ChardevInfoList;
-
-extern const char *DataFormat_lookup[];
-typedef enum DataFormat
-{
- DATA_FORMAT_UTF8 = 0,
- DATA_FORMAT_BASE64 = 1,
- DATA_FORMAT_MAX = 2,
-} DataFormat;
-
-typedef struct DataFormatList
-{
- DataFormat value;
- struct DataFormatList *next;
-} DataFormatList;
-
-
-typedef struct CommandInfo CommandInfo;
-
-typedef struct CommandInfoList
-{
- union {
- CommandInfo *value;
- uint64_t padding;
- };
- struct CommandInfoList *next;
-} CommandInfoList;
-
-
-typedef struct EventInfo EventInfo;
-
-typedef struct EventInfoList
-{
- union {
- EventInfo *value;
- uint64_t padding;
- };
- struct EventInfoList *next;
-} EventInfoList;
-
-
-typedef struct MigrationStats MigrationStats;
-
-typedef struct MigrationStatsList
-{
- union {
- MigrationStats *value;
- uint64_t padding;
- };
- struct MigrationStatsList *next;
-} MigrationStatsList;
-
-
-typedef struct XBZRLECacheStats XBZRLECacheStats;
-
-typedef struct XBZRLECacheStatsList
-{
- union {
- XBZRLECacheStats *value;
- uint64_t padding;
- };
- struct XBZRLECacheStatsList *next;
-} XBZRLECacheStatsList;
-
-
-typedef struct MigrationInfo MigrationInfo;
-
-typedef struct MigrationInfoList
-{
- union {
- MigrationInfo *value;
- uint64_t padding;
- };
- struct MigrationInfoList *next;
-} MigrationInfoList;
-
-extern const char *MigrationCapability_lookup[];
-typedef enum MigrationCapability
-{
- MIGRATION_CAPABILITY_XBZRLE = 0,
- MIGRATION_CAPABILITY_X_RDMA_PIN_ALL = 1,
- MIGRATION_CAPABILITY_AUTO_CONVERGE = 2,
- MIGRATION_CAPABILITY_MAX = 3,
-} MigrationCapability;
-
-typedef struct MigrationCapabilityList
-{
- MigrationCapability value;
- struct MigrationCapabilityList *next;
-} MigrationCapabilityList;
-
-
-typedef struct MigrationCapabilityStatus MigrationCapabilityStatus;
-
-typedef struct MigrationCapabilityStatusList
-{
- union {
- MigrationCapabilityStatus *value;
- uint64_t padding;
- };
- struct MigrationCapabilityStatusList *next;
-} MigrationCapabilityStatusList;
-
-
-typedef struct MouseInfo MouseInfo;
-
-typedef struct MouseInfoList
-{
- union {
- MouseInfo *value;
- uint64_t padding;
- };
- struct MouseInfoList *next;
-} MouseInfoList;
-
-
-typedef struct CpuInfo CpuInfo;
-
-typedef struct CpuInfoList
-{
- union {
- CpuInfo *value;
- uint64_t padding;
- };
- struct CpuInfoList *next;
-} CpuInfoList;
-
-
-typedef struct BlockDeviceInfo BlockDeviceInfo;
-
-typedef struct BlockDeviceInfoList
-{
- union {
- BlockDeviceInfo *value;
- uint64_t padding;
- };
- struct BlockDeviceInfoList *next;
-} BlockDeviceInfoList;
-
-extern const char *BlockDeviceIoStatus_lookup[];
-typedef enum BlockDeviceIoStatus
-{
- BLOCK_DEVICE_IO_STATUS_OK = 0,
- BLOCK_DEVICE_IO_STATUS_FAILED = 1,
- BLOCK_DEVICE_IO_STATUS_NOSPACE = 2,
- BLOCK_DEVICE_IO_STATUS_MAX = 3,
-} BlockDeviceIoStatus;
-
-typedef struct BlockDeviceIoStatusList
-{
- BlockDeviceIoStatus value;
- struct BlockDeviceIoStatusList *next;
-} BlockDeviceIoStatusList;
-
-
-typedef struct BlockDirtyInfo BlockDirtyInfo;
-
-typedef struct BlockDirtyInfoList
-{
- union {
- BlockDirtyInfo *value;
- uint64_t padding;
- };
- struct BlockDirtyInfoList *next;
-} BlockDirtyInfoList;
-
-
-typedef struct BlockInfo BlockInfo;
-
-typedef struct BlockInfoList
-{
- union {
- BlockInfo *value;
- uint64_t padding;
- };
- struct BlockInfoList *next;
-} BlockInfoList;
-
-
-typedef struct BlockDeviceStats BlockDeviceStats;
-
-typedef struct BlockDeviceStatsList
-{
- union {
- BlockDeviceStats *value;
- uint64_t padding;
- };
- struct BlockDeviceStatsList *next;
-} BlockDeviceStatsList;
-
-
-typedef struct BlockStats BlockStats;
-
-typedef struct BlockStatsList
-{
- union {
- BlockStats *value;
- uint64_t padding;
- };
- struct BlockStatsList *next;
-} BlockStatsList;
-
-
-typedef struct VncClientInfo VncClientInfo;
-
-typedef struct VncClientInfoList
-{
- union {
- VncClientInfo *value;
- uint64_t padding;
- };
- struct VncClientInfoList *next;
-} VncClientInfoList;
-
-
-typedef struct VncInfo VncInfo;
-
-typedef struct VncInfoList
-{
- union {
- VncInfo *value;
- uint64_t padding;
- };
- struct VncInfoList *next;
-} VncInfoList;
-
-
-typedef struct SpiceChannel SpiceChannel;
-
-typedef struct SpiceChannelList
-{
- union {
- SpiceChannel *value;
- uint64_t padding;
- };
- struct SpiceChannelList *next;
-} SpiceChannelList;
-
-extern const char *SpiceQueryMouseMode_lookup[];
-typedef enum SpiceQueryMouseMode
-{
- SPICE_QUERY_MOUSE_MODE_CLIENT = 0,
- SPICE_QUERY_MOUSE_MODE_SERVER = 1,
- SPICE_QUERY_MOUSE_MODE_UNKNOWN = 2,
- SPICE_QUERY_MOUSE_MODE_MAX = 3,
-} SpiceQueryMouseMode;
-
-typedef struct SpiceQueryMouseModeList
-{
- SpiceQueryMouseMode value;
- struct SpiceQueryMouseModeList *next;
-} SpiceQueryMouseModeList;
-
-
-typedef struct SpiceInfo SpiceInfo;
-
-typedef struct SpiceInfoList
-{
- union {
- SpiceInfo *value;
- uint64_t padding;
- };
- struct SpiceInfoList *next;
-} SpiceInfoList;
-
-
-typedef struct BalloonInfo BalloonInfo;
-
-typedef struct BalloonInfoList
-{
- union {
- BalloonInfo *value;
- uint64_t padding;
- };
- struct BalloonInfoList *next;
-} BalloonInfoList;
-
-
-typedef struct PciMemoryRange PciMemoryRange;
-
-typedef struct PciMemoryRangeList
-{
- union {
- PciMemoryRange *value;
- uint64_t padding;
- };
- struct PciMemoryRangeList *next;
-} PciMemoryRangeList;
-
-
-typedef struct PciMemoryRegion PciMemoryRegion;
-
-typedef struct PciMemoryRegionList
-{
- union {
- PciMemoryRegion *value;
- uint64_t padding;
- };
- struct PciMemoryRegionList *next;
-} PciMemoryRegionList;
-
-
-typedef struct PciBridgeInfo PciBridgeInfo;
-
-typedef struct PciBridgeInfoList
-{
- union {
- PciBridgeInfo *value;
- uint64_t padding;
- };
- struct PciBridgeInfoList *next;
-} PciBridgeInfoList;
-
-
-typedef struct PciDeviceInfo PciDeviceInfo;
-
-typedef struct PciDeviceInfoList
-{
- union {
- PciDeviceInfo *value;
- uint64_t padding;
- };
- struct PciDeviceInfoList *next;
-} PciDeviceInfoList;
-
-
-typedef struct PciInfo PciInfo;
-
-typedef struct PciInfoList
-{
- union {
- PciInfo *value;
- uint64_t padding;
- };
- struct PciInfoList *next;
-} PciInfoList;
-
-extern const char *BlockdevOnError_lookup[];
-typedef enum BlockdevOnError
-{
- BLOCKDEV_ON_ERROR_REPORT = 0,
- BLOCKDEV_ON_ERROR_IGNORE = 1,
- BLOCKDEV_ON_ERROR_ENOSPC = 2,
- BLOCKDEV_ON_ERROR_STOP = 3,
- BLOCKDEV_ON_ERROR_MAX = 4,
-} BlockdevOnError;
-
-typedef struct BlockdevOnErrorList
-{
- BlockdevOnError value;
- struct BlockdevOnErrorList *next;
-} BlockdevOnErrorList;
-
-extern const char *MirrorSyncMode_lookup[];
-typedef enum MirrorSyncMode
-{
- MIRROR_SYNC_MODE_TOP = 0,
- MIRROR_SYNC_MODE_FULL = 1,
- MIRROR_SYNC_MODE_NONE = 2,
- MIRROR_SYNC_MODE_MAX = 3,
-} MirrorSyncMode;
-
-typedef struct MirrorSyncModeList
-{
- MirrorSyncMode value;
- struct MirrorSyncModeList *next;
-} MirrorSyncModeList;
-
-
-typedef struct BlockJobInfo BlockJobInfo;
-
-typedef struct BlockJobInfoList
-{
- union {
- BlockJobInfo *value;
- uint64_t padding;
- };
- struct BlockJobInfoList *next;
-} BlockJobInfoList;
-
-extern const char *NewImageMode_lookup[];
-typedef enum NewImageMode
-{
- NEW_IMAGE_MODE_EXISTING = 0,
- NEW_IMAGE_MODE_ABSOLUTE_PATHS = 1,
- NEW_IMAGE_MODE_MAX = 2,
-} NewImageMode;
-
-typedef struct NewImageModeList
-{
- NewImageMode value;
- struct NewImageModeList *next;
-} NewImageModeList;
-
-
-typedef struct BlockdevSnapshot BlockdevSnapshot;
-
-typedef struct BlockdevSnapshotList
-{
- union {
- BlockdevSnapshot *value;
- uint64_t padding;
- };
- struct BlockdevSnapshotList *next;
-} BlockdevSnapshotList;
-
-
-typedef struct DriveBackup DriveBackup;
-
-typedef struct DriveBackupList
-{
- union {
- DriveBackup *value;
- uint64_t padding;
- };
- struct DriveBackupList *next;
-} DriveBackupList;
-
-
-typedef struct Abort Abort;
-
-typedef struct AbortList
-{
- union {
- Abort *value;
- uint64_t padding;
- };
- struct AbortList *next;
-} AbortList;
-
-
-typedef struct TransactionAction TransactionAction;
-
-typedef struct TransactionActionList
-{
- union {
- TransactionAction *value;
- uint64_t padding;
- };
- struct TransactionActionList *next;
-} TransactionActionList;
-
-extern const char *TransactionActionKind_lookup[];
-typedef enum TransactionActionKind
-{
- TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC = 0,
- TRANSACTION_ACTION_KIND_DRIVE_BACKUP = 1,
- TRANSACTION_ACTION_KIND_ABORT = 2,
- TRANSACTION_ACTION_KIND_MAX = 3,
-} TransactionActionKind;
-
-
-typedef struct ObjectPropertyInfo ObjectPropertyInfo;
-
-typedef struct ObjectPropertyInfoList
-{
- union {
- ObjectPropertyInfo *value;
- uint64_t padding;
- };
- struct ObjectPropertyInfoList *next;
-} ObjectPropertyInfoList;
-
-
-typedef struct ObjectTypeInfo ObjectTypeInfo;
-
-typedef struct ObjectTypeInfoList
-{
- union {
- ObjectTypeInfo *value;
- uint64_t padding;
- };
- struct ObjectTypeInfoList *next;
-} ObjectTypeInfoList;
-
-
-typedef struct DevicePropertyInfo DevicePropertyInfo;
-
-typedef struct DevicePropertyInfoList
-{
- union {
- DevicePropertyInfo *value;
- uint64_t padding;
- };
- struct DevicePropertyInfoList *next;
-} DevicePropertyInfoList;
-
-
-typedef struct NetdevNoneOptions NetdevNoneOptions;
-
-typedef struct NetdevNoneOptionsList
-{
- union {
- NetdevNoneOptions *value;
- uint64_t padding;
- };
- struct NetdevNoneOptionsList *next;
-} NetdevNoneOptionsList;
-
-
-typedef struct NetLegacyNicOptions NetLegacyNicOptions;
-
-typedef struct NetLegacyNicOptionsList
-{
- union {
- NetLegacyNicOptions *value;
- uint64_t padding;
- };
- struct NetLegacyNicOptionsList *next;
-} NetLegacyNicOptionsList;
-
-
-typedef struct String String;
-
-typedef struct StringList
-{
- union {
- String *value;
- uint64_t padding;
- };
- struct StringList *next;
-} StringList;
-
-
-typedef struct NetdevUserOptions NetdevUserOptions;
-
-typedef struct NetdevUserOptionsList
-{
- union {
- NetdevUserOptions *value;
- uint64_t padding;
- };
- struct NetdevUserOptionsList *next;
-} NetdevUserOptionsList;
-
-
-typedef struct NetdevTapOptions NetdevTapOptions;
-
-typedef struct NetdevTapOptionsList
-{
- union {
- NetdevTapOptions *value;
- uint64_t padding;
- };
- struct NetdevTapOptionsList *next;
-} NetdevTapOptionsList;
-
-
-typedef struct NetdevSocketOptions NetdevSocketOptions;
-
-typedef struct NetdevSocketOptionsList
-{
- union {
- NetdevSocketOptions *value;
- uint64_t padding;
- };
- struct NetdevSocketOptionsList *next;
-} NetdevSocketOptionsList;
-
-
-typedef struct NetdevVdeOptions NetdevVdeOptions;
-
-typedef struct NetdevVdeOptionsList
-{
- union {
- NetdevVdeOptions *value;
- uint64_t padding;
- };
- struct NetdevVdeOptionsList *next;
-} NetdevVdeOptionsList;
-
-
-typedef struct NetdevDumpOptions NetdevDumpOptions;
-
-typedef struct NetdevDumpOptionsList
-{
- union {
- NetdevDumpOptions *value;
- uint64_t padding;
- };
- struct NetdevDumpOptionsList *next;
-} NetdevDumpOptionsList;
-
-
-typedef struct NetdevBridgeOptions NetdevBridgeOptions;
-
-typedef struct NetdevBridgeOptionsList
-{
- union {
- NetdevBridgeOptions *value;
- uint64_t padding;
- };
- struct NetdevBridgeOptionsList *next;
-} NetdevBridgeOptionsList;
-
-
-typedef struct NetdevHubPortOptions NetdevHubPortOptions;
-
-typedef struct NetdevHubPortOptionsList
-{
- union {
- NetdevHubPortOptions *value;
- uint64_t padding;
- };
- struct NetdevHubPortOptionsList *next;
-} NetdevHubPortOptionsList;
-
-
-typedef struct NetClientOptions NetClientOptions;
-
-typedef struct NetClientOptionsList
-{
- union {
- NetClientOptions *value;
- uint64_t padding;
- };
- struct NetClientOptionsList *next;
-} NetClientOptionsList;
-
-extern const char *NetClientOptionsKind_lookup[];
-typedef enum NetClientOptionsKind
-{
- NET_CLIENT_OPTIONS_KIND_NONE = 0,
- NET_CLIENT_OPTIONS_KIND_NIC = 1,
- NET_CLIENT_OPTIONS_KIND_USER = 2,
- NET_CLIENT_OPTIONS_KIND_TAP = 3,
- NET_CLIENT_OPTIONS_KIND_SOCKET = 4,
- NET_CLIENT_OPTIONS_KIND_VDE = 5,
- NET_CLIENT_OPTIONS_KIND_DUMP = 6,
- NET_CLIENT_OPTIONS_KIND_BRIDGE = 7,
- NET_CLIENT_OPTIONS_KIND_HUBPORT = 8,
- NET_CLIENT_OPTIONS_KIND_MAX = 9,
-} NetClientOptionsKind;
-
-
-typedef struct NetLegacy NetLegacy;
-
-typedef struct NetLegacyList
-{
- union {
- NetLegacy *value;
- uint64_t padding;
- };
- struct NetLegacyList *next;
-} NetLegacyList;
-
-
-typedef struct Netdev Netdev;
-
-typedef struct NetdevList
-{
- union {
- Netdev *value;
- uint64_t padding;
- };
- struct NetdevList *next;
-} NetdevList;
-
-
-typedef struct InetSocketAddress InetSocketAddress;
-
-typedef struct InetSocketAddressList
-{
- union {
- InetSocketAddress *value;
- uint64_t padding;
- };
- struct InetSocketAddressList *next;
-} InetSocketAddressList;
-
-
-typedef struct UnixSocketAddress UnixSocketAddress;
-
-typedef struct UnixSocketAddressList
-{
- union {
- UnixSocketAddress *value;
- uint64_t padding;
- };
- struct UnixSocketAddressList *next;
-} UnixSocketAddressList;
-
-
-typedef struct SocketAddress SocketAddress;
-
-typedef struct SocketAddressList
-{
- union {
- SocketAddress *value;
- uint64_t padding;
- };
- struct SocketAddressList *next;
-} SocketAddressList;
-
-extern const char *SocketAddressKind_lookup[];
-typedef enum SocketAddressKind
-{
- SOCKET_ADDRESS_KIND_INET = 0,
- SOCKET_ADDRESS_KIND_UNIX = 1,
- SOCKET_ADDRESS_KIND_FD = 2,
- SOCKET_ADDRESS_KIND_MAX = 3,
-} SocketAddressKind;
-
-
-typedef struct MachineInfo MachineInfo;
-
-typedef struct MachineInfoList
-{
- union {
- MachineInfo *value;
- uint64_t padding;
- };
- struct MachineInfoList *next;
-} MachineInfoList;
-
-
-typedef struct CpuDefinitionInfo CpuDefinitionInfo;
-
-typedef struct CpuDefinitionInfoList
-{
- union {
- CpuDefinitionInfo *value;
- uint64_t padding;
- };
- struct CpuDefinitionInfoList *next;
-} CpuDefinitionInfoList;
-
-
-typedef struct AddfdInfo AddfdInfo;
-
-typedef struct AddfdInfoList
-{
- union {
- AddfdInfo *value;
- uint64_t padding;
- };
- struct AddfdInfoList *next;
-} AddfdInfoList;
-
-
-typedef struct FdsetFdInfo FdsetFdInfo;
-
-typedef struct FdsetFdInfoList
-{
- union {
- FdsetFdInfo *value;
- uint64_t padding;
- };
- struct FdsetFdInfoList *next;
-} FdsetFdInfoList;
-
-
-typedef struct FdsetInfo FdsetInfo;
-
-typedef struct FdsetInfoList
-{
- union {
- FdsetInfo *value;
- uint64_t padding;
- };
- struct FdsetInfoList *next;
-} FdsetInfoList;
-
-
-typedef struct TargetInfo TargetInfo;
-
-typedef struct TargetInfoList
-{
- union {
- TargetInfo *value;
- uint64_t padding;
- };
- struct TargetInfoList *next;
-} TargetInfoList;
-
-extern const char *QKeyCode_lookup[];
-typedef enum QKeyCode
-{
- Q_KEY_CODE_SHIFT = 0,
- Q_KEY_CODE_SHIFT_R = 1,
- Q_KEY_CODE_ALT = 2,
- Q_KEY_CODE_ALT_R = 3,
- Q_KEY_CODE_ALTGR = 4,
- Q_KEY_CODE_ALTGR_R = 5,
- Q_KEY_CODE_CTRL = 6,
- Q_KEY_CODE_CTRL_R = 7,
- Q_KEY_CODE_MENU = 8,
- Q_KEY_CODE_ESC = 9,
- Q_KEY_CODE_1 = 10,
- Q_KEY_CODE_2 = 11,
- Q_KEY_CODE_3 = 12,
- Q_KEY_CODE_4 = 13,
- Q_KEY_CODE_5 = 14,
- Q_KEY_CODE_6 = 15,
- Q_KEY_CODE_7 = 16,
- Q_KEY_CODE_8 = 17,
- Q_KEY_CODE_9 = 18,
- Q_KEY_CODE_0 = 19,
- Q_KEY_CODE_MINUS = 20,
- Q_KEY_CODE_EQUAL = 21,
- Q_KEY_CODE_BACKSPACE = 22,
- Q_KEY_CODE_TAB = 23,
- Q_KEY_CODE_Q = 24,
- Q_KEY_CODE_W = 25,
- Q_KEY_CODE_E = 26,
- Q_KEY_CODE_R = 27,
- Q_KEY_CODE_T = 28,
- Q_KEY_CODE_Y = 29,
- Q_KEY_CODE_U = 30,
- Q_KEY_CODE_I = 31,
- Q_KEY_CODE_O = 32,
- Q_KEY_CODE_P = 33,
- Q_KEY_CODE_BRACKET_LEFT = 34,
- Q_KEY_CODE_BRACKET_RIGHT = 35,
- Q_KEY_CODE_RET = 36,
- Q_KEY_CODE_A = 37,
- Q_KEY_CODE_S = 38,
- Q_KEY_CODE_D = 39,
- Q_KEY_CODE_F = 40,
- Q_KEY_CODE_G = 41,
- Q_KEY_CODE_H = 42,
- Q_KEY_CODE_J = 43,
- Q_KEY_CODE_K = 44,
- Q_KEY_CODE_L = 45,
- Q_KEY_CODE_SEMICOLON = 46,
- Q_KEY_CODE_APOSTROPHE = 47,
- Q_KEY_CODE_GRAVE_ACCENT = 48,
- Q_KEY_CODE_BACKSLASH = 49,
- Q_KEY_CODE_Z = 50,
- Q_KEY_CODE_X = 51,
- Q_KEY_CODE_C = 52,
- Q_KEY_CODE_V = 53,
- Q_KEY_CODE_B = 54,
- Q_KEY_CODE_N = 55,
- Q_KEY_CODE_M = 56,
- Q_KEY_CODE_COMMA = 57,
- Q_KEY_CODE_DOT = 58,
- Q_KEY_CODE_SLASH = 59,
- Q_KEY_CODE_ASTERISK = 60,
- Q_KEY_CODE_SPC = 61,
- Q_KEY_CODE_CAPS_LOCK = 62,
- Q_KEY_CODE_F1 = 63,
- Q_KEY_CODE_F2 = 64,
- Q_KEY_CODE_F3 = 65,
- Q_KEY_CODE_F4 = 66,
- Q_KEY_CODE_F5 = 67,
- Q_KEY_CODE_F6 = 68,
- Q_KEY_CODE_F7 = 69,
- Q_KEY_CODE_F8 = 70,
- Q_KEY_CODE_F9 = 71,
- Q_KEY_CODE_F10 = 72,
- Q_KEY_CODE_NUM_LOCK = 73,
- Q_KEY_CODE_SCROLL_LOCK = 74,
- Q_KEY_CODE_KP_DIVIDE = 75,
- Q_KEY_CODE_KP_MULTIPLY = 76,
- Q_KEY_CODE_KP_SUBTRACT = 77,
- Q_KEY_CODE_KP_ADD = 78,
- Q_KEY_CODE_KP_ENTER = 79,
- Q_KEY_CODE_KP_DECIMAL = 80,
- Q_KEY_CODE_SYSRQ = 81,
- Q_KEY_CODE_KP_0 = 82,
- Q_KEY_CODE_KP_1 = 83,
- Q_KEY_CODE_KP_2 = 84,
- Q_KEY_CODE_KP_3 = 85,
- Q_KEY_CODE_KP_4 = 86,
- Q_KEY_CODE_KP_5 = 87,
- Q_KEY_CODE_KP_6 = 88,
- Q_KEY_CODE_KP_7 = 89,
- Q_KEY_CODE_KP_8 = 90,
- Q_KEY_CODE_KP_9 = 91,
- Q_KEY_CODE_LESS = 92,
- Q_KEY_CODE_F11 = 93,
- Q_KEY_CODE_F12 = 94,
- Q_KEY_CODE_PRINT = 95,
- Q_KEY_CODE_HOME = 96,
- Q_KEY_CODE_PGUP = 97,
- Q_KEY_CODE_PGDN = 98,
- Q_KEY_CODE_END = 99,
- Q_KEY_CODE_LEFT = 100,
- Q_KEY_CODE_UP = 101,
- Q_KEY_CODE_DOWN = 102,
- Q_KEY_CODE_RIGHT = 103,
- Q_KEY_CODE_INSERT = 104,
- Q_KEY_CODE_DELETE = 105,
- Q_KEY_CODE_STOP = 106,
- Q_KEY_CODE_AGAIN = 107,
- Q_KEY_CODE_PROPS = 108,
- Q_KEY_CODE_UNDO = 109,
- Q_KEY_CODE_FRONT = 110,
- Q_KEY_CODE_COPY = 111,
- Q_KEY_CODE_OPEN = 112,
- Q_KEY_CODE_PASTE = 113,
- Q_KEY_CODE_FIND = 114,
- Q_KEY_CODE_CUT = 115,
- Q_KEY_CODE_LF = 116,
- Q_KEY_CODE_HELP = 117,
- Q_KEY_CODE_META_L = 118,
- Q_KEY_CODE_META_R = 119,
- Q_KEY_CODE_COMPOSE = 120,
- Q_KEY_CODE_MAX = 121,
-} QKeyCode;
-
-typedef struct QKeyCodeList
-{
- QKeyCode value;
- struct QKeyCodeList *next;
-} QKeyCodeList;
-
-
-typedef struct KeyValue KeyValue;
-
-typedef struct KeyValueList
-{
- union {
- KeyValue *value;
- uint64_t padding;
- };
- struct KeyValueList *next;
-} KeyValueList;
-
-extern const char *KeyValueKind_lookup[];
-typedef enum KeyValueKind
-{
- KEY_VALUE_KIND_NUMBER = 0,
- KEY_VALUE_KIND_QCODE = 1,
- KEY_VALUE_KIND_MAX = 2,
-} KeyValueKind;
-
-
-typedef struct ChardevFile ChardevFile;
-
-typedef struct ChardevFileList
-{
- union {
- ChardevFile *value;
- uint64_t padding;
- };
- struct ChardevFileList *next;
-} ChardevFileList;
-
-
-typedef struct ChardevHostdev ChardevHostdev;
-
-typedef struct ChardevHostdevList
-{
- union {
- ChardevHostdev *value;
- uint64_t padding;
- };
- struct ChardevHostdevList *next;
-} ChardevHostdevList;
-
-
-typedef struct ChardevSocket ChardevSocket;
-
-typedef struct ChardevSocketList
-{
- union {
- ChardevSocket *value;
- uint64_t padding;
- };
- struct ChardevSocketList *next;
-} ChardevSocketList;
-
-
-typedef struct ChardevUdp ChardevUdp;
-
-typedef struct ChardevUdpList
-{
- union {
- ChardevUdp *value;
- uint64_t padding;
- };
- struct ChardevUdpList *next;
-} ChardevUdpList;
-
-
-typedef struct ChardevMux ChardevMux;
-
-typedef struct ChardevMuxList
-{
- union {
- ChardevMux *value;
- uint64_t padding;
- };
- struct ChardevMuxList *next;
-} ChardevMuxList;
-
-
-typedef struct ChardevStdio ChardevStdio;
-
-typedef struct ChardevStdioList
-{
- union {
- ChardevStdio *value;
- uint64_t padding;
- };
- struct ChardevStdioList *next;
-} ChardevStdioList;
-
-
-typedef struct ChardevSpiceChannel ChardevSpiceChannel;
-
-typedef struct ChardevSpiceChannelList
-{
- union {
- ChardevSpiceChannel *value;
- uint64_t padding;
- };
- struct ChardevSpiceChannelList *next;
-} ChardevSpiceChannelList;
-
-
-typedef struct ChardevSpicePort ChardevSpicePort;
-
-typedef struct ChardevSpicePortList
-{
- union {
- ChardevSpicePort *value;
- uint64_t padding;
- };
- struct ChardevSpicePortList *next;
-} ChardevSpicePortList;
-
-
-typedef struct ChardevVC ChardevVC;
-
-typedef struct ChardevVCList
-{
- union {
- ChardevVC *value;
- uint64_t padding;
- };
- struct ChardevVCList *next;
-} ChardevVCList;
-
-
-typedef struct ChardevMemory ChardevMemory;
-
-typedef struct ChardevMemoryList
-{
- union {
- ChardevMemory *value;
- uint64_t padding;
- };
- struct ChardevMemoryList *next;
-} ChardevMemoryList;
-
-
-typedef struct ChardevDummy ChardevDummy;
-
-typedef struct ChardevDummyList
-{
- union {
- ChardevDummy *value;
- uint64_t padding;
- };
- struct ChardevDummyList *next;
-} ChardevDummyList;
-
-
-typedef struct ChardevBackend ChardevBackend;
-
-typedef struct ChardevBackendList
-{
- union {
- ChardevBackend *value;
- uint64_t padding;
- };
- struct ChardevBackendList *next;
-} ChardevBackendList;
-
-extern const char *ChardevBackendKind_lookup[];
-typedef enum ChardevBackendKind
-{
- CHARDEV_BACKEND_KIND_FILE = 0,
- CHARDEV_BACKEND_KIND_SERIAL = 1,
- CHARDEV_BACKEND_KIND_PARALLEL = 2,
- CHARDEV_BACKEND_KIND_PIPE = 3,
- CHARDEV_BACKEND_KIND_SOCKET = 4,
- CHARDEV_BACKEND_KIND_UDP = 5,
- CHARDEV_BACKEND_KIND_PTY = 6,
- CHARDEV_BACKEND_KIND_NULL = 7,
- CHARDEV_BACKEND_KIND_MUX = 8,
- CHARDEV_BACKEND_KIND_MSMOUSE = 9,
- CHARDEV_BACKEND_KIND_BRAILLE = 10,
- CHARDEV_BACKEND_KIND_STDIO = 11,
- CHARDEV_BACKEND_KIND_CONSOLE = 12,
- CHARDEV_BACKEND_KIND_SPICEVMC = 13,
- CHARDEV_BACKEND_KIND_SPICEPORT = 14,
- CHARDEV_BACKEND_KIND_VC = 15,
- CHARDEV_BACKEND_KIND_MEMORY = 16,
- CHARDEV_BACKEND_KIND_MAX = 17,
-} ChardevBackendKind;
-
-
-typedef struct ChardevReturn ChardevReturn;
-
-typedef struct ChardevReturnList
-{
- union {
- ChardevReturn *value;
- uint64_t padding;
- };
- struct ChardevReturnList *next;
-} ChardevReturnList;
-
-extern const char *TpmModel_lookup[];
-typedef enum TpmModel
-{
- TPM_MODEL_TPM_TIS = 0,
- TPM_MODEL_MAX = 1,
-} TpmModel;
-
-typedef struct TpmModelList
-{
- TpmModel value;
- struct TpmModelList *next;
-} TpmModelList;
-
-extern const char *TpmType_lookup[];
-typedef enum TpmType
-{
- TPM_TYPE_PASSTHROUGH = 0,
- TPM_TYPE_MAX = 1,
-} TpmType;
-
-typedef struct TpmTypeList
-{
- TpmType value;
- struct TpmTypeList *next;
-} TpmTypeList;
-
-
-typedef struct TPMPassthroughOptions TPMPassthroughOptions;
-
-typedef struct TPMPassthroughOptionsList
-{
- union {
- TPMPassthroughOptions *value;
- uint64_t padding;
- };
- struct TPMPassthroughOptionsList *next;
-} TPMPassthroughOptionsList;
-
-
-typedef struct TpmTypeOptions TpmTypeOptions;
-
-typedef struct TpmTypeOptionsList
-{
- union {
- TpmTypeOptions *value;
- uint64_t padding;
- };
- struct TpmTypeOptionsList *next;
-} TpmTypeOptionsList;
-
-extern const char *TpmTypeOptionsKind_lookup[];
-typedef enum TpmTypeOptionsKind
-{
- TPM_TYPE_OPTIONS_KIND_PASSTHROUGH = 0,
- TPM_TYPE_OPTIONS_KIND_MAX = 1,
-} TpmTypeOptionsKind;
-
-
-typedef struct TPMInfo TPMInfo;
-
-typedef struct TPMInfoList
-{
- union {
- TPMInfo *value;
- uint64_t padding;
- };
- struct TPMInfoList *next;
-} TPMInfoList;
-
-
-typedef struct AcpiTableOptions AcpiTableOptions;
-
-typedef struct AcpiTableOptionsList
-{
- union {
- AcpiTableOptions *value;
- uint64_t padding;
- };
- struct AcpiTableOptionsList *next;
-} AcpiTableOptionsList;
-
-extern const char *CommandLineParameterType_lookup[];
-typedef enum CommandLineParameterType
-{
- COMMAND_LINE_PARAMETER_TYPE_STRING = 0,
- COMMAND_LINE_PARAMETER_TYPE_BOOLEAN = 1,
- COMMAND_LINE_PARAMETER_TYPE_NUMBER = 2,
- COMMAND_LINE_PARAMETER_TYPE_SIZE = 3,
- COMMAND_LINE_PARAMETER_TYPE_MAX = 4,
-} CommandLineParameterType;
-
-typedef struct CommandLineParameterTypeList
-{
- CommandLineParameterType value;
- struct CommandLineParameterTypeList *next;
-} CommandLineParameterTypeList;
-
-
-typedef struct CommandLineParameterInfo CommandLineParameterInfo;
-
-typedef struct CommandLineParameterInfoList
-{
- union {
- CommandLineParameterInfo *value;
- uint64_t padding;
- };
- struct CommandLineParameterInfoList *next;
-} CommandLineParameterInfoList;
-
-
-typedef struct CommandLineOptionInfo CommandLineOptionInfo;
-
-typedef struct CommandLineOptionInfoList
-{
- union {
- CommandLineOptionInfo *value;
- uint64_t padding;
- };
- struct CommandLineOptionInfoList *next;
-} CommandLineOptionInfoList;
-
-extern const char *X86CPURegister32_lookup[];
-typedef enum X86CPURegister32
-{
- X86_C_P_U_REGISTER32_EAX = 0,
- X86_C_P_U_REGISTER32_EBX = 1,
- X86_C_P_U_REGISTER32_ECX = 2,
- X86_C_P_U_REGISTER32_EDX = 3,
- X86_C_P_U_REGISTER32_ESP = 4,
- X86_C_P_U_REGISTER32_EBP = 5,
- X86_C_P_U_REGISTER32_ESI = 6,
- X86_C_P_U_REGISTER32_EDI = 7,
- X86_C_P_U_REGISTER32_MAX = 8,
-} X86CPURegister32;
-
-typedef struct X86CPURegister32List
-{
- X86CPURegister32 value;
- struct X86CPURegister32List *next;
-} X86CPURegister32List;
-
-
-typedef struct X86CPUFeatureWordInfo X86CPUFeatureWordInfo;
-
-typedef struct X86CPUFeatureWordInfoList
-{
- union {
- X86CPUFeatureWordInfo *value;
- uint64_t padding;
- };
- struct X86CPUFeatureWordInfoList *next;
-} X86CPUFeatureWordInfoList;
-
-extern const char *RxState_lookup[];
-typedef enum RxState
-{
- RX_STATE_NORMAL = 0,
- RX_STATE_NONE = 1,
- RX_STATE_ALL = 2,
- RX_STATE_MAX = 3,
-} RxState;
-
-typedef struct RxStateList
-{
- RxState value;
- struct RxStateList *next;
-} RxStateList;
-
-
-typedef struct RxFilterInfo RxFilterInfo;
-
-typedef struct RxFilterInfoList
-{
- union {
- RxFilterInfo *value;
- uint64_t padding;
- };
- struct RxFilterInfoList *next;
-} RxFilterInfoList;
-
-#ifndef QAPI_TYPES_BUILTIN_CLEANUP_DECL_H
-#define QAPI_TYPES_BUILTIN_CLEANUP_DECL_H
-
-void qapi_free_strList(strList * obj);
-void qapi_free_intList(intList * obj);
-void qapi_free_numberList(numberList * obj);
-void qapi_free_boolList(boolList * obj);
-void qapi_free_int8List(int8List * obj);
-void qapi_free_int16List(int16List * obj);
-void qapi_free_int32List(int32List * obj);
-void qapi_free_int64List(int64List * obj);
-void qapi_free_uint8List(uint8List * obj);
-void qapi_free_uint16List(uint16List * obj);
-void qapi_free_uint32List(uint32List * obj);
-void qapi_free_uint64List(uint64List * obj);
-
-#endif /* QAPI_TYPES_BUILTIN_CLEANUP_DECL_H */
-
-
-void qapi_free_ErrorClassList(ErrorClassList * obj);
-
-struct NameInfo
-{
- bool has_name;
- char * name;
-};
-
-void qapi_free_NameInfoList(NameInfoList * obj);
-void qapi_free_NameInfo(NameInfo * obj);
-
-struct VersionInfo
-{
- struct
- {
- int64_t major;
- int64_t minor;
- int64_t micro;
- } qemu;
- char * package;
-};
-
-void qapi_free_VersionInfoList(VersionInfoList * obj);
-void qapi_free_VersionInfo(VersionInfo * obj);
-
-struct KvmInfo
-{
- bool enabled;
- bool present;
-};
-
-void qapi_free_KvmInfoList(KvmInfoList * obj);
-void qapi_free_KvmInfo(KvmInfo * obj);
-
-void qapi_free_RunStateList(RunStateList * obj);
-
-struct SnapshotInfo
-{
- char * id;
- char * name;
- int64_t vm_state_size;
- int64_t date_sec;
- int64_t date_nsec;
- int64_t vm_clock_sec;
- int64_t vm_clock_nsec;
-};
-
-void qapi_free_SnapshotInfoList(SnapshotInfoList * obj);
-void qapi_free_SnapshotInfo(SnapshotInfo * obj);
-
-struct ImageInfo
-{
- char * filename;
- char * format;
- bool has_dirty_flag;
- bool dirty_flag;
- bool has_actual_size;
- int64_t actual_size;
- int64_t virtual_size;
- bool has_cluster_size;
- int64_t cluster_size;
- bool has_encrypted;
- bool encrypted;
- bool has_backing_filename;
- char * backing_filename;
- bool has_full_backing_filename;
- char * full_backing_filename;
- bool has_backing_filename_format;
- char * backing_filename_format;
- bool has_snapshots;
- SnapshotInfoList * snapshots;
- bool has_backing_image;
- ImageInfo * backing_image;
-};
-
-void qapi_free_ImageInfoList(ImageInfoList * obj);
-void qapi_free_ImageInfo(ImageInfo * obj);
-
-struct ImageCheck
-{
- char * filename;
- char * format;
- int64_t check_errors;
- bool has_image_end_offset;
- int64_t image_end_offset;
- bool has_corruptions;
- int64_t corruptions;
- bool has_leaks;
- int64_t leaks;
- bool has_corruptions_fixed;
- int64_t corruptions_fixed;
- bool has_leaks_fixed;
- int64_t leaks_fixed;
- bool has_total_clusters;
- int64_t total_clusters;
- bool has_allocated_clusters;
- int64_t allocated_clusters;
- bool has_fragmented_clusters;
- int64_t fragmented_clusters;
- bool has_compressed_clusters;
- int64_t compressed_clusters;
-};
-
-void qapi_free_ImageCheckList(ImageCheckList * obj);
-void qapi_free_ImageCheck(ImageCheck * obj);
-
-struct StatusInfo
-{
- bool running;
- bool singlestep;
- RunState status;
-};
-
-void qapi_free_StatusInfoList(StatusInfoList * obj);
-void qapi_free_StatusInfo(StatusInfo * obj);
-
-struct UuidInfo
-{
- char * UUID;
-};
-
-void qapi_free_UuidInfoList(UuidInfoList * obj);
-void qapi_free_UuidInfo(UuidInfo * obj);
-
-struct ChardevInfo
-{
- char * label;
- char * filename;
-};
-
-void qapi_free_ChardevInfoList(ChardevInfoList * obj);
-void qapi_free_ChardevInfo(ChardevInfo * obj);
-
-void qapi_free_DataFormatList(DataFormatList * obj);
-
-struct CommandInfo
-{
- char * name;
-};
-
-void qapi_free_CommandInfoList(CommandInfoList * obj);
-void qapi_free_CommandInfo(CommandInfo * obj);
-
-struct EventInfo
-{
- char * name;
-};
-
-void qapi_free_EventInfoList(EventInfoList * obj);
-void qapi_free_EventInfo(EventInfo * obj);
-
-struct MigrationStats
-{
- int64_t transferred;
- int64_t remaining;
- int64_t total;
- int64_t duplicate;
- int64_t skipped;
- int64_t normal;
- int64_t normal_bytes;
- int64_t dirty_pages_rate;
- double mbps;
-};
-
-void qapi_free_MigrationStatsList(MigrationStatsList * obj);
-void qapi_free_MigrationStats(MigrationStats * obj);
-
-struct XBZRLECacheStats
-{
- int64_t cache_size;
- int64_t bytes;
- int64_t pages;
- int64_t cache_miss;
- int64_t overflow;
-};
-
-void qapi_free_XBZRLECacheStatsList(XBZRLECacheStatsList * obj);
-void qapi_free_XBZRLECacheStats(XBZRLECacheStats * obj);
-
-struct MigrationInfo
-{
- bool has_status;
- char * status;
- bool has_ram;
- MigrationStats * ram;
- bool has_disk;
- MigrationStats * disk;
- bool has_xbzrle_cache;
- XBZRLECacheStats * xbzrle_cache;
- bool has_total_time;
- int64_t total_time;
- bool has_expected_downtime;
- int64_t expected_downtime;
- bool has_downtime;
- int64_t downtime;
-};
-
-void qapi_free_MigrationInfoList(MigrationInfoList * obj);
-void qapi_free_MigrationInfo(MigrationInfo * obj);
-
-void qapi_free_MigrationCapabilityList(MigrationCapabilityList * obj);
-
-struct MigrationCapabilityStatus
-{
- MigrationCapability capability;
- bool state;
-};
-
-void qapi_free_MigrationCapabilityStatusList(MigrationCapabilityStatusList * obj);
-void qapi_free_MigrationCapabilityStatus(MigrationCapabilityStatus * obj);
-
-struct MouseInfo
-{
- char * name;
- int64_t index;
- bool current;
- bool absolute;
-};
-
-void qapi_free_MouseInfoList(MouseInfoList * obj);
-void qapi_free_MouseInfo(MouseInfo * obj);
-
-struct CpuInfo
-{
- int64_t CPU;
- bool current;
- bool halted;
- bool has_pc;
- int64_t pc;
- bool has_nip;
- int64_t nip;
- bool has_npc;
- int64_t npc;
- bool has_PC;
- int64_t PC;
- int64_t thread_id;
-};
-
-void qapi_free_CpuInfoList(CpuInfoList * obj);
-void qapi_free_CpuInfo(CpuInfo * obj);
-
-struct BlockDeviceInfo
-{
- char * file;
- bool ro;
- char * drv;
- bool has_backing_file;
- char * backing_file;
- int64_t backing_file_depth;
- bool encrypted;
- bool encryption_key_missing;
- int64_t bps;
- int64_t bps_rd;
- int64_t bps_wr;
- int64_t iops;
- int64_t iops_rd;
- int64_t iops_wr;
- ImageInfo * image;
-};
-
-void qapi_free_BlockDeviceInfoList(BlockDeviceInfoList * obj);
-void qapi_free_BlockDeviceInfo(BlockDeviceInfo * obj);
-
-void qapi_free_BlockDeviceIoStatusList(BlockDeviceIoStatusList * obj);
-
-struct BlockDirtyInfo
-{
- int64_t count;
- int64_t granularity;
-};
-
-void qapi_free_BlockDirtyInfoList(BlockDirtyInfoList * obj);
-void qapi_free_BlockDirtyInfo(BlockDirtyInfo * obj);
-
-struct BlockInfo
-{
- char * device;
- char * type;
- bool removable;
- bool locked;
- bool has_inserted;
- BlockDeviceInfo * inserted;
- bool has_tray_open;
- bool tray_open;
- bool has_io_status;
- BlockDeviceIoStatus io_status;
- bool has_dirty;
- BlockDirtyInfo * dirty;
-};
-
-void qapi_free_BlockInfoList(BlockInfoList * obj);
-void qapi_free_BlockInfo(BlockInfo * obj);
-
-struct BlockDeviceStats
-{
- int64_t rd_bytes;
- int64_t wr_bytes;
- int64_t rd_operations;
- int64_t wr_operations;
- int64_t flush_operations;
- int64_t flush_total_time_ns;
- int64_t wr_total_time_ns;
- int64_t rd_total_time_ns;
- int64_t wr_highest_offset;
-};
-
-void qapi_free_BlockDeviceStatsList(BlockDeviceStatsList * obj);
-void qapi_free_BlockDeviceStats(BlockDeviceStats * obj);
-
-struct BlockStats
-{
- bool has_device;
- char * device;
- BlockDeviceStats * stats;
- bool has_parent;
- BlockStats * parent;
-};
-
-void qapi_free_BlockStatsList(BlockStatsList * obj);
-void qapi_free_BlockStats(BlockStats * obj);
-
-struct VncClientInfo
-{
- char * host;
- char * family;
- char * service;
- bool has_x509_dname;
- char * x509_dname;
- bool has_sasl_username;
- char * sasl_username;
-};
-
-void qapi_free_VncClientInfoList(VncClientInfoList * obj);
-void qapi_free_VncClientInfo(VncClientInfo * obj);
-
-struct VncInfo
-{
- bool enabled;
- bool has_host;
- char * host;
- bool has_family;
- char * family;
- bool has_service;
- char * service;
- bool has_auth;
- char * auth;
- bool has_clients;
- VncClientInfoList * clients;
-};
-
-void qapi_free_VncInfoList(VncInfoList * obj);
-void qapi_free_VncInfo(VncInfo * obj);
-
-struct SpiceChannel
-{
- char * host;
- char * family;
- char * port;
- int64_t connection_id;
- int64_t channel_type;
- int64_t channel_id;
- bool tls;
-};
-
-void qapi_free_SpiceChannelList(SpiceChannelList * obj);
-void qapi_free_SpiceChannel(SpiceChannel * obj);
-
-void qapi_free_SpiceQueryMouseModeList(SpiceQueryMouseModeList * obj);
-
-struct SpiceInfo
-{
- bool enabled;
- bool migrated;
- bool has_host;
- char * host;
- bool has_port;
- int64_t port;
- bool has_tls_port;
- int64_t tls_port;
- bool has_auth;
- char * auth;
- bool has_compiled_version;
- char * compiled_version;
- SpiceQueryMouseMode mouse_mode;
- bool has_channels;
- SpiceChannelList * channels;
-};
-
-void qapi_free_SpiceInfoList(SpiceInfoList * obj);
-void qapi_free_SpiceInfo(SpiceInfo * obj);
-
-struct BalloonInfo
-{
- int64_t actual;
-};
-
-void qapi_free_BalloonInfoList(BalloonInfoList * obj);
-void qapi_free_BalloonInfo(BalloonInfo * obj);
-
-struct PciMemoryRange
-{
- int64_t base;
- int64_t limit;
-};
-
-void qapi_free_PciMemoryRangeList(PciMemoryRangeList * obj);
-void qapi_free_PciMemoryRange(PciMemoryRange * obj);
-
-struct PciMemoryRegion
-{
- int64_t bar;
- char * type;
- int64_t address;
- int64_t size;
- bool has_prefetch;
- bool prefetch;
- bool has_mem_type_64;
- bool mem_type_64;
-};
-
-void qapi_free_PciMemoryRegionList(PciMemoryRegionList * obj);
-void qapi_free_PciMemoryRegion(PciMemoryRegion * obj);
-
-struct PciBridgeInfo
-{
- struct
- {
- int64_t number;
- int64_t secondary;
- int64_t subordinate;
- PciMemoryRange * io_range;
- PciMemoryRange * memory_range;
- PciMemoryRange * prefetchable_range;
- } bus;
- bool has_devices;
- PciDeviceInfoList * devices;
-};
-
-void qapi_free_PciBridgeInfoList(PciBridgeInfoList * obj);
-void qapi_free_PciBridgeInfo(PciBridgeInfo * obj);
-
-struct PciDeviceInfo
-{
- int64_t bus;
- int64_t slot;
- int64_t function;
- struct
- {
- bool has_desc;
- char * desc;
- int64_t class;
- } class_info;
- struct
- {
- int64_t device;
- int64_t vendor;
- } id;
- bool has_irq;
- int64_t irq;
- char * qdev_id;
- bool has_pci_bridge;
- PciBridgeInfo * pci_bridge;
- PciMemoryRegionList * regions;
-};
-
-void qapi_free_PciDeviceInfoList(PciDeviceInfoList * obj);
-void qapi_free_PciDeviceInfo(PciDeviceInfo * obj);
-
-struct PciInfo
-{
- int64_t bus;
- PciDeviceInfoList * devices;
-};
-
-void qapi_free_PciInfoList(PciInfoList * obj);
-void qapi_free_PciInfo(PciInfo * obj);
-
-void qapi_free_BlockdevOnErrorList(BlockdevOnErrorList * obj);
-
-void qapi_free_MirrorSyncModeList(MirrorSyncModeList * obj);
-
-struct BlockJobInfo
-{
- char * type;
- char * device;
- int64_t len;
- int64_t offset;
- bool busy;
- bool paused;
- int64_t speed;
- BlockDeviceIoStatus io_status;
-};
-
-void qapi_free_BlockJobInfoList(BlockJobInfoList * obj);
-void qapi_free_BlockJobInfo(BlockJobInfo * obj);
-
-void qapi_free_NewImageModeList(NewImageModeList * obj);
-
-struct BlockdevSnapshot
-{
- char * device;
- char * snapshot_file;
- bool has_format;
- char * format;
- bool has_mode;
- NewImageMode mode;
-};
-
-void qapi_free_BlockdevSnapshotList(BlockdevSnapshotList * obj);
-void qapi_free_BlockdevSnapshot(BlockdevSnapshot * obj);
-
-struct DriveBackup
-{
- char * device;
- char * target;
- bool has_format;
- char * format;
- MirrorSyncMode sync;
- bool has_mode;
- NewImageMode mode;
- bool has_speed;
- int64_t speed;
- bool has_on_source_error;
- BlockdevOnError on_source_error;
- bool has_on_target_error;
- BlockdevOnError on_target_error;
-};
-
-void qapi_free_DriveBackupList(DriveBackupList * obj);
-void qapi_free_DriveBackup(DriveBackup * obj);
-
-struct Abort
-{
-};
-
-void qapi_free_AbortList(AbortList * obj);
-void qapi_free_Abort(Abort * obj);
-
-struct TransactionAction
-{
- TransactionActionKind kind;
- union {
- void *data;
- BlockdevSnapshot * blockdev_snapshot_sync;
- DriveBackup * drive_backup;
- Abort * abort;
- };
-};
-void qapi_free_TransactionActionList(TransactionActionList * obj);
-void qapi_free_TransactionAction(TransactionAction * obj);
-
-struct ObjectPropertyInfo
-{
- char * name;
- char * type;
-};
-
-void qapi_free_ObjectPropertyInfoList(ObjectPropertyInfoList * obj);
-void qapi_free_ObjectPropertyInfo(ObjectPropertyInfo * obj);
-
-struct ObjectTypeInfo
-{
- char * name;
-};
-
-void qapi_free_ObjectTypeInfoList(ObjectTypeInfoList * obj);
-void qapi_free_ObjectTypeInfo(ObjectTypeInfo * obj);
-
-struct DevicePropertyInfo
-{
- char * name;
- char * type;
-};
-
-void qapi_free_DevicePropertyInfoList(DevicePropertyInfoList * obj);
-void qapi_free_DevicePropertyInfo(DevicePropertyInfo * obj);
-
-struct NetdevNoneOptions
-{
-};
-
-void qapi_free_NetdevNoneOptionsList(NetdevNoneOptionsList * obj);
-void qapi_free_NetdevNoneOptions(NetdevNoneOptions * obj);
-
-struct NetLegacyNicOptions
-{
- bool has_netdev;
- char * netdev;
- bool has_macaddr;
- char * macaddr;
- bool has_model;
- char * model;
- bool has_addr;
- char * addr;
- bool has_vectors;
- uint32_t vectors;
-};
-
-void qapi_free_NetLegacyNicOptionsList(NetLegacyNicOptionsList * obj);
-void qapi_free_NetLegacyNicOptions(NetLegacyNicOptions * obj);
-
-struct String
-{
- char * str;
-};
-
-void qapi_free_StringList(StringList * obj);
-void qapi_free_String(String * obj);
-
-struct NetdevUserOptions
-{
- bool has_hostname;
- char * hostname;
- bool has_q_restrict;
- bool q_restrict;
- bool has_ip;
- char * ip;
- bool has_net;
- char * net;
- bool has_host;
- char * host;
- bool has_tftp;
- char * tftp;
- bool has_bootfile;
- char * bootfile;
- bool has_dhcpstart;
- char * dhcpstart;
- bool has_dns;
- char * dns;
- bool has_dnssearch;
- StringList * dnssearch;
- bool has_smb;
- char * smb;
- bool has_smbserver;
- char * smbserver;
- bool has_hostfwd;
- StringList * hostfwd;
- bool has_guestfwd;
- StringList * guestfwd;
-};
-
-void qapi_free_NetdevUserOptionsList(NetdevUserOptionsList * obj);
-void qapi_free_NetdevUserOptions(NetdevUserOptions * obj);
-
-struct NetdevTapOptions
-{
- bool has_ifname;
- char * ifname;
- bool has_fd;
- char * fd;
- bool has_fds;
- char * fds;
- bool has_script;
- char * script;
- bool has_downscript;
- char * downscript;
- bool has_helper;
- char * helper;
- bool has_sndbuf;
- uint64_t sndbuf;
- bool has_vnet_hdr;
- bool vnet_hdr;
- bool has_vhost;
- bool vhost;
- bool has_vhostfd;
- char * vhostfd;
- bool has_vhostfds;
- char * vhostfds;
- bool has_vhostforce;
- bool vhostforce;
- bool has_queues;
- uint32_t queues;
-};
-
-void qapi_free_NetdevTapOptionsList(NetdevTapOptionsList * obj);
-void qapi_free_NetdevTapOptions(NetdevTapOptions * obj);
-
-struct NetdevSocketOptions
-{
- bool has_fd;
- char * fd;
- bool has_listen;
- char * listen;
- bool has_connect;
- char * connect;
- bool has_mcast;
- char * mcast;
- bool has_localaddr;
- char * localaddr;
- bool has_udp;
- char * udp;
-};
-
-void qapi_free_NetdevSocketOptionsList(NetdevSocketOptionsList * obj);
-void qapi_free_NetdevSocketOptions(NetdevSocketOptions * obj);
-
-struct NetdevVdeOptions
-{
- bool has_sock;
- char * sock;
- bool has_port;
- uint16_t port;
- bool has_group;
- char * group;
- bool has_mode;
- uint16_t mode;
-};
-
-void qapi_free_NetdevVdeOptionsList(NetdevVdeOptionsList * obj);
-void qapi_free_NetdevVdeOptions(NetdevVdeOptions * obj);
-
-struct NetdevDumpOptions
-{
- bool has_len;
- uint64_t len;
- bool has_file;
- char * file;
-};
-
-void qapi_free_NetdevDumpOptionsList(NetdevDumpOptionsList * obj);
-void qapi_free_NetdevDumpOptions(NetdevDumpOptions * obj);
-
-struct NetdevBridgeOptions
-{
- bool has_br;
- char * br;
- bool has_helper;
- char * helper;
-};
-
-void qapi_free_NetdevBridgeOptionsList(NetdevBridgeOptionsList * obj);
-void qapi_free_NetdevBridgeOptions(NetdevBridgeOptions * obj);
-
-struct NetdevHubPortOptions
-{
- int32_t hubid;
-};
-
-void qapi_free_NetdevHubPortOptionsList(NetdevHubPortOptionsList * obj);
-void qapi_free_NetdevHubPortOptions(NetdevHubPortOptions * obj);
-
-struct NetClientOptions
-{
- NetClientOptionsKind kind;
- union {
- void *data;
- NetdevNoneOptions * none;
- NetLegacyNicOptions * nic;
- NetdevUserOptions * user;
- NetdevTapOptions * tap;
- NetdevSocketOptions * socket;
- NetdevVdeOptions * vde;
- NetdevDumpOptions * dump;
- NetdevBridgeOptions * bridge;
- NetdevHubPortOptions * hubport;
- };
-};
-void qapi_free_NetClientOptionsList(NetClientOptionsList * obj);
-void qapi_free_NetClientOptions(NetClientOptions * obj);
-
-struct NetLegacy
-{
- bool has_vlan;
- int32_t vlan;
- bool has_id;
- char * id;
- bool has_name;
- char * name;
- NetClientOptions * opts;
-};
-
-void qapi_free_NetLegacyList(NetLegacyList * obj);
-void qapi_free_NetLegacy(NetLegacy * obj);
-
-struct Netdev
-{
- char * id;
- NetClientOptions * opts;
-};
-
-void qapi_free_NetdevList(NetdevList * obj);
-void qapi_free_Netdev(Netdev * obj);
-
-struct InetSocketAddress
-{
- char * host;
- char * port;
- bool has_to;
- uint16_t to;
- bool has_ipv4;
- bool ipv4;
- bool has_ipv6;
- bool ipv6;
-};
-
-void qapi_free_InetSocketAddressList(InetSocketAddressList * obj);
-void qapi_free_InetSocketAddress(InetSocketAddress * obj);
-
-struct UnixSocketAddress
-{
- char * path;
-};
-
-void qapi_free_UnixSocketAddressList(UnixSocketAddressList * obj);
-void qapi_free_UnixSocketAddress(UnixSocketAddress * obj);
-
-struct SocketAddress
-{
- SocketAddressKind kind;
- union {
- void *data;
- InetSocketAddress * inet;
- UnixSocketAddress * q_unix;
- String * fd;
- };
-};
-void qapi_free_SocketAddressList(SocketAddressList * obj);
-void qapi_free_SocketAddress(SocketAddress * obj);
-
-struct MachineInfo
-{
- char * name;
- bool has_alias;
- char * alias;
- bool has_is_default;
- bool is_default;
- int64_t cpu_max;
-};
-
-void qapi_free_MachineInfoList(MachineInfoList * obj);
-void qapi_free_MachineInfo(MachineInfo * obj);
-
-struct CpuDefinitionInfo
-{
- char * name;
-};
-
-void qapi_free_CpuDefinitionInfoList(CpuDefinitionInfoList * obj);
-void qapi_free_CpuDefinitionInfo(CpuDefinitionInfo * obj);
-
-struct AddfdInfo
-{
- int64_t fdset_id;
- int64_t fd;
-};
-
-void qapi_free_AddfdInfoList(AddfdInfoList * obj);
-void qapi_free_AddfdInfo(AddfdInfo * obj);
-
-struct FdsetFdInfo
-{
- int64_t fd;
- bool has_opaque;
- char * opaque;
-};
-
-void qapi_free_FdsetFdInfoList(FdsetFdInfoList * obj);
-void qapi_free_FdsetFdInfo(FdsetFdInfo * obj);
-
-struct FdsetInfo
-{
- int64_t fdset_id;
- FdsetFdInfoList * fds;
-};
-
-void qapi_free_FdsetInfoList(FdsetInfoList * obj);
-void qapi_free_FdsetInfo(FdsetInfo * obj);
-
-struct TargetInfo
-{
- char * arch;
-};
-
-void qapi_free_TargetInfoList(TargetInfoList * obj);
-void qapi_free_TargetInfo(TargetInfo * obj);
-
-void qapi_free_QKeyCodeList(QKeyCodeList * obj);
-
-struct KeyValue
-{
- KeyValueKind kind;
- union {
- void *data;
- int64_t number;
- QKeyCode qcode;
- };
-};
-void qapi_free_KeyValueList(KeyValueList * obj);
-void qapi_free_KeyValue(KeyValue * obj);
-
-struct ChardevFile
-{
- bool has_in;
- char * in;
- char * out;
-};
-
-void qapi_free_ChardevFileList(ChardevFileList * obj);
-void qapi_free_ChardevFile(ChardevFile * obj);
-
-struct ChardevHostdev
-{
- char * device;
-};
-
-void qapi_free_ChardevHostdevList(ChardevHostdevList * obj);
-void qapi_free_ChardevHostdev(ChardevHostdev * obj);
-
-struct ChardevSocket
-{
- SocketAddress * addr;
- bool has_server;
- bool server;
- bool has_wait;
- bool wait;
- bool has_nodelay;
- bool nodelay;
- bool has_telnet;
- bool telnet;
-};
-
-void qapi_free_ChardevSocketList(ChardevSocketList * obj);
-void qapi_free_ChardevSocket(ChardevSocket * obj);
-
-struct ChardevUdp
-{
- SocketAddress * remote;
- bool has_local;
- SocketAddress * local;
-};
-
-void qapi_free_ChardevUdpList(ChardevUdpList * obj);
-void qapi_free_ChardevUdp(ChardevUdp * obj);
-
-struct ChardevMux
-{
- char * chardev;
-};
-
-void qapi_free_ChardevMuxList(ChardevMuxList * obj);
-void qapi_free_ChardevMux(ChardevMux * obj);
-
-struct ChardevStdio
-{
- bool has_signal;
- bool signal;
-};
-
-void qapi_free_ChardevStdioList(ChardevStdioList * obj);
-void qapi_free_ChardevStdio(ChardevStdio * obj);
-
-struct ChardevSpiceChannel
-{
- char * type;
-};
-
-void qapi_free_ChardevSpiceChannelList(ChardevSpiceChannelList * obj);
-void qapi_free_ChardevSpiceChannel(ChardevSpiceChannel * obj);
-
-struct ChardevSpicePort
-{
- char * fqdn;
-};
-
-void qapi_free_ChardevSpicePortList(ChardevSpicePortList * obj);
-void qapi_free_ChardevSpicePort(ChardevSpicePort * obj);
-
-struct ChardevVC
-{
- bool has_width;
- int64_t width;
- bool has_height;
- int64_t height;
- bool has_cols;
- int64_t cols;
- bool has_rows;
- int64_t rows;
-};
-
-void qapi_free_ChardevVCList(ChardevVCList * obj);
-void qapi_free_ChardevVC(ChardevVC * obj);
-
-struct ChardevMemory
-{
- bool has_size;
- int64_t size;
-};
-
-void qapi_free_ChardevMemoryList(ChardevMemoryList * obj);
-void qapi_free_ChardevMemory(ChardevMemory * obj);
-
-struct ChardevDummy
-{
-};
-
-void qapi_free_ChardevDummyList(ChardevDummyList * obj);
-void qapi_free_ChardevDummy(ChardevDummy * obj);
-
-struct ChardevBackend
-{
- ChardevBackendKind kind;
- union {
- void *data;
- ChardevFile * file;
- ChardevHostdev * serial;
- ChardevHostdev * parallel;
- ChardevHostdev * pipe;
- ChardevSocket * socket;
- ChardevUdp * udp;
- ChardevDummy * pty;
- ChardevDummy * null;
- ChardevMux * mux;
- ChardevDummy * msmouse;
- ChardevDummy * braille;
- ChardevStdio * stdio;
- ChardevDummy * console;
- ChardevSpiceChannel * spicevmc;
- ChardevSpicePort * spiceport;
- ChardevVC * vc;
- ChardevMemory * memory;
- };
-};
-void qapi_free_ChardevBackendList(ChardevBackendList * obj);
-void qapi_free_ChardevBackend(ChardevBackend * obj);
-
-struct ChardevReturn
-{
- bool has_pty;
- char * pty;
-};
-
-void qapi_free_ChardevReturnList(ChardevReturnList * obj);
-void qapi_free_ChardevReturn(ChardevReturn * obj);
-
-void qapi_free_TpmModelList(TpmModelList * obj);
-
-void qapi_free_TpmTypeList(TpmTypeList * obj);
-
-struct TPMPassthroughOptions
-{
- bool has_path;
- char * path;
- bool has_cancel_path;
- char * cancel_path;
-};
-
-void qapi_free_TPMPassthroughOptionsList(TPMPassthroughOptionsList * obj);
-void qapi_free_TPMPassthroughOptions(TPMPassthroughOptions * obj);
-
-struct TpmTypeOptions
-{
- TpmTypeOptionsKind kind;
- union {
- void *data;
- TPMPassthroughOptions * passthrough;
- };
-};
-void qapi_free_TpmTypeOptionsList(TpmTypeOptionsList * obj);
-void qapi_free_TpmTypeOptions(TpmTypeOptions * obj);
-
-struct TPMInfo
-{
- char * id;
- TpmModel model;
- TpmTypeOptions * options;
-};
-
-void qapi_free_TPMInfoList(TPMInfoList * obj);
-void qapi_free_TPMInfo(TPMInfo * obj);
-
-struct AcpiTableOptions
-{
- bool has_sig;
- char * sig;
- bool has_rev;
- uint8_t rev;
- bool has_oem_id;
- char * oem_id;
- bool has_oem_table_id;
- char * oem_table_id;
- bool has_oem_rev;
- uint32_t oem_rev;
- bool has_asl_compiler_id;
- char * asl_compiler_id;
- bool has_asl_compiler_rev;
- uint32_t asl_compiler_rev;
- bool has_file;
- char * file;
- bool has_data;
- char * data;
-};
-
-void qapi_free_AcpiTableOptionsList(AcpiTableOptionsList * obj);
-void qapi_free_AcpiTableOptions(AcpiTableOptions * obj);
-
-void qapi_free_CommandLineParameterTypeList(CommandLineParameterTypeList * obj);
-
-struct CommandLineParameterInfo
-{
- char * name;
- CommandLineParameterType type;
- bool has_help;
- char * help;
-};
-
-void qapi_free_CommandLineParameterInfoList(CommandLineParameterInfoList * obj);
-void qapi_free_CommandLineParameterInfo(CommandLineParameterInfo * obj);
-
-struct CommandLineOptionInfo
-{
- char * option;
- CommandLineParameterInfoList * parameters;
-};
-
-void qapi_free_CommandLineOptionInfoList(CommandLineOptionInfoList * obj);
-void qapi_free_CommandLineOptionInfo(CommandLineOptionInfo * obj);
-
-void qapi_free_X86CPURegister32List(X86CPURegister32List * obj);
-
-struct X86CPUFeatureWordInfo
-{
- int64_t cpuid_input_eax;
- bool has_cpuid_input_ecx;
- int64_t cpuid_input_ecx;
- X86CPURegister32 cpuid_register;
- int64_t features;
-};
-
-void qapi_free_X86CPUFeatureWordInfoList(X86CPUFeatureWordInfoList * obj);
-void qapi_free_X86CPUFeatureWordInfo(X86CPUFeatureWordInfo * obj);
-
-void qapi_free_RxStateList(RxStateList * obj);
-
-struct RxFilterInfo
-{
- char * name;
- bool promiscuous;
- RxState multicast;
- RxState unicast;
- bool broadcast_allowed;
- bool multicast_overflow;
- bool unicast_overflow;
- char * main_mac;
- intList * vlan_table;
- strList * unicast_table;
- strList * multicast_table;
-};
-
-void qapi_free_RxFilterInfoList(RxFilterInfoList * obj);
-void qapi_free_RxFilterInfo(RxFilterInfo * obj);
-
-#endif
diff --git a/contrib/qemu/qemu-coroutine-lock.c b/contrib/qemu/qemu-coroutine-lock.c
deleted file mode 100644
index d9fea4989d4..00000000000
--- a/contrib/qemu/qemu-coroutine-lock.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * coroutine queues and locks
- *
- * Copyright (c) 2011 Kevin Wolf <kwolf@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu-common.h"
-#include "block/coroutine.h"
-#include "block/coroutine_int.h"
-#include "qemu/queue.h"
-#include "trace.h"
-
-void qemu_co_queue_init(CoQueue *queue)
-{
- QTAILQ_INIT(&queue->entries);
-}
-
-void coroutine_fn qemu_co_queue_wait(CoQueue *queue)
-{
- Coroutine *self = qemu_coroutine_self();
- QTAILQ_INSERT_TAIL(&queue->entries, self, co_queue_next);
- qemu_coroutine_yield();
- assert(qemu_in_coroutine());
-}
-
-void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue)
-{
- Coroutine *self = qemu_coroutine_self();
- QTAILQ_INSERT_HEAD(&queue->entries, self, co_queue_next);
- qemu_coroutine_yield();
- assert(qemu_in_coroutine());
-}
-
-/**
- * qemu_co_queue_run_restart:
- *
- * Enter each coroutine that was previously marked for restart by
- * qemu_co_queue_next() or qemu_co_queue_restart_all(). This function is
- * invoked by the core coroutine code when the current coroutine yields or
- * terminates.
- */
-void qemu_co_queue_run_restart(Coroutine *co)
-{
- Coroutine *next;
-
- trace_qemu_co_queue_run_restart(co);
- while ((next = QTAILQ_FIRST(&co->co_queue_wakeup))) {
- QTAILQ_REMOVE(&co->co_queue_wakeup, next, co_queue_next);
- qemu_coroutine_enter(next, NULL);
- }
-}
-
-static bool qemu_co_queue_do_restart(CoQueue *queue, bool single)
-{
- Coroutine *self = qemu_coroutine_self();
- Coroutine *next;
-
- if (QTAILQ_EMPTY(&queue->entries)) {
- return false;
- }
-
- while ((next = QTAILQ_FIRST(&queue->entries)) != NULL) {
- QTAILQ_REMOVE(&queue->entries, next, co_queue_next);
- QTAILQ_INSERT_TAIL(&self->co_queue_wakeup, next, co_queue_next);
- trace_qemu_co_queue_next(next);
- if (single) {
- break;
- }
- }
- return true;
-}
-
-bool qemu_co_queue_next(CoQueue *queue)
-{
- return qemu_co_queue_do_restart(queue, true);
-}
-
-void qemu_co_queue_restart_all(CoQueue *queue)
-{
- qemu_co_queue_do_restart(queue, false);
-}
-
-bool qemu_co_queue_empty(CoQueue *queue)
-{
- return (QTAILQ_FIRST(&queue->entries) == NULL);
-}
-
-void qemu_co_mutex_init(CoMutex *mutex)
-{
- memset(mutex, 0, sizeof(*mutex));
- qemu_co_queue_init(&mutex->queue);
-}
-
-void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex)
-{
- Coroutine *self = qemu_coroutine_self();
-
- trace_qemu_co_mutex_lock_entry(mutex, self);
-
- while (mutex->locked) {
- qemu_co_queue_wait(&mutex->queue);
- }
-
- mutex->locked = true;
-
- trace_qemu_co_mutex_lock_return(mutex, self);
-}
-
-void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex)
-{
- Coroutine *self = qemu_coroutine_self();
-
- trace_qemu_co_mutex_unlock_entry(mutex, self);
-
- assert(mutex->locked == true);
- assert(qemu_in_coroutine());
-
- mutex->locked = false;
- qemu_co_queue_next(&mutex->queue);
-
- trace_qemu_co_mutex_unlock_return(mutex, self);
-}
-
-void qemu_co_rwlock_init(CoRwlock *lock)
-{
- memset(lock, 0, sizeof(*lock));
- qemu_co_queue_init(&lock->queue);
-}
-
-void qemu_co_rwlock_rdlock(CoRwlock *lock)
-{
- while (lock->writer) {
- qemu_co_queue_wait(&lock->queue);
- }
- lock->reader++;
-}
-
-void qemu_co_rwlock_unlock(CoRwlock *lock)
-{
- assert(qemu_in_coroutine());
- if (lock->writer) {
- lock->writer = false;
- qemu_co_queue_restart_all(&lock->queue);
- } else {
- lock->reader--;
- assert(lock->reader >= 0);
- /* Wakeup only one waiting writer */
- if (!lock->reader) {
- qemu_co_queue_next(&lock->queue);
- }
- }
-}
-
-void qemu_co_rwlock_wrlock(CoRwlock *lock)
-{
- while (lock->writer || lock->reader) {
- qemu_co_queue_wait(&lock->queue);
- }
- lock->writer = true;
-}
diff --git a/contrib/qemu/qemu-coroutine-sleep.c b/contrib/qemu/qemu-coroutine-sleep.c
deleted file mode 100644
index 169ce5ccc92..00000000000
--- a/contrib/qemu/qemu-coroutine-sleep.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * QEMU coroutine sleep
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "block/coroutine.h"
-#include "qemu/timer.h"
-
-typedef struct CoSleepCB {
- QEMUTimer *ts;
- Coroutine *co;
-} CoSleepCB;
-
-static void co_sleep_cb(void *opaque)
-{
- CoSleepCB *sleep_cb = opaque;
-
- qemu_coroutine_enter(sleep_cb->co, NULL);
-}
-
-void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns)
-{
- CoSleepCB sleep_cb = {
- .co = qemu_coroutine_self(),
- };
- sleep_cb.ts = qemu_new_timer(clock, SCALE_NS, co_sleep_cb, &sleep_cb);
- qemu_mod_timer(sleep_cb.ts, qemu_get_clock_ns(clock) + ns);
- qemu_coroutine_yield();
- qemu_del_timer(sleep_cb.ts);
- qemu_free_timer(sleep_cb.ts);
-}
diff --git a/contrib/qemu/qemu-coroutine.c b/contrib/qemu/qemu-coroutine.c
deleted file mode 100644
index 5e19307eeda..00000000000
--- a/contrib/qemu/qemu-coroutine.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * QEMU coroutines
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
- * Kevin Wolf <kwolf@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "trace.h"
-#include "qemu-common.h"
-#include "qemu/thread.h"
-#include "block/coroutine.h"
-#include "block/coroutine_int.h"
-
-enum {
- /* Maximum free pool size prevents holding too many freed coroutines */
- POOL_MAX_SIZE = 0,
-};
-
-/** Free list to speed up creation */
-static QemuMutex pool_lock;
-static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool);
-static unsigned int pool_size;
-
-Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
-{
- Coroutine *co;
-
- qemu_mutex_lock(&pool_lock);
- co = QSLIST_FIRST(&pool);
- if (co) {
- QSLIST_REMOVE_HEAD(&pool, pool_next);
- pool_size--;
- }
- qemu_mutex_unlock(&pool_lock);
-
- if (!co) {
- co = qemu_coroutine_new();
- }
-
- co->entry = entry;
- QTAILQ_INIT(&co->co_queue_wakeup);
- return co;
-}
-
-static void coroutine_delete(Coroutine *co)
-{
- qemu_mutex_lock(&pool_lock);
- if (pool_size < POOL_MAX_SIZE) {
- QSLIST_INSERT_HEAD(&pool, co, pool_next);
- co->caller = NULL;
- pool_size++;
- qemu_mutex_unlock(&pool_lock);
- return;
- }
- qemu_mutex_unlock(&pool_lock);
-
- qemu_coroutine_delete(co);
-}
-
-static void __attribute__((constructor)) coroutine_pool_init(void)
-{
- qemu_mutex_init(&pool_lock);
-}
-
-static void __attribute__((destructor)) coroutine_pool_cleanup(void)
-{
- Coroutine *co;
- Coroutine *tmp;
-
- QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
- QSLIST_REMOVE_HEAD(&pool, pool_next);
- qemu_coroutine_delete(co);
- }
-
- qemu_mutex_destroy(&pool_lock);
-}
-
-static void coroutine_swap(Coroutine *from, Coroutine *to)
-{
- CoroutineAction ret;
-
- ret = qemu_coroutine_switch(from, to, COROUTINE_YIELD);
-
- qemu_co_queue_run_restart(to);
-
- switch (ret) {
- case COROUTINE_YIELD:
- return;
- case COROUTINE_TERMINATE:
- trace_qemu_coroutine_terminate(to);
- coroutine_delete(to);
- return;
- default:
- abort();
- }
-}
-
-void qemu_coroutine_enter(Coroutine *co, void *opaque)
-{
- Coroutine *self = qemu_coroutine_self();
-
- trace_qemu_coroutine_enter(self, co, opaque);
-
- if (co->caller) {
- fprintf(stderr, "Co-routine re-entered recursively\n");
- abort();
- }
-
- co->caller = self;
- co->entry_arg = opaque;
- coroutine_swap(self, co);
-}
-
-void coroutine_fn qemu_coroutine_yield(void)
-{
- Coroutine *self = qemu_coroutine_self();
- Coroutine *to = self->caller;
-
- trace_qemu_coroutine_yield(self, to);
-
- if (!to) {
- fprintf(stderr, "Co-routine is yielding to no one\n");
- abort();
- }
-
- self->caller = NULL;
- coroutine_swap(self, to);
-}
diff --git a/contrib/qemu/qmp-commands.h b/contrib/qemu/qmp-commands.h
deleted file mode 100644
index fcc0ff0f7f0..00000000000
--- a/contrib/qemu/qmp-commands.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
-
-/*
- * schema-defined QAPI function prototypes
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QMP_COMMANDS_H
-#define QMP_COMMANDS_H
-
-#include "qapi-types.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/error.h"
-
-void qmp_add_client(const char * protocol, const char * fdname, bool has_skipauth, bool skipauth, bool has_tls, bool tls, Error **errp);
-int qmp_marshal_input_add_client(Monitor *mon, const QDict *qdict, QObject **ret);
-NameInfo * qmp_query_name(Error **errp);
-int qmp_marshal_input_query_name(Monitor *mon, const QDict *qdict, QObject **ret);
-VersionInfo * qmp_query_version(Error **errp);
-int qmp_marshal_input_query_version(Monitor *mon, const QDict *qdict, QObject **ret);
-KvmInfo * qmp_query_kvm(Error **errp);
-int qmp_marshal_input_query_kvm(Monitor *mon, const QDict *qdict, QObject **ret);
-StatusInfo * qmp_query_status(Error **errp);
-int qmp_marshal_input_query_status(Monitor *mon, const QDict *qdict, QObject **ret);
-UuidInfo * qmp_query_uuid(Error **errp);
-int qmp_marshal_input_query_uuid(Monitor *mon, const QDict *qdict, QObject **ret);
-ChardevInfoList * qmp_query_chardev(Error **errp);
-int qmp_marshal_input_query_chardev(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_ringbuf_write(const char * device, const char * data, bool has_format, DataFormat format, Error **errp);
-int qmp_marshal_input_ringbuf_write(Monitor *mon, const QDict *qdict, QObject **ret);
-char * qmp_ringbuf_read(const char * device, int64_t size, bool has_format, DataFormat format, Error **errp);
-int qmp_marshal_input_ringbuf_read(Monitor *mon, const QDict *qdict, QObject **ret);
-CommandInfoList * qmp_query_commands(Error **errp);
-int qmp_marshal_input_query_commands(Monitor *mon, const QDict *qdict, QObject **ret);
-EventInfoList * qmp_query_events(Error **errp);
-int qmp_marshal_input_query_events(Monitor *mon, const QDict *qdict, QObject **ret);
-MigrationInfo * qmp_query_migrate(Error **errp);
-int qmp_marshal_input_query_migrate(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_migrate_set_capabilities(MigrationCapabilityStatusList * capabilities, Error **errp);
-int qmp_marshal_input_migrate_set_capabilities(Monitor *mon, const QDict *qdict, QObject **ret);
-MigrationCapabilityStatusList * qmp_query_migrate_capabilities(Error **errp);
-int qmp_marshal_input_query_migrate_capabilities(Monitor *mon, const QDict *qdict, QObject **ret);
-MouseInfoList * qmp_query_mice(Error **errp);
-int qmp_marshal_input_query_mice(Monitor *mon, const QDict *qdict, QObject **ret);
-CpuInfoList * qmp_query_cpus(Error **errp);
-int qmp_marshal_input_query_cpus(Monitor *mon, const QDict *qdict, QObject **ret);
-BlockInfoList * qmp_query_block(Error **errp);
-int qmp_marshal_input_query_block(Monitor *mon, const QDict *qdict, QObject **ret);
-BlockStatsList * qmp_query_blockstats(Error **errp);
-int qmp_marshal_input_query_blockstats(Monitor *mon, const QDict *qdict, QObject **ret);
-VncInfo * qmp_query_vnc(Error **errp);
-int qmp_marshal_input_query_vnc(Monitor *mon, const QDict *qdict, QObject **ret);
-SpiceInfo * qmp_query_spice(Error **errp);
-int qmp_marshal_input_query_spice(Monitor *mon, const QDict *qdict, QObject **ret);
-BalloonInfo * qmp_query_balloon(Error **errp);
-int qmp_marshal_input_query_balloon(Monitor *mon, const QDict *qdict, QObject **ret);
-PciInfoList * qmp_query_pci(Error **errp);
-int qmp_marshal_input_query_pci(Monitor *mon, const QDict *qdict, QObject **ret);
-BlockJobInfoList * qmp_query_block_jobs(Error **errp);
-int qmp_marshal_input_query_block_jobs(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_quit(Error **errp);
-int qmp_marshal_input_quit(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_stop(Error **errp);
-int qmp_marshal_input_stop(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_system_reset(Error **errp);
-int qmp_marshal_input_system_reset(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_system_powerdown(Error **errp);
-int qmp_marshal_input_system_powerdown(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_cpu(int64_t index, Error **errp);
-int qmp_marshal_input_cpu(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_cpu_add(int64_t id, Error **errp);
-int qmp_marshal_input_cpu_add(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_memsave(int64_t val, int64_t size, const char * filename, bool has_cpu_index, int64_t cpu_index, Error **errp);
-int qmp_marshal_input_memsave(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_pmemsave(int64_t val, int64_t size, const char * filename, Error **errp);
-int qmp_marshal_input_pmemsave(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_cont(Error **errp);
-int qmp_marshal_input_cont(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_system_wakeup(Error **errp);
-int qmp_marshal_input_system_wakeup(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_inject_nmi(Error **errp);
-int qmp_marshal_input_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_set_link(const char * name, bool up, Error **errp);
-int qmp_marshal_input_set_link(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_passwd(const char * device, const char * password, Error **errp);
-int qmp_marshal_input_block_passwd(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_balloon(int64_t value, Error **errp);
-int qmp_marshal_input_balloon(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_resize(const char * device, int64_t size, Error **errp);
-int qmp_marshal_input_block_resize(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_transaction(TransactionActionList * actions, Error **errp);
-int qmp_marshal_input_transaction(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_blockdev_snapshot_sync(const char * device, const char * snapshot_file, bool has_format, const char * format, bool has_mode, NewImageMode mode, Error **errp);
-int qmp_marshal_input_blockdev_snapshot_sync(Monitor *mon, const QDict *qdict, QObject **ret);
-char * qmp_human_monitor_command(const char * command_line, bool has_cpu_index, int64_t cpu_index, Error **errp);
-int qmp_marshal_input_human_monitor_command(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_commit(const char * device, bool has_base, const char * base, const char * top, bool has_speed, int64_t speed, Error **errp);
-int qmp_marshal_input_block_commit(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_drive_backup(const char * device, const char * target, bool has_format, const char * format, MirrorSyncMode sync, bool has_mode, NewImageMode mode, bool has_speed, int64_t speed, bool has_on_source_error, BlockdevOnError on_source_error, bool has_on_target_error, BlockdevOnError on_target_error, Error **errp);
-int qmp_marshal_input_drive_backup(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_drive_mirror(const char * device, const char * target, bool has_format, const char * format, MirrorSyncMode sync, bool has_mode, NewImageMode mode, bool has_speed, int64_t speed, bool has_granularity, uint32_t granularity, bool has_buf_size, int64_t buf_size, bool has_on_source_error, BlockdevOnError on_source_error, bool has_on_target_error, BlockdevOnError on_target_error, Error **errp);
-int qmp_marshal_input_drive_mirror(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_migrate_cancel(Error **errp);
-int qmp_marshal_input_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_migrate_set_downtime(double value, Error **errp);
-int qmp_marshal_input_migrate_set_downtime(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_migrate_set_speed(int64_t value, Error **errp);
-int qmp_marshal_input_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_migrate_set_cache_size(int64_t value, Error **errp);
-int qmp_marshal_input_migrate_set_cache_size(Monitor *mon, const QDict *qdict, QObject **ret);
-int64_t qmp_query_migrate_cache_size(Error **errp);
-int qmp_marshal_input_query_migrate_cache_size(Monitor *mon, const QDict *qdict, QObject **ret);
-ObjectPropertyInfoList * qmp_qom_list(const char * path, Error **errp);
-int qmp_marshal_input_qom_list(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_set_password(const char * protocol, const char * password, bool has_connected, const char * connected, Error **errp);
-int qmp_marshal_input_set_password(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_expire_password(const char * protocol, const char * time, Error **errp);
-int qmp_marshal_input_expire_password(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_eject(const char * device, bool has_force, bool force, Error **errp);
-int qmp_marshal_input_eject(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_change_vnc_password(const char * password, Error **errp);
-int qmp_marshal_input_change_vnc_password(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_change(const char * device, const char * target, bool has_arg, const char * arg, Error **errp);
-int qmp_marshal_input_change(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_set_io_throttle(const char * device, int64_t bps, int64_t bps_rd, int64_t bps_wr, int64_t iops, int64_t iops_rd, int64_t iops_wr, Error **errp);
-int qmp_marshal_input_block_set_io_throttle(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_stream(const char * device, bool has_base, const char * base, bool has_speed, int64_t speed, bool has_on_error, BlockdevOnError on_error, Error **errp);
-int qmp_marshal_input_block_stream(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_job_set_speed(const char * device, int64_t speed, Error **errp);
-int qmp_marshal_input_block_job_set_speed(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_job_cancel(const char * device, bool has_force, bool force, Error **errp);
-int qmp_marshal_input_block_job_cancel(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_job_pause(const char * device, Error **errp);
-int qmp_marshal_input_block_job_pause(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_job_resume(const char * device, Error **errp);
-int qmp_marshal_input_block_job_resume(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_block_job_complete(const char * device, Error **errp);
-int qmp_marshal_input_block_job_complete(Monitor *mon, const QDict *qdict, QObject **ret);
-ObjectTypeInfoList * qmp_qom_list_types(bool has_implements, const char * implements, bool has_abstract, bool abstract, Error **errp);
-int qmp_marshal_input_qom_list_types(Monitor *mon, const QDict *qdict, QObject **ret);
-DevicePropertyInfoList * qmp_device_list_properties(const char * typename, Error **errp);
-int qmp_marshal_input_device_list_properties(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_migrate(const char * uri, bool has_blk, bool blk, bool has_inc, bool inc, bool has_detach, bool detach, Error **errp);
-int qmp_marshal_input_migrate(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_xen_save_devices_state(const char * filename, Error **errp);
-int qmp_marshal_input_xen_save_devices_state(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_xen_set_global_dirty_log(bool enable, Error **errp);
-int qmp_marshal_input_xen_set_global_dirty_log(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_device_del(const char * id, Error **errp);
-int qmp_marshal_input_device_del(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_dump_guest_memory(bool paging, const char * protocol, bool has_begin, int64_t begin, bool has_length, int64_t length, Error **errp);
-int qmp_marshal_input_dump_guest_memory(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_netdev_del(const char * id, Error **errp);
-int qmp_marshal_input_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_getfd(const char * fdname, Error **errp);
-int qmp_marshal_input_getfd(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_closefd(const char * fdname, Error **errp);
-int qmp_marshal_input_closefd(Monitor *mon, const QDict *qdict, QObject **ret);
-MachineInfoList * qmp_query_machines(Error **errp);
-int qmp_marshal_input_query_machines(Monitor *mon, const QDict *qdict, QObject **ret);
-CpuDefinitionInfoList * qmp_query_cpu_definitions(Error **errp);
-int qmp_marshal_input_query_cpu_definitions(Monitor *mon, const QDict *qdict, QObject **ret);
-AddfdInfo * qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque, const char * opaque, Error **errp);
-int qmp_marshal_input_add_fd(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp);
-int qmp_marshal_input_remove_fd(Monitor *mon, const QDict *qdict, QObject **ret);
-FdsetInfoList * qmp_query_fdsets(Error **errp);
-int qmp_marshal_input_query_fdsets(Monitor *mon, const QDict *qdict, QObject **ret);
-TargetInfo * qmp_query_target(Error **errp);
-int qmp_marshal_input_query_target(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_send_key(KeyValueList * keys, bool has_hold_time, int64_t hold_time, Error **errp);
-int qmp_marshal_input_send_key(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_screendump(const char * filename, Error **errp);
-int qmp_marshal_input_screendump(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_nbd_server_start(SocketAddress * addr, Error **errp);
-int qmp_marshal_input_nbd_server_start(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_nbd_server_add(const char * device, bool has_writable, bool writable, Error **errp);
-int qmp_marshal_input_nbd_server_add(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_nbd_server_stop(Error **errp);
-int qmp_marshal_input_nbd_server_stop(Monitor *mon, const QDict *qdict, QObject **ret);
-ChardevReturn * qmp_chardev_add(const char * id, ChardevBackend * backend, Error **errp);
-int qmp_marshal_input_chardev_add(Monitor *mon, const QDict *qdict, QObject **ret);
-void qmp_chardev_remove(const char * id, Error **errp);
-int qmp_marshal_input_chardev_remove(Monitor *mon, const QDict *qdict, QObject **ret);
-TpmModelList * qmp_query_tpm_models(Error **errp);
-int qmp_marshal_input_query_tpm_models(Monitor *mon, const QDict *qdict, QObject **ret);
-TpmTypeList * qmp_query_tpm_types(Error **errp);
-int qmp_marshal_input_query_tpm_types(Monitor *mon, const QDict *qdict, QObject **ret);
-TPMInfoList * qmp_query_tpm(Error **errp);
-int qmp_marshal_input_query_tpm(Monitor *mon, const QDict *qdict, QObject **ret);
-CommandLineOptionInfoList * qmp_query_command_line_options(bool has_option, const char * option, Error **errp);
-int qmp_marshal_input_query_command_line_options(Monitor *mon, const QDict *qdict, QObject **ret);
-RxFilterInfoList * qmp_query_rx_filter(bool has_name, const char * name, Error **errp);
-int qmp_marshal_input_query_rx_filter(Monitor *mon, const QDict *qdict, QObject **ret);
-
-#endif
diff --git a/contrib/qemu/qobject/json-lexer.c b/contrib/qemu/qobject/json-lexer.c
deleted file mode 100644
index 440df60392b..00000000000
--- a/contrib/qemu/qobject/json-lexer.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * JSON lexer
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qapi/qmp/qstring.h"
-#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qint.h"
-#include "qemu-common.h"
-#include "qapi/qmp/json-lexer.h"
-
-#define MAX_TOKEN_SIZE (64ULL << 20)
-
-/*
- * \"([^\\\"]|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*\"
- * '([^\\']|(\\\"\\'\\\\\\/\\b\\f\\n\\r\\t\\u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))*'
- * 0|([1-9][0-9]*(.[0-9]+)?([eE]([-+])?[0-9]+))
- * [{}\[\],:]
- * [a-z]+
- *
- */
-
-enum json_lexer_state {
- IN_ERROR = 0,
- IN_DQ_UCODE3,
- IN_DQ_UCODE2,
- IN_DQ_UCODE1,
- IN_DQ_UCODE0,
- IN_DQ_STRING_ESCAPE,
- IN_DQ_STRING,
- IN_SQ_UCODE3,
- IN_SQ_UCODE2,
- IN_SQ_UCODE1,
- IN_SQ_UCODE0,
- IN_SQ_STRING_ESCAPE,
- IN_SQ_STRING,
- IN_ZERO,
- IN_DIGITS,
- IN_DIGIT,
- IN_EXP_E,
- IN_MANTISSA,
- IN_MANTISSA_DIGITS,
- IN_NONZERO_NUMBER,
- IN_NEG_NONZERO_NUMBER,
- IN_KEYWORD,
- IN_ESCAPE,
- IN_ESCAPE_L,
- IN_ESCAPE_LL,
- IN_ESCAPE_I,
- IN_ESCAPE_I6,
- IN_ESCAPE_I64,
- IN_WHITESPACE,
- IN_START,
-};
-
-#define TERMINAL(state) [0 ... 0x7F] = (state)
-
-/* Return whether TERMINAL is a terminal state and the transition to it
- from OLD_STATE required lookahead. This happens whenever the table
- below uses the TERMINAL macro. */
-#define TERMINAL_NEEDED_LOOKAHEAD(old_state, terminal) \
- (json_lexer[(old_state)][0] == (terminal))
-
-static const uint8_t json_lexer[][256] = {
- /* double quote string */
- [IN_DQ_UCODE3] = {
- ['0' ... '9'] = IN_DQ_STRING,
- ['a' ... 'f'] = IN_DQ_STRING,
- ['A' ... 'F'] = IN_DQ_STRING,
- },
- [IN_DQ_UCODE2] = {
- ['0' ... '9'] = IN_DQ_UCODE3,
- ['a' ... 'f'] = IN_DQ_UCODE3,
- ['A' ... 'F'] = IN_DQ_UCODE3,
- },
- [IN_DQ_UCODE1] = {
- ['0' ... '9'] = IN_DQ_UCODE2,
- ['a' ... 'f'] = IN_DQ_UCODE2,
- ['A' ... 'F'] = IN_DQ_UCODE2,
- },
- [IN_DQ_UCODE0] = {
- ['0' ... '9'] = IN_DQ_UCODE1,
- ['a' ... 'f'] = IN_DQ_UCODE1,
- ['A' ... 'F'] = IN_DQ_UCODE1,
- },
- [IN_DQ_STRING_ESCAPE] = {
- ['b'] = IN_DQ_STRING,
- ['f'] = IN_DQ_STRING,
- ['n'] = IN_DQ_STRING,
- ['r'] = IN_DQ_STRING,
- ['t'] = IN_DQ_STRING,
- ['/'] = IN_DQ_STRING,
- ['\\'] = IN_DQ_STRING,
- ['\''] = IN_DQ_STRING,
- ['\"'] = IN_DQ_STRING,
- ['u'] = IN_DQ_UCODE0,
- },
- [IN_DQ_STRING] = {
- [1 ... 0xBF] = IN_DQ_STRING,
- [0xC2 ... 0xF4] = IN_DQ_STRING,
- ['\\'] = IN_DQ_STRING_ESCAPE,
- ['"'] = JSON_STRING,
- },
-
- /* single quote string */
- [IN_SQ_UCODE3] = {
- ['0' ... '9'] = IN_SQ_STRING,
- ['a' ... 'f'] = IN_SQ_STRING,
- ['A' ... 'F'] = IN_SQ_STRING,
- },
- [IN_SQ_UCODE2] = {
- ['0' ... '9'] = IN_SQ_UCODE3,
- ['a' ... 'f'] = IN_SQ_UCODE3,
- ['A' ... 'F'] = IN_SQ_UCODE3,
- },
- [IN_SQ_UCODE1] = {
- ['0' ... '9'] = IN_SQ_UCODE2,
- ['a' ... 'f'] = IN_SQ_UCODE2,
- ['A' ... 'F'] = IN_SQ_UCODE2,
- },
- [IN_SQ_UCODE0] = {
- ['0' ... '9'] = IN_SQ_UCODE1,
- ['a' ... 'f'] = IN_SQ_UCODE1,
- ['A' ... 'F'] = IN_SQ_UCODE1,
- },
- [IN_SQ_STRING_ESCAPE] = {
- ['b'] = IN_SQ_STRING,
- ['f'] = IN_SQ_STRING,
- ['n'] = IN_SQ_STRING,
- ['r'] = IN_SQ_STRING,
- ['t'] = IN_SQ_STRING,
- ['/'] = IN_DQ_STRING,
- ['\\'] = IN_DQ_STRING,
- ['\''] = IN_SQ_STRING,
- ['\"'] = IN_SQ_STRING,
- ['u'] = IN_SQ_UCODE0,
- },
- [IN_SQ_STRING] = {
- [1 ... 0xBF] = IN_SQ_STRING,
- [0xC2 ... 0xF4] = IN_SQ_STRING,
- ['\\'] = IN_SQ_STRING_ESCAPE,
- ['\''] = JSON_STRING,
- },
-
- /* Zero */
- [IN_ZERO] = {
- TERMINAL(JSON_INTEGER),
- ['0' ... '9'] = IN_ERROR,
- ['.'] = IN_MANTISSA,
- },
-
- /* Float */
- [IN_DIGITS] = {
- TERMINAL(JSON_FLOAT),
- ['0' ... '9'] = IN_DIGITS,
- },
-
- [IN_DIGIT] = {
- ['0' ... '9'] = IN_DIGITS,
- },
-
- [IN_EXP_E] = {
- ['-'] = IN_DIGIT,
- ['+'] = IN_DIGIT,
- ['0' ... '9'] = IN_DIGITS,
- },
-
- [IN_MANTISSA_DIGITS] = {
- TERMINAL(JSON_FLOAT),
- ['0' ... '9'] = IN_MANTISSA_DIGITS,
- ['e'] = IN_EXP_E,
- ['E'] = IN_EXP_E,
- },
-
- [IN_MANTISSA] = {
- ['0' ... '9'] = IN_MANTISSA_DIGITS,
- },
-
- /* Number */
- [IN_NONZERO_NUMBER] = {
- TERMINAL(JSON_INTEGER),
- ['0' ... '9'] = IN_NONZERO_NUMBER,
- ['e'] = IN_EXP_E,
- ['E'] = IN_EXP_E,
- ['.'] = IN_MANTISSA,
- },
-
- [IN_NEG_NONZERO_NUMBER] = {
- ['0'] = IN_ZERO,
- ['1' ... '9'] = IN_NONZERO_NUMBER,
- },
-
- /* keywords */
- [IN_KEYWORD] = {
- TERMINAL(JSON_KEYWORD),
- ['a' ... 'z'] = IN_KEYWORD,
- },
-
- /* whitespace */
- [IN_WHITESPACE] = {
- TERMINAL(JSON_SKIP),
- [' '] = IN_WHITESPACE,
- ['\t'] = IN_WHITESPACE,
- ['\r'] = IN_WHITESPACE,
- ['\n'] = IN_WHITESPACE,
- },
-
- /* escape */
- [IN_ESCAPE_LL] = {
- ['d'] = JSON_ESCAPE,
- },
-
- [IN_ESCAPE_L] = {
- ['d'] = JSON_ESCAPE,
- ['l'] = IN_ESCAPE_LL,
- },
-
- [IN_ESCAPE_I64] = {
- ['d'] = JSON_ESCAPE,
- },
-
- [IN_ESCAPE_I6] = {
- ['4'] = IN_ESCAPE_I64,
- },
-
- [IN_ESCAPE_I] = {
- ['6'] = IN_ESCAPE_I6,
- },
-
- [IN_ESCAPE] = {
- ['d'] = JSON_ESCAPE,
- ['i'] = JSON_ESCAPE,
- ['p'] = JSON_ESCAPE,
- ['s'] = JSON_ESCAPE,
- ['f'] = JSON_ESCAPE,
- ['l'] = IN_ESCAPE_L,
- ['I'] = IN_ESCAPE_I,
- },
-
- /* top level rule */
- [IN_START] = {
- ['"'] = IN_DQ_STRING,
- ['\''] = IN_SQ_STRING,
- ['0'] = IN_ZERO,
- ['1' ... '9'] = IN_NONZERO_NUMBER,
- ['-'] = IN_NEG_NONZERO_NUMBER,
- ['{'] = JSON_OPERATOR,
- ['}'] = JSON_OPERATOR,
- ['['] = JSON_OPERATOR,
- [']'] = JSON_OPERATOR,
- [','] = JSON_OPERATOR,
- [':'] = JSON_OPERATOR,
- ['a' ... 'z'] = IN_KEYWORD,
- ['%'] = IN_ESCAPE,
- [' '] = IN_WHITESPACE,
- ['\t'] = IN_WHITESPACE,
- ['\r'] = IN_WHITESPACE,
- ['\n'] = IN_WHITESPACE,
- },
-};
-
-void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func)
-{
- lexer->emit = func;
- lexer->state = IN_START;
- lexer->token = qstring_new();
- lexer->x = lexer->y = 0;
-}
-
-static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
-{
- int char_consumed, new_state;
-
- lexer->x++;
- if (ch == '\n') {
- lexer->x = 0;
- lexer->y++;
- }
-
- do {
- new_state = json_lexer[lexer->state][(uint8_t)ch];
- char_consumed = !TERMINAL_NEEDED_LOOKAHEAD(lexer->state, new_state);
- if (char_consumed) {
- qstring_append_chr(lexer->token, ch);
- }
-
- switch (new_state) {
- case JSON_OPERATOR:
- case JSON_ESCAPE:
- case JSON_INTEGER:
- case JSON_FLOAT:
- case JSON_KEYWORD:
- case JSON_STRING:
- lexer->emit(lexer, lexer->token, new_state, lexer->x, lexer->y);
- /* fall through */
- case JSON_SKIP:
- QDECREF(lexer->token);
- lexer->token = qstring_new();
- new_state = IN_START;
- break;
- case IN_ERROR:
- /* XXX: To avoid having previous bad input leaving the parser in an
- * unresponsive state where we consume unpredictable amounts of
- * subsequent "good" input, percolate this error state up to the
- * tokenizer/parser by forcing a NULL object to be emitted, then
- * reset state.
- *
- * Also note that this handling is required for reliable channel
- * negotiation between QMP and the guest agent, since chr(0xFF)
- * is placed at the beginning of certain events to ensure proper
- * delivery when the channel is in an unknown state. chr(0xFF) is
- * never a valid ASCII/UTF-8 sequence, so this should reliably
- * induce an error/flush state.
- */
- lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y);
- QDECREF(lexer->token);
- lexer->token = qstring_new();
- new_state = IN_START;
- lexer->state = new_state;
- return 0;
- default:
- break;
- }
- lexer->state = new_state;
- } while (!char_consumed && !flush);
-
- /* Do not let a single token grow to an arbitrarily large size,
- * this is a security consideration.
- */
- if (lexer->token->length > MAX_TOKEN_SIZE) {
- lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y);
- QDECREF(lexer->token);
- lexer->token = qstring_new();
- lexer->state = IN_START;
- }
-
- return 0;
-}
-
-int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size)
-{
- size_t i;
-
- for (i = 0; i < size; i++) {
- int err;
-
- err = json_lexer_feed_char(lexer, buffer[i], false);
- if (err < 0) {
- return err;
- }
- }
-
- return 0;
-}
-
-int json_lexer_flush(JSONLexer *lexer)
-{
- return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0, true);
-}
-
-void json_lexer_destroy(JSONLexer *lexer)
-{
- QDECREF(lexer->token);
-}
diff --git a/contrib/qemu/qobject/json-parser.c b/contrib/qemu/qobject/json-parser.c
deleted file mode 100644
index e7947b340c1..00000000000
--- a/contrib/qemu/qobject/json-parser.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * JSON Parser
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include <stdarg.h>
-
-#include "qemu-common.h"
-#include "qapi/qmp/qstring.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qfloat.h"
-#include "qapi/qmp/qbool.h"
-#include "qapi/qmp/json-parser.h"
-#include "qapi/qmp/json-lexer.h"
-#include "qapi/qmp/qerror.h"
-
-typedef struct JSONParserContext
-{
- Error *err;
- struct {
- QObject **buf;
- size_t pos;
- size_t count;
- } tokens;
-} JSONParserContext;
-
-#define BUG_ON(cond) assert(!(cond))
-
-/**
- * TODO
- *
- * 0) make errors meaningful again
- * 1) add geometry information to tokens
- * 3) should we return a parsed size?
- * 4) deal with premature EOI
- */
-
-static QObject *parse_value(JSONParserContext *ctxt, va_list *ap);
-
-/**
- * Token manipulators
- *
- * tokens are dictionaries that contain a type, a string value, and geometry information
- * about a token identified by the lexer. These are routines that make working with
- * these objects a bit easier.
- */
-static const char *token_get_value(QObject *obj)
-{
- return qdict_get_str(qobject_to_qdict(obj), "token");
-}
-
-static JSONTokenType token_get_type(QObject *obj)
-{
- return qdict_get_int(qobject_to_qdict(obj), "type");
-}
-
-static int token_is_operator(QObject *obj, char op)
-{
- const char *val;
-
- if (token_get_type(obj) != JSON_OPERATOR) {
- return 0;
- }
-
- val = token_get_value(obj);
-
- return (val[0] == op) && (val[1] == 0);
-}
-
-static int token_is_keyword(QObject *obj, const char *value)
-{
- if (token_get_type(obj) != JSON_KEYWORD) {
- return 0;
- }
-
- return strcmp(token_get_value(obj), value) == 0;
-}
-
-static int token_is_escape(QObject *obj, const char *value)
-{
- if (token_get_type(obj) != JSON_ESCAPE) {
- return 0;
- }
-
- return (strcmp(token_get_value(obj), value) == 0);
-}
-
-/**
- * Error handler
- */
-static void GCC_FMT_ATTR(3, 4) parse_error(JSONParserContext *ctxt,
- QObject *token, const char *msg, ...)
-{
- va_list ap;
- char message[1024];
- va_start(ap, msg);
- vsnprintf(message, sizeof(message), msg, ap);
- va_end(ap);
- if (ctxt->err) {
- error_free(ctxt->err);
- ctxt->err = NULL;
- }
- error_set(&ctxt->err, QERR_JSON_PARSE_ERROR, message);
-}
-
-/**
- * String helpers
- *
- * These helpers are used to unescape strings.
- */
-static void wchar_to_utf8(uint16_t wchar, char *buffer, size_t buffer_length)
-{
- if (wchar <= 0x007F) {
- BUG_ON(buffer_length < 2);
-
- buffer[0] = wchar & 0x7F;
- buffer[1] = 0;
- } else if (wchar <= 0x07FF) {
- BUG_ON(buffer_length < 3);
-
- buffer[0] = 0xC0 | ((wchar >> 6) & 0x1F);
- buffer[1] = 0x80 | (wchar & 0x3F);
- buffer[2] = 0;
- } else {
- BUG_ON(buffer_length < 4);
-
- buffer[0] = 0xE0 | ((wchar >> 12) & 0x0F);
- buffer[1] = 0x80 | ((wchar >> 6) & 0x3F);
- buffer[2] = 0x80 | (wchar & 0x3F);
- buffer[3] = 0;
- }
-}
-
-static int hex2decimal(char ch)
-{
- if (ch >= '0' && ch <= '9') {
- return (ch - '0');
- } else if (ch >= 'a' && ch <= 'f') {
- return 10 + (ch - 'a');
- } else if (ch >= 'A' && ch <= 'F') {
- return 10 + (ch - 'A');
- }
-
- return -1;
-}
-
-/**
- * parse_string(): Parse a json string and return a QObject
- *
- * string
- * ""
- * " chars "
- * chars
- * char
- * char chars
- * char
- * any-Unicode-character-
- * except-"-or-\-or-
- * control-character
- * \"
- * \\
- * \/
- * \b
- * \f
- * \n
- * \r
- * \t
- * \u four-hex-digits
- */
-static QString *qstring_from_escaped_str(JSONParserContext *ctxt, QObject *token)
-{
- const char *ptr = token_get_value(token);
- QString *str;
- int double_quote = 1;
-
- if (*ptr == '"') {
- double_quote = 1;
- } else {
- double_quote = 0;
- }
- ptr++;
-
- str = qstring_new();
- while (*ptr &&
- ((double_quote && *ptr != '"') || (!double_quote && *ptr != '\''))) {
- if (*ptr == '\\') {
- ptr++;
-
- switch (*ptr) {
- case '"':
- qstring_append(str, "\"");
- ptr++;
- break;
- case '\'':
- qstring_append(str, "'");
- ptr++;
- break;
- case '\\':
- qstring_append(str, "\\");
- ptr++;
- break;
- case '/':
- qstring_append(str, "/");
- ptr++;
- break;
- case 'b':
- qstring_append(str, "\b");
- ptr++;
- break;
- case 'f':
- qstring_append(str, "\f");
- ptr++;
- break;
- case 'n':
- qstring_append(str, "\n");
- ptr++;
- break;
- case 'r':
- qstring_append(str, "\r");
- ptr++;
- break;
- case 't':
- qstring_append(str, "\t");
- ptr++;
- break;
- case 'u': {
- uint16_t unicode_char = 0;
- char utf8_char[4];
- int i = 0;
-
- ptr++;
-
- for (i = 0; i < 4; i++) {
- if (qemu_isxdigit(*ptr)) {
- unicode_char |= hex2decimal(*ptr) << ((3 - i) * 4);
- } else {
- parse_error(ctxt, token,
- "invalid hex escape sequence in string");
- goto out;
- }
- ptr++;
- }
-
- wchar_to_utf8(unicode_char, utf8_char, sizeof(utf8_char));
- qstring_append(str, utf8_char);
- } break;
- default:
- parse_error(ctxt, token, "invalid escape sequence in string");
- goto out;
- }
- } else {
- char dummy[2];
-
- dummy[0] = *ptr++;
- dummy[1] = 0;
-
- qstring_append(str, dummy);
- }
- }
-
- return str;
-
-out:
- QDECREF(str);
- return NULL;
-}
-
-static QObject *parser_context_pop_token(JSONParserContext *ctxt)
-{
- QObject *token;
- g_assert(ctxt->tokens.pos < ctxt->tokens.count);
- token = ctxt->tokens.buf[ctxt->tokens.pos];
- ctxt->tokens.pos++;
- return token;
-}
-
-/* Note: parser_context_{peek|pop}_token do not increment the
- * token object's refcount. In both cases the references will continue
- * to be tracked and cleaned up in parser_context_free(), so do not
- * attempt to free the token object.
- */
-static QObject *parser_context_peek_token(JSONParserContext *ctxt)
-{
- QObject *token;
- g_assert(ctxt->tokens.pos < ctxt->tokens.count);
- token = ctxt->tokens.buf[ctxt->tokens.pos];
- return token;
-}
-
-static JSONParserContext parser_context_save(JSONParserContext *ctxt)
-{
- JSONParserContext saved_ctxt = {0};
- saved_ctxt.tokens.pos = ctxt->tokens.pos;
- saved_ctxt.tokens.count = ctxt->tokens.count;
- saved_ctxt.tokens.buf = ctxt->tokens.buf;
- return saved_ctxt;
-}
-
-static void parser_context_restore(JSONParserContext *ctxt,
- JSONParserContext saved_ctxt)
-{
- ctxt->tokens.pos = saved_ctxt.tokens.pos;
- ctxt->tokens.count = saved_ctxt.tokens.count;
- ctxt->tokens.buf = saved_ctxt.tokens.buf;
-}
-
-static void tokens_append_from_iter(QObject *obj, void *opaque)
-{
- JSONParserContext *ctxt = opaque;
- g_assert(ctxt->tokens.pos < ctxt->tokens.count);
- ctxt->tokens.buf[ctxt->tokens.pos++] = obj;
- qobject_incref(obj);
-}
-
-static JSONParserContext *parser_context_new(QList *tokens)
-{
- JSONParserContext *ctxt;
- size_t count;
-
- if (!tokens) {
- return NULL;
- }
-
- count = qlist_size(tokens);
- if (count == 0) {
- return NULL;
- }
-
- ctxt = g_malloc0(sizeof(JSONParserContext));
- ctxt->tokens.pos = 0;
- ctxt->tokens.count = count;
- ctxt->tokens.buf = g_malloc(count * sizeof(QObject *));
- qlist_iter(tokens, tokens_append_from_iter, ctxt);
- ctxt->tokens.pos = 0;
-
- return ctxt;
-}
-
-/* to support error propagation, ctxt->err must be freed separately */
-static void parser_context_free(JSONParserContext *ctxt)
-{
- int i;
- if (ctxt) {
- for (i = 0; i < ctxt->tokens.count; i++) {
- qobject_decref(ctxt->tokens.buf[i]);
- }
- g_free(ctxt->tokens.buf);
- g_free(ctxt);
- }
-}
-
-/**
- * Parsing rules
- */
-static int parse_pair(JSONParserContext *ctxt, QDict *dict, va_list *ap)
-{
- QObject *key = NULL, *token = NULL, *value, *peek;
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
-
- peek = parser_context_peek_token(ctxt);
- if (peek == NULL) {
- parse_error(ctxt, NULL, "premature EOI");
- goto out;
- }
-
- key = parse_value(ctxt, ap);
- if (!key || qobject_type(key) != QTYPE_QSTRING) {
- parse_error(ctxt, peek, "key is not a string in object");
- goto out;
- }
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- parse_error(ctxt, NULL, "premature EOI");
- goto out;
- }
-
- if (!token_is_operator(token, ':')) {
- parse_error(ctxt, token, "missing : in object pair");
- goto out;
- }
-
- value = parse_value(ctxt, ap);
- if (value == NULL) {
- parse_error(ctxt, token, "Missing value in dict");
- goto out;
- }
-
- qdict_put_obj(dict, qstring_get_str(qobject_to_qstring(key)), value);
-
- qobject_decref(key);
-
- return 0;
-
-out:
- parser_context_restore(ctxt, saved_ctxt);
- qobject_decref(key);
-
- return -1;
-}
-
-static QObject *parse_object(JSONParserContext *ctxt, va_list *ap)
-{
- QDict *dict = NULL;
- QObject *token, *peek;
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- goto out;
- }
-
- if (!token_is_operator(token, '{')) {
- goto out;
- }
- token = NULL;
-
- dict = qdict_new();
-
- peek = parser_context_peek_token(ctxt);
- if (peek == NULL) {
- parse_error(ctxt, NULL, "premature EOI");
- goto out;
- }
-
- if (!token_is_operator(peek, '}')) {
- if (parse_pair(ctxt, dict, ap) == -1) {
- goto out;
- }
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- parse_error(ctxt, NULL, "premature EOI");
- goto out;
- }
-
- while (!token_is_operator(token, '}')) {
- if (!token_is_operator(token, ',')) {
- parse_error(ctxt, token, "expected separator in dict");
- goto out;
- }
- token = NULL;
-
- if (parse_pair(ctxt, dict, ap) == -1) {
- goto out;
- }
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- parse_error(ctxt, NULL, "premature EOI");
- goto out;
- }
- }
- token = NULL;
- } else {
- token = parser_context_pop_token(ctxt);
- token = NULL;
- }
-
- return QOBJECT(dict);
-
-out:
- parser_context_restore(ctxt, saved_ctxt);
- QDECREF(dict);
- return NULL;
-}
-
-static QObject *parse_array(JSONParserContext *ctxt, va_list *ap)
-{
- QList *list = NULL;
- QObject *token, *peek;
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- goto out;
- }
-
- if (!token_is_operator(token, '[')) {
- token = NULL;
- goto out;
- }
- token = NULL;
-
- list = qlist_new();
-
- peek = parser_context_peek_token(ctxt);
- if (peek == NULL) {
- parse_error(ctxt, NULL, "premature EOI");
- goto out;
- }
-
- if (!token_is_operator(peek, ']')) {
- QObject *obj;
-
- obj = parse_value(ctxt, ap);
- if (obj == NULL) {
- parse_error(ctxt, token, "expecting value");
- goto out;
- }
-
- qlist_append_obj(list, obj);
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- parse_error(ctxt, NULL, "premature EOI");
- goto out;
- }
-
- while (!token_is_operator(token, ']')) {
- if (!token_is_operator(token, ',')) {
- parse_error(ctxt, token, "expected separator in list");
- goto out;
- }
-
- token = NULL;
-
- obj = parse_value(ctxt, ap);
- if (obj == NULL) {
- parse_error(ctxt, token, "expecting value");
- goto out;
- }
-
- qlist_append_obj(list, obj);
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- parse_error(ctxt, NULL, "premature EOI");
- goto out;
- }
- }
-
- token = NULL;
- } else {
- token = parser_context_pop_token(ctxt);
- token = NULL;
- }
-
- return QOBJECT(list);
-
-out:
- parser_context_restore(ctxt, saved_ctxt);
- QDECREF(list);
- return NULL;
-}
-
-static QObject *parse_keyword(JSONParserContext *ctxt)
-{
- QObject *token, *ret;
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- goto out;
- }
-
- if (token_get_type(token) != JSON_KEYWORD) {
- goto out;
- }
-
- if (token_is_keyword(token, "true")) {
- ret = QOBJECT(qbool_from_int(true));
- } else if (token_is_keyword(token, "false")) {
- ret = QOBJECT(qbool_from_int(false));
- } else {
- parse_error(ctxt, token, "invalid keyword `%s'", token_get_value(token));
- goto out;
- }
-
- return ret;
-
-out:
- parser_context_restore(ctxt, saved_ctxt);
-
- return NULL;
-}
-
-static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
-{
- QObject *token = NULL, *obj;
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
-
- if (ap == NULL) {
- goto out;
- }
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- goto out;
- }
-
- if (token_is_escape(token, "%p")) {
- obj = va_arg(*ap, QObject *);
- } else if (token_is_escape(token, "%i")) {
- obj = QOBJECT(qbool_from_int(va_arg(*ap, int)));
- } else if (token_is_escape(token, "%d")) {
- obj = QOBJECT(qint_from_int(va_arg(*ap, int)));
- } else if (token_is_escape(token, "%ld")) {
- obj = QOBJECT(qint_from_int(va_arg(*ap, long)));
- } else if (token_is_escape(token, "%lld") ||
- token_is_escape(token, "%I64d")) {
- obj = QOBJECT(qint_from_int(va_arg(*ap, long long)));
- } else if (token_is_escape(token, "%s")) {
- obj = QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
- } else if (token_is_escape(token, "%f")) {
- obj = QOBJECT(qfloat_from_double(va_arg(*ap, double)));
- } else {
- goto out;
- }
-
- return obj;
-
-out:
- parser_context_restore(ctxt, saved_ctxt);
-
- return NULL;
-}
-
-static QObject *parse_literal(JSONParserContext *ctxt)
-{
- QObject *token, *obj;
- JSONParserContext saved_ctxt = parser_context_save(ctxt);
-
- token = parser_context_pop_token(ctxt);
- if (token == NULL) {
- goto out;
- }
-
- switch (token_get_type(token)) {
- case JSON_STRING:
- obj = QOBJECT(qstring_from_escaped_str(ctxt, token));
- break;
- case JSON_INTEGER: {
- /* A possibility exists that this is a whole-valued float where the
- * fractional part was left out due to being 0 (.0). It's not a big
- * deal to treat these as ints in the parser, so long as users of the
- * resulting QObject know to expect a QInt in place of a QFloat in
- * cases like these.
- *
- * However, in some cases these values will overflow/underflow a
- * QInt/int64 container, thus we should assume these are to be handled
- * as QFloats/doubles rather than silently changing their values.
- *
- * strtoll() indicates these instances by setting errno to ERANGE
- */
- int64_t value;
-
- errno = 0; /* strtoll doesn't set errno on success */
- value = strtoll(token_get_value(token), NULL, 10);
- if (errno != ERANGE) {
- obj = QOBJECT(qint_from_int(value));
- break;
- }
- /* fall through to JSON_FLOAT */
- }
- case JSON_FLOAT:
- /* FIXME dependent on locale */
- obj = QOBJECT(qfloat_from_double(strtod(token_get_value(token), NULL)));
- break;
- default:
- goto out;
- }
-
- return obj;
-
-out:
- parser_context_restore(ctxt, saved_ctxt);
-
- return NULL;
-}
-
-static QObject *parse_value(JSONParserContext *ctxt, va_list *ap)
-{
- QObject *obj;
-
- obj = parse_object(ctxt, ap);
- if (obj == NULL) {
- obj = parse_array(ctxt, ap);
- }
- if (obj == NULL) {
- obj = parse_escape(ctxt, ap);
- }
- if (obj == NULL) {
- obj = parse_keyword(ctxt);
- }
- if (obj == NULL) {
- obj = parse_literal(ctxt);
- }
-
- return obj;
-}
-
-QObject *json_parser_parse(QList *tokens, va_list *ap)
-{
- return json_parser_parse_err(tokens, ap, NULL);
-}
-
-QObject *json_parser_parse_err(QList *tokens, va_list *ap, Error **errp)
-{
- JSONParserContext *ctxt = parser_context_new(tokens);
- QObject *result;
-
- if (!ctxt) {
- return NULL;
- }
-
- result = parse_value(ctxt, ap);
-
- error_propagate(errp, ctxt->err);
-
- parser_context_free(ctxt);
-
- return result;
-}
diff --git a/contrib/qemu/qobject/json-streamer.c b/contrib/qemu/qobject/json-streamer.c
deleted file mode 100644
index 1b2f9b1d107..00000000000
--- a/contrib/qemu/qobject/json-streamer.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * JSON streaming support
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qdict.h"
-#include "qemu-common.h"
-#include "qapi/qmp/json-lexer.h"
-#include "qapi/qmp/json-streamer.h"
-
-#define MAX_TOKEN_SIZE (64ULL << 20)
-#define MAX_NESTING (1ULL << 10)
-
-static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y)
-{
- JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
- QDict *dict;
-
- if (type == JSON_OPERATOR) {
- switch (qstring_get_str(token)[0]) {
- case '{':
- parser->brace_count++;
- break;
- case '}':
- parser->brace_count--;
- break;
- case '[':
- parser->bracket_count++;
- break;
- case ']':
- parser->bracket_count--;
- break;
- default:
- break;
- }
- }
-
- dict = qdict_new();
- qdict_put(dict, "type", qint_from_int(type));
- QINCREF(token);
- qdict_put(dict, "token", token);
- qdict_put(dict, "x", qint_from_int(x));
- qdict_put(dict, "y", qint_from_int(y));
-
- parser->token_size += token->length;
-
- qlist_append(parser->tokens, dict);
-
- if (type == JSON_ERROR) {
- goto out_emit_bad;
- } else if (parser->brace_count < 0 ||
- parser->bracket_count < 0 ||
- (parser->brace_count == 0 &&
- parser->bracket_count == 0)) {
- goto out_emit;
- } else if (parser->token_size > MAX_TOKEN_SIZE ||
- parser->bracket_count > MAX_NESTING ||
- parser->brace_count > MAX_NESTING) {
- /* Security consideration, we limit total memory allocated per object
- * and the maximum recursion depth that a message can force.
- */
- goto out_emit;
- }
-
- return;
-
-out_emit_bad:
- /* clear out token list and tell the parser to emit and error
- * indication by passing it a NULL list
- */
- QDECREF(parser->tokens);
- parser->tokens = NULL;
-out_emit:
- /* send current list of tokens to parser and reset tokenizer */
- parser->brace_count = 0;
- parser->bracket_count = 0;
- parser->emit(parser, parser->tokens);
- if (parser->tokens) {
- QDECREF(parser->tokens);
- }
- parser->tokens = qlist_new();
- parser->token_size = 0;
-}
-
-void json_message_parser_init(JSONMessageParser *parser,
- void (*func)(JSONMessageParser *, QList *))
-{
- parser->emit = func;
- parser->brace_count = 0;
- parser->bracket_count = 0;
- parser->tokens = qlist_new();
- parser->token_size = 0;
-
- json_lexer_init(&parser->lexer, json_message_process_token);
-}
-
-int json_message_parser_feed(JSONMessageParser *parser,
- const char *buffer, size_t size)
-{
- return json_lexer_feed(&parser->lexer, buffer, size);
-}
-
-int json_message_parser_flush(JSONMessageParser *parser)
-{
- return json_lexer_flush(&parser->lexer);
-}
-
-void json_message_parser_destroy(JSONMessageParser *parser)
-{
- json_lexer_destroy(&parser->lexer);
- QDECREF(parser->tokens);
-}
diff --git a/contrib/qemu/qobject/qbool.c b/contrib/qemu/qobject/qbool.c
deleted file mode 100644
index a3d2afa827f..00000000000
--- a/contrib/qemu/qobject/qbool.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * QBool Module
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qapi/qmp/qbool.h"
-#include "qapi/qmp/qobject.h"
-#include "qemu-common.h"
-
-static void qbool_destroy_obj(QObject *obj);
-
-static const QType qbool_type = {
- .code = QTYPE_QBOOL,
- .destroy = qbool_destroy_obj,
-};
-
-/**
- * qbool_from_int(): Create a new QBool from an int
- *
- * Return strong reference.
- */
-QBool *qbool_from_int(int value)
-{
- QBool *qb;
-
- qb = g_malloc(sizeof(*qb));
- qb->value = value;
- QOBJECT_INIT(qb, &qbool_type);
-
- return qb;
-}
-
-/**
- * qbool_get_int(): Get the stored int
- */
-int qbool_get_int(const QBool *qb)
-{
- return qb->value;
-}
-
-/**
- * qobject_to_qbool(): Convert a QObject into a QBool
- */
-QBool *qobject_to_qbool(const QObject *obj)
-{
- if (qobject_type(obj) != QTYPE_QBOOL)
- return NULL;
-
- return container_of(obj, QBool, base);
-}
-
-/**
- * qbool_destroy_obj(): Free all memory allocated by a
- * QBool object
- */
-static void qbool_destroy_obj(QObject *obj)
-{
- assert(obj != NULL);
- g_free(qobject_to_qbool(obj));
-}
diff --git a/contrib/qemu/qobject/qdict.c b/contrib/qemu/qobject/qdict.c
deleted file mode 100644
index ed381f9a507..00000000000
--- a/contrib/qemu/qobject/qdict.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * QDict Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qfloat.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qbool.h"
-#include "qapi/qmp/qstring.h"
-#include "qapi/qmp/qobject.h"
-#include "qemu/queue.h"
-#include "qemu-common.h"
-
-static void qdict_destroy_obj(QObject *obj);
-
-static const QType qdict_type = {
- .code = QTYPE_QDICT,
- .destroy = qdict_destroy_obj,
-};
-
-/**
- * qdict_new(): Create a new QDict
- *
- * Return strong reference.
- */
-QDict *qdict_new(void)
-{
- QDict *qdict;
-
- qdict = g_malloc0(sizeof(*qdict));
- QOBJECT_INIT(qdict, &qdict_type);
-
- return qdict;
-}
-
-/**
- * qobject_to_qdict(): Convert a QObject into a QDict
- */
-QDict *qobject_to_qdict(const QObject *obj)
-{
- if (qobject_type(obj) != QTYPE_QDICT)
- return NULL;
-
- return container_of(obj, QDict, base);
-}
-
-/**
- * tdb_hash(): based on the hash agorithm from gdbm, via tdb
- * (from module-init-tools)
- */
-static unsigned int tdb_hash(const char *name)
-{
- unsigned value; /* Used to compute the hash value. */
- unsigned i; /* Used to cycle through random values. */
-
- /* Set the initial value from the key size. */
- for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
- value = (value + (((const unsigned char *)name)[i] << (i*5 % 24)));
-
- return (1103515243 * value + 12345);
-}
-
-/**
- * alloc_entry(): allocate a new QDictEntry
- */
-static QDictEntry *alloc_entry(const char *key, QObject *value)
-{
- QDictEntry *entry;
-
- entry = g_malloc0(sizeof(*entry));
- entry->key = g_strdup(key);
- entry->value = value;
-
- return entry;
-}
-
-/**
- * qdict_entry_value(): Return qdict entry value
- *
- * Return weak reference.
- */
-QObject *qdict_entry_value(const QDictEntry *entry)
-{
- return entry->value;
-}
-
-/**
- * qdict_entry_key(): Return qdict entry key
- *
- * Return a *pointer* to the string, it has to be duplicated before being
- * stored.
- */
-const char *qdict_entry_key(const QDictEntry *entry)
-{
- return entry->key;
-}
-
-/**
- * qdict_find(): List lookup function
- */
-static QDictEntry *qdict_find(const QDict *qdict,
- const char *key, unsigned int bucket)
-{
- QDictEntry *entry;
-
- QLIST_FOREACH(entry, &qdict->table[bucket], next)
- if (!strcmp(entry->key, key))
- return entry;
-
- return NULL;
-}
-
-/**
- * qdict_put_obj(): Put a new QObject into the dictionary
- *
- * Insert the pair 'key:value' into 'qdict', if 'key' already exists
- * its 'value' will be replaced.
- *
- * This is done by freeing the reference to the stored QObject and
- * storing the new one in the same entry.
- *
- * NOTE: ownership of 'value' is transferred to the QDict
- */
-void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
-{
- unsigned int bucket;
- QDictEntry *entry;
-
- bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
- entry = qdict_find(qdict, key, bucket);
- if (entry) {
- /* replace key's value */
- qobject_decref(entry->value);
- entry->value = value;
- } else {
- /* allocate a new entry */
- entry = alloc_entry(key, value);
- QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next);
- qdict->size++;
- }
-}
-
-/**
- * qdict_get(): Lookup for a given 'key'
- *
- * Return a weak reference to the QObject associated with 'key' if
- * 'key' is present in the dictionary, NULL otherwise.
- */
-QObject *qdict_get(const QDict *qdict, const char *key)
-{
- QDictEntry *entry;
-
- entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
- return (entry == NULL ? NULL : entry->value);
-}
-
-/**
- * qdict_haskey(): Check if 'key' exists
- *
- * Return 1 if 'key' exists in the dict, 0 otherwise
- */
-int qdict_haskey(const QDict *qdict, const char *key)
-{
- unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
- return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1);
-}
-
-/**
- * qdict_size(): Return the size of the dictionary
- */
-size_t qdict_size(const QDict *qdict)
-{
- return qdict->size;
-}
-
-/**
- * qdict_get_obj(): Get a QObject of a specific type
- */
-static QObject *qdict_get_obj(const QDict *qdict, const char *key,
- qtype_code type)
-{
- QObject *obj;
-
- obj = qdict_get(qdict, key);
- assert(obj != NULL);
- assert(qobject_type(obj) == type);
-
- return obj;
-}
-
-/**
- * qdict_get_double(): Get an number mapped by 'key'
- *
- * This function assumes that 'key' exists and it stores a
- * QFloat or QInt object.
- *
- * Return number mapped by 'key'.
- */
-double qdict_get_double(const QDict *qdict, const char *key)
-{
- QObject *obj = qdict_get(qdict, key);
-
- assert(obj);
- switch (qobject_type(obj)) {
- case QTYPE_QFLOAT:
- return qfloat_get_double(qobject_to_qfloat(obj));
- case QTYPE_QINT:
- return qint_get_int(qobject_to_qint(obj));
- default:
- abort();
- }
-}
-
-/**
- * qdict_get_int(): Get an integer mapped by 'key'
- *
- * This function assumes that 'key' exists and it stores a
- * QInt object.
- *
- * Return integer mapped by 'key'.
- */
-int64_t qdict_get_int(const QDict *qdict, const char *key)
-{
- QObject *obj = qdict_get_obj(qdict, key, QTYPE_QINT);
- return qint_get_int(qobject_to_qint(obj));
-}
-
-/**
- * qdict_get_bool(): Get a bool mapped by 'key'
- *
- * This function assumes that 'key' exists and it stores a
- * QBool object.
- *
- * Return bool mapped by 'key'.
- */
-int qdict_get_bool(const QDict *qdict, const char *key)
-{
- QObject *obj = qdict_get_obj(qdict, key, QTYPE_QBOOL);
- return qbool_get_int(qobject_to_qbool(obj));
-}
-
-/**
- * qdict_get_qlist(): Get the QList mapped by 'key'
- *
- * This function assumes that 'key' exists and it stores a
- * QList object.
- *
- * Return QList mapped by 'key'.
- */
-QList *qdict_get_qlist(const QDict *qdict, const char *key)
-{
- return qobject_to_qlist(qdict_get_obj(qdict, key, QTYPE_QLIST));
-}
-
-/**
- * qdict_get_qdict(): Get the QDict mapped by 'key'
- *
- * This function assumes that 'key' exists and it stores a
- * QDict object.
- *
- * Return QDict mapped by 'key'.
- */
-QDict *qdict_get_qdict(const QDict *qdict, const char *key)
-{
- return qobject_to_qdict(qdict_get_obj(qdict, key, QTYPE_QDICT));
-}
-
-/**
- * qdict_get_str(): Get a pointer to the stored string mapped
- * by 'key'
- *
- * This function assumes that 'key' exists and it stores a
- * QString object.
- *
- * Return pointer to the string mapped by 'key'.
- */
-const char *qdict_get_str(const QDict *qdict, const char *key)
-{
- QObject *obj = qdict_get_obj(qdict, key, QTYPE_QSTRING);
- return qstring_get_str(qobject_to_qstring(obj));
-}
-
-/**
- * qdict_get_try_int(): Try to get integer mapped by 'key'
- *
- * Return integer mapped by 'key', if it is not present in
- * the dictionary or if the stored object is not of QInt type
- * 'def_value' will be returned.
- */
-int64_t qdict_get_try_int(const QDict *qdict, const char *key,
- int64_t def_value)
-{
- QObject *obj;
-
- obj = qdict_get(qdict, key);
- if (!obj || qobject_type(obj) != QTYPE_QINT)
- return def_value;
-
- return qint_get_int(qobject_to_qint(obj));
-}
-
-/**
- * qdict_get_try_bool(): Try to get a bool mapped by 'key'
- *
- * Return bool mapped by 'key', if it is not present in the
- * dictionary or if the stored object is not of QBool type
- * 'def_value' will be returned.
- */
-int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value)
-{
- QObject *obj;
-
- obj = qdict_get(qdict, key);
- if (!obj || qobject_type(obj) != QTYPE_QBOOL)
- return def_value;
-
- return qbool_get_int(qobject_to_qbool(obj));
-}
-
-/**
- * qdict_get_try_str(): Try to get a pointer to the stored string
- * mapped by 'key'
- *
- * Return a pointer to the string mapped by 'key', if it is not present
- * in the dictionary or if the stored object is not of QString type
- * NULL will be returned.
- */
-const char *qdict_get_try_str(const QDict *qdict, const char *key)
-{
- QObject *obj;
-
- obj = qdict_get(qdict, key);
- if (!obj || qobject_type(obj) != QTYPE_QSTRING)
- return NULL;
-
- return qstring_get_str(qobject_to_qstring(obj));
-}
-
-/**
- * qdict_iter(): Iterate over all the dictionary's stored values.
- *
- * This function allows the user to provide an iterator, which will be
- * called for each stored value in the dictionary.
- */
-void qdict_iter(const QDict *qdict,
- void (*iter)(const char *key, QObject *obj, void *opaque),
- void *opaque)
-{
- int i;
- QDictEntry *entry;
-
- for (i = 0; i < QDICT_BUCKET_MAX; i++) {
- QLIST_FOREACH(entry, &qdict->table[i], next)
- iter(entry->key, entry->value, opaque);
- }
-}
-
-static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket)
-{
- int i;
-
- for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) {
- if (!QLIST_EMPTY(&qdict->table[i])) {
- return QLIST_FIRST(&qdict->table[i]);
- }
- }
-
- return NULL;
-}
-
-/**
- * qdict_first(): Return first qdict entry for iteration.
- */
-const QDictEntry *qdict_first(const QDict *qdict)
-{
- return qdict_next_entry(qdict, 0);
-}
-
-/**
- * qdict_next(): Return next qdict entry in an iteration.
- */
-const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
-{
- QDictEntry *ret;
-
- ret = QLIST_NEXT(entry, next);
- if (!ret) {
- unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX;
- ret = qdict_next_entry(qdict, bucket + 1);
- }
-
- return ret;
-}
-
-/**
- * qdict_clone_shallow(): Clones a given QDict. Its entries are not copied, but
- * another reference is added.
- */
-QDict *qdict_clone_shallow(const QDict *src)
-{
- QDict *dest;
- QDictEntry *entry;
- int i;
-
- dest = qdict_new();
-
- for (i = 0; i < QDICT_BUCKET_MAX; i++) {
- QLIST_FOREACH(entry, &src->table[i], next) {
- qobject_incref(entry->value);
- qdict_put_obj(dest, entry->key, entry->value);
- }
- }
-
- return dest;
-}
-
-/**
- * qentry_destroy(): Free all the memory allocated by a QDictEntry
- */
-static void qentry_destroy(QDictEntry *e)
-{
- assert(e != NULL);
- assert(e->key != NULL);
- assert(e->value != NULL);
-
- qobject_decref(e->value);
- g_free(e->key);
- g_free(e);
-}
-
-/**
- * qdict_del(): Delete a 'key:value' pair from the dictionary
- *
- * This will destroy all data allocated by this entry.
- */
-void qdict_del(QDict *qdict, const char *key)
-{
- QDictEntry *entry;
-
- entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
- if (entry) {
- QLIST_REMOVE(entry, next);
- qentry_destroy(entry);
- qdict->size--;
- }
-}
-
-/**
- * qdict_destroy_obj(): Free all the memory allocated by a QDict
- */
-static void qdict_destroy_obj(QObject *obj)
-{
- int i;
- QDict *qdict;
-
- assert(obj != NULL);
- qdict = qobject_to_qdict(obj);
-
- for (i = 0; i < QDICT_BUCKET_MAX; i++) {
- QDictEntry *entry = QLIST_FIRST(&qdict->table[i]);
- while (entry) {
- QDictEntry *tmp = QLIST_NEXT(entry, next);
- QLIST_REMOVE(entry, next);
- qentry_destroy(entry);
- entry = tmp;
- }
- }
-
- g_free(qdict);
-}
diff --git a/contrib/qemu/qobject/qerror.c b/contrib/qemu/qobject/qerror.c
deleted file mode 100644
index 3aee1cf6a69..00000000000
--- a/contrib/qemu/qobject/qerror.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * QError Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include "monitor/monitor.h"
-#include "qapi/qmp/qjson.h"
-#include "qapi/qmp/qerror.h"
-#include "qemu-common.h"
-
-static void qerror_destroy_obj(QObject *obj);
-
-static const QType qerror_type = {
- .code = QTYPE_QERROR,
- .destroy = qerror_destroy_obj,
-};
-
-/**
- * qerror_new(): Create a new QError
- *
- * Return strong reference.
- */
-static QError *qerror_new(void)
-{
- QError *qerr;
-
- qerr = g_malloc0(sizeof(*qerr));
- QOBJECT_INIT(qerr, &qerror_type);
-
- return qerr;
-}
-
-/**
- * qerror_from_info(): Create a new QError from error information
- *
- * Return strong reference.
- */
-static QError *qerror_from_info(ErrorClass err_class, const char *fmt,
- va_list *va)
-{
- QError *qerr;
-
- qerr = qerror_new();
- loc_save(&qerr->loc);
-
- qerr->err_msg = g_strdup_vprintf(fmt, *va);
- qerr->err_class = err_class;
-
- return qerr;
-}
-
-/**
- * qerror_human(): Format QError data into human-readable string.
- */
-QString *qerror_human(const QError *qerror)
-{
- return qstring_from_str(qerror->err_msg);
-}
-
-/**
- * qerror_print(): Print QError data
- *
- * This function will print the member 'desc' of the specified QError object,
- * it uses error_report() for this, so that the output is routed to the right
- * place (ie. stderr or Monitor's device).
- */
-static void qerror_print(QError *qerror)
-{
- QString *qstring = qerror_human(qerror);
- loc_push_restore(&qerror->loc);
- error_report("%s", qstring_get_str(qstring));
- loc_pop(&qerror->loc);
- QDECREF(qstring);
-}
-
-void qerror_report(ErrorClass eclass, const char *fmt, ...)
-{
- va_list va;
- QError *qerror;
-
- va_start(va, fmt);
- qerror = qerror_from_info(eclass, fmt, &va);
- va_end(va);
-
- if (monitor_cur_is_qmp()) {
- monitor_set_error(cur_mon, qerror);
- } else {
- qerror_print(qerror);
- QDECREF(qerror);
- }
-}
-
-/* Evil... */
-struct Error
-{
- char *msg;
- ErrorClass err_class;
-};
-
-void qerror_report_err(Error *err)
-{
- QError *qerr;
-
- qerr = qerror_new();
- loc_save(&qerr->loc);
- qerr->err_msg = g_strdup(err->msg);
- qerr->err_class = err->err_class;
-
- if (monitor_cur_is_qmp()) {
- monitor_set_error(cur_mon, qerr);
- } else {
- qerror_print(qerr);
- QDECREF(qerr);
- }
-}
-
-void assert_no_error(Error *err)
-{
- if (err) {
- qerror_report_err(err);
- abort();
- }
-}
-
-/**
- * qobject_to_qerror(): Convert a QObject into a QError
- */
-static QError *qobject_to_qerror(const QObject *obj)
-{
- if (qobject_type(obj) != QTYPE_QERROR) {
- return NULL;
- }
-
- return container_of(obj, QError, base);
-}
-
-/**
- * qerror_destroy_obj(): Free all memory allocated by a QError
- */
-static void qerror_destroy_obj(QObject *obj)
-{
- QError *qerr;
-
- assert(obj != NULL);
- qerr = qobject_to_qerror(obj);
-
- g_free(qerr->err_msg);
- g_free(qerr);
-}
diff --git a/contrib/qemu/qobject/qfloat.c b/contrib/qemu/qobject/qfloat.c
deleted file mode 100644
index 7de0992dba7..00000000000
--- a/contrib/qemu/qobject/qfloat.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * QFloat Module
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qapi/qmp/qfloat.h"
-#include "qapi/qmp/qobject.h"
-#include "qemu-common.h"
-
-static void qfloat_destroy_obj(QObject *obj);
-
-static const QType qfloat_type = {
- .code = QTYPE_QFLOAT,
- .destroy = qfloat_destroy_obj,
-};
-
-/**
- * qfloat_from_int(): Create a new QFloat from a float
- *
- * Return strong reference.
- */
-QFloat *qfloat_from_double(double value)
-{
- QFloat *qf;
-
- qf = g_malloc(sizeof(*qf));
- qf->value = value;
- QOBJECT_INIT(qf, &qfloat_type);
-
- return qf;
-}
-
-/**
- * qfloat_get_double(): Get the stored float
- */
-double qfloat_get_double(const QFloat *qf)
-{
- return qf->value;
-}
-
-/**
- * qobject_to_qfloat(): Convert a QObject into a QFloat
- */
-QFloat *qobject_to_qfloat(const QObject *obj)
-{
- if (qobject_type(obj) != QTYPE_QFLOAT)
- return NULL;
-
- return container_of(obj, QFloat, base);
-}
-
-/**
- * qfloat_destroy_obj(): Free all memory allocated by a
- * QFloat object
- */
-static void qfloat_destroy_obj(QObject *obj)
-{
- assert(obj != NULL);
- g_free(qobject_to_qfloat(obj));
-}
diff --git a/contrib/qemu/qobject/qint.c b/contrib/qemu/qobject/qint.c
deleted file mode 100644
index 86b9b04f0b6..00000000000
--- a/contrib/qemu/qobject/qint.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * QInt Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qobject.h"
-#include "qemu-common.h"
-
-static void qint_destroy_obj(QObject *obj);
-
-static const QType qint_type = {
- .code = QTYPE_QINT,
- .destroy = qint_destroy_obj,
-};
-
-/**
- * qint_from_int(): Create a new QInt from an int64_t
- *
- * Return strong reference.
- */
-QInt *qint_from_int(int64_t value)
-{
- QInt *qi;
-
- qi = g_malloc(sizeof(*qi));
- qi->value = value;
- QOBJECT_INIT(qi, &qint_type);
-
- return qi;
-}
-
-/**
- * qint_get_int(): Get the stored integer
- */
-int64_t qint_get_int(const QInt *qi)
-{
- return qi->value;
-}
-
-/**
- * qobject_to_qint(): Convert a QObject into a QInt
- */
-QInt *qobject_to_qint(const QObject *obj)
-{
- if (qobject_type(obj) != QTYPE_QINT)
- return NULL;
-
- return container_of(obj, QInt, base);
-}
-
-/**
- * qint_destroy_obj(): Free all memory allocated by a
- * QInt object
- */
-static void qint_destroy_obj(QObject *obj)
-{
- assert(obj != NULL);
- g_free(qobject_to_qint(obj));
-}
diff --git a/contrib/qemu/qobject/qjson.c b/contrib/qemu/qobject/qjson.c
deleted file mode 100644
index 19085a1bb7f..00000000000
--- a/contrib/qemu/qobject/qjson.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * QObject JSON integration
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qapi/qmp/json-lexer.h"
-#include "qapi/qmp/json-parser.h"
-#include "qapi/qmp/json-streamer.h"
-#include "qapi/qmp/qjson.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qbool.h"
-#include "qapi/qmp/qfloat.h"
-#include "qapi/qmp/qdict.h"
-
-typedef struct JSONParsingState
-{
- JSONMessageParser parser;
- va_list *ap;
- QObject *result;
-} JSONParsingState;
-
-static void parse_json(JSONMessageParser *parser, QList *tokens)
-{
- JSONParsingState *s = container_of(parser, JSONParsingState, parser);
- s->result = json_parser_parse(tokens, s->ap);
-}
-
-QObject *qobject_from_jsonv(const char *string, va_list *ap)
-{
- JSONParsingState state = {};
-
- state.ap = ap;
-
- json_message_parser_init(&state.parser, parse_json);
- json_message_parser_feed(&state.parser, string, strlen(string));
- json_message_parser_flush(&state.parser);
- json_message_parser_destroy(&state.parser);
-
- return state.result;
-}
-
-QObject *qobject_from_json(const char *string)
-{
- return qobject_from_jsonv(string, NULL);
-}
-
-/*
- * IMPORTANT: This function aborts on error, thus it must not
- * be used with untrusted arguments.
- */
-QObject *qobject_from_jsonf(const char *string, ...)
-{
- QObject *obj;
- va_list ap;
-
- va_start(ap, string);
- obj = qobject_from_jsonv(string, &ap);
- va_end(ap);
-
- assert(obj != NULL);
- return obj;
-}
-
-typedef struct ToJsonIterState
-{
- int indent;
- int pretty;
- int count;
- QString *str;
-} ToJsonIterState;
-
-static void to_json(const QObject *obj, QString *str, int pretty, int indent);
-
-static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
-{
- ToJsonIterState *s = opaque;
- QString *qkey;
- int j;
-
- if (s->count)
- qstring_append(s->str, ", ");
-
- if (s->pretty) {
- qstring_append(s->str, "\n");
- for (j = 0 ; j < s->indent ; j++)
- qstring_append(s->str, " ");
- }
-
- qkey = qstring_from_str(key);
- to_json(QOBJECT(qkey), s->str, s->pretty, s->indent);
- QDECREF(qkey);
-
- qstring_append(s->str, ": ");
- to_json(obj, s->str, s->pretty, s->indent);
- s->count++;
-}
-
-static void to_json_list_iter(QObject *obj, void *opaque)
-{
- ToJsonIterState *s = opaque;
- int j;
-
- if (s->count)
- qstring_append(s->str, ", ");
-
- if (s->pretty) {
- qstring_append(s->str, "\n");
- for (j = 0 ; j < s->indent ; j++)
- qstring_append(s->str, " ");
- }
-
- to_json(obj, s->str, s->pretty, s->indent);
- s->count++;
-}
-
-static void to_json(const QObject *obj, QString *str, int pretty, int indent)
-{
- switch (qobject_type(obj)) {
- case QTYPE_QINT: {
- QInt *val = qobject_to_qint(obj);
- char buffer[1024];
-
- snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val));
- qstring_append(str, buffer);
- break;
- }
- case QTYPE_QSTRING: {
- QString *val = qobject_to_qstring(obj);
- const char *ptr;
- int cp;
- char buf[16];
- char *end;
-
- ptr = qstring_get_str(val);
- qstring_append(str, "\"");
-
- for (; *ptr; ptr = end) {
- cp = mod_utf8_codepoint(ptr, 6, &end);
- switch (cp) {
- case '\"':
- qstring_append(str, "\\\"");
- break;
- case '\\':
- qstring_append(str, "\\\\");
- break;
- case '\b':
- qstring_append(str, "\\b");
- break;
- case '\f':
- qstring_append(str, "\\f");
- break;
- case '\n':
- qstring_append(str, "\\n");
- break;
- case '\r':
- qstring_append(str, "\\r");
- break;
- case '\t':
- qstring_append(str, "\\t");
- break;
- default:
- if (cp < 0) {
- cp = 0xFFFD; /* replacement character */
- }
- if (cp > 0xFFFF) {
- /* beyond BMP; need a surrogate pair */
- snprintf(buf, sizeof(buf), "\\u%04X\\u%04X",
- 0xD800 + ((cp - 0x10000) >> 10),
- 0xDC00 + ((cp - 0x10000) & 0x3FF));
- } else if (cp < 0x20 || cp >= 0x7F) {
- snprintf(buf, sizeof(buf), "\\u%04X", cp);
- } else {
- buf[0] = cp;
- buf[1] = 0;
- }
- qstring_append(str, buf);
- }
- };
-
- qstring_append(str, "\"");
- break;
- }
- case QTYPE_QDICT: {
- ToJsonIterState s;
- QDict *val = qobject_to_qdict(obj);
-
- s.count = 0;
- s.str = str;
- s.indent = indent + 1;
- s.pretty = pretty;
- qstring_append(str, "{");
- qdict_iter(val, to_json_dict_iter, &s);
- if (pretty) {
- int j;
- qstring_append(str, "\n");
- for (j = 0 ; j < indent ; j++)
- qstring_append(str, " ");
- }
- qstring_append(str, "}");
- break;
- }
- case QTYPE_QLIST: {
- ToJsonIterState s;
- QList *val = qobject_to_qlist(obj);
-
- s.count = 0;
- s.str = str;
- s.indent = indent + 1;
- s.pretty = pretty;
- qstring_append(str, "[");
- qlist_iter(val, (void *)to_json_list_iter, &s);
- if (pretty) {
- int j;
- qstring_append(str, "\n");
- for (j = 0 ; j < indent ; j++)
- qstring_append(str, " ");
- }
- qstring_append(str, "]");
- break;
- }
- case QTYPE_QFLOAT: {
- QFloat *val = qobject_to_qfloat(obj);
- char buffer[1024];
- int len;
-
- len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val));
- while (len > 0 && buffer[len - 1] == '0') {
- len--;
- }
-
- if (len && buffer[len - 1] == '.') {
- buffer[len - 1] = 0;
- } else {
- buffer[len] = 0;
- }
-
- qstring_append(str, buffer);
- break;
- }
- case QTYPE_QBOOL: {
- QBool *val = qobject_to_qbool(obj);
-
- if (qbool_get_int(val)) {
- qstring_append(str, "true");
- } else {
- qstring_append(str, "false");
- }
- break;
- }
- case QTYPE_QERROR:
- /* XXX: should QError be emitted? */
- case QTYPE_NONE:
- break;
- }
-}
-
-QString *qobject_to_json(const QObject *obj)
-{
- QString *str = qstring_new();
-
- to_json(obj, str, 0, 0);
-
- return str;
-}
-
-QString *qobject_to_json_pretty(const QObject *obj)
-{
- QString *str = qstring_new();
-
- to_json(obj, str, 1, 0);
-
- return str;
-}
diff --git a/contrib/qemu/qobject/qlist.c b/contrib/qemu/qobject/qlist.c
deleted file mode 100644
index 1ced0de58e2..00000000000
--- a/contrib/qemu/qobject/qlist.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * QList Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qobject.h"
-#include "qemu/queue.h"
-#include "qemu-common.h"
-
-static void qlist_destroy_obj(QObject *obj);
-
-static const QType qlist_type = {
- .code = QTYPE_QLIST,
- .destroy = qlist_destroy_obj,
-};
-
-/**
- * qlist_new(): Create a new QList
- *
- * Return strong reference.
- */
-QList *qlist_new(void)
-{
- QList *qlist;
-
- qlist = g_malloc(sizeof(*qlist));
- QTAILQ_INIT(&qlist->head);
- QOBJECT_INIT(qlist, &qlist_type);
-
- return qlist;
-}
-
-static void qlist_copy_elem(QObject *obj, void *opaque)
-{
- QList *dst = opaque;
-
- qobject_incref(obj);
- qlist_append_obj(dst, obj);
-}
-
-QList *qlist_copy(QList *src)
-{
- QList *dst = qlist_new();
-
- qlist_iter(src, qlist_copy_elem, dst);
-
- return dst;
-}
-
-/**
- * qlist_append_obj(): Append an QObject into QList
- *
- * NOTE: ownership of 'value' is transferred to the QList
- */
-void qlist_append_obj(QList *qlist, QObject *value)
-{
- QListEntry *entry;
-
- entry = g_malloc(sizeof(*entry));
- entry->value = value;
-
- QTAILQ_INSERT_TAIL(&qlist->head, entry, next);
-}
-
-/**
- * qlist_iter(): Iterate over all the list's stored values.
- *
- * This function allows the user to provide an iterator, which will be
- * called for each stored value in the list.
- */
-void qlist_iter(const QList *qlist,
- void (*iter)(QObject *obj, void *opaque), void *opaque)
-{
- QListEntry *entry;
-
- QTAILQ_FOREACH(entry, &qlist->head, next)
- iter(entry->value, opaque);
-}
-
-QObject *qlist_pop(QList *qlist)
-{
- QListEntry *entry;
- QObject *ret;
-
- if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
- return NULL;
- }
-
- entry = QTAILQ_FIRST(&qlist->head);
- QTAILQ_REMOVE(&qlist->head, entry, next);
-
- ret = entry->value;
- g_free(entry);
-
- return ret;
-}
-
-QObject *qlist_peek(QList *qlist)
-{
- QListEntry *entry;
- QObject *ret;
-
- if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
- return NULL;
- }
-
- entry = QTAILQ_FIRST(&qlist->head);
-
- ret = entry->value;
-
- return ret;
-}
-
-int qlist_empty(const QList *qlist)
-{
- return QTAILQ_EMPTY(&qlist->head);
-}
-
-static void qlist_size_iter(QObject *obj, void *opaque)
-{
- size_t *count = opaque;
- (*count)++;
-}
-
-size_t qlist_size(const QList *qlist)
-{
- size_t count = 0;
- qlist_iter(qlist, qlist_size_iter, &count);
- return count;
-}
-
-/**
- * qobject_to_qlist(): Convert a QObject into a QList
- */
-QList *qobject_to_qlist(const QObject *obj)
-{
- if (qobject_type(obj) != QTYPE_QLIST) {
- return NULL;
- }
-
- return container_of(obj, QList, base);
-}
-
-/**
- * qlist_destroy_obj(): Free all the memory allocated by a QList
- */
-static void qlist_destroy_obj(QObject *obj)
-{
- QList *qlist;
- QListEntry *entry, *next_entry;
-
- assert(obj != NULL);
- qlist = qobject_to_qlist(obj);
-
- QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) {
- QTAILQ_REMOVE(&qlist->head, entry, next);
- qobject_decref(entry->value);
- g_free(entry);
- }
-
- g_free(qlist);
-}
diff --git a/contrib/qemu/qobject/qstring.c b/contrib/qemu/qobject/qstring.c
deleted file mode 100644
index 607b7a142c6..00000000000
--- a/contrib/qemu/qobject/qstring.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * QString Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- * Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include "qapi/qmp/qobject.h"
-#include "qapi/qmp/qstring.h"
-#include "qemu-common.h"
-
-static void qstring_destroy_obj(QObject *obj);
-
-static const QType qstring_type = {
- .code = QTYPE_QSTRING,
- .destroy = qstring_destroy_obj,
-};
-
-/**
- * qstring_new(): Create a new empty QString
- *
- * Return strong reference.
- */
-QString *qstring_new(void)
-{
- return qstring_from_str("");
-}
-
-/**
- * qstring_get_length(): Get the length of a QString
- */
-size_t qstring_get_length(const QString *qstring)
-{
- return qstring->length;
-}
-
-/**
- * qstring_from_substr(): Create a new QString from a C string substring
- *
- * Return string reference
- */
-QString *qstring_from_substr(const char *str, int start, int end)
-{
- QString *qstring;
-
- qstring = g_malloc(sizeof(*qstring));
-
- qstring->length = end - start + 1;
- qstring->capacity = qstring->length;
-
- qstring->string = g_malloc(qstring->capacity + 1);
- memcpy(qstring->string, str + start, qstring->length);
- qstring->string[qstring->length] = 0;
-
- QOBJECT_INIT(qstring, &qstring_type);
-
- return qstring;
-}
-
-/**
- * qstring_from_str(): Create a new QString from a regular C string
- *
- * Return strong reference.
- */
-QString *qstring_from_str(const char *str)
-{
- return qstring_from_substr(str, 0, strlen(str) - 1);
-}
-
-static void capacity_increase(QString *qstring, size_t len)
-{
- if (qstring->capacity < (qstring->length + len)) {
- qstring->capacity += len;
- qstring->capacity *= 2; /* use exponential growth */
-
- qstring->string = g_realloc(qstring->string, qstring->capacity + 1);
- }
-}
-
-/* qstring_append(): Append a C string to a QString
- */
-void qstring_append(QString *qstring, const char *str)
-{
- size_t len = strlen(str);
-
- capacity_increase(qstring, len);
- memcpy(qstring->string + qstring->length, str, len);
- qstring->length += len;
- qstring->string[qstring->length] = 0;
-}
-
-void qstring_append_int(QString *qstring, int64_t value)
-{
- char num[32];
-
- snprintf(num, sizeof(num), "%" PRId64, value);
- qstring_append(qstring, num);
-}
-
-/**
- * qstring_append_chr(): Append a C char to a QString
- */
-void qstring_append_chr(QString *qstring, int c)
-{
- capacity_increase(qstring, 1);
- qstring->string[qstring->length++] = c;
- qstring->string[qstring->length] = 0;
-}
-
-/**
- * qobject_to_qstring(): Convert a QObject to a QString
- */
-QString *qobject_to_qstring(const QObject *obj)
-{
- if (qobject_type(obj) != QTYPE_QSTRING)
- return NULL;
-
- return container_of(obj, QString, base);
-}
-
-/**
- * qstring_get_str(): Return a pointer to the stored string
- *
- * NOTE: Should be used with caution, if the object is deallocated
- * this pointer becomes invalid.
- */
-const char *qstring_get_str(const QString *qstring)
-{
- return qstring->string;
-}
-
-/**
- * qstring_destroy_obj(): Free all memory allocated by a QString
- * object
- */
-static void qstring_destroy_obj(QObject *obj)
-{
- QString *qs;
-
- assert(obj != NULL);
- qs = qobject_to_qstring(obj);
- g_free(qs->string);
- g_free(qs);
-}
diff --git a/contrib/qemu/trace/generated-tracers.h b/contrib/qemu/trace/generated-tracers.h
deleted file mode 100644
index b512660f358..00000000000
--- a/contrib/qemu/trace/generated-tracers.h
+++ /dev/null
@@ -1,3759 +0,0 @@
-/* This file is autogenerated by tracetool, do not edit. */
-
-#ifndef TRACE__GENERATED_TRACERS_H
-#define TRACE__GENERATED_TRACERS_H
-
-#include "qemu-common.h"
-
-static inline void trace_qxl_interface_set_mm_time(int qid, uint32_t mm_time)
-{
-}
-
-static inline void trace_qxl_io_write_vga(int qid, const char * mode, uint32_t addr, uint32_t val)
-{
-}
-
-static inline void trace_g_malloc(size_t size, void * ptr)
-{
-}
-
-static inline void trace_g_realloc(void * ptr, size_t size, void * newptr)
-{
-}
-
-static inline void trace_g_free(void * ptr)
-{
-}
-
-static inline void trace_qemu_memalign(size_t alignment, size_t size, void * ptr)
-{
-}
-
-static inline void trace_qemu_anon_ram_alloc(size_t size, void * ptr)
-{
-}
-
-static inline void trace_qemu_vfree(void * ptr)
-{
-}
-
-static inline void trace_qemu_anon_ram_free(void * ptr, size_t size)
-{
-}
-
-static inline void trace_virtqueue_fill(void * vq, const void * elem, unsigned int len, unsigned int idx)
-{
-}
-
-static inline void trace_virtqueue_flush(void * vq, unsigned int count)
-{
-}
-
-static inline void trace_virtqueue_pop(void * vq, void * elem, unsigned int in_num, unsigned int out_num)
-{
-}
-
-static inline void trace_virtio_queue_notify(void * vdev, int n, void * vq)
-{
-}
-
-static inline void trace_virtio_irq(void * vq)
-{
-}
-
-static inline void trace_virtio_notify(void * vdev, void * vq)
-{
-}
-
-static inline void trace_virtio_set_status(void * vdev, uint8_t val)
-{
-}
-
-static inline void trace_virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value)
-{
-}
-
-static inline void trace_virtio_serial_throttle_port(unsigned int port, bool throttle)
-{
-}
-
-static inline void trace_virtio_serial_handle_control_message(uint16_t event, uint16_t value)
-{
-}
-
-static inline void trace_virtio_serial_handle_control_message_port(unsigned int port)
-{
-}
-
-static inline void trace_virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret)
-{
-}
-
-static inline void trace_virtio_console_chr_read(unsigned int port, int size)
-{
-}
-
-static inline void trace_virtio_console_chr_event(unsigned int port, int event)
-{
-}
-
-static inline void trace_bdrv_open_common(void * bs, const char * filename, int flags, const char * format_name)
-{
-}
-
-static inline void trace_multiwrite_cb(void * mcb, int ret)
-{
-}
-
-static inline void trace_bdrv_aio_multiwrite(void * mcb, int num_callbacks, int num_reqs)
-{
-}
-
-static inline void trace_bdrv_aio_discard(void * bs, int64_t sector_num, int nb_sectors, void * opaque)
-{
-}
-
-static inline void trace_bdrv_aio_flush(void * bs, void * opaque)
-{
-}
-
-static inline void trace_bdrv_aio_readv(void * bs, int64_t sector_num, int nb_sectors, void * opaque)
-{
-}
-
-static inline void trace_bdrv_aio_writev(void * bs, int64_t sector_num, int nb_sectors, void * opaque)
-{
-}
-
-static inline void trace_bdrv_lock_medium(void * bs, bool locked)
-{
-}
-
-static inline void trace_bdrv_co_readv(void * bs, int64_t sector_num, int nb_sector)
-{
-}
-
-static inline void trace_bdrv_co_copy_on_readv(void * bs, int64_t sector_num, int nb_sector)
-{
-}
-
-static inline void trace_bdrv_co_writev(void * bs, int64_t sector_num, int nb_sector)
-{
-}
-
-static inline void trace_bdrv_co_write_zeroes(void * bs, int64_t sector_num, int nb_sector)
-{
-}
-
-static inline void trace_bdrv_co_io_em(void * bs, int64_t sector_num, int nb_sectors, int is_write, void * acb)
-{
-}
-
-static inline void trace_bdrv_co_do_copy_on_readv(void * bs, int64_t sector_num, int nb_sectors, int64_t cluster_sector_num, int cluster_nb_sectors)
-{
-}
-
-static inline void trace_stream_one_iteration(void * s, int64_t sector_num, int nb_sectors, int is_allocated)
-{
-}
-
-static inline void trace_stream_start(void * bs, void * base, void * s, void * co, void * opaque)
-{
-}
-
-static inline void trace_commit_one_iteration(void * s, int64_t sector_num, int nb_sectors, int is_allocated)
-{
-}
-
-static inline void trace_commit_start(void * bs, void * base, void * top, void * s, void * co, void * opaque)
-{
-}
-
-static inline void trace_mirror_start(void * bs, void * s, void * co, void * opaque)
-{
-}
-
-static inline void trace_mirror_restart_iter(void * s, int64_t cnt)
-{
-}
-
-static inline void trace_mirror_before_flush(void * s)
-{
-}
-
-static inline void trace_mirror_before_drain(void * s, int64_t cnt)
-{
-}
-
-static inline void trace_mirror_before_sleep(void * s, int64_t cnt, int synced)
-{
-}
-
-static inline void trace_mirror_one_iteration(void * s, int64_t sector_num, int nb_sectors)
-{
-}
-
-static inline void trace_mirror_cow(void * s, int64_t sector_num)
-{
-}
-
-static inline void trace_mirror_iteration_done(void * s, int64_t sector_num, int nb_sectors, int ret)
-{
-}
-
-static inline void trace_mirror_yield(void * s, int64_t cnt, int buf_free_count, int in_flight)
-{
-}
-
-static inline void trace_mirror_yield_in_flight(void * s, int64_t sector_num, int in_flight)
-{
-}
-
-static inline void trace_mirror_yield_buf_busy(void * s, int nb_chunks, int in_flight)
-{
-}
-
-static inline void trace_mirror_break_buf_busy(void * s, int nb_chunks, int in_flight)
-{
-}
-
-static inline void trace_backup_do_cow_enter(void * job, int64_t start, int64_t sector_num, int nb_sectors)
-{
-}
-
-static inline void trace_backup_do_cow_return(void * job, int64_t sector_num, int nb_sectors, int ret)
-{
-}
-
-static inline void trace_backup_do_cow_skip(void * job, int64_t start)
-{
-}
-
-static inline void trace_backup_do_cow_process(void * job, int64_t start)
-{
-}
-
-static inline void trace_backup_do_cow_read_fail(void * job, int64_t start, int ret)
-{
-}
-
-static inline void trace_backup_do_cow_write_fail(void * job, int64_t start, int ret)
-{
-}
-
-static inline void trace_qmp_block_job_cancel(void * job)
-{
-}
-
-static inline void trace_qmp_block_job_pause(void * job)
-{
-}
-
-static inline void trace_qmp_block_job_resume(void * job)
-{
-}
-
-static inline void trace_qmp_block_job_complete(void * job)
-{
-}
-
-static inline void trace_block_job_cb(void * bs, void * job, int ret)
-{
-}
-
-static inline void trace_qmp_block_stream(void * bs, void * job)
-{
-}
-
-static inline void trace_virtio_blk_req_complete(void * req, int status)
-{
-}
-
-static inline void trace_virtio_blk_rw_complete(void * req, int ret)
-{
-}
-
-static inline void trace_virtio_blk_handle_write(void * req, uint64_t sector, size_t nsectors)
-{
-}
-
-static inline void trace_virtio_blk_handle_read(void * req, uint64_t sector, size_t nsectors)
-{
-}
-
-static inline void trace_virtio_blk_data_plane_start(void * s)
-{
-}
-
-static inline void trace_virtio_blk_data_plane_stop(void * s)
-{
-}
-
-static inline void trace_virtio_blk_data_plane_process_request(void * s, unsigned int out_num, unsigned int in_num, unsigned int head)
-{
-}
-
-static inline void trace_virtio_blk_data_plane_complete_request(void * s, unsigned int head, int ret)
-{
-}
-
-static inline void trace_vring_setup(uint64_t physical, void * desc, void * avail, void * used)
-{
-}
-
-static inline void trace_thread_pool_submit(void * pool, void * req, void * opaque)
-{
-}
-
-static inline void trace_thread_pool_complete(void * pool, void * req, void * opaque, int ret)
-{
-}
-
-static inline void trace_thread_pool_cancel(void * req, void * opaque)
-{
-}
-
-static inline void trace_paio_submit(void * acb, void * opaque, int64_t sector_num, int nb_sectors, int type)
-{
-}
-
-static inline void trace_paio_complete(void * acb, void * opaque, int ret)
-{
-}
-
-static inline void trace_paio_cancel(void * acb, void * opaque)
-{
-}
-
-static inline void trace_cpu_in(unsigned int addr, unsigned int val)
-{
-}
-
-static inline void trace_cpu_out(unsigned int addr, unsigned int val)
-{
-}
-
-static inline void trace_balloon_event(void * opaque, unsigned long addr)
-{
-}
-
-static inline void trace_apic_local_deliver(int vector, uint32_t lvt)
-{
-}
-
-static inline void trace_apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode)
-{
-}
-
-static inline void trace_cpu_set_apic_base(uint64_t val)
-{
-}
-
-static inline void trace_cpu_get_apic_base(uint64_t val)
-{
-}
-
-static inline void trace_apic_mem_readl(uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_apic_mem_writel(uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_apic_report_irq_delivered(int apic_irq_delivered)
-{
-}
-
-static inline void trace_apic_reset_irq_delivered(int apic_irq_delivered)
-{
-}
-
-static inline void trace_apic_get_irq_delivered(int apic_irq_delivered)
-{
-}
-
-static inline void trace_cs4231_mem_readl_dreg(uint32_t reg, uint32_t ret)
-{
-}
-
-static inline void trace_cs4231_mem_readl_reg(uint32_t reg, uint32_t ret)
-{
-}
-
-static inline void trace_cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val)
-{
-}
-
-static inline void trace_cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val)
-{
-}
-
-static inline void trace_nvram_read(uint32_t addr, uint32_t ret)
-{
-}
-
-static inline void trace_nvram_write(uint32_t addr, uint32_t old, uint32_t val)
-{
-}
-
-static inline void trace_ecc_mem_writel_mer(uint32_t val)
-{
-}
-
-static inline void trace_ecc_mem_writel_mdr(uint32_t val)
-{
-}
-
-static inline void trace_ecc_mem_writel_mfsr(uint32_t val)
-{
-}
-
-static inline void trace_ecc_mem_writel_vcr(uint32_t val)
-{
-}
-
-static inline void trace_ecc_mem_writel_dr(uint32_t val)
-{
-}
-
-static inline void trace_ecc_mem_writel_ecr0(uint32_t val)
-{
-}
-
-static inline void trace_ecc_mem_writel_ecr1(uint32_t val)
-{
-}
-
-static inline void trace_ecc_mem_readl_mer(uint32_t ret)
-{
-}
-
-static inline void trace_ecc_mem_readl_mdr(uint32_t ret)
-{
-}
-
-static inline void trace_ecc_mem_readl_mfsr(uint32_t ret)
-{
-}
-
-static inline void trace_ecc_mem_readl_vcr(uint32_t ret)
-{
-}
-
-static inline void trace_ecc_mem_readl_mfar0(uint32_t ret)
-{
-}
-
-static inline void trace_ecc_mem_readl_mfar1(uint32_t ret)
-{
-}
-
-static inline void trace_ecc_mem_readl_dr(uint32_t ret)
-{
-}
-
-static inline void trace_ecc_mem_readl_ecr0(uint32_t ret)
-{
-}
-
-static inline void trace_ecc_mem_readl_ecr1(uint32_t ret)
-{
-}
-
-static inline void trace_ecc_diag_mem_writeb(uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_ecc_diag_mem_readb(uint64_t addr, uint32_t ret)
-{
-}
-
-static inline void trace_fw_cfg_write(void * s, uint8_t value)
-{
-}
-
-static inline void trace_fw_cfg_select(void * s, uint16_t key, int ret)
-{
-}
-
-static inline void trace_fw_cfg_read(void * s, uint8_t ret)
-{
-}
-
-static inline void trace_fw_cfg_add_file_dupe(void * s, char * name)
-{
-}
-
-static inline void trace_fw_cfg_add_file(void * s, int index, char * name, size_t len)
-{
-}
-
-static inline void trace_hd_geometry_lchs_guess(void * bs, int cyls, int heads, int secs)
-{
-}
-
-static inline void trace_hd_geometry_guess(void * bs, uint32_t cyls, uint32_t heads, uint32_t secs, int trans)
-{
-}
-
-static inline void trace_jazz_led_read(uint64_t addr, uint8_t val)
-{
-}
-
-static inline void trace_jazz_led_write(uint64_t addr, uint8_t new)
-{
-}
-
-static inline void trace_lance_mem_readw(uint64_t addr, uint32_t ret)
-{
-}
-
-static inline void trace_lance_mem_writew(uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret)
-{
-}
-
-static inline void trace_slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_slavio_intctl_mem_writel_clear(uint32_t cpu, uint32_t val, uint32_t intreg_pending)
-{
-}
-
-static inline void trace_slavio_intctl_mem_writel_set(uint32_t cpu, uint32_t val, uint32_t intreg_pending)
-{
-}
-
-static inline void trace_slavio_intctlm_mem_readl(uint64_t addr, uint32_t ret)
-{
-}
-
-static inline void trace_slavio_intctlm_mem_writel(uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_slavio_intctlm_mem_writel_enable(uint32_t val, uint32_t intregm_disabled)
-{
-}
-
-static inline void trace_slavio_intctlm_mem_writel_disable(uint32_t val, uint32_t intregm_disabled)
-{
-}
-
-static inline void trace_slavio_intctlm_mem_writel_target(uint32_t cpu)
-{
-}
-
-static inline void trace_slavio_check_interrupts(uint32_t pending, uint32_t intregm_disabled)
-{
-}
-
-static inline void trace_slavio_set_irq(uint32_t target_cpu, int irq, uint32_t pil, int level)
-{
-}
-
-static inline void trace_slavio_set_timer_irq_cpu(int cpu, int level)
-{
-}
-
-static inline void trace_slavio_misc_update_irq_raise(void)
-{
-}
-
-static inline void trace_slavio_misc_update_irq_lower(void)
-{
-}
-
-static inline void trace_slavio_set_power_fail(int power_failing, uint8_t config)
-{
-}
-
-static inline void trace_slavio_cfg_mem_writeb(uint32_t val)
-{
-}
-
-static inline void trace_slavio_cfg_mem_readb(uint32_t ret)
-{
-}
-
-static inline void trace_slavio_diag_mem_writeb(uint32_t val)
-{
-}
-
-static inline void trace_slavio_diag_mem_readb(uint32_t ret)
-{
-}
-
-static inline void trace_slavio_mdm_mem_writeb(uint32_t val)
-{
-}
-
-static inline void trace_slavio_mdm_mem_readb(uint32_t ret)
-{
-}
-
-static inline void trace_slavio_aux1_mem_writeb(uint32_t val)
-{
-}
-
-static inline void trace_slavio_aux1_mem_readb(uint32_t ret)
-{
-}
-
-static inline void trace_slavio_aux2_mem_writeb(uint32_t val)
-{
-}
-
-static inline void trace_slavio_aux2_mem_readb(uint32_t ret)
-{
-}
-
-static inline void trace_apc_mem_writeb(uint32_t val)
-{
-}
-
-static inline void trace_apc_mem_readb(uint32_t ret)
-{
-}
-
-static inline void trace_slavio_sysctrl_mem_writel(uint32_t val)
-{
-}
-
-static inline void trace_slavio_sysctrl_mem_readl(uint32_t ret)
-{
-}
-
-static inline void trace_slavio_led_mem_writew(uint32_t val)
-{
-}
-
-static inline void trace_slavio_led_mem_readw(uint32_t ret)
-{
-}
-
-static inline void trace_slavio_timer_get_out(uint64_t limit, uint32_t counthigh, uint32_t count)
-{
-}
-
-static inline void trace_slavio_timer_irq(uint32_t counthigh, uint32_t count)
-{
-}
-
-static inline void trace_slavio_timer_mem_readl_invalid(uint64_t addr)
-{
-}
-
-static inline void trace_slavio_timer_mem_readl(uint64_t addr, uint32_t ret)
-{
-}
-
-static inline void trace_slavio_timer_mem_writel(uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_slavio_timer_mem_writel_limit(unsigned int timer_index, uint64_t count)
-{
-}
-
-static inline void trace_slavio_timer_mem_writel_counter_invalid(void)
-{
-}
-
-static inline void trace_slavio_timer_mem_writel_status_start(unsigned int timer_index)
-{
-}
-
-static inline void trace_slavio_timer_mem_writel_status_stop(unsigned int timer_index)
-{
-}
-
-static inline void trace_slavio_timer_mem_writel_mode_user(unsigned int timer_index)
-{
-}
-
-static inline void trace_slavio_timer_mem_writel_mode_counter(unsigned int timer_index)
-{
-}
-
-static inline void trace_slavio_timer_mem_writel_mode_invalid(void)
-{
-}
-
-static inline void trace_slavio_timer_mem_writel_invalid(uint64_t addr)
-{
-}
-
-static inline void trace_ledma_memory_read(uint64_t addr)
-{
-}
-
-static inline void trace_ledma_memory_write(uint64_t addr)
-{
-}
-
-static inline void trace_sparc32_dma_set_irq_raise(void)
-{
-}
-
-static inline void trace_sparc32_dma_set_irq_lower(void)
-{
-}
-
-static inline void trace_espdma_memory_read(uint32_t addr)
-{
-}
-
-static inline void trace_espdma_memory_write(uint32_t addr)
-{
-}
-
-static inline void trace_sparc32_dma_mem_readl(uint64_t addr, uint32_t ret)
-{
-}
-
-static inline void trace_sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val)
-{
-}
-
-static inline void trace_sparc32_dma_enable_raise(void)
-{
-}
-
-static inline void trace_sparc32_dma_enable_lower(void)
-{
-}
-
-static inline void trace_sun4m_cpu_interrupt(unsigned int level)
-{
-}
-
-static inline void trace_sun4m_cpu_reset_interrupt(unsigned int level)
-{
-}
-
-static inline void trace_sun4m_cpu_set_irq_raise(int level)
-{
-}
-
-static inline void trace_sun4m_cpu_set_irq_lower(int level)
-{
-}
-
-static inline void trace_sun4m_iommu_mem_readl(uint64_t addr, uint32_t ret)
-{
-}
-
-static inline void trace_sun4m_iommu_mem_writel(uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_sun4m_iommu_mem_writel_ctrl(uint64_t iostart)
-{
-}
-
-static inline void trace_sun4m_iommu_mem_writel_tlbflush(uint32_t val)
-{
-}
-
-static inline void trace_sun4m_iommu_mem_writel_pgflush(uint32_t val)
-{
-}
-
-static inline void trace_sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret)
-{
-}
-
-static inline void trace_sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte)
-{
-}
-
-static inline void trace_sun4m_iommu_bad_addr(uint64_t addr)
-{
-}
-
-static inline void trace_usb_packet_state_change(int bus, const char * port, int ep, void * p, const char * o, const char * n)
-{
-}
-
-static inline void trace_usb_packet_state_fault(int bus, const char * port, int ep, void * p, const char * o, const char * n)
-{
-}
-
-static inline void trace_usb_port_claim(int bus, const char * port)
-{
-}
-
-static inline void trace_usb_port_attach(int bus, const char * port, const char * devspeed, const char * portspeed)
-{
-}
-
-static inline void trace_usb_port_detach(int bus, const char * port)
-{
-}
-
-static inline void trace_usb_port_release(int bus, const char * port)
-{
-}
-
-static inline void trace_usb_ehci_reset(void)
-{
-}
-
-static inline void trace_usb_ehci_opreg_read(uint32_t addr, const char * str, uint32_t val)
-{
-}
-
-static inline void trace_usb_ehci_opreg_write(uint32_t addr, const char * str, uint32_t val)
-{
-}
-
-static inline void trace_usb_ehci_opreg_change(uint32_t addr, const char * str, uint32_t new, uint32_t old)
-{
-}
-
-static inline void trace_usb_ehci_portsc_read(uint32_t addr, uint32_t port, uint32_t val)
-{
-}
-
-static inline void trace_usb_ehci_portsc_write(uint32_t addr, uint32_t port, uint32_t val)
-{
-}
-
-static inline void trace_usb_ehci_portsc_change(uint32_t addr, uint32_t port, uint32_t new, uint32_t old)
-{
-}
-
-static inline void trace_usb_ehci_usbsts(const char * sts, int state)
-{
-}
-
-static inline void trace_usb_ehci_state(const char * schedule, const char * state)
-{
-}
-
-static inline void trace_usb_ehci_qh_ptrs(void * q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd)
-{
-}
-
-static inline void trace_usb_ehci_qh_fields(uint32_t addr, int rl, int mplen, int eps, int ep, int devaddr)
-{
-}
-
-static inline void trace_usb_ehci_qh_bits(uint32_t addr, int c, int h, int dtc, int i)
-{
-}
-
-static inline void trace_usb_ehci_qtd_ptrs(void * q, uint32_t addr, uint32_t nxt, uint32_t altnext)
-{
-}
-
-static inline void trace_usb_ehci_qtd_fields(uint32_t addr, int tbytes, int cpage, int cerr, int pid)
-{
-}
-
-static inline void trace_usb_ehci_qtd_bits(uint32_t addr, int ioc, int active, int halt, int babble, int xacterr)
-{
-}
-
-static inline void trace_usb_ehci_itd(uint32_t addr, uint32_t nxt, uint32_t mplen, uint32_t mult, uint32_t ep, uint32_t devaddr)
-{
-}
-
-static inline void trace_usb_ehci_sitd(uint32_t addr, uint32_t nxt, uint32_t active)
-{
-}
-
-static inline void trace_usb_ehci_port_attach(uint32_t port, const char * owner, const char * device)
-{
-}
-
-static inline void trace_usb_ehci_port_detach(uint32_t port, const char * owner)
-{
-}
-
-static inline void trace_usb_ehci_port_reset(uint32_t port, int enable)
-{
-}
-
-static inline void trace_usb_ehci_data(int rw, uint32_t cpage, uint32_t offset, uint32_t addr, uint32_t len, uint32_t bufpos)
-{
-}
-
-static inline void trace_usb_ehci_queue_action(void * q, const char * action)
-{
-}
-
-static inline void trace_usb_ehci_packet_action(void * q, void * p, const char * action)
-{
-}
-
-static inline void trace_usb_ehci_irq(uint32_t level, uint32_t frindex, uint32_t sts, uint32_t mask)
-{
-}
-
-static inline void trace_usb_ehci_guest_bug(const char * reason)
-{
-}
-
-static inline void trace_usb_ehci_doorbell_ring(void)
-{
-}
-
-static inline void trace_usb_ehci_doorbell_ack(void)
-{
-}
-
-static inline void trace_usb_ehci_dma_error(void)
-{
-}
-
-static inline void trace_usb_uhci_reset(void)
-{
-}
-
-static inline void trace_usb_uhci_schedule_start(void)
-{
-}
-
-static inline void trace_usb_uhci_schedule_stop(void)
-{
-}
-
-static inline void trace_usb_uhci_frame_start(uint32_t num)
-{
-}
-
-static inline void trace_usb_uhci_frame_stop_bandwidth(void)
-{
-}
-
-static inline void trace_usb_uhci_frame_loop_stop_idle(void)
-{
-}
-
-static inline void trace_usb_uhci_frame_loop_continue(void)
-{
-}
-
-static inline void trace_usb_uhci_mmio_readw(uint32_t addr, uint32_t val)
-{
-}
-
-static inline void trace_usb_uhci_mmio_writew(uint32_t addr, uint32_t val)
-{
-}
-
-static inline void trace_usb_uhci_queue_add(uint32_t token)
-{
-}
-
-static inline void trace_usb_uhci_queue_del(uint32_t token, const char * reason)
-{
-}
-
-static inline void trace_usb_uhci_packet_add(uint32_t token, uint32_t addr)
-{
-}
-
-static inline void trace_usb_uhci_packet_link_async(uint32_t token, uint32_t addr)
-{
-}
-
-static inline void trace_usb_uhci_packet_unlink_async(uint32_t token, uint32_t addr)
-{
-}
-
-static inline void trace_usb_uhci_packet_cancel(uint32_t token, uint32_t addr, int done)
-{
-}
-
-static inline void trace_usb_uhci_packet_complete_success(uint32_t token, uint32_t addr)
-{
-}
-
-static inline void trace_usb_uhci_packet_complete_shortxfer(uint32_t token, uint32_t addr)
-{
-}
-
-static inline void trace_usb_uhci_packet_complete_stall(uint32_t token, uint32_t addr)
-{
-}
-
-static inline void trace_usb_uhci_packet_complete_babble(uint32_t token, uint32_t addr)
-{
-}
-
-static inline void trace_usb_uhci_packet_complete_error(uint32_t token, uint32_t addr)
-{
-}
-
-static inline void trace_usb_uhci_packet_del(uint32_t token, uint32_t addr)
-{
-}
-
-static inline void trace_usb_uhci_qh_load(uint32_t qh)
-{
-}
-
-static inline void trace_usb_uhci_td_load(uint32_t qh, uint32_t td, uint32_t ctrl, uint32_t token)
-{
-}
-
-static inline void trace_usb_uhci_td_queue(uint32_t td, uint32_t ctrl, uint32_t token)
-{
-}
-
-static inline void trace_usb_uhci_td_nextqh(uint32_t qh, uint32_t td)
-{
-}
-
-static inline void trace_usb_uhci_td_async(uint32_t qh, uint32_t td)
-{
-}
-
-static inline void trace_usb_uhci_td_complete(uint32_t qh, uint32_t td)
-{
-}
-
-static inline void trace_usb_xhci_reset(void)
-{
-}
-
-static inline void trace_usb_xhci_run(void)
-{
-}
-
-static inline void trace_usb_xhci_stop(void)
-{
-}
-
-static inline void trace_usb_xhci_cap_read(uint32_t off, uint32_t val)
-{
-}
-
-static inline void trace_usb_xhci_oper_read(uint32_t off, uint32_t val)
-{
-}
-
-static inline void trace_usb_xhci_port_read(uint32_t port, uint32_t off, uint32_t val)
-{
-}
-
-static inline void trace_usb_xhci_runtime_read(uint32_t off, uint32_t val)
-{
-}
-
-static inline void trace_usb_xhci_doorbell_read(uint32_t off, uint32_t val)
-{
-}
-
-static inline void trace_usb_xhci_oper_write(uint32_t off, uint32_t val)
-{
-}
-
-static inline void trace_usb_xhci_port_write(uint32_t port, uint32_t off, uint32_t val)
-{
-}
-
-static inline void trace_usb_xhci_runtime_write(uint32_t off, uint32_t val)
-{
-}
-
-static inline void trace_usb_xhci_doorbell_write(uint32_t off, uint32_t val)
-{
-}
-
-static inline void trace_usb_xhci_irq_intx(uint32_t level)
-{
-}
-
-static inline void trace_usb_xhci_irq_msi(uint32_t nr)
-{
-}
-
-static inline void trace_usb_xhci_irq_msix(uint32_t nr)
-{
-}
-
-static inline void trace_usb_xhci_irq_msix_use(uint32_t nr)
-{
-}
-
-static inline void trace_usb_xhci_irq_msix_unuse(uint32_t nr)
-{
-}
-
-static inline void trace_usb_xhci_queue_event(uint32_t vector, uint32_t idx, const char * trb, const char * evt, uint64_t param, uint32_t status, uint32_t control)
-{
-}
-
-static inline void trace_usb_xhci_fetch_trb(uint64_t addr, const char * name, uint64_t param, uint32_t status, uint32_t control)
-{
-}
-
-static inline void trace_usb_xhci_port_reset(uint32_t port)
-{
-}
-
-static inline void trace_usb_xhci_port_link(uint32_t port, uint32_t pls)
-{
-}
-
-static inline void trace_usb_xhci_port_notify(uint32_t port, uint32_t pls)
-{
-}
-
-static inline void trace_usb_xhci_slot_enable(uint32_t slotid)
-{
-}
-
-static inline void trace_usb_xhci_slot_disable(uint32_t slotid)
-{
-}
-
-static inline void trace_usb_xhci_slot_address(uint32_t slotid)
-{
-}
-
-static inline void trace_usb_xhci_slot_configure(uint32_t slotid)
-{
-}
-
-static inline void trace_usb_xhci_slot_evaluate(uint32_t slotid)
-{
-}
-
-static inline void trace_usb_xhci_slot_reset(uint32_t slotid)
-{
-}
-
-static inline void trace_usb_xhci_ep_enable(uint32_t slotid, uint32_t epid)
-{
-}
-
-static inline void trace_usb_xhci_ep_disable(uint32_t slotid, uint32_t epid)
-{
-}
-
-static inline void trace_usb_xhci_ep_set_dequeue(uint32_t slotid, uint32_t epid, uint32_t streamid, uint64_t param)
-{
-}
-
-static inline void trace_usb_xhci_ep_kick(uint32_t slotid, uint32_t epid, uint32_t streamid)
-{
-}
-
-static inline void trace_usb_xhci_ep_stop(uint32_t slotid, uint32_t epid)
-{
-}
-
-static inline void trace_usb_xhci_ep_reset(uint32_t slotid, uint32_t epid)
-{
-}
-
-static inline void trace_usb_xhci_xfer_start(void * xfer, uint32_t slotid, uint32_t epid, uint32_t streamid)
-{
-}
-
-static inline void trace_usb_xhci_xfer_async(void * xfer)
-{
-}
-
-static inline void trace_usb_xhci_xfer_nak(void * xfer)
-{
-}
-
-static inline void trace_usb_xhci_xfer_retry(void * xfer)
-{
-}
-
-static inline void trace_usb_xhci_xfer_success(void * xfer, uint32_t bytes)
-{
-}
-
-static inline void trace_usb_xhci_xfer_error(void * xfer, uint32_t ret)
-{
-}
-
-static inline void trace_usb_xhci_unimplemented(const char * item, int nr)
-{
-}
-
-static inline void trace_usb_desc_device(int addr, int len, int ret)
-{
-}
-
-static inline void trace_usb_desc_device_qualifier(int addr, int len, int ret)
-{
-}
-
-static inline void trace_usb_desc_config(int addr, int index, int len, int ret)
-{
-}
-
-static inline void trace_usb_desc_other_speed_config(int addr, int index, int len, int ret)
-{
-}
-
-static inline void trace_usb_desc_string(int addr, int index, int len, int ret)
-{
-}
-
-static inline void trace_usb_desc_bos(int addr, int len, int ret)
-{
-}
-
-static inline void trace_usb_set_addr(int addr)
-{
-}
-
-static inline void trace_usb_set_config(int addr, int config, int ret)
-{
-}
-
-static inline void trace_usb_set_interface(int addr, int iface, int alt, int ret)
-{
-}
-
-static inline void trace_usb_clear_device_feature(int addr, int feature, int ret)
-{
-}
-
-static inline void trace_usb_set_device_feature(int addr, int feature, int ret)
-{
-}
-
-static inline void trace_usb_hub_reset(int addr)
-{
-}
-
-static inline void trace_usb_hub_control(int addr, int request, int value, int index, int length)
-{
-}
-
-static inline void trace_usb_hub_get_port_status(int addr, int nr, int status, int changed)
-{
-}
-
-static inline void trace_usb_hub_set_port_feature(int addr, int nr, const char * f)
-{
-}
-
-static inline void trace_usb_hub_clear_port_feature(int addr, int nr, const char * f)
-{
-}
-
-static inline void trace_usb_hub_attach(int addr, int nr)
-{
-}
-
-static inline void trace_usb_hub_detach(int addr, int nr)
-{
-}
-
-static inline void trace_usb_uas_reset(int addr)
-{
-}
-
-static inline void trace_usb_uas_command(int addr, uint16_t tag, int lun, uint32_t lun64_1, uint32_t lun64_2)
-{
-}
-
-static inline void trace_usb_uas_response(int addr, uint16_t tag, uint8_t code)
-{
-}
-
-static inline void trace_usb_uas_sense(int addr, uint16_t tag, uint8_t status)
-{
-}
-
-static inline void trace_usb_uas_read_ready(int addr, uint16_t tag)
-{
-}
-
-static inline void trace_usb_uas_write_ready(int addr, uint16_t tag)
-{
-}
-
-static inline void trace_usb_uas_xfer_data(int addr, uint16_t tag, uint32_t copy, uint32_t uoff, uint32_t usize, uint32_t soff, uint32_t ssize)
-{
-}
-
-static inline void trace_usb_uas_scsi_data(int addr, uint16_t tag, uint32_t bytes)
-{
-}
-
-static inline void trace_usb_uas_scsi_complete(int addr, uint16_t tag, uint32_t status, uint32_t resid)
-{
-}
-
-static inline void trace_usb_uas_tmf_abort_task(int addr, uint16_t tag, uint16_t task_tag)
-{
-}
-
-static inline void trace_usb_uas_tmf_logical_unit_reset(int addr, uint16_t tag, int lun)
-{
-}
-
-static inline void trace_usb_uas_tmf_unsupported(int addr, uint16_t tag, uint32_t function)
-{
-}
-
-static inline void trace_usb_host_open_started(int bus, int addr)
-{
-}
-
-static inline void trace_usb_host_open_success(int bus, int addr)
-{
-}
-
-static inline void trace_usb_host_open_failure(int bus, int addr)
-{
-}
-
-static inline void trace_usb_host_disconnect(int bus, int addr)
-{
-}
-
-static inline void trace_usb_host_close(int bus, int addr)
-{
-}
-
-static inline void trace_usb_host_attach_kernel(int bus, int addr, int interface)
-{
-}
-
-static inline void trace_usb_host_detach_kernel(int bus, int addr, int interface)
-{
-}
-
-static inline void trace_usb_host_set_address(int bus, int addr, int config)
-{
-}
-
-static inline void trace_usb_host_set_config(int bus, int addr, int config)
-{
-}
-
-static inline void trace_usb_host_set_interface(int bus, int addr, int interface, int alt)
-{
-}
-
-static inline void trace_usb_host_claim_interfaces(int bus, int addr, int config, int nif)
-{
-}
-
-static inline void trace_usb_host_claim_interface(int bus, int addr, int config, int interface)
-{
-}
-
-static inline void trace_usb_host_release_interfaces(int bus, int addr)
-{
-}
-
-static inline void trace_usb_host_release_interface(int bus, int addr, int interface)
-{
-}
-
-static inline void trace_usb_host_req_control(int bus, int addr, void * p, int req, int value, int index)
-{
-}
-
-static inline void trace_usb_host_req_data(int bus, int addr, void * p, int in, int ep, int size)
-{
-}
-
-static inline void trace_usb_host_req_complete(int bus, int addr, void * p, int status, int length)
-{
-}
-
-static inline void trace_usb_host_req_emulated(int bus, int addr, void * p, int status)
-{
-}
-
-static inline void trace_usb_host_req_canceled(int bus, int addr, void * p)
-{
-}
-
-static inline void trace_usb_host_urb_submit(int bus, int addr, void * aurb, int length, int more)
-{
-}
-
-static inline void trace_usb_host_urb_complete(int bus, int addr, void * aurb, int status, int length, int more)
-{
-}
-
-static inline void trace_usb_host_urb_canceled(int bus, int addr, void * aurb)
-{
-}
-
-static inline void trace_usb_host_ep_set_halt(int bus, int addr, int ep)
-{
-}
-
-static inline void trace_usb_host_ep_clear_halt(int bus, int addr, int ep)
-{
-}
-
-static inline void trace_usb_host_iso_start(int bus, int addr, int ep)
-{
-}
-
-static inline void trace_usb_host_iso_stop(int bus, int addr, int ep)
-{
-}
-
-static inline void trace_usb_host_iso_out_of_bufs(int bus, int addr, int ep)
-{
-}
-
-static inline void trace_usb_host_iso_many_urbs(int bus, int addr, int count)
-{
-}
-
-static inline void trace_usb_host_reset(int bus, int addr)
-{
-}
-
-static inline void trace_usb_host_auto_scan_enabled(void)
-{
-}
-
-static inline void trace_usb_host_auto_scan_disabled(void)
-{
-}
-
-static inline void trace_usb_host_claim_port(int bus, int hub, int port)
-{
-}
-
-static inline void trace_usb_host_parse_device(int bus, int addr, int vendor, int product)
-{
-}
-
-static inline void trace_usb_host_parse_config(int bus, int addr, int value, int active)
-{
-}
-
-static inline void trace_usb_host_parse_interface(int bus, int addr, int num, int alt, int active)
-{
-}
-
-static inline void trace_usb_host_parse_endpoint(int bus, int addr, int ep, const char * dir, const char * type, int active)
-{
-}
-
-static inline void trace_usb_host_parse_unknown(int bus, int addr, int len, int type)
-{
-}
-
-static inline void trace_usb_host_parse_error(int bus, int addr, const char * errmsg)
-{
-}
-
-static inline void trace_scsi_req_alloc(int target, int lun, int tag)
-{
-}
-
-static inline void trace_scsi_req_cancel(int target, int lun, int tag)
-{
-}
-
-static inline void trace_scsi_req_data(int target, int lun, int tag, int len)
-{
-}
-
-static inline void trace_scsi_req_data_canceled(int target, int lun, int tag, int len)
-{
-}
-
-static inline void trace_scsi_req_dequeue(int target, int lun, int tag)
-{
-}
-
-static inline void trace_scsi_req_continue(int target, int lun, int tag)
-{
-}
-
-static inline void trace_scsi_req_continue_canceled(int target, int lun, int tag)
-{
-}
-
-static inline void trace_scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer)
-{
-}
-
-static inline void trace_scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba)
-{
-}
-
-static inline void trace_scsi_req_parse_bad(int target, int lun, int tag, int cmd)
-{
-}
-
-static inline void trace_scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq)
-{
-}
-
-static inline void trace_scsi_device_set_ua(int target, int lun, int key, int asc, int ascq)
-{
-}
-
-static inline void trace_scsi_report_luns(int target, int lun, int tag)
-{
-}
-
-static inline void trace_scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2)
-{
-}
-
-static inline void trace_scsi_test_unit_ready(int target, int lun, int tag)
-{
-}
-
-static inline void trace_scsi_request_sense(int target, int lun, int tag)
-{
-}
-
-static inline void trace_vm_state_notify(int running, int reason)
-{
-}
-
-static inline void trace_load_file(const char * name, const char * path)
-{
-}
-
-static inline void trace_runstate_set(int new_state)
-{
-}
-
-static inline void trace_qcow2_writev_start_req(void * co, int64_t sector, int nb_sectors)
-{
-}
-
-static inline void trace_qcow2_writev_done_req(void * co, int ret)
-{
-}
-
-static inline void trace_qcow2_writev_start_part(void * co)
-{
-}
-
-static inline void trace_qcow2_writev_done_part(void * co, int cur_nr_sectors)
-{
-}
-
-static inline void trace_qcow2_writev_data(void * co, uint64_t offset)
-{
-}
-
-static inline void trace_qcow2_alloc_clusters_offset(void * co, uint64_t offset, int n_start, int n_end)
-{
-}
-
-static inline void trace_qcow2_handle_copied(void * co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes)
-{
-}
-
-static inline void trace_qcow2_handle_alloc(void * co, uint64_t guest_offset, uint64_t host_offset, uint64_t bytes)
-{
-}
-
-static inline void trace_qcow2_do_alloc_clusters_offset(void * co, uint64_t guest_offset, uint64_t host_offset, int nb_clusters)
-{
-}
-
-static inline void trace_qcow2_cluster_alloc_phys(void * co)
-{
-}
-
-static inline void trace_qcow2_cluster_link_l2(void * co, int nb_clusters)
-{
-}
-
-static inline void trace_qcow2_l2_allocate(void * bs, int l1_index)
-{
-}
-
-static inline void trace_qcow2_l2_allocate_get_empty(void * bs, int l1_index)
-{
-}
-
-static inline void trace_qcow2_l2_allocate_write_l2(void * bs, int l1_index)
-{
-}
-
-static inline void trace_qcow2_l2_allocate_write_l1(void * bs, int l1_index)
-{
-}
-
-static inline void trace_qcow2_l2_allocate_done(void * bs, int l1_index, int ret)
-{
-}
-
-static inline void trace_qcow2_cache_get(void * co, int c, uint64_t offset, bool read_from_disk)
-{
-}
-
-static inline void trace_qcow2_cache_get_replace_entry(void * co, int c, int i)
-{
-}
-
-static inline void trace_qcow2_cache_get_read(void * co, int c, int i)
-{
-}
-
-static inline void trace_qcow2_cache_get_done(void * co, int c, int i)
-{
-}
-
-static inline void trace_qcow2_cache_flush(void * co, int c)
-{
-}
-
-static inline void trace_qcow2_cache_entry_flush(void * co, int c, int i)
-{
-}
-
-static inline void trace_qed_alloc_l2_cache_entry(void * l2_cache, void * entry)
-{
-}
-
-static inline void trace_qed_unref_l2_cache_entry(void * entry, int ref)
-{
-}
-
-static inline void trace_qed_find_l2_cache_entry(void * l2_cache, void * entry, uint64_t offset, int ref)
-{
-}
-
-static inline void trace_qed_read_table(void * s, uint64_t offset, void * table)
-{
-}
-
-static inline void trace_qed_read_table_cb(void * s, void * table, int ret)
-{
-}
-
-static inline void trace_qed_write_table(void * s, uint64_t offset, void * table, unsigned int index, unsigned int n)
-{
-}
-
-static inline void trace_qed_write_table_cb(void * s, void * table, int flush, int ret)
-{
-}
-
-static inline void trace_qed_need_check_timer_cb(void * s)
-{
-}
-
-static inline void trace_qed_start_need_check_timer(void * s)
-{
-}
-
-static inline void trace_qed_cancel_need_check_timer(void * s)
-{
-}
-
-static inline void trace_qed_aio_complete(void * s, void * acb, int ret)
-{
-}
-
-static inline void trace_qed_aio_setup(void * s, void * acb, int64_t sector_num, int nb_sectors, void * opaque, int flags)
-{
-}
-
-static inline void trace_qed_aio_next_io(void * s, void * acb, int ret, uint64_t cur_pos)
-{
-}
-
-static inline void trace_qed_aio_read_data(void * s, void * acb, int ret, uint64_t offset, size_t len)
-{
-}
-
-static inline void trace_qed_aio_write_data(void * s, void * acb, int ret, uint64_t offset, size_t len)
-{
-}
-
-static inline void trace_qed_aio_write_prefill(void * s, void * acb, uint64_t start, size_t len, uint64_t offset)
-{
-}
-
-static inline void trace_qed_aio_write_postfill(void * s, void * acb, uint64_t start, size_t len, uint64_t offset)
-{
-}
-
-static inline void trace_qed_aio_write_main(void * s, void * acb, int ret, uint64_t offset, size_t len)
-{
-}
-
-static inline void trace_g364fb_read(uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_g364fb_write(uint64_t addr, uint32_t new)
-{
-}
-
-static inline void trace_grlib_gptimer_enable(int id, uint32_t count)
-{
-}
-
-static inline void trace_grlib_gptimer_disabled(int id, uint32_t config)
-{
-}
-
-static inline void trace_grlib_gptimer_restart(int id, uint32_t reload)
-{
-}
-
-static inline void trace_grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq)
-{
-}
-
-static inline void trace_grlib_gptimer_hit(int id)
-{
-}
-
-static inline void trace_grlib_gptimer_readl(int id, uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_grlib_gptimer_writel(int id, uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2)
-{
-}
-
-static inline void trace_grlib_irqmp_ack(int intno)
-{
-}
-
-static inline void trace_grlib_irqmp_set_irq(int irq)
-{
-}
-
-static inline void trace_grlib_irqmp_readl_unknown(uint64_t addr)
-{
-}
-
-static inline void trace_grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value)
-{
-}
-
-static inline void trace_grlib_apbuart_event(int event)
-{
-}
-
-static inline void trace_grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value)
-{
-}
-
-static inline void trace_grlib_apbuart_readl_unknown(uint64_t addr)
-{
-}
-
-static inline void trace_leon3_set_irq(int intno)
-{
-}
-
-static inline void trace_leon3_reset_irq(int intno)
-{
-}
-
-static inline void trace_spice_vmc_write(ssize_t out, int len)
-{
-}
-
-static inline void trace_spice_vmc_read(int bytes, int len)
-{
-}
-
-static inline void trace_spice_vmc_register_interface(void * scd)
-{
-}
-
-static inline void trace_spice_vmc_unregister_interface(void * scd)
-{
-}
-
-static inline void trace_spice_vmc_event(int event)
-{
-}
-
-static inline void trace_lm32_pic_raise_irq(void)
-{
-}
-
-static inline void trace_lm32_pic_lower_irq(void)
-{
-}
-
-static inline void trace_lm32_pic_interrupt(int irq, int level)
-{
-}
-
-static inline void trace_lm32_pic_set_im(uint32_t im)
-{
-}
-
-static inline void trace_lm32_pic_set_ip(uint32_t ip)
-{
-}
-
-static inline void trace_lm32_pic_get_im(uint32_t im)
-{
-}
-
-static inline void trace_lm32_pic_get_ip(uint32_t ip)
-{
-}
-
-static inline void trace_lm32_juart_get_jtx(uint32_t value)
-{
-}
-
-static inline void trace_lm32_juart_set_jtx(uint32_t value)
-{
-}
-
-static inline void trace_lm32_juart_get_jrx(uint32_t value)
-{
-}
-
-static inline void trace_lm32_juart_set_jrx(uint32_t value)
-{
-}
-
-static inline void trace_lm32_timer_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_lm32_timer_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_lm32_timer_hit(void)
-{
-}
-
-static inline void trace_lm32_timer_irq_state(int level)
-{
-}
-
-static inline void trace_lm32_uart_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_lm32_uart_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_lm32_uart_irq_state(int level)
-{
-}
-
-static inline void trace_lm32_sys_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_megasas_init_firmware(uint64_t pa)
-{
-}
-
-static inline void trace_megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags)
-{
-}
-
-static inline void trace_megasas_initq_map_failed(int frame)
-{
-}
-
-static inline void trace_megasas_initq_mismatch(int queue_len, int fw_cmds)
-{
-}
-
-static inline void trace_megasas_qf_found(unsigned int index, uint64_t pa)
-{
-}
-
-static inline void trace_megasas_qf_new(unsigned int index, void * cmd)
-{
-}
-
-static inline void trace_megasas_qf_failed(unsigned long pa)
-{
-}
-
-static inline void trace_megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, unsigned int tail, int busy)
-{
-}
-
-static inline void trace_megasas_qf_update(unsigned int head, unsigned int busy)
-{
-}
-
-static inline void trace_megasas_qf_dequeue(unsigned int index)
-{
-}
-
-static inline void trace_megasas_qf_map_failed(int cmd, unsigned long frame)
-{
-}
-
-static inline void trace_megasas_qf_complete_noirq(uint64_t context)
-{
-}
-
-static inline void trace_megasas_qf_complete(uint64_t context, unsigned int tail, unsigned int offset, int busy, unsigned int doorbell)
-{
-}
-
-static inline void trace_megasas_handle_frame(const char * cmd, uint64_t addr, uint64_t context, uint32_t count)
-{
-}
-
-static inline void trace_megasas_frame_busy(uint64_t addr)
-{
-}
-
-static inline void trace_megasas_unhandled_frame_cmd(int cmd, uint8_t frame_cmd)
-{
-}
-
-static inline void trace_megasas_handle_scsi(const char * frame, int bus, int dev, int lun, void * sdev, unsigned long size)
-{
-}
-
-static inline void trace_megasas_scsi_target_not_present(const char * frame, int bus, int dev, int lun)
-{
-}
-
-static inline void trace_megasas_scsi_invalid_cdb_len(const char * frame, int bus, int dev, int lun, int len)
-{
-}
-
-static inline void trace_megasas_iov_read_overflow(int cmd, int bytes, int len)
-{
-}
-
-static inline void trace_megasas_iov_write_overflow(int cmd, int bytes, int len)
-{
-}
-
-static inline void trace_megasas_iov_read_underflow(int cmd, int bytes, int len)
-{
-}
-
-static inline void trace_megasas_iov_write_underflow(int cmd, int bytes, int len)
-{
-}
-
-static inline void trace_megasas_scsi_req_alloc_failed(const char * frame, int dev, int lun)
-{
-}
-
-static inline void trace_megasas_scsi_read_start(int cmd, int len)
-{
-}
-
-static inline void trace_megasas_scsi_write_start(int cmd, int len)
-{
-}
-
-static inline void trace_megasas_scsi_nodata(int cmd)
-{
-}
-
-static inline void trace_megasas_scsi_complete(int cmd, uint32_t status, int len, int xfer)
-{
-}
-
-static inline void trace_megasas_command_complete(int cmd, uint32_t status, uint32_t resid)
-{
-}
-
-static inline void trace_megasas_handle_io(int cmd, const char * frame, int dev, int lun, unsigned long lba, unsigned long count)
-{
-}
-
-static inline void trace_megasas_io_target_not_present(int cmd, const char * frame, int dev, int lun)
-{
-}
-
-static inline void trace_megasas_io_read_start(int cmd, unsigned long lba, unsigned long count, unsigned long len)
-{
-}
-
-static inline void trace_megasas_io_write_start(int cmd, unsigned long lba, unsigned long count, unsigned long len)
-{
-}
-
-static inline void trace_megasas_io_complete(int cmd, uint32_t len)
-{
-}
-
-static inline void trace_megasas_io_read(int cmd, int bytes, int len, unsigned long offset)
-{
-}
-
-static inline void trace_megasas_io_write(int cmd, int bytes, int len, unsigned long offset)
-{
-}
-
-static inline void trace_megasas_io_continue(int cmd, int bytes)
-{
-}
-
-static inline void trace_megasas_iovec_map_failed(int cmd, int index, unsigned long iov_size)
-{
-}
-
-static inline void trace_megasas_iovec_sgl_overflow(int cmd, int index, int limit)
-{
-}
-
-static inline void trace_megasas_iovec_sgl_underflow(int cmd, int index)
-{
-}
-
-static inline void trace_megasas_iovec_sgl_invalid(int cmd, int index, uint64_t pa, uint32_t len)
-{
-}
-
-static inline void trace_megasas_iovec_overflow(int cmd, int len, int limit)
-{
-}
-
-static inline void trace_megasas_iovec_underflow(int cmd, int len, int limit)
-{
-}
-
-static inline void trace_megasas_handle_dcmd(int cmd, int opcode)
-{
-}
-
-static inline void trace_megasas_finish_dcmd(int cmd, int size)
-{
-}
-
-static inline void trace_megasas_dcmd_req_alloc_failed(int cmd, const char * desc)
-{
-}
-
-static inline void trace_megasas_dcmd_internal_submit(int cmd, const char * desc, int dev)
-{
-}
-
-static inline void trace_megasas_dcmd_internal_finish(int cmd, int opcode, int lun)
-{
-}
-
-static inline void trace_megasas_dcmd_internal_invalid(int cmd, int opcode)
-{
-}
-
-static inline void trace_megasas_dcmd_unhandled(int cmd, int opcode, int len)
-{
-}
-
-static inline void trace_megasas_dcmd_zero_sge(int cmd)
-{
-}
-
-static inline void trace_megasas_dcmd_invalid_sge(int cmd, int count)
-{
-}
-
-static inline void trace_megasas_dcmd_map_failed(int cmd)
-{
-}
-
-static inline void trace_megasas_dcmd_invalid_xfer_len(int cmd, unsigned long size, unsigned long max)
-{
-}
-
-static inline void trace_megasas_dcmd_enter(int cmd, const char * dcmd, int len)
-{
-}
-
-static inline void trace_megasas_dcmd_dummy(int cmd, unsigned long size)
-{
-}
-
-static inline void trace_megasas_dcmd_set_fw_time(int cmd, unsigned long time)
-{
-}
-
-static inline void trace_megasas_dcmd_pd_get_list(int cmd, int num, int max, int offset)
-{
-}
-
-static inline void trace_megasas_dcmd_ld_get_list(int cmd, int num, int max)
-{
-}
-
-static inline void trace_megasas_dcmd_ld_get_info(int cmd, int ld_id)
-{
-}
-
-static inline void trace_megasas_dcmd_pd_get_info(int cmd, int pd_id)
-{
-}
-
-static inline void trace_megasas_dcmd_pd_list_query(int cmd, int flags)
-{
-}
-
-static inline void trace_megasas_dcmd_unsupported(int cmd, unsigned long size)
-{
-}
-
-static inline void trace_megasas_abort_frame(int cmd, int abort_cmd)
-{
-}
-
-static inline void trace_megasas_abort_no_cmd(int cmd, uint64_t context)
-{
-}
-
-static inline void trace_megasas_abort_invalid_context(int cmd, uint64_t context, int abort_cmd)
-{
-}
-
-static inline void trace_megasas_reset(void)
-{
-}
-
-static inline void trace_megasas_init(int sges, int cmds, const char * intr, const char * mode)
-{
-}
-
-static inline void trace_megasas_msix_raise(int vector)
-{
-}
-
-static inline void trace_megasas_irq_lower(void)
-{
-}
-
-static inline void trace_megasas_irq_raise(void)
-{
-}
-
-static inline void trace_megasas_intr_enabled(void)
-{
-}
-
-static inline void trace_megasas_intr_disabled(void)
-{
-}
-
-static inline void trace_megasas_mmio_readl(unsigned long addr, uint32_t val)
-{
-}
-
-static inline void trace_megasas_mmio_invalid_readl(unsigned long addr)
-{
-}
-
-static inline void trace_megasas_mmio_writel(uint32_t addr, uint32_t val)
-{
-}
-
-static inline void trace_megasas_mmio_invalid_writel(uint32_t addr, uint32_t val)
-{
-}
-
-static inline void trace_milkymist_ac97_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_ac97_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_ac97_pulse_irq_crrequest(void)
-{
-}
-
-static inline void trace_milkymist_ac97_pulse_irq_crreply(void)
-{
-}
-
-static inline void trace_milkymist_ac97_pulse_irq_dmaw(void)
-{
-}
-
-static inline void trace_milkymist_ac97_pulse_irq_dmar(void)
-{
-}
-
-static inline void trace_milkymist_ac97_in_cb(int avail, uint32_t remaining)
-{
-}
-
-static inline void trace_milkymist_ac97_in_cb_transferred(int transferred)
-{
-}
-
-static inline void trace_milkymist_ac97_out_cb(int free, uint32_t remaining)
-{
-}
-
-static inline void trace_milkymist_ac97_out_cb_transferred(int transferred)
-{
-}
-
-static inline void trace_milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_memcard_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_memcard_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_minimac2_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_minimac2_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value)
-{
-}
-
-static inline void trace_milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value)
-{
-}
-
-static inline void trace_milkymist_minimac2_tx_frame(uint32_t length)
-{
-}
-
-static inline void trace_milkymist_minimac2_rx_frame(const void * buf, uint32_t length)
-{
-}
-
-static inline void trace_milkymist_minimac2_drop_rx_frame(const void * buf)
-{
-}
-
-static inline void trace_milkymist_minimac2_rx_transfer(const void * buf, uint32_t length)
-{
-}
-
-static inline void trace_milkymist_minimac2_raise_irq_rx(void)
-{
-}
-
-static inline void trace_milkymist_minimac2_lower_irq_rx(void)
-{
-}
-
-static inline void trace_milkymist_minimac2_pulse_irq_tx(void)
-{
-}
-
-static inline void trace_milkymist_pfpu_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_pfpu_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr)
-{
-}
-
-static inline void trace_milkymist_pfpu_pulse_irq(void)
-{
-}
-
-static inline void trace_milkymist_softusb_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_softusb_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_softusb_mevt(uint8_t m)
-{
-}
-
-static inline void trace_milkymist_softusb_kevt(uint8_t m)
-{
-}
-
-static inline void trace_milkymist_softusb_mouse_event(int dx, int dy, int dz, int bs)
-{
-}
-
-static inline void trace_milkymist_softusb_pulse_irq(void)
-{
-}
-
-static inline void trace_milkymist_sysctl_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_sysctl_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_sysctl_icap_write(uint32_t value)
-{
-}
-
-static inline void trace_milkymist_sysctl_start_timer0(void)
-{
-}
-
-static inline void trace_milkymist_sysctl_stop_timer0(void)
-{
-}
-
-static inline void trace_milkymist_sysctl_start_timer1(void)
-{
-}
-
-static inline void trace_milkymist_sysctl_stop_timer1(void)
-{
-}
-
-static inline void trace_milkymist_sysctl_pulse_irq_timer0(void)
-{
-}
-
-static inline void trace_milkymist_sysctl_pulse_irq_timer1(void)
-{
-}
-
-static inline void trace_milkymist_tmu2_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_tmu2_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_tmu2_start(void)
-{
-}
-
-static inline void trace_milkymist_tmu2_pulse_irq(void)
-{
-}
-
-static inline void trace_milkymist_uart_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_uart_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_uart_raise_irq(void)
-{
-}
-
-static inline void trace_milkymist_uart_lower_irq(void)
-{
-}
-
-static inline void trace_milkymist_vgafb_memory_read(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_milkymist_vgafb_memory_write(uint32_t addr, uint32_t value)
-{
-}
-
-static inline void trace_mipsnet_send(uint32_t size)
-{
-}
-
-static inline void trace_mipsnet_receive(uint32_t size)
-{
-}
-
-static inline void trace_mipsnet_read(uint64_t addr, uint32_t val)
-{
-}
-
-static inline void trace_mipsnet_write(uint64_t addr, uint64_t val)
-{
-}
-
-static inline void trace_mipsnet_irq(uint32_t isr, uint32_t intctl)
-{
-}
-
-static inline void trace_pc87312_io_read(uint32_t addr, uint32_t val)
-{
-}
-
-static inline void trace_pc87312_io_write(uint32_t addr, uint32_t val)
-{
-}
-
-static inline void trace_pc87312_info_floppy(uint32_t base)
-{
-}
-
-static inline void trace_pc87312_info_ide(uint32_t base)
-{
-}
-
-static inline void trace_pc87312_info_parallel(uint32_t base, uint32_t irq)
-{
-}
-
-static inline void trace_pc87312_info_serial(int n, uint32_t base, uint32_t irq)
-{
-}
-
-static inline void trace_pvscsi_ring_init_data(uint32_t txr_len_log2, uint32_t rxr_len_log2)
-{
-}
-
-static inline void trace_pvscsi_ring_init_msg(uint32_t len_log2)
-{
-}
-
-static inline void trace_pvscsi_ring_flush_cmp(uint64_t filled_cmp_ptr)
-{
-}
-
-static inline void trace_pvscsi_ring_flush_msg(uint64_t filled_cmp_ptr)
-{
-}
-
-static inline void trace_pvscsi_update_irq_level(bool raise, uint64_t mask, uint64_t status)
-{
-}
-
-static inline void trace_pvscsi_update_irq_msi(void)
-{
-}
-
-static inline void trace_pvscsi_cmp_ring_put(unsigned long addr)
-{
-}
-
-static inline void trace_pvscsi_msg_ring_put(unsigned long addr)
-{
-}
-
-static inline void trace_pvscsi_complete_request(uint64_t context, uint64_t len, uint8_t sense_key)
-{
-}
-
-static inline void trace_pvscsi_get_sg_list(int nsg, size_t size)
-{
-}
-
-static inline void trace_pvscsi_get_next_sg_elem(uint32_t flags)
-{
-}
-
-static inline void trace_pvscsi_command_complete_not_found(uint32_t tag)
-{
-}
-
-static inline void trace_pvscsi_command_complete_data_run(void)
-{
-}
-
-static inline void trace_pvscsi_command_complete_sense_len(int len)
-{
-}
-
-static inline void trace_pvscsi_convert_sglist(uint64_t context, unsigned long addr, uint32_t resid)
-{
-}
-
-static inline void trace_pvscsi_process_req_descr(uint8_t cmd, uint64_t ctx)
-{
-}
-
-static inline void trace_pvscsi_process_req_descr_unknown_device(void)
-{
-}
-
-static inline void trace_pvscsi_process_req_descr_invalid_dir(void)
-{
-}
-
-static inline void trace_pvscsi_process_io(unsigned long addr)
-{
-}
-
-static inline void trace_pvscsi_on_cmd_noimpl(const char* cmd)
-{
-}
-
-static inline void trace_pvscsi_on_cmd_reset_dev(uint32_t tgt, int lun, void* dev)
-{
-}
-
-static inline void trace_pvscsi_on_cmd_arrived(const char* cmd)
-{
-}
-
-static inline void trace_pvscsi_on_cmd_abort(uint64_t ctx, uint32_t tgt)
-{
-}
-
-static inline void trace_pvscsi_on_cmd_unknown(uint64_t cmd_id)
-{
-}
-
-static inline void trace_pvscsi_on_cmd_unknown_data(uint32_t data)
-{
-}
-
-static inline void trace_pvscsi_io_write(const char* cmd, uint64_t val)
-{
-}
-
-static inline void trace_pvscsi_io_write_unknown(unsigned long addr, unsigned sz, uint64_t val)
-{
-}
-
-static inline void trace_pvscsi_io_read(const char* cmd, uint64_t status)
-{
-}
-
-static inline void trace_pvscsi_io_read_unknown(unsigned long addr, unsigned sz)
-{
-}
-
-static inline void trace_pvscsi_init_msi_fail(int res)
-{
-}
-
-static inline void trace_pvscsi_state(const char* state)
-{
-}
-
-static inline void trace_pvscsi_tx_rings_ppn(const char* label, uint64_t ppn)
-{
-}
-
-static inline void trace_pvscsi_tx_rings_num_pages(const char* label, uint32_t num)
-{
-}
-
-static inline void trace_xen_ram_alloc(unsigned long ram_addr, unsigned long size)
-{
-}
-
-static inline void trace_xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty)
-{
-}
-
-static inline void trace_xen_map_cache(uint64_t phys_addr)
-{
-}
-
-static inline void trace_xen_remap_bucket(uint64_t index)
-{
-}
-
-static inline void trace_xen_map_cache_return(void* ptr)
-{
-}
-
-static inline void trace_xen_map_block(uint64_t phys_addr, uint64_t size)
-{
-}
-
-static inline void trace_xen_unmap_block(void* addr, unsigned long size)
-{
-}
-
-static inline void trace_xen_platform_log(char * s)
-{
-}
-
-static inline void trace_qemu_coroutine_enter(void * from, void * to, void * opaque)
-{
-}
-
-static inline void trace_qemu_coroutine_yield(void * from, void * to)
-{
-}
-
-static inline void trace_qemu_coroutine_terminate(void * co)
-{
-}
-
-static inline void trace_qemu_co_queue_run_restart(void * co)
-{
-}
-
-static inline void trace_qemu_co_queue_next(void * nxt)
-{
-}
-
-static inline void trace_qemu_co_mutex_lock_entry(void * mutex, void * self)
-{
-}
-
-static inline void trace_qemu_co_mutex_lock_return(void * mutex, void * self)
-{
-}
-
-static inline void trace_qemu_co_mutex_unlock_entry(void * mutex, void * self)
-{
-}
-
-static inline void trace_qemu_co_mutex_unlock_return(void * mutex, void * self)
-{
-}
-
-static inline void trace_escc_put_queue(char channel, int b)
-{
-}
-
-static inline void trace_escc_get_queue(char channel, int val)
-{
-}
-
-static inline void trace_escc_update_irq(int irq)
-{
-}
-
-static inline void trace_escc_update_parameters(char channel, int speed, int parity, int data_bits, int stop_bits)
-{
-}
-
-static inline void trace_escc_mem_writeb_ctrl(char channel, uint32_t reg, uint32_t val)
-{
-}
-
-static inline void trace_escc_mem_writeb_data(char channel, uint32_t val)
-{
-}
-
-static inline void trace_escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val)
-{
-}
-
-static inline void trace_escc_mem_readb_data(char channel, uint32_t ret)
-{
-}
-
-static inline void trace_escc_serial_receive_byte(char channel, int ch)
-{
-}
-
-static inline void trace_escc_sunkbd_event_in(int ch)
-{
-}
-
-static inline void trace_escc_sunkbd_event_out(int ch)
-{
-}
-
-static inline void trace_escc_kbd_command(int val)
-{
-}
-
-static inline void trace_escc_sunmouse_event(int dx, int dy, int buttons_state)
-{
-}
-
-static inline void trace_iscsi_aio_write16_cb(void * iscsi, int status, void * acb, int canceled)
-{
-}
-
-static inline void trace_iscsi_aio_writev(void * iscsi, int64_t sector_num, int nb_sectors, void * opaque, void * acb)
-{
-}
-
-static inline void trace_iscsi_aio_read16_cb(void * iscsi, int status, void * acb, int canceled)
-{
-}
-
-static inline void trace_iscsi_aio_readv(void * iscsi, int64_t sector_num, int nb_sectors, void * opaque, void * acb)
-{
-}
-
-static inline void trace_esp_error_fifo_overrun(void)
-{
-}
-
-static inline void trace_esp_error_unhandled_command(uint32_t val)
-{
-}
-
-static inline void trace_esp_error_invalid_write(uint32_t val, uint32_t addr)
-{
-}
-
-static inline void trace_esp_raise_irq(void)
-{
-}
-
-static inline void trace_esp_lower_irq(void)
-{
-}
-
-static inline void trace_esp_dma_enable(void)
-{
-}
-
-static inline void trace_esp_dma_disable(void)
-{
-}
-
-static inline void trace_esp_get_cmd(uint32_t dmalen, int target)
-{
-}
-
-static inline void trace_esp_do_busid_cmd(uint8_t busid)
-{
-}
-
-static inline void trace_esp_handle_satn_stop(uint32_t cmdlen)
-{
-}
-
-static inline void trace_esp_write_response(uint32_t status)
-{
-}
-
-static inline void trace_esp_do_dma(uint32_t cmdlen, uint32_t len)
-{
-}
-
-static inline void trace_esp_command_complete(void)
-{
-}
-
-static inline void trace_esp_command_complete_unexpected(void)
-{
-}
-
-static inline void trace_esp_command_complete_fail(void)
-{
-}
-
-static inline void trace_esp_transfer_data(uint32_t dma_left, int32_t ti_size)
-{
-}
-
-static inline void trace_esp_handle_ti(uint32_t minlen)
-{
-}
-
-static inline void trace_esp_handle_ti_cmd(uint32_t cmdlen)
-{
-}
-
-static inline void trace_esp_mem_readb(uint32_t saddr, uint8_t reg)
-{
-}
-
-static inline void trace_esp_mem_writeb(uint32_t saddr, uint8_t reg, uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_nop(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_flush(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_reset(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_bus_reset(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_iccs(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_msgacc(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_pad(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_satn(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_rstatn(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_sel(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_selatn(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_selatns(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_ensel(uint32_t val)
-{
-}
-
-static inline void trace_esp_mem_writeb_cmd_dissel(uint32_t val)
-{
-}
-
-static inline void trace_esp_pci_error_invalid_dma_direction(void)
-{
-}
-
-static inline void trace_esp_pci_error_invalid_read(uint32_t reg)
-{
-}
-
-static inline void trace_esp_pci_error_invalid_write(uint32_t reg)
-{
-}
-
-static inline void trace_esp_pci_error_invalid_write_dma(uint32_t val, uint32_t addr)
-{
-}
-
-static inline void trace_esp_pci_dma_read(uint32_t saddr, uint32_t reg)
-{
-}
-
-static inline void trace_esp_pci_dma_write(uint32_t saddr, uint32_t reg, uint32_t val)
-{
-}
-
-static inline void trace_esp_pci_dma_idle(uint32_t val)
-{
-}
-
-static inline void trace_esp_pci_dma_blast(uint32_t val)
-{
-}
-
-static inline void trace_esp_pci_dma_abort(uint32_t val)
-{
-}
-
-static inline void trace_esp_pci_dma_start(uint32_t val)
-{
-}
-
-static inline void trace_esp_pci_sbac_read(uint32_t reg)
-{
-}
-
-static inline void trace_esp_pci_sbac_write(uint32_t reg, uint32_t val)
-{
-}
-
-static inline void trace_handle_qmp_command(void * mon, const char * cmd_name)
-{
-}
-
-static inline void trace_monitor_protocol_emitter(void * mon)
-{
-}
-
-static inline void trace_monitor_protocol_event(uint32_t event, const char * evname, void * data)
-{
-}
-
-static inline void trace_monitor_protocol_event_handler(uint32_t event, void * data, uint64_t last, uint64_t now)
-{
-}
-
-static inline void trace_monitor_protocol_event_emit(uint32_t event, void * data)
-{
-}
-
-static inline void trace_monitor_protocol_event_queue(uint32_t event, void * data, uint64_t rate, uint64_t last, uint64_t now)
-{
-}
-
-static inline void trace_monitor_protocol_event_throttle(uint32_t event, uint64_t rate)
-{
-}
-
-static inline void trace_open_eth_mii_write(unsigned idx, uint16_t v)
-{
-}
-
-static inline void trace_open_eth_mii_read(unsigned idx, uint16_t v)
-{
-}
-
-static inline void trace_open_eth_update_irq(uint32_t v)
-{
-}
-
-static inline void trace_open_eth_receive(unsigned len)
-{
-}
-
-static inline void trace_open_eth_receive_mcast(unsigned idx, uint32_t h0, uint32_t h1)
-{
-}
-
-static inline void trace_open_eth_receive_reject(void)
-{
-}
-
-static inline void trace_open_eth_receive_desc(uint32_t addr, uint32_t len_flags)
-{
-}
-
-static inline void trace_open_eth_start_xmit(uint32_t addr, unsigned len, unsigned tx_len)
-{
-}
-
-static inline void trace_open_eth_reg_read(uint32_t addr, uint32_t v)
-{
-}
-
-static inline void trace_open_eth_reg_write(uint32_t addr, uint32_t v)
-{
-}
-
-static inline void trace_open_eth_desc_read(uint32_t addr, uint32_t v)
-{
-}
-
-static inline void trace_open_eth_desc_write(uint32_t addr, uint32_t v)
-{
-}
-
-static inline void trace_v9fs_rerror(uint16_t tag, uint8_t id, int err)
-{
-}
-
-static inline void trace_v9fs_version(uint16_t tag, uint8_t id, int32_t msize, char* version)
-{
-}
-
-static inline void trace_v9fs_version_return(uint16_t tag, uint8_t id, int32_t msize, char* version)
-{
-}
-
-static inline void trace_v9fs_attach(uint16_t tag, uint8_t id, int32_t fid, int32_t afid, char* uname, char* aname)
-{
-}
-
-static inline void trace_v9fs_attach_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path)
-{
-}
-
-static inline void trace_v9fs_stat(uint16_t tag, uint8_t id, int32_t fid)
-{
-}
-
-static inline void trace_v9fs_stat_return(uint16_t tag, uint8_t id, int32_t mode, int32_t atime, int32_t mtime, int64_t length)
-{
-}
-
-static inline void trace_v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask)
-{
-}
-
-static inline void trace_v9fs_getattr_return(uint16_t tag, uint8_t id, uint64_t result_mask, uint32_t mode, uint32_t uid, uint32_t gid)
-{
-}
-
-static inline void trace_v9fs_walk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, uint16_t nwnames)
-{
-}
-
-static inline void trace_v9fs_walk_return(uint16_t tag, uint8_t id, uint16_t nwnames, void* qids)
-{
-}
-
-static inline void trace_v9fs_open(uint16_t tag, uint8_t id, int32_t fid, int32_t mode)
-{
-}
-
-static inline void trace_v9fs_open_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit)
-{
-}
-
-static inline void trace_v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode, uint32_t gid)
-{
-}
-
-static inline void trace_v9fs_lcreate_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int32_t iounit)
-{
-}
-
-static inline void trace_v9fs_fsync(uint16_t tag, uint8_t id, int32_t fid, int datasync)
-{
-}
-
-static inline void trace_v9fs_clunk(uint16_t tag, uint8_t id, int32_t fid)
-{
-}
-
-static inline void trace_v9fs_read(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t max_count)
-{
-}
-
-static inline void trace_v9fs_read_return(uint16_t tag, uint8_t id, int32_t count, ssize_t err)
-{
-}
-
-static inline void trace_v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, uint64_t offset, uint32_t max_count)
-{
-}
-
-static inline void trace_v9fs_readdir_return(uint16_t tag, uint8_t id, uint32_t count, ssize_t retval)
-{
-}
-
-static inline void trace_v9fs_write(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t count, int cnt)
-{
-}
-
-static inline void trace_v9fs_write_return(uint16_t tag, uint8_t id, int32_t total, ssize_t err)
-{
-}
-
-static inline void trace_v9fs_create(uint16_t tag, uint8_t id, int32_t fid, char* name, int32_t perm, int8_t mode)
-{
-}
-
-static inline void trace_v9fs_create_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit)
-{
-}
-
-static inline void trace_v9fs_symlink(uint16_t tag, uint8_t id, int32_t fid, char* name, char* symname, uint32_t gid)
-{
-}
-
-static inline void trace_v9fs_symlink_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path)
-{
-}
-
-static inline void trace_v9fs_flush(uint16_t tag, uint8_t id, int16_t flush_tag)
-{
-}
-
-static inline void trace_v9fs_link(uint16_t tag, uint8_t id, int32_t dfid, int32_t oldfid, char* name)
-{
-}
-
-static inline void trace_v9fs_remove(uint16_t tag, uint8_t id, int32_t fid)
-{
-}
-
-static inline void trace_v9fs_wstat(uint16_t tag, uint8_t id, int32_t fid, int32_t mode, int32_t atime, int32_t mtime)
-{
-}
-
-static inline void trace_v9fs_mknod(uint16_t tag, uint8_t id, int32_t fid, int mode, int major, int minor)
-{
-}
-
-static inline void trace_v9fs_mknod_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path)
-{
-}
-
-static inline void trace_v9fs_lock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length)
-{
-}
-
-static inline void trace_v9fs_lock_return(uint16_t tag, uint8_t id, int8_t status)
-{
-}
-
-static inline void trace_v9fs_getlock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length)
-{
-}
-
-static inline void trace_v9fs_getlock_return(uint16_t tag, uint8_t id, uint8_t type, uint64_t start, uint64_t length, uint32_t proc_id)
-{
-}
-
-static inline void trace_v9fs_mkdir(uint16_t tag, uint8_t id, int32_t fid, char* name, int mode, uint32_t gid)
-{
-}
-
-static inline void trace_v9fs_mkdir_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int err)
-{
-}
-
-static inline void trace_v9fs_xattrwalk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, char* name)
-{
-}
-
-static inline void trace_v9fs_xattrwalk_return(uint16_t tag, uint8_t id, int64_t size)
-{
-}
-
-static inline void trace_v9fs_xattrcreate(uint16_t tag, uint8_t id, int32_t fid, char* name, int64_t size, int flags)
-{
-}
-
-static inline void trace_v9fs_readlink(uint16_t tag, uint8_t id, int32_t fid)
-{
-}
-
-static inline void trace_v9fs_readlink_return(uint16_t tag, uint8_t id, char* target)
-{
-}
-
-static inline void trace_mmu_helper_dfault(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl)
-{
-}
-
-static inline void trace_mmu_helper_dprot(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl)
-{
-}
-
-static inline void trace_mmu_helper_dmiss(uint64_t address, uint64_t context)
-{
-}
-
-static inline void trace_mmu_helper_tfault(uint64_t address, uint64_t context)
-{
-}
-
-static inline void trace_mmu_helper_tmiss(uint64_t address, uint64_t context)
-{
-}
-
-static inline void trace_mmu_helper_get_phys_addr_code(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address)
-{
-}
-
-static inline void trace_mmu_helper_get_phys_addr_data(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address)
-{
-}
-
-static inline void trace_mmu_helper_mmu_fault(uint64_t address, uint64_t paddr, int mmu_idx, uint32_t tl, uint64_t prim_context, uint64_t sec_context)
-{
-}
-
-static inline void trace_int_helper_set_softint(uint32_t softint)
-{
-}
-
-static inline void trace_int_helper_clear_softint(uint32_t softint)
-{
-}
-
-static inline void trace_int_helper_write_softint(uint32_t softint)
-{
-}
-
-static inline void trace_int_helper_icache_freeze(void)
-{
-}
-
-static inline void trace_int_helper_dcache_freeze(void)
-{
-}
-
-static inline void trace_win_helper_gregset_error(uint32_t pstate)
-{
-}
-
-static inline void trace_win_helper_switch_pstate(uint32_t pstate_regs, uint32_t new_pstate_regs)
-{
-}
-
-static inline void trace_win_helper_no_switch_pstate(uint32_t new_pstate_regs)
-{
-}
-
-static inline void trace_win_helper_wrpil(uint32_t psrpil, uint32_t new_pil)
-{
-}
-
-static inline void trace_win_helper_done(uint32_t tl)
-{
-}
-
-static inline void trace_win_helper_retry(uint32_t tl)
-{
-}
-
-static inline void trace_dma_bdrv_io(void * dbs, void * bs, int64_t sector_num, bool to_dev)
-{
-}
-
-static inline void trace_dma_aio_cancel(void * dbs)
-{
-}
-
-static inline void trace_dma_complete(void * dbs, int ret, void * cb)
-{
-}
-
-static inline void trace_dma_bdrv_cb(void * dbs, int ret)
-{
-}
-
-static inline void trace_dma_map_wait(void * dbs)
-{
-}
-
-static inline void trace_console_gfx_new(void)
-{
-}
-
-static inline void trace_console_txt_new(int w, int h)
-{
-}
-
-static inline void trace_console_select(int nr)
-{
-}
-
-static inline void trace_console_refresh(int interval)
-{
-}
-
-static inline void trace_displaysurface_create(void * display_surface, int w, int h)
-{
-}
-
-static inline void trace_displaysurface_create_from(void * display_surface, int w, int h, int bpp, int swap)
-{
-}
-
-static inline void trace_displaysurface_free(void * display_surface)
-{
-}
-
-static inline void trace_displaychangelistener_register(void * dcl, const char * name)
-{
-}
-
-static inline void trace_displaychangelistener_unregister(void * dcl, const char * name)
-{
-}
-
-static inline void trace_ppm_save(const char * filename, void * display_surface)
-{
-}
-
-static inline void trace_vmware_value_read(uint32_t index, uint32_t value)
-{
-}
-
-static inline void trace_vmware_value_write(uint32_t index, uint32_t value)
-{
-}
-
-static inline void trace_vmware_palette_read(uint32_t index, uint32_t value)
-{
-}
-
-static inline void trace_vmware_palette_write(uint32_t index, uint32_t value)
-{
-}
-
-static inline void trace_vmware_scratch_read(uint32_t index, uint32_t value)
-{
-}
-
-static inline void trace_vmware_scratch_write(uint32_t index, uint32_t value)
-{
-}
-
-static inline void trace_vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp)
-{
-}
-
-static inline void trace_savevm_section_start(void)
-{
-}
-
-static inline void trace_savevm_section_end(unsigned int section_id)
-{
-}
-
-static inline void trace_migration_bitmap_sync_start(void)
-{
-}
-
-static inline void trace_migration_bitmap_sync_end(uint64_t dirty_pages)
-{
-}
-
-static inline void trace_migration_throttle(void)
-{
-}
-
-static inline void trace_qxl_create_guest_primary(int qid, uint32_t width, uint32_t height, uint64_t mem, uint32_t format, uint32_t position)
-{
-}
-
-static inline void trace_qxl_create_guest_primary_rest(int qid, int32_t stride, uint32_t type, uint32_t flags)
-{
-}
-
-static inline void trace_qxl_destroy_primary(int qid)
-{
-}
-
-static inline void trace_qxl_enter_vga_mode(int qid)
-{
-}
-
-static inline void trace_qxl_exit_vga_mode(int qid)
-{
-}
-
-static inline void trace_qxl_hard_reset(int qid, int64_t loadvm)
-{
-}
-
-static inline void trace_qxl_interface_async_complete_io(int qid, uint32_t current_async, void * cookie)
-{
-}
-
-static inline void trace_qxl_interface_attach_worker(int qid)
-{
-}
-
-static inline void trace_qxl_interface_get_init_info(int qid)
-{
-}
-
-static inline void trace_qxl_interface_set_compression_level(int qid, int64_t level)
-{
-}
-
-static inline void trace_qxl_interface_update_area_complete(int qid, uint32_t surface_id, uint32_t dirty_left, uint32_t dirty_right, uint32_t dirty_top, uint32_t dirty_bottom)
-{
-}
-
-static inline void trace_qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects)
-{
-}
-
-static inline void trace_qxl_interface_update_area_complete_overflow(int qid, int max)
-{
-}
-
-static inline void trace_qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty)
-{
-}
-
-static inline void trace_qxl_io_destroy_primary_ignored(int qid, const char * mode)
-{
-}
-
-static inline void trace_qxl_io_log(int qid, const uint8_t * log_buf)
-{
-}
-
-static inline void trace_qxl_io_read_unexpected(int qid)
-{
-}
-
-static inline void trace_qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char * desc)
-{
-}
-
-static inline void trace_qxl_io_write(int qid, const char * mode, uint64_t addr, uint64_t val, unsigned size, int async)
-{
-}
-
-static inline void trace_qxl_memslot_add_guest(int qid, uint32_t slot_id, uint64_t guest_start, uint64_t guest_end)
-{
-}
-
-static inline void trace_qxl_post_load(int qid, const char * mode)
-{
-}
-
-static inline void trace_qxl_pre_load(int qid)
-{
-}
-
-static inline void trace_qxl_pre_save(int qid)
-{
-}
-
-static inline void trace_qxl_reset_surfaces(int qid)
-{
-}
-
-static inline void trace_qxl_ring_command_check(int qid, const char * mode)
-{
-}
-
-static inline void trace_qxl_ring_command_get(int qid, const char * mode)
-{
-}
-
-static inline void trace_qxl_ring_command_req_notification(int qid)
-{
-}
-
-static inline void trace_qxl_ring_cursor_check(int qid, const char * mode)
-{
-}
-
-static inline void trace_qxl_ring_cursor_get(int qid, const char * mode)
-{
-}
-
-static inline void trace_qxl_ring_cursor_req_notification(int qid)
-{
-}
-
-static inline void trace_qxl_ring_res_push(int qid, const char * mode, uint32_t surface_count, uint32_t free_res, void * last_release, const char * notify)
-{
-}
-
-static inline void trace_qxl_ring_res_push_rest(int qid, uint32_t ring_has, uint32_t ring_size, uint32_t prod, uint32_t cons)
-{
-}
-
-static inline void trace_qxl_ring_res_put(int qid, uint32_t free_res)
-{
-}
-
-static inline void trace_qxl_set_mode(int qid, int modenr, uint32_t x_res, uint32_t y_res, uint32_t bits, uint64_t devmem)
-{
-}
-
-static inline void trace_qxl_soft_reset(int qid)
-{
-}
-
-static inline void trace_qemu_spice_add_memslot(int qid, uint32_t slot_id, unsigned long virt_start, unsigned long virt_end, int async)
-{
-}
-
-static inline void trace_qemu_spice_del_memslot(int qid, uint32_t gid, uint32_t slot_id)
-{
-}
-
-static inline void trace_qemu_spice_create_primary_surface(int qid, uint32_t sid, void * surface, int async)
-{
-}
-
-static inline void trace_qemu_spice_destroy_primary_surface(int qid, uint32_t sid, int async)
-{
-}
-
-static inline void trace_qemu_spice_wakeup(uint32_t qid)
-{
-}
-
-static inline void trace_qemu_spice_start(uint32_t qid)
-{
-}
-
-static inline void trace_qemu_spice_stop(uint32_t qid)
-{
-}
-
-static inline void trace_qemu_spice_create_update(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom)
-{
-}
-
-static inline void trace_qxl_spice_destroy_surfaces_complete(int qid)
-{
-}
-
-static inline void trace_qxl_spice_destroy_surfaces(int qid, int async)
-{
-}
-
-static inline void trace_qxl_spice_destroy_surface_wait_complete(int qid, uint32_t id)
-{
-}
-
-static inline void trace_qxl_spice_destroy_surface_wait(int qid, uint32_t id, int async)
-{
-}
-
-static inline void trace_qxl_spice_flush_surfaces_async(int qid, uint32_t surface_count, uint32_t num_free_res)
-{
-}
-
-static inline void trace_qxl_spice_monitors_config(int qid)
-{
-}
-
-static inline void trace_qxl_spice_loadvm_commands(int qid, void * ext, uint32_t count)
-{
-}
-
-static inline void trace_qxl_spice_oom(int qid)
-{
-}
-
-static inline void trace_qxl_spice_reset_cursor(int qid)
-{
-}
-
-static inline void trace_qxl_spice_reset_image_cache(int qid)
-{
-}
-
-static inline void trace_qxl_spice_reset_memslots(int qid)
-{
-}
-
-static inline void trace_qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom)
-{
-}
-
-static inline void trace_qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region)
-{
-}
-
-static inline void trace_qxl_surfaces_dirty(int qid, int surface, int offset, int size)
-{
-}
-
-static inline void trace_qxl_send_events(int qid, uint32_t events)
-{
-}
-
-static inline void trace_qxl_send_events_vm_stopped(int qid, uint32_t events)
-{
-}
-
-static inline void trace_qxl_set_guest_bug(int qid)
-{
-}
-
-static inline void trace_qxl_interrupt_client_monitors_config(int qid, int num_heads, void * heads)
-{
-}
-
-static inline void trace_qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void * client_monitors_config)
-{
-}
-
-static inline void trace_qxl_client_monitors_config_unsupported_by_device(int qid, int revision)
-{
-}
-
-static inline void trace_qxl_client_monitors_config_capped(int qid, int requested, int limit)
-{
-}
-
-static inline void trace_qxl_client_monitors_config_crc(int qid, unsigned size, uint32_t crc32)
-{
-}
-
-static inline void trace_qxl_set_client_capabilities_unsupported_by_revision(int qid, int revision)
-{
-}
-
-static inline void trace_qxl_render_blit_guest_primary_initialized(void)
-{
-}
-
-static inline void trace_qxl_render_blit(int32_t stride, int32_t left, int32_t right, int32_t top, int32_t bottom)
-{
-}
-
-static inline void trace_qxl_render_guest_primary_resized(int32_t width, int32_t height, int32_t stride, int32_t bytes_pp, int32_t bits_pp)
-{
-}
-
-static inline void trace_qxl_render_update_area_done(void * cookie)
-{
-}
-
-static inline void trace_spapr_pci_msi(const char * msg, uint32_t n, uint32_t ca)
-{
-}
-
-static inline void trace_spapr_pci_msi_setup(const char * name, unsigned vector, uint64_t addr)
-{
-}
-
-static inline void trace_spapr_pci_rtas_ibm_change_msi(unsigned func, unsigned req)
-{
-}
-
-static inline void trace_spapr_pci_rtas_ibm_query_interrupt_source_number(unsigned ioa, unsigned intr)
-{
-}
-
-static inline void trace_spapr_pci_msi_write(uint64_t addr, uint64_t data, uint32_t dt_irq)
-{
-}
-
-static inline void trace_spapr_pci_lsi_set(const char * busname, int pin, uint32_t irq)
-{
-}
-
-static inline void trace_xics_icp_check_ipi(int server, uint8_t mfrr)
-{
-}
-
-static inline void trace_xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr)
-{
-}
-
-static inline void trace_xics_icp_eoi(int server, uint32_t xirr, uint32_t new_xirr)
-{
-}
-
-static inline void trace_xics_icp_irq(int server, int nr, uint8_t priority)
-{
-}
-
-static inline void trace_xics_icp_raise(uint32_t xirr, uint8_t pending_priority)
-{
-}
-
-static inline void trace_xics_set_irq_msi(int srcno, int nr)
-{
-}
-
-static inline void trace_xics_masked_pending(void)
-{
-}
-
-static inline void trace_xics_set_irq_lsi(int srcno, int nr)
-{
-}
-
-static inline void trace_xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority)
-{
-}
-
-static inline void trace_xics_ics_reject(int nr, int srcno)
-{
-}
-
-static inline void trace_xics_ics_eoi(int nr)
-{
-}
-
-static inline void trace_hbitmap_iter_skip_words(const void * hb, void * hbi, uint64_t pos, unsigned long cur)
-{
-}
-
-static inline void trace_hbitmap_reset(void * hb, uint64_t start, uint64_t count, uint64_t sbit, uint64_t ebit)
-{
-}
-
-static inline void trace_hbitmap_set(void * hb, uint64_t start, uint64_t count, uint64_t sbit, uint64_t ebit)
-{
-}
-
-static inline void trace_ioinst(const char * insn)
-{
-}
-
-static inline void trace_ioinst_sch_id(const char * insn, int cssid, int ssid, int schid)
-{
-}
-
-static inline void trace_ioinst_chp_id(const char * insn, int cssid, int chpid)
-{
-}
-
-static inline void trace_ioinst_chsc_cmd(uint16_t cmd, uint16_t len)
-{
-}
-
-static inline void trace_css_enable_facility(const char * facility)
-{
-}
-
-static inline void trace_css_crw(uint8_t rsc, uint8_t erc, uint16_t rsid, const char * chained)
-{
-}
-
-static inline void trace_css_chpid_add(uint8_t cssid, uint8_t chpid, uint8_t type)
-{
-}
-
-static inline void trace_css_new_image(uint8_t cssid, const char * default_cssid)
-{
-}
-
-static inline void trace_css_assign_subch(const char * do_assign, uint8_t cssid, uint8_t ssid, uint16_t schid, uint16_t devno)
-{
-}
-
-static inline void trace_css_io_interrupt(int cssid, int ssid, int schid, uint32_t intparm, uint8_t isc, const char * conditional)
-{
-}
-
-static inline void trace_virtio_ccw_interpret_ccw(int cssid, int ssid, int schid, int cmd_code)
-{
-}
-
-static inline void trace_virtio_ccw_new_device(int cssid, int ssid, int schid, int devno, const char * devno_mode)
-{
-}
-
-static inline void trace_migrate_set_state(int new_state)
-{
-}
-
-static inline void trace_kvm_ioctl(int type, void * arg)
-{
-}
-
-static inline void trace_kvm_vm_ioctl(int type, void * arg)
-{
-}
-
-static inline void trace_kvm_vcpu_ioctl(int cpu_index, int type, void * arg)
-{
-}
-
-static inline void trace_kvm_run_exit(int cpu_index, uint32_t reason)
-{
-}
-
-static inline void trace_object_dynamic_cast_assert(const char * type, const char * target, const char * file, int line, const char * func)
-{
-}
-
-static inline void trace_object_class_dynamic_cast_assert(const char * type, const char * target, const char * file, int line, const char * func)
-{
-}
-#endif /* TRACE__GENERATED_TRACERS_H */
diff --git a/contrib/qemu/util/aes.c b/contrib/qemu/util/aes.c
deleted file mode 100644
index 91e97fa6e7f..00000000000
--- a/contrib/qemu/util/aes.c
+++ /dev/null
@@ -1,1314 +0,0 @@
-/**
- *
- * aes.c - integrated in QEMU by Fabrice Bellard from the OpenSSL project.
- */
-/*
- * rijndael-alg-fst.c
- *
- * @version 3.0 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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 "qemu-common.h"
-#include "qemu/aes.h"
-
-#ifndef NDEBUG
-#define NDEBUG
-#endif
-
-typedef uint32_t u32;
-typedef uint16_t u16;
-typedef uint8_t u8;
-
-/* This controls loop-unrolling in aes_core.c */
-#undef FULL_UNROLL
-# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
-# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
-
-/*
-AES_Te0[x] = S [x].[02, 01, 01, 03];
-AES_Te1[x] = S [x].[03, 02, 01, 01];
-AES_Te2[x] = S [x].[01, 03, 02, 01];
-AES_Te3[x] = S [x].[01, 01, 03, 02];
-AES_Te4[x] = S [x].[01, 01, 01, 01];
-
-AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
-AES_Td1[x] = Si[x].[0b, 0e, 09, 0d];
-AES_Td2[x] = Si[x].[0d, 0b, 0e, 09];
-AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
-AES_Td4[x] = Si[x].[01, 01, 01, 01];
-*/
-
-const uint32_t AES_Te0[256] = {
- 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
- 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
- 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
- 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
- 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
- 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
- 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
- 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
- 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
- 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
- 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
- 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
- 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
- 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
- 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
- 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
- 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
- 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
- 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
- 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
- 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
- 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
- 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
- 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
- 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
- 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
- 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
- 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
- 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
- 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
- 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
- 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
- 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
- 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
- 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
- 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
- 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
- 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
- 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
- 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
- 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
- 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
- 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
- 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
- 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
- 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
- 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
- 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
- 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
- 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
- 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
- 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
- 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
- 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
- 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
- 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
- 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
- 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
- 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
- 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
- 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
- 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
- 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
- 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-};
-const uint32_t AES_Te1[256] = {
- 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
- 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
- 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
- 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
- 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
- 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
- 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
- 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
- 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
- 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
- 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
- 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
- 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
- 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
- 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
- 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
- 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
- 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
- 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
- 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
- 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
- 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
- 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
- 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
- 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
- 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
- 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
- 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
- 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
- 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
- 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
- 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
- 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
- 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
- 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
- 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
- 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
- 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
- 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
- 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
- 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
- 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
- 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
- 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
- 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
- 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
- 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
- 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
- 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
- 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
- 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
- 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
- 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
- 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
- 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
- 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
- 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
- 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
- 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
- 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
- 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
- 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
- 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
- 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-};
-const uint32_t AES_Te2[256] = {
- 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
- 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
- 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
- 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
- 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
- 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
- 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
- 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
- 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
- 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
- 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
- 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
- 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
- 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
- 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
- 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
- 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
- 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
- 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
- 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
- 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
- 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
- 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
- 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
- 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
- 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
- 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
- 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
- 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
- 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
- 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
- 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
- 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
- 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
- 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
- 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
- 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
- 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
- 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
- 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
- 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
- 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
- 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
- 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
- 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
- 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
- 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
- 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
- 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
- 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
- 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
- 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
- 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
- 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
- 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
- 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
- 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
- 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
- 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
- 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
- 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
- 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
- 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
- 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-};
-const uint32_t AES_Te3[256] = {
-
- 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
- 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
- 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
- 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
- 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
- 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
- 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
- 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
- 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
- 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
- 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
- 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
- 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
- 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
- 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
- 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
- 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
- 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
- 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
- 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
- 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
- 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
- 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
- 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
- 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
- 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
- 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
- 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
- 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
- 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
- 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
- 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
- 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
- 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
- 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
- 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
- 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
- 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
- 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
- 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
- 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
- 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
- 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
- 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
- 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
- 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
- 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
- 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
- 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
- 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
- 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
- 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
- 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
- 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
- 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
- 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
- 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
- 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
- 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
- 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
- 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
- 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
- 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
- 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-};
-const uint32_t AES_Te4[256] = {
- 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
- 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
- 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
- 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
- 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
- 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
- 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
- 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
- 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
- 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
- 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
- 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
- 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
- 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
- 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
- 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
- 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
- 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
- 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
- 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
- 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
- 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
- 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
- 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
- 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
- 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
- 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
- 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
- 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
- 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
- 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
- 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
- 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
- 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
- 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
- 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
- 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
- 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
- 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
- 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
- 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
- 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
- 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
- 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
- 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
- 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
- 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
- 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
- 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
- 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
- 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
- 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
- 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
- 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
- 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
- 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
- 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
- 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
- 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
- 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
- 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
- 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
- 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
- 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
-};
-const uint32_t AES_Td0[256] = {
- 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
- 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
- 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
- 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
- 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
- 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
- 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
- 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
- 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
- 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
- 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
- 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
- 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
- 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
- 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
- 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
- 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
- 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
- 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
- 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
- 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
- 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
- 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
- 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
- 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
- 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
- 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
- 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
- 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
- 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
- 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
- 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
- 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
- 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
- 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
- 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
- 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
- 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
- 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
- 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
- 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
- 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
- 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
- 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
- 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
- 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
- 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
- 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
- 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
- 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
- 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
- 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
- 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
- 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
- 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
- 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
- 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
- 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
- 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
- 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
- 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
- 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
- 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
- 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-};
-const uint32_t AES_Td1[256] = {
- 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
- 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
- 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
- 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
- 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
- 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
- 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
- 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
- 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
- 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
- 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
- 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
- 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
- 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
- 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
- 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
- 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
- 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
- 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
- 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
- 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
- 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
- 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
- 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
- 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
- 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
- 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
- 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
- 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
- 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
- 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
- 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
- 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
- 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
- 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
- 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
- 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
- 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
- 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
- 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
- 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
- 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
- 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
- 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
- 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
- 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
- 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
- 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
- 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
- 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
- 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
- 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
- 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
- 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
- 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
- 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
- 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
- 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
- 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
- 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
- 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
- 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
- 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
- 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-};
-const uint32_t AES_Td2[256] = {
- 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
- 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
- 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
- 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
- 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
- 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
- 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
- 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
- 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
- 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
- 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
- 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
- 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
- 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
- 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
- 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
- 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
- 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
- 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
- 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-
- 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
- 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
- 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
- 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
- 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
- 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
- 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
- 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
- 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
- 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
- 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
- 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
- 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
- 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
- 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
- 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
- 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
- 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
- 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
- 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
- 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
- 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
- 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
- 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
- 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
- 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
- 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
- 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
- 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
- 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
- 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
- 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
- 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
- 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
- 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
- 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
- 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
- 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
- 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
- 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
- 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
- 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
- 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
- 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-};
-const uint32_t AES_Td3[256] = {
- 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
- 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
- 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
- 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
- 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
- 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
- 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
- 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
- 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
- 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
- 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
- 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
- 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
- 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
- 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
- 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
- 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
- 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
- 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
- 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
- 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
- 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
- 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
- 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
- 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
- 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
- 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
- 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
- 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
- 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
- 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
- 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
- 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
- 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
- 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
- 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
- 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
- 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
- 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
- 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
- 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
- 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
- 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
- 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
- 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
- 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
- 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
- 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
- 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
- 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
- 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
- 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
- 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
- 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
- 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
- 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
- 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
- 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
- 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
- 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
- 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
- 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
- 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
- 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-};
-const uint32_t AES_Td4[256] = {
- 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
- 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
- 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
- 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
- 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
- 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
- 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
- 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
- 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
- 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
- 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
- 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
- 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
- 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
- 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
- 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
- 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
- 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
- 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
- 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
- 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
- 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
- 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
- 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
- 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
- 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
- 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
- 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
- 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
- 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
- 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
- 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
- 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
- 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
- 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
- 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
- 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
- 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
- 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
- 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
- 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
- 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
- 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
- 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
- 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
- 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
- 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
- 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
- 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
- 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
- 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
- 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
- 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
- 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
- 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
- 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
- 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
- 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
- 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
- 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
- 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
- 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
- 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
- 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
-};
-static const u32 rcon[] = {
- 0x01000000, 0x02000000, 0x04000000, 0x08000000,
- 0x10000000, 0x20000000, 0x40000000, 0x80000000,
- 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-
-/**
- * Expand the cipher key into the encryption key schedule.
- */
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i = 0;
- u32 temp;
-
- if (!userKey || !key)
- return -1;
- if (bits != 128 && bits != 192 && bits != 256)
- return -2;
-
- rk = key->rd_key;
-
- if (bits==128)
- key->rounds = 10;
- else if (bits==192)
- key->rounds = 12;
- else
- key->rounds = 14;
-
- rk[0] = GETU32(userKey );
- rk[1] = GETU32(userKey + 4);
- rk[2] = GETU32(userKey + 8);
- rk[3] = GETU32(userKey + 12);
- if (bits == 128) {
- while (1) {
- temp = rk[3];
- rk[4] = rk[0] ^
- (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (AES_Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (AES_Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (AES_Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[5] = rk[1] ^ rk[4];
- rk[6] = rk[2] ^ rk[5];
- rk[7] = rk[3] ^ rk[6];
- if (++i == 10) {
- return 0;
- }
- rk += 4;
- }
- }
- rk[4] = GETU32(userKey + 16);
- rk[5] = GETU32(userKey + 20);
- if (bits == 192) {
- while (1) {
- temp = rk[ 5];
- rk[ 6] = rk[ 0] ^
- (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (AES_Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (AES_Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (AES_Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 7] = rk[ 1] ^ rk[ 6];
- rk[ 8] = rk[ 2] ^ rk[ 7];
- rk[ 9] = rk[ 3] ^ rk[ 8];
- if (++i == 8) {
- return 0;
- }
- rk[10] = rk[ 4] ^ rk[ 9];
- rk[11] = rk[ 5] ^ rk[10];
- rk += 6;
- }
- }
- rk[6] = GETU32(userKey + 24);
- rk[7] = GETU32(userKey + 28);
- if (bits == 256) {
- while (1) {
- temp = rk[ 7];
- rk[ 8] = rk[ 0] ^
- (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (AES_Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (AES_Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (AES_Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 9] = rk[ 1] ^ rk[ 8];
- rk[10] = rk[ 2] ^ rk[ 9];
- rk[11] = rk[ 3] ^ rk[10];
- if (++i == 7) {
- return 0;
- }
- temp = rk[11];
- rk[12] = rk[ 4] ^
- (AES_Te4[(temp >> 24) ] & 0xff000000) ^
- (AES_Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
- (AES_Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
- (AES_Te4[(temp ) & 0xff] & 0x000000ff);
- rk[13] = rk[ 5] ^ rk[12];
- rk[14] = rk[ 6] ^ rk[13];
- rk[15] = rk[ 7] ^ rk[14];
-
- rk += 8;
- }
- }
- return 0;
-}
-
-/**
- * Expand the cipher key into the decryption key schedule.
- */
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i, j, status;
- u32 temp;
-
- /* first, start with an encryption schedule */
- status = AES_set_encrypt_key(userKey, bits, key);
- if (status < 0)
- return status;
-
- rk = key->rd_key;
-
- /* invert the order of the round keys: */
- for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
- temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
- temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
- temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
- temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
- }
- /* apply the inverse MixColumn transform to all round keys but the first and the last: */
- for (i = 1; i < (key->rounds); i++) {
- rk += 4;
- rk[0] =
- AES_Td0[AES_Te4[(rk[0] >> 24) ] & 0xff] ^
- AES_Td1[AES_Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
- AES_Td2[AES_Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
- AES_Td3[AES_Te4[(rk[0] ) & 0xff] & 0xff];
- rk[1] =
- AES_Td0[AES_Te4[(rk[1] >> 24) ] & 0xff] ^
- AES_Td1[AES_Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
- AES_Td2[AES_Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
- AES_Td3[AES_Te4[(rk[1] ) & 0xff] & 0xff];
- rk[2] =
- AES_Td0[AES_Te4[(rk[2] >> 24) ] & 0xff] ^
- AES_Td1[AES_Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
- AES_Td2[AES_Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
- AES_Td3[AES_Te4[(rk[2] ) & 0xff] & 0xff];
- rk[3] =
- AES_Td0[AES_Te4[(rk[3] >> 24) ] & 0xff] ^
- AES_Td1[AES_Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
- AES_Td2[AES_Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
- AES_Td3[AES_Te4[(rk[3] ) & 0xff] & 0xff];
- }
- return 0;
-}
-
-#ifndef AES_ASM
-/*
- * Encrypt a single block
- * in and out can overlap
- */
-void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[ 4];
- t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[ 5];
- t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[ 6];
- t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[ 8];
- s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[ 9];
- s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[10];
- s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[12];
- t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[13];
- t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[14];
- t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[16];
- s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[17];
- s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[18];
- s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[20];
- t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[21];
- t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[22];
- t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[24];
- s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[25];
- s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[26];
- s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[28];
- t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[29];
- t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[30];
- t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[32];
- s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[33];
- s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[34];
- s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[36];
- t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[37];
- t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[38];
- t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[39];
- if (key->rounds > 10) {
- /* round 10: */
- s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[40];
- s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[41];
- s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[42];
- s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[44];
- t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[45];
- t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[46];
- t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[47];
- if (key->rounds > 12) {
- /* round 12: */
- s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[48];
- s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[49];
- s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[50];
- s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[52];
- t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[53];
- t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[54];
- t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[55];
- }
- }
- rk += key->rounds << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = key->rounds >> 1;
- for (;;) {
- t0 =
- AES_Te0[(s0 >> 24) ] ^
- AES_Te1[(s1 >> 16) & 0xff] ^
- AES_Te2[(s2 >> 8) & 0xff] ^
- AES_Te3[(s3 ) & 0xff] ^
- rk[4];
- t1 =
- AES_Te0[(s1 >> 24) ] ^
- AES_Te1[(s2 >> 16) & 0xff] ^
- AES_Te2[(s3 >> 8) & 0xff] ^
- AES_Te3[(s0 ) & 0xff] ^
- rk[5];
- t2 =
- AES_Te0[(s2 >> 24) ] ^
- AES_Te1[(s3 >> 16) & 0xff] ^
- AES_Te2[(s0 >> 8) & 0xff] ^
- AES_Te3[(s1 ) & 0xff] ^
- rk[6];
- t3 =
- AES_Te0[(s3 >> 24) ] ^
- AES_Te1[(s0 >> 16) & 0xff] ^
- AES_Te2[(s1 >> 8) & 0xff] ^
- AES_Te3[(s2 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- AES_Te0[(t0 >> 24) ] ^
- AES_Te1[(t1 >> 16) & 0xff] ^
- AES_Te2[(t2 >> 8) & 0xff] ^
- AES_Te3[(t3 ) & 0xff] ^
- rk[0];
- s1 =
- AES_Te0[(t1 >> 24) ] ^
- AES_Te1[(t2 >> 16) & 0xff] ^
- AES_Te2[(t3 >> 8) & 0xff] ^
- AES_Te3[(t0 ) & 0xff] ^
- rk[1];
- s2 =
- AES_Te0[(t2 >> 24) ] ^
- AES_Te1[(t3 >> 16) & 0xff] ^
- AES_Te2[(t0 >> 8) & 0xff] ^
- AES_Te3[(t1 ) & 0xff] ^
- rk[2];
- s3 =
- AES_Te0[(t3 >> 24) ] ^
- AES_Te1[(t0 >> 16) & 0xff] ^
- AES_Te2[(t1 >> 8) & 0xff] ^
- AES_Te3[(t2 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (AES_Te4[(t0 >> 24) ] & 0xff000000) ^
- (AES_Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (AES_Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (AES_Te4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(out , s0);
- s1 =
- (AES_Te4[(t1 >> 24) ] & 0xff000000) ^
- (AES_Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (AES_Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (AES_Te4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(out + 4, s1);
- s2 =
- (AES_Te4[(t2 >> 24) ] & 0xff000000) ^
- (AES_Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (AES_Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (AES_Te4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(out + 8, s2);
- s3 =
- (AES_Te4[(t3 >> 24) ] & 0xff000000) ^
- (AES_Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (AES_Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (AES_Te4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(out + 12, s3);
-}
-
-/*
- * Decrypt a single block
- * in and out can overlap
- */
-void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[ 4];
- t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[ 5];
- t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[ 6];
- t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[ 8];
- s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[ 9];
- s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[10];
- s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[12];
- t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[13];
- t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[14];
- t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[16];
- s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[17];
- s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[18];
- s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[20];
- t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[21];
- t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[22];
- t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[24];
- s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[25];
- s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[26];
- s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[28];
- t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[29];
- t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[30];
- t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[32];
- s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[33];
- s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[34];
- s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[36];
- t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[37];
- t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[38];
- t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[39];
- if (key->rounds > 10) {
- /* round 10: */
- s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[40];
- s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[41];
- s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[42];
- s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[44];
- t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[45];
- t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[46];
- t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[47];
- if (key->rounds > 12) {
- /* round 12: */
- s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[48];
- s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[49];
- s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[50];
- s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[52];
- t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[53];
- t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[54];
- t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[55];
- }
- }
- rk += key->rounds << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = key->rounds >> 1;
- for (;;) {
- t0 =
- AES_Td0[(s0 >> 24) ] ^
- AES_Td1[(s3 >> 16) & 0xff] ^
- AES_Td2[(s2 >> 8) & 0xff] ^
- AES_Td3[(s1 ) & 0xff] ^
- rk[4];
- t1 =
- AES_Td0[(s1 >> 24) ] ^
- AES_Td1[(s0 >> 16) & 0xff] ^
- AES_Td2[(s3 >> 8) & 0xff] ^
- AES_Td3[(s2 ) & 0xff] ^
- rk[5];
- t2 =
- AES_Td0[(s2 >> 24) ] ^
- AES_Td1[(s1 >> 16) & 0xff] ^
- AES_Td2[(s0 >> 8) & 0xff] ^
- AES_Td3[(s3 ) & 0xff] ^
- rk[6];
- t3 =
- AES_Td0[(s3 >> 24) ] ^
- AES_Td1[(s2 >> 16) & 0xff] ^
- AES_Td2[(s1 >> 8) & 0xff] ^
- AES_Td3[(s0 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- AES_Td0[(t0 >> 24) ] ^
- AES_Td1[(t3 >> 16) & 0xff] ^
- AES_Td2[(t2 >> 8) & 0xff] ^
- AES_Td3[(t1 ) & 0xff] ^
- rk[0];
- s1 =
- AES_Td0[(t1 >> 24) ] ^
- AES_Td1[(t0 >> 16) & 0xff] ^
- AES_Td2[(t3 >> 8) & 0xff] ^
- AES_Td3[(t2 ) & 0xff] ^
- rk[1];
- s2 =
- AES_Td0[(t2 >> 24) ] ^
- AES_Td1[(t1 >> 16) & 0xff] ^
- AES_Td2[(t0 >> 8) & 0xff] ^
- AES_Td3[(t3 ) & 0xff] ^
- rk[2];
- s3 =
- AES_Td0[(t3 >> 24) ] ^
- AES_Td1[(t2 >> 16) & 0xff] ^
- AES_Td2[(t1 >> 8) & 0xff] ^
- AES_Td3[(t0 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (AES_Td4[(t0 >> 24) ] & 0xff000000) ^
- (AES_Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (AES_Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (AES_Td4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(out , s0);
- s1 =
- (AES_Td4[(t1 >> 24) ] & 0xff000000) ^
- (AES_Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (AES_Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (AES_Td4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(out + 4, s1);
- s2 =
- (AES_Td4[(t2 >> 24) ] & 0xff000000) ^
- (AES_Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (AES_Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (AES_Td4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(out + 8, s2);
- s3 =
- (AES_Td4[(t3 >> 24) ] & 0xff000000) ^
- (AES_Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (AES_Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (AES_Td4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(out + 12, s3);
-}
-
-#endif /* AES_ASM */
-
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc)
-{
-
- unsigned long n;
- unsigned long len = length;
- unsigned char tmp[AES_BLOCK_SIZE];
-
- assert(in && out && key && ivec);
-
- if (enc) {
- while (len >= AES_BLOCK_SIZE) {
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = in[n] ^ ivec[n];
- AES_encrypt(tmp, out, key);
- memcpy(ivec, out, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- for(n=0; n < len; ++n)
- tmp[n] = in[n] ^ ivec[n];
- for(n=len; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = ivec[n];
- AES_encrypt(tmp, tmp, key);
- memcpy(out, tmp, AES_BLOCK_SIZE);
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- } else {
- while (len >= AES_BLOCK_SIZE) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(in, out, key);
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- out[n] ^= ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(tmp, tmp, key);
- for(n=0; n < len; ++n)
- out[n] = tmp[n] ^ ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- }
-}
diff --git a/contrib/qemu/util/bitmap.c b/contrib/qemu/util/bitmap.c
deleted file mode 100644
index 687841dcec0..00000000000
--- a/contrib/qemu/util/bitmap.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Bitmap Module
- *
- * Stolen from linux/src/lib/bitmap.c
- *
- * Copyright (C) 2010 Corentin Chary
- *
- * This source code is licensed under the GNU General Public License,
- * Version 2.
- */
-
-#include "qemu/bitops.h"
-#include "qemu/bitmap.h"
-
-/*
- * bitmaps provide an array of bits, implemented using an an
- * array of unsigned longs. The number of valid bits in a
- * given bitmap does _not_ need to be an exact multiple of
- * BITS_PER_LONG.
- *
- * The possible unused bits in the last, partially used word
- * of a bitmap are 'don't care'. The implementation makes
- * no particular effort to keep them zero. It ensures that
- * their value will not affect the results of any operation.
- * The bitmap operations that return Boolean (bitmap_empty,
- * for example) or scalar (bitmap_weight, for example) results
- * carefully filter out these unused bits from impacting their
- * results.
- *
- * These operations actually hold to a slightly stronger rule:
- * if you don't input any bitmaps to these ops that have some
- * unused bits set, then they won't output any set unused bits
- * in output bitmaps.
- *
- * The byte ordering of bitmaps is more natural on little
- * endian architectures.
- */
-
-int slow_bitmap_empty(const unsigned long *bitmap, int bits)
-{
- int k, lim = bits/BITS_PER_LONG;
-
- for (k = 0; k < lim; ++k) {
- if (bitmap[k]) {
- return 0;
- }
- }
- if (bits % BITS_PER_LONG) {
- if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) {
- return 0;
- }
- }
-
- return 1;
-}
-
-int slow_bitmap_full(const unsigned long *bitmap, int bits)
-{
- int k, lim = bits/BITS_PER_LONG;
-
- for (k = 0; k < lim; ++k) {
- if (~bitmap[k]) {
- return 0;
- }
- }
-
- if (bits % BITS_PER_LONG) {
- if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) {
- return 0;
- }
- }
-
- return 1;
-}
-
-int slow_bitmap_equal(const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits)
-{
- int k, lim = bits/BITS_PER_LONG;
-
- for (k = 0; k < lim; ++k) {
- if (bitmap1[k] != bitmap2[k]) {
- return 0;
- }
- }
-
- if (bits % BITS_PER_LONG) {
- if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) {
- return 0;
- }
- }
-
- return 1;
-}
-
-void slow_bitmap_complement(unsigned long *dst, const unsigned long *src,
- int bits)
-{
- int k, lim = bits/BITS_PER_LONG;
-
- for (k = 0; k < lim; ++k) {
- dst[k] = ~src[k];
- }
-
- if (bits % BITS_PER_LONG) {
- dst[k] = ~src[k] & BITMAP_LAST_WORD_MASK(bits);
- }
-}
-
-int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits)
-{
- int k;
- int nr = BITS_TO_LONGS(bits);
- unsigned long result = 0;
-
- for (k = 0; k < nr; k++) {
- result |= (dst[k] = bitmap1[k] & bitmap2[k]);
- }
- return result != 0;
-}
-
-void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits)
-{
- int k;
- int nr = BITS_TO_LONGS(bits);
-
- for (k = 0; k < nr; k++) {
- dst[k] = bitmap1[k] | bitmap2[k];
- }
-}
-
-void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits)
-{
- int k;
- int nr = BITS_TO_LONGS(bits);
-
- for (k = 0; k < nr; k++) {
- dst[k] = bitmap1[k] ^ bitmap2[k];
- }
-}
-
-int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits)
-{
- int k;
- int nr = BITS_TO_LONGS(bits);
- unsigned long result = 0;
-
- for (k = 0; k < nr; k++) {
- result |= (dst[k] = bitmap1[k] & ~bitmap2[k]);
- }
- return result != 0;
-}
-
-#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))
-
-void bitmap_set(unsigned long *map, int start, int nr)
-{
- unsigned long *p = map + BIT_WORD(start);
- const int size = start + nr;
- int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
- unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
-
- while (nr - bits_to_set >= 0) {
- *p |= mask_to_set;
- nr -= bits_to_set;
- bits_to_set = BITS_PER_LONG;
- mask_to_set = ~0UL;
- p++;
- }
- if (nr) {
- mask_to_set &= BITMAP_LAST_WORD_MASK(size);
- *p |= mask_to_set;
- }
-}
-
-void bitmap_clear(unsigned long *map, int start, int nr)
-{
- unsigned long *p = map + BIT_WORD(start);
- const int size = start + nr;
- int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
- unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
-
- while (nr - bits_to_clear >= 0) {
- *p &= ~mask_to_clear;
- nr -= bits_to_clear;
- bits_to_clear = BITS_PER_LONG;
- mask_to_clear = ~0UL;
- p++;
- }
- if (nr) {
- mask_to_clear &= BITMAP_LAST_WORD_MASK(size);
- *p &= ~mask_to_clear;
- }
-}
-
-#define ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
-
-/**
- * bitmap_find_next_zero_area - find a contiguous aligned zero area
- * @map: The address to base the search on
- * @size: The bitmap size in bits
- * @start: The bitnumber to start searching at
- * @nr: The number of zeroed bits we're looking for
- * @align_mask: Alignment mask for zero area
- *
- * The @align_mask should be one less than a power of 2; the effect is that
- * the bit offset of all zero areas this function finds is multiples of that
- * power of 2. A @align_mask of 0 means no alignment is required.
- */
-unsigned long bitmap_find_next_zero_area(unsigned long *map,
- unsigned long size,
- unsigned long start,
- unsigned int nr,
- unsigned long align_mask)
-{
- unsigned long index, end, i;
-again:
- index = find_next_zero_bit(map, size, start);
-
- /* Align allocation */
- index = ALIGN_MASK(index, align_mask);
-
- end = index + nr;
- if (end > size) {
- return end;
- }
- i = find_next_bit(map, end, index);
- if (i < end) {
- start = i + 1;
- goto again;
- }
- return index;
-}
-
-int slow_bitmap_intersects(const unsigned long *bitmap1,
- const unsigned long *bitmap2, int bits)
-{
- int k, lim = bits/BITS_PER_LONG;
-
- for (k = 0; k < lim; ++k) {
- if (bitmap1[k] & bitmap2[k]) {
- return 1;
- }
- }
-
- if (bits % BITS_PER_LONG) {
- if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) {
- return 1;
- }
- }
- return 0;
-}
diff --git a/contrib/qemu/util/bitops.c b/contrib/qemu/util/bitops.c
deleted file mode 100644
index 227c38b883d..00000000000
--- a/contrib/qemu/util/bitops.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- * Copyright (C) 2008 IBM Corporation
- * Written by Rusty Russell <rusty@rustcorp.com.au>
- * (Inspired by David Howell's find_next_bit implementation)
- *
- * 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.
- */
-
-#include "qemu/bitops.h"
-
-#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
-
-/*
- * Find the next set bit in a memory region.
- */
-unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
-{
- const unsigned long *p = addr + BITOP_WORD(offset);
- unsigned long result = offset & ~(BITS_PER_LONG-1);
- unsigned long tmp;
-
- if (offset >= size) {
- return size;
- }
- size -= result;
- offset %= BITS_PER_LONG;
- if (offset) {
- tmp = *(p++);
- tmp &= (~0UL << offset);
- if (size < BITS_PER_LONG) {
- goto found_first;
- }
- if (tmp) {
- goto found_middle;
- }
- size -= BITS_PER_LONG;
- result += BITS_PER_LONG;
- }
- while (size >= 4*BITS_PER_LONG) {
- unsigned long d1, d2, d3;
- tmp = *p;
- d1 = *(p+1);
- d2 = *(p+2);
- d3 = *(p+3);
- if (tmp) {
- goto found_middle;
- }
- if (d1 | d2 | d3) {
- break;
- }
- p += 4;
- result += 4*BITS_PER_LONG;
- size -= 4*BITS_PER_LONG;
- }
- while (size >= BITS_PER_LONG) {
- if ((tmp = *(p++))) {
- goto found_middle;
- }
- result += BITS_PER_LONG;
- size -= BITS_PER_LONG;
- }
- if (!size) {
- return result;
- }
- tmp = *p;
-
-found_first:
- tmp &= (~0UL >> (BITS_PER_LONG - size));
- if (tmp == 0UL) { /* Are any bits set? */
- return result + size; /* Nope. */
- }
-found_middle:
- return result + ctzl(tmp);
-}
-
-/*
- * This implementation of find_{first,next}_zero_bit was stolen from
- * Linus' asm-alpha/bitops.h.
- */
-unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
-{
- const unsigned long *p = addr + BITOP_WORD(offset);
- unsigned long result = offset & ~(BITS_PER_LONG-1);
- unsigned long tmp;
-
- if (offset >= size) {
- return size;
- }
- size -= result;
- offset %= BITS_PER_LONG;
- if (offset) {
- tmp = *(p++);
- tmp |= ~0UL >> (BITS_PER_LONG - offset);
- if (size < BITS_PER_LONG) {
- goto found_first;
- }
- if (~tmp) {
- goto found_middle;
- }
- size -= BITS_PER_LONG;
- result += BITS_PER_LONG;
- }
- while (size & ~(BITS_PER_LONG-1)) {
- if (~(tmp = *(p++))) {
- goto found_middle;
- }
- result += BITS_PER_LONG;
- size -= BITS_PER_LONG;
- }
- if (!size) {
- return result;
- }
- tmp = *p;
-
-found_first:
- tmp |= ~0UL << size;
- if (tmp == ~0UL) { /* Are any bits zero? */
- return result + size; /* Nope. */
- }
-found_middle:
- return result + ctzl(~tmp);
-}
-
-unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
-{
- unsigned long words;
- unsigned long tmp;
-
- /* Start at final word. */
- words = size / BITS_PER_LONG;
-
- /* Partial final word? */
- if (size & (BITS_PER_LONG-1)) {
- tmp = (addr[words] & (~0UL >> (BITS_PER_LONG
- - (size & (BITS_PER_LONG-1)))));
- if (tmp) {
- goto found;
- }
- }
-
- while (words) {
- tmp = addr[--words];
- if (tmp) {
- found:
- return words * BITS_PER_LONG + BITS_PER_LONG - 1 - clzl(tmp);
- }
- }
-
- /* Not found */
- return size;
-}
diff --git a/contrib/qemu/util/cutils.c b/contrib/qemu/util/cutils.c
deleted file mode 100644
index 6caa4b8ddc4..00000000000
--- a/contrib/qemu/util/cutils.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Simple C functions to supplement the C library
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu-common.h"
-#include "qemu/host-utils.h"
-#include <math.h>
-
-#include "qemu/sockets.h"
-#include "qemu/iov.h"
-
-void strpadcpy(char *buf, int buf_size, const char *str, char pad)
-{
- int len = qemu_strnlen(str, buf_size);
- memcpy(buf, str, len);
- memset(buf + len, pad, buf_size - len);
-}
-
-void pstrcpy(char *buf, int buf_size, const char *str)
-{
- int c;
- char *q = buf;
-
- if (buf_size <= 0)
- return;
-
- for(;;) {
- c = *str++;
- if (c == 0 || q >= buf + buf_size - 1)
- break;
- *q++ = c;
- }
- *q = '\0';
-}
-
-/* strcat and truncate. */
-char *pstrcat(char *buf, int buf_size, const char *s)
-{
- int len;
- len = strlen(buf);
- if (len < buf_size)
- pstrcpy(buf + len, buf_size - len, s);
- return buf;
-}
-
-int strstart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (*p != *q)
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
-
-int stristart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (qemu_toupper(*p) != qemu_toupper(*q))
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
-
-/* XXX: use host strnlen if available ? */
-int qemu_strnlen(const char *s, int max_len)
-{
- int i;
-
- for(i = 0; i < max_len; i++) {
- if (s[i] == '\0') {
- break;
- }
- }
- return i;
-}
-
-char *qemu_strsep(char **input, const char *delim)
-{
- char *result = *input;
- if (result != NULL) {
- char *p;
-
- for (p = result; *p != '\0'; p++) {
- if (strchr(delim, *p)) {
- break;
- }
- }
- if (*p == '\0') {
- *input = NULL;
- } else {
- *p = '\0';
- *input = p + 1;
- }
- }
- return result;
-}
-
-time_t mktimegm(struct tm *tm)
-{
- time_t t;
- int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
- if (m < 3) {
- m += 12;
- y--;
- }
- t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
- y / 400 - 719469);
- t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
- return t;
-}
-
-int qemu_fls(int i)
-{
- return 32 - clz32(i);
-}
-
-/*
- * Make sure data goes on disk, but if possible do not bother to
- * write out the inode just for timestamp updates.
- *
- * Unfortunately even in 2009 many operating systems do not support
- * fdatasync and have to fall back to fsync.
- */
-int qemu_fdatasync(int fd)
-{
-#ifdef HAVE_FDATASYNC
- return fdatasync(fd);
-#else
- return fsync(fd);
-#endif
-}
-
-/*
- * Searches for an area with non-zero content in a buffer
- *
- * Attention! The len must be a multiple of
- * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE)
- * and addr must be a multiple of sizeof(VECTYPE) due to
- * restriction of optimizations in this function.
- *
- * can_use_buffer_find_nonzero_offset() can be used to check
- * these requirements.
- *
- * The return value is the offset of the non-zero area rounded
- * down to a multiple of sizeof(VECTYPE) for the first
- * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR chunks and down to
- * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE)
- * afterwards.
- *
- * If the buffer is all zero the return value is equal to len.
- */
-
-size_t buffer_find_nonzero_offset(const void *buf, size_t len)
-{
- const VECTYPE *p = buf;
- const VECTYPE zero = (VECTYPE){0};
- size_t i;
-
- assert(can_use_buffer_find_nonzero_offset(buf, len));
-
- if (!len) {
- return 0;
- }
-
- for (i = 0; i < BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) {
- if (!ALL_EQ(p[i], zero)) {
- return i * sizeof(VECTYPE);
- }
- }
-
- for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR;
- i < len / sizeof(VECTYPE);
- i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) {
- VECTYPE tmp0 = p[i + 0] | p[i + 1];
- VECTYPE tmp1 = p[i + 2] | p[i + 3];
- VECTYPE tmp2 = p[i + 4] | p[i + 5];
- VECTYPE tmp3 = p[i + 6] | p[i + 7];
- VECTYPE tmp01 = tmp0 | tmp1;
- VECTYPE tmp23 = tmp2 | tmp3;
- if (!ALL_EQ(tmp01 | tmp23, zero)) {
- break;
- }
- }
-
- return i * sizeof(VECTYPE);
-}
-
-/*
- * Checks if a buffer is all zeroes
- *
- * Attention! The len must be a multiple of 4 * sizeof(long) due to
- * restriction of optimizations in this function.
- */
-bool buffer_is_zero(const void *buf, size_t len)
-{
- /*
- * Use long as the biggest available internal data type that fits into the
- * CPU register and unroll the loop to smooth out the effect of memory
- * latency.
- */
-
- size_t i;
- long d0, d1, d2, d3;
- const long * const data = buf;
-
- /* use vector optimized zero check if possible */
- if (can_use_buffer_find_nonzero_offset(buf, len)) {
- return buffer_find_nonzero_offset(buf, len) == len;
- }
-
- assert(len % (4 * sizeof(long)) == 0);
- len /= sizeof(long);
-
- for (i = 0; i < len; i += 4) {
- d0 = data[i + 0];
- d1 = data[i + 1];
- d2 = data[i + 2];
- d3 = data[i + 3];
-
- if (d0 || d1 || d2 || d3) {
- return false;
- }
- }
-
- return true;
-}
-
-#ifndef _WIN32
-/* Sets a specific flag */
-int fcntl_setfl(int fd, int flag)
-{
- int flags;
-
- flags = fcntl(fd, F_GETFL);
- if (flags == -1)
- return -errno;
-
- if (fcntl(fd, F_SETFL, flags | flag) == -1)
- return -errno;
-
- return 0;
-}
-#endif
-
-static int64_t suffix_mul(char suffix, int64_t unit)
-{
- switch (qemu_toupper(suffix)) {
- case STRTOSZ_DEFSUFFIX_B:
- return 1;
- case STRTOSZ_DEFSUFFIX_KB:
- return unit;
- case STRTOSZ_DEFSUFFIX_MB:
- return unit * unit;
- case STRTOSZ_DEFSUFFIX_GB:
- return unit * unit * unit;
- case STRTOSZ_DEFSUFFIX_TB:
- return unit * unit * unit * unit;
- case STRTOSZ_DEFSUFFIX_PB:
- return unit * unit * unit * unit * unit;
- case STRTOSZ_DEFSUFFIX_EB:
- return unit * unit * unit * unit * unit * unit;
- }
- return -1;
-}
-
-/*
- * Convert string to bytes, allowing either B/b for bytes, K/k for KB,
- * M/m for MB, G/g for GB or T/t for TB. End pointer will be returned
- * in *end, if not NULL. Return -ERANGE on overflow, Return -EINVAL on
- * other error.
- */
-int64_t strtosz_suffix_unit(const char *nptr, char **end,
- const char default_suffix, int64_t unit)
-{
- int64_t retval = -EINVAL;
- char *endptr;
- unsigned char c;
- int mul_required = 0;
- double val, mul, integral, fraction;
-
- errno = 0;
- val = strtod(nptr, &endptr);
- if (isnan(val) || endptr == nptr || errno != 0) {
- goto fail;
- }
- fraction = modf(val, &integral);
- if (fraction != 0) {
- mul_required = 1;
- }
- c = *endptr;
- mul = suffix_mul(c, unit);
- if (mul >= 0) {
- endptr++;
- } else {
- mul = suffix_mul(default_suffix, unit);
- assert(mul >= 0);
- }
- if (mul == 1 && mul_required) {
- goto fail;
- }
- if ((val * mul >= INT64_MAX) || val < 0) {
- retval = -ERANGE;
- goto fail;
- }
- retval = val * mul;
-
-fail:
- if (end) {
- *end = endptr;
- }
-
- return retval;
-}
-
-int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
-{
- return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
-}
-
-int64_t strtosz(const char *nptr, char **end)
-{
- return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB);
-}
-
-/**
- * parse_uint:
- *
- * @s: String to parse
- * @value: Destination for parsed integer value
- * @endptr: Destination for pointer to first character not consumed
- * @base: integer base, between 2 and 36 inclusive, or 0
- *
- * Parse unsigned integer
- *
- * Parsed syntax is like strtoull()'s: arbitrary whitespace, a single optional
- * '+' or '-', an optional "0x" if @base is 0 or 16, one or more digits.
- *
- * If @s is null, or @base is invalid, or @s doesn't start with an
- * integer in the syntax above, set *@value to 0, *@endptr to @s, and
- * return -EINVAL.
- *
- * Set *@endptr to point right beyond the parsed integer (even if the integer
- * overflows or is negative, all digits will be parsed and *@endptr will
- * point right beyond them).
- *
- * If the integer is negative, set *@value to 0, and return -ERANGE.
- *
- * If the integer overflows unsigned long long, set *@value to
- * ULLONG_MAX, and return -ERANGE.
- *
- * Else, set *@value to the parsed integer, and return 0.
- */
-int parse_uint(const char *s, unsigned long long *value, char **endptr,
- int base)
-{
- int r = 0;
- char *endp = (char *)s;
- unsigned long long val = 0;
-
- if (!s) {
- r = -EINVAL;
- goto out;
- }
-
- errno = 0;
- val = strtoull(s, &endp, base);
- if (errno) {
- r = -errno;
- goto out;
- }
-
- if (endp == s) {
- r = -EINVAL;
- goto out;
- }
-
- /* make sure we reject negative numbers: */
- while (isspace((unsigned char)*s)) {
- s++;
- }
- if (*s == '-') {
- val = 0;
- r = -ERANGE;
- goto out;
- }
-
-out:
- *value = val;
- *endptr = endp;
- return r;
-}
-
-/**
- * parse_uint_full:
- *
- * @s: String to parse
- * @value: Destination for parsed integer value
- * @base: integer base, between 2 and 36 inclusive, or 0
- *
- * Parse unsigned integer from entire string
- *
- * Have the same behavior of parse_uint(), but with an additional check
- * for additional data after the parsed number. If extra characters are present
- * after the parsed number, the function will return -EINVAL, and *@v will
- * be set to 0.
- */
-int parse_uint_full(const char *s, unsigned long long *value, int base)
-{
- char *endp;
- int r;
-
- r = parse_uint(s, value, &endp, base);
- if (r < 0) {
- return r;
- }
- if (*endp) {
- *value = 0;
- return -EINVAL;
- }
-
- return 0;
-}
-
-int qemu_parse_fd(const char *param)
-{
- int fd;
- char *endptr = NULL;
-
- fd = strtol(param, &endptr, 10);
- if (*endptr || (fd == 0 && param == endptr)) {
- return -1;
- }
- return fd;
-}
-
-/* round down to the nearest power of 2*/
-int64_t pow2floor(int64_t value)
-{
- if (!is_power_of_2(value)) {
- value = 0x8000000000000000ULL >> clz64(value);
- }
- return value;
-}
-
-/*
- * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128)
- * Input is limited to 14-bit numbers
- */
-int uleb128_encode_small(uint8_t *out, uint32_t n)
-{
- g_assert(n <= 0x3fff);
- if (n < 0x80) {
- *out++ = n;
- return 1;
- } else {
- *out++ = (n & 0x7f) | 0x80;
- *out++ = n >> 7;
- return 2;
- }
-}
-
-int uleb128_decode_small(const uint8_t *in, uint32_t *n)
-{
- if (!(*in & 0x80)) {
- *n = *in++;
- return 1;
- } else {
- *n = *in++ & 0x7f;
- /* we exceed 14 bit number */
- if (*in & 0x80) {
- return -1;
- }
- *n |= *in++ << 7;
- return 2;
- }
-}
-
-/*
- * helper to parse debug environment variables
- */
-int parse_debug_env(const char *name, int max, int initial)
-{
- char *debug_env = getenv(name);
- char *inv = NULL;
- int debug;
-
- if (!debug_env) {
- return initial;
- }
- debug = strtol(debug_env, &inv, 10);
- if (inv == debug_env) {
- return initial;
- }
- if (debug < 0 || debug > max) {
- fprintf(stderr, "warning: %s not in [0, %d]", name, max);
- return initial;
- }
- return debug;
-}
diff --git a/contrib/qemu/util/error.c b/contrib/qemu/util/error.c
deleted file mode 100644
index 53b04354aef..00000000000
--- a/contrib/qemu/util/error.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * QEMU Error Objects
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2. See
- * the COPYING.LIB file in the top-level directory.
- */
-
-#include "qemu-common.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qjson.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi-types.h"
-#include "qapi/qmp/qerror.h"
-
-struct Error
-{
- char *msg;
- ErrorClass err_class;
-};
-
-void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
-{
- Error *err;
- va_list ap;
-
- if (errp == NULL) {
- return;
- }
- assert(*errp == NULL);
-
- err = g_malloc0(sizeof(*err));
-
- va_start(ap, fmt);
- err->msg = g_strdup_vprintf(fmt, ap);
- va_end(ap);
- err->err_class = err_class;
-
- *errp = err;
-}
-
-void error_set_errno(Error **errp, int os_errno, ErrorClass err_class,
- const char *fmt, ...)
-{
- Error *err;
- char *msg1;
- va_list ap;
-
- if (errp == NULL) {
- return;
- }
- assert(*errp == NULL);
-
- err = g_malloc0(sizeof(*err));
-
- va_start(ap, fmt);
- msg1 = g_strdup_vprintf(fmt, ap);
- if (os_errno != 0) {
- err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno));
- g_free(msg1);
- } else {
- err->msg = msg1;
- }
- va_end(ap);
- err->err_class = err_class;
-
- *errp = err;
-}
-
-void error_setg_file_open(Error **errp, int os_errno, const char *filename)
-{
- error_setg_errno(errp, os_errno, "Could not open '%s'", filename);
-}
-
-Error *error_copy(const Error *err)
-{
- Error *err_new;
-
- err_new = g_malloc0(sizeof(*err));
- err_new->msg = g_strdup(err->msg);
- err_new->err_class = err->err_class;
-
- return err_new;
-}
-
-bool error_is_set(Error **errp)
-{
- return (errp && *errp);
-}
-
-ErrorClass error_get_class(const Error *err)
-{
- return err->err_class;
-}
-
-const char *error_get_pretty(Error *err)
-{
- return err->msg;
-}
-
-void error_free(Error *err)
-{
- if (err) {
- g_free(err->msg);
- g_free(err);
- }
-}
-
-void error_propagate(Error **dst_err, Error *local_err)
-{
- if (dst_err && !*dst_err) {
- *dst_err = local_err;
- } else if (local_err) {
- error_free(local_err);
- }
-}
diff --git a/contrib/qemu/util/hbitmap.c b/contrib/qemu/util/hbitmap.c
deleted file mode 100644
index e063e681f52..00000000000
--- a/contrib/qemu/util/hbitmap.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Hierarchical Bitmap Data Type
- *
- * Copyright Red Hat, Inc., 2012
- *
- * Author: Paolo Bonzini <pbonzini@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * later. See the COPYING file in the top-level directory.
- */
-
-#include <string.h>
-#include <glib.h>
-#include <assert.h>
-#include "qemu/osdep.h"
-#include "qemu/hbitmap.h"
-#include "qemu/host-utils.h"
-#include "trace.h"
-
-/* HBitmaps provides an array of bits. The bits are stored as usual in an
- * array of unsigned longs, but HBitmap is also optimized to provide fast
- * iteration over set bits; going from one bit to the next is O(logB n)
- * worst case, with B = sizeof(long) * CHAR_BIT: the result is low enough
- * that the number of levels is in fact fixed.
- *
- * In order to do this, it stacks multiple bitmaps with progressively coarser
- * granularity; in all levels except the last, bit N is set iff the N-th
- * unsigned long is nonzero in the immediately next level. When iteration
- * completes on the last level it can examine the 2nd-last level to quickly
- * skip entire words, and even do so recursively to skip blocks of 64 words or
- * powers thereof (32 on 32-bit machines).
- *
- * Given an index in the bitmap, it can be split in group of bits like
- * this (for the 64-bit case):
- *
- * bits 0-57 => word in the last bitmap | bits 58-63 => bit in the word
- * bits 0-51 => word in the 2nd-last bitmap | bits 52-57 => bit in the word
- * bits 0-45 => word in the 3rd-last bitmap | bits 46-51 => bit in the word
- *
- * So it is easy to move up simply by shifting the index right by
- * log2(BITS_PER_LONG) bits. To move down, you shift the index left
- * similarly, and add the word index within the group. Iteration uses
- * ffs (find first set bit) to find the next word to examine; this
- * operation can be done in constant time in most current architectures.
- *
- * Setting or clearing a range of m bits on all levels, the work to perform
- * is O(m + m/W + m/W^2 + ...), which is O(m) like on a regular bitmap.
- *
- * When iterating on a bitmap, each bit (on any level) is only visited
- * once. Hence, The total cost of visiting a bitmap with m bits in it is
- * the number of bits that are set in all bitmaps. Unless the bitmap is
- * extremely sparse, this is also O(m + m/W + m/W^2 + ...), so the amortized
- * cost of advancing from one bit to the next is usually constant (worst case
- * O(logB n) as in the non-amortized complexity).
- */
-
-struct HBitmap {
- /* Number of total bits in the bottom level. */
- uint64_t size;
-
- /* Number of set bits in the bottom level. */
- uint64_t count;
-
- /* A scaling factor. Given a granularity of G, each bit in the bitmap will
- * will actually represent a group of 2^G elements. Each operation on a
- * range of bits first rounds the bits to determine which group they land
- * in, and then affect the entire page; iteration will only visit the first
- * bit of each group. Here is an example of operations in a size-16,
- * granularity-1 HBitmap:
- *
- * initial state 00000000
- * set(start=0, count=9) 11111000 (iter: 0, 2, 4, 6, 8)
- * reset(start=1, count=3) 00111000 (iter: 4, 6, 8)
- * set(start=9, count=2) 00111100 (iter: 4, 6, 8, 10)
- * reset(start=5, count=5) 00000000
- *
- * From an implementation point of view, when setting or resetting bits,
- * the bitmap will scale bit numbers right by this amount of bits. When
- * iterating, the bitmap will scale bit numbers left by this amount of
- * bits.
- */
- int granularity;
-
- /* A number of progressively less coarse bitmaps (i.e. level 0 is the
- * coarsest). Each bit in level N represents a word in level N+1 that
- * has a set bit, except the last level where each bit represents the
- * actual bitmap.
- *
- * Note that all bitmaps have the same number of levels. Even a 1-bit
- * bitmap will still allocate HBITMAP_LEVELS arrays.
- */
- unsigned long *levels[HBITMAP_LEVELS];
-};
-
-#ifndef __NetBSD__ /* we have it in <strings.h> */
-static inline int popcountl(unsigned long l)
-{
- return BITS_PER_LONG == 32 ? ctpop32(l) : ctpop64(l);
-}
-#endif
-
-/* Advance hbi to the next nonzero word and return it. hbi->pos
- * is updated. Returns zero if we reach the end of the bitmap.
- */
-unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi)
-{
- size_t pos = hbi->pos;
- const HBitmap *hb = hbi->hb;
- unsigned i = HBITMAP_LEVELS - 1;
-
- unsigned long cur;
- do {
- cur = hbi->cur[--i];
- pos >>= BITS_PER_LEVEL;
- } while (cur == 0);
-
- /* Check for end of iteration. We always use fewer than BITS_PER_LONG
- * bits in the level 0 bitmap; thus we can repurpose the most significant
- * bit as a sentinel. The sentinel is set in hbitmap_alloc and ensures
- * that the above loop ends even without an explicit check on i.
- */
-
- if (i == 0 && cur == (1UL << (BITS_PER_LONG - 1))) {
- return 0;
- }
- for (; i < HBITMAP_LEVELS - 1; i++) {
- /* Shift back pos to the left, matching the right shifts above.
- * The index of this word's least significant set bit provides
- * the low-order bits.
- */
- assert(cur);
- pos = (pos << BITS_PER_LEVEL) + ctzl(cur);
- hbi->cur[i] = cur & (cur - 1);
-
- /* Set up next level for iteration. */
- cur = hb->levels[i + 1][pos];
- }
-
- hbi->pos = pos;
- trace_hbitmap_iter_skip_words(hbi->hb, hbi, pos, cur);
-
- assert(cur);
- return cur;
-}
-
-void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first)
-{
- unsigned i, bit;
- uint64_t pos;
-
- hbi->hb = hb;
- pos = first >> hb->granularity;
- assert(pos < hb->size);
- hbi->pos = pos >> BITS_PER_LEVEL;
- hbi->granularity = hb->granularity;
-
- for (i = HBITMAP_LEVELS; i-- > 0; ) {
- bit = pos & (BITS_PER_LONG - 1);
- pos >>= BITS_PER_LEVEL;
-
- /* Drop bits representing items before first. */
- hbi->cur[i] = hb->levels[i][pos] & ~((1UL << bit) - 1);
-
- /* We have already added level i+1, so the lowest set bit has
- * been processed. Clear it.
- */
- if (i != HBITMAP_LEVELS - 1) {
- hbi->cur[i] &= ~(1UL << bit);
- }
- }
-}
-
-bool hbitmap_empty(const HBitmap *hb)
-{
- return hb->count == 0;
-}
-
-int hbitmap_granularity(const HBitmap *hb)
-{
- return hb->granularity;
-}
-
-uint64_t hbitmap_count(const HBitmap *hb)
-{
- return hb->count << hb->granularity;
-}
-
-/* Count the number of set bits between start and end, not accounting for
- * the granularity. Also an example of how to use hbitmap_iter_next_word.
- */
-static uint64_t hb_count_between(HBitmap *hb, uint64_t start, uint64_t last)
-{
- HBitmapIter hbi;
- uint64_t count = 0;
- uint64_t end = last + 1;
- unsigned long cur;
- size_t pos;
-
- hbitmap_iter_init(&hbi, hb, start << hb->granularity);
- for (;;) {
- pos = hbitmap_iter_next_word(&hbi, &cur);
- if (pos >= (end >> BITS_PER_LEVEL)) {
- break;
- }
- count += popcountl(cur);
- }
-
- if (pos == (end >> BITS_PER_LEVEL)) {
- /* Drop bits representing the END-th and subsequent items. */
- int bit = end & (BITS_PER_LONG - 1);
- cur &= (1UL << bit) - 1;
- count += popcountl(cur);
- }
-
- return count;
-}
-
-/* Setting starts at the last layer and propagates up if an element
- * changes from zero to non-zero.
- */
-static inline bool hb_set_elem(unsigned long *elem, uint64_t start, uint64_t last)
-{
- unsigned long mask;
- bool changed;
-
- assert((last >> BITS_PER_LEVEL) == (start >> BITS_PER_LEVEL));
- assert(start <= last);
-
- mask = 2UL << (last & (BITS_PER_LONG - 1));
- mask -= 1UL << (start & (BITS_PER_LONG - 1));
- changed = (*elem == 0);
- *elem |= mask;
- return changed;
-}
-
-/* The recursive workhorse (the depth is limited to HBITMAP_LEVELS)... */
-static void hb_set_between(HBitmap *hb, int level, uint64_t start, uint64_t last)
-{
- size_t pos = start >> BITS_PER_LEVEL;
- size_t lastpos = last >> BITS_PER_LEVEL;
- bool changed = false;
- size_t i;
-
- i = pos;
- if (i < lastpos) {
- uint64_t next = (start | (BITS_PER_LONG - 1)) + 1;
- changed |= hb_set_elem(&hb->levels[level][i], start, next - 1);
- for (;;) {
- start = next;
- next += BITS_PER_LONG;
- if (++i == lastpos) {
- break;
- }
- changed |= (hb->levels[level][i] == 0);
- hb->levels[level][i] = ~0UL;
- }
- }
- changed |= hb_set_elem(&hb->levels[level][i], start, last);
-
- /* If there was any change in this layer, we may have to update
- * the one above.
- */
- if (level > 0 && changed) {
- hb_set_between(hb, level - 1, pos, lastpos);
- }
-}
-
-void hbitmap_set(HBitmap *hb, uint64_t start, uint64_t count)
-{
- /* Compute range in the last layer. */
- uint64_t last = start + count - 1;
-
- trace_hbitmap_set(hb, start, count,
- start >> hb->granularity, last >> hb->granularity);
-
- start >>= hb->granularity;
- last >>= hb->granularity;
- count = last - start + 1;
-
- hb->count += count - hb_count_between(hb, start, last);
- hb_set_between(hb, HBITMAP_LEVELS - 1, start, last);
-}
-
-/* Resetting works the other way round: propagate up if the new
- * value is zero.
- */
-static inline bool hb_reset_elem(unsigned long *elem, uint64_t start, uint64_t last)
-{
- unsigned long mask;
- bool blanked;
-
- assert((last >> BITS_PER_LEVEL) == (start >> BITS_PER_LEVEL));
- assert(start <= last);
-
- mask = 2UL << (last & (BITS_PER_LONG - 1));
- mask -= 1UL << (start & (BITS_PER_LONG - 1));
- blanked = *elem != 0 && ((*elem & ~mask) == 0);
- *elem &= ~mask;
- return blanked;
-}
-
-/* The recursive workhorse (the depth is limited to HBITMAP_LEVELS)... */
-static void hb_reset_between(HBitmap *hb, int level, uint64_t start, uint64_t last)
-{
- size_t pos = start >> BITS_PER_LEVEL;
- size_t lastpos = last >> BITS_PER_LEVEL;
- bool changed = false;
- size_t i;
-
- i = pos;
- if (i < lastpos) {
- uint64_t next = (start | (BITS_PER_LONG - 1)) + 1;
-
- /* Here we need a more complex test than when setting bits. Even if
- * something was changed, we must not blank bits in the upper level
- * unless the lower-level word became entirely zero. So, remove pos
- * from the upper-level range if bits remain set.
- */
- if (hb_reset_elem(&hb->levels[level][i], start, next - 1)) {
- changed = true;
- } else {
- pos++;
- }
-
- for (;;) {
- start = next;
- next += BITS_PER_LONG;
- if (++i == lastpos) {
- break;
- }
- changed |= (hb->levels[level][i] != 0);
- hb->levels[level][i] = 0UL;
- }
- }
-
- /* Same as above, this time for lastpos. */
- if (hb_reset_elem(&hb->levels[level][i], start, last)) {
- changed = true;
- } else {
- lastpos--;
- }
-
- if (level > 0 && changed) {
- hb_reset_between(hb, level - 1, pos, lastpos);
- }
-}
-
-void hbitmap_reset(HBitmap *hb, uint64_t start, uint64_t count)
-{
- /* Compute range in the last layer. */
- uint64_t last = start + count - 1;
-
- trace_hbitmap_reset(hb, start, count,
- start >> hb->granularity, last >> hb->granularity);
-
- start >>= hb->granularity;
- last >>= hb->granularity;
-
- hb->count -= hb_count_between(hb, start, last);
- hb_reset_between(hb, HBITMAP_LEVELS - 1, start, last);
-}
-
-bool hbitmap_get(const HBitmap *hb, uint64_t item)
-{
- /* Compute position and bit in the last layer. */
- uint64_t pos = item >> hb->granularity;
- unsigned long bit = 1UL << (pos & (BITS_PER_LONG - 1));
-
- return (hb->levels[HBITMAP_LEVELS - 1][pos >> BITS_PER_LEVEL] & bit) != 0;
-}
-
-void hbitmap_free(HBitmap *hb)
-{
- unsigned i;
- for (i = HBITMAP_LEVELS; i-- > 0; ) {
- g_free(hb->levels[i]);
- }
- g_free(hb);
-}
-
-HBitmap *hbitmap_alloc(uint64_t size, int granularity)
-{
- HBitmap *hb = g_malloc0(sizeof (struct HBitmap));
- unsigned i;
-
- assert(granularity >= 0 && granularity < 64);
- size = (size + (1ULL << granularity) - 1) >> granularity;
- assert(size <= ((uint64_t)1 << HBITMAP_LOG_MAX_SIZE));
-
- hb->size = size;
- hb->granularity = granularity;
- for (i = HBITMAP_LEVELS; i-- > 0; ) {
- size = MAX((size + BITS_PER_LONG - 1) >> BITS_PER_LEVEL, 1);
- hb->levels[i] = g_malloc0(size * sizeof(unsigned long));
- }
-
- /* We necessarily have free bits in level 0 due to the definition
- * of HBITMAP_LEVELS, so use one for a sentinel. This speeds up
- * hbitmap_iter_skip_words.
- */
- assert(size == 1);
- hb->levels[0][0] |= 1UL << (BITS_PER_LONG - 1);
- return hb;
-}
diff --git a/contrib/qemu/util/hexdump.c b/contrib/qemu/util/hexdump.c
deleted file mode 100644
index 969b3406c07..00000000000
--- a/contrib/qemu/util/hexdump.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Helper to hexdump a buffer
- *
- * Copyright (c) 2013 Red Hat, Inc.
- * Copyright (c) 2013 Gerd Hoffmann <kraxel@redhat.com>
- * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com>
- * Copyright (c) 2013 Xilinx, Inc
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu-common.h"
-
-void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size)
-{
- unsigned int b;
-
- for (b = 0; b < size; b++) {
- if ((b % 16) == 0) {
- fprintf(fp, "%s: %04x:", prefix, b);
- }
- if ((b % 4) == 0) {
- fprintf(fp, " ");
- }
- fprintf(fp, " %02x", (unsigned char)buf[b]);
- if ((b % 16) == 15) {
- fprintf(fp, "\n");
- }
- }
- if ((b % 16) != 0) {
- fprintf(fp, "\n");
- }
-}
diff --git a/contrib/qemu/util/iov.c b/contrib/qemu/util/iov.c
deleted file mode 100644
index cc6e837c836..00000000000
--- a/contrib/qemu/util/iov.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * Helpers for getting linearized buffers from iov / filling buffers into iovs
- *
- * Copyright IBM, Corp. 2007, 2008
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * Author(s):
- * Anthony Liguori <aliguori@us.ibm.com>
- * Amit Shah <amit.shah@redhat.com>
- * Michael Tokarev <mjt@tls.msk.ru>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/iov.h"
-
-#ifdef _WIN32
-# include <windows.h>
-# include <winsock2.h>
-#else
-# include <sys/types.h>
-# include <sys/socket.h>
-#endif
-
-size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
- size_t offset, const void *buf, size_t bytes)
-{
- size_t done;
- unsigned int i;
- for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
- if (offset < iov[i].iov_len) {
- size_t len = MIN(iov[i].iov_len - offset, bytes - done);
- memcpy(iov[i].iov_base + offset, buf + done, len);
- done += len;
- offset = 0;
- } else {
- offset -= iov[i].iov_len;
- }
- }
- assert(offset == 0);
- return done;
-}
-
-size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
- size_t offset, void *buf, size_t bytes)
-{
- size_t done;
- unsigned int i;
- for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
- if (offset < iov[i].iov_len) {
- size_t len = MIN(iov[i].iov_len - offset, bytes - done);
- memcpy(buf + done, iov[i].iov_base + offset, len);
- done += len;
- offset = 0;
- } else {
- offset -= iov[i].iov_len;
- }
- }
- assert(offset == 0);
- return done;
-}
-
-size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
- size_t offset, int fillc, size_t bytes)
-{
- size_t done;
- unsigned int i;
- for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
- if (offset < iov[i].iov_len) {
- size_t len = MIN(iov[i].iov_len - offset, bytes - done);
- memset(iov[i].iov_base + offset, fillc, len);
- done += len;
- offset = 0;
- } else {
- offset -= iov[i].iov_len;
- }
- }
- assert(offset == 0);
- return done;
-}
-
-size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt)
-{
- size_t len;
- unsigned int i;
-
- len = 0;
- for (i = 0; i < iov_cnt; i++) {
- len += iov[i].iov_len;
- }
- return len;
-}
-
-/* helper function for iov_send_recv() */
-static ssize_t
-do_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, bool do_send)
-{
-#ifdef CONFIG_POSIX
- ssize_t ret;
- struct msghdr msg;
- memset(&msg, 0, sizeof(msg));
- msg.msg_iov = iov;
- msg.msg_iovlen = iov_cnt;
- do {
- ret = do_send
- ? sendmsg(sockfd, &msg, 0)
- : recvmsg(sockfd, &msg, 0);
- } while (ret < 0 && errno == EINTR);
- return ret;
-#else
- /* else send piece-by-piece */
- /*XXX Note: windows has WSASend() and WSARecv() */
- unsigned i = 0;
- ssize_t ret = 0;
- while (i < iov_cnt) {
- ssize_t r = do_send
- ? send(sockfd, iov[i].iov_base, iov[i].iov_len, 0)
- : recv(sockfd, iov[i].iov_base, iov[i].iov_len, 0);
- if (r > 0) {
- ret += r;
- } else if (!r) {
- break;
- } else if (errno == EINTR) {
- continue;
- } else {
- /* else it is some "other" error,
- * only return if there was no data processed. */
- if (ret == 0) {
- ret = -1;
- }
- break;
- }
- i++;
- }
- return ret;
-#endif
-}
-
-ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt,
- size_t offset, size_t bytes,
- bool do_send)
-{
- ssize_t total = 0;
- ssize_t ret;
- size_t orig_len, tail;
- unsigned niov;
-
- while (bytes > 0) {
- /* Find the start position, skipping `offset' bytes:
- * first, skip all full-sized vector elements, */
- for (niov = 0; niov < iov_cnt && offset >= iov[niov].iov_len; ++niov) {
- offset -= iov[niov].iov_len;
- }
-
- /* niov == iov_cnt would only be valid if bytes == 0, which
- * we already ruled out in the loop condition. */
- assert(niov < iov_cnt);
- iov += niov;
- iov_cnt -= niov;
-
- if (offset) {
- /* second, skip `offset' bytes from the (now) first element,
- * undo it on exit */
- iov[0].iov_base += offset;
- iov[0].iov_len -= offset;
- }
- /* Find the end position skipping `bytes' bytes: */
- /* first, skip all full-sized elements */
- tail = bytes;
- for (niov = 0; niov < iov_cnt && iov[niov].iov_len <= tail; ++niov) {
- tail -= iov[niov].iov_len;
- }
- if (tail) {
- /* second, fixup the last element, and remember the original
- * length */
- assert(niov < iov_cnt);
- assert(iov[niov].iov_len > tail);
- orig_len = iov[niov].iov_len;
- iov[niov++].iov_len = tail;
- }
-
- ret = do_send_recv(sockfd, iov, niov, do_send);
-
- /* Undo the changes above before checking for errors */
- if (tail) {
- iov[niov-1].iov_len = orig_len;
- }
- if (offset) {
- iov[0].iov_base -= offset;
- iov[0].iov_len += offset;
- }
-
- if (ret < 0) {
- assert(errno != EINTR);
- if (errno == EAGAIN && total > 0) {
- return total;
- }
- return -1;
- }
-
- /* Prepare for the next iteration */
- offset += ret;
- total += ret;
- bytes -= ret;
- }
-
- return total;
-}
-
-
-void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
- FILE *fp, const char *prefix, size_t limit)
-{
- int v;
- size_t size = 0;
- char *buf;
-
- for (v = 0; v < iov_cnt; v++) {
- size += iov[v].iov_len;
- }
- size = size > limit ? limit : size;
- buf = g_malloc(size);
- iov_to_buf(iov, iov_cnt, 0, buf, size);
- qemu_hexdump(buf, fp, prefix, size);
- g_free(buf);
-}
-
-unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
- const struct iovec *iov, unsigned int iov_cnt,
- size_t offset, size_t bytes)
-{
- size_t len;
- unsigned int i, j;
- for (i = 0, j = 0; i < iov_cnt && j < dst_iov_cnt && bytes; i++) {
- if (offset >= iov[i].iov_len) {
- offset -= iov[i].iov_len;
- continue;
- }
- len = MIN(bytes, iov[i].iov_len - offset);
-
- dst_iov[j].iov_base = iov[i].iov_base + offset;
- dst_iov[j].iov_len = len;
- j++;
- bytes -= len;
- offset = 0;
- }
- assert(offset == 0);
- return j;
-}
-
-/* io vectors */
-
-void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
-{
- qiov->iov = g_malloc(alloc_hint * sizeof(struct iovec));
- qiov->niov = 0;
- qiov->nalloc = alloc_hint;
- qiov->size = 0;
-}
-
-void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov)
-{
- int i;
-
- qiov->iov = iov;
- qiov->niov = niov;
- qiov->nalloc = -1;
- qiov->size = 0;
- for (i = 0; i < niov; i++)
- qiov->size += iov[i].iov_len;
-}
-
-void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
-{
- assert(qiov->nalloc != -1);
-
- if (qiov->niov == qiov->nalloc) {
- qiov->nalloc = 2 * qiov->nalloc + 1;
- qiov->iov = g_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));
- }
- qiov->iov[qiov->niov].iov_base = base;
- qiov->iov[qiov->niov].iov_len = len;
- qiov->size += len;
- ++qiov->niov;
-}
-
-/*
- * Concatenates (partial) iovecs from src_iov to the end of dst.
- * It starts copying after skipping `soffset' bytes at the
- * beginning of src and adds individual vectors from src to
- * dst copies up to `sbytes' bytes total, or up to the end
- * of src_iov if it comes first. This way, it is okay to specify
- * very large value for `sbytes' to indicate "up to the end
- * of src".
- * Only vector pointers are processed, not the actual data buffers.
- */
-void qemu_iovec_concat_iov(QEMUIOVector *dst,
- struct iovec *src_iov, unsigned int src_cnt,
- size_t soffset, size_t sbytes)
-{
- int i;
- size_t done;
-
- if (!sbytes) {
- return;
- }
- assert(dst->nalloc != -1);
- for (i = 0, done = 0; done < sbytes && i < src_cnt; i++) {
- if (soffset < src_iov[i].iov_len) {
- size_t len = MIN(src_iov[i].iov_len - soffset, sbytes - done);
- qemu_iovec_add(dst, src_iov[i].iov_base + soffset, len);
- done += len;
- soffset = 0;
- } else {
- soffset -= src_iov[i].iov_len;
- }
- }
- assert(soffset == 0); /* offset beyond end of src */
-}
-
-/*
- * Concatenates (partial) iovecs from src to the end of dst.
- * It starts copying after skipping `soffset' bytes at the
- * beginning of src and adds individual vectors from src to
- * dst copies up to `sbytes' bytes total, or up to the end
- * of src if it comes first. This way, it is okay to specify
- * very large value for `sbytes' to indicate "up to the end
- * of src".
- * Only vector pointers are processed, not the actual data buffers.
- */
-void qemu_iovec_concat(QEMUIOVector *dst,
- QEMUIOVector *src, size_t soffset, size_t sbytes)
-{
- qemu_iovec_concat_iov(dst, src->iov, src->niov, soffset, sbytes);
-}
-
-void qemu_iovec_destroy(QEMUIOVector *qiov)
-{
- assert(qiov->nalloc != -1);
-
- qemu_iovec_reset(qiov);
- g_free(qiov->iov);
- qiov->nalloc = 0;
- qiov->iov = NULL;
-}
-
-void qemu_iovec_reset(QEMUIOVector *qiov)
-{
- assert(qiov->nalloc != -1);
-
- qiov->niov = 0;
- qiov->size = 0;
-}
-
-size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset,
- void *buf, size_t bytes)
-{
- return iov_to_buf(qiov->iov, qiov->niov, offset, buf, bytes);
-}
-
-size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset,
- const void *buf, size_t bytes)
-{
- return iov_from_buf(qiov->iov, qiov->niov, offset, buf, bytes);
-}
-
-size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
- int fillc, size_t bytes)
-{
- return iov_memset(qiov->iov, qiov->niov, offset, fillc, bytes);
-}
-
-size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
- size_t bytes)
-{
- size_t total = 0;
- struct iovec *cur;
-
- for (cur = *iov; *iov_cnt > 0; cur++) {
- if (cur->iov_len > bytes) {
- cur->iov_base += bytes;
- cur->iov_len -= bytes;
- total += bytes;
- break;
- }
-
- bytes -= cur->iov_len;
- total += cur->iov_len;
- *iov_cnt -= 1;
- }
-
- *iov = cur;
- return total;
-}
-
-size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
- size_t bytes)
-{
- size_t total = 0;
- struct iovec *cur;
-
- if (*iov_cnt == 0) {
- return 0;
- }
-
- cur = iov + (*iov_cnt - 1);
-
- while (*iov_cnt > 0) {
- if (cur->iov_len > bytes) {
- cur->iov_len -= bytes;
- total += bytes;
- break;
- }
-
- bytes -= cur->iov_len;
- total += cur->iov_len;
- cur--;
- *iov_cnt -= 1;
- }
-
- return total;
-}
diff --git a/contrib/qemu/util/module.c b/contrib/qemu/util/module.c
deleted file mode 100644
index 7acc33d076a..00000000000
--- a/contrib/qemu/util/module.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * QEMU Module Infrastructure
- *
- * Copyright IBM, Corp. 2009
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu-common.h"
-#include "qemu/queue.h"
-#include "qemu/module.h"
-
-typedef struct ModuleEntry
-{
- void (*init)(void);
- QTAILQ_ENTRY(ModuleEntry) node;
-} ModuleEntry;
-
-typedef QTAILQ_HEAD(, ModuleEntry) ModuleTypeList;
-
-static ModuleTypeList init_type_list[MODULE_INIT_MAX];
-
-static void init_types(void)
-{
- static int inited;
- int i;
-
- if (inited) {
- return;
- }
-
- for (i = 0; i < MODULE_INIT_MAX; i++) {
- QTAILQ_INIT(&init_type_list[i]);
- }
-
- inited = 1;
-}
-
-
-static ModuleTypeList *find_type(module_init_type type)
-{
- ModuleTypeList *l;
-
- init_types();
-
- l = &init_type_list[type];
-
- return l;
-}
-
-void register_module_init(void (*fn)(void), module_init_type type)
-{
- ModuleEntry *e;
- ModuleTypeList *l;
-
- e = g_malloc0(sizeof(*e));
- e->init = fn;
-
- l = find_type(type);
-
- QTAILQ_INSERT_TAIL(l, e, node);
-}
-
-void module_call_init(module_init_type type)
-{
- ModuleTypeList *l;
- ModuleEntry *e;
-
- l = find_type(type);
-
- QTAILQ_FOREACH(e, l, node) {
- e->init();
- }
-}
diff --git a/contrib/qemu/util/oslib-posix.c b/contrib/qemu/util/oslib-posix.c
deleted file mode 100644
index bac4c1a158e..00000000000
--- a/contrib/qemu/util/oslib-posix.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * os-posix-lib.c
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- * Copyright (c) 2010 Red Hat, Inc.
- *
- * QEMU library functions on POSIX which are shared between QEMU and
- * the QEMU tools.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* The following block of code temporarily renames the daemon() function so the
- compiler does not see the warning associated with it in stdlib.h on OSX */
-#ifdef __APPLE__
-#define daemon qemu_fake_daemon_function
-#include <stdlib.h>
-#undef daemon
-extern int daemon(int, int);
-#endif
-
-#if defined(__linux__) && (defined(__x86_64__) || defined(__arm__))
- /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
- Valgrind does not support alignments larger than 1 MiB,
- therefore we need special code which handles running on Valgrind. */
-# define QEMU_VMALLOC_ALIGN (512 * 4096)
-#elif defined(__linux__) && defined(__s390x__)
- /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */
-# define QEMU_VMALLOC_ALIGN (256 * 4096)
-#else
-# define QEMU_VMALLOC_ALIGN getpagesize()
-#endif
-
-#include <glib/gprintf.h>
-
-#include "config-host.h"
-#include "qemu-common.h"
-#include "sysemu/sysemu.h"
-#include "trace.h"
-#include "qemu/sockets.h"
-#include <sys/mman.h>
-
-#ifdef CONFIG_LINUX
-#include <sys/syscall.h>
-#endif
-
-int qemu_get_thread_id(void)
-{
-#if defined(__linux__)
- return syscall(SYS_gettid);
-#else
- return getpid();
-#endif
-}
-
-int qemu_daemon(int nochdir, int noclose)
-{
- return daemon(nochdir, noclose);
-}
-
-void *qemu_oom_check(void *ptr)
-{
- if (ptr == NULL) {
- fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
- abort();
- }
- return ptr;
-}
-
-void *qemu_memalign(size_t alignment, size_t size)
-{
- void *ptr;
-#if defined(_POSIX_C_SOURCE) && !defined(__sun__) || defined(__APPLE__)
- int ret;
- ret = posix_memalign(&ptr, alignment, size);
- if (ret != 0) {
- fprintf(stderr, "Failed to allocate %zu B: %s\n",
- size, strerror(ret));
- abort();
- }
-#elif defined(GF_BSD_HOST_OS)
- ptr = qemu_oom_check(valloc(size));
-#else
- ptr = qemu_oom_check(memalign(alignment, size));
-#endif
- trace_qemu_memalign(alignment, size, ptr);
- return ptr;
-}
-
-/* alloc shared memory pages */
-void *qemu_anon_ram_alloc(size_t size)
-{
- size_t align = QEMU_VMALLOC_ALIGN;
- size_t total = size + align - getpagesize();
- void *ptr = mmap(0, total, PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- size_t offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr;
-
- if (ptr == MAP_FAILED) {
- fprintf(stderr, "Failed to allocate %zu B: %s\n",
- size, strerror(errno));
- abort();
- }
-
- ptr += offset;
- total -= offset;
-
- if (offset > 0) {
- munmap(ptr - offset, offset);
- }
- if (total > size) {
- munmap(ptr + size, total - size);
- }
-
- trace_qemu_anon_ram_alloc(size, ptr);
- return ptr;
-}
-
-void qemu_vfree(void *ptr)
-{
- trace_qemu_vfree(ptr);
- free(ptr);
-}
-
-void qemu_anon_ram_free(void *ptr, size_t size)
-{
- trace_qemu_anon_ram_free(ptr, size);
- if (ptr) {
- munmap(ptr, size);
- }
-}
-
-void qemu_set_block(int fd)
-{
- int f;
- f = fcntl(fd, F_GETFL);
- fcntl(fd, F_SETFL, f & ~O_NONBLOCK);
-}
-
-void qemu_set_nonblock(int fd)
-{
- int f;
- f = fcntl(fd, F_GETFL);
- fcntl(fd, F_SETFL, f | O_NONBLOCK);
-}
-
-void qemu_set_cloexec(int fd)
-{
- int f;
- f = fcntl(fd, F_GETFD);
- fcntl(fd, F_SETFD, f | FD_CLOEXEC);
-}
-
-/*
- * Creates a pipe with FD_CLOEXEC set on both file descriptors
- */
-int qemu_pipe(int pipefd[2])
-{
- int ret;
-
-#ifdef CONFIG_PIPE2
-#ifdef pipe2
- ret = pipe2(pipefd, O_CLOEXEC);
- if (ret != -1 || errno != ENOSYS) {
- return ret;
- }
-#endif
-#endif
- ret = pipe(pipefd);
- if (ret == 0) {
- qemu_set_cloexec(pipefd[0]);
- qemu_set_cloexec(pipefd[1]);
- }
-
- return ret;
-}
-
-int qemu_utimens(const char *path, const struct timespec *times)
-{
- struct timeval tv[2], tv_now;
- struct stat st;
- int i;
-#if defined(CONFIG_UTIMENSAT)
-#ifdef utimensat
- int ret;
-
- ret = utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW);
- if (ret != -1 || errno != ENOSYS) {
- return ret;
- }
-#endif
-#endif
- /* Fallback: use utimes() instead of utimensat() */
-
- /* happy if special cases */
- if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) {
- return 0;
- }
- if (times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW) {
- return utimes(path, NULL);
- }
-
- /* prepare for hard cases */
- if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) {
- gettimeofday(&tv_now, NULL);
- }
- if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) {
- stat(path, &st);
- }
-
- for (i = 0; i < 2; i++) {
- if (times[i].tv_nsec == UTIME_NOW) {
- tv[i].tv_sec = tv_now.tv_sec;
- tv[i].tv_usec = tv_now.tv_usec;
- } else if (times[i].tv_nsec == UTIME_OMIT) {
- tv[i].tv_sec = (i == 0) ? st.st_atime : st.st_mtime;
- tv[i].tv_usec = 0;
- } else {
- tv[i].tv_sec = times[i].tv_sec;
- tv[i].tv_usec = times[i].tv_nsec / 1000;
- }
- }
-
- return utimes(path, &tv[0]);
-}
-
-char *
-qemu_get_local_state_pathname(const char *relative_pathname)
-{
- return g_strdup_printf("%s/%s", CONFIG_QEMU_LOCALSTATEDIR,
- relative_pathname);
-}
diff --git a/contrib/qemu/util/qemu-error.c b/contrib/qemu/util/qemu-error.c
deleted file mode 100644
index fec02c60754..00000000000
--- a/contrib/qemu/util/qemu-error.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Error reporting
- *
- * Copyright (C) 2010 Red Hat Inc.
- *
- * Authors:
- * Markus Armbruster <armbru@redhat.com>,
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include <stdio.h>
-#include "monitor/monitor.h"
-
-/*
- * Print to current monitor if we have one, else to stderr.
- * TODO should return int, so callers can calculate width, but that
- * requires surgery to monitor_vprintf(). Left for another day.
- */
-void error_vprintf(const char *fmt, va_list ap)
-{
- if (cur_mon) {
- monitor_vprintf(cur_mon, fmt, ap);
- } else {
- vfprintf(stderr, fmt, ap);
- }
-}
-
-/*
- * Print to current monitor if we have one, else to stderr.
- * TODO just like error_vprintf()
- */
-void error_printf(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- error_vprintf(fmt, ap);
- va_end(ap);
-}
-
-void error_printf_unless_qmp(const char *fmt, ...)
-{
- va_list ap;
-
- if (!monitor_cur_is_qmp()) {
- va_start(ap, fmt);
- error_vprintf(fmt, ap);
- va_end(ap);
- }
-}
-
-static Location std_loc = {
- .kind = LOC_NONE
-};
-static Location *cur_loc = &std_loc;
-
-/*
- * Push location saved in LOC onto the location stack, return it.
- * The top of that stack is the current location.
- * Needs a matching loc_pop().
- */
-Location *loc_push_restore(Location *loc)
-{
- assert(!loc->prev);
- loc->prev = cur_loc;
- cur_loc = loc;
- return loc;
-}
-
-/*
- * Initialize *LOC to "nowhere", push it onto the location stack.
- * The top of that stack is the current location.
- * Needs a matching loc_pop().
- * Return LOC.
- */
-Location *loc_push_none(Location *loc)
-{
- loc->kind = LOC_NONE;
- loc->prev = NULL;
- return loc_push_restore(loc);
-}
-
-/*
- * Pop the location stack.
- * LOC must be the current location, i.e. the top of the stack.
- */
-Location *loc_pop(Location *loc)
-{
- assert(cur_loc == loc && loc->prev);
- cur_loc = loc->prev;
- loc->prev = NULL;
- return loc;
-}
-
-/*
- * Save the current location in LOC, return LOC.
- */
-Location *loc_save(Location *loc)
-{
- *loc = *cur_loc;
- loc->prev = NULL;
- return loc;
-}
-
-/*
- * Change the current location to the one saved in LOC.
- */
-void loc_restore(Location *loc)
-{
- Location *prev = cur_loc->prev;
- assert(!loc->prev);
- *cur_loc = *loc;
- cur_loc->prev = prev;
-}
-
-/*
- * Change the current location to "nowhere in particular".
- */
-void loc_set_none(void)
-{
- cur_loc->kind = LOC_NONE;
-}
-
-/*
- * Change the current location to argument ARGV[IDX..IDX+CNT-1].
- */
-void loc_set_cmdline(char **argv, int idx, int cnt)
-{
- cur_loc->kind = LOC_CMDLINE;
- cur_loc->num = cnt;
- cur_loc->ptr = argv + idx;
-}
-
-/*
- * Change the current location to file FNAME, line LNO.
- */
-void loc_set_file(const char *fname, int lno)
-{
- assert (fname || cur_loc->kind == LOC_FILE);
- cur_loc->kind = LOC_FILE;
- cur_loc->num = lno;
- if (fname) {
- cur_loc->ptr = fname;
- }
-}
-
-static const char *progname;
-
-/*
- * Set the program name for error_print_loc().
- */
-void error_set_progname(const char *argv0)
-{
- const char *p = strrchr(argv0, '/');
- progname = p ? p + 1 : argv0;
-}
-
-const char *error_get_progname(void)
-{
- return progname;
-}
-
-/*
- * Print current location to current monitor if we have one, else to stderr.
- */
-void error_print_loc(void)
-{
- const char *sep = "";
- int i;
- const char *const *argp;
-
- if (!cur_mon && progname) {
- fprintf(stderr, "%s:", progname);
- sep = " ";
- }
- switch (cur_loc->kind) {
- case LOC_CMDLINE:
- argp = cur_loc->ptr;
- for (i = 0; i < cur_loc->num; i++) {
- error_printf("%s%s", sep, argp[i]);
- sep = " ";
- }
- error_printf(": ");
- break;
- case LOC_FILE:
- error_printf("%s:", (const char *)cur_loc->ptr);
- if (cur_loc->num) {
- error_printf("%d:", cur_loc->num);
- }
- error_printf(" ");
- break;
- default:
- error_printf("%s", sep);
- }
-}
-
-bool enable_timestamp_msg;
-/*
- * Print an error message to current monitor if we have one, else to stderr.
- * Format arguments like sprintf(). The result should not contain
- * newlines.
- * Prepend the current location and append a newline.
- * It's wrong to call this in a QMP monitor. Use qerror_report() there.
- */
-void error_report(const char *fmt, ...)
-{
- va_list ap;
- GTimeVal tv;
- gchar *timestr;
-
- if (enable_timestamp_msg) {
- g_get_current_time(&tv);
- timestr = g_time_val_to_iso8601(&tv);
- error_printf("%s ", timestr);
- g_free(timestr);
- }
-
- error_print_loc();
- va_start(ap, fmt);
- error_vprintf(fmt, ap);
- va_end(ap);
- error_printf("\n");
-}
diff --git a/contrib/qemu/util/qemu-option.c b/contrib/qemu/util/qemu-option.c
deleted file mode 100644
index e0ef426daa0..00000000000
--- a/contrib/qemu/util/qemu-option.c
+++ /dev/null
@@ -1,1126 +0,0 @@
-/*
- * Commandline option parsing functions
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- * Copyright (c) 2009 Kevin Wolf <kwolf@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "qemu-common.h"
-#include "qemu/error-report.h"
-#include "qapi/qmp/types.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qerror.h"
-#include "qemu/option_int.h"
-
-/*
- * Extracts the name of an option from the parameter string (p points at the
- * first byte of the option name)
- *
- * The option name is delimited by delim (usually , or =) or the string end
- * and is copied into buf. If the option name is longer than buf_size, it is
- * truncated. buf is always zero terminated.
- *
- * The return value is the position of the delimiter/zero byte after the option
- * name in p.
- */
-const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
-{
- char *q;
-
- q = buf;
- while (*p != '\0' && *p != delim) {
- if (q && (q - buf) < buf_size - 1)
- *q++ = *p;
- p++;
- }
- if (q)
- *q = '\0';
-
- return p;
-}
-
-/*
- * Extracts the value of an option from the parameter string p (p points at the
- * first byte of the option value)
- *
- * This function is comparable to get_opt_name with the difference that the
- * delimiter is fixed to be comma which starts a new option. To specify an
- * option value that contains commas, double each comma.
- */
-const char *get_opt_value(char *buf, int buf_size, const char *p)
-{
- char *q;
-
- q = buf;
- while (*p != '\0') {
- if (*p == ',') {
- if (*(p + 1) != ',')
- break;
- p++;
- }
- if (q && (q - buf) < buf_size - 1)
- *q++ = *p;
- p++;
- }
- if (q)
- *q = '\0';
-
- return p;
-}
-
-int get_next_param_value(char *buf, int buf_size,
- const char *tag, const char **pstr)
-{
- const char *p;
- char option[128];
-
- p = *pstr;
- for(;;) {
- p = get_opt_name(option, sizeof(option), p, '=');
- if (*p != '=')
- break;
- p++;
- if (!strcmp(tag, option)) {
- *pstr = get_opt_value(buf, buf_size, p);
- if (**pstr == ',') {
- (*pstr)++;
- }
- return strlen(buf);
- } else {
- p = get_opt_value(NULL, 0, p);
- }
- if (*p != ',')
- break;
- p++;
- }
- return 0;
-}
-
-int get_param_value(char *buf, int buf_size,
- const char *tag, const char *str)
-{
- return get_next_param_value(buf, buf_size, tag, &str);
-}
-
-/*
- * Searches an option list for an option with the given name
- */
-QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
- const char *name)
-{
- while (list && list->name) {
- if (!strcmp(list->name, name)) {
- return list;
- }
- list++;
- }
-
- return NULL;
-}
-
-static void parse_option_bool(const char *name, const char *value, bool *ret,
- Error **errp)
-{
- if (value != NULL) {
- if (!strcmp(value, "on")) {
- *ret = 1;
- } else if (!strcmp(value, "off")) {
- *ret = 0;
- } else {
- error_set(errp,QERR_INVALID_PARAMETER_VALUE, name, "'on' or 'off'");
- }
- } else {
- *ret = 1;
- }
-}
-
-static void parse_option_number(const char *name, const char *value,
- uint64_t *ret, Error **errp)
-{
- char *postfix;
- uint64_t number;
-
- if (value != NULL) {
- number = strtoull(value, &postfix, 0);
- if (*postfix != '\0') {
- error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
- return;
- }
- *ret = number;
- } else {
- error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
- }
-}
-
-static void parse_option_size(const char *name, const char *value,
- uint64_t *ret, Error **errp)
-{
- char *postfix;
- double sizef;
-
- if (value != NULL) {
- sizef = strtod(value, &postfix);
- switch (*postfix) {
- case 'T':
- sizef *= 1024;
- /* fall through */
- case 'G':
- sizef *= 1024;
- /* fall through */
- case 'M':
- sizef *= 1024;
- /* fall through */
- case 'K':
- case 'k':
- sizef *= 1024;
- /* fall through */
- case 'b':
- case '\0':
- *ret = (uint64_t) sizef;
- break;
- default:
- error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size");
-#if 0 /* conversion from qerror_report() to error_set() broke this: */
- error_printf_unless_qmp("You may use k, M, G or T suffixes for "
- "kilobytes, megabytes, gigabytes and terabytes.\n");
-#endif
- return;
- }
- } else {
- error_set(errp, QERR_INVALID_PARAMETER_VALUE, name, "a size");
- }
-}
-
-/*
- * Sets the value of a parameter in a given option list. The parsing of the
- * value depends on the type of option:
- *
- * OPT_FLAG (uses value.n):
- * If no value is given, the flag is set to 1.
- * Otherwise the value must be "on" (set to 1) or "off" (set to 0)
- *
- * OPT_STRING (uses value.s):
- * value is strdup()ed and assigned as option value
- *
- * OPT_SIZE (uses value.n):
- * The value is converted to an integer. Suffixes for kilobytes etc. are
- * allowed (powers of 1024).
- *
- * Returns 0 on succes, -1 in error cases
- */
-int set_option_parameter(QEMUOptionParameter *list, const char *name,
- const char *value)
-{
- bool flag;
- Error *local_err = NULL;
-
- // Find a matching parameter
- list = get_option_parameter(list, name);
- if (list == NULL) {
- fprintf(stderr, "Unknown option '%s'\n", name);
- return -1;
- }
-
- // Process parameter
- switch (list->type) {
- case OPT_FLAG:
- parse_option_bool(name, value, &flag, &local_err);
- if (!error_is_set(&local_err)) {
- list->value.n = flag;
- }
- break;
-
- case OPT_STRING:
- if (value != NULL) {
- list->value.s = g_strdup(value);
- } else {
- fprintf(stderr, "Option '%s' needs a parameter\n", name);
- return -1;
- }
- break;
-
- case OPT_SIZE:
- parse_option_size(name, value, &list->value.n, &local_err);
- break;
-
- default:
- fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name);
- return -1;
- }
-
- if (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Sets the given parameter to an integer instead of a string.
- * This function cannot be used to set string options.
- *
- * Returns 0 on success, -1 in error cases
- */
-int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
- uint64_t value)
-{
- // Find a matching parameter
- list = get_option_parameter(list, name);
- if (list == NULL) {
- fprintf(stderr, "Unknown option '%s'\n", name);
- return -1;
- }
-
- // Process parameter
- switch (list->type) {
- case OPT_FLAG:
- case OPT_NUMBER:
- case OPT_SIZE:
- list->value.n = value;
- break;
-
- default:
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Frees a option list. If it contains strings, the strings are freed as well.
- */
-void free_option_parameters(QEMUOptionParameter *list)
-{
- QEMUOptionParameter *cur = list;
-
- while (cur && cur->name) {
- if (cur->type == OPT_STRING) {
- g_free(cur->value.s);
- }
- cur++;
- }
-
- g_free(list);
-}
-
-/*
- * Count valid options in list
- */
-static size_t count_option_parameters(QEMUOptionParameter *list)
-{
- size_t num_options = 0;
-
- while (list && list->name) {
- num_options++;
- list++;
- }
-
- return num_options;
-}
-
-/*
- * Append an option list (list) to an option list (dest).
- *
- * If dest is NULL, a new copy of list is created.
- *
- * Returns a pointer to the first element of dest (or the newly allocated copy)
- */
-QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
- QEMUOptionParameter *list)
-{
- size_t num_options, num_dest_options;
-
- num_options = count_option_parameters(dest);
- num_dest_options = num_options;
-
- num_options += count_option_parameters(list);
-
- dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
- dest[num_dest_options].name = NULL;
-
- while (list && list->name) {
- if (get_option_parameter(dest, list->name) == NULL) {
- dest[num_dest_options++] = *list;
- dest[num_dest_options].name = NULL;
- }
- list++;
- }
-
- return dest;
-}
-
-/*
- * Parses a parameter string (param) into an option list (dest).
- *
- * list is the template option list. If dest is NULL, a new copy of list is
- * created. If list is NULL, this function fails.
- *
- * A parameter string consists of one or more parameters, separated by commas.
- * Each parameter consists of its name and possibly of a value. In the latter
- * case, the value is delimited by an = character. To specify a value which
- * contains commas, double each comma so it won't be recognized as the end of
- * the parameter.
- *
- * For more details of the parsing see above.
- *
- * Returns a pointer to the first element of dest (or the newly allocated copy)
- * or NULL in error cases
- */
-QEMUOptionParameter *parse_option_parameters(const char *param,
- QEMUOptionParameter *list, QEMUOptionParameter *dest)
-{
- QEMUOptionParameter *allocated = NULL;
- char name[256];
- char value[256];
- char *param_delim, *value_delim;
- char next_delim;
-
- if (list == NULL) {
- return NULL;
- }
-
- if (dest == NULL) {
- dest = allocated = append_option_parameters(NULL, list);
- }
-
- while (*param) {
-
- // Find parameter name and value in the string
- param_delim = strchr(param, ',');
- value_delim = strchr(param, '=');
-
- if (value_delim && (value_delim < param_delim || !param_delim)) {
- next_delim = '=';
- } else {
- next_delim = ',';
- value_delim = NULL;
- }
-
- param = get_opt_name(name, sizeof(name), param, next_delim);
- if (value_delim) {
- param = get_opt_value(value, sizeof(value), param + 1);
- }
- if (*param != '\0') {
- param++;
- }
-
- // Set the parameter
- if (set_option_parameter(dest, name, value_delim ? value : NULL)) {
- goto fail;
- }
- }
-
- return dest;
-
-fail:
- // Only free the list if it was newly allocated
- free_option_parameters(allocated);
- return NULL;
-}
-
-/*
- * Prints all options of a list that have a value to stdout
- */
-void print_option_parameters(QEMUOptionParameter *list)
-{
- while (list && list->name) {
- switch (list->type) {
- case OPT_STRING:
- if (list->value.s != NULL) {
- printf("%s='%s' ", list->name, list->value.s);
- }
- break;
- case OPT_FLAG:
- printf("%s=%s ", list->name, list->value.n ? "on" : "off");
- break;
- case OPT_SIZE:
- case OPT_NUMBER:
- printf("%s=%" PRId64 " ", list->name, list->value.n);
- break;
- default:
- printf("%s=(unknown type) ", list->name);
- break;
- }
- list++;
- }
-}
-
-/*
- * Prints an overview of all available options
- */
-void print_option_help(QEMUOptionParameter *list)
-{
- printf("Supported options:\n");
- while (list && list->name) {
- printf("%-16s %s\n", list->name,
- list->help ? list->help : "No description available");
- list++;
- }
-}
-
-/* ------------------------------------------------------------------ */
-
-static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
-{
- QemuOpt *opt;
-
- QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
- if (strcmp(opt->name, name) != 0)
- continue;
- return opt;
- }
- return NULL;
-}
-
-const char *qemu_opt_get(QemuOpts *opts, const char *name)
-{
- QemuOpt *opt = qemu_opt_find(opts, name);
- return opt ? opt->str : NULL;
-}
-
-bool qemu_opt_has_help_opt(QemuOpts *opts)
-{
- QemuOpt *opt;
-
- QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
- if (is_help_option(opt->name)) {
- return true;
- }
- }
- return false;
-}
-
-bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
-{
- QemuOpt *opt = qemu_opt_find(opts, name);
-
- if (opt == NULL)
- return defval;
- assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
- return opt->value.boolean;
-}
-
-uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval)
-{
- QemuOpt *opt = qemu_opt_find(opts, name);
-
- if (opt == NULL)
- return defval;
- assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
- return opt->value.uint;
-}
-
-uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval)
-{
- QemuOpt *opt = qemu_opt_find(opts, name);
-
- if (opt == NULL)
- return defval;
- assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
- return opt->value.uint;
-}
-
-static void qemu_opt_parse(QemuOpt *opt, Error **errp)
-{
- if (opt->desc == NULL)
- return;
-
- switch (opt->desc->type) {
- case QEMU_OPT_STRING:
- /* nothing */
- return;
- case QEMU_OPT_BOOL:
- parse_option_bool(opt->name, opt->str, &opt->value.boolean, errp);
- break;
- case QEMU_OPT_NUMBER:
- parse_option_number(opt->name, opt->str, &opt->value.uint, errp);
- break;
- case QEMU_OPT_SIZE:
- parse_option_size(opt->name, opt->str, &opt->value.uint, errp);
- break;
- default:
- abort();
- }
-}
-
-static void qemu_opt_del(QemuOpt *opt)
-{
- QTAILQ_REMOVE(&opt->opts->head, opt, next);
- g_free((/* !const */ char*)opt->name);
- g_free((/* !const */ char*)opt->str);
- g_free(opt);
-}
-
-static bool opts_accepts_any(const QemuOpts *opts)
-{
- return opts->list->desc[0].name == NULL;
-}
-
-static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc,
- const char *name)
-{
- int i;
-
- for (i = 0; desc[i].name != NULL; i++) {
- if (strcmp(desc[i].name, name) == 0) {
- return &desc[i];
- }
- }
-
- return NULL;
-}
-
-static void opt_set(QemuOpts *opts, const char *name, const char *value,
- bool prepend, Error **errp)
-{
- QemuOpt *opt;
- const QemuOptDesc *desc;
- Error *local_err = NULL;
-
- desc = find_desc_by_name(opts->list->desc, name);
- if (!desc && !opts_accepts_any(opts)) {
- error_set(errp, QERR_INVALID_PARAMETER, name);
- return;
- }
-
- opt = g_malloc0(sizeof(*opt));
- opt->name = g_strdup(name);
- opt->opts = opts;
- if (prepend) {
- QTAILQ_INSERT_HEAD(&opts->head, opt, next);
- } else {
- QTAILQ_INSERT_TAIL(&opts->head, opt, next);
- }
- opt->desc = desc;
- opt->str = g_strdup(value);
- qemu_opt_parse(opt, &local_err);
- if (error_is_set(&local_err)) {
- error_propagate(errp, local_err);
- qemu_opt_del(opt);
- }
-}
-
-int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
-{
- Error *local_err = NULL;
-
- opt_set(opts, name, value, false, &local_err);
- if (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
- }
-
- return 0;
-}
-
-void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
- Error **errp)
-{
- opt_set(opts, name, value, false, errp);
-}
-
-int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
-{
- QemuOpt *opt;
- const QemuOptDesc *desc = opts->list->desc;
-
- opt = g_malloc0(sizeof(*opt));
- opt->desc = find_desc_by_name(desc, name);
- if (!opt->desc && !opts_accepts_any(opts)) {
- qerror_report(QERR_INVALID_PARAMETER, name);
- g_free(opt);
- return -1;
- }
-
- opt->name = g_strdup(name);
- opt->opts = opts;
- opt->value.boolean = !!val;
- opt->str = g_strdup(val ? "on" : "off");
- QTAILQ_INSERT_TAIL(&opts->head, opt, next);
-
- return 0;
-}
-
-int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
-{
- QemuOpt *opt;
- const QemuOptDesc *desc = opts->list->desc;
-
- opt = g_malloc0(sizeof(*opt));
- opt->desc = find_desc_by_name(desc, name);
- if (!opt->desc && !opts_accepts_any(opts)) {
- qerror_report(QERR_INVALID_PARAMETER, name);
- g_free(opt);
- return -1;
- }
-
- opt->name = g_strdup(name);
- opt->opts = opts;
- opt->value.uint = val;
- opt->str = g_strdup_printf("%" PRId64, val);
- QTAILQ_INSERT_TAIL(&opts->head, opt, next);
-
- return 0;
-}
-
-int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
- int abort_on_failure)
-{
- QemuOpt *opt;
- int rc = 0;
-
- QTAILQ_FOREACH(opt, &opts->head, next) {
- rc = func(opt->name, opt->str, opaque);
- if (abort_on_failure && rc != 0)
- break;
- }
- return rc;
-}
-
-QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
-{
- QemuOpts *opts;
-
- QTAILQ_FOREACH(opts, &list->head, next) {
- if (!opts->id && !id) {
- return opts;
- }
- if (opts->id && id && !strcmp(opts->id, id)) {
- return opts;
- }
- }
- return NULL;
-}
-
-static int id_wellformed(const char *id)
-{
- int i;
-
- if (!qemu_isalpha(id[0])) {
- return 0;
- }
- for (i = 1; id[i]; i++) {
- if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
- return 0;
- }
- }
- return 1;
-}
-
-QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
- int fail_if_exists, Error **errp)
-{
- QemuOpts *opts = NULL;
-
- if (id) {
- if (!id_wellformed(id)) {
- error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
-#if 0 /* conversion from qerror_report() to error_set() broke this: */
- error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n");
-#endif
- return NULL;
- }
- opts = qemu_opts_find(list, id);
- if (opts != NULL) {
- if (fail_if_exists && !list->merge_lists) {
- error_set(errp, QERR_DUPLICATE_ID, id, list->name);
- return NULL;
- } else {
- return opts;
- }
- }
- } else if (list->merge_lists) {
- opts = qemu_opts_find(list, NULL);
- if (opts) {
- return opts;
- }
- }
- opts = g_malloc0(sizeof(*opts));
- opts->id = g_strdup(id);
- opts->list = list;
- loc_save(&opts->loc);
- QTAILQ_INIT(&opts->head);
- QTAILQ_INSERT_TAIL(&list->head, opts, next);
- return opts;
-}
-
-QemuOpts *qemu_opts_create_nofail(QemuOptsList *list)
-{
- QemuOpts *opts;
- Error *errp = NULL;
- opts = qemu_opts_create(list, NULL, 0, &errp);
- assert_no_error(errp);
- return opts;
-}
-
-void qemu_opts_reset(QemuOptsList *list)
-{
- QemuOpts *opts, *next_opts;
-
- QTAILQ_FOREACH_SAFE(opts, &list->head, next, next_opts) {
- qemu_opts_del(opts);
- }
-}
-
-void qemu_opts_loc_restore(QemuOpts *opts)
-{
- loc_restore(&opts->loc);
-}
-
-int qemu_opts_set(QemuOptsList *list, const char *id,
- const char *name, const char *value)
-{
- QemuOpts *opts;
- Error *local_err = NULL;
-
- opts = qemu_opts_create(list, id, 1, &local_err);
- if (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
- }
- return qemu_opt_set(opts, name, value);
-}
-
-const char *qemu_opts_id(QemuOpts *opts)
-{
- return opts->id;
-}
-
-void qemu_opts_del(QemuOpts *opts)
-{
- QemuOpt *opt;
-
- for (;;) {
- opt = QTAILQ_FIRST(&opts->head);
- if (opt == NULL)
- break;
- qemu_opt_del(opt);
- }
- QTAILQ_REMOVE(&opts->list->head, opts, next);
- g_free(opts->id);
- g_free(opts);
-}
-
-int qemu_opts_print(QemuOpts *opts, void *dummy)
-{
- QemuOpt *opt;
-
- fprintf(stderr, "%s: %s:", opts->list->name,
- opts->id ? opts->id : "<noid>");
- QTAILQ_FOREACH(opt, &opts->head, next) {
- fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
- }
- fprintf(stderr, "\n");
- return 0;
-}
-
-static int opts_do_parse(QemuOpts *opts, const char *params,
- const char *firstname, bool prepend)
-{
- char option[128], value[1024];
- const char *p,*pe,*pc;
- Error *local_err = NULL;
-
- for (p = params; *p != '\0'; p++) {
- pe = strchr(p, '=');
- pc = strchr(p, ',');
- if (!pe || (pc && pc < pe)) {
- /* found "foo,more" */
- if (p == params && firstname) {
- /* implicitly named first option */
- pstrcpy(option, sizeof(option), firstname);
- p = get_opt_value(value, sizeof(value), p);
- } else {
- /* option without value, probably a flag */
- p = get_opt_name(option, sizeof(option), p, ',');
- if (strncmp(option, "no", 2) == 0) {
- memmove(option, option+2, strlen(option+2)+1);
- pstrcpy(value, sizeof(value), "off");
- } else {
- pstrcpy(value, sizeof(value), "on");
- }
- }
- } else {
- /* found "foo=bar,more" */
- p = get_opt_name(option, sizeof(option), p, '=');
- if (*p != '=') {
- break;
- }
- p++;
- p = get_opt_value(value, sizeof(value), p);
- }
- if (strcmp(option, "id") != 0) {
- /* store and parse */
- opt_set(opts, option, value, prepend, &local_err);
- if (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
- }
- }
- if (*p != ',') {
- break;
- }
- }
- return 0;
-}
-
-int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)
-{
- return opts_do_parse(opts, params, firstname, false);
-}
-
-static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
- int permit_abbrev, bool defaults)
-{
- const char *firstname;
- char value[1024], *id = NULL;
- const char *p;
- QemuOpts *opts;
- Error *local_err = NULL;
-
- assert(!permit_abbrev || list->implied_opt_name);
- firstname = permit_abbrev ? list->implied_opt_name : NULL;
-
- if (strncmp(params, "id=", 3) == 0) {
- get_opt_value(value, sizeof(value), params+3);
- id = value;
- } else if ((p = strstr(params, ",id=")) != NULL) {
- get_opt_value(value, sizeof(value), p+4);
- id = value;
- }
- opts = qemu_opts_create(list, id, !defaults, &local_err);
- if (opts == NULL) {
- if (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- }
- return NULL;
- }
-
- if (opts_do_parse(opts, params, firstname, defaults) != 0) {
- qemu_opts_del(opts);
- return NULL;
- }
-
- return opts;
-}
-
-QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
- int permit_abbrev)
-{
- return opts_parse(list, params, permit_abbrev, false);
-}
-
-void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
- int permit_abbrev)
-{
- QemuOpts *opts;
-
- opts = opts_parse(list, params, permit_abbrev, true);
- assert(opts);
-}
-
-typedef struct OptsFromQDictState {
- QemuOpts *opts;
- Error **errp;
-} OptsFromQDictState;
-
-static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
-{
- OptsFromQDictState *state = opaque;
- char buf[32];
- const char *value;
- int n;
-
- if (!strcmp(key, "id") || error_is_set(state->errp)) {
- return;
- }
-
- switch (qobject_type(obj)) {
- case QTYPE_QSTRING:
- value = qstring_get_str(qobject_to_qstring(obj));
- break;
- case QTYPE_QINT:
- n = snprintf(buf, sizeof(buf), "%" PRId64,
- qint_get_int(qobject_to_qint(obj)));
- assert(n < sizeof(buf));
- value = buf;
- break;
- case QTYPE_QFLOAT:
- n = snprintf(buf, sizeof(buf), "%.17g",
- qfloat_get_double(qobject_to_qfloat(obj)));
- assert(n < sizeof(buf));
- value = buf;
- break;
- case QTYPE_QBOOL:
- pstrcpy(buf, sizeof(buf),
- qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
- value = buf;
- break;
- default:
- return;
- }
-
- qemu_opt_set_err(state->opts, key, value, state->errp);
-}
-
-/*
- * Create QemuOpts from a QDict.
- * Use value of key "id" as ID if it exists and is a QString.
- * Only QStrings, QInts, QFloats and QBools are copied. Entries with
- * other types are silently ignored.
- */
-QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
- Error **errp)
-{
- OptsFromQDictState state;
- Error *local_err = NULL;
- QemuOpts *opts;
-
- opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1,
- &local_err);
- if (error_is_set(&local_err)) {
- error_propagate(errp, local_err);
- return NULL;
- }
-
- assert(opts != NULL);
-
- state.errp = &local_err;
- state.opts = opts;
- qdict_iter(qdict, qemu_opts_from_qdict_1, &state);
- if (error_is_set(&local_err)) {
- error_propagate(errp, local_err);
- qemu_opts_del(opts);
- return NULL;
- }
-
- return opts;
-}
-
-/*
- * Adds all QDict entries to the QemuOpts that can be added and removes them
- * from the QDict. When this function returns, the QDict contains only those
- * entries that couldn't be added to the QemuOpts.
- */
-void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
-{
- const QDictEntry *entry, *next;
-
- entry = qdict_first(qdict);
-
- while (entry != NULL) {
- Error *local_err = NULL;
- OptsFromQDictState state = {
- .errp = &local_err,
- .opts = opts,
- };
-
- next = qdict_next(qdict, entry);
-
- if (find_desc_by_name(opts->list->desc, entry->key)) {
- qemu_opts_from_qdict_1(entry->key, entry->value, &state);
- if (error_is_set(&local_err)) {
- error_propagate(errp, local_err);
- return;
- } else {
- qdict_del(qdict, entry->key);
- }
- }
-
- entry = next;
- }
-}
-
-/*
- * Convert from QemuOpts to QDict.
- * The QDict values are of type QString.
- * TODO We'll want to use types appropriate for opt->desc->type, but
- * this is enough for now.
- */
-QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
-{
- QemuOpt *opt;
- QObject *val;
-
- if (!qdict) {
- qdict = qdict_new();
- }
- if (opts->id) {
- qdict_put(qdict, "id", qstring_from_str(opts->id));
- }
- QTAILQ_FOREACH(opt, &opts->head, next) {
- val = QOBJECT(qstring_from_str(opt->str));
- qdict_put_obj(qdict, opt->name, val);
- }
- return qdict;
-}
-
-/* Validate parsed opts against descriptions where no
- * descriptions were provided in the QemuOptsList.
- */
-void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
-{
- QemuOpt *opt;
- Error *local_err = NULL;
-
- assert(opts_accepts_any(opts));
-
- QTAILQ_FOREACH(opt, &opts->head, next) {
- opt->desc = find_desc_by_name(desc, opt->name);
- if (!opt->desc) {
- error_set(errp, QERR_INVALID_PARAMETER, opt->name);
- return;
- }
-
- qemu_opt_parse(opt, &local_err);
- if (error_is_set(&local_err)) {
- error_propagate(errp, local_err);
- return;
- }
- }
-}
-
-int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
- int abort_on_failure)
-{
- Location loc;
- QemuOpts *opts;
- int rc = 0;
-
- loc_push_none(&loc);
- QTAILQ_FOREACH(opts, &list->head, next) {
- loc_restore(&opts->loc);
- rc |= func(opts, opaque);
- if (abort_on_failure && rc != 0)
- break;
- }
- loc_pop(&loc);
- return rc;
-}
diff --git a/contrib/qemu/util/qemu-thread-posix.c b/contrib/qemu/util/qemu-thread-posix.c
deleted file mode 100644
index 4489abf1d85..00000000000
--- a/contrib/qemu/util/qemu-thread-posix.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Wrappers around mutex/cond/thread functions
- *
- * Copyright Red Hat, Inc. 2009
- *
- * Author:
- * Marcelo Tosatti <mtosatti@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <time.h>
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
-#include <limits.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include "qemu/thread.h"
-
-static void error_exit(int err, const char *msg)
-{
- fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
- abort();
-}
-
-void qemu_mutex_init(QemuMutex *mutex)
-{
- int err;
- pthread_mutexattr_t mutexattr;
-
- pthread_mutexattr_init(&mutexattr);
- pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
- err = pthread_mutex_init(&mutex->lock, &mutexattr);
- pthread_mutexattr_destroy(&mutexattr);
- if (err)
- error_exit(err, __func__);
-}
-
-void qemu_mutex_destroy(QemuMutex *mutex)
-{
- int err;
-
- err = pthread_mutex_destroy(&mutex->lock);
- if (err)
- error_exit(err, __func__);
-}
-
-void qemu_mutex_lock(QemuMutex *mutex)
-{
- int err;
-
- err = pthread_mutex_lock(&mutex->lock);
- if (err)
- error_exit(err, __func__);
-}
-
-int qemu_mutex_trylock(QemuMutex *mutex)
-{
- return pthread_mutex_trylock(&mutex->lock);
-}
-
-void qemu_mutex_unlock(QemuMutex *mutex)
-{
- int err;
-
- err = pthread_mutex_unlock(&mutex->lock);
- if (err)
- error_exit(err, __func__);
-}
-
-void qemu_cond_init(QemuCond *cond)
-{
- int err;
-
- err = pthread_cond_init(&cond->cond, NULL);
- if (err)
- error_exit(err, __func__);
-}
-
-void qemu_cond_destroy(QemuCond *cond)
-{
- int err;
-
- err = pthread_cond_destroy(&cond->cond);
- if (err)
- error_exit(err, __func__);
-}
-
-void qemu_cond_signal(QemuCond *cond)
-{
- int err;
-
- err = pthread_cond_signal(&cond->cond);
- if (err)
- error_exit(err, __func__);
-}
-
-void qemu_cond_broadcast(QemuCond *cond)
-{
- int err;
-
- err = pthread_cond_broadcast(&cond->cond);
- if (err)
- error_exit(err, __func__);
-}
-
-void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
-{
- int err;
-
- err = pthread_cond_wait(&cond->cond, &mutex->lock);
- if (err)
- error_exit(err, __func__);
-}
-
-void qemu_sem_init(QemuSemaphore *sem, int init)
-{
- int rc;
-
-#if defined(__APPLE__) || defined(__NetBSD__)
- rc = pthread_mutex_init(&sem->lock, NULL);
- if (rc != 0) {
- error_exit(rc, __func__);
- }
- rc = pthread_cond_init(&sem->cond, NULL);
- if (rc != 0) {
- error_exit(rc, __func__);
- }
- if (init < 0) {
- error_exit(EINVAL, __func__);
- }
- sem->count = init;
-#else
- rc = sem_init(&sem->sem, 0, init);
- if (rc < 0) {
- error_exit(errno, __func__);
- }
-#endif
-}
-
-void qemu_sem_destroy(QemuSemaphore *sem)
-{
- int rc;
-
-#if defined(__APPLE__) || defined(__NetBSD__)
- rc = pthread_cond_destroy(&sem->cond);
- if (rc < 0) {
- error_exit(rc, __func__);
- }
- rc = pthread_mutex_destroy(&sem->lock);
- if (rc < 0) {
- error_exit(rc, __func__);
- }
-#else
- rc = sem_destroy(&sem->sem);
- if (rc < 0) {
- error_exit(errno, __func__);
- }
-#endif
-}
-
-void qemu_sem_post(QemuSemaphore *sem)
-{
- int rc;
-
-#if defined(__APPLE__) || defined(__NetBSD__)
- pthread_mutex_lock(&sem->lock);
- if (sem->count == INT_MAX) {
- rc = EINVAL;
- } else if (sem->count++ < 0) {
- rc = pthread_cond_signal(&sem->cond);
- } else {
- rc = 0;
- }
- pthread_mutex_unlock(&sem->lock);
- if (rc != 0) {
- error_exit(rc, __func__);
- }
-#else
- rc = sem_post(&sem->sem);
- if (rc < 0) {
- error_exit(errno, __func__);
- }
-#endif
-}
-
-static void compute_abs_deadline(struct timespec *ts, int ms)
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- ts->tv_nsec = tv.tv_usec * 1000 + (ms % 1000) * 1000000;
- ts->tv_sec = tv.tv_sec + ms / 1000;
- if (ts->tv_nsec >= 1000000000) {
- ts->tv_sec++;
- ts->tv_nsec -= 1000000000;
- }
-}
-
-int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
-{
- int rc;
- struct timespec ts;
-
-#if defined(__APPLE__) || defined(__NetBSD__)
- compute_abs_deadline(&ts, ms);
- pthread_mutex_lock(&sem->lock);
- --sem->count;
- while (sem->count < 0) {
- rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts);
- if (rc == ETIMEDOUT) {
- ++sem->count;
- break;
- }
- if (rc != 0) {
- error_exit(rc, __func__);
- }
- }
- pthread_mutex_unlock(&sem->lock);
- return (rc == ETIMEDOUT ? -1 : 0);
-#else
- if (ms <= 0) {
- /* This is cheaper than sem_timedwait. */
- do {
- rc = sem_trywait(&sem->sem);
- } while (rc == -1 && errno == EINTR);
- if (rc == -1 && errno == EAGAIN) {
- return -1;
- }
- } else {
- compute_abs_deadline(&ts, ms);
- do {
- rc = sem_timedwait(&sem->sem, &ts);
- } while (rc == -1 && errno == EINTR);
- if (rc == -1 && errno == ETIMEDOUT) {
- return -1;
- }
- }
- if (rc < 0) {
- error_exit(errno, __func__);
- }
- return 0;
-#endif
-}
-
-void qemu_sem_wait(QemuSemaphore *sem)
-{
-#if defined(__APPLE__) || defined(__NetBSD__)
- pthread_mutex_lock(&sem->lock);
- --sem->count;
- while (sem->count < 0) {
- pthread_cond_wait(&sem->cond, &sem->lock);
- }
- pthread_mutex_unlock(&sem->lock);
-#else
- int rc;
-
- do {
- rc = sem_wait(&sem->sem);
- } while (rc == -1 && errno == EINTR);
- if (rc < 0) {
- error_exit(errno, __func__);
- }
-#endif
-}
-
-void qemu_thread_create(QemuThread *thread,
- void *(*start_routine)(void*),
- void *arg, int mode)
-{
- sigset_t set, oldset;
- int err;
- pthread_attr_t attr;
-
- err = pthread_attr_init(&attr);
- if (err) {
- error_exit(err, __func__);
- }
- if (mode == QEMU_THREAD_DETACHED) {
- err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (err) {
- error_exit(err, __func__);
- }
- }
-
- /* Leave signal handling to the iothread. */
- sigfillset(&set);
- pthread_sigmask(SIG_SETMASK, &set, &oldset);
- err = pthread_create(&thread->thread, &attr, start_routine, arg);
- if (err)
- error_exit(err, __func__);
-
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
-
- pthread_attr_destroy(&attr);
-}
-
-void qemu_thread_get_self(QemuThread *thread)
-{
- thread->thread = pthread_self();
-}
-
-bool qemu_thread_is_self(QemuThread *thread)
-{
- return pthread_equal(pthread_self(), thread->thread);
-}
-
-void qemu_thread_exit(void *retval)
-{
- pthread_exit(retval);
-}
-
-void *qemu_thread_join(QemuThread *thread)
-{
- int err;
- void *ret;
-
- err = pthread_join(thread->thread, &ret);
- if (err) {
- error_exit(err, __func__);
- }
- return ret;
-}
diff --git a/contrib/qemu/util/unicode.c b/contrib/qemu/util/unicode.c
deleted file mode 100644
index d1c86588505..00000000000
--- a/contrib/qemu/util/unicode.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Dealing with Unicode
- *
- * Copyright (C) 2013 Red Hat, Inc.
- *
- * Authors:
- * Markus Armbruster <armbru@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * later. See the COPYING file in the top-level directory.
- */
-
-#include "qemu-common.h"
-
-/**
- * mod_utf8_codepoint:
- * @s: string encoded in modified UTF-8
- * @n: maximum number of bytes to read from @s, if less than 6
- * @end: set to end of sequence on return
- *
- * Convert the modified UTF-8 sequence at the start of @s. Modified
- * UTF-8 is exactly like UTF-8, except U+0000 is encoded as
- * "\xC0\x80".
- *
- * If @n is zero or @s points to a zero byte, the sequence is invalid,
- * and @end is set to @s.
- *
- * If @s points to an impossible byte (0xFE or 0xFF) or a continuation
- * byte, the sequence is invalid, and @end is set to @s + 1
- *
- * Else, the first byte determines how many continuation bytes are
- * expected. If there are fewer, the sequence is invalid, and @end is
- * set to @s + 1 + actual number of continuation bytes. Else, the
- * sequence is well-formed, and @end is set to @s + 1 + expected
- * number of continuation bytes.
- *
- * A well-formed sequence is valid unless it encodes a codepoint
- * outside the Unicode range U+0000..U+10FFFF, one of Unicode's 66
- * noncharacters, a surrogate codepoint, or is overlong. Except the
- * overlong sequence "\xC0\x80" is valid.
- *
- * Conversion succeeds if and only if the sequence is valid.
- *
- * Returns: the Unicode codepoint on success, -1 on failure.
- */
-int mod_utf8_codepoint(const char *s, size_t n, char **end)
-{
- static int min_cp[5] = { 0x80, 0x800, 0x10000, 0x200000, 0x4000000 };
- const unsigned char *p;
- unsigned byte, mask, len, i;
- int cp;
-
- if (n == 0 || *s == 0) {
- /* empty sequence */
- *end = (char *)s;
- return -1;
- }
-
- p = (const unsigned char *)s;
- byte = *p++;
- if (byte < 0x80) {
- cp = byte; /* one byte sequence */
- } else if (byte >= 0xFE) {
- cp = -1; /* impossible bytes 0xFE, 0xFF */
- } else if ((byte & 0x40) == 0) {
- cp = -1; /* unexpected continuation byte */
- } else {
- /* multi-byte sequence */
- len = 0;
- for (mask = 0x80; byte & mask; mask >>= 1) {
- len++;
- }
- assert(len > 1 && len < 7);
- cp = byte & (mask - 1);
- for (i = 1; i < len; i++) {
- byte = i < n ? *p : 0;
- if ((byte & 0xC0) != 0x80) {
- cp = -1; /* continuation byte missing */
- goto out;
- }
- p++;
- cp <<= 6;
- cp |= byte & 0x3F;
- }
- if (cp > 0x10FFFF) {
- cp = -1; /* beyond Unicode range */
- } else if ((cp >= 0xFDD0 && cp <= 0xFDEF)
- || (cp & 0xFFFE) == 0xFFFE) {
- cp = -1; /* noncharacter */
- } else if (cp >= 0xD800 && cp <= 0xDFFF) {
- cp = -1; /* surrogate code point */
- } else if (cp < min_cp[len - 2] && !(cp == 0 && len == 2)) {
- cp = -1; /* overlong, not \xC0\x80 */
- }
- }
-
-out:
- *end = (char *)p;
- return cp;
-}
diff --git a/contrib/stdlib/gf_mkostemp.c b/contrib/stdlib/gf_mkostemp.c
deleted file mode 100644
index 931249a4520..00000000000
--- a/contrib/stdlib/gf_mkostemp.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* 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/sunrpc/xdr_sizeof.c b/contrib/sunrpc/xdr_sizeof.c
deleted file mode 100644
index ca1f7bf0a5e..00000000000
--- a/contrib/sunrpc/xdr_sizeof.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
- * Reserved. 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 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource 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,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-
-/*
- * xdr_sizeof.c
- *
- * Copyright 1990 Sun Microsystems, Inc.
- *
- * General purpose routine to see how much space something will use
- * when serialized using XDR.
- */
-
-#ifdef GF_DARWIN_HOST_OS
-
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-#include <stdlib.h>
-
-/* ARGSUSED */
-#ifdef GF_DARWIN_HOST_OS
-static bool_t
-x_putlong (XDR *xdrs, const int *longp)
-{
- xdrs->x_handy += BYTES_PER_XDR_UNIT;
- return TRUE;
-}
-
-#else
-static bool_t
-x_putlong (XDR *xdrs, const long *longp)
-{
- xdrs->x_handy += BYTES_PER_XDR_UNIT;
- return TRUE;
-}
-#endif
-
-/* ARGSUSED */
-static bool_t
-x_putbytes (XDR *xdrs, const char *bp, u_int len)
-{
- xdrs->x_handy += len;
- return TRUE;
-}
-
-#ifdef GF_DARWIN_HOST_OS
-static u_int
-x_getpostn (XDR *xdrs)
-{
- return xdrs->x_handy;
-}
-#else
-static u_int
-x_getpostn (const XDR *xdrs)
-{
- return xdrs->x_handy;
-}
-#endif
-
-/* ARGSUSED */
-static bool_t
-x_setpostn (XDR *xdrs, u_int len)
-{
- /* This is not allowed */
- return FALSE;
-}
-
-static int32_t *
-x_inline (XDR *xdrs, u_int len)
-{
- if (len == 0)
- return NULL;
- if (xdrs->x_op != XDR_ENCODE)
- return NULL;
- if (len < (u_int) (long int) xdrs->x_base)
- {
- /* x_private was already allocated */
- xdrs->x_handy += len;
- return (int32_t *) xdrs->x_private;
- }
- else
- {
- /* Free the earlier space and allocate new area */
- free (xdrs->x_private);
- if ((xdrs->x_private = (caddr_t) malloc (len)) == NULL)
- {
- xdrs->x_base = 0;
- return NULL;
- }
- xdrs->x_base = (void *) (long) len;
- xdrs->x_handy += len;
- return (int32_t *) xdrs->x_private;
- }
-}
-
-static int
-harmless (void)
-{
- /* Always return FALSE/NULL, as the case may be */
- return 0;
-}
-
-static void
-x_destroy (XDR *xdrs)
-{
- xdrs->x_handy = 0;
- xdrs->x_base = 0;
- if (xdrs->x_private)
- {
- free (xdrs->x_private);
- xdrs->x_private = NULL;
- }
- return;
-}
-
-unsigned long
-xdr_sizeof (xdrproc_t func, void *data)
-{
- XDR x;
- struct xdr_ops ops;
- bool_t stat;
-
-#ifdef GF_DARWIN_HOST_OS
- typedef bool_t (*dummyfunc1) (XDR *, int *);
-#else
- typedef bool_t (*dummyfunc1) (XDR *, long *);
-#endif
- typedef bool_t (*dummyfunc2) (XDR *, caddr_t, u_int);
-
- ops.x_putlong = x_putlong;
- ops.x_putbytes = x_putbytes;
- ops.x_inline = x_inline;
- ops.x_getpostn = x_getpostn;
- ops.x_setpostn = x_setpostn;
- ops.x_destroy = x_destroy;
-
- /* the other harmless ones */
- ops.x_getlong = (dummyfunc1) harmless;
- ops.x_getbytes = (dummyfunc2) harmless;
-
- x.x_op = XDR_ENCODE;
- x.x_ops = &ops;
- x.x_handy = 0;
- x.x_private = (caddr_t) NULL;
- x.x_base = (caddr_t) 0;
-
- stat = func (&x, data, 0);
- if (x.x_private)
- free (x.x_private);
- return (stat == TRUE ? (unsigned) x.x_handy : 0);
-}
-#endif /* GF_DARWIN_HOST_OS */
diff --git a/contrib/timer-wheel/find_last_bit.c b/contrib/timer-wheel/find_last_bit.c
index 054e90a076f..192fee802a8 100644
--- a/contrib/timer-wheel/find_last_bit.c
+++ b/contrib/timer-wheel/find_last_bit.c
@@ -1,18 +1,20 @@
-/*
- 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.
-*/
+/* bit search implementation
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * Copyright (C) 2008 IBM Corporation
+ * 'find_last_bit' is written by Rusty Russell <rusty@rustcorp.com.au>
+ * (Inspired by David Howell's find_next_bit implementation)
+ *
+ * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease
+ * size and improve performance, 2015.
+ *
+ * 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.
+ */
/**
* @find_last_bit
@@ -20,63 +22,40 @@
*/
#ifndef BITS_PER_LONG
+#ifdef __LP64__
#define BITS_PER_LONG 64
+#else
+#define BITS_PER_LONG 32
+#endif
#endif
-static inline int fls(int x)
-{
- int r = 32;
-
- if (!x)
- return 0;
- if (!(x & 0xffff0000u)) {
- x <<= 16;
- r -= 16;
- }
- if (!(x & 0xff000000u)) {
- x <<= 8;
- r -= 8;
- }
- if (!(x & 0xf0000000u)) {
- x <<= 4;
- r -= 4;
- }
- if (!(x & 0xc0000000u)) {
- x <<= 2;
- r -= 2;
- }
- if (!(x & 0x80000000u)) {
- x <<= 1;
- r -= 1;
- }
- return r;
-}
-
-
-unsigned long gf_tw_find_last_bit(const unsigned long *addr, unsigned long size)
+unsigned long gw_tw_fls (unsigned long word)
{
- unsigned long words;
- unsigned long tmp;
-
- /* Start at final word. */
- words = size / BITS_PER_LONG;
+ int num = BITS_PER_LONG;
- /* Partial final word? */
- if (size & (BITS_PER_LONG-1)) {
- tmp = (addr[words] & (~0UL >> (BITS_PER_LONG
- - (size & (BITS_PER_LONG-1)))));
- if (tmp)
- goto found;
- }
-
- while (words) {
- tmp = addr[--words];
- if (tmp) {
-found:
- return words * BITS_PER_LONG + fls(tmp);
- }
- }
-
- /* Not found */
- return size;
+#if BITS_PER_LONG == 64
+ if (!(word & (~0ul << 32))) {
+ num -= 32;
+ word <<= 32;
+ }
+#endif
+ if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
+ num -= 16;
+ word <<= 16;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
+ num -= 8;
+ word <<= 8;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
+ num -= 4;
+ word <<= 4;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
+ num -= 2;
+ word <<= 2;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-1))))
+ num -= 1;
+ return num;
}
diff --git a/contrib/timer-wheel/timer-wheel.c b/contrib/timer-wheel/timer-wheel.c
index 013c0f278a1..58e0607bf0c 100644
--- a/contrib/timer-wheel/timer-wheel.c
+++ b/contrib/timer-wheel/timer-wheel.c
@@ -1,4 +1,12 @@
/*
+ * linux/kernel/timer.c
+ *
+ * Kernel internal timers
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ */
+/*
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
@@ -57,9 +65,17 @@ __gf_tw_add_timer (struct tvec_base *base, struct gf_tw_timer_list *timer)
list_add_tail (&timer->entry, vec);
}
-/* optimized find_last_bit() */
unsigned long gf_tw_find_last_bit(const unsigned long *, unsigned long);
+#if defined(__GNUC__) || defined(__clang__)
+static inline unsigned long gf_tw_fls (unsigned long word)
+{
+ return BITS_PER_LONG - __builtin_clzl(word);
+}
+#else
+extern unsigned long gf_tw_fls (unsigned long);
+#endif
+
static inline unsigned long
apply_slack(struct tvec_base *base, struct gf_tw_timer_list *timer)
{
@@ -77,7 +93,7 @@ apply_slack(struct tvec_base *base, struct gf_tw_timer_list *timer)
if (mask == 0)
return expires;
- int bit = gf_tw_find_last_bit (&mask, BITS_PER_LONG);
+ int bit = gf_tw_fls (mask);
mask = (1UL << bit) - 1;
expires_limit = expires_limit & ~(mask);
@@ -143,7 +159,14 @@ run_timers (struct tvec_base *base)
data = timer->data;
__gf_tw_detach_timer (timer);
- fn (timer, data, call_time);
+ pthread_spin_unlock(&base->lock);
+ {
+ /* It is required to run the actual function outside
+ of the locked zone, so we don't bother about
+ locked operations inside that function */
+ fn(timer, data, call_time);
+ }
+ pthread_spin_lock(&base->lock);
}
}
pthread_spin_unlock (&base->lock);
diff --git a/contrib/timer-wheel/timer-wheel.h b/contrib/timer-wheel/timer-wheel.h
index baa029ebb30..5637735ec22 100644
--- a/contrib/timer-wheel/timer-wheel.h
+++ b/contrib/timer-wheel/timer-wheel.h
@@ -17,9 +17,9 @@
#ifndef __TIMER_WHEEL_H
#define __TIMER_WHEEL_H
-#include "locking.h"
+#include "glusterfs/locking.h"
-#include "list.h"
+#include "glusterfs/list.h"
#define TVR_BITS 8
#define TVN_BITS 6
diff --git a/contrib/umountd/Makefile.am b/contrib/umountd/Makefile.am
index c03b0cbcae6..b39e000f5aa 100644
--- a/contrib/umountd/Makefile.am
+++ b/contrib/umountd/Makefile.am
@@ -4,7 +4,8 @@ umountd_CFLAGS = $(GF_CFLAGS) -DDATADIR=\"$(localstatedir)\"
umountd_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la ${GF_LDADD}
umountd_LDFLAGS = $(GF_LDFLAGS)
-AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
+AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src
AM_CFLAGS = -Wall $(GF_CFLAGS)
CLEANFILES =
diff --git a/contrib/umountd/umountd.c b/contrib/umountd/umountd.c
index 0d2c6f20b60..3f933ecb554 100644
--- a/contrib/umountd/umountd.c
+++ b/contrib/umountd/umountd.c
@@ -23,11 +23,11 @@
#include <sys/stat.h>
#include <sys/mount.h>
-#include "glusterfs.h"
-#include "globals.h"
-#include "logging.h"
-#include "syscall.h"
-#include "mem-types.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/globals.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/mem-types.h"
static void
usage (void)
@@ -56,7 +56,8 @@ sanity_check (char *path, dev_t *devp)
break;
default:
gf_log ("umountd", GF_LOG_ERROR,
- "Cannot access %s\n", path, strerror (errno));
+ "Cannot access %s: %s\n",
+ path, strerror (errno));
goto out;
}
}
@@ -65,12 +66,13 @@ sanity_check (char *path, dev_t *devp)
if (*devp == -1 && ret == 0)
*devp = st.st_dev;
- strncpy (pathtmp, path, PATH_MAX);
+ snprintf (pathtmp, PATH_MAX, "%s", path);
parent = dirname (pathtmp);
if (stat (parent, &parent_st) != 0) {
gf_log ("umountd", GF_LOG_ERROR,
- "Cannot access %s\n", parent, strerror (errno));
+ "Cannot access %s: %s\n",
+ parent, strerror (errno));
goto out;
}
diff --git a/contrib/userspace-rcu/static-wfcqueue.h b/contrib/userspace-rcu/static-wfcqueue.h
new file mode 100644
index 00000000000..37d14ad674b
--- /dev/null
+++ b/contrib/userspace-rcu/static-wfcqueue.h
@@ -0,0 +1,685 @@
+#ifndef _URCU_WFCQUEUE_STATIC_H
+#define _URCU_WFCQUEUE_STATIC_H
+
+/*
+ * urcu/static/wfcqueue.h
+ *
+ * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue
+ *
+ * TO BE INCLUDED ONLY IN LGPL-COMPATIBLE CODE. See urcu/wfcqueue.h for
+ * linking dynamically with the userspace rcu library.
+ *
+ * Copyright 2010-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright 2011-2012 - Lai Jiangshan <laijs@cn.fujitsu.com>
+ *
+ * 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 2.1 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
+ */
+
+/* Copied from userspace-rcu 0.10 because version 0.7 doesn't contain it. */
+
+#include <pthread.h>
+#include <assert.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <urcu/compiler.h>
+#include <urcu/uatomic.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Concurrent queue with wait-free enqueue/blocking dequeue.
+ *
+ * This queue has been designed and implemented collaboratively by
+ * Mathieu Desnoyers and Lai Jiangshan. Inspired from
+ * half-wait-free/half-blocking queue implementation done by Paul E.
+ * McKenney.
+ *
+ * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API
+ *
+ * Synchronization table:
+ *
+ * External synchronization techniques described in the API below is
+ * required between pairs marked with "X". No external synchronization
+ * required between pairs marked with "-".
+ *
+ * Legend:
+ * [1] cds_wfcq_enqueue
+ * [2] __cds_wfcq_splice (destination queue)
+ * [3] __cds_wfcq_dequeue
+ * [4] __cds_wfcq_splice (source queue)
+ * [5] __cds_wfcq_first
+ * [6] __cds_wfcq_next
+ *
+ * [1] [2] [3] [4] [5] [6]
+ * [1] - - - - - -
+ * [2] - - - - - -
+ * [3] - - X X X X
+ * [4] - - X - X X
+ * [5] - - X X - -
+ * [6] - - X X - -
+ *
+ * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock().
+ *
+ * For convenience, cds_wfcq_dequeue_blocking() and
+ * cds_wfcq_splice_blocking() hold the dequeue lock.
+ *
+ * Besides locking, mutual exclusion of dequeue, splice and iteration
+ * can be ensured by performing all of those operations from a single
+ * thread, without requiring any lock.
+ */
+
+#define WFCQ_ADAPT_ATTEMPTS 10 /* Retry if being set */
+#define WFCQ_WAIT 10 /* Wait 10 ms if being set */
+
+/*
+ * cds_wfcq_node_init: initialize wait-free queue node.
+ */
+static inline void _cds_wfcq_node_init(struct cds_wfcq_node *node)
+{
+ node->next = NULL;
+}
+
+/*
+ * cds_wfcq_init: initialize wait-free queue (with lock). Pair with
+ * cds_wfcq_destroy().
+ */
+static inline void _cds_wfcq_init(struct cds_wfcq_head *head,
+ struct cds_wfcq_tail *tail)
+{
+ int ret;
+
+ /* Set queue head and tail */
+ _cds_wfcq_node_init(&head->node);
+ tail->p = &head->node;
+ ret = pthread_mutex_init(&head->lock, NULL);
+ assert(!ret);
+}
+
+/*
+ * cds_wfcq_destroy: destroy wait-free queue (with lock). Pair with
+ * cds_wfcq_init().
+ */
+static inline void _cds_wfcq_destroy(struct cds_wfcq_head *head,
+ struct cds_wfcq_tail *tail)
+{
+ int ret = pthread_mutex_destroy(&head->lock);
+ assert(!ret);
+}
+
+/*
+ * __cds_wfcq_init: initialize wait-free queue (without lock). Don't
+ * pair with any destroy function.
+ */
+static inline void ___cds_wfcq_init(struct __cds_wfcq_head *head,
+ struct cds_wfcq_tail *tail)
+{
+ /* Set queue head and tail */
+ _cds_wfcq_node_init(&head->node);
+ tail->p = &head->node;
+}
+
+/*
+ * cds_wfcq_empty: return whether wait-free queue is empty.
+ *
+ * No memory barrier is issued. No mutual exclusion is required.
+ *
+ * We perform the test on head->node.next to check if the queue is
+ * possibly empty, but we confirm this by checking if the tail pointer
+ * points to the head node because the tail pointer is the linearisation
+ * point of the enqueuers. Just checking the head next pointer could
+ * make a queue appear empty if an enqueuer is preempted for a long time
+ * between xchg() and setting the previous node's next pointer.
+ */
+static inline bool _cds_wfcq_empty(cds_wfcq_head_ptr_t u_head,
+ struct cds_wfcq_tail *tail)
+{
+ struct __cds_wfcq_head *head = u_head._h;
+ /*
+ * Queue is empty if no node is pointed by head->node.next nor
+ * tail->p. Even though the tail->p check is sufficient to find
+ * out of the queue is empty, we first check head->node.next as a
+ * common case to ensure that dequeuers do not frequently access
+ * enqueuer's tail->p cache line.
+ */
+ return CMM_LOAD_SHARED(head->node.next) == NULL
+ && CMM_LOAD_SHARED(tail->p) == &head->node;
+}
+
+static inline void _cds_wfcq_dequeue_lock(struct cds_wfcq_head *head,
+ struct cds_wfcq_tail *tail)
+{
+ int ret;
+
+ ret = pthread_mutex_lock(&head->lock);
+ assert(!ret);
+}
+
+static inline void _cds_wfcq_dequeue_unlock(struct cds_wfcq_head *head,
+ struct cds_wfcq_tail *tail)
+{
+ int ret;
+
+ ret = pthread_mutex_unlock(&head->lock);
+ assert(!ret);
+}
+
+static inline bool ___cds_wfcq_append(cds_wfcq_head_ptr_t u_head,
+ struct cds_wfcq_tail *tail,
+ struct cds_wfcq_node *new_head,
+ struct cds_wfcq_node *new_tail)
+{
+ struct __cds_wfcq_head *head = u_head._h;
+ struct cds_wfcq_node *old_tail;
+
+ /*
+ * Implicit memory barrier before uatomic_xchg() orders earlier
+ * stores to data structure containing node and setting
+ * node->next to NULL before publication.
+ */
+ old_tail = uatomic_xchg(&tail->p, new_tail);
+
+ /*
+ * Implicit memory barrier after uatomic_xchg() orders store to
+ * q->tail before store to old_tail->next.
+ *
+ * At this point, dequeuers see a NULL tail->p->next, which
+ * indicates that the queue is being appended to. The following
+ * store will append "node" to the queue from a dequeuer
+ * perspective.
+ */
+ CMM_STORE_SHARED(old_tail->next, new_head);
+ /*
+ * Return false if queue was empty prior to adding the node,
+ * else return true.
+ */
+ return old_tail != &head->node;
+}
+
+/*
+ * cds_wfcq_enqueue: enqueue a node into a wait-free queue.
+ *
+ * Issues a full memory barrier before enqueue. No mutual exclusion is
+ * required.
+ *
+ * Returns false if the queue was empty prior to adding the node.
+ * Returns true otherwise.
+ */
+static inline bool _cds_wfcq_enqueue(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail,
+ struct cds_wfcq_node *new_tail)
+{
+ return ___cds_wfcq_append(head, tail, new_tail, new_tail);
+}
+
+/*
+ * CDS_WFCQ_WAIT_SLEEP:
+ *
+ * By default, this sleeps for the given @msec milliseconds.
+ * This is a macro which LGPL users may #define themselves before
+ * including wfcqueue.h to override the default behavior (e.g.
+ * to log a warning or perform other background work).
+ */
+#ifndef CDS_WFCQ_WAIT_SLEEP
+#define CDS_WFCQ_WAIT_SLEEP(msec) ___cds_wfcq_wait_sleep(msec)
+#endif
+
+static inline void ___cds_wfcq_wait_sleep(int msec)
+{
+ (void) poll(NULL, 0, msec);
+}
+
+/*
+ * ___cds_wfcq_busy_wait: adaptative busy-wait.
+ *
+ * Returns 1 if nonblocking and needs to block, 0 otherwise.
+ */
+static inline bool
+___cds_wfcq_busy_wait(int *attempt, int blocking)
+{
+ if (!blocking)
+ return 1;
+ if (++(*attempt) >= WFCQ_ADAPT_ATTEMPTS) {
+ CDS_WFCQ_WAIT_SLEEP(WFCQ_WAIT); /* Wait for 10ms */
+ *attempt = 0;
+ } else {
+ caa_cpu_relax();
+ }
+ return 0;
+}
+
+/*
+ * Waiting for enqueuer to complete enqueue and return the next node.
+ */
+static inline struct cds_wfcq_node *
+___cds_wfcq_node_sync_next(struct cds_wfcq_node *node, int blocking)
+{
+ struct cds_wfcq_node *next;
+ int attempt = 0;
+
+ /*
+ * Adaptative busy-looping waiting for enqueuer to complete enqueue.
+ */
+ while ((next = CMM_LOAD_SHARED(node->next)) == NULL) {
+ if (___cds_wfcq_busy_wait(&attempt, blocking))
+ return CDS_WFCQ_WOULDBLOCK;
+ }
+
+ return next;
+}
+
+static inline struct cds_wfcq_node *
+___cds_wfcq_first(cds_wfcq_head_ptr_t u_head,
+ struct cds_wfcq_tail *tail,
+ int blocking)
+{
+ struct __cds_wfcq_head *head = u_head._h;
+ struct cds_wfcq_node *node;
+
+ if (_cds_wfcq_empty(__cds_wfcq_head_cast(head), tail))
+ return NULL;
+ node = ___cds_wfcq_node_sync_next(&head->node, blocking);
+ /* Load head->node.next before loading node's content */
+ cmm_smp_read_barrier_depends();
+ return node;
+}
+
+/*
+ * __cds_wfcq_first_blocking: get first node of a queue, without dequeuing.
+ *
+ * Content written into the node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ * Dequeue/splice/iteration mutual exclusion should be ensured by the
+ * caller.
+ *
+ * Used by for-like iteration macros in urcu/wfqueue.h:
+ * __cds_wfcq_for_each_blocking()
+ * __cds_wfcq_for_each_blocking_safe()
+ *
+ * Returns NULL if queue is empty, first node otherwise.
+ */
+static inline struct cds_wfcq_node *
+___cds_wfcq_first_blocking(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail)
+{
+ return ___cds_wfcq_first(head, tail, 1);
+}
+
+
+/*
+ * __cds_wfcq_first_nonblocking: get first node of a queue, without dequeuing.
+ *
+ * Same as __cds_wfcq_first_blocking, but returns CDS_WFCQ_WOULDBLOCK if
+ * it needs to block.
+ */
+static inline struct cds_wfcq_node *
+___cds_wfcq_first_nonblocking(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail)
+{
+ return ___cds_wfcq_first(head, tail, 0);
+}
+
+static inline struct cds_wfcq_node *
+___cds_wfcq_next(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail,
+ struct cds_wfcq_node *node,
+ int blocking)
+{
+ struct cds_wfcq_node *next;
+
+ /*
+ * Even though the following tail->p check is sufficient to find
+ * out if we reached the end of the queue, we first check
+ * node->next as a common case to ensure that iteration on nodes
+ * do not frequently access enqueuer's tail->p cache line.
+ */
+ if ((next = CMM_LOAD_SHARED(node->next)) == NULL) {
+ /* Load node->next before tail->p */
+ cmm_smp_rmb();
+ if (CMM_LOAD_SHARED(tail->p) == node)
+ return NULL;
+ next = ___cds_wfcq_node_sync_next(node, blocking);
+ }
+ /* Load node->next before loading next's content */
+ cmm_smp_read_barrier_depends();
+ return next;
+}
+
+/*
+ * __cds_wfcq_next_blocking: get next node of a queue, without dequeuing.
+ *
+ * Content written into the node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ * Dequeue/splice/iteration mutual exclusion should be ensured by the
+ * caller.
+ *
+ * Used by for-like iteration macros in urcu/wfqueue.h:
+ * __cds_wfcq_for_each_blocking()
+ * __cds_wfcq_for_each_blocking_safe()
+ *
+ * Returns NULL if reached end of queue, non-NULL next queue node
+ * otherwise.
+ */
+static inline struct cds_wfcq_node *
+___cds_wfcq_next_blocking(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail,
+ struct cds_wfcq_node *node)
+{
+ return ___cds_wfcq_next(head, tail, node, 1);
+}
+
+/*
+ * __cds_wfcq_next_blocking: get next node of a queue, without dequeuing.
+ *
+ * Same as __cds_wfcq_next_blocking, but returns CDS_WFCQ_WOULDBLOCK if
+ * it needs to block.
+ */
+static inline struct cds_wfcq_node *
+___cds_wfcq_next_nonblocking(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail,
+ struct cds_wfcq_node *node)
+{
+ return ___cds_wfcq_next(head, tail, node, 0);
+}
+
+static inline struct cds_wfcq_node *
+___cds_wfcq_dequeue_with_state(cds_wfcq_head_ptr_t u_head,
+ struct cds_wfcq_tail *tail,
+ int *state,
+ int blocking)
+{
+ struct __cds_wfcq_head *head = u_head._h;
+ struct cds_wfcq_node *node, *next;
+
+ if (state)
+ *state = 0;
+
+ if (_cds_wfcq_empty(__cds_wfcq_head_cast(head), tail)) {
+ return NULL;
+ }
+
+ node = ___cds_wfcq_node_sync_next(&head->node, blocking);
+ if (!blocking && node == CDS_WFCQ_WOULDBLOCK) {
+ return CDS_WFCQ_WOULDBLOCK;
+ }
+
+ if ((next = CMM_LOAD_SHARED(node->next)) == NULL) {
+ /*
+ * @node is probably the only node in the queue.
+ * Try to move the tail to &q->head.
+ * q->head.next is set to NULL here, and stays
+ * NULL if the cmpxchg succeeds. Should the
+ * cmpxchg fail due to a concurrent enqueue, the
+ * q->head.next will be set to the next node.
+ * The implicit memory barrier before
+ * uatomic_cmpxchg() orders load node->next
+ * before loading q->tail.
+ * The implicit memory barrier before uatomic_cmpxchg
+ * orders load q->head.next before loading node's
+ * content.
+ */
+ _cds_wfcq_node_init(&head->node);
+ if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) {
+ if (state)
+ *state |= CDS_WFCQ_STATE_LAST;
+ return node;
+ }
+ next = ___cds_wfcq_node_sync_next(node, blocking);
+ /*
+ * In nonblocking mode, if we would need to block to
+ * get node's next, set the head next node pointer
+ * (currently NULL) back to its original value.
+ */
+ if (!blocking && next == CDS_WFCQ_WOULDBLOCK) {
+ head->node.next = node;
+ return CDS_WFCQ_WOULDBLOCK;
+ }
+ }
+
+ /*
+ * Move queue head forward.
+ */
+ head->node.next = next;
+
+ /* Load q->head.next before loading node's content */
+ cmm_smp_read_barrier_depends();
+ return node;
+}
+
+/*
+ * __cds_wfcq_dequeue_with_state_blocking: dequeue node from queue, with state.
+ *
+ * Content written into the node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ * It is valid to reuse and free a dequeued node immediately.
+ * Dequeue/splice/iteration mutual exclusion should be ensured by the
+ * caller.
+ */
+static inline struct cds_wfcq_node *
+___cds_wfcq_dequeue_with_state_blocking(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail, int *state)
+{
+ return ___cds_wfcq_dequeue_with_state(head, tail, state, 1);
+}
+
+/*
+ * ___cds_wfcq_dequeue_blocking: dequeue node from queue.
+ *
+ * Same as __cds_wfcq_dequeue_with_state_blocking, but without saving
+ * state.
+ */
+static inline struct cds_wfcq_node *
+___cds_wfcq_dequeue_blocking(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail)
+{
+ return ___cds_wfcq_dequeue_with_state_blocking(head, tail, NULL);
+}
+
+/*
+ * __cds_wfcq_dequeue_with_state_nonblocking: dequeue node, with state.
+ *
+ * Same as __cds_wfcq_dequeue_blocking, but returns CDS_WFCQ_WOULDBLOCK
+ * if it needs to block.
+ */
+static inline struct cds_wfcq_node *
+___cds_wfcq_dequeue_with_state_nonblocking(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail, int *state)
+{
+ return ___cds_wfcq_dequeue_with_state(head, tail, state, 0);
+}
+
+/*
+ * ___cds_wfcq_dequeue_nonblocking: dequeue node from queue.
+ *
+ * Same as __cds_wfcq_dequeue_with_state_nonblocking, but without saving
+ * state.
+ */
+static inline struct cds_wfcq_node *
+___cds_wfcq_dequeue_nonblocking(cds_wfcq_head_ptr_t head,
+ struct cds_wfcq_tail *tail)
+{
+ return ___cds_wfcq_dequeue_with_state_nonblocking(head, tail, NULL);
+}
+
+/*
+ * __cds_wfcq_splice: enqueue all src_q nodes at the end of dest_q.
+ *
+ * Dequeue all nodes from src_q.
+ * dest_q must be already initialized.
+ * Mutual exclusion for src_q should be ensured by the caller as
+ * specified in the "Synchronisation table".
+ * Returns enum cds_wfcq_ret which indicates the state of the src or
+ * dest queue.
+ */
+static inline enum cds_wfcq_ret
+___cds_wfcq_splice(
+ cds_wfcq_head_ptr_t u_dest_q_head,
+ struct cds_wfcq_tail *dest_q_tail,
+ cds_wfcq_head_ptr_t u_src_q_head,
+ struct cds_wfcq_tail *src_q_tail,
+ int blocking)
+{
+ struct __cds_wfcq_head *dest_q_head = u_dest_q_head._h;
+ struct __cds_wfcq_head *src_q_head = u_src_q_head._h;
+ struct cds_wfcq_node *head, *tail;
+ int attempt = 0;
+
+ /*
+ * Initial emptiness check to speed up cases where queue is
+ * empty: only require loads to check if queue is empty.
+ */
+ if (_cds_wfcq_empty(__cds_wfcq_head_cast(src_q_head), src_q_tail))
+ return CDS_WFCQ_RET_SRC_EMPTY;
+
+ for (;;) {
+ /*
+ * Open-coded _cds_wfcq_empty() by testing result of
+ * uatomic_xchg, as well as tail pointer vs head node
+ * address.
+ */
+ head = uatomic_xchg(&src_q_head->node.next, NULL);
+ if (head)
+ break; /* non-empty */
+ if (CMM_LOAD_SHARED(src_q_tail->p) == &src_q_head->node)
+ return CDS_WFCQ_RET_SRC_EMPTY;
+ if (___cds_wfcq_busy_wait(&attempt, blocking))
+ return CDS_WFCQ_RET_WOULDBLOCK;
+ }
+
+ /*
+ * Memory barrier implied before uatomic_xchg() orders store to
+ * src_q->head before store to src_q->tail. This is required by
+ * concurrent enqueue on src_q, which exchanges the tail before
+ * updating the previous tail's next pointer.
+ */
+ tail = uatomic_xchg(&src_q_tail->p, &src_q_head->node);
+
+ /*
+ * Append the spliced content of src_q into dest_q. Does not
+ * require mutual exclusion on dest_q (wait-free).
+ */
+ if (___cds_wfcq_append(__cds_wfcq_head_cast(dest_q_head), dest_q_tail,
+ head, tail))
+ return CDS_WFCQ_RET_DEST_NON_EMPTY;
+ else
+ return CDS_WFCQ_RET_DEST_EMPTY;
+}
+
+/*
+ * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q.
+ *
+ * Dequeue all nodes from src_q.
+ * dest_q must be already initialized.
+ * Mutual exclusion for src_q should be ensured by the caller as
+ * specified in the "Synchronisation table".
+ * Returns enum cds_wfcq_ret which indicates the state of the src or
+ * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK.
+ */
+static inline enum cds_wfcq_ret
+___cds_wfcq_splice_blocking(
+ cds_wfcq_head_ptr_t dest_q_head,
+ struct cds_wfcq_tail *dest_q_tail,
+ cds_wfcq_head_ptr_t src_q_head,
+ struct cds_wfcq_tail *src_q_tail)
+{
+ return ___cds_wfcq_splice(dest_q_head, dest_q_tail,
+ src_q_head, src_q_tail, 1);
+}
+
+/*
+ * __cds_wfcq_splice_nonblocking: enqueue all src_q nodes at the end of dest_q.
+ *
+ * Same as __cds_wfcq_splice_blocking, but returns
+ * CDS_WFCQ_RET_WOULDBLOCK if it needs to block.
+ */
+static inline enum cds_wfcq_ret
+___cds_wfcq_splice_nonblocking(
+ cds_wfcq_head_ptr_t dest_q_head,
+ struct cds_wfcq_tail *dest_q_tail,
+ cds_wfcq_head_ptr_t src_q_head,
+ struct cds_wfcq_tail *src_q_tail)
+{
+ return ___cds_wfcq_splice(dest_q_head, dest_q_tail,
+ src_q_head, src_q_tail, 0);
+}
+
+/*
+ * cds_wfcq_dequeue_with_state_blocking: dequeue a node from a wait-free queue.
+ *
+ * Content written into the node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ * Mutual exclusion with cds_wfcq_splice_blocking and dequeue lock is
+ * ensured.
+ * It is valid to reuse and free a dequeued node immediately.
+ */
+static inline struct cds_wfcq_node *
+_cds_wfcq_dequeue_with_state_blocking(struct cds_wfcq_head *head,
+ struct cds_wfcq_tail *tail, int *state)
+{
+ struct cds_wfcq_node *retval;
+
+ _cds_wfcq_dequeue_lock(head, tail);
+ retval = ___cds_wfcq_dequeue_with_state_blocking(cds_wfcq_head_cast(head),
+ tail, state);
+ _cds_wfcq_dequeue_unlock(head, tail);
+ return retval;
+}
+
+/*
+ * cds_wfcq_dequeue_blocking: dequeue node from queue.
+ *
+ * Same as cds_wfcq_dequeue_blocking, but without saving state.
+ */
+static inline struct cds_wfcq_node *
+_cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head,
+ struct cds_wfcq_tail *tail)
+{
+ return _cds_wfcq_dequeue_with_state_blocking(head, tail, NULL);
+}
+
+/*
+ * cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q.
+ *
+ * Dequeue all nodes from src_q.
+ * dest_q must be already initialized.
+ * Content written into the node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ * Mutual exclusion with cds_wfcq_dequeue_blocking and dequeue lock is
+ * ensured.
+ * Returns enum cds_wfcq_ret which indicates the state of the src or
+ * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK.
+ */
+static inline enum cds_wfcq_ret
+_cds_wfcq_splice_blocking(
+ struct cds_wfcq_head *dest_q_head,
+ struct cds_wfcq_tail *dest_q_tail,
+ struct cds_wfcq_head *src_q_head,
+ struct cds_wfcq_tail *src_q_tail)
+{
+ enum cds_wfcq_ret ret;
+
+ _cds_wfcq_dequeue_lock(src_q_head, src_q_tail);
+ ret = ___cds_wfcq_splice_blocking(cds_wfcq_head_cast(dest_q_head), dest_q_tail,
+ cds_wfcq_head_cast(src_q_head), src_q_tail);
+ _cds_wfcq_dequeue_unlock(src_q_head, src_q_tail);
+ return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _URCU_WFCQUEUE_STATIC_H */
diff --git a/contrib/userspace-rcu/static-wfstack.h b/contrib/userspace-rcu/static-wfstack.h
new file mode 100644
index 00000000000..29b81c3aac3
--- /dev/null
+++ b/contrib/userspace-rcu/static-wfstack.h
@@ -0,0 +1,455 @@
+#ifndef _URCU_STATIC_WFSTACK_H
+#define _URCU_STATIC_WFSTACK_H
+
+/*
+ * urcu/static/wfstack.h
+ *
+ * Userspace RCU library - Stack with with wait-free push, blocking traversal.
+ *
+ * TO BE INCLUDED ONLY IN LGPL-COMPATIBLE CODE. See urcu/wfstack.h for
+ * linking dynamically with the userspace rcu library.
+ *
+ * Copyright 2010-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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 2.1 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
+ */
+
+/* Adapted from userspace-rcu 0.10 because version 0.7 doesn't support a stack
+ * without mutex. */
+
+#include <pthread.h>
+#include <assert.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <urcu/compiler.h>
+#include <urcu/uatomic.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CDS_WFS_END ((void *) 0x1UL)
+#define CDS_WFS_ADAPT_ATTEMPTS 10 /* Retry if being set */
+#define CDS_WFS_WAIT 10 /* Wait 10 ms if being set */
+
+/*
+ * Stack with wait-free push, blocking traversal.
+ *
+ * Stack implementing push, pop, pop_all operations, as well as iterator
+ * on the stack head returned by pop_all.
+ *
+ * Wait-free operations: cds_wfs_push, __cds_wfs_pop_all, cds_wfs_empty,
+ * cds_wfs_first.
+ * Blocking operations: cds_wfs_pop, cds_wfs_pop_all, cds_wfs_next,
+ * iteration on stack head returned by pop_all.
+ *
+ * Synchronization table:
+ *
+ * External synchronization techniques described in the API below is
+ * required between pairs marked with "X". No external synchronization
+ * required between pairs marked with "-".
+ *
+ * cds_wfs_push __cds_wfs_pop __cds_wfs_pop_all
+ * cds_wfs_push - - -
+ * __cds_wfs_pop - X X
+ * __cds_wfs_pop_all - X -
+ *
+ * cds_wfs_pop and cds_wfs_pop_all use an internal mutex to provide
+ * synchronization.
+ */
+
+/*
+ * cds_wfs_node_init: initialize wait-free stack node.
+ */
+static inline
+void _cds_wfs_node_init(struct cds_wfs_node *node)
+{
+ node->next = NULL;
+}
+
+/*
+ * __cds_wfs_init: initialize wait-free stack. Don't pair with
+ * any destroy function.
+ */
+static inline void ___cds_wfs_init(struct __cds_wfs_stack *s)
+{
+ s->head = CDS_WFS_END;
+}
+
+/*
+ * cds_wfs_init: initialize wait-free stack. Pair with
+ * cds_wfs_destroy().
+ */
+static inline
+void _cds_wfs_init(struct cds_wfs_stack *s)
+{
+ int ret;
+
+ s->head = CDS_WFS_END;
+ ret = pthread_mutex_init(&s->lock, NULL);
+ assert(!ret);
+}
+
+/*
+ * cds_wfs_destroy: destroy wait-free stack. Pair with
+ * cds_wfs_init().
+ */
+static inline
+void _cds_wfs_destroy(struct cds_wfs_stack *s)
+{
+ int ret = pthread_mutex_destroy(&s->lock);
+ assert(!ret);
+}
+
+static inline bool ___cds_wfs_end(void *node)
+{
+ return node == CDS_WFS_END;
+}
+
+/*
+ * cds_wfs_empty: return whether wait-free stack is empty.
+ *
+ * No memory barrier is issued. No mutual exclusion is required.
+ */
+static inline bool _cds_wfs_empty(cds_wfs_stack_ptr_t u_stack)
+{
+ struct __cds_wfs_stack *s = u_stack._s;
+
+ return ___cds_wfs_end(CMM_LOAD_SHARED(s->head));
+}
+
+/*
+ * cds_wfs_push: push a node into the stack.
+ *
+ * Issues a full memory barrier before push. No mutual exclusion is
+ * required.
+ *
+ * Returns 0 if the stack was empty prior to adding the node.
+ * Returns non-zero otherwise.
+ */
+static inline
+int _cds_wfs_push(cds_wfs_stack_ptr_t u_stack, struct cds_wfs_node *node)
+{
+ struct __cds_wfs_stack *s = u_stack._s;
+ struct cds_wfs_head *old_head, *new_head;
+
+ assert(node->next == NULL);
+ new_head = caa_container_of(node, struct cds_wfs_head, node);
+ /*
+ * uatomic_xchg() implicit memory barrier orders earlier stores
+ * to node (setting it to NULL) before publication.
+ */
+ old_head = uatomic_xchg(&s->head, new_head);
+ /*
+ * At this point, dequeuers see a NULL node->next, they should
+ * busy-wait until node->next is set to old_head.
+ */
+ CMM_STORE_SHARED(node->next, &old_head->node);
+ return !___cds_wfs_end(old_head);
+}
+
+/*
+ * Waiting for push to complete enqueue and return the next node.
+ */
+static inline struct cds_wfs_node *
+___cds_wfs_node_sync_next(struct cds_wfs_node *node, int blocking)
+{
+ struct cds_wfs_node *next;
+ int attempt = 0;
+
+ /*
+ * Adaptative busy-looping waiting for push to complete.
+ */
+ while ((next = CMM_LOAD_SHARED(node->next)) == NULL) {
+ if (!blocking)
+ return CDS_WFS_WOULDBLOCK;
+ if (++attempt >= CDS_WFS_ADAPT_ATTEMPTS) {
+ (void) poll(NULL, 0, CDS_WFS_WAIT); /* Wait for 10ms */
+ attempt = 0;
+ } else {
+ caa_cpu_relax();
+ }
+ }
+
+ return next;
+}
+
+static inline
+struct cds_wfs_node *
+___cds_wfs_pop(cds_wfs_stack_ptr_t u_stack, int *state, int blocking)
+{
+ struct cds_wfs_head *head, *new_head;
+ struct cds_wfs_node *next;
+ struct __cds_wfs_stack *s = u_stack._s;
+
+ if (state)
+ *state = 0;
+ for (;;) {
+ head = CMM_LOAD_SHARED(s->head);
+ if (___cds_wfs_end(head)) {
+ return NULL;
+ }
+ next = ___cds_wfs_node_sync_next(&head->node, blocking);
+ if (!blocking && next == CDS_WFS_WOULDBLOCK) {
+ return CDS_WFS_WOULDBLOCK;
+ }
+ new_head = caa_container_of(next, struct cds_wfs_head, node);
+ if (uatomic_cmpxchg(&s->head, head, new_head) == head) {
+ if (state && ___cds_wfs_end(new_head))
+ *state |= CDS_WFS_STATE_LAST;
+ return &head->node;
+ }
+ if (!blocking) {
+ return CDS_WFS_WOULDBLOCK;
+ }
+ /* busy-loop if head changed under us */
+ }
+}
+
+/*
+ * __cds_wfs_pop_with_state_blocking: pop a node from the stack, with state.
+ *
+ * Returns NULL if stack is empty.
+ *
+ * __cds_wfs_pop_blocking needs to be synchronized using one of the
+ * following techniques:
+ *
+ * 1) Calling __cds_wfs_pop_blocking under rcu read lock critical
+ * section. The caller must wait for a grace period to pass before
+ * freeing the returned node or modifying the cds_wfs_node structure.
+ * 2) Using mutual exclusion (e.g. mutexes) to protect
+ * __cds_wfs_pop_blocking and __cds_wfs_pop_all callers.
+ * 3) Ensuring that only ONE thread can call __cds_wfs_pop_blocking()
+ * and __cds_wfs_pop_all(). (multi-provider/single-consumer scheme).
+ *
+ * "state" saves state flags atomically sampled with pop operation.
+ */
+static inline
+struct cds_wfs_node *
+___cds_wfs_pop_with_state_blocking(cds_wfs_stack_ptr_t u_stack, int *state)
+{
+ return ___cds_wfs_pop(u_stack, state, 1);
+}
+
+static inline
+struct cds_wfs_node *
+___cds_wfs_pop_blocking(cds_wfs_stack_ptr_t u_stack)
+{
+ return ___cds_wfs_pop_with_state_blocking(u_stack, NULL);
+}
+
+/*
+ * __cds_wfs_pop_with_state_nonblocking: pop a node from the stack.
+ *
+ * Same as __cds_wfs_pop_with_state_blocking, but returns
+ * CDS_WFS_WOULDBLOCK if it needs to block.
+ *
+ * "state" saves state flags atomically sampled with pop operation.
+ */
+static inline
+struct cds_wfs_node *
+___cds_wfs_pop_with_state_nonblocking(cds_wfs_stack_ptr_t u_stack, int *state)
+{
+ return ___cds_wfs_pop(u_stack, state, 0);
+}
+
+/*
+ * __cds_wfs_pop_nonblocking: pop a node from the stack.
+ *
+ * Same as __cds_wfs_pop_blocking, but returns CDS_WFS_WOULDBLOCK if
+ * it needs to block.
+ */
+static inline
+struct cds_wfs_node *
+___cds_wfs_pop_nonblocking(cds_wfs_stack_ptr_t u_stack)
+{
+ return ___cds_wfs_pop_with_state_nonblocking(u_stack, NULL);
+}
+
+/*
+ * __cds_wfs_pop_all: pop all nodes from a stack.
+ *
+ * __cds_wfs_pop_all does not require any synchronization with other
+ * push, nor with other __cds_wfs_pop_all, but requires synchronization
+ * matching the technique used to synchronize __cds_wfs_pop_blocking:
+ *
+ * 1) If __cds_wfs_pop_blocking is called under rcu read lock critical
+ * section, both __cds_wfs_pop_blocking and cds_wfs_pop_all callers
+ * must wait for a grace period to pass before freeing the returned
+ * node or modifying the cds_wfs_node structure. However, no RCU
+ * read-side critical section is needed around __cds_wfs_pop_all.
+ * 2) Using mutual exclusion (e.g. mutexes) to protect
+ * __cds_wfs_pop_blocking and __cds_wfs_pop_all callers.
+ * 3) Ensuring that only ONE thread can call __cds_wfs_pop_blocking()
+ * and __cds_wfs_pop_all(). (multi-provider/single-consumer scheme).
+ */
+static inline
+struct cds_wfs_head *
+___cds_wfs_pop_all(cds_wfs_stack_ptr_t u_stack)
+{
+ struct __cds_wfs_stack *s = u_stack._s;
+ struct cds_wfs_head *head;
+
+ /*
+ * Implicit memory barrier after uatomic_xchg() matches implicit
+ * memory barrier before uatomic_xchg() in cds_wfs_push. It
+ * ensures that all nodes of the returned list are consistent.
+ * There is no need to issue memory barriers when iterating on
+ * the returned list, because the full memory barrier issued
+ * prior to each uatomic_cmpxchg, which each write to head, are
+ * taking care to order writes to each node prior to the full
+ * memory barrier after this uatomic_xchg().
+ */
+ head = uatomic_xchg(&s->head, CDS_WFS_END);
+ if (___cds_wfs_end(head))
+ return NULL;
+ return head;
+}
+
+/*
+ * cds_wfs_pop_lock: lock stack pop-protection mutex.
+ */
+static inline void _cds_wfs_pop_lock(struct cds_wfs_stack *s)
+{
+ int ret;
+
+ ret = pthread_mutex_lock(&s->lock);
+ assert(!ret);
+}
+
+/*
+ * cds_wfs_pop_unlock: unlock stack pop-protection mutex.
+ */
+static inline void _cds_wfs_pop_unlock(struct cds_wfs_stack *s)
+{
+ int ret;
+
+ ret = pthread_mutex_unlock(&s->lock);
+ assert(!ret);
+}
+
+/*
+ * Call __cds_wfs_pop_with_state_blocking with an internal pop mutex held.
+ */
+static inline
+struct cds_wfs_node *
+_cds_wfs_pop_with_state_blocking(struct cds_wfs_stack *s, int *state)
+{
+ struct cds_wfs_node *retnode;
+
+ _cds_wfs_pop_lock(s);
+ retnode = ___cds_wfs_pop_with_state_blocking(s, state);
+ _cds_wfs_pop_unlock(s);
+ return retnode;
+}
+
+/*
+ * Call _cds_wfs_pop_with_state_blocking without saving any state.
+ */
+static inline
+struct cds_wfs_node *
+_cds_wfs_pop_blocking(struct cds_wfs_stack *s)
+{
+ return _cds_wfs_pop_with_state_blocking(s, NULL);
+}
+
+/*
+ * Call __cds_wfs_pop_all with an internal pop mutex held.
+ */
+static inline
+struct cds_wfs_head *
+_cds_wfs_pop_all_blocking(struct cds_wfs_stack *s)
+{
+ struct cds_wfs_head *rethead;
+
+ _cds_wfs_pop_lock(s);
+ rethead = ___cds_wfs_pop_all(s);
+ _cds_wfs_pop_unlock(s);
+ return rethead;
+}
+
+/*
+ * cds_wfs_first: get first node of a popped stack.
+ *
+ * Content written into the node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ *
+ * Used by for-like iteration macros in urcu/wfstack.h:
+ * cds_wfs_for_each_blocking()
+ * cds_wfs_for_each_blocking_safe()
+ *
+ * Returns NULL if popped stack is empty, top stack node otherwise.
+ */
+static inline struct cds_wfs_node *
+_cds_wfs_first(struct cds_wfs_head *head)
+{
+ if (___cds_wfs_end(head))
+ return NULL;
+ return &head->node;
+}
+
+static inline struct cds_wfs_node *
+___cds_wfs_next(struct cds_wfs_node *node, int blocking)
+{
+ struct cds_wfs_node *next;
+
+ next = ___cds_wfs_node_sync_next(node, blocking);
+ /*
+ * CDS_WFS_WOULDBLOCK != CSD_WFS_END, so we can check for end
+ * even if ___cds_wfs_node_sync_next returns CDS_WFS_WOULDBLOCK,
+ * and still return CDS_WFS_WOULDBLOCK.
+ */
+ if (___cds_wfs_end(next))
+ return NULL;
+ return next;
+}
+
+/*
+ * cds_wfs_next_blocking: get next node of a popped stack.
+ *
+ * Content written into the node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ *
+ * Used by for-like iteration macros in urcu/wfstack.h:
+ * cds_wfs_for_each_blocking()
+ * cds_wfs_for_each_blocking_safe()
+ *
+ * Returns NULL if reached end of popped stack, non-NULL next stack
+ * node otherwise.
+ */
+static inline struct cds_wfs_node *
+_cds_wfs_next_blocking(struct cds_wfs_node *node)
+{
+ return ___cds_wfs_next(node, 1);
+}
+
+
+/*
+ * cds_wfs_next_nonblocking: get next node of a popped stack.
+ *
+ * Same as cds_wfs_next_blocking, but returns CDS_WFS_WOULDBLOCK if it
+ * needs to block.
+ */
+static inline struct cds_wfs_node *
+_cds_wfs_next_nonblocking(struct cds_wfs_node *node)
+{
+ return ___cds_wfs_next(node, 0);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _URCU_STATIC_WFSTACK_H */
diff --git a/contrib/userspace-rcu/wfcqueue.h b/contrib/userspace-rcu/wfcqueue.h
new file mode 100644
index 00000000000..0292585ac79
--- /dev/null
+++ b/contrib/userspace-rcu/wfcqueue.h
@@ -0,0 +1,216 @@
+#ifndef _URCU_WFCQUEUE_H
+#define _URCU_WFCQUEUE_H
+
+/*
+ * urcu/wfcqueue.h
+ *
+ * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue
+ *
+ * Copyright 2010-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright 2011-2012 - Lai Jiangshan <laijs@cn.fujitsu.com>
+ *
+ * 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 2.1 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
+ */
+
+/* Adapted from userspace-rcu 0.10 because version 0.7 doesn't contain it.
+ * The non-LGPL section has been removed. */
+
+#include <pthread.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <urcu/compiler.h>
+#include <urcu/arch.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Concurrent queue with wait-free enqueue/blocking dequeue.
+ *
+ * This queue has been designed and implemented collaboratively by
+ * Mathieu Desnoyers and Lai Jiangshan. Inspired from
+ * half-wait-free/half-blocking queue implementation done by Paul E.
+ * McKenney.
+ */
+
+#define CDS_WFCQ_WOULDBLOCK ((struct cds_wfcq_node *) -1UL)
+
+enum cds_wfcq_ret {
+ CDS_WFCQ_RET_WOULDBLOCK = -1,
+ CDS_WFCQ_RET_DEST_EMPTY = 0,
+ CDS_WFCQ_RET_DEST_NON_EMPTY = 1,
+ CDS_WFCQ_RET_SRC_EMPTY = 2,
+};
+
+enum cds_wfcq_state {
+ CDS_WFCQ_STATE_LAST = (1U << 0),
+};
+
+struct cds_wfcq_node {
+ struct cds_wfcq_node *next;
+};
+
+/*
+ * Do not put head and tail on the same cache-line if concurrent
+ * enqueue/dequeue are expected from many CPUs. This eliminates
+ * false-sharing between enqueue and dequeue.
+ */
+struct __cds_wfcq_head {
+ struct cds_wfcq_node node;
+};
+
+struct cds_wfcq_head {
+ struct cds_wfcq_node node;
+ pthread_mutex_t lock;
+};
+
+#ifndef __cplusplus
+/*
+ * The transparent union allows calling functions that work on both
+ * struct cds_wfcq_head and struct __cds_wfcq_head on any of those two
+ * types.
+ */
+typedef union {
+ struct __cds_wfcq_head *_h;
+ struct cds_wfcq_head *h;
+} __attribute__((__transparent_union__)) cds_wfcq_head_ptr_t;
+
+/*
+ * This static inline is only present for compatibility with C++. It is
+ * effect-less in C.
+ */
+static inline struct __cds_wfcq_head *__cds_wfcq_head_cast(struct __cds_wfcq_head *head)
+{
+ return head;
+}
+
+/*
+ * This static inline is only present for compatibility with C++. It is
+ * effect-less in C.
+ */
+static inline struct cds_wfcq_head *cds_wfcq_head_cast(struct cds_wfcq_head *head)
+{
+ return head;
+}
+#else /* #ifndef __cplusplus */
+
+/* C++ ignores transparent union. */
+typedef union {
+ struct __cds_wfcq_head *_h;
+ struct cds_wfcq_head *h;
+} cds_wfcq_head_ptr_t;
+
+/* C++ ignores transparent union. Requires an explicit conversion. */
+static inline cds_wfcq_head_ptr_t __cds_wfcq_head_cast(struct __cds_wfcq_head *head)
+{
+ cds_wfcq_head_ptr_t ret = { ._h = head };
+ return ret;
+}
+/* C++ ignores transparent union. Requires an explicit conversion. */
+static inline cds_wfcq_head_ptr_t cds_wfcq_head_cast(struct cds_wfcq_head *head)
+{
+ cds_wfcq_head_ptr_t ret = { .h = head };
+ return ret;
+}
+#endif /* #else #ifndef __cplusplus */
+
+struct cds_wfcq_tail {
+ struct cds_wfcq_node *p;
+};
+
+#include "static-wfcqueue.h"
+
+#define cds_wfcq_node_init _cds_wfcq_node_init
+#define cds_wfcq_init _cds_wfcq_init
+#define __cds_wfcq_init ___cds_wfcq_init
+#define cds_wfcq_destroy _cds_wfcq_destroy
+#define cds_wfcq_empty _cds_wfcq_empty
+#define cds_wfcq_enqueue _cds_wfcq_enqueue
+
+/* Dequeue locking */
+#define cds_wfcq_dequeue_lock _cds_wfcq_dequeue_lock
+#define cds_wfcq_dequeue_unlock _cds_wfcq_dequeue_unlock
+
+/* Locking performed within cds_wfcq calls. */
+#define cds_wfcq_dequeue_blocking _cds_wfcq_dequeue_blocking
+#define cds_wfcq_dequeue_with_state_blocking \
+ _cds_wfcq_dequeue_with_state_blocking
+#define cds_wfcq_splice_blocking _cds_wfcq_splice_blocking
+#define cds_wfcq_first_blocking _cds_wfcq_first_blocking
+#define cds_wfcq_next_blocking _cds_wfcq_next_blocking
+
+/* Locking ensured by caller by holding cds_wfcq_dequeue_lock() */
+#define __cds_wfcq_dequeue_blocking ___cds_wfcq_dequeue_blocking
+#define __cds_wfcq_dequeue_with_state_blocking \
+ ___cds_wfcq_dequeue_with_state_blocking
+#define __cds_wfcq_splice_blocking ___cds_wfcq_splice_blocking
+#define __cds_wfcq_first_blocking ___cds_wfcq_first_blocking
+#define __cds_wfcq_next_blocking ___cds_wfcq_next_blocking
+
+/*
+ * Locking ensured by caller by holding cds_wfcq_dequeue_lock().
+ * Non-blocking: deque, first, next return CDS_WFCQ_WOULDBLOCK if they
+ * need to block. splice returns nonzero if it needs to block.
+ */
+#define __cds_wfcq_dequeue_nonblocking ___cds_wfcq_dequeue_nonblocking
+#define __cds_wfcq_dequeue_with_state_nonblocking \
+ ___cds_wfcq_dequeue_with_state_nonblocking
+#define __cds_wfcq_splice_nonblocking ___cds_wfcq_splice_nonblocking
+#define __cds_wfcq_first_nonblocking ___cds_wfcq_first_nonblocking
+#define __cds_wfcq_next_nonblocking ___cds_wfcq_next_nonblocking
+
+/*
+ * __cds_wfcq_for_each_blocking: Iterate over all nodes in a queue,
+ * without dequeuing them.
+ * @head: head of the queue (struct cds_wfcq_head or __cds_wfcq_head pointer).
+ * @tail: tail of the queue (struct cds_wfcq_tail pointer).
+ * @node: iterator on the queue (struct cds_wfcq_node pointer).
+ *
+ * Content written into each node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ * Dequeue/splice/iteration mutual exclusion should be ensured by the
+ * caller.
+ */
+#define __cds_wfcq_for_each_blocking(head, tail, node) \
+ for (node = __cds_wfcq_first_blocking(head, tail); \
+ node != NULL; \
+ node = __cds_wfcq_next_blocking(head, tail, node))
+
+/*
+ * __cds_wfcq_for_each_blocking_safe: Iterate over all nodes in a queue,
+ * without dequeuing them. Safe against deletion.
+ * @head: head of the queue (struct cds_wfcq_head or __cds_wfcq_head pointer).
+ * @tail: tail of the queue (struct cds_wfcq_tail pointer).
+ * @node: iterator on the queue (struct cds_wfcq_node pointer).
+ * @n: struct cds_wfcq_node pointer holding the next pointer (used
+ * internally).
+ *
+ * Content written into each node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ * Dequeue/splice/iteration mutual exclusion should be ensured by the
+ * caller.
+ */
+#define __cds_wfcq_for_each_blocking_safe(head, tail, node, n) \
+ for (node = __cds_wfcq_first_blocking(head, tail), \
+ n = (node ? __cds_wfcq_next_blocking(head, tail, node) : NULL); \
+ node != NULL; \
+ node = n, n = (node ? __cds_wfcq_next_blocking(head, tail, node) : NULL))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _URCU_WFCQUEUE_H */
diff --git a/contrib/userspace-rcu/wfstack.h b/contrib/userspace-rcu/wfstack.h
new file mode 100644
index 00000000000..738fd1cfd33
--- /dev/null
+++ b/contrib/userspace-rcu/wfstack.h
@@ -0,0 +1,178 @@
+#ifndef _URCU_WFSTACK_H
+#define _URCU_WFSTACK_H
+
+/*
+ * urcu/wfstack.h
+ *
+ * Userspace RCU library - Stack with wait-free push, blocking traversal.
+ *
+ * Copyright 2010-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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 2.1 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
+ */
+
+/* Adapted from userspace-rcu 0.10 because version 0.7 doesn't support a stack
+ * without mutex. The non-LGPL section has been removed. */
+
+#include <pthread.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <urcu/compiler.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Stack with wait-free push, blocking traversal.
+ *
+ * Stack implementing push, pop, pop_all operations, as well as iterator
+ * on the stack head returned by pop_all.
+ *
+ * Wait-free operations: cds_wfs_push, __cds_wfs_pop_all, cds_wfs_empty,
+ * cds_wfs_first.
+ * Blocking operations: cds_wfs_pop, cds_wfs_pop_all, cds_wfs_next,
+ * iteration on stack head returned by pop_all.
+ *
+ * Synchronization table:
+ *
+ * External synchronization techniques described in the API below is
+ * required between pairs marked with "X". No external synchronization
+ * required between pairs marked with "-".
+ *
+ * cds_wfs_push __cds_wfs_pop __cds_wfs_pop_all
+ * cds_wfs_push - - -
+ * __cds_wfs_pop - X X
+ * __cds_wfs_pop_all - X -
+ *
+ * cds_wfs_pop and cds_wfs_pop_all use an internal mutex to provide
+ * synchronization.
+ */
+
+#define CDS_WFS_WOULDBLOCK ((void *) -1UL)
+
+enum cds_wfs_state {
+ CDS_WFS_STATE_LAST = (1U << 0),
+};
+
+/*
+ * struct cds_wfs_node is returned by __cds_wfs_pop, and also used as
+ * iterator on stack. It is not safe to dereference the node next
+ * pointer when returned by __cds_wfs_pop_blocking.
+ */
+struct cds_wfs_node {
+ struct cds_wfs_node *next;
+};
+
+/*
+ * struct cds_wfs_head is returned by __cds_wfs_pop_all, and can be used
+ * to begin iteration on the stack. "node" needs to be the first field of
+ * cds_wfs_head, so the end-of-stack pointer value can be used for both
+ * types.
+ */
+struct cds_wfs_head {
+ struct cds_wfs_node node;
+};
+
+struct __cds_wfs_stack {
+ struct cds_wfs_head *head;
+};
+
+struct cds_wfs_stack {
+ struct cds_wfs_head *head;
+ pthread_mutex_t lock;
+};
+
+/*
+ * The transparent union allows calling functions that work on both
+ * struct cds_wfs_stack and struct __cds_wfs_stack on any of those two
+ * types.
+ */
+typedef union {
+ struct __cds_wfs_stack *_s;
+ struct cds_wfs_stack *s;
+} __attribute__((__transparent_union__)) cds_wfs_stack_ptr_t;
+
+#include "static-wfstack.h"
+
+#define cds_wfs_node_init _cds_wfs_node_init
+#define cds_wfs_init _cds_wfs_init
+#define cds_wfs_destroy _cds_wfs_destroy
+#define __cds_wfs_init ___cds_wfs_init
+#define cds_wfs_empty _cds_wfs_empty
+#define cds_wfs_push _cds_wfs_push
+
+/* Locking performed internally */
+#define cds_wfs_pop_blocking _cds_wfs_pop_blocking
+#define cds_wfs_pop_with_state_blocking _cds_wfs_pop_with_state_blocking
+#define cds_wfs_pop_all_blocking _cds_wfs_pop_all_blocking
+
+/*
+ * For iteration on cds_wfs_head returned by __cds_wfs_pop_all or
+ * cds_wfs_pop_all_blocking.
+ */
+#define cds_wfs_first _cds_wfs_first
+#define cds_wfs_next_blocking _cds_wfs_next_blocking
+#define cds_wfs_next_nonblocking _cds_wfs_next_nonblocking
+
+/* Pop locking with internal mutex */
+#define cds_wfs_pop_lock _cds_wfs_pop_lock
+#define cds_wfs_pop_unlock _cds_wfs_pop_unlock
+
+/* Synchronization ensured by the caller. See synchronization table. */
+#define __cds_wfs_pop_blocking ___cds_wfs_pop_blocking
+#define __cds_wfs_pop_with_state_blocking \
+ ___cds_wfs_pop_with_state_blocking
+#define __cds_wfs_pop_nonblocking ___cds_wfs_pop_nonblocking
+#define __cds_wfs_pop_with_state_nonblocking \
+ ___cds_wfs_pop_with_state_nonblocking
+#define __cds_wfs_pop_all ___cds_wfs_pop_all
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * cds_wfs_for_each_blocking: Iterate over all nodes returned by
+ * __cds_wfs_pop_all().
+ * @head: head of the queue (struct cds_wfs_head pointer).
+ * @node: iterator (struct cds_wfs_node pointer).
+ *
+ * Content written into each node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ */
+#define cds_wfs_for_each_blocking(head, node) \
+ for (node = cds_wfs_first(head); \
+ node != NULL; \
+ node = cds_wfs_next_blocking(node))
+
+/*
+ * cds_wfs_for_each_blocking_safe: Iterate over all nodes returned by
+ * __cds_wfs_pop_all(). Safe against deletion.
+ * @head: head of the queue (struct cds_wfs_head pointer).
+ * @node: iterator (struct cds_wfs_node pointer).
+ * @n: struct cds_wfs_node pointer holding the next pointer (used
+ * internally).
+ *
+ * Content written into each node before enqueue is guaranteed to be
+ * consistent, but no other memory ordering is ensured.
+ */
+#define cds_wfs_for_each_blocking_safe(head, node, n) \
+ for (node = cds_wfs_first(head), \
+ n = (node ? cds_wfs_next_blocking(node) : NULL); \
+ node != NULL; \
+ node = n, n = (node ? cds_wfs_next_blocking(node) : NULL))
+
+#endif /* _URCU_WFSTACK_H */
diff --git a/contrib/uuid/clear.c b/contrib/uuid/clear.c
deleted file mode 100644
index 0362d073e3d..00000000000
--- a/contrib/uuid/clear.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * clear.c -- Clear a UUID
- *
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#include "string.h"
-
-#include "uuidP.h"
-
-void gf_uuid_clear(uuid_t uu)
-{
- memset(uu, 0, 16);
-}
-
diff --git a/contrib/uuid/compare.c b/contrib/uuid/compare.c
deleted file mode 100644
index dba4c5bf8cf..00000000000
--- a/contrib/uuid/compare.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * compare.c --- compare whether or not two UUID's are the same
- *
- * Returns 0 if the two UUID's are different, and 1 if they are the same.
- *
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#include "uuidP.h"
-#include <string.h>
-
-#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1);
-
-int gf_uuid_compare(const uuid_t uu1, const uuid_t uu2)
-{
- struct uuid uuid1, uuid2;
-
- uuid_unpack(uu1, &uuid1);
- uuid_unpack(uu2, &uuid2);
-
- UUCMP(uuid1.time_low, uuid2.time_low);
- UUCMP(uuid1.time_mid, uuid2.time_mid);
- UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version);
- UUCMP(uuid1.clock_seq, uuid2.clock_seq);
- return memcmp(uuid1.node, uuid2.node, 6);
-}
-
diff --git a/contrib/uuid/copy.c b/contrib/uuid/copy.c
deleted file mode 100644
index 45983bfd48b..00000000000
--- a/contrib/uuid/copy.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * copy.c --- copy UUIDs
- *
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#include "uuidP.h"
-
-void gf_uuid_copy(uuid_t dst, const uuid_t src)
-{
- unsigned char *cp1;
- const unsigned char *cp2;
- int i;
-
- for (i=0, cp1 = dst, cp2 = src; i < 16; i++)
- *cp1++ = *cp2++;
-}
diff --git a/contrib/uuid/gen_uuid.c b/contrib/uuid/gen_uuid.c
deleted file mode 100644
index 1ec156f76ff..00000000000
--- a/contrib/uuid/gen_uuid.c
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * gen_uuid.c --- generate a DCE-compatible uuid
- *
- * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-/*
- * Force inclusion of SVID stuff since we need it if we're compiling in
- * gcc-wall wall mode
- */
-#define _SVID_SOURCE
-
-#include "config.h"
-#ifdef _WIN32
-#define _WIN32_WINNT 0x0500
-#include <windows.h>
-#define UUID MYUUID
-#endif
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <sys/wait.h>
-#include <sys/stat.h>
-#ifdef HAVE_SYS_FILE_H
-#include <sys/file.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-#ifdef HAVE_NET_IF_H
-#include <net/if.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_NET_IF_DL_H
-#include <net/if_dl.h>
-#endif
-#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
-#include <sys/syscall.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-#include <limits.h>
-
-#include "uuidP.h"
-#include "uuidd.h"
-
-#ifdef HAVE_SRANDOM
-#define srand(x) srandom(x)
-#define rand() random()
-#endif
-
-#ifdef TLS
-#define THREAD_LOCAL static TLS
-#else
-#define THREAD_LOCAL static
-#endif
-
-#if defined(__linux__) && defined(__NR_gettid) && defined(HAVE_JRAND48)
-#define DO_JRAND_MIX
-THREAD_LOCAL unsigned short jrand_seed[3];
-#endif
-
-#ifndef OPEN_MAX
-#define OPEN_MAX 1024
-#endif
-
-#ifdef _WIN32
-static void gettimeofday (struct timeval *tv, void *dummy)
-{
- FILETIME ftime;
- uint64_t n;
-
- GetSystemTimeAsFileTime (&ftime);
- n = (((uint64_t) ftime.dwHighDateTime << 32)
- + (uint64_t) ftime.dwLowDateTime);
- if (n) {
- n /= 10;
- n -= ((369 * 365 + 89) * (uint64_t) 86400) * 1000000;
- }
-
- tv->tv_sec = n / 1000000;
- tv->tv_usec = n % 1000000;
-}
-
-static int getuid (void)
-{
- return 1;
-}
-#endif
-
-static int get_random_fd(void)
-{
- struct timeval tv;
- static int fd = -2;
- int i;
-
- if (fd == -2) {
- gettimeofday(&tv, 0);
-#ifndef _WIN32
- fd = open("/dev/urandom", O_RDONLY);
- if (fd == -1)
- fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
- if (fd >= 0) {
- i = fcntl(fd, F_GETFD);
- if (i >= 0)
- fcntl(fd, F_SETFD, i | FD_CLOEXEC);
- }
-#endif
- srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
-#ifdef DO_JRAND_MIX
- jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF);
- jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF);
- jrand_seed[2] = (tv.tv_sec ^ tv.tv_usec) >> 16;
-#endif
- }
- /* Crank the random number generator a few times */
- gettimeofday(&tv, 0);
- for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
- rand();
- return fd;
-}
-
-
-/*
- * Generate a series of random bytes. Use /dev/urandom if possible,
- * and if not, use srandom/random.
- */
-static void get_random_bytes(void *buf, int nbytes)
-{
- int i, n = nbytes, fd = get_random_fd();
- int lose_counter = 0;
- unsigned char *cp = (unsigned char *) buf;
-#ifdef DO_JRAND_MIX
- unsigned short tmp_seed[3];
-#endif
- if (fd >= 0) {
- while (n > 0) {
- i = read(fd, cp, n);
- if (i <= 0) {
- if (lose_counter++ > 16)
- break;
- continue;
- }
- n -= i;
- cp += i;
- lose_counter = 0;
- }
- }
-
- /*
- * We do this all the time, but this is the only source of
- * randomness if /dev/random/urandom is out to lunch.
- */
- for (cp = buf, i = 0; i < nbytes; i++)
- *cp++ ^= (rand() >> 7) & 0xFF;
-#ifdef DO_JRAND_MIX
- memcpy(tmp_seed, jrand_seed, sizeof(tmp_seed));
- jrand_seed[2] = jrand_seed[2] ^ syscall(__NR_gettid);
- for (cp = buf, i = 0; i < nbytes; i++)
- *cp++ ^= (jrand48(tmp_seed) >> 7) & 0xFF;
- memcpy(jrand_seed, tmp_seed,
- sizeof(jrand_seed)-sizeof(unsigned short));
-#endif
-
- return;
-}
-
-/*
- * Get the ethernet hardware address, if we can find it...
- *
- * XXX for a windows version, probably should use GetAdaptersInfo:
- * http://www.codeguru.com/cpp/i-n/network/networkinformation/article.php/c5451
- * commenting out get_node_id just to get gen_uuid to compile under windows
- * is not the right way to go!
- */
-static int get_node_id(unsigned char *node_id)
-{
-#ifdef HAVE_NET_IF_H
- int sd;
- struct ifreq ifr, *ifrp;
- struct ifconf ifc;
- char buf[1024];
- int n, i;
- unsigned char *a;
-#ifdef HAVE_NET_IF_DL_H
- struct sockaddr_dl *sdlp;
-#endif
-
-/*
- * BSD 4.4 defines the size of an ifreq to be
- * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
- * However, under earlier systems, sa_len isn't present, so the size is
- * just sizeof(struct ifreq)
- */
-#ifdef HAVE_SA_LEN
-#ifndef max
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#endif
-#define ifreq_size(i) max(sizeof(struct ifreq),\
- sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
-#else
-#define ifreq_size(i) sizeof(struct ifreq)
-#endif /* HAVE_SA_LEN*/
-
- sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
- if (sd < 0) {
- return -1;
- }
- memset(buf, 0, sizeof(buf));
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
- if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
- close(sd);
- return -1;
- }
- n = ifc.ifc_len;
- for (i = 0; i < n; i+= ifreq_size(*ifrp) ) {
- ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
- strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
-#ifdef SIOCGIFHWADDR
- if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
- continue;
- a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
-#else
-#ifdef SIOCGENADDR
- if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
- continue;
- a = (unsigned char *) ifr.ifr_enaddr;
-#else
-#ifdef HAVE_NET_IF_DL_H
- sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr;
- if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))
- continue;
- a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen];
-#else
- /*
- * XXX we don't have a way of getting the hardware
- * address
- */
- close(sd);
- return 0;
-#endif /* HAVE_NET_IF_DL_H */
-#endif /* SIOCGENADDR */
-#endif /* SIOCGIFHWADDR */
- if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
- continue;
- if (node_id) {
- memcpy(node_id, a, 6);
- close(sd);
- return 1;
- }
- }
- close(sd);
-#endif
- return 0;
-}
-
-/* Assume that the gettimeofday() has microsecond granularity */
-#define MAX_ADJUSTMENT 10
-
-static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
- uint16_t *ret_clock_seq, int *num)
-{
- THREAD_LOCAL int adjustment = 0;
- THREAD_LOCAL struct timeval last = {0, 0};
- THREAD_LOCAL int state_fd = -2;
- THREAD_LOCAL FILE *state_f;
- THREAD_LOCAL uint16_t clock_seq;
- struct timeval tv;
- struct flock fl;
- uint64_t clock_reg;
- mode_t save_umask;
- int len;
-
- if (state_fd == -2) {
- save_umask = umask(0);
- state_fd = open("/var/lib/libuuid/clock.txt",
- O_RDWR|O_CREAT, 0660);
- (void) umask(save_umask);
- state_f = fdopen(state_fd, "r+");
- if (!state_f) {
- close(state_fd);
- state_fd = -1;
- }
- }
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
- fl.l_pid = 0;
- if (state_fd >= 0) {
- rewind(state_f);
- while (fcntl(state_fd, F_SETLKW, &fl) < 0) {
- if ((errno == EAGAIN) || (errno == EINTR))
- continue;
- fclose(state_f);
- close(state_fd);
- state_fd = -1;
- break;
- }
- }
- if (state_fd >= 0) {
- unsigned int cl;
- unsigned long tv1, tv2;
- int a;
-
- if (fscanf(state_f, "clock: %04x tv: %lu %lu adj: %d\n",
- &cl, &tv1, &tv2, &a) == 4) {
- clock_seq = cl & 0x3FFF;
- last.tv_sec = tv1;
- last.tv_usec = tv2;
- adjustment = a;
- }
- }
-
- if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
- get_random_bytes(&clock_seq, sizeof(clock_seq));
- clock_seq &= 0x3FFF;
- gettimeofday(&last, 0);
- last.tv_sec--;
- }
-
-try_again:
- gettimeofday(&tv, 0);
- if ((tv.tv_sec < last.tv_sec) ||
- ((tv.tv_sec == last.tv_sec) &&
- (tv.tv_usec < last.tv_usec))) {
- clock_seq = (clock_seq+1) & 0x3FFF;
- adjustment = 0;
- last = tv;
- } else if ((tv.tv_sec == last.tv_sec) &&
- (tv.tv_usec == last.tv_usec)) {
- if (adjustment >= MAX_ADJUSTMENT)
- goto try_again;
- adjustment++;
- } else {
- adjustment = 0;
- last = tv;
- }
-
- clock_reg = tv.tv_usec*10 + adjustment;
- clock_reg += ((uint64_t) tv.tv_sec)*10000000;
- clock_reg += (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
-
- if (num && (*num > 1)) {
- adjustment += *num - 1;
- last.tv_usec += adjustment / 10;
- adjustment = adjustment % 10;
- last.tv_sec += last.tv_usec / 1000000;
- last.tv_usec = last.tv_usec % 1000000;
- }
-
- if (state_fd > 0) {
- rewind(state_f);
- len = fprintf(state_f,
- "clock: %04x tv: %016lu %08lu adj: %08d\n",
- clock_seq, last.tv_sec, last.tv_usec, adjustment);
- fflush(state_f);
- if (ftruncate(state_fd, len) < 0) {
- fprintf(state_f, " \n");
- fflush(state_f);
- }
- rewind(state_f);
- fl.l_type = F_UNLCK;
- fcntl(state_fd, F_SETLK, &fl);
- }
-
- *clock_high = clock_reg >> 32;
- *clock_low = clock_reg;
- *ret_clock_seq = clock_seq;
- return 0;
-}
-
-#if defined(USE_UUIDD) && defined(HAVE_SYS_UN_H)
-static ssize_t read_all(int fd, char *buf, size_t count)
-{
- ssize_t ret;
- ssize_t c = 0;
- int tries = 0;
-
- memset(buf, 0, count);
- while (count > 0) {
- ret = read(fd, buf, count);
- if (ret <= 0) {
- if ((errno == EAGAIN || errno == EINTR || ret == 0) &&
- (tries++ < 5))
- continue;
- return c ? c : -1;
- }
- if (ret > 0)
- tries = 0;
- count -= ret;
- buf += ret;
- c += ret;
- }
- return c;
-}
-#endif
-
-/*
- * Close all file descriptors
- */
-#if defined(USE_UUIDD) && defined(HAVE_SYS_UN_H)
-static void close_all_fds(void)
-{
-#ifdef F_CLOSEM
- (void)fcntl(0, F_CLOSEM);
- (void)open("/dev/null", O_RDWR); /* stdin */
- (void)open("/dev/null", O_RDWR); /* stdout */
- (void)open("/dev/null", O_RDWR); /* stderr */
-#else /* F_CLOSEM */
- int i, max;
-
-#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
- max = sysconf(_SC_OPEN_MAX);
-#elif defined(HAVE_GETDTABLESIZE)
- max = getdtablesize();
-#elif defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
- struct rlimit rl;
-
- getrlimit(RLIMIT_NOFILE, &rl);
- max = rl.rlim_cur;
-#else
- max = OPEN_MAX;
-#endif
-
- for (i=0; i < max; i++) {
- close(i);
- if (i <= 2)
- open("/dev/null", O_RDWR);
- }
-#endif /* F_CLOSEM */
-}
-#endif
-
-
-/*
- * Try using the uuidd daemon to generate the UUID
- *
- * Returns 0 on success, non-zero on failure.
- */
-static int get_uuid_via_daemon(int op, uuid_t out, int *num)
-{
-#if defined(USE_UUIDD) && defined(HAVE_SYS_UN_H)
- char op_buf[64];
- int op_len;
- int s;
- ssize_t ret;
- int32_t reply_len = 0, expected = 16;
- struct sockaddr_un srv_addr;
- struct stat st;
- pid_t pid;
- static const char *uuidd_path = UUIDD_PATH;
- static int access_ret = -2;
- static int start_attempts = 0;
-
- if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
- return -1;
-
- srv_addr.sun_family = AF_UNIX;
- strcpy(srv_addr.sun_path, UUIDD_SOCKET_PATH);
-
- if (connect(s, (const struct sockaddr *) &srv_addr,
- sizeof(struct sockaddr_un)) < 0) {
- if (access_ret == -2)
- access_ret = access(uuidd_path, X_OK);
- if (access_ret == 0)
- access_ret = stat(uuidd_path, &st);
- if (access_ret == 0 && (st.st_mode & (S_ISUID | S_ISGID)) == 0)
- access_ret = access(UUIDD_DIR, W_OK);
- if (access_ret == 0 && start_attempts++ < 5) {
- if ((pid = fork()) == 0) {
- close_all_fds();
- execl(uuidd_path, "uuidd", "-qT", "300",
- (char *) NULL);
- exit(1);
- }
- (void) waitpid(pid, 0, 0);
- if (connect(s, (const struct sockaddr *) &srv_addr,
- sizeof(struct sockaddr_un)) < 0)
- goto fail;
- } else
- goto fail;
- }
- op_buf[0] = op;
- op_len = 1;
- if (op == UUIDD_OP_BULK_TIME_UUID) {
- memcpy(op_buf+1, num, sizeof(*num));
- op_len += sizeof(*num);
- expected += sizeof(*num);
- }
-
- ret = write(s, op_buf, op_len);
- if (ret < 1)
- goto fail;
-
- ret = read_all(s, (char *) &reply_len, sizeof(reply_len));
- if (ret < 0)
- goto fail;
-
- if (reply_len != expected)
- goto fail;
-
- ret = read_all(s, op_buf, reply_len);
-
- if (op == UUIDD_OP_BULK_TIME_UUID)
- memcpy(op_buf+16, num, sizeof(int));
-
- memcpy(out, op_buf, 16);
-
- close(s);
- return ((ret == expected) ? 0 : -1);
-
-fail:
- close(s);
-#endif
- return -1;
-}
-
-void uuid__generate_time(uuid_t out, int *num)
-{
- static unsigned char node_id[6];
- static int has_init = 0;
- struct uuid uu;
- uint32_t clock_mid;
-
- if (!has_init) {
- if (get_node_id(node_id) <= 0) {
- get_random_bytes(node_id, 6);
- /*
- * Set multicast bit, to prevent conflicts
- * with IEEE 802 addresses obtained from
- * network cards
- */
- node_id[0] |= 0x01;
- }
- has_init = 1;
- }
- get_clock(&clock_mid, &uu.time_low, &uu.clock_seq, num);
- uu.clock_seq |= 0x8000;
- uu.time_mid = (uint16_t) clock_mid;
- uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000;
- memcpy(uu.node, node_id, 6);
- uuid_pack(&uu, out);
-}
-
-void gf_uuid_generate_time(uuid_t out)
-{
-#ifdef TLS
- THREAD_LOCAL int num = 0;
- THREAD_LOCAL struct uuid uu;
- THREAD_LOCAL time_t last_time = 0;
- time_t now;
-
- if (num > 0) {
- now = time(0);
- if (now > last_time+1)
- num = 0;
- }
- if (num <= 0) {
- num = 1000;
- if (get_uuid_via_daemon(UUIDD_OP_BULK_TIME_UUID,
- out, &num) == 0) {
- last_time = time(0);
- uuid_unpack(out, &uu);
- num--;
- return;
- }
- num = 0;
- }
- if (num > 0) {
- uu.time_low++;
- if (uu.time_low == 0) {
- uu.time_mid++;
- if (uu.time_mid == 0)
- uu.time_hi_and_version++;
- }
- num--;
- uuid_pack(&uu, out);
- return;
- }
-#else
- if (get_uuid_via_daemon(UUIDD_OP_TIME_UUID, out, 0) == 0)
- return;
-#endif
-
- uuid__generate_time(out, 0);
-}
-
-
-void uuid__generate_random(uuid_t out, int *num)
-{
- uuid_t buf;
- struct uuid uu;
- int i, n;
-
- if (!num || !*num)
- n = 1;
- else
- n = *num;
-
- for (i = 0; i < n; i++) {
- get_random_bytes(buf, sizeof(buf));
- uuid_unpack(buf, &uu);
-
- uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
- uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF)
- | 0x4000;
- uuid_pack(&uu, out);
- out += sizeof(uuid_t);
- }
-}
-
-void gf_uuid_generate_random(uuid_t out)
-{
- int num = 1;
- /* No real reason to use the daemon for random uuid's -- yet */
-
- uuid__generate_random(out, &num);
-}
-
-
-/*
- * This is the generic front-end to gf_uuid_generate_random and
- * gf_uuid_generate_time. It uses gf_uuid_generate_random only if
- * /dev/urandom is available, since otherwise we won't have
- * high-quality randomness.
- */
-void gf_uuid_generate(uuid_t out)
-{
- if (get_random_fd() >= 0)
- gf_uuid_generate_random(out);
- else
- gf_uuid_generate_time(out);
-}
diff --git a/contrib/uuid/gen_uuid_nt.c b/contrib/uuid/gen_uuid_nt.c
deleted file mode 100644
index 91828b7a13b..00000000000
--- a/contrib/uuid/gen_uuid_nt.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * gen_uuid_nt.c -- Use NT api to generate uuid
- *
- * Written by Andrey Shedel (andreys@ns.cr.cyco.com)
- */
-
-
-#include "uuidP.h"
-
-#pragma warning(push,4)
-
-#pragma comment(lib, "ntdll.lib")
-
-//
-// Here is a nice example why it's not a good idea
-// to use native API in ordinary applications.
-// Number of parameters in function below was changed from 3 to 4
-// for NT5.
-//
-//
-// NTSYSAPI
-// NTSTATUS
-// NTAPI
-// NtAllocateUuids(
-// OUT PULONG p1,
-// OUT PULONG p2,
-// OUT PULONG p3,
-// OUT PUCHAR Seed // 6 bytes
-// );
-//
-//
-
-unsigned long
-__stdcall
-NtAllocateUuids(
- void* p1, // 8 bytes
- void* p2, // 4 bytes
- void* p3 // 4 bytes
- );
-
-typedef
-unsigned long
-(__stdcall*
-NtAllocateUuids_2000)(
- void* p1, // 8 bytes
- void* p2, // 4 bytes
- void* p3, // 4 bytes
- void* seed // 6 bytes
- );
-
-
-
-//
-// Nice, but instead of including ntddk.h ot winnt.h
-// I should define it here because they MISSED __stdcall in those headers.
-//
-
-__declspec(dllimport)
-struct _TEB*
-__stdcall
-NtCurrentTeb(void);
-
-
-//
-// The only way to get version information from the system is to examine
-// one stored in PEB. But it's pretty dangerouse because this value could
-// be altered in image header.
-//
-
-static
-int
-Nt5(void)
-{
- //return NtCuttentTeb()->Peb->OSMajorVersion >= 5;
- return (int)*(int*)((char*)(int)(*(int*)((char*)NtCurrentTeb() + 0x30)) + 0xA4) >= 5;
-}
-
-
-
-
-void gf_uuid_generate(uuid_t out)
-{
- if(Nt5())
- {
- unsigned char seed[6];
- ((NtAllocateUuids_2000)NtAllocateUuids)(out, ((char*)out)+8, ((char*)out)+12, &seed[0] );
- }
- else
- {
- NtAllocateUuids(out, ((char*)out)+8, ((char*)out)+12);
- }
-}
diff --git a/contrib/uuid/isnull.c b/contrib/uuid/isnull.c
deleted file mode 100644
index 20d8fcef6da..00000000000
--- a/contrib/uuid/isnull.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * isnull.c --- Check whether or not the UUID is null
- *
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#include "uuidP.h"
-
-/* Returns 1 if the uuid is the NULL uuid */
-int gf_uuid_is_null(const uuid_t uu)
-{
- const unsigned char *cp;
- int i;
-
- for (i=0, cp = uu; i < 16; i++)
- if (*cp++)
- return 0;
- return 1;
-}
-
diff --git a/contrib/uuid/pack.c b/contrib/uuid/pack.c
deleted file mode 100644
index 097516d2e2f..00000000000
--- a/contrib/uuid/pack.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Internal routine for packing UUID's
- *
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#include <string.h>
-#include "uuidP.h"
-
-void uuid_pack(const struct uuid *uu, uuid_t ptr)
-{
- uint32_t tmp;
- unsigned char *out = ptr;
-
- tmp = uu->time_low;
- out[3] = (unsigned char) tmp;
- tmp >>= 8;
- out[2] = (unsigned char) tmp;
- tmp >>= 8;
- out[1] = (unsigned char) tmp;
- tmp >>= 8;
- out[0] = (unsigned char) tmp;
-
- tmp = uu->time_mid;
- out[5] = (unsigned char) tmp;
- tmp >>= 8;
- out[4] = (unsigned char) tmp;
-
- tmp = uu->time_hi_and_version;
- out[7] = (unsigned char) tmp;
- tmp >>= 8;
- out[6] = (unsigned char) tmp;
-
- tmp = uu->clock_seq;
- out[9] = (unsigned char) tmp;
- tmp >>= 8;
- out[8] = (unsigned char) tmp;
-
- memcpy(out+10, uu->node, 6);
-}
-
diff --git a/contrib/uuid/parse.c b/contrib/uuid/parse.c
deleted file mode 100644
index 059ae437805..00000000000
--- a/contrib/uuid/parse.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * parse.c --- UUID parsing
- *
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "uuidP.h"
-
-int gf_uuid_parse(const char *in, uuid_t uu)
-{
- struct uuid uuid;
- int i;
- const char *cp;
- char buf[3];
-
- if (strlen(in) != 36)
- return -1;
- for (i=0, cp = in; i <= 36; i++,cp++) {
- if ((i == 8) || (i == 13) || (i == 18) ||
- (i == 23)) {
- if (*cp == '-')
- continue;
- else
- return -1;
- }
- if (i== 36)
- if (*cp == 0)
- continue;
- if (!isxdigit(*cp))
- return -1;
- }
- uuid.time_low = strtoul(in, NULL, 16);
- uuid.time_mid = strtoul(in+9, NULL, 16);
- uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
- uuid.clock_seq = strtoul(in+19, NULL, 16);
- cp = in+24;
- buf[2] = 0;
- for (i=0; i < 6; i++) {
- buf[0] = *cp++;
- buf[1] = *cp++;
- uuid.node[i] = strtoul(buf, NULL, 16);
- }
-
- uuid_pack(&uuid, uu);
- return 0;
-}
diff --git a/contrib/uuid/tst_uuid.c b/contrib/uuid/tst_uuid.c
deleted file mode 100644
index 865564b0c34..00000000000
--- a/contrib/uuid/tst_uuid.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * tst_uuid.c --- test program from the UUID library
- *
- * Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#ifdef _WIN32
-#define _WIN32_WINNT 0x0500
-#include <windows.h>
-#define UUID MYUUID
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "uuid.h"
-
-static int test_uuid(const char * uuid, int isValid)
-{
- static const char * validStr[2] = {"invalid", "valid"};
- uuid_t uuidBits;
- int parsedOk;
-
- parsedOk = gf_uuid_parse(uuid, uuidBits) == 0;
-
- printf("%s is %s", uuid, validStr[isValid]);
- if (parsedOk != isValid) {
- printf(" but gf_uuid_parse says %s\n", validStr[parsedOk]);
- return 1;
- }
- printf(", OK\n");
- return 0;
-}
-
-#ifdef __GNUC__
-#define ATTR(x) __attribute__(x)
-#else
-#define ATTR(x)
-#endif
-
-int
-main(int argc ATTR((unused)) , char **argv ATTR((unused)))
-{
- uuid_t buf, tst;
- char str[100];
- struct timeval tv;
- time_t time_reg;
- unsigned char *cp;
- int i;
- int failed = 0;
- int type, variant;
-
- gf_uuid_generate(buf);
- gf_uuid_unparse(buf, str);
- printf("UUID generate = %s\n", str);
- printf("UUID: ");
- for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
- printf("%02x", *cp++);
- }
- printf("\n");
- type = gf_uuid_type(buf); variant = gf_uuid_variant(buf);
- printf("UUID type = %d, UUID variant = %d\n", type, variant);
- if (variant != UUID_VARIANT_DCE) {
- printf("Incorrect UUID Variant; was expecting DCE!\n");
- failed++;
- }
- printf("\n");
-
- gf_uuid_generate_random(buf);
- gf_uuid_unparse(buf, str);
- printf("UUID random string = %s\n", str);
- printf("UUID: ");
- for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
- printf("%02x", *cp++);
- }
- printf("\n");
- type = gf_uuid_type(buf); variant = gf_uuid_variant(buf);
- printf("UUID type = %d, UUID variant = %d\n", type, variant);
- if (variant != UUID_VARIANT_DCE) {
- printf("Incorrect UUID Variant; was expecting DCE!\n");
- failed++;
- }
- if (type != 4) {
- printf("Incorrect UUID type; was expecting "
- "4 (random type)!\n");
- failed++;
- }
- printf("\n");
-
- gf_uuid_generate_time(buf);
- gf_uuid_unparse(buf, str);
- printf("UUID string = %s\n", str);
- printf("UUID time: ");
- for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
- printf("%02x", *cp++);
- }
- printf("\n");
- type = gf_uuid_type(buf); variant = gf_uuid_variant(buf);
- printf("UUID type = %d, UUID variant = %d\n", type, variant);
- if (variant != UUID_VARIANT_DCE) {
- printf("Incorrect UUID Variant; was expecting DCE!\n");
- failed++;
- }
- if (type != 1) {
- printf("Incorrect UUID type; was expecting "
- "1 (time-based type)!\\n");
- failed++;
- }
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- time_reg = gf_uuid_time(buf, &tv);
- printf("UUID time is: (%ld, %ld): %s\n", tv.tv_sec, tv.tv_usec,
- ctime(&time_reg));
- gf_uuid_parse(str, tst);
- if (!gf_uuid_compare(buf, tst))
- printf("UUID parse and compare succeeded.\n");
- else {
- printf("UUID parse and compare failed!\n");
- failed++;
- }
- gf_uuid_clear(tst);
- if (gf_uuid_is_null(tst))
- printf("UUID clear and is null succeeded.\n");
- else {
- printf("UUID clear and is null failed!\n");
- failed++;
- }
- gf_uuid_copy(buf, tst);
- if (!gf_uuid_compare(buf, tst))
- printf("UUID copy and compare succeeded.\n");
- else {
- printf("UUID copy and compare failed!\n");
- failed++;
- }
- failed += test_uuid("84949cc5-4701-4a84-895b-354c584a981b", 1);
- failed += test_uuid("84949CC5-4701-4A84-895B-354C584A981B", 1);
- failed += test_uuid("84949cc5-4701-4a84-895b-354c584a981bc", 0);
- failed += test_uuid("84949cc5-4701-4a84-895b-354c584a981", 0);
- failed += test_uuid("84949cc5x4701-4a84-895b-354c584a981b", 0);
- failed += test_uuid("84949cc504701-4a84-895b-354c584a981b", 0);
- failed += test_uuid("84949cc5-470104a84-895b-354c584a981b", 0);
- failed += test_uuid("84949cc5-4701-4a840895b-354c584a981b", 0);
- failed += test_uuid("84949cc5-4701-4a84-895b0354c584a981b", 0);
- failed += test_uuid("g4949cc5-4701-4a84-895b-354c584a981b", 0);
- failed += test_uuid("84949cc5-4701-4a84-895b-354c584a981g", 0);
-
- if (failed) {
- printf("%d failures.\n", failed);
- exit(1);
- }
- return 0;
-}
diff --git a/contrib/uuid/unpack.c b/contrib/uuid/unpack.c
deleted file mode 100644
index beaaff3ca8a..00000000000
--- a/contrib/uuid/unpack.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Internal routine for unpacking UUID
- *
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#include <string.h>
-#include "uuidP.h"
-
-void uuid_unpack(const uuid_t in, struct uuid *uu)
-{
- const uint8_t *ptr = in;
- uint32_t tmp;
-
- tmp = *ptr++;
- tmp = (tmp << 8) | *ptr++;
- tmp = (tmp << 8) | *ptr++;
- tmp = (tmp << 8) | *ptr++;
- uu->time_low = tmp;
-
- tmp = *ptr++;
- tmp = (tmp << 8) | *ptr++;
- uu->time_mid = tmp;
-
- tmp = *ptr++;
- tmp = (tmp << 8) | *ptr++;
- uu->time_hi_and_version = tmp;
-
- tmp = *ptr++;
- tmp = (tmp << 8) | *ptr++;
- uu->clock_seq = tmp;
-
- memcpy(uu->node, ptr, 6);
-}
-
diff --git a/contrib/uuid/unparse.c b/contrib/uuid/unparse.c
deleted file mode 100644
index f6e29534140..00000000000
--- a/contrib/uuid/unparse.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * unparse.c -- convert a UUID to string
- *
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#include <stdio.h>
-
-#include "uuidP.h"
-
-static const char *fmt_lower =
- "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
-
-static const char *fmt_upper =
- "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X";
-
-#ifdef UUID_UNPARSE_DEFAULT_UPPER
-#define FMT_DEFAULT fmt_upper
-#else
-#define FMT_DEFAULT fmt_lower
-#endif
-
-static void gf_uuid_unparse_x(const uuid_t uu, char *out, const char *fmt)
-{
- struct uuid uuid;
-
- uuid_unpack(uu, &uuid);
- sprintf(out, fmt,
- uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
- uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
- uuid.node[0], uuid.node[1], uuid.node[2],
- uuid.node[3], uuid.node[4], uuid.node[5]);
-}
-
-void gf_uuid_unparse_lower(const uuid_t uu, char *out)
-{
- gf_uuid_unparse_x(uu, out, fmt_lower);
-}
-
-void gf_uuid_unparse_upper(const uuid_t uu, char *out)
-{
- gf_uuid_unparse_x(uu, out, fmt_upper);
-}
-
-void gf_uuid_unparse(const uuid_t uu, char *out)
-{
- gf_uuid_unparse_x(uu, out, FMT_DEFAULT);
-}
diff --git a/contrib/uuid/uuid.h b/contrib/uuid/uuid.h
deleted file mode 100644
index 97de360ad52..00000000000
--- a/contrib/uuid/uuid.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Public include file for the UUID library
- *
- * Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#ifndef _UUID_UUID_H
-#define _UUID_UUID_H
-
-#include "config.h"
-#include <sys/types.h>
-#ifndef _WIN32
-#include <sys/time.h>
-#endif
-#include <time.h>
-
-typedef unsigned char uuid_t[16];
-
-/* UUID Variant definitions */
-#define UUID_VARIANT_NCS 0
-#define UUID_VARIANT_DCE 1
-#define UUID_VARIANT_MICROSOFT 2
-#define UUID_VARIANT_OTHER 3
-
-/* UUID Type definitions */
-#define UUID_TYPE_DCE_TIME 1
-#define UUID_TYPE_DCE_RANDOM 4
-
-/* Allow UUID constants to be defined */
-#ifdef __GNUC__
-#define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \
- static const uuid_t name __attribute__ ((unused)) = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15}
-#else
-#define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \
- static const uuid_t name = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15}
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* clear.c */
-void gf_uuid_clear(uuid_t uu);
-
-/* compare.c */
-int gf_uuid_compare(const uuid_t uu1, const uuid_t uu2);
-
-/* copy.c */
-void gf_uuid_copy(uuid_t dst, const uuid_t src);
-
-/* gen_uuid.c */
-void gf_uuid_generate(uuid_t out);
-void gf_uuid_generate_random(uuid_t out);
-void gf_uuid_generate_time(uuid_t out);
-
-/* isnull.c */
-int gf_uuid_is_null(const uuid_t uu);
-
-/* parse.c */
-int gf_uuid_parse(const char *in, uuid_t uu);
-
-/* unparse.c */
-void gf_uuid_unparse(const uuid_t uu, char *out);
-void gf_uuid_unparse_lower(const uuid_t uu, char *out);
-void gf_uuid_unparse_upper(const uuid_t uu, char *out);
-
-/* uuid_time.c */
-time_t gf_uuid_time(const uuid_t uu, struct timeval *ret_tv);
-int gf_uuid_type(const uuid_t uu);
-int gf_uuid_variant(const uuid_t uu);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _UUID_UUID_H */
diff --git a/contrib/uuid/uuidP.h b/contrib/uuid/uuidP.h
deleted file mode 100644
index 9a2de6132fe..00000000000
--- a/contrib/uuid/uuidP.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * uuid.h -- private header file for uuids
- *
- * Copyright (C) 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#include "uuid.h"
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include "uuid_types.h"
-#endif
-#include <sys/types.h>
-
-
-/*
- * Offset between 15-Oct-1582 and 1-Jan-70
- */
-#define TIME_OFFSET_HIGH 0x01B21DD2
-#define TIME_OFFSET_LOW 0x13814000
-
-struct uuid {
- uint32_t time_low;
- uint16_t time_mid;
- uint16_t time_hi_and_version;
- uint16_t clock_seq;
- uint8_t node[6];
-};
-
-
-/*
- * prototypes
- */
-void uuid_pack(const struct uuid *uu, uuid_t ptr);
-void uuid_unpack(const uuid_t in, struct uuid *uu);
diff --git a/contrib/uuid/uuid_time.c b/contrib/uuid/uuid_time.c
deleted file mode 100644
index 35f727018b1..00000000000
--- a/contrib/uuid/uuid_time.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * uuid_time.c --- Interpret the time field from a uuid. This program
- * violates the UUID abstraction barrier by reaching into the guts
- * of a UUID and interpreting it.
- *
- * Copyright (C) 1998, 1999 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#ifdef _WIN32
-#define _WIN32_WINNT 0x0500
-#include <windows.h>
-#define UUID MYUUID
-#endif
-
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <stdlib.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <time.h>
-
-#include "uuidP.h"
-#include "logging.h"
-
-time_t gf_uuid_time(const uuid_t uu, struct timeval *ret_tv)
-{
- struct timeval tv;
- struct uuid uuid;
- uint32_t high;
- uint64_t clock_reg;
-
- uuid_unpack(uu, &uuid);
-
- high = uuid.time_mid | ((uuid.time_hi_and_version & 0xFFF) << 16);
- clock_reg = uuid.time_low | ((uint64_t) high << 32);
-
- clock_reg -= (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
- tv.tv_sec = clock_reg / 10000000;
- tv.tv_usec = (clock_reg % 10000000) / 10;
-
- if (ret_tv)
- *ret_tv = tv;
-
- return tv.tv_sec;
-}
-
-int gf_uuid_type(const uuid_t uu)
-{
- struct uuid uuid;
-
- uuid_unpack(uu, &uuid);
- return ((uuid.time_hi_and_version >> 12) & 0xF);
-}
-
-int gf_uuid_variant(const uuid_t uu)
-{
- struct uuid uuid;
- int var;
-
- uuid_unpack(uu, &uuid);
- var = uuid.clock_seq;
-
- if ((var & 0x8000) == 0)
- return UUID_VARIANT_NCS;
- if ((var & 0x4000) == 0)
- return UUID_VARIANT_DCE;
- if ((var & 0x2000) == 0)
- return UUID_VARIANT_MICROSOFT;
- return UUID_VARIANT_OTHER;
-}
-
-#ifdef DEBUG
-static const char *variant_string(int variant)
-{
- switch (variant) {
- case UUID_VARIANT_NCS:
- return "NCS";
- case UUID_VARIANT_DCE:
- return "DCE";
- case UUID_VARIANT_MICROSOFT:
- return "Microsoft";
- default:
- return "Other";
- }
-}
-
-
-int
-main(int argc, char **argv)
-{
- uuid_t buf;
- time_t time_reg;
- struct timeval tv;
- int type, variant;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s uuid\n", argv[0]);
- exit(1);
- }
- if (gf_uuid_parse(argv[1], buf)) {
- fprintf(stderr, "Invalid UUID: %s\n", argv[1]);
- exit(1);
- }
- variant = gf_uuid_variant(buf);
- type = gf_uuid_type(buf);
- time_reg = gf_uuid_time(buf, &tv);
-
- printf("UUID variant is %d (%s)\n", variant, variant_string(variant));
- if (variant != UUID_VARIANT_DCE) {
- printf("Warning: This program only knows how to interpret "
- "DCE UUIDs.\n\tThe rest of the output is likely "
- "to be incorrect!!\n");
- }
- printf("UUID type is %d", type);
- switch (type) {
- case 1:
- printf(" (time based)\n");
- break;
- case 2:
- printf(" (DCE)\n");
- break;
- case 3:
- printf(" (name-based)\n");
- break;
- case 4:
- printf(" (random)\n");
- break;
- default:
- printf("\n");
- }
- if (type != 1) {
- printf("Warning: not a time-based UUID, so UUID time "
- "decoding will likely not work!\n");
- }
- printf("UUID time is: (%" GF_PRI_SECOND ", %" GF_PRI_USEC "): %s\n", tv.tv_sec, tv.tv_usec, ctime(&time_reg));
-
- return 0;
-}
-#endif
diff --git a/contrib/uuid/uuid_types.h.in b/contrib/uuid/uuid_types.h.in
deleted file mode 100644
index f21ff4ee183..00000000000
--- a/contrib/uuid/uuid_types.h.in
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * If linux/types.h is already been included, assume it has defined
- * everything we need. (cross fingers) Other header files may have
- * also defined the types that we need.
- */
-#if (!defined(_STDINT_H) && !defined(_UUID_STDINT_H))
-#define _UUID_STDINT_H
-
-typedef unsigned char uint8_t;
-typedef signed char int8_t;
-
-#if (@SIZEOF_INT@ == 8)
-typedef int int64_t;
-typedef unsigned int uint64_t;
-#elif (@SIZEOF_LONG@ == 8)
-typedef long int64_t;
-typedef unsigned long uint64_t;
-#elif (@SIZEOF_LONG_LONG@ == 8)
-#if defined(__GNUC__)
-typedef __signed__ long long int64_t;
-#else
-typedef signed long long int64_t;
-#endif
-typedef unsigned long long uint64_t;
-#endif
-
-#if (@SIZEOF_INT@ == 2)
-typedef int int16_t;
-typedef unsigned int uint16_t;
-#elif (@SIZEOF_SHORT@ == 2)
-typedef short int16_t;
-typedef unsigned short uint16_t;
-#else
- ?==error: undefined 16 bit type
-#endif
-
-#if (@SIZEOF_INT@ == 4)
-typedef int int32_t;
-typedef unsigned int uint32_t;
-#elif (@SIZEOF_LONG@ == 4)
-typedef long int32_t;
-typedef unsigned long uint32_t;
-#elif (@SIZEOF_SHORT@ == 4)
-typedef short int32_t;
-typedef unsigned short uint32_t;
-#else
- ?== error: undefined 32 bit type
-#endif
-
-#endif
diff --git a/contrib/uuid/uuidd.h b/contrib/uuid/uuidd.h
deleted file mode 100644
index c71f4b78835..00000000000
--- a/contrib/uuid/uuidd.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Definitions used by the uuidd daemon
- *
- * Copyright (C) 2007 Theodore Ts'o.
- *
- * %Begin-Header%
- * 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
- * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * %End-Header%
- */
-
-#ifndef _UUID_UUIDD_H
-#define _UUID_UUIDD_H
-
-#define UUIDD_DIR "/var/lib/libuuid"
-#define UUIDD_SOCKET_PATH UUIDD_DIR "/request"
-#define UUIDD_PIDFILE_PATH UUIDD_DIR "/uuidd.pid"
-#define UUIDD_PATH "/usr/sbin/uuidd"
-
-#define UUIDD_OP_GETPID 0
-#define UUIDD_OP_GET_MAXOP 1
-#define UUIDD_OP_TIME_UUID 2
-#define UUIDD_OP_RANDOM_UUID 3
-#define UUIDD_OP_BULK_TIME_UUID 4
-#define UUIDD_OP_BULK_RANDOM_UUID 5
-#define UUIDD_MAX_OP UUIDD_OP_BULK_RANDOM_UUID
-
-extern void uuid__generate_time(uuid_t out, int *num);
-extern void uuid__generate_random(uuid_t out, int *num);
-
-#endif /* _UUID_UUID_H */
diff --git a/contrib/xxhash/xxhash.c b/contrib/xxhash/xxhash.c
new file mode 100644
index 00000000000..56f80f8811d
--- /dev/null
+++ b/contrib/xxhash/xxhash.c
@@ -0,0 +1,1029 @@
+/*
+* xxHash - Fast Hash algorithm
+* Copyright (C) 2012-2016, Yann Collet
+*
+* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * 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.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+* OWNER 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.
+*
+* You can contact the author at :
+* - xxHash homepage: http://www.xxhash.com
+* - xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+
+/* *************************************
+* Tuning parameters
+***************************************/
+/*!XXH_FORCE_MEMORY_ACCESS :
+ * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
+ * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
+ * The below switch allow to select different access method for improved performance.
+ * Method 0 (default) : use `memcpy()`. Safe and portable.
+ * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
+ * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
+ * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.
+ * It can generate buggy code on targets which do not support unaligned memory accesses.
+ * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
+ * See http://stackoverflow.com/a/32095106/646947 for details.
+ * Prefer these methods in priority order (0 > 1 > 2)
+ */
+#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
+# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
+# define XXH_FORCE_MEMORY_ACCESS 2
+# elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \
+ (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7S__) ))
+# define XXH_FORCE_MEMORY_ACCESS 1
+# endif
+#endif
+
+/*!XXH_ACCEPT_NULL_INPUT_POINTER :
+ * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault.
+ * When this macro is enabled, xxHash actively checks input for null pointer.
+ * It it is, result for null input pointers is the same as a null-length input.
+ */
+#ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */
+# define XXH_ACCEPT_NULL_INPUT_POINTER 0
+#endif
+
+/*!XXH_FORCE_NATIVE_FORMAT :
+ * By default, xxHash library provides endian-independent Hash values, based on little-endian convention.
+ * Results are therefore identical for little-endian and big-endian CPU.
+ * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
+ * Should endian-independence be of no importance for your application, you may set the #define below to 1,
+ * to improve speed for Big-endian CPU.
+ * This option has no impact on Little_Endian CPU.
+ */
+#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */
+# define XXH_FORCE_NATIVE_FORMAT 0
+#endif
+
+/*!XXH_FORCE_ALIGN_CHECK :
+ * This is a minor performance trick, only useful with lots of very small keys.
+ * It means : check for aligned/unaligned input.
+ * The check costs one initial branch per hash;
+ * set it to 0 when the input is guaranteed to be aligned,
+ * or when alignment doesn't matter for performance.
+ */
+#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
+# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
+# define XXH_FORCE_ALIGN_CHECK 0
+# else
+# define XXH_FORCE_ALIGN_CHECK 1
+# endif
+#endif
+
+
+/* *************************************
+* Includes & Memory related functions
+***************************************/
+/*! Modify the local functions below should you wish to use some other memory routines
+* for malloc(), free() */
+#include <stdlib.h>
+static void* XXH_malloc(size_t s) { return malloc(s); }
+static void XXH_free (void* p) { free(p); }
+/*! and for memcpy() */
+#include <string.h>
+static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
+
+#include <assert.h> /* assert */
+
+#define XXH_STATIC_LINKING_ONLY
+#include "xxhash.h"
+
+
+/* *************************************
+* Compiler Specific Options
+***************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+# define FORCE_INLINE static __forceinline
+#else
+# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# ifdef __GNUC__
+# define FORCE_INLINE static inline __attribute__((always_inline))
+# else
+# define FORCE_INLINE static inline
+# endif
+# else
+# define FORCE_INLINE static
+# endif /* __STDC_VERSION__ */
+#endif
+
+
+/* *************************************
+* Basic Types
+***************************************/
+#ifndef MEM_MODULE
+# if !defined (__VMS) \
+ && (defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+ typedef uint8_t BYTE;
+ typedef uint16_t U16;
+ typedef uint32_t U32;
+# else
+ typedef unsigned char BYTE;
+ typedef unsigned short U16;
+ typedef unsigned int U32;
+# endif
+#endif
+
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
+
+/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
+static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
+
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
+
+/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
+/* currently only defined for gcc and icc */
+typedef union { U32 u32; } __attribute__((packed)) unalign;
+static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
+
+#else
+
+/* portable and safe solution. Generally efficient.
+ * see : http://stackoverflow.com/a/32095106/646947
+ */
+static U32 XXH_read32(const void* memPtr)
+{
+ U32 val;
+ memcpy(&val, memPtr, sizeof(val));
+ return val;
+}
+
+#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
+
+
+/* ****************************************
+* Compiler-specific Functions and Macros
+******************************************/
+#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
+#if defined(_MSC_VER)
+# define XXH_rotl32(x,r) _rotl(x,r)
+# define XXH_rotl64(x,r) _rotl64(x,r)
+#else
+# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
+# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
+#endif
+
+#if defined(_MSC_VER) /* Visual Studio */
+# define XXH_swap32 _byteswap_ulong
+#elif GCC_VERSION >= 403
+# define XXH_swap32 __builtin_bswap32
+#else
+static U32 XXH_swap32 (U32 x)
+{
+ return ((x << 24) & 0xff000000 ) |
+ ((x << 8) & 0x00ff0000 ) |
+ ((x >> 8) & 0x0000ff00 ) |
+ ((x >> 24) & 0x000000ff );
+}
+#endif
+
+
+/* *************************************
+* Architecture Macros
+***************************************/
+typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
+
+/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
+#ifndef XXH_CPU_LITTLE_ENDIAN
+static int XXH_isLittleEndian(void)
+{
+ const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
+ return one.c[0];
+}
+# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian()
+#endif
+
+
+/* ***************************
+* Memory reads
+*****************************/
+typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
+
+FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
+{
+ if (align==XXH_unaligned)
+ return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
+ else
+ return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
+}
+
+FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
+{
+ return XXH_readLE32_align(ptr, endian, XXH_unaligned);
+}
+
+static U32 XXH_readBE32(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
+}
+
+
+/* *************************************
+* Macros
+***************************************/
+#define XXH_STATIC_ASSERT(c) { enum { XXH_sa = 1/(int)(!!(c)) }; } /* use after variable declarations */
+XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
+
+
+/* *******************************************************************
+* 32-bit hash functions
+*********************************************************************/
+static const U32 PRIME32_1 = 2654435761U;
+static const U32 PRIME32_2 = 2246822519U;
+static const U32 PRIME32_3 = 3266489917U;
+static const U32 PRIME32_4 = 668265263U;
+static const U32 PRIME32_5 = 374761393U;
+
+static U32 XXH32_round(U32 seed, U32 input)
+{
+ seed += input * PRIME32_2;
+ seed = XXH_rotl32(seed, 13);
+ seed *= PRIME32_1;
+ return seed;
+}
+
+/* mix all bits */
+static U32 XXH32_avalanche(U32 h32)
+{
+ h32 ^= h32 >> 15;
+ h32 *= PRIME32_2;
+ h32 ^= h32 >> 13;
+ h32 *= PRIME32_3;
+ h32 ^= h32 >> 16;
+ return(h32);
+}
+
+#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
+
+static U32
+XXH32_finalize(U32 h32, const void* ptr, size_t len,
+ XXH_endianess endian, XXH_alignment align)
+
+{
+ const BYTE* p = (const BYTE*)ptr;
+#define PROCESS1 \
+ h32 += (*p) * PRIME32_5; \
+ p++; \
+ h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
+
+#define PROCESS4 \
+ h32 += XXH_get32bits(p) * PRIME32_3; \
+ p+=4; \
+ h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
+
+ switch(len&15) /* or switch(bEnd - p) */
+ {
+ case 12: PROCESS4;
+ /* fallthrough */
+ case 8: PROCESS4;
+ /* fallthrough */
+ case 4: PROCESS4;
+ return XXH32_avalanche(h32);
+
+ case 13: PROCESS4;
+ /* fallthrough */
+ case 9: PROCESS4;
+ /* fallthrough */
+ case 5: PROCESS4;
+ PROCESS1;
+ return XXH32_avalanche(h32);
+
+ case 14: PROCESS4;
+ /* fallthrough */
+ case 10: PROCESS4;
+ /* fallthrough */
+ case 6: PROCESS4;
+ PROCESS1;
+ PROCESS1;
+ return XXH32_avalanche(h32);
+
+ case 15: PROCESS4;
+ /* fallthrough */
+ case 11: PROCESS4;
+ /* fallthrough */
+ case 7: PROCESS4;
+ /* fallthrough */
+ case 3: PROCESS1;
+ /* fallthrough */
+ case 2: PROCESS1;
+ /* fallthrough */
+ case 1: PROCESS1;
+ /* fallthrough */
+ case 0: return XXH32_avalanche(h32);
+ }
+ assert(0);
+ return h32; /* reaching this point is deemed impossible */
+}
+
+
+FORCE_INLINE U32
+XXH32_endian_align(const void* input, size_t len, U32 seed,
+ XXH_endianess endian, XXH_alignment align)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* bEnd = p + len;
+ U32 h32;
+
+#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
+ if (p==NULL) {
+ len=0;
+ bEnd=p=(const BYTE*)(size_t)16;
+ }
+#endif
+
+ if (len>=16) {
+ const BYTE* const limit = bEnd - 15;
+ U32 v1 = seed + PRIME32_1 + PRIME32_2;
+ U32 v2 = seed + PRIME32_2;
+ U32 v3 = seed + 0;
+ U32 v4 = seed - PRIME32_1;
+
+ do {
+ v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;
+ v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;
+ v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;
+ v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;
+ } while (p < limit);
+
+ h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7)
+ + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
+ } else {
+ h32 = seed + PRIME32_5;
+ }
+
+ h32 += (U32)len;
+
+ return XXH32_finalize(h32, p, len&15, endian, align);
+}
+
+
+XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)
+{
+#if 0
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+ XXH32_state_t state;
+ XXH32_reset(&state, seed);
+ XXH32_update(&state, input, len);
+ return XXH32_digest(&state);
+#else
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if (XXH_FORCE_ALIGN_CHECK) {
+ if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
+ else
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
+ } }
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
+ else
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
+#endif
+}
+
+
+
+/*====== Hash streaming ======*/
+
+XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
+{
+ return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
+}
+XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
+{
+ XXH_free(statePtr);
+ return XXH_OK;
+}
+
+XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
+{
+ memcpy(dstState, srcState, sizeof(*dstState));
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)
+{
+ XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
+ memset(&state, 0, sizeof(state));
+ state.v1 = seed + PRIME32_1 + PRIME32_2;
+ state.v2 = seed + PRIME32_2;
+ state.v3 = seed + 0;
+ state.v4 = seed - PRIME32_1;
+ /* do not write into reserved, planned to be removed in a future version */
+ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));
+ return XXH_OK;
+}
+
+
+FORCE_INLINE
+XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* const bEnd = p + len;
+
+ if (input==NULL)
+#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
+ return XXH_OK;
+#else
+ return XXH_ERROR;
+#endif
+
+ state->total_len_32 += (unsigned)len;
+ state->large_len |= (len>=16) | (state->total_len_32>=16);
+
+ if (state->memsize + len < 16) { /* fill in tmp buffer */
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
+ state->memsize += (unsigned)len;
+ return XXH_OK;
+ }
+
+ if (state->memsize) { /* some data left from previous update */
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
+ { const U32* p32 = state->mem32;
+ state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;
+ state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;
+ state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;
+ state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian));
+ }
+ p += 16-state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p <= bEnd-16) {
+ const BYTE* const limit = bEnd - 16;
+ U32 v1 = state->v1;
+ U32 v2 = state->v2;
+ U32 v3 = state->v3;
+ U32 v4 = state->v4;
+
+ do {
+ v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;
+ v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;
+ v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;
+ v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;
+ } while (p<=limit);
+
+ state->v1 = v1;
+ state->v2 = v2;
+ state->v3 = v3;
+ state->v4 = v4;
+ }
+
+ if (p < bEnd) {
+ XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
+ state->memsize = (unsigned)(bEnd-p);
+ }
+
+ return XXH_OK;
+}
+
+
+XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
+ else
+ return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
+}
+
+
+FORCE_INLINE U32
+XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
+{
+ U32 h32;
+
+ if (state->large_len) {
+ h32 = XXH_rotl32(state->v1, 1)
+ + XXH_rotl32(state->v2, 7)
+ + XXH_rotl32(state->v3, 12)
+ + XXH_rotl32(state->v4, 18);
+ } else {
+ h32 = state->v3 /* == seed */ + PRIME32_5;
+ }
+
+ h32 += state->total_len_32;
+
+ return XXH32_finalize(h32, state->mem32, state->memsize, endian, XXH_aligned);
+}
+
+
+XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_digest_endian(state_in, XXH_littleEndian);
+ else
+ return XXH32_digest_endian(state_in, XXH_bigEndian);
+}
+
+
+/*====== Canonical representation ======*/
+
+/*! Default XXH result types are basic unsigned 32 and 64 bits.
+* The canonical representation follows human-readable write convention, aka big-endian (large digits first).
+* These functions allow transformation of hash result into and from its canonical format.
+* This way, hash values can be written into a file or buffer, remaining comparable across different systems.
+*/
+
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
+{
+ XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
+ memcpy(dst, &hash, sizeof(*dst));
+}
+
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
+{
+ return XXH_readBE32(src);
+}
+
+
+#ifndef XXH_NO_LONG_LONG
+
+/* *******************************************************************
+* 64-bit hash functions
+*********************************************************************/
+
+/*====== Memory access ======*/
+
+#ifndef MEM_MODULE
+# define MEM_MODULE
+# if !defined (__VMS) \
+ && (defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+ typedef uint64_t U64;
+# else
+ /* if compiler doesn't support unsigned long long, replace by another 64-bit type */
+ typedef unsigned long long U64;
+# endif
+#endif
+
+
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
+
+/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
+static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
+
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
+
+/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
+/* currently only defined for gcc and icc */
+typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64;
+static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; }
+
+#else
+
+/* portable and safe solution. Generally efficient.
+ * see : http://stackoverflow.com/a/32095106/646947
+ */
+
+static U64 XXH_read64(const void* memPtr)
+{
+ U64 val;
+ memcpy(&val, memPtr, sizeof(val));
+ return val;
+}
+
+#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
+
+#if defined(_MSC_VER) /* Visual Studio */
+# define XXH_swap64 _byteswap_uint64
+#elif GCC_VERSION >= 403
+# define XXH_swap64 __builtin_bswap64
+#else
+static U64 XXH_swap64 (U64 x)
+{
+ return ((x << 56) & 0xff00000000000000ULL) |
+ ((x << 40) & 0x00ff000000000000ULL) |
+ ((x << 24) & 0x0000ff0000000000ULL) |
+ ((x << 8) & 0x000000ff00000000ULL) |
+ ((x >> 8) & 0x00000000ff000000ULL) |
+ ((x >> 24) & 0x0000000000ff0000ULL) |
+ ((x >> 40) & 0x000000000000ff00ULL) |
+ ((x >> 56) & 0x00000000000000ffULL);
+}
+#endif
+
+FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
+{
+ if (align==XXH_unaligned)
+ return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
+ else
+ return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
+}
+
+FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
+{
+ return XXH_readLE64_align(ptr, endian, XXH_unaligned);
+}
+
+static U64 XXH_readBE64(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
+}
+
+
+/*====== xxh64 ======*/
+
+static const U64 PRIME64_1 = 11400714785074694791ULL;
+static const U64 PRIME64_2 = 14029467366897019727ULL;
+static const U64 PRIME64_3 = 1609587929392839161ULL;
+static const U64 PRIME64_4 = 9650029242287828579ULL;
+static const U64 PRIME64_5 = 2870177450012600261ULL;
+
+static U64 XXH64_round(U64 acc, U64 input)
+{
+ acc += input * PRIME64_2;
+ acc = XXH_rotl64(acc, 31);
+ acc *= PRIME64_1;
+ return acc;
+}
+
+static U64 XXH64_mergeRound(U64 acc, U64 val)
+{
+ val = XXH64_round(0, val);
+ acc ^= val;
+ acc = acc * PRIME64_1 + PRIME64_4;
+ return acc;
+}
+
+static U64 XXH64_avalanche(U64 h64)
+{
+ h64 ^= h64 >> 33;
+ h64 *= PRIME64_2;
+ h64 ^= h64 >> 29;
+ h64 *= PRIME64_3;
+ h64 ^= h64 >> 32;
+ return h64;
+}
+
+
+#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
+
+static U64
+XXH64_finalize(U64 h64, const void* ptr, size_t len,
+ XXH_endianess endian, XXH_alignment align)
+{
+ const BYTE* p = (const BYTE*)ptr;
+
+#define PROCESS1_64 \
+ h64 ^= (*p) * PRIME64_5; \
+ p++; \
+ h64 = XXH_rotl64(h64, 11) * PRIME64_1;
+
+#define PROCESS4_64 \
+ h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; \
+ p+=4; \
+ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
+
+#define PROCESS8_64 { \
+ U64 const k1 = XXH64_round(0, XXH_get64bits(p)); \
+ p+=8; \
+ h64 ^= k1; \
+ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \
+}
+
+ switch(len&31) {
+ case 24: PROCESS8_64;
+ /* fallthrough */
+ case 16: PROCESS8_64;
+ /* fallthrough */
+ case 8: PROCESS8_64;
+ return XXH64_avalanche(h64);
+
+ case 28: PROCESS8_64;
+ /* fallthrough */
+ case 20: PROCESS8_64;
+ /* fallthrough */
+ case 12: PROCESS8_64;
+ /* fallthrough */
+ case 4: PROCESS4_64;
+ return XXH64_avalanche(h64);
+
+ case 25: PROCESS8_64;
+ /* fallthrough */
+ case 17: PROCESS8_64;
+ /* fallthrough */
+ case 9: PROCESS8_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 29: PROCESS8_64;
+ /* fallthrough */
+ case 21: PROCESS8_64;
+ /* fallthrough */
+ case 13: PROCESS8_64;
+ /* fallthrough */
+ case 5: PROCESS4_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 26: PROCESS8_64;
+ /* fallthrough */
+ case 18: PROCESS8_64;
+ /* fallthrough */
+ case 10: PROCESS8_64;
+ PROCESS1_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 30: PROCESS8_64;
+ /* fallthrough */
+ case 22: PROCESS8_64;
+ /* fallthrough */
+ case 14: PROCESS8_64;
+ /* fallthrough */
+ case 6: PROCESS4_64;
+ PROCESS1_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 27: PROCESS8_64;
+ /* fallthrough */
+ case 19: PROCESS8_64;
+ /* fallthrough */
+ case 11: PROCESS8_64;
+ PROCESS1_64;
+ PROCESS1_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 31: PROCESS8_64;
+ /* fallthrough */
+ case 23: PROCESS8_64;
+ /* fallthrough */
+ case 15: PROCESS8_64;
+ /* fallthrough */
+ case 7: PROCESS4_64;
+ /* fallthrough */
+ case 3: PROCESS1_64;
+ /* fallthrough */
+ case 2: PROCESS1_64;
+ /* fallthrough */
+ case 1: PROCESS1_64;
+ /* fallthrough */
+ case 0: return XXH64_avalanche(h64);
+ }
+
+ /* impossible to reach */
+ assert(0);
+ return 0; /* unreachable, but some compilers complain without it */
+}
+
+FORCE_INLINE U64
+XXH64_endian_align(const void* input, size_t len, U64 seed,
+ XXH_endianess endian, XXH_alignment align)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* bEnd = p + len;
+ U64 h64;
+
+#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
+ if (p==NULL) {
+ len=0;
+ bEnd=p=(const BYTE*)(size_t)32;
+ }
+#endif
+
+ if (len>=32) {
+ const BYTE* const limit = bEnd - 32;
+ U64 v1 = seed + PRIME64_1 + PRIME64_2;
+ U64 v2 = seed + PRIME64_2;
+ U64 v3 = seed + 0;
+ U64 v4 = seed - PRIME64_1;
+
+ do {
+ v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;
+ v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;
+ v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;
+ v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;
+ } while (p<=limit);
+
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+ h64 = XXH64_mergeRound(h64, v1);
+ h64 = XXH64_mergeRound(h64, v2);
+ h64 = XXH64_mergeRound(h64, v3);
+ h64 = XXH64_mergeRound(h64, v4);
+
+ } else {
+ h64 = seed + PRIME64_5;
+ }
+
+ h64 += (U64) len;
+
+ return XXH64_finalize(h64, p, len, endian, align);
+}
+
+
+XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
+{
+#if 0
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+ XXH64_state_t state;
+ XXH64_reset(&state, seed);
+ XXH64_update(&state, input, len);
+ return XXH64_digest(&state);
+#else
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if (XXH_FORCE_ALIGN_CHECK) {
+ if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
+ else
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
+ } }
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
+ else
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
+#endif
+}
+
+/*====== Hash Streaming ======*/
+
+XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
+{
+ return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
+}
+XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
+{
+ XXH_free(statePtr);
+ return XXH_OK;
+}
+
+XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
+{
+ memcpy(dstState, srcState, sizeof(*dstState));
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)
+{
+ XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
+ memset(&state, 0, sizeof(state));
+ state.v1 = seed + PRIME64_1 + PRIME64_2;
+ state.v2 = seed + PRIME64_2;
+ state.v3 = seed + 0;
+ state.v4 = seed - PRIME64_1;
+ /* do not write into reserved, planned to be removed in a future version */
+ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));
+ return XXH_OK;
+}
+
+FORCE_INLINE
+XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* const bEnd = p + len;
+
+ if (input==NULL)
+#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
+ return XXH_OK;
+#else
+ return XXH_ERROR;
+#endif
+
+ state->total_len += len;
+
+ if (state->memsize + len < 32) { /* fill in tmp buffer */
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
+ state->memsize += (U32)len;
+ return XXH_OK;
+ }
+
+ if (state->memsize) { /* tmp buffer is full */
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
+ state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));
+ state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));
+ state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));
+ state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));
+ p += 32-state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p+32 <= bEnd) {
+ const BYTE* const limit = bEnd - 32;
+ U64 v1 = state->v1;
+ U64 v2 = state->v2;
+ U64 v3 = state->v3;
+ U64 v4 = state->v4;
+
+ do {
+ v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;
+ v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;
+ v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;
+ v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;
+ } while (p<=limit);
+
+ state->v1 = v1;
+ state->v2 = v2;
+ state->v3 = v3;
+ state->v4 = v4;
+ }
+
+ if (p < bEnd) {
+ XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
+ state->memsize = (unsigned)(bEnd-p);
+ }
+
+ return XXH_OK;
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
+ else
+ return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
+}
+
+FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
+{
+ U64 h64;
+
+ if (state->total_len >= 32) {
+ U64 const v1 = state->v1;
+ U64 const v2 = state->v2;
+ U64 const v3 = state->v3;
+ U64 const v4 = state->v4;
+
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+ h64 = XXH64_mergeRound(h64, v1);
+ h64 = XXH64_mergeRound(h64, v2);
+ h64 = XXH64_mergeRound(h64, v3);
+ h64 = XXH64_mergeRound(h64, v4);
+ } else {
+ h64 = state->v3 /*seed*/ + PRIME64_5;
+ }
+
+ h64 += (U64) state->total_len;
+
+ return XXH64_finalize(h64, state->mem64, (size_t)state->total_len, endian, XXH_aligned);
+}
+
+XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_digest_endian(state_in, XXH_littleEndian);
+ else
+ return XXH64_digest_endian(state_in, XXH_bigEndian);
+}
+
+
+/*====== Canonical representation ======*/
+
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
+{
+ XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
+ memcpy(dst, &hash, sizeof(*dst));
+}
+
+XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
+{
+ return XXH_readBE64(src);
+}
+
+#endif /* XXH_NO_LONG_LONG */
diff --git a/contrib/xxhash/xxhash.h b/contrib/xxhash/xxhash.h
new file mode 100644
index 00000000000..d6bad943358
--- /dev/null
+++ b/contrib/xxhash/xxhash.h
@@ -0,0 +1,328 @@
+/*
+ xxHash - Extremely Fast Hash algorithm
+ Header File
+ Copyright (C) 2012-2016, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * 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.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ OWNER 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.
+
+ You can contact the author at :
+ - xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+/* Notice extracted from xxHash homepage :
+
+xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
+It also successfully passes all tests from the SMHasher suite.
+
+Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
+
+Name Speed Q.Score Author
+xxHash 5.4 GB/s 10
+CrapWow 3.2 GB/s 2 Andrew
+MumurHash 3a 2.7 GB/s 10 Austin Appleby
+SpookyHash 2.0 GB/s 10 Bob Jenkins
+SBox 1.4 GB/s 9 Bret Mulvey
+Lookup3 1.2 GB/s 9 Bob Jenkins
+SuperFastHash 1.2 GB/s 1 Paul Hsieh
+CityHash64 1.05 GB/s 10 Pike & Alakuijala
+FNV 0.55 GB/s 5 Fowler, Noll, Vo
+CRC32 0.43 GB/s 9
+MD5-32 0.33 GB/s 10 Ronald L. Rivest
+SHA1-32 0.28 GB/s 10
+
+Q.Score is a measure of quality of the hash function.
+It depends on successfully passing SMHasher test set.
+10 is a perfect score.
+
+A 64-bit version, named XXH64, is available since r35.
+It offers much better speed, but for 64-bit applications only.
+Name Speed on 64 bits Speed on 32 bits
+XXH64 13.8 GB/s 1.9 GB/s
+XXH32 6.8 GB/s 6.0 GB/s
+*/
+
+#ifndef XXHASH_H_5627135585666179
+#define XXHASH_H_5627135585666179 1
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* ****************************
+* Definitions
+******************************/
+#include <stddef.h> /* size_t */
+typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
+
+
+/* ****************************
+ * API modifier
+ ******************************/
+/** XXH_INLINE_ALL (and XXH_PRIVATE_API)
+ * This is useful to include xxhash functions in `static` mode
+ * in order to inline them, and remove their symbol from the public list.
+ * Inlining can offer dramatic performance improvement on small keys.
+ * Methodology :
+ * #define XXH_INLINE_ALL
+ * #include "xxhash.h"
+ * `xxhash.c` is automatically included.
+ * It's not useful to compile and link it as a separate module.
+ */
+#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
+# ifndef XXH_STATIC_LINKING_ONLY
+# define XXH_STATIC_LINKING_ONLY
+# endif
+# if defined(__GNUC__)
+# define XXH_PUBLIC_API static __inline __attribute__((unused))
+# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
+# define XXH_PUBLIC_API static inline
+# elif defined(_MSC_VER)
+# define XXH_PUBLIC_API static __inline
+# else
+ /* this version may generate warnings for unused static functions */
+# define XXH_PUBLIC_API static
+# endif
+#else
+# define XXH_PUBLIC_API /* do nothing */
+#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */
+
+/*! XXH_NAMESPACE, aka Namespace Emulation :
+ *
+ * If you want to include _and expose_ xxHash functions from within your own library,
+ * but also want to avoid symbol collisions with other libraries which may also include xxHash,
+ *
+ * you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library
+ * with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values).
+ *
+ * Note that no change is required within the calling program as long as it includes `xxhash.h` :
+ * regular symbol name will be automatically translated by this header.
+ */
+#ifdef XXH_NAMESPACE
+# define XXH_CAT(A,B) A##B
+# define XXH_NAME2(A,B) XXH_CAT(A,B)
+# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
+# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
+# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
+# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
+# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
+# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
+# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
+# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
+# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
+# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
+# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
+# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
+# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
+# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
+# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
+# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
+# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
+# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
+# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
+#endif
+
+
+/* *************************************
+* Version
+***************************************/
+#define XXH_VERSION_MAJOR 0
+#define XXH_VERSION_MINOR 6
+#define XXH_VERSION_RELEASE 5
+#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
+XXH_PUBLIC_API unsigned XXH_versionNumber (void);
+
+
+/*-**********************************************************************
+* 32-bit hash
+************************************************************************/
+typedef unsigned int XXH32_hash_t;
+
+/*! XXH32() :
+ Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input".
+ The memory between input & input+length must be valid (allocated and read-accessible).
+ "seed" can be used to alter the result predictably.
+ Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */
+XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);
+
+/*====== Streaming ======*/
+typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */
+XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
+XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
+XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);
+
+XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed);
+XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
+XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
+
+/*
+ * Streaming functions generate the xxHash of an input provided in multiple segments.
+ * Note that, for small input, they are slower than single-call functions, due to state management.
+ * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized.
+ *
+ * XXH state must first be allocated, using XXH*_createState() .
+ *
+ * Start a new hash by initializing state with a seed, using XXH*_reset().
+ *
+ * Then, feed the hash state by calling XXH*_update() as many times as necessary.
+ * The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
+ *
+ * Finally, a hash value can be produced anytime, by using XXH*_digest().
+ * This function returns the nn-bits hash as an int or long long.
+ *
+ * It's still possible to continue inserting input into the hash state after a digest,
+ * and generate some new hashes later on, by calling again XXH*_digest().
+ *
+ * When done, free XXH state space if it was allocated dynamically.
+ */
+
+/*====== Canonical representation ======*/
+
+typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
+
+/* Default result type for XXH functions are primitive unsigned 32 and 64 bits.
+ * The canonical representation uses human-readable write convention, aka big-endian (large digits first).
+ * These functions allow transformation of hash result into and from its canonical format.
+ * This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
+ */
+
+
+#ifndef XXH_NO_LONG_LONG
+/*-**********************************************************************
+* 64-bit hash
+************************************************************************/
+typedef unsigned long long XXH64_hash_t;
+
+/*! XXH64() :
+ Calculate the 64-bit hash of sequence of length "len" stored at memory address "input".
+ "seed" can be used to alter the result predictably.
+ This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark).
+*/
+XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);
+
+/*====== Streaming ======*/
+typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
+XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
+XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
+XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
+
+XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
+XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
+XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
+
+/*====== Canonical representation ======*/
+typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
+XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
+#endif /* XXH_NO_LONG_LONG */
+
+
+
+#ifdef XXH_STATIC_LINKING_ONLY
+
+/* ================================================================================================
+ This section contains declarations which are not guaranteed to remain stable.
+ They may change in future versions, becoming incompatible with a different version of the library.
+ These declarations should only be used with static linking.
+ Never use them in association with dynamic linking !
+=================================================================================================== */
+
+/* These definitions are only present to allow
+ * static allocation of XXH state, on stack or in a struct for example.
+ * Never **ever** use members directly. */
+
+#if !defined (__VMS) \
+ && (defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+
+struct XXH32_state_s {
+ uint32_t total_len_32;
+ uint32_t large_len;
+ uint32_t v1;
+ uint32_t v2;
+ uint32_t v3;
+ uint32_t v4;
+ uint32_t mem32[4];
+ uint32_t memsize;
+ uint32_t reserved; /* never read nor write, might be removed in a future version */
+}; /* typedef'd to XXH32_state_t */
+
+struct XXH64_state_s {
+ uint64_t total_len;
+ uint64_t v1;
+ uint64_t v2;
+ uint64_t v3;
+ uint64_t v4;
+ uint64_t mem64[4];
+ uint32_t memsize;
+ uint32_t reserved[2]; /* never read nor write, might be removed in a future version */
+}; /* typedef'd to XXH64_state_t */
+
+# else
+
+struct XXH32_state_s {
+ unsigned total_len_32;
+ unsigned large_len;
+ unsigned v1;
+ unsigned v2;
+ unsigned v3;
+ unsigned v4;
+ unsigned mem32[4];
+ unsigned memsize;
+ unsigned reserved; /* never read nor write, might be removed in a future version */
+}; /* typedef'd to XXH32_state_t */
+
+# ifndef XXH_NO_LONG_LONG /* remove 64-bit support */
+struct XXH64_state_s {
+ unsigned long long total_len;
+ unsigned long long v1;
+ unsigned long long v2;
+ unsigned long long v3;
+ unsigned long long v4;
+ unsigned long long mem64[4];
+ unsigned memsize;
+ unsigned reserved[2]; /* never read nor write, might be removed in a future version */
+}; /* typedef'd to XXH64_state_t */
+# endif
+
+# endif
+
+
+#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
+# include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */
+#endif
+
+#endif /* XXH_STATIC_LINKING_ONLY */
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* XXHASH_H_5627135585666179 */
diff --git a/contrib/xxhash/xxhsum.c b/contrib/xxhash/xxhsum.c
new file mode 100644
index 00000000000..69931f727f0
--- /dev/null
+++ b/contrib/xxhash/xxhsum.c
@@ -0,0 +1,1301 @@
+/*
+* xxhsum - Command line interface for xxhash algorithms
+* Copyright (C) Yann Collet 2012-2016
+*
+* GPL v2 License
+*
+* 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.
+*
+* You can contact the author at :
+* - xxHash homepage : http://www.xxhash.com
+* - xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+/* xxhsum :
+ * Provides hash value of a file content, or a list of files, or stdin
+ * Display convention is Big Endian, for both 32 and 64 bits algorithms
+ */
+
+#ifndef XXHASH_C_2097394837
+#define XXHASH_C_2097394837
+
+/* ************************************
+ * Compiler Options
+ **************************************/
+/* MS Visual */
+#if defined(_MSC_VER) || defined(_WIN32)
+# define _CRT_SECURE_NO_WARNINGS /* removes visual warnings */
+#endif
+
+/* Under Linux at least, pull in the *64 commands */
+#ifndef _LARGEFILE64_SOURCE
+# define _LARGEFILE64_SOURCE
+#endif
+
+
+/* ************************************
+ * Includes
+ **************************************/
+#include <stdlib.h> /* malloc, calloc, free, exit */
+#include <stdio.h> /* fprintf, fopen, ftello64, fread, stdin, stdout, _fileno (when present) */
+#include <string.h> /* strcmp */
+#include <sys/types.h> /* stat, stat64, _stat64 */
+#include <sys/stat.h> /* stat, stat64, _stat64 */
+#include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
+#include <assert.h> /* assert */
+
+#define XXH_STATIC_LINKING_ONLY /* *_state_t */
+#include "xxhash.h"
+
+
+/* ************************************
+ * OS-Specific Includes
+ **************************************/
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
+# include <fcntl.h> /* _O_BINARY */
+# include <io.h> /* _setmode, _isatty */
+# define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY)
+# define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
+#else
+# include <unistd.h> /* isatty, STDIN_FILENO */
+# define SET_BINARY_MODE(file)
+# define IS_CONSOLE(stdStream) isatty(STDIN_FILENO)
+#endif
+
+#if !defined(S_ISREG)
+# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
+#endif
+
+
+/* ************************************
+* Basic Types
+**************************************/
+#ifndef MEM_MODULE
+# define MEM_MODULE
+# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# include <stdint.h>
+ typedef uint8_t BYTE;
+ typedef uint16_t U16;
+ typedef uint32_t U32;
+ typedef int32_t S32;
+ typedef uint64_t U64;
+# else
+ typedef unsigned char BYTE;
+ typedef unsigned short U16;
+ typedef unsigned int U32;
+ typedef signed int S32;
+ typedef unsigned long long U64;
+# endif
+#endif
+
+static unsigned BMK_isLittleEndian(void)
+{
+ const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
+ return one.c[0];
+}
+
+
+/* *************************************
+ * Constants
+ ***************************************/
+#define LIB_VERSION XXH_VERSION_MAJOR.XXH_VERSION_MINOR.XXH_VERSION_RELEASE
+#define QUOTE(str) #str
+#define EXPAND_AND_QUOTE(str) QUOTE(str)
+#define PROGRAM_VERSION EXPAND_AND_QUOTE(LIB_VERSION)
+static const int g_nbBits = (int)(sizeof(void*)*8);
+static const char g_lename[] = "little endian";
+static const char g_bename[] = "big endian";
+#define ENDIAN_NAME (BMK_isLittleEndian() ? g_lename : g_bename)
+static const char author[] = "Yann Collet";
+#define WELCOME_MESSAGE(exename) "%s %s (%i-bits %s), by %s \n", \
+ exename, PROGRAM_VERSION, g_nbBits, ENDIAN_NAME, author
+
+#define KB *( 1<<10)
+#define MB *( 1<<20)
+#define GB *(1U<<30)
+
+static size_t XXH_DEFAULT_SAMPLE_SIZE = 100 KB;
+#define NBLOOPS 3 /* Default number of benchmark iterations */
+#define TIMELOOP_S 1
+#define TIMELOOP (TIMELOOP_S * CLOCKS_PER_SEC) /* Minimum timing per iteration */
+#define XXHSUM32_DEFAULT_SEED 0 /* Default seed for algo_xxh32 */
+#define XXHSUM64_DEFAULT_SEED 0 /* Default seed for algo_xxh64 */
+
+#define MAX_MEM (2 GB - 64 MB)
+
+static const char stdinName[] = "-";
+typedef enum { algo_xxh32, algo_xxh64 } algoType;
+static const algoType g_defaultAlgo = algo_xxh64; /* required within main() & usage() */
+
+/* <16 hex char> <SPC> <SPC> <filename> <'\0'>
+ * '4096' is typical Linux PATH_MAX configuration. */
+#define DEFAULT_LINE_LENGTH (sizeof(XXH64_hash_t) * 2 + 2 + 4096 + 1)
+
+/* Maximum acceptable line length. */
+#define MAX_LINE_LENGTH (32 KB)
+
+
+/* ************************************
+ * Display macros
+ **************************************/
+#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
+#define DISPLAYRESULT(...) fprintf(stdout, __VA_ARGS__)
+#define DISPLAYLEVEL(l, ...) do { if (g_displayLevel>=l) DISPLAY(__VA_ARGS__); } while (0)
+static int g_displayLevel = 2;
+
+
+/* ************************************
+ * Local variables
+ **************************************/
+static U32 g_nbIterations = NBLOOPS;
+
+
+/* ************************************
+ * Benchmark Functions
+ **************************************/
+static clock_t BMK_clockSpan( clock_t start )
+{
+ return clock() - start; /* works even if overflow; Typical max span ~ 30 mn */
+}
+
+
+static size_t BMK_findMaxMem(U64 requiredMem)
+{
+ size_t const step = 64 MB;
+ void* testmem = NULL;
+
+ requiredMem = (((requiredMem >> 26) + 1) << 26);
+ requiredMem += 2*step;
+ if (requiredMem > MAX_MEM) requiredMem = MAX_MEM;
+
+ while (!testmem) {
+ if (requiredMem > step) requiredMem -= step;
+ else requiredMem >>= 1;
+ testmem = malloc ((size_t)requiredMem);
+ }
+ free (testmem);
+
+ /* keep some space available */
+ if (requiredMem > step) requiredMem -= step;
+ else requiredMem >>= 1;
+
+ return (size_t)requiredMem;
+}
+
+
+static U64 BMK_GetFileSize(const char* infilename)
+{
+ int r;
+#if defined(_MSC_VER)
+ struct _stat64 statbuf;
+ r = _stat64(infilename, &statbuf);
+#else
+ struct stat statbuf;
+ r = stat(infilename, &statbuf);
+#endif
+ if (r || !S_ISREG(statbuf.st_mode)) return 0; /* No good... */
+ return (U64)statbuf.st_size;
+}
+
+typedef U32 (*hashFunction)(const void* buffer, size_t bufferSize, U32 seed);
+
+static U32 localXXH32(const void* buffer, size_t bufferSize, U32 seed) { return XXH32(buffer, bufferSize, seed); }
+
+static U32 localXXH64(const void* buffer, size_t bufferSize, U32 seed) { return (U32)XXH64(buffer, bufferSize, seed); }
+
+static void BMK_benchHash(hashFunction h, const char* hName, const void* buffer, size_t bufferSize)
+{
+ U32 nbh_perIteration = ((300 MB) / (bufferSize+1)) + 1; /* first loop conservatively aims for 300 MB/s */
+ U32 iterationNb;
+ double fastestH = 100000000.;
+
+ DISPLAYLEVEL(2, "\r%70s\r", ""); /* Clean display line */
+ if (g_nbIterations<1) g_nbIterations=1;
+ for (iterationNb = 1; iterationNb <= g_nbIterations; iterationNb++) {
+ U32 r=0;
+ clock_t cStart;
+
+ DISPLAYLEVEL(2, "%1i-%-17.17s : %10u ->\r", iterationNb, hName, (U32)bufferSize);
+ cStart = clock();
+ while (clock() == cStart); /* starts clock() at its exact beginning */
+ cStart = clock();
+
+ { U32 i;
+ for (i=0; i<nbh_perIteration; i++)
+ r += h(buffer, bufferSize, i);
+ }
+ if (r==0) DISPLAYLEVEL(3,".\r"); /* do something with r to avoid compiler "optimizing" away hash function */
+ { double const timeS = ((double)BMK_clockSpan(cStart) / CLOCKS_PER_SEC) / nbh_perIteration;
+ if (timeS < fastestH) fastestH = timeS;
+ DISPLAYLEVEL(2, "%1i-%-17.17s : %10u -> %8.0f it/s (%7.1f MB/s) \r",
+ iterationNb, hName, (U32)bufferSize,
+ (double)1 / fastestH,
+ ((double)bufferSize / (1<<20)) / fastestH );
+ }
+ assert(fastestH > 1./2000000000); /* avoid U32 overflow */
+ nbh_perIteration = (U32)(1 / fastestH) + 1; /* adjust nbh_perIteration to last roughtly one second */
+ }
+ DISPLAYLEVEL(1, "%-19.19s : %10u -> %8.0f it/s (%7.1f MB/s) \n", hName, (U32)bufferSize,
+ (double)1 / fastestH,
+ ((double)bufferSize / (1<<20)) / fastestH);
+ if (g_displayLevel<1)
+ DISPLAYLEVEL(0, "%u, ", (U32)((double)1 / fastestH));
+}
+
+
+/* BMK_benchMem():
+ * specificTest : 0 == run all tests, 1+ run only specific test
+ * buffer : is supposed 8-bytes aligned (if malloc'ed, it should be)
+ * the real allocated size of buffer is supposed to be >= (bufferSize+3).
+ * @return : 0 on success, 1 if error (invalid mode selected) */
+static int BMK_benchMem(const void* buffer, size_t bufferSize, U32 specificTest)
+{
+ assert((((size_t)buffer) & 8) == 0); /* ensure alignment */
+
+ /* XXH32 bench */
+ if ((specificTest==0) | (specificTest==1))
+ BMK_benchHash(localXXH32, "XXH32", buffer, bufferSize);
+
+ /* Bench XXH32 on Unaligned input */
+ if ((specificTest==0) | (specificTest==2))
+ BMK_benchHash(localXXH32, "XXH32 unaligned", ((const char*)buffer)+1, bufferSize);
+
+ /* Bench XXH64 */
+ if ((specificTest==0) | (specificTest==3))
+ BMK_benchHash(localXXH64, "XXH64", buffer, bufferSize);
+
+ /* Bench XXH64 on Unaligned input */
+ if ((specificTest==0) | (specificTest==4))
+ BMK_benchHash(localXXH64, "XXH64 unaligned", ((const char*)buffer)+3, bufferSize);
+
+ if (specificTest > 4) {
+ DISPLAY("benchmark mode invalid \n");
+ return 1;
+ }
+ return 0;
+}
+
+
+static size_t BMK_selectBenchedSize(const char* fileName)
+{ U64 const inFileSize = BMK_GetFileSize(fileName);
+ size_t benchedSize = (size_t) BMK_findMaxMem(inFileSize);
+ if ((U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize;
+ if (benchedSize < inFileSize) {
+ DISPLAY("Not enough memory for '%s' full size; testing %i MB only...\n", fileName, (int)(benchedSize>>20));
+ }
+ return benchedSize;
+}
+
+
+static int BMK_benchFiles(const char** fileNamesTable, int nbFiles, U32 specificTest)
+{
+ int result = 0;
+ int fileIdx;
+
+ for (fileIdx=0; fileIdx<nbFiles; fileIdx++) {
+ const char* const inFileName = fileNamesTable[fileIdx];
+ FILE* const inFile = fopen( inFileName, "rb" );
+ size_t const benchedSize = BMK_selectBenchedSize(inFileName);
+ char* const buffer = (char*)calloc(benchedSize+16+3, 1);
+ void* const alignedBuffer = (buffer+15) - (((size_t)(buffer+15)) & 0xF); /* align on next 16 bytes */
+
+ /* Checks */
+ if ((inFile==NULL) || (inFileName==NULL)) {
+ DISPLAY("Pb opening %s\n", inFileName);
+ free(buffer);
+ return 11;
+ }
+ if(!buffer) {
+ DISPLAY("\nError: not enough memory!\n");
+ fclose(inFile);
+ return 12;
+ }
+
+ /* Fill input buffer */
+ DISPLAYLEVEL(1, "\rLoading %s... \n", inFileName);
+ { size_t const readSize = fread(alignedBuffer, 1, benchedSize, inFile);
+ fclose(inFile);
+ if(readSize != benchedSize) {
+ DISPLAY("\nError: problem reading file '%s' !! \n", inFileName);
+ free(buffer);
+ return 13;
+ } }
+
+ /* bench */
+ result |= BMK_benchMem(alignedBuffer, benchedSize, specificTest);
+
+ free(buffer);
+ }
+
+ return result;
+}
+
+
+
+static int BMK_benchInternal(size_t keySize, int specificTest)
+{
+ void* const buffer = calloc(keySize+16+3, 1);
+ void* const alignedBuffer = ((char*)buffer+15) - (((size_t)((char*)buffer+15)) & 0xF); /* align on next 16 bytes */
+ if(!buffer) {
+ DISPLAY("\nError: not enough memory!\n");
+ return 12;
+ }
+
+ /* bench */
+ DISPLAYLEVEL(1, "Sample of ");
+ if (keySize > 10 KB) {
+ DISPLAYLEVEL(1, "%u KB", (U32)(keySize >> 10));
+ } else {
+ DISPLAYLEVEL(1, "%u bytes", (U32)keySize);
+ }
+ DISPLAYLEVEL(1, "... \n");
+
+ { int const result = BMK_benchMem(alignedBuffer, keySize, specificTest);
+ free(buffer);
+ return result;
+ }
+}
+
+
+static void BMK_checkResult(U32 r1, U32 r2)
+{
+ static int nbTests = 1;
+ if (r1==r2) {
+ DISPLAYLEVEL(3, "\rTest%3i : %08X == %08X ok ", nbTests, r1, r2);
+ } else {
+ DISPLAY("\rERROR : Test%3i : %08X <> %08X !!!!! \n", nbTests, r1, r2);
+ exit(1);
+ }
+ nbTests++;
+}
+
+
+static void BMK_checkResult64(U64 r1, U64 r2)
+{
+ static int nbTests = 1;
+ if (r1!=r2) {
+ DISPLAY("\rERROR : Test%3i : 64-bit values non equals !!!!! \n", nbTests);
+ DISPLAY("\r %08X%08X != %08X%08X \n", (U32)(r1>>32), (U32)r1, (U32)(r2>>32), (U32)r2);
+ exit(1);
+ }
+ nbTests++;
+}
+
+
+static void BMK_testSequence64(void* sentence, size_t len, U64 seed, U64 Nresult)
+{
+ XXH64_state_t state;
+ U64 Dresult;
+ size_t pos;
+
+ Dresult = XXH64(sentence, len, seed);
+ BMK_checkResult64(Dresult, Nresult);
+
+ XXH64_reset(&state, seed);
+ XXH64_update(&state, sentence, len);
+ Dresult = XXH64_digest(&state);
+ BMK_checkResult64(Dresult, Nresult);
+
+ XXH64_reset(&state, seed);
+ for (pos=0; pos<len; pos++)
+ XXH64_update(&state, ((char*)sentence)+pos, 1);
+ Dresult = XXH64_digest(&state);
+ BMK_checkResult64(Dresult, Nresult);
+}
+
+
+static void BMK_testSequence(const void* sequence, size_t len, U32 seed, U32 Nresult)
+{
+ XXH32_state_t state;
+ U32 Dresult;
+ size_t pos;
+
+ Dresult = XXH32(sequence, len, seed);
+ BMK_checkResult(Dresult, Nresult);
+
+ XXH32_reset(&state, seed);
+ XXH32_update(&state, sequence, len);
+ Dresult = XXH32_digest(&state);
+ BMK_checkResult(Dresult, Nresult);
+
+ XXH32_reset(&state, seed);
+ for (pos=0; pos<len; pos++)
+ XXH32_update(&state, ((const char*)sequence)+pos, 1);
+ Dresult = XXH32_digest(&state);
+ BMK_checkResult(Dresult, Nresult);
+}
+
+
+#define SANITY_BUFFER_SIZE 101
+static void BMK_sanityCheck(void)
+{
+ static const U32 prime = 2654435761U;
+ BYTE sanityBuffer[SANITY_BUFFER_SIZE];
+ U32 byteGen = prime;
+
+ int i;
+ for (i=0; i<SANITY_BUFFER_SIZE; i++) {
+ sanityBuffer[i] = (BYTE)(byteGen>>24);
+ byteGen *= byteGen;
+ }
+
+ BMK_testSequence(NULL, 0, 0, 0x02CC5D05);
+ BMK_testSequence(NULL, 0, prime, 0x36B78AE7);
+ BMK_testSequence(sanityBuffer, 1, 0, 0xB85CBEE5);
+ BMK_testSequence(sanityBuffer, 1, prime, 0xD5845D64);
+ BMK_testSequence(sanityBuffer, 14, 0, 0xE5AA0AB4);
+ BMK_testSequence(sanityBuffer, 14, prime, 0x4481951D);
+ BMK_testSequence(sanityBuffer, SANITY_BUFFER_SIZE, 0, 0x1F1AA412);
+ BMK_testSequence(sanityBuffer, SANITY_BUFFER_SIZE, prime, 0x498EC8E2);
+
+ BMK_testSequence64(NULL , 0, 0, 0xEF46DB3751D8E999ULL);
+ BMK_testSequence64(NULL , 0, prime, 0xAC75FDA2929B17EFULL);
+ BMK_testSequence64(sanityBuffer, 1, 0, 0x4FCE394CC88952D8ULL);
+ BMK_testSequence64(sanityBuffer, 1, prime, 0x739840CB819FA723ULL);
+ BMK_testSequence64(sanityBuffer, 14, 0, 0xCFFA8DB881BC3A3DULL);
+ BMK_testSequence64(sanityBuffer, 14, prime, 0x5B9611585EFCC9CBULL);
+ BMK_testSequence64(sanityBuffer, SANITY_BUFFER_SIZE, 0, 0x0EAB543384F878ADULL);
+ BMK_testSequence64(sanityBuffer, SANITY_BUFFER_SIZE, prime, 0xCAA65939306F1E21ULL);
+
+ DISPLAYLEVEL(3, "\r%70s\r", ""); /* Clean display line */
+ DISPLAYLEVEL(3, "Sanity check -- all tests ok\n");
+}
+
+
+/* ********************************************************
+* File Hashing
+**********************************************************/
+
+static void BMK_display_LittleEndian(const void* ptr, size_t length)
+{
+ const BYTE* p = (const BYTE*)ptr;
+ size_t idx;
+ for (idx=length-1; idx<length; idx--) /* intentional underflow to negative to detect end */
+ DISPLAYRESULT("%02x", p[idx]);
+}
+
+static void BMK_display_BigEndian(const void* ptr, size_t length)
+{
+ const BYTE* p = (const BYTE*)ptr;
+ size_t idx;
+ for (idx=0; idx<length; idx++)
+ DISPLAYRESULT("%02x", p[idx]);
+}
+
+static void BMK_hashStream(void* xxhHashValue, const algoType hashType, FILE* inFile, void* buffer, size_t blockSize)
+{
+ XXH64_state_t state64;
+ XXH32_state_t state32;
+ size_t readSize;
+
+ /* Init */
+ XXH32_reset(&state32, XXHSUM32_DEFAULT_SEED);
+ XXH64_reset(&state64, XXHSUM64_DEFAULT_SEED);
+
+ /* Load file & update hash */
+ readSize = 1;
+ while (readSize) {
+ readSize = fread(buffer, 1, blockSize, inFile);
+ switch(hashType)
+ {
+ case algo_xxh32:
+ XXH32_update(&state32, buffer, readSize);
+ break;
+ case algo_xxh64:
+ XXH64_update(&state64, buffer, readSize);
+ break;
+ default:
+ break;
+ }
+ }
+
+ switch(hashType)
+ {
+ case algo_xxh32:
+ { U32 const h32 = XXH32_digest(&state32);
+ memcpy(xxhHashValue, &h32, sizeof(h32));
+ break;
+ }
+ case algo_xxh64:
+ { U64 const h64 = XXH64_digest(&state64);
+ memcpy(xxhHashValue, &h64, sizeof(h64));
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+
+typedef enum { big_endian, little_endian} endianess;
+
+static int BMK_hash(const char* fileName,
+ const algoType hashType,
+ const endianess displayEndianess)
+{
+ FILE* inFile;
+ size_t const blockSize = 64 KB;
+ void* buffer;
+ U32 h32 = 0;
+ U64 h64 = 0;
+
+ /* Check file existence */
+ if (fileName == stdinName) {
+ inFile = stdin;
+ SET_BINARY_MODE(stdin);
+ }
+ else
+ inFile = fopen( fileName, "rb" );
+ if (inFile==NULL) {
+ DISPLAY( "Pb opening %s\n", fileName);
+ return 1;
+ }
+
+ /* Memory allocation & restrictions */
+ buffer = malloc(blockSize);
+ if(!buffer) {
+ DISPLAY("\nError: not enough memory!\n");
+ fclose(inFile);
+ return 1;
+ }
+
+ /* loading notification */
+ { const size_t fileNameSize = strlen(fileName);
+ const char* const fileNameEnd = fileName + fileNameSize;
+ const int maxInfoFilenameSize = (int)(fileNameSize > 30 ? 30 : fileNameSize);
+ int infoFilenameSize = 1;
+ while ((infoFilenameSize < maxInfoFilenameSize)
+ && (fileNameEnd[-1-infoFilenameSize] != '/')
+ && (fileNameEnd[-1-infoFilenameSize] != '\\') )
+ infoFilenameSize++;
+ DISPLAY("\rLoading %s... \r", fileNameEnd - infoFilenameSize);
+
+ /* Load file & update hash */
+ switch(hashType)
+ {
+ case algo_xxh32:
+ BMK_hashStream(&h32, algo_xxh32, inFile, buffer, blockSize);
+ break;
+ case algo_xxh64:
+ BMK_hashStream(&h64, algo_xxh64, inFile, buffer, blockSize);
+ break;
+ default:
+ break;
+ }
+
+ fclose(inFile);
+ free(buffer);
+ DISPLAY("%s \r", fileNameEnd - infoFilenameSize); /* erase line */
+ }
+
+ /* display Hash */
+ switch(hashType)
+ {
+ case algo_xxh32:
+ { XXH32_canonical_t hcbe32;
+ XXH32_canonicalFromHash(&hcbe32, h32);
+ displayEndianess==big_endian ?
+ BMK_display_BigEndian(&hcbe32, sizeof(hcbe32)) : BMK_display_LittleEndian(&hcbe32, sizeof(hcbe32));
+ DISPLAYRESULT(" %s\n", fileName);
+ break;
+ }
+ case algo_xxh64:
+ { XXH64_canonical_t hcbe64;
+ XXH64_canonicalFromHash(&hcbe64, h64);
+ displayEndianess==big_endian ?
+ BMK_display_BigEndian(&hcbe64, sizeof(hcbe64)) : BMK_display_LittleEndian(&hcbe64, sizeof(hcbe64));
+ DISPLAYRESULT(" %s\n", fileName);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+
+static int BMK_hashFiles(const char** fnList, int fnTotal,
+ algoType hashType, endianess displayEndianess)
+{
+ int fnNb;
+ int result = 0;
+
+ if (fnTotal==0)
+ return BMK_hash(stdinName, hashType, displayEndianess);
+
+ for (fnNb=0; fnNb<fnTotal; fnNb++)
+ result += BMK_hash(fnList[fnNb], hashType, displayEndianess);
+ DISPLAY("\r%70s\r", "");
+ return result;
+}
+
+
+typedef enum {
+ GetLine_ok,
+ GetLine_eof,
+ GetLine_exceedMaxLineLength,
+ GetLine_outOfMemory,
+} GetLineResult;
+
+typedef enum {
+ CanonicalFromString_ok,
+ CanonicalFromString_invalidFormat,
+} CanonicalFromStringResult;
+
+typedef enum {
+ ParseLine_ok,
+ ParseLine_invalidFormat,
+} ParseLineResult;
+
+typedef enum {
+ LineStatus_hashOk,
+ LineStatus_hashFailed,
+ LineStatus_failedToOpen,
+} LineStatus;
+
+typedef union {
+ XXH32_canonical_t xxh32;
+ XXH64_canonical_t xxh64;
+} Canonical;
+
+typedef struct {
+ Canonical canonical;
+ const char* filename;
+ int xxhBits; /* canonical type : 32:xxh32, 64:xxh64 */
+} ParsedLine;
+
+typedef struct {
+ unsigned long nProperlyFormattedLines;
+ unsigned long nImproperlyFormattedLines;
+ unsigned long nMismatchedChecksums;
+ unsigned long nOpenOrReadFailures;
+ unsigned long nMixedFormatLines;
+ int xxhBits;
+ int quit;
+} ParseFileReport;
+
+typedef struct {
+ const char* inFileName;
+ FILE* inFile;
+ int lineMax;
+ char* lineBuf;
+ size_t blockSize;
+ char* blockBuf;
+ int strictMode;
+ int statusOnly;
+ int warn;
+ int quiet;
+ ParseFileReport report;
+} ParseFileArg;
+
+
+/* Read line from stream.
+ Returns GetLine_ok, if it reads line successfully.
+ Returns GetLine_eof, if stream reaches EOF.
+ Returns GetLine_exceedMaxLineLength, if line length is longer than MAX_LINE_LENGTH.
+ Returns GetLine_outOfMemory, if line buffer memory allocation failed.
+ */
+static GetLineResult getLine(char** lineBuf, int* lineMax, FILE* inFile)
+{
+ GetLineResult result = GetLine_ok;
+ int len = 0;
+
+ if ((*lineBuf == NULL) || (*lineMax<1)) {
+ free(*lineBuf); /* in case it's != NULL */
+ *lineMax = 0;
+ *lineBuf = (char*)malloc(DEFAULT_LINE_LENGTH);
+ if(*lineBuf == NULL) return GetLine_outOfMemory;
+ *lineMax = DEFAULT_LINE_LENGTH;
+ }
+
+ for (;;) {
+ const int c = fgetc(inFile);
+ if (c == EOF) {
+ /* If we meet EOF before first character, returns GetLine_eof,
+ * otherwise GetLine_ok.
+ */
+ if (len == 0) result = GetLine_eof;
+ break;
+ }
+
+ /* Make enough space for len+1 (for final NUL) bytes. */
+ if (len+1 >= *lineMax) {
+ char* newLineBuf = NULL;
+ int newBufSize = *lineMax;
+
+ newBufSize += (newBufSize/2) + 1; /* x 1.5 */
+ if (newBufSize > MAX_LINE_LENGTH) newBufSize = MAX_LINE_LENGTH;
+ if (len+1 >= newBufSize) return GetLine_exceedMaxLineLength;
+
+ newLineBuf = (char*) realloc(*lineBuf, newBufSize);
+ if (newLineBuf == NULL) return GetLine_outOfMemory;
+
+ *lineBuf = newLineBuf;
+ *lineMax = newBufSize;
+ }
+
+ if (c == '\n') break;
+ (*lineBuf)[len++] = (char) c;
+ }
+
+ (*lineBuf)[len] = '\0';
+ return result;
+}
+
+
+/* Converts one hexadecimal character to integer.
+ * Returns -1, if given character is not hexadecimal.
+ */
+static int charToHex(char c)
+{
+ int result = -1;
+ if (c >= '0' && c <= '9') {
+ result = (int) (c - '0');
+ } else if (c >= 'A' && c <= 'F') {
+ result = (int) (c - 'A') + 0x0a;
+ } else if (c >= 'a' && c <= 'f') {
+ result = (int) (c - 'a') + 0x0a;
+ }
+ return result;
+}
+
+
+/* Converts XXH32 canonical hexadecimal string hashStr to big endian unsigned char array dst.
+ * Returns CANONICAL_FROM_STRING_INVALID_FORMAT, if hashStr is not well formatted.
+ * Returns CANONICAL_FROM_STRING_OK, if hashStr is parsed successfully.
+ */
+static CanonicalFromStringResult canonicalFromString(unsigned char* dst,
+ size_t dstSize,
+ const char* hashStr)
+{
+ size_t i;
+ for (i = 0; i < dstSize; ++i) {
+ int h0, h1;
+
+ h0 = charToHex(hashStr[i*2 + 0]);
+ if (h0 < 0) return CanonicalFromString_invalidFormat;
+
+ h1 = charToHex(hashStr[i*2 + 1]);
+ if (h1 < 0) return CanonicalFromString_invalidFormat;
+
+ dst[i] = (unsigned char) ((h0 << 4) | h1);
+ }
+ return CanonicalFromString_ok;
+}
+
+
+/* Parse single line of xxHash checksum file.
+ * Returns PARSE_LINE_ERROR_INVALID_FORMAT, if line is not well formatted.
+ * Returns PARSE_LINE_OK if line is parsed successfully.
+ * And members of parseLine will be filled by parsed values.
+ *
+ * - line must be ended with '\0'.
+ * - Since parsedLine.filename will point within given argument `line`,
+ * users must keep `line`s content during they are using parsedLine.
+ *
+ * Given xxHash checksum line should have the following format:
+ *
+ * <8 or 16 hexadecimal char> <space> <space> <filename...> <'\0'>
+ */
+static ParseLineResult parseLine(ParsedLine* parsedLine, const char* line)
+{
+ const char* const firstSpace = strchr(line, ' ');
+ const char* const secondSpace = firstSpace + 1;
+
+ parsedLine->filename = NULL;
+ parsedLine->xxhBits = 0;
+
+ if (firstSpace == NULL || *secondSpace != ' ') return ParseLine_invalidFormat;
+
+ switch (firstSpace - line)
+ {
+ case 8:
+ { XXH32_canonical_t* xxh32c = &parsedLine->canonical.xxh32;
+ if (canonicalFromString(xxh32c->digest, sizeof(xxh32c->digest), line)
+ != CanonicalFromString_ok) {
+ return ParseLine_invalidFormat;
+ }
+ parsedLine->xxhBits = 32;
+ break;
+ }
+
+ case 16:
+ { XXH64_canonical_t* xxh64c = &parsedLine->canonical.xxh64;
+ if (canonicalFromString(xxh64c->digest, sizeof(xxh64c->digest), line)
+ != CanonicalFromString_ok) {
+ return ParseLine_invalidFormat;
+ }
+ parsedLine->xxhBits = 64;
+ break;
+ }
+
+ default:
+ return ParseLine_invalidFormat;
+ break;
+ }
+
+ parsedLine->filename = secondSpace + 1;
+ return ParseLine_ok;
+}
+
+
+/*! Parse xxHash checksum file.
+ */
+static void parseFile1(ParseFileArg* parseFileArg)
+{
+ const char* const inFileName = parseFileArg->inFileName;
+ ParseFileReport* const report = &parseFileArg->report;
+
+ unsigned long lineNumber = 0;
+ memset(report, 0, sizeof(*report));
+
+ while (!report->quit) {
+ FILE* fp = NULL;
+ LineStatus lineStatus = LineStatus_hashFailed;
+ GetLineResult getLineResult;
+ ParsedLine parsedLine;
+ memset(&parsedLine, 0, sizeof(parsedLine));
+
+ lineNumber++;
+ if (lineNumber == 0) {
+ /* This is unlikely happen, but md5sum.c has this
+ * error check. */
+ DISPLAY("%s : too many checksum lines\n", inFileName);
+ report->quit = 1;
+ break;
+ }
+
+ getLineResult = getLine(&parseFileArg->lineBuf, &parseFileArg->lineMax,
+ parseFileArg->inFile);
+ if (getLineResult != GetLine_ok) {
+ if (getLineResult == GetLine_eof) break;
+
+ switch (getLineResult)
+ {
+ case GetLine_ok:
+ case GetLine_eof:
+ /* These cases never happen. See above getLineResult related "if"s.
+ They exist just for make gcc's -Wswitch-enum happy. */
+ break;
+
+ default:
+ DISPLAY("%s : %lu: unknown error\n", inFileName, lineNumber);
+ break;
+
+ case GetLine_exceedMaxLineLength:
+ DISPLAY("%s : %lu: too long line\n", inFileName, lineNumber);
+ break;
+
+ case GetLine_outOfMemory:
+ DISPLAY("%s : %lu: out of memory\n", inFileName, lineNumber);
+ break;
+ }
+ report->quit = 1;
+ break;
+ }
+
+ if (parseLine(&parsedLine, parseFileArg->lineBuf) != ParseLine_ok) {
+ report->nImproperlyFormattedLines++;
+ if (parseFileArg->warn) {
+ DISPLAY("%s : %lu: improperly formatted XXHASH checksum line\n"
+ , inFileName, lineNumber);
+ }
+ continue;
+ }
+
+ if (report->xxhBits != 0 && report->xxhBits != parsedLine.xxhBits) {
+ /* Don't accept xxh32/xxh64 mixed file */
+ report->nImproperlyFormattedLines++;
+ report->nMixedFormatLines++;
+ if (parseFileArg->warn) {
+ DISPLAY("%s : %lu: improperly formatted XXHASH checksum line (XXH32/64)\n"
+ , inFileName, lineNumber);
+ }
+ continue;
+ }
+
+ report->nProperlyFormattedLines++;
+ if (report->xxhBits == 0) {
+ report->xxhBits = parsedLine.xxhBits;
+ }
+
+ fp = fopen(parsedLine.filename, "rb");
+ if (fp == NULL) {
+ lineStatus = LineStatus_failedToOpen;
+ } else {
+ lineStatus = LineStatus_hashFailed;
+ switch (parsedLine.xxhBits)
+ {
+ case 32:
+ { XXH32_hash_t xxh;
+ BMK_hashStream(&xxh, algo_xxh32, fp, parseFileArg->blockBuf, parseFileArg->blockSize);
+ if (xxh == XXH32_hashFromCanonical(&parsedLine.canonical.xxh32)) {
+ lineStatus = LineStatus_hashOk;
+ } }
+ break;
+
+ case 64:
+ { XXH64_hash_t xxh;
+ BMK_hashStream(&xxh, algo_xxh64, fp, parseFileArg->blockBuf, parseFileArg->blockSize);
+ if (xxh == XXH64_hashFromCanonical(&parsedLine.canonical.xxh64)) {
+ lineStatus = LineStatus_hashOk;
+ } }
+ break;
+
+ default:
+ break;
+ }
+ fclose(fp);
+ }
+
+ switch (lineStatus)
+ {
+ default:
+ DISPLAY("%s : unknown error\n", inFileName);
+ report->quit = 1;
+ break;
+
+ case LineStatus_failedToOpen:
+ report->nOpenOrReadFailures++;
+ if (!parseFileArg->statusOnly) {
+ DISPLAYRESULT("%s : %lu: FAILED open or read %s\n"
+ , inFileName, lineNumber, parsedLine.filename);
+ }
+ break;
+
+ case LineStatus_hashOk:
+ case LineStatus_hashFailed:
+ { int b = 1;
+ if (lineStatus == LineStatus_hashOk) {
+ /* If --quiet is specified, don't display "OK" */
+ if (parseFileArg->quiet) b = 0;
+ } else {
+ report->nMismatchedChecksums++;
+ }
+
+ if (b && !parseFileArg->statusOnly) {
+ DISPLAYRESULT("%s: %s\n", parsedLine.filename
+ , lineStatus == LineStatus_hashOk ? "OK" : "FAILED");
+ } }
+ break;
+ }
+ } /* while (!report->quit) */
+}
+
+
+/* Parse xxHash checksum file.
+ * Returns 1, if all procedures were succeeded.
+ * Returns 0, if any procedures was failed.
+ *
+ * If strictMode != 0, return error code if any line is invalid.
+ * If statusOnly != 0, don't generate any output.
+ * If warn != 0, print a warning message to stderr.
+ * If quiet != 0, suppress "OK" line.
+ *
+ * "All procedures are succeeded" means:
+ * - Checksum file contains at least one line and less than SIZE_T_MAX lines.
+ * - All files are properly opened and read.
+ * - All hash values match with its content.
+ * - (strict mode) All lines in checksum file are consistent and well formatted.
+ *
+ */
+static int checkFile(const char* inFileName,
+ const endianess displayEndianess,
+ U32 strictMode,
+ U32 statusOnly,
+ U32 warn,
+ U32 quiet)
+{
+ int result = 0;
+ FILE* inFile = NULL;
+ ParseFileArg parseFileArgBody;
+ ParseFileArg* const parseFileArg = &parseFileArgBody;
+ ParseFileReport* const report = &parseFileArg->report;
+
+ if (displayEndianess != big_endian) {
+ /* Don't accept little endian */
+ DISPLAY( "Check file mode doesn't support little endian\n" );
+ return 0;
+ }
+
+ /* note : stdinName is special constant pointer. It is not a string. */
+ if (inFileName == stdinName) {
+ /* note : Since we expect text input for xxhash -c mode,
+ * Don't set binary mode for stdin */
+ inFile = stdin;
+ } else {
+ inFile = fopen( inFileName, "rt" );
+ }
+
+ if (inFile == NULL) {
+ DISPLAY( "Pb opening %s\n", inFileName);
+ return 0;
+ }
+
+ parseFileArg->inFileName = inFileName;
+ parseFileArg->inFile = inFile;
+ parseFileArg->lineMax = DEFAULT_LINE_LENGTH;
+ parseFileArg->lineBuf = (char*) malloc((size_t) parseFileArg->lineMax);
+ parseFileArg->blockSize = 64 * 1024;
+ parseFileArg->blockBuf = (char*) malloc(parseFileArg->blockSize);
+ parseFileArg->strictMode = strictMode;
+ parseFileArg->statusOnly = statusOnly;
+ parseFileArg->warn = warn;
+ parseFileArg->quiet = quiet;
+
+ parseFile1(parseFileArg);
+
+ free(parseFileArg->blockBuf);
+ free(parseFileArg->lineBuf);
+
+ if (inFile != stdin) fclose(inFile);
+
+ /* Show error/warning messages. All messages are copied from md5sum.c
+ */
+ if (report->nProperlyFormattedLines == 0) {
+ DISPLAY("%s: no properly formatted XXHASH checksum lines found\n", inFileName);
+ } else if (!statusOnly) {
+ if (report->nImproperlyFormattedLines) {
+ DISPLAYRESULT("%lu lines are improperly formatted\n"
+ , report->nImproperlyFormattedLines);
+ }
+ if (report->nOpenOrReadFailures) {
+ DISPLAYRESULT("%lu listed files could not be read\n"
+ , report->nOpenOrReadFailures);
+ }
+ if (report->nMismatchedChecksums) {
+ DISPLAYRESULT("%lu computed checksums did NOT match\n"
+ , report->nMismatchedChecksums);
+ } }
+
+ /* Result (exit) code logic is copied from
+ * gnu coreutils/src/md5sum.c digest_check() */
+ result = report->nProperlyFormattedLines != 0
+ && report->nMismatchedChecksums == 0
+ && report->nOpenOrReadFailures == 0
+ && (!strictMode || report->nImproperlyFormattedLines == 0)
+ && report->quit == 0;
+ return result;
+}
+
+
+static int checkFiles(const char** fnList, int fnTotal,
+ const endianess displayEndianess,
+ U32 strictMode,
+ U32 statusOnly,
+ U32 warn,
+ U32 quiet)
+{
+ int ok = 1;
+
+ /* Special case for stdinName "-",
+ * note: stdinName is not a string. It's special pointer. */
+ if (fnTotal==0) {
+ ok &= checkFile(stdinName, displayEndianess, strictMode, statusOnly, warn, quiet);
+ } else {
+ int fnNb;
+ for (fnNb=0; fnNb<fnTotal; fnNb++)
+ ok &= checkFile(fnList[fnNb], displayEndianess, strictMode, statusOnly, warn, quiet);
+ }
+ return ok ? 0 : 1;
+}
+
+
+/* ********************************************************
+* Main
+**********************************************************/
+
+static int usage(const char* exename)
+{
+ DISPLAY( WELCOME_MESSAGE(exename) );
+ DISPLAY( "Usage :\n");
+ DISPLAY( " %s [arg] [filenames]\n", exename);
+ DISPLAY( "When no filename provided, or - provided : use stdin as input\n");
+ DISPLAY( "Arguments :\n");
+ DISPLAY( " -H# : hash selection : 0=32bits, 1=64bits (default: %i)\n", (int)g_defaultAlgo);
+ DISPLAY( " -c : read xxHash sums from the [filenames] and check them\n");
+ DISPLAY( " -h : help \n");
+ return 0;
+}
+
+
+static int usage_advanced(const char* exename)
+{
+ usage(exename);
+ DISPLAY( "Advanced :\n");
+ DISPLAY( " --little-endian : hash printed using little endian convention (default: big endian)\n");
+ DISPLAY( " -V, --version : display version\n");
+ DISPLAY( " -h, --help : display long help and exit\n");
+ DISPLAY( " -b : benchmark mode \n");
+ DISPLAY( " -i# : number of iterations (benchmark mode; default %i)\n", g_nbIterations);
+ DISPLAY( "\n");
+ DISPLAY( "The following four options are useful only when verifying checksums (-c):\n");
+ DISPLAY( "--strict : don't print OK for each successfully verified file\n");
+ DISPLAY( "--status : don't output anything, status code shows success\n");
+ DISPLAY( "--quiet : exit non-zero for improperly formatted checksum lines\n");
+ DISPLAY( "--warn : warn about improperly formatted checksum lines\n");
+ return 0;
+}
+
+static int badusage(const char* exename)
+{
+ DISPLAY("Wrong parameters\n");
+ usage(exename);
+ return 1;
+}
+
+/*! readU32FromChar() :
+ @return : unsigned integer value read from input in `char` format,
+ 0 is no figure at *stringPtr position.
+ Interprets K, KB, KiB, M, MB and MiB suffix.
+ Modifies `*stringPtr`, advancing it to position where reading stopped.
+ Note : function result can overflow if digit string > MAX_UINT */
+static unsigned readU32FromChar(const char** stringPtr)
+{
+ unsigned result = 0;
+ while ((**stringPtr >='0') && (**stringPtr <='9'))
+ result *= 10, result += **stringPtr - '0', (*stringPtr)++ ;
+ if ((**stringPtr=='K') || (**stringPtr=='M')) {
+ result <<= 10;
+ if (**stringPtr=='M') result <<= 10;
+ (*stringPtr)++ ;
+ if (**stringPtr=='i') (*stringPtr)++;
+ if (**stringPtr=='B') (*stringPtr)++;
+ }
+ return result;
+}
+
+int main(int argc, const char** argv)
+{
+ int i, filenamesStart = 0;
+ const char* const exename = argv[0];
+ U32 benchmarkMode = 0;
+ U32 fileCheckMode = 0;
+ U32 strictMode = 0;
+ U32 statusOnly = 0;
+ U32 warn = 0;
+ U32 quiet = 0;
+ U32 specificTest = 0;
+ size_t keySize = XXH_DEFAULT_SAMPLE_SIZE;
+ algoType algo = g_defaultAlgo;
+ endianess displayEndianess = big_endian;
+
+ /* special case : xxh32sum default to 32 bits checksum */
+ if (strstr(exename, "xxh32sum") != NULL) algo = algo_xxh32;
+
+ for(i=1; i<argc; i++) {
+ const char* argument = argv[i];
+
+ if(!argument) continue; /* Protection, if argument empty */
+
+ if (!strcmp(argument, "--little-endian")) { displayEndianess = little_endian; continue; }
+ if (!strcmp(argument, "--check")) { fileCheckMode = 1; continue; }
+ if (!strcmp(argument, "--strict")) { strictMode = 1; continue; }
+ if (!strcmp(argument, "--status")) { statusOnly = 1; continue; }
+ if (!strcmp(argument, "--quiet")) { quiet = 1; continue; }
+ if (!strcmp(argument, "--warn")) { warn = 1; continue; }
+ if (!strcmp(argument, "--help")) { return usage_advanced(exename); }
+ if (!strcmp(argument, "--version")) { DISPLAY(WELCOME_MESSAGE(exename)); return 0; }
+
+ if (*argument!='-') {
+ if (filenamesStart==0) filenamesStart=i; /* only supports a continuous list of filenames */
+ continue;
+ }
+
+ /* command selection */
+ argument++; /* note : *argument=='-' */
+
+ while (*argument!=0) {
+ switch(*argument)
+ {
+ /* Display version */
+ case 'V':
+ DISPLAY(WELCOME_MESSAGE(exename)); return 0;
+
+ /* Display help on usage */
+ case 'h':
+ return usage_advanced(exename);
+
+ /* select hash algorithm */
+ case 'H':
+ algo = (algoType)(argument[1] - '0');
+ argument+=2;
+ break;
+
+ /* File check mode */
+ case 'c':
+ fileCheckMode=1;
+ argument++;
+ break;
+
+ /* Warning mode (file check mode only, alias of "--warning") */
+ case 'w':
+ warn=1;
+ argument++;
+ break;
+
+ /* Trigger benchmark mode */
+ case 'b':
+ argument++;
+ benchmarkMode = 1;
+ specificTest = readU32FromChar(&argument); /* select one specific test (hidden option) */
+ break;
+
+ /* Modify Nb Iterations (benchmark only) */
+ case 'i':
+ argument++;
+ g_nbIterations = readU32FromChar(&argument);
+ break;
+
+ /* Modify Block size (benchmark only) */
+ case 'B':
+ argument++;
+ keySize = readU32FromChar(&argument);
+ break;
+
+ /* Modify verbosity of benchmark output (hidden option) */
+ case 'q':
+ argument++;
+ g_displayLevel--;
+ break;
+
+ default:
+ return badusage(exename);
+ }
+ }
+ } /* for(i=1; i<argc; i++) */
+
+ /* Check benchmark mode */
+ if (benchmarkMode) {
+ DISPLAYLEVEL(2, WELCOME_MESSAGE(exename) );
+ BMK_sanityCheck();
+ if (filenamesStart==0) return BMK_benchInternal(keySize, specificTest);
+ return BMK_benchFiles(argv+filenamesStart, argc-filenamesStart, specificTest);
+ }
+
+ /* Check if input is defined as console; trigger an error in this case */
+ if ( (filenamesStart==0) && IS_CONSOLE(stdin) ) return badusage(exename);
+
+ if (filenamesStart==0) filenamesStart = argc;
+ if (fileCheckMode) {
+ return checkFiles(argv+filenamesStart, argc-filenamesStart,
+ displayEndianess, strictMode, statusOnly, warn, quiet);
+ } else {
+ return BMK_hashFiles(argv+filenamesStart, argc-filenamesStart, algo, displayEndianess);
+ }
+}
+
+#endif /* XXHASH_C_2097394837 */
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 1103b607dba..de68c20b4d7 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,6 +1,9 @@
EXTRA_DIST = glusterfs.8 mount.glusterfs.8 gluster.8 \
glusterd.8 glusterfsd.8
-man8_MANS = glusterfs.8 mount.glusterfs.8 gluster.8 glusterd.8 glusterfsd.8
+man8_MANS = glusterfs.8 mount.glusterfs.8 gluster.8
+if WITH_SERVER
+man8_MANS += glusterd.8 glusterfsd.8
+endif
CLEANFILES =
diff --git a/doc/README.md b/doc/README.md
index e057437fcba..6aa28642ef4 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -1,6 +1,14 @@
+## Developer Guide
+
+Gluster's contributors can check about the internals by visiting [Developer Guide Section](developer-guide). While it is not 'comprehensive', it can help you to get started.
+
+Also while coding, keep [Coding Standard](developer-guide/coding-standard.md) in mind.
+
+When you are ready to commit the changes, make sure you meet our [Commit message standard](developer-guide/commit-guidelines.md).
+
## Admin Guide ##
-The gluster administration guide is maintained at [github](https://github.com/gluster/glusterdocs). The browsable admin guide can be found [here](http://gluster.readthedocs.org/en/latest/Administrator%20Guide/README/).
+The gluster administration guide is maintained at [github](https://github.com/gluster/glusterdocs). The browsable admin guide can be found [here](http://docs.gluster.org/en/latest/Administrator%20Guide/).
The doc patch has to be sent against the above mentioned repository.
@@ -10,7 +18,7 @@ The Gluster features which are 'in progress' or implemented can be found at [git
## Upgrade Guide ##
-The gluster upgrade guide is maintained at [github](https://github.com/gluster/glusterdocs). The browsable upgrade guide can be found [here](http://gluster.readthedocs.org/en/latest/Upgrade-Guide/README/)
+The gluster upgrade guide is maintained at [github](https://github.com/gluster/glusterdocs). The browsable upgrade guide can be found [here](http://docs.gluster.org/en/latest/Upgrade-Guide)
The doc patch has to be sent against the above mentioned repository.
diff --git a/doc/debugging/analyzing-regression-cores.md b/doc/debugging/analyzing-regression-cores.md
new file mode 100644
index 00000000000..5e10f41c6eb
--- /dev/null
+++ b/doc/debugging/analyzing-regression-cores.md
@@ -0,0 +1,54 @@
+# Analyzing Regression Cores
+This document explains how to analyze core-dumps obtained from regression machines, with examples.
+1. Download the core-tarball and extract it.
+2. `cd` into directory where the tarball is extracted.
+```
+[sh]# pwd
+/home/user/Downloads
+[sh]# ls
+build build-install-20150625_05_42_39.tar.bz2 lib64 usr
+```
+3. Determine the core file you need to examine. There can be more than one core file. You can list them from './build/install/cores' directory.
+```
+[sh]# ls build/install/cores/
+core.9341 liblist.txt liblist.txt.tmp
+```
+In case you are unsure which binary generated the core-file, executing 'file' command on it will help.
+```
+[sh]# file ./build/install/cores/core.9341
+./build/install/cores/core.9341: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from '/build/install/sbin/glusterfsd -s slave26.cloud.gluster.org --volfile-id patchy'
+```
+As seen, the core file was generated by glusterfsd binary, and path to it is provided (/build/install/sbin/glusterfsd).
+
+4. Now, run the following command on the core:
+```
+gdb -ex 'set sysroot ./' -ex 'core-file ./build/install/cores/core.xxx' <target, say ./build/install/sbin/glusterd>
+In this case,
+gdb -ex 'set sysroot ./' -ex 'core-file ./build/install/cores/core.9341' ./build/install/sbin/glusterfsd
+```
+5. You can cross check if all shared libraries are available and loaded by using 'info sharedlibrary' command from inside gdb.
+6. Once verified, usual gdb commands based on requirement can be used to debug the core.
+ `bt` or `backtrace` from gdb of core used in examples:
+```
+Core was generated by `/build/install/sbin/glusterfsd -s slave26.cloud.gluster.org --volfile-id patchy'.
+Program terminated with signal SIGABRT, Aborted.
+#0 0x00007f512a54e625 in raise () from ./lib64/libc.so.6
+(gdb) bt
+#0 0x00007f512a54e625 in raise () from ./lib64/libc.so.6
+#1 0x00007f512a54fe05 in abort () from ./lib64/libc.so.6
+#2 0x00007f512a54774e in __assert_fail_base () from ./lib64/libc.so.6
+#3 0x00007f512a547810 in __assert_fail () from ./lib64/libc.so.6
+#4 0x00007f512b9fc434 in __gf_free (free_ptr=0x7f50f4000e50) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/libglusterfs/src/mem-pool.c:304
+#5 0x00007f512b9b6657 in loc_wipe (loc=0x7f510c20d1a0) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/libglusterfs/src/xlator.c:685
+#6 0x00007f511cb8201d in mq_start_quota_txn_v2 (this=0x7f5118019b60, loc=0x7f510c20d2b8, ctx=0x7f50f4000bf0, contri=0x7f50f4000d60)
+ at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:2921
+#7 0x00007f511cb82c55 in mq_initiate_quota_task (opaque=0x7f510c20d2b0) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:3199
+#8 0x00007f511cb81820 in mq_synctask (this=0x7f5118019b60, task=0x7f511cb829fa <mq_initiate_quota_task>, spawn=_gf_false, loc=0x7f510c20d430, dict=0x0, buf=0x0, contri=0)
+ at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:2789
+#9 0x00007f511cb82f82 in mq_initiate_quota_blocking_txn (this=0x7f5118019b60, loc=0x7f510c20d430) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:3230
+#10 0x00007f511cb82844 in mq_reduce_parent_size_task (opaque=0x7f510c000df0) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/xlators/features/marker/src/marker-quota.c:3117
+#11 0x00007f512ba0f9dc in synctask_wrap (old_task=0x7f510c0053e0) at /home/jenkins/root/workspace/rackspace-regression-2GB-triggered/libglusterfs/src/syncop.c:370
+#12 0x00007f512a55f8f0 in ?? () from ./lib64/libc.so.6
+#13 0x0000000000000000 in ?? ()
+(gdb)
+```
diff --git a/doc/debugging/coredump-analysis.md b/doc/debugging/coredump-analysis.md
deleted file mode 100644
index f9ecf73216e..00000000000
--- a/doc/debugging/coredump-analysis.md
+++ /dev/null
@@ -1,31 +0,0 @@
-This document explains how to analyze core-dumps obtained from regression
-machines, with examples.
-1) Download the core-tarball and extract it.
-2) 'cd' into the root of extracted tarball.
-~~~
-[root@atalur Downloads]# pwd
-/home/atalur/Downloads
-[root@atalur Downloads]# ls
-build build-install-20150625_05_42_39.tar.bz2 lib64 usr
-~~~
-3) Determine the core file you need to examine. There can be more than one core file.
-You can list them from './build/install/cores' directory.
-~~~
-[root@atalur Downloads]# ls build/install/cores/
-core.9341 liblist.txt liblist.txt.tmp
-~~~
-In case you are unsure which binary generated the core-file, executing 'file' command on it will help.
-~~~
-[root@atalur Downloads]# file ./build/install/cores/core.9341
-./build/install/cores/core.9341: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from '/build/install/sbin/glusterfsd -s slave26.cloud.gluster.org --volfile-id patchy'
-~~~
-As seen, the core file was generated by glusterfsd binary, and path to it is provide (/build/install/sbin/glusterfsd).
-4) Now, run the following command on the core:
-~~~
-gdb -ex 'set sysroot ./' -ex 'core-file ./build/install/cores/core.xxx' <target, say ./build/install/sbin/glusterd>
-In this case,
-gdb -ex 'set sysroot ./' -ex 'core-file ./build/install/cores/core.9341' ./build/install/sbin/glusterfsd
-~~~
-5) You can cross check if all shared libraries are available and loaded by using 'info sharedlibrary' command from
-inside gdb.
-6) Once verified, usual gdb commands based on requirement can be used to debug the core.
diff --git a/doc/debugging/gfid-to-path.md b/doc/debugging/gfid-to-path.md
index 09c459e52c8..1917bf2cca1 100644
--- a/doc/debugging/gfid-to-path.md
+++ b/doc/debugging/gfid-to-path.md
@@ -1,37 +1,37 @@
-#Convert GFID to Path
+# Convert GFID to Path
GlusterFS internal file identifier (GFID) is a uuid that is unique to each
file across the entire cluster. This is analogous to inode number in a
normal filesystem. The GFID of a file is stored in its xattr named
`trusted.gfid`.
-####Special mount using [gfid-access translator][1]:
-~~~
+#### Special mount using [gfid-access translator][1]:
+```
mount -t glusterfs -o aux-gfid-mount vm1:test /mnt/testvol
-~~~
+```
Assuming, you have `GFID` of a file from changelog (or somewhere else).
For trying this out, you can get `GFID` of a file from mountpoint:
-~~~
+```
getfattr -n glusterfs.gfid.string /mnt/testvol/dir/file
-~~~
+```
---
-###Get file path from GFID (Method 1):
+### Get file path from GFID (Method 1):
**(Lists hardlinks delimited by `:`, returns path as seen from mountpoint)**
-####Turn on build-pgfid option
-~~~
+#### Turn on build-pgfid option
+```
gluster volume set test build-pgfid on
-~~~
+```
Read virtual xattr `glusterfs.ancestry.path` which contains the file path
-~~~
+```
getfattr -n glusterfs.ancestry.path -e text /mnt/testvol/.gfid/<GFID>
-~~~
+```
**Example:**
-~~~
+```
[root@vm1 glusterfs]# ls -il /mnt/testvol/dir/
total 1
10610563327990022372 -rw-r--r--. 2 root root 3 Jul 17 18:05 file
@@ -46,28 +46,23 @@ glusterfs.gfid.string="11118443-1894-4273-9340-4b212fa1c0e4"
getfattr: Removing leading '/' from absolute path names
# file: mnt/testvol/.gfid/11118443-1894-4273-9340-4b212fa1c0e4
glusterfs.ancestry.path="/dir/file:/dir/file3"
-~~~
+```
---
-###Get file path from GFID (Method 2):
+### Get file path from GFID (Method 2):
**(Does not list all hardlinks, returns backend brick path)**
-~~~
+```
getfattr -n trusted.glusterfs.pathinfo -e text /mnt/testvol/.gfid/<GFID>
-~~~
+```
**Example:**
-~~~
+```
[root@vm1 glusterfs]# getfattr -n trusted.glusterfs.pathinfo -e text /mnt/testvol/.gfid/11118443-1894-4273-9340-4b212fa1c0e4
getfattr: Removing leading '/' from absolute path names
# file: mnt/testvol/.gfid/11118443-1894-4273-9340-4b212fa1c0e4
trusted.glusterfs.pathinfo="(<DISTRIBUTE:test-dht> <POSIX(/mnt/brick-test/b):vm1:/mnt/brick-test/b/dir//file3>)"
-~~~
+```
---
-###Get file path from GFID (Method 3):
-https://gist.github.com/semiosis/4392640
-
----
-####References and links:
+#### References and links:
[posix: placeholders for GFID to path conversion](http://review.gluster.org/5951)
-[1]: https://github.com/gluster/glusterfs/blob/master/doc/features/gfid-access.md
diff --git a/doc/debugging/mem-alloc-list.md b/doc/debugging/mem-alloc-list.md
new file mode 100644
index 00000000000..1c68e65d323
--- /dev/null
+++ b/doc/debugging/mem-alloc-list.md
@@ -0,0 +1,19 @@
+## Viewing Memory Allocations
+
+While statedumps provide stats of the number of allocations, size etc for a
+particular mem type, there is no easy way to examine all the allocated objects of that type
+in memory.Being able to view this information could help with determining how an object is used,
+and if there are any memory leaks.
+
+The mem_acct_rec structures have been updated to include lists to which the allocated object is
+added. These can be examined in gdb using simple scripts.
+
+`gdb> plist xl->mem_acct.rec[$type]->obj_list`
+
+will print out the pointers of all allocations of $type.
+
+These changes are primarily targeted at developers and need to enabled
+at compile-time using `configure --enable-debug`.
+
+
+
diff --git a/doc/debugging/split-brain.md b/doc/debugging/split-brain.md
index b0d938e26bc..6b122c40551 100644
--- a/doc/debugging/split-brain.md
+++ b/doc/debugging/split-brain.md
@@ -1,33 +1,36 @@
-Steps to recover from File split-brain.
-======================================
-
-Quick Start:
-============
-1. Get the path of the file that is in split-brain:
-> It can be obtained either by
-> a) The command `gluster volume heal info split-brain`.
-> b) Identify the files for which file operations performed
- from the client keep failing with Input/Output error.
-
-2. Close the applications that opened this file from the mount point.
+# Steps to recover from File split-brain
+This document contains steps to recover from a file split-brain.
+## Quick Start:
+### Step 1. Get the path of the file that is in split-brain:
+It can be obtained either by
+1. The command `gluster volume heal info split-brain`.
+2. Identify the files for which file operations performed from the client keep failing with Input/Output error.
+
+### Step 2. Close the applications that opened this file from the mount point.
In case of VMs, they need to be powered-off.
-3. Decide on the correct copy:
-> This is done by observing the afr changelog extended attributes of the file on
+### Step 3. Decide on the correct copy:
+This is done by observing the afr changelog extended attributes of the file on
the bricks using the getfattr command; then identifying the type of split-brain
(data split-brain, metadata split-brain, entry split-brain or split-brain due to
gfid-mismatch); and finally determining which of the bricks contains the 'good copy'
of the file.
-> `getfattr -d -m . -e hex <file-path-on-brick>`.
+```
+getfattr -d -m . -e hex <file-path-on-brick>
+```
+
It is also possible that one brick might contain the correct data while the
other might contain the correct metadata.
-4. Reset the relevant extended attribute on the brick(s) that contains the
-'bad copy' of the file data/metadata using the setfattr command.
-> `setfattr -n <attribute-name> -v <attribute-value> <file-path-on-brick>`
+### Step 4. Reset the relevant extended attribute on the brick(s) that contains the 'bad copy' of the file data/metadata using the setfattr command.
+```
+setfattr -n <attribute-name> -v <attribute-value> <file-path-on-brick>
+```
-5. Trigger self-heal on the file by performing lookup from the client:
-> `ls -l <file-path-on-gluster-mount>`
+### Step 5. Trigger self-heal on the file by performing lookup from the client:
+```
+ls -l <file-path-on-gluster-mount>
+```
Detailed Instructions for steps 3 through 5:
===========================================
@@ -36,13 +39,15 @@ afr changelog extended attributes.
Execute `getfattr -d -m . -e hex <file-path-on-brick>`
-* Example:
+Example:
+```
[root@store3 ~]# getfattr -d -e hex -m. brick-a/file.txt
\#file: brick-a/file.txt
security.selinux=0x726f6f743a6f626a6563745f723a66696c655f743a733000
trusted.afr.vol-client-2=0x000000000000000000000000
trusted.afr.vol-client-3=0x000000000200000000000000
trusted.gfid=0x307a5c9efddd4e7c96e94fd4bcdcbd1b
+```
The extended attributes with `trusted.afr.<volname>-client-<subvolume-index>`
are used by afr to maintain changelog of the file.The values of the
@@ -51,10 +56,11 @@ client (fuse or nfs-server) processes. When the glusterfs client modifies a file
or directory, the client contacts each brick and updates the changelog extended
attribute according to the response of the brick.
-'subvolume-index' is nothing but (brick number - 1) in
+`subvolume-index` is nothing but (brick number - 1) in
`gluster volume info <volname>` output.
-* Example:
+Example:
+```
[root@pranithk-laptop ~]# gluster volume info vol
Volume Name: vol
Type: Distributed-Replicate
@@ -71,6 +77,7 @@ attribute according to the response of the brick.
brick-f: pranithk-laptop:/gfs/brick-f
brick-g: pranithk-laptop:/gfs/brick-g
brick-h: pranithk-laptop:/gfs/brick-h
+```
In the example above:
```
@@ -91,12 +98,15 @@ present in all the other bricks in it's replica set as seen by that brick.
In the example volume given above, all files in brick-a will have 2 entries,
one for itself and the other for the file present in it's replica pair, i.e.brick-b:
+```
trusted.afr.vol-client-0=0x000000000000000000000000 -->changelog for itself (brick-a)
trusted.afr.vol-client-1=0x000000000000000000000000 -->changelog for brick-b as seen by brick-a
-
+```
Likewise, all files in brick-b will have:
+```
trusted.afr.vol-client-0=0x000000000000000000000000 -->changelog for brick-a as seen by brick-b
trusted.afr.vol-client-1=0x000000000000000000000000 -->changelog for itself (brick-b)
+```
The same can be extended for other replica pairs.
@@ -122,7 +132,8 @@ When a file split-brain happens it could be either data split-brain or
meta-data split-brain or both. When a split-brain happens the changelog of the
file would be something like this:
-* Example:(Lets consider both data, metadata split-brain on same file).
+Example:(Lets consider both data, metadata split-brain on same file).
+```
[root@pranithk-laptop vol]# getfattr -d -m . -e hex /gfs/brick-?/a
getfattr: Removing leading '/' from absolute path names
\#file: gfs/brick-a/a
@@ -133,10 +144,11 @@ trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57
trusted.afr.vol-client-0=0x000003b00000000100000000
trusted.afr.vol-client-1=0x000000000000000000000000
trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57
+```
-###Observations:
+### Observations:
-####According to changelog extended attributes on file /gfs/brick-a/a:
+#### According to changelog extended attributes on file /gfs/brick-a/a:
The first 8 digits of trusted.afr.vol-client-0 are all
zeros (0x00000000................), and the first 8 digits of
trusted.afr.vol-client-1 are not all zeros (0x000003d7................).
@@ -149,7 +161,7 @@ trusted.afr.vol-client-1 are not all zeros (0x........00000001........).
So the changelog on /gfs/brick-a/a implies that some metadata operations succeeded
on itself but failed on /gfs/brick-b/a.
-####According to Changelog extended attributes on file /gfs/brick-b/a:
+#### According to Changelog extended attributes on file /gfs/brick-b/a:
The first 8 digits of trusted.afr.vol-client-0 are not all
zeros (0x000003b0................), and the first 8 digits of
trusted.afr.vol-client-1 are all zeros (0x00000000................).
@@ -205,6 +217,7 @@ Hence execute
`setfattr -n trusted.afr.vol-client-1 -v 0x000003d70000000000000000 /gfs/brick-a/a`
Thus after the above operations are done, the changelogs look like this:
+```
[root@pranithk-laptop vol]# getfattr -d -m . -e hex /gfs/brick-?/a
getfattr: Removing leading '/' from absolute path names
\#file: gfs/brick-a/a
@@ -216,7 +229,7 @@ trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57
trusted.afr.vol-client-0=0x000000000000000100000000
trusted.afr.vol-client-1=0x000000000000000000000000
trusted.gfid=0x80acdbd886524f6fbefa21fc356fed57
-
+```
Triggering Self-heal:
---------------------
@@ -243,9 +256,9 @@ needs to be removed.The gfid-link files are present in the .glusterfs folder
in the top-level directory of the brick. If the gfid of the file is
0x307a5c9efddd4e7c96e94fd4bcdcbd1b (the trusted.gfid extended attribute got
from the getfattr command earlier),the gfid-link file can be found at
-> /gfs/brick-a/.glusterfs/30/7a/307a5c9efddd4e7c96e94fd4bcdcbd1b
+`/gfs/brick-a/.glusterfs/30/7a/307a5c9efddd4e7c96e94fd4bcdcbd1b`
-####Word of caution:
+#### Word of caution:
Before deleting the gfid-link, we have to ensure that there are no hard links
to the file present on that brick. If hard-links exist,they must be deleted as
well.
diff --git a/doc/debugging/statedump.md b/doc/debugging/statedump.md
index f34a5c3436a..9dfdce15fad 100644
--- a/doc/debugging/statedump.md
+++ b/doc/debugging/statedump.md
@@ -1,31 +1,53 @@
-#Statedump
+# Statedump
Statedump is a file generated by glusterfs process with different data structure state which may contain the active inodes, fds, mempools, iobufs, memory allocation stats of different types of datastructures per xlator etc.
-##How to generate statedump
-We can find the directory where statedump files are created using 'gluster --print-statedumpdir' command.
+## How to generate statedump
+We can find the directory where statedump files are created using `gluster --print-statedumpdir` command.
Create that directory if not already present based on the type of installation.
Lets call this directory `statedump-directory`.
-We can generate statedump using 'kill -USR1 <pid-of-gluster-process>'.
+We can generate statedump using `kill -USR1 <pid-of-gluster-process>`.
gluster-process is nothing but glusterd/glusterfs/glusterfsd process.
There are also commands to generate statedumps for brick processes/nfs server/quotad
-For bricks: `gluster volume statedump <volname>`
+For bricks:
+```
+gluster volume statedump <volname>
+```
-For nfs server: `gluster volume statedump <volname> nfs`
+For nfs server:
+```
+gluster volume statedump <volname> nfs
+```
-For quotad: `gluster volume statedump <volname> quotad`
+For quotad:
+```
+gluster volume statedump <volname> quotad
+```
For brick-processes files will be created in `statedump-directory` with name of the file as `hyphenated-brick-path.<pid>.dump.timestamp`. For all other processes it will be `glusterdump.<pid>.dump.timestamp`.
-##How to read statedump
+For applications using libgfapi, `SIGUSR1` cannot be used, eg: smbd/libvirtd
+processes could have used the `SIGUSR1` signal already for other purposes.
+To generate statedump for the processes, using libgfapi, below command can be
+executed from one of the nodes in the gluster cluster to which the libgfapi
+application is connected to.
+```
+gluster volume statedump <volname> client <hostname>:<process id>
+```
+The statedumps can be found in the `statedump-directory`, the name of the
+statedumps being `glusterdump.<pid>.dump.timestamp`. For a process there can be
+multiple such files created depending on the number of times the volume is
+accessed by the process (related to the number of `glfs_init()` calls).
+
+## How to read statedump
We shall see snippets of each type of statedump.
First and last lines of the file have starting and ending time of writing the statedump file. Times will be in UTC timezone.
mallinfo return status is printed in the following format. Please read man mallinfo for more information about what each field means.
-###Mallinfo
+### Mallinfo
```
[mallinfo]
mallinfo_arena=100020224 /* Non-mmapped space allocated (bytes) */
@@ -40,7 +62,7 @@ mallinfo_fordblks=3310112 /* Total free space (bytes) */
mallinfo_keepcost=133712 /* Top-most, releasable space (bytes) */
```
-###Data structure allocation stats
+### Data structure allocation stats
For every xlator data structure memory per translator loaded in the call-graph is displayed in the following format:
For xlator with name: glusterfs
@@ -61,7 +83,7 @@ max_num_allocs=3 #Maximum number of active allocations at any point in the life
total_allocs=7 #Number of times this data is allocated in the life of the process.
```
-###Mempools
+### Mempools
Mempools are optimization to reduce the number of allocations of a data type. If we create a mem-pool of lets say 1024 elements for a data-type, new elements will be allocated from heap using syscalls like calloc, only if all the 1024 elements in the pool are in active use.
@@ -81,7 +103,7 @@ cur-stdalloc=0 #Denotes the number of allocations made from heap once cold-count
max-stdalloc=0 #Maximum number of allocations from heap that are in active use at any point in the life of the process.
```
-###Iobufs
+### Iobufs
```
[iobuf.global]
iobuf_pool=0x1f0d970 #The memory pool for iobufs
@@ -92,7 +114,7 @@ iobuf_pool.arena_cnt=8 #Total number of arenas in the pool
iobuf_pool.request_misses=0 #The number of iobufs that were stdalloc'd (as they exceeded the default max page size provided by iobuf_pool).
```
-There are 3 lists of arenas
+There are 3 lists of arenas:
1. Arena list: arenas allocated during iobuf pool creation and the arenas that are in use(active_cnt != 0) will be part of this list.
2. Purge list: arenas that can be purged(no active iobufs, active_cnt == 0).
@@ -129,7 +151,7 @@ arena.6.active_iobuf.2.ptr=0x7fdb92189000
At any given point in time if there are lots of filled arenas then that could be a sign of iobuf leaks.
-###Call stack
+### Call stack
All the fops received by gluster are handled using call-stacks. Call stack contains the information about uid/gid/pid etc of the process that is executing the fop. Each call-stack contains different call-frames per xlator which handles that fop.
```
@@ -144,7 +166,7 @@ op=LOOKUP #Fop
type=1 #Type of the op i.e. FOP/MGMT-OP
cnt=9 #Number of frames in this stack.
```
-###Call-frame
+### Call-frame
Each frame will have information about which xlator the frame belongs to, what is the function it wound to/from and will be unwind to. It also mentions if the unwind happened or not. If we observe hangs in the system and want to find out which xlator is causing it. Take a statedump and see what is the final xlator which is yet to be unwound.
```
@@ -159,7 +181,7 @@ wind_to=priv->children[i]->fops->lookup
unwind_to=afr_lookup_cbk #Parent xlator function to which unwind happened
```
-###History of operations in Fuse
+### History of operations in Fuse
Fuse maintains history of operations that happened in fuse.
@@ -175,7 +197,7 @@ TIME=2014-07-09 16:44:57.523394
message=[0] fuse_getattr_resume: 4591, STAT, path: (/iozone.tmp), gfid: (3afb4968-5100-478d-91e9-76264e634c9f)
```
-###Xlator configuration
+### Xlator configuration
```
[cluster/replicate.r2-replicate-0] #Xlator type, name information
child_count=2 #Number of children to the xlator
@@ -195,7 +217,7 @@ favorite_child=-1
wait_count=1
```
-###Graph/inode table
+### Graph/inode table
```
[active graph - 1]
@@ -207,7 +229,7 @@ conn.1.bound_xl./data/brick01a/homegfs.lru_size=183 #Number of inodes present in
conn.1.bound_xl./data/brick01a/homegfs.purge_size=0 #Number of inodes present in purge list
```
-###Inode
+### Inode
```
[conn.1.bound_xl./data/brick01a/homegfs.active.324] #324th inode in active inode list
gfid=e6d337cf-97eb-44b3-9492-379ba3f6ad42 #Gfid of the inode
@@ -215,6 +237,7 @@ nlookup=13 #Number of times lookups happened from the client or from fuse kernel
fd-count=4 #Number of fds opened on the inode
ref=11 #Number of refs taken on the inode
ia_type=1 #Type of the inode. This should be changed to some string :-(
+Ref by xl:.patchy-md-cache=11 #Further this there will be a list of xlators, and the ref count taken by each of them on this inode at the time of statedump
[conn.1.bound_xl./data/brick01a/homegfs.lru.1] #1st inode in lru list. Note that ref count is zero for these inodes.
gfid=5114574e-69bc-412b-9e52-f13ff087c6fc
@@ -222,8 +245,10 @@ nlookup=5
fd-count=0
ref=0
ia_type=2
+Ref by xl:.fuse=1
+Ref by xl:.patchy-client-0=-1
```
-###Inode context
+### Inode context
For each inode per xlator some context could be stored. This context can also be printed in the statedump. Here is the inode ctx of locks xlator
```
[xlator.features.locks.homegfs-locks.inode]
@@ -240,12 +265,12 @@ lock-dump.domain.domain=homegfs-replicate-0 #Domain name where entry/data operat
inodelk.inodelk[0](ACTIVE)=type=WRITE, whence=0, start=11141120, len=131072, pid = 18446744073709551615, owner=080b1ada117f0000, client=0xb7fc30, connection-id=compute-30-029.com-3505-2014/06/29-14:46:12:477358-homegfs-client-0-0-1, granted at Sun Jun 29 11:10:36 2014 #Active lock information
```
-##FAQ
-###How to debug Memory leaks using statedump?
+## FAQ
+### How to debug Memory leaks using statedump?
-####Using memory accounting feature:
+#### Using memory accounting feature:
-`https://bugzilla.redhat.com/show_bug.cgi?id=1120151` is one of the bugs which was debugged using statedump to see which data-structure is leaking. Here is the process used to find what the leak is using statedump. According to the bug the observation is that the process memory usage is increasing whenever one of the bricks is wiped in a replicate volume and a `full` self-heal is invoked to heal the contents. Statedump of the process is taken using kill -USR1 `<pid-of-gluster-self-heal-daemon>`.
+[Bug 1120151](https://bugzilla.redhat.com/show_bug.cgi?id=1120151) is one of the bugs which was debugged using statedump to see which data-structure is leaking. Here is the process used to find what the leak is using statedump. According to the bug the observation is that the process memory usage is increasing whenever one of the bricks is wiped in a replicate volume and a `full` self-heal is invoked to heal the contents. Statedump of the process is taken using `kill -USR1 <pid-of-gluster-self-heal-daemon>`.
```
grep -w num_allocs glusterdump.5225.dump.1405493251
num_allocs=77078
@@ -268,10 +293,10 @@ grep of the statedump revealed too many allocations for the following data-types
3. gf_common_mt_mem_pool.
After checking afr-code for allocations with tag `gf_common_mt_char` found `data-self-heal` code path does not free one such allocated memory. `gf_common_mt_mem_pool` suggests that there is a leak in pool memory. `replicate-0:dict_t`, `glusterfs:data_t` and `glusterfs:data_pair_t` pools are using lot of memory, i.e. cold_count is `0` and too many allocations. Checking source code of dict.c revealed that `key` in `dict` is allocated with `gf_common_mt_char` i.e. `2.` tag and value is created using gf_asprintf which in-turn uses `gf_common_mt_asprintf` i.e. `1.`. Browsing the code for leak in self-heal code paths lead to a line which over-writes a variable with new dictionary even when it was already holding a reference to another dictionary. After fixing these leaks, ran the same test to verify that none of the `num_allocs` are increasing even after healing 10,000 files directory hierarchy in statedump of self-heal daemon.
-Please check http://review.gluster.org/8316 for more info about patch/code.
+Please check this [patch](http://review.gluster.org/8316) for more info about the fix.
-####Debugging leaks in memory pools:
-Statedump output of memory pools was used to test and verify the fixes to https://bugzilla.redhat.com/show_bug.cgi?id=1134221. On code analysis, dict_t objects were found to be leaking (in terms of not being unref'd enough number of times, during name self-heal. The test involved creating 100 files on plain replicate volume, removing them from one of the bricks's backend, and then triggering lookup on them from the mount point. Statedump of the mount process was taken before executing the test case and after it, after compiling glusterfs with -DDEBUG flags (to have cold count set to 0 by default).
+#### Debugging leaks in memory pools:
+Statedump output of memory pools was used to test and verify the fixes to [Bug 1134221](https://bugzilla.redhat.com/show_bug.cgi?id=1134221). On code analysis, dict_t objects were found to be leaking (in terms of not being unref'd enough number of times, during name self-heal. The test involved creating 100 files on plain replicate volume, removing them from one of the brick's backend, and then triggering lookup on them from the mount point. Statedump of the mount process was taken before executing the test case and after it, after compiling glusterfs with -DDEBUG flags (to have cold count set to 0 by default).
Statedump output of the fuse mount process before the test case was executed:
@@ -303,7 +328,7 @@ cur-stdalloc=214
max-stdalloc=220
```
-Here, with cold count being 0 by default, cur-stdalloc indicated the number of dict_t objects that were allocated in heap using mem_get(), and yet to be freed using mem_put() (refer to https://github.com/gluster/glusterfs/blob/master/doc/data-structures/mem-pool.md for more details on how mempool works). After the test case (name selfheal of 100 files), there was a rise in the cur-stdalloc value (from 14 to 214) for dict_t.
+Here, with cold count being 0 by default, `cur-stdalloc` indicated the number of `dict_t` objects that were allocated in heap using `mem_get()`, and yet to be freed using `mem_put()` (refer to this [page](../developer-guide/datastructure-mem-pool.md) for more details on how mempool works). After the test case (name selfheal of 100 files), there was a rise in the cur-stdalloc value (from 14 to 214) for `dict_t`.
After these leaks were fixed, glusterfs was again compiled with -DDEBUG flags, and the same steps were performed again and statedump was taken before and after executing the test case, of the mount. This was done to ascertain the validity of the fix. And the following are the results:
@@ -337,8 +362,8 @@ max-stdalloc=119
```
The value of cur-stdalloc remained 14 before and after the test, indicating that the fix indeed does what it's supposed to do.
-###How to debug hangs because of frame-loss?
-`https://bugzilla.redhat.com/show_bug.cgi?id=994959` is one of the bugs where statedump was helpful in finding where the frame was lost. Here is the process used to find where the hang is using statedump.
+### How to debug hangs because of frame-loss?
+[Bug 994959](https://bugzilla.redhat.com/show_bug.cgi?id=994959) is one of the bugs where statedump was helpful in finding where the frame was lost. Here is the process used to find where the hang is using statedump.
When the hang was observed, statedumps are taken for all the processes. On mount's statedump the following stack is shown:
```
[global.callpool.stack.1.frame.1]
@@ -386,4 +411,4 @@ unwind_to=qr_readdirp_cbk
```
`unwind_to` shows that call was unwound to `afr_readdirp_cbk` from client xlator.
Inspecting that function revealed that afr is not unwinding the stack when fop failed.
-Check http://review.gluster.org/5531 for more info about patch/code changes.
+Check this [patch](http://review.gluster.org/5531) for more info about the fix.
diff --git a/doc/developer-guide/Language-Bindings.md b/doc/developer-guide/Language-Bindings.md
new file mode 100644
index 00000000000..951f5fae2f6
--- /dev/null
+++ b/doc/developer-guide/Language-Bindings.md
@@ -0,0 +1,45 @@
+# Language Bindings
+GlusterFS 3.4 introduced the libgfapi client API for C programs. This
+page lists bindings to the libgfapi C library from other languages.
+
+Go
+--
+
+- [gogfapi](https://github.com/gluster/gogfapi) - Go language bindings
+ for libgfapi, aiming to provide an api consistent with the default
+ Go file apis.
+
+Java
+----
+
+- [libgfapi-jni](https://github.com/semiosis/libgfapi-jni/) - Low
+ level JNI binding for libgfapi
+- [glusterfs-java-filesystem](https://github.com/semiosis/glusterfs-java-filesystem)
+ - High level NIO.2 FileSystem Provider implementation for the Java
+ platform
+- [libgfapi-java-io](https://github.com/gluster/libgfapi-java-io) -
+ Java bindings for libgfapi, similar to java.io
+
+Python
+------
+
+- [libgfapi-python](https://github.com/gluster/libgfapi-python) -
+ Libgfapi bindings for Python
+
+Ruby
+----
+
+- [libgfapi-ruby](https://github.com/spajus/libgfapi-ruby) - Libgfapi
+ bindings for Ruby using FFI
+
+Rust
+----
+
+- [gfapi-sys](https://github.com/cholcombe973/Gfapi-sys) - Libgfapi
+ bindings for Rust using FFI
+
+Perl
+----
+
+- [libgfapi-perl](https://github.com/gluster/libgfapi-perl) - Libgfapi
+ bindings for Perl using FFI
diff --git a/doc/developer-guide/README.md b/doc/developer-guide/README.md
new file mode 100644
index 00000000000..aaf9c7476b0
--- /dev/null
+++ b/doc/developer-guide/README.md
@@ -0,0 +1,81 @@
+Developers
+==========
+
+### From GlusterDocumentation
+
+Contributing to the Gluster community
+-------------------------------------
+
+Are you itching to send in patches and participate as a developer in the
+Gluster community? Here are a number of starting points for getting
+involved. We don't require a signed contributor license agreement or
+copyright assignment, but we do require a "signed-off-by" line on each
+code check-in.
+
+- [License
+ Change](http://www.gluster.org/2012/05/glusterfs-license-change/) -
+ we recently changed the client library code to a dual license under
+ the GPL v2 and the LGPL v3 or later
+- [GlusterFS Coding Standards](./coding-standard.md)
+
+- If you are not sure of where to start, and what to do, we have a small
+ write-up on what you can pick. [Check it out](./options-to-contribute.md)
+
+
+Adding File operations
+----------------------
+
+- [Steps to be followed when adding a new FOP to GlusterFS ](./adding-fops.md)
+
+Automatic File Replication
+--------------------------
+
+- [Cluster/afr translator](./afr.md)
+- [History of Locking in AFR](./afr-locks-evolution.md)
+- [Self heal Daemon](./afr-self-heal-daemon.md)
+
+Data Structures
+---------------
+
+- [inode data structure](./datastructure-inode.md)
+- [iobuf data structure](./datastructure-iobuf.md)
+- [mem-pool data structure](./datastructure-mem-pool.md)
+
+Find the gfapi symbol versions [here](./gfapi-symbol-versions.md)
+
+Daemon Management Framework
+---------------------------
+
+- [How to introduce new daemons using daemon management framework](./daemon-management-framework.md)
+
+Translators
+-----------
+
+- [Performance/write-Behind Translator](./write-behind.md)
+- [Translator Development](./translator-development.md)
+- [Storage/posix Translator](./posix.md)
+
+
+Brick multiplex
+---------------
+
+- [Brick mux resource reduction](./brickmux-thread-reduction.md)
+
+Fuse
+----
+
+- [Interrupt handling](./fuse-interrupt.md)
+
+Testing/Debugging
+-----------------
+
+- [Unit Tests in GlusterFS](./unittest.md)
+- [Using the Gluster Test
+ Framework](./Using-Gluster-Test-Framework.md) - Step by
+ step instructions for running the Gluster Test Framework
+- [Coredump Analysis](../debugging/analyzing-regression-cores.md) - Steps to analize coredumps generated by regression machines.
+- [Identifying Resource Leaks](./identifying-resource-leaks.md)
+
+Release Process
+---------------
+- [Versioning](./versioning.md)
diff --git a/doc/developer-guide/Using-Gluster-Test-Framework.md b/doc/developer-guide/Using-Gluster-Test-Framework.md
new file mode 100644
index 00000000000..d2bb1c391da
--- /dev/null
+++ b/doc/developer-guide/Using-Gluster-Test-Framework.md
@@ -0,0 +1,271 @@
+# USing Gluster Test Framwork
+Description
+-----------
+
+The Gluster Test Framework, is a suite of scripts used for regression
+testing of Gluster.
+
+It runs well on RHEL and CentOS (possibly Fedora too, presently being
+tested), and is automatically run against every patch submitted to
+Gluster [for review](http://review.gluster.org).
+
+The Gluster Test Framework is part of the main Gluster code base, living
+under the "tests" subdirectory:
+
+ http://git.gluster.org/?p=glusterfs.git;a=summary
+
+WARNING
+-------
+
+Running the Gluster Test Framework deletes “/var/lib/glusterd/\*”.
+
+**DO NOT run it on a server with any data.**
+
+Preparation steps for Ubuntu 14.04 LTS
+--------------------------------------
+
+​1. \# apt-get install dbench git libacl1-dev mock nfs-common
+nfs-kernel-server libtest-harness-perl libyajl-dev xfsprogs psmisc attr
+acl lvm2 rpm
+
+​2. \# apt-get install python-webob python-paste python-sphinx
+
+​3. \# apt-get install autoconf automake bison dos2unix flex libfuse-dev
+libaio-dev libibverbs-dev librdmacm-dev libtool libxml2-dev
+libxml2-utils liblvm2-dev make libssl-dev pkg-config libpython-dev
+python-eventlet python-netifaces python-simplejson python-pyxattr
+libreadline-dev tar
+
+​4) Install cmockery2 from github (https://github.com/lpabon/cmockery2)
+and compile and make install as in Readme
+
+5)
+
+ sudo groupadd mock
+ sudo useradd -g mock mock
+
+​6) mkdir /var/run/gluster
+
+**Note**: redhat-rpm-config package is not found in ubuntu
+
+Preparation steps for CentOS 7 (only)
+-------------------------------------
+
+​1. Install EPEL:
+
+ $ sudo yum install -y http://epel.mirror.net.in/epel/7/x86_64/e/epel-release-7-1.noarch.rpm
+
+​2. Install the CentOS 7.x dependencies:
+
+ $ sudo yum install -y --enablerepo=epel cmockery2-devel dbench git libacl-devel mock nfs-utils perl-Test-Harness yajl xfsprogs psmisc
+
+ $ sudo yum install -y --enablerepo=epel python-webob1.0 python-paste-deploy1.5 python-sphinx10 redhat-rpm-config
+
+==\> Despite below missing packages it worked for me
+
+ No package python-webob1.0 available.
+ No package python-paste-deploy1.5 available.
+ No package python-sphinx10 available.
+
+ $ sudo yum install -y --enablerepo=epel autoconf automake bison dos2unix flex fuse-devel libaio-devel libibverbs-devel \
+  librdmacm-devel libtool libxml2-devel lvm2-devel make openssl-devel pkgconfig \
+  python-devel python-eventlet python-netifaces python-paste-deploy \
+  python-simplejson python-sphinx python-webob pyxattr readline-devel rpm-build \
+  tar
+
+​3. Create the mock user
+
+ $ sudo useradd -g mock mock
+
+Preparation steps for CentOS 6.3+ (only)
+----------------------------------------
+
+​1. Install EPEL:
+
+ $ sudo yum install -y http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
+
+​2. Install the CentOS 6.x dependencies:
+
+ $ sudo yum install -y --enablerepo=epel cmockery2-devel dbench git libacl-devel mock nfs-utils perl-Test-Harness yajl xfsprogs
+ $ sudo yum install -y --enablerepo=epel python-webob1.0 python-paste-deploy1.5 python-sphinx10 redhat-rpm-config
+ $ sudo yum install -y --enablerepo=epel autoconf automake bison dos2unix flex fuse-devel libaio-devel libibverbs-devel \
+   librdmacm-devel libtool libxml2-devel lvm2-devel make openssl-devel pkgconfig \
+   python-devel python-eventlet python-netifaces python-paste-deploy \
+   python-simplejson python-sphinx python-webob pyxattr readline-devel rpm-build \
+   tar
+
+​3. Create the mock user
+
+ $ sudo useradd -g mock mock
+
+Preparation steps for RHEL 6.3+ (only)
+--------------------------------------
+
+​1. Ensure you have the "Scalable Filesystem Support" group installed
+
+This provides the xfsprogs package, which is required by the test
+framework.
+
+​2. Install EPEL:
+
+ $ sudo yum install -y http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
+
+​3. Install the CentOS 6.x dependencies:
+
+ $ sudo yum install -y --enablerepo=epel cmockery2-devel dbench git libacl-devel mock nfs-utils yajl perl-Test-Harness
+ $ sudo yum install -y --enablerepo=rhel-6-server-optional-rpms python-webob1.0 python-paste-deploy1.5 python-sphinx10 redhat-rpm-config
+ $ sudo yum install -y --disablerepo=rhs* --enablerepo=*optional-rpms autoconf \
+   automake bison dos2unix flex fuse-devel libaio-devel libibverbs-devel \
+   librdmacm-devel libtool libxml2-devel lvm2-devel make openssl-devel pkgconfig \
+   python-devel python-eventlet python-netifaces python-paste-deploy \
+   python-simplejson python-sphinx python-webob pyxattr readline-devel rpm-build \
+   tar
+
+​4. Create the mock user
+
+ $ sudo useradd -g mock mock
+
+Preparation steps for Fedora 16-19 (only)
+-----------------------------------------
+
+**Still in development**
+
+​1. Install the Fedora dependencies:
+
+ $ sudo yum install -y attr cmockery2-devel dbench git mock nfs-utils perl-Test-Harness psmisc xfsprogs
+ $ sudo yum install -y python-webob1.0 python-paste-deploy1.5 python-sphinx10 redhat-rpm-config
+ $ sudo yum install -y autoconf automake bison dos2unix flex fuse-devel libaio-devel libibverbs-devel \
+   librdmacm-devel libtool libxml2-devel lvm2-devel make openssl-devel pkgconfig \
+   python-devel python-eventlet python-netifaces python-paste-deploy \
+   python-simplejson python-sphinx python-webob pyxattr readline-devel rpm-build \
+   tar
+
+​3. Create the mock user
+
+ $ sudo useradd -g mock mock
+
+Common steps
+------------
+
+​1. Ensure DNS for your server is working
+
+The Gluster Test Framework fails miserably if the full domain name for
+your server doesn't resolve back to itself.
+
+If you don't have a working DNS infrastructure in place, adding an entry
+for your server to its /etc/hosts file will work.
+
+​2. Install the version of Gluster you are testing
+
+Either install an existing set of rpms:
+
+ $ sudo yum install [your gluster rpms here]
+
+Or compile your own ones (fairly easy):
+
+ http://www.gluster.org/community/documentation/index.php/CompilingRPMS
+
+​3. Clone the GlusterFS git repository
+
+ $ git clone git://git.gluster.org/glusterfs
+ $ cd glusterfs
+
+Ensure mock can access the directory
+------------------------------------
+
+Some tests run as the user "mock". If the mock user can't access the
+tests subdirectory directory, these tests fail. (rpm.t is one such test)
+
+This is a known gotcha when the git repo is cloned to your home
+directory. Home directories generally don't have world readable
+permissions. You can fix this by adjusting your home directory
+permissions, or placing the git repo somewhere else (with access for the
+mock user).
+
+Running the tests
+-----------------
+
+The tests need to run as root, so they can mount volumes and manage
+gluster processes as needed.
+
+It's also best to run them directly as the root user, instead of through
+sudo. Strange things sporadicly happen (for me) when using the full test
+framework through sudo, that haven't happened (yet) when running
+directly as root. Hangs in dbench particularly, which are part of at
+least one test.
+
+ # ./run-tests.sh
+
+The test framework takes just over 45 minutes to run in a VM here (4
+cpu's assigned, 8GB ram, SSD storage). It may take significantly more or
+less time for you, depending on the hardware and software you're using.
+
+Showing debug information
+-------------------------
+
+To display verbose information while the tests are running, set the
+DEBUG environment variable to 1 prior to running the tests.
+
+ # DEBUG=1 ./run-tests.sh
+
+Log files
+---------
+
+Verbose output from the rpm.t test goes into "rpmbuild-mock.log",
+located in the same directory the test is run from.
+
+Reporting bugs
+--------------
+
+If you hit a bug when running the test framework, **please** create a
+bug report for it on Bugzilla so it gets fixed:
+
+ https://bugzilla.redhat.com/enter_bug.cgi?product=GlusterFS&component=tests
+
+Creating your own tests
+-----------------------
+
+The test scripts are written in bash, with their filenames ending in .t
+instead of .sh.
+
+When creating your own test scripts, create them in an appropriate
+subdirectory under "tests" (eg "bugs" or "features") and use descriptive
+names like "bug-XXXXXXX-checking-feature-X.t"
+
+Also include the "include.rc" file, which defines the test types and
+host/brick/volume defaults:
+
+ . $(dirname $0)/../include.rc
+
+There are 5 test types available at present, but feel free to add more
+if you need something that doesn't yet exist. The test types are
+explained in more detail below.
+
+Also essential is the "cleanup" command, which removes any existing
+Gluster configuration (**without backing it up**), and also kills any
+running gluster processes.
+
+There is a basic test template you can copy, named bug-000000.t in the
+bugs subdirectory:
+
+ $ cp bugs/bug-000000.t somedir/descriptive-name.t
+
+### TEST
+
+- Example of usage in basic/volume.t
+
+### TEST\_IN\_LOOP
+
+- Example of usage in basic/rpm.t
+
+### EXPECT
+
+- Example of usage in basic/volume.t
+
+### EXPECT\_WITHIN
+
+- Example of usage in basic/volume-status.t
+
+### EXPECT\_KEYWORD
+
+- Defined in include.rc, but seems to be unused?
diff --git a/doc/developer-guide/afr/afr-locks-evolution.md b/doc/developer-guide/afr-locks-evolution.md
index 7d2a136d871..2dabbcfeb13 100644
--- a/doc/developer-guide/afr/afr-locks-evolution.md
+++ b/doc/developer-guide/afr-locks-evolution.md
@@ -32,10 +32,10 @@ AFR makes use of locks xlator extensively:
* For Entry self-heal, it is `entrylk(NULL name, parent inode)`. Specifying NULL for the name takes full lock on the directory referred to by the inode.
* For data self-heal, there is a bit of history as to how locks evolved:
-###Initial version (say version 1) :
+### Initial version (say version 1) :
There was no concept of selfheal daemon (shd). Only client lookups triggered heals. so AFR always took `inodelk(0,0,DATA_DOMAIN)` for healing. The issue with this approach was that when heal was in progress, I/O from clients was blocked .
-###version 2:
+### version 2:
shd was introduced. We needed to allow I/O to go through when heal was going,provided the ranges did not overlap. To that extent, the following approach was adopted:
+ 1.shd takes (full inodelk in DATA_DOMAIN). Thus client FOPS are blocked and cannot modify changelog-xattrs
@@ -79,7 +79,7 @@ It modifies data but the FOP succeeds only on brick 2. writev returns success, a
and thus goes ahead and copies stale 128Kb from brick 1 to brick2. Thus as far as application is concerned, `writev` returned success but bricks have stale data.
What needs to be done is `writev` must return success only if it succeeded on atleast one source brick (brick b1 in this case). Otherwise The heal still happens in reverse direction but as far as the application is concerned, it received an error.
-###Note on lock **domains**
+### Note on lock **domains**
We have used conceptual names in this document like DATA_DOMAIN/ METADATA_DOMAIN/ SELF_HEAL_DOMAIN. In the code, these are mapped to strings that are based on the AFR xlator name like so:
DATA_DOMAIN --->"vol_name-replicate-n"
diff --git a/doc/developer-guide/afr/self-heal-daemon.md b/doc/developer-guide/afr-self-heal-daemon.md
index d5e081f5f49..65940d420b7 100644
--- a/doc/developer-guide/afr/self-heal-daemon.md
+++ b/doc/developer-guide/afr-self-heal-daemon.md
@@ -13,7 +13,8 @@ replicate xlators (subvolumes) of *only* the bricks present in that particular n
The shd does two types of self-heal crawls: Index heal and Full heal. For both these types of crawls, the basic idea is the same:
For each file encountered while crawling, perform metadata, data and entry heals under appropriate locks.
* An overview of how each of these heals is performed is detailed in the 'Self-healing' section of *doc/features/afr-v1.md*
-* The different file locks which the shd takes for each of these heals is detailed in *doc/developer-guide/afr/afr-locks-evolution.md*
+* The different file locks which the shd takes for each of these heals is detailed in *doc/developer
+-guide/afr-locks-evolution.md*
Metadata heal refers to healing extended attributes, mode and permissions of a file or directory.
Data heal refers to healing the file contents.
@@ -32,13 +33,13 @@ each entry in index heal, a check is made if a full heal is queued. If it is, th
In index heal, each shd reads the entries present inside .glusterfs/indices/xattrop/ folder and triggers heal on each entry with appropriate locks.
The .glusterfs/indices/xattrop/ directory contains a base entry of the name "xattrop-<virtual-gfid-string>". All other entries are hardlinks to the base entry. The
-*names* of the hardlinks are the gfid strings of the files that may need heal.
+*names* of the hardlinks are the gfid strings of the files that may need heal.
When a client (mount) performs an operation on the file, the index xlator present in each brick process adds the hardlinks in the pre-op phase of the FOP's transaction
-and removes it in post-op phase if the operation is successful. Thus if an entry is present inside the .glusterfs/indices/xattrop directory when there is no I/O
+and removes it in post-op phase if the operation is successful. Thus if an entry is present inside the .glusterfs/indices/xattrop/ directory when there is no I/O
happening on the file, it means the file needs healing (or atleast an examination if the brick crashed after the post-op completed but just before the removal of the hardlink).
-####Index heal steps:
+#### Index heal steps:
<pre><code>
In shd process of *each node* {
opendir +readdir (.glusterfs/indices/xattrop/)
@@ -85,6 +86,7 @@ In shd process of *highest UUID node per replica* {
/* Recurse*/
again opendir+readdir (directory) followed by self_heal_entry() of each entry.
}
+
}
}
</code></pre>
diff --git a/doc/developer-guide/afr/afr.md b/doc/developer-guide/afr.md
index 566573a4e26..566573a4e26 100644
--- a/doc/developer-guide/afr/afr.md
+++ b/doc/developer-guide/afr.md
diff --git a/doc/developer-guide/bd-xlator.md b/doc/developer-guide/bd-xlator.md
deleted file mode 100644
index 1771fb6e24b..00000000000
--- a/doc/developer-guide/bd-xlator.md
+++ /dev/null
@@ -1,469 +0,0 @@
-#Block device translator
-
-Block device translator (BD xlator) is a translator added to GlusterFS which provides block backend for GlusterFS. This replaces the existing bd_map translator in GlusterFS that provided similar but very limited functionality. GlusterFS expects the underlying brick to be formatted with a POSIX compatible file system. BD xlator changes that and allows for having bricks that are raw block devices like LVM which needn’t have any file systems on them. Hence with BD xlator, it becomes possible to build a GlusterFS volume comprising of bricks that are logical volumes (LV).
-
-##bd
-
-BD xlator maps underlying LVs to files and hence the LVs appear as files to GlusterFS clients. Though BD volume externally appears very similar to the usual Posix volume, not all operations are supported or possible for the files on a BD volume. Only those operations that make sense for a block device are supported and the exact semantics are described in subsequent sections.
-
-While Posix volume takes a file system directory as brick, BD volume needs a volume group (VG) as brick. In the usual use case of BD volume, a file created on BD volume will result in an LV being created in the brick VG. In addition to a VG, BD volume also needs a file system directory that should be specified at the volume creation time. This directory is necessary for supporting the notion of directories and directory hierarchy for the BD volume. Metadata about LVs (size, mapping info) is stored in this directory.
-
-BD xlator was mainly developed to use block devices directly as VM images when GlusterFS is used as storage for KVM virtualization. Some of the salient points of BD xlator are
-
-* Since BD supports file level snapshots and clones by leveraging the snapshot and clone capabilities of LVM, it can be used to fully off-load snapshot and cloning operations from QEMU to the storage (GlusterFS) itself.
-
-* BD understands dm-thin LVs and hence can support files that are backed by thinly provisioned LVs. This capability of BD xlator translates to having thinly provisioned raw VM images.
-
-* BD enables thin LVs from a thin pool to be used from multiple nodes that have visibility to GlusterFS BD volume. Thus thin pool can be used as a VM image repository allowing access/visibility to it from multiple nodes.
-
-* BD supports true zerofill by using BLKZEROOUT ioctl on underlying block devices. Thus BD allows SCSI WRITESAME to be used on underlying block device if the device supports it.
-
-Though BD xlator is primarily intended to be used with block devices, it does provide full Posix xlator compatibility for files that are created on BD volume but are not backed by or mapped to a block device. Such files which don’t have a block device mapping exist on the Posix directory that is specified during BD volume creation. BD xlator is available from GlusterFS-3.5 release.
-
-###Compiling BD translator
-
-BD xlator needs lvm2 development library. –enable-bd-xlator option can be used with `./configure` script to explicitly enable BD translator. The following snippet from the output of configure script shows that BD xlator is enabled for compilation.
-
-
-#####GlusterFS configure summary
-
- …
- Block Device xlator : yes
-
-
-###Creating a BD volume
-
-BD supports hosting of both linear LV and thin LV within the same volume. However seperate examples are provided below. As noted above, the prerequisite for a BD volume is VG which is created from a loop device here, but it can be any other device too.
-
-
-* Creating BD volume with linear LV backend
-
-* Create a loop device
-
-
- [root@node ~]# dd if=/dev/zero of=bd-loop count=1024 bs=1M
-
- [root@node ~]# losetup /dev/loop0 bd-loop
-
-
-* Prepare a brick by creating a VG
-
- [root@node ~]# pvcreate /dev/loop0
-
- [root@node ~]# vgcreate bd-vg /dev/loop0
-
-
-* Create the BD volume
-
-* Create a POSIX directory first
-
-
- [root@node ~]# mkdir /bd-meta
-
-It is recommended that this directory is created on an LV in the brick VG itself so that both data and metadata live together on the same device.
-
-
-* Create and mount the volume
-
- [root@node ~]# gluster volume create bd node:/bd-meta?bd-vg force
-
-
-The general syntax for specifying the brick is `host:/posix-dir?volume-group-name` where “?” is the separator.
-
-
-
- [root@node ~]# gluster volume start bd
- [root@node ~]# gluster volume info bd
- Volume Name: bd
- Type: Distribute
- Volume ID: cb042d2a-f435-4669-b886-55f5927a4d7f
- Status: Started
- Xlator 1: BD
- Capability 1: offload_copy
- Capability 2: offload_snapshot
- Number of Bricks: 1
- Transport-type: tcp
- Bricks:
- Brick1: node:/bd-meta
- Brick1 VG: bd-vg
-
-
-
- [root@node ~]# mount -t glusterfs node:/bd /mnt
-
-* Create a file that is backed by an LV
-
- [root@node ~]# ls /mnt
-
- [root@node ~]#
-
-Since the volume is empty now, so is the underlying VG.
-
- [root@node ~]# lvdisplay bd-vg
- [root@node ~]#
-
-Creating a file that is mapped to an LV is a 2 step operation. First the file should be created on the mount point and a specific extended attribute should be set to map the file to LV.
-
- [root@node ~]# touch /mnt/lv
- [root@node ~]# setfattr -n “user.glusterfs.bd” -v “lv” /mnt/lv
-
-Now an LV got created in the VG brick and the file /mnt/lv maps to this LV. Any read/write to this file ends up as read/write to the underlying LV.
-
- [root@node ~]# lvdisplay bd-vg
- — Logical volume —
- LV Path /dev/bd-vg/6ff0f25f-2776-4d19-adfb-df1a3cab8287
- LV Name 6ff0f25f-2776-4d19-adfb-df1a3cab8287
- VG Name bd-vg
- LV UUID PjMPcc-RkD5-RADz-6ixG-UYsk-oclz-vL0nv6
- LV Write Access read/write
- LV Creation host, time node, 2013-11-26 16:15:45 +0530
- LV Status available
- open 0
- LV Size 4.00 MiB
- Current LE 1
- Segments 1
- Allocation inherit
- Read ahead sectors 0
- Block device 253:6
-
-The file gets created with default LV size which is 1 LE which is 4MB in this case.
-
- [root@node ~]# ls -lh /mnt/lv
- -rw-r–r–. 1 root root 4.0M Nov 26 16:15 /mnt/lv
-
-truncate can be used to set the required file size.
-
- [root@node ~]# truncate /mnt/lv -s 256M
- [root@node ~]# lvdisplay bd-vg
- — Logical volume —
- LV Path /dev/bd-vg/6ff0f25f-2776-4d19-adfb-df1a3cab8287
- LV Name 6ff0f25f-2776-4d19-adfb-df1a3cab8287
- VG Name bd-vg
- LV UUID PjMPcc-RkD5-RADz-6ixG-UYsk-oclz-vL0nv6
- LV Write Access read/write
- LV Creation host, time node, 2013-11-26 16:15:45 +0530
- LV Status available
- # open 0
- LV Size 256.00 MiB
- Current LE 64
- Segments 1
- Allocation inherit
- Read ahead sectors 0
- Block device 253:6
-
-
- [root@node ~]# ls -lh /mnt/lv
- -rw-r–r–. 1 root root 256M Nov 26 16:15 /mnt/lv
-
- currently LV size has been set to 256
-
-The size of the file/LV can be specified during creation/mapping time itself like this:
-
- setfattr -n “user.glusterfs.bd” -v “lv:256MB” /mnt/lv
-
-2. Creating BD volume with thin LV backend
-
-* Create a loop device
-
-
- [root@node ~]# dd if=/dev/zero of=bd-loop-thin count=1024 bs=1M
-
- [root@node ~]# losetup /dev/loop0 bd-loop-thin
-
-
-* Prepare a brick by creating a VG and thin pool
-
-
- [root@node ~]# pvcreate /dev/loop0
-
- [root@node ~]# vgcreate bd-vg-thin /dev/loop0
-
-
-* Create a thin pool
-
-
- [root@node ~]# lvcreate –thin bd-vg-thin -L 1000M
-
- Rounding up size to full physical extent 4.00 MiB
- Logical volume “lvol0″ created
-
-lvdisplay shows the thin pool
-
- [root@node ~]# lvdisplay bd-vg-thin
- — Logical volume —
- LV Name lvol0
- VG Name bd-vg-thin
- LV UUID HVa3EM-IVMS-QG2g-oqU6-1UxC-RgqS-g8zhVn
- LV Write Access read/write
- LV Creation host, time node, 2013-11-26 16:39:06 +0530
- LV Pool transaction ID 0
- LV Pool metadata lvol0_tmeta
- LV Pool data lvol0_tdata
- LV Pool chunk size 64.00 KiB
- LV Zero new blocks yes
- LV Status available
- # open 0
- LV Size 1000.00 MiB
- Allocated pool data 0.00%
- Allocated metadata 0.88%
- Current LE 250
- Segments 1
- Allocation inherit
- Read ahead sectors auto
- Block device 253:9
-
-* Create the BD volume
-
-* Create a POSIX directory first
-
-
- [root@node ~]# mkdir /bd-meta-thin
-
-* Create and mount the volume
-
- [root@node ~]# gluster volume create bd-thin node:/bd-meta-thin?bd-vg-thin force
-
- [root@node ~]# gluster volume start bd-thin
-
-
- [root@node ~]# gluster volume info bd-thin
- Volume Name: bd-thin
- Type: Distribute
- Volume ID: 27aa7eb0-4ffa-497e-b639-7cbda0128793
- Status: Started
- Xlator 1: BD
- Capability 1: thin
- Capability 2: offload_copy
- Capability 3: offload_snapshot
- Number of Bricks: 1
- Transport-type: tcp
- Bricks:
- Brick1: node:/bd-meta-thin
- Brick1 VG: bd-vg-thin
-
-
- [root@node ~]# mount -t glusterfs node:/bd-thin /mnt
-
-* Create a file that is backed by a thin LV
-
-
- [root@node ~]# ls /mnt
-
- [root@node ~]#
-
-Creating a file that is mapped to a thin LV is a 2 step operation. First the file should be created on the mount point and a specific extended attribute should be set to map the file to a thin LV.
-
- [root@node ~]# touch /mnt/thin-lv
-
- [root@node ~]# setfattr -n “user.glusterfs.bd” -v “thin:256MB” /mnt/thin-lv
-
-Now /mnt/thin-lv is a thin provisioned file that is backed by a thin LV and size has been set to 256.
-
- [root@node ~]# lvdisplay bd-vg-thin
- — Logical volume —
- LV Name lvol0
- VG Name bd-vg-thin
- LV UUID HVa3EM-IVMS-QG2g-oqU6-1UxC-RgqS-g8zhVn
- LV Write Access read/write
- LV Creation host, time node, 2013-11-26 16:39:06 +0530
- LV Pool transaction ID 1
- LV Pool metadata lvol0_tmeta
- LV Pool data lvol0_tdata
- LV Pool chunk size 64.00 KiB
- LV Zero new blocks yes
- LV Status available
- # open 0
- LV Size 000.00 MiB
- Allocated pool data 0.00%
- Allocated metadata 0.98%
- Current LE 250
- Segments 1
- Allocation inherit
- Read ahead sectors auto
- Block device 253:9
-
-
-
-
- — Logical volume —
- LV Path dev/bd-vg-thin/081b01d1-1436-4306-9baf-41c7bf5a2c73
- LV Name 081b01d1-1436-4306-9baf-41c7bf5a2c73
- VG Name bd-vg-thin
- LV UUID coxpTY-2UZl-9293-8H2X-eAZn-wSp6-csZIeB
- LV Write Access read/write
- LV Creation host, time node, 2013-11-26 16:43:19 +0530
- LV Pool name lvol0
- LV Status available
- # open 0
- LV Size 256.00 MiB
- Mapped size 0.00%
- Current LE 64
- Segments 1
- Allocation inherit
- Read ahead sectors auto
- Block device 253:10
-
-
-
-
-
-As can be seen from above, creation of a file resulted in creation of a thin LV in the brick.
-
-
-###Improvisation on BD translator:
-
-First version of BD xlator ( block backend) had few limitations such as
-
-* Creation of directories not supported
-* Supports only single brick
-* Does not use extended attributes (and client gfid) like posix xlator
-* Creation of special files (symbolic links, device nodes etc) not
- supported
-
-Basic limitation of not allowing directory creation was blocking
-oVirt/VDSM to consume BD xlator as part of Gluster domain since VDSM
-creates multi-level directories when GlusterFS is used as storage
-backend for storing VM images.
-
-To overcome these limitations a new BD xlator with following
-improvements are implemented.
-
-* New hybrid BD xlator that handles both regular files and block device
- files
-* The volume will have both POSIX and BD bricks. Regular files are
- created on POSIX bricks, block devices are created on the BD brick (VG)
-* BD xlator leverages exiting POSIX xlator for most POSIX calls and
- hence sits above the POSIX xlator
-* Block device file is differentiated from regular file by an extended
- attribute
-* The xattr 'user.glusterfs.bd' (BD_XATTR) plays a role in mapping a
- posix file to Logical Volume (LV).
-* When a client sends a request to set BD_XATTR on a posix file, a new
- LV is created and mapped to posix file. So every block device will
- have a representative file in POSIX brick with 'user.glusterfs.bd'
- (BD_XATTR) set.
-* Here after all operations on this file results in LV related
- operations.
-
-For example, opening a file that has BD_XATTR set results in opening
-the LV block device, reading results in reading the corresponding LV
-block device.
-
-When BD xlator gets request to set BD_XATTR via setxattr call, it
-creates a LV and information about this LV is placed in the xattr of the
-posix file. xattr "user.glusterfs.bd" used to identify that posix file
-is mapped to BD.
-
-Usage:
-Server side:
-
- [root@host1 ~]# gluster volume create bdvol host1:/storage/vg1_info?vg1 host2:/storage/vg2_info?vg2
-
-It creates a distributed gluster volume 'bdvol' with Volume Group vg1
-using posix brick /storage/vg1_info in host1 and Volume Group vg2 using
-/storage/vg2_info in host2.
-
-
- [root@host1 ~]# gluster volume start bdvol
-
-Client side:
-
- [root@node ~]# mount -t glusterfs host1:/bdvol /media
- [root@node ~]# touch /media/posix
-
-It creates regular posix file 'posix' in either host1:/vg1 or host2:/vg2 brick
-
- [root@node ~]# mkdir /media/image
-
- [root@node ~]# touch /media/image/lv1
-
-
-It also creates regular posix file 'lv1' in either host1:/vg1 or
-host2:/vg2 brick
-
- [root@node ~]# setfattr -n "user.glusterfs.bd" -v "lv" /media/image/lv1
-
- [root@node ~]#
-
-
-Above setxattr results in creating a new LV in corresponding brick's VG
-and it sets 'user.glusterfs.bd' with value 'lv:<default-extent-size''
-
-
- [root@node ~]# truncate -s5G /media/image/lv1
-
-
-It results in resizig LV 'lv1'to 5G
-
-New BD xlator code is placed in `xlators/storage/bd` directory.
-
-Also add volume-uuid to the VG so that same VG cannot be used for other
-bricks/volumes. After deleting a gluster volume, one has to manually
-remove the associated tag using vgchange <vg-name> --deltag
-`<trusted.glusterfs.volume-id:<volume-id>>`
-
-
-#### Exposing volume capabilities
-
-With multiple storage translators (posix and bd) being supported in GlusterFS, it becomes
-necessary to know the volume type so that user can issue appropriate calls that are relevant
-only to the a given volume type. Hence there needs to be a way to expose the type of
-the storage translator of the volume to the user.
-
-BD xlator is capable of providing server offloaded file copy, server/storage offloaded
-zeroing of a file etc. This capabilities should be visible to the client/user, so that these
-features can be exploited.
-
-BD xlator exports capability information through gluster volume info (and --xml) output. For eg:
-
-`snip of gluster volume info output for a BD based volume`
-
- Xlator 1: BD
- Capability 1: thin
-
-`snip of gluster volume info --xml output for a BD based volume`
-
- <xlators>
- <xlator>
- <name>BD</name>
- <capabilities>
- <capability>thin</capability>
- </capabilities>
- </xlator>
- </xlators>
-
-But this capability information should also exposed through some other means so that a host
-which is not part of Gluster peer could also avail this capabilities.
-
-* Type
-
-BD translator supports both regular files and block device, i,e., one can create files on
-GlusterFS volume backed by BD translator and this file could end up as regular posix file or
-a logical volume (block device) based on the user''s choice. User can do a setxattr on the
-created file to convert it to a logical volume.
-
-Users of BD backed volume like QEMU would like to know that it is working with BD type of volume
-so that it can issue an additional setxattr call after creating a VM image on GlusterFS backend.
-This is necessary to ensure that the created VM image is backed by LV instead of file.
-
-There are different ways to expose this information (BD type of volume) to user.
-One way is to export it via a `getxattr` call. That said, When a client issues getxattr("volume_type")
-on a root gfid, bd xlator will return 1 implying its BD xlator. But posix xlator will return ENODATA
-and client code can interpret this as posix xlator. Also capability list can be returned via
-getxattr("caps") for root gfid.
-
-* Capabilities
-
-BD xlator supports new features such as server offloaded file copy, thin provisioned VM images etc.
-
-There is no standard way of exploiting these features from client side (such as syscall
-to exploit server offloaded copy). So these features need to be exported to the client so that
-they can be used. BD xlator latest version exports these capabilities information through
-gluster volume info (and --xml) output. But if a client is not part of GlusterFS peer
-it can''t run volume info command to get the list of capabilities of a given GlusterFS volume.
-For example, GlusterFS block driver in qemu need to get the capability list so that these features are used.
-
-
-
-Parts of this documentation were originally published here
-#http://raobharata.wordpress.com/2013/11/27/glusterfs-block-device-translator/
diff --git a/doc/developer-guide/brickmux-thread-reduction.md b/doc/developer-guide/brickmux-thread-reduction.md
new file mode 100644
index 00000000000..7d76e8ff579
--- /dev/null
+++ b/doc/developer-guide/brickmux-thread-reduction.md
@@ -0,0 +1,64 @@
+# Resource usage reduction in brick multiplexing
+
+Each brick is regresented with a graph of translators in a brick process.
+Each translator in the graph has its own set of threads and mem pools
+and other system resources allocations. Most of the times all these
+resources are not put to full use. Reducing the resource consumption
+of each brick is a problem in itself that needs to be addressed. The other
+aspect to it is, sharing of resources across brick graph, this becomes
+critical in brick multiplexing scenario. In this document we will be discussing
+only about the threads.
+
+If a brick mux process hosts 50 bricks there are atleast 600+ threads created
+in that process. Some of these are global threads that are shared by all the
+brick graphs, and others are per translator threads. The global threads like
+synctask threads, timer threads, sigwaiter, poller etc. are configurable and
+do not needs to be reduced. The per translator threads keeps growing as the
+number of bricks in the process increases. Each brick spawns atleast 10+
+threads:
+- io-threads
+- posix threads:
+ 1. Janitor
+ 2. Fsyncer
+ 3. Helper
+ 4. aio-thread
+- changelog and bitrot threads(even when the features are not enabled)
+
+## io-threads
+
+io-threads should be made global to the process, having 16+ threads for
+each brick does not make sense. But io-thread translator is loaded in
+the graph, and the position of io-thread translator decides from when
+the fops will be parallelised across threads. We cannot entirely move
+the io-threads to libglusterfs and say the multiplexing happens from
+the master translator or so. Hence, the io-thread orchestrator code
+is moved to libglusterfs, which ensures there is only one set of
+io-threads that is shared among the io-threads translator in each brick.
+This poses performance issues due to lock-contention in the io-threds
+layer. This also shall be addressed by having multiple locks instead of
+one global lock for io-threads.
+
+## Posix threads
+Most of the posix threads execute tasks in a timely manner, hence it can be
+replaced with a timer whose handler register a task to synctask framework, once
+the task is complete, the timer is registered again. With this we can eliminate
+the need of one thread for each task. The problem with using synctasks is
+the performance impact it will have due to make/swapcontext. For task that
+does not involve network wait, we need not do makecontext, instead the task
+function with arg can be stored and executed when a synctask thread is free.
+We need to implement an api in synctask to execute atomic tasks(no network wait)
+without the overhead of make/swapcontext. This will solve the performance
+impact associated with using synctask framework.
+
+And the other challenge, is to cancel all the tasks pending from a translator.
+This is important to cleanly detach brick. For this, we need to implement an
+api in synctask that can cancel all the tasks from a given translator.
+
+For future, this will be replced to use global thread-pool(once implemented).
+
+## Changelog and bitrot threads
+
+In the initial implementation, the threads are not created if the feature is
+not enabled. We need to share threads across changelog instances if we plan
+to enable these features in brick mux scenario.
+
diff --git a/doc/developer-guide/coding-standard.md b/doc/developer-guide/coding-standard.md
index 368c5553464..031c6c0da99 100644
--- a/doc/developer-guide/coding-standard.md
+++ b/doc/developer-guide/coding-standard.md
@@ -1,11 +1,38 @@
GlusterFS Coding Standards
==========================
+Before you get started
+----------------------
+Before starting with other part of coding standard, install `clang-format`
+
+On Fedora:
+```
+$ dnf install clang
+```
+On debian/Ubuntu:
+```
+$ apt-get install clang
+```
+Once you are done with all the local changes, you need to run below set of commands,
+before submitting the patch for review.
+```
+$ git add $file # if any
+$ git commit -a -s -m "commit message"
+$ git show --pretty="format:" --name-only | grep -v "contrib/" | egrep "*\.[ch]$" | xargs clang-format -i
+$ git diff # see if there are any changes
+$ git commit -a --amend # get the format changes done
+$ ./submit-for-review.sh
+```
+
+
Structure definitions should have a comment per member
------------------------------------------------------
-Every member in a structure definition must have a comment about its
-purpose. The comment should be descriptive without being overly verbose.
+Every member in a structure definition must have a comment about its purpose.
+The comment should be descriptive without being overly verbose. For pointer
+members, lifecycle concerns for the pointed-to object should be noted. For lock
+members, the relationship between the lock member and the other members it
+protects should be explicit.
*Bad:*
@@ -23,59 +50,182 @@ DBTYPE access_mode; /* access mode for accessing
*/
```
-Declare all variables at the beginning of the function
-------------------------------------------------------
+Structure members should be aligned based on the padding requirements
+---------------------------------------------------------------------
-All local variables in a function must be declared immediately after the
-opening brace. This makes it easy to keep track of memory that needs to be freed
-during exit. It also helps debugging, since gdb cannot handle variables
-declared inside loops or other such blocks.
+The compiler will make sure that structure members have optimum alignment,
+but at the expense of suboptimal padding. More important is to optimize the
+padding. The compiler won't do that for you.
-Always initialize local variables
----------------------------------
+This also will help utilize the memory better
-Every local variable should be initialized to a sensible default value
-at the point of its declaration. All pointers should be initialized to NULL,
-and all integers should be zero or (if it makes sense) an error value.
+*Bad:*
+```
+struct bad {
+ bool b; /* 0 */
+ /* 1..7 pad */
+ void *p; /* 8..15 */
+ char c; /* 16 */
+ char a[16]; /* 17..33 */
+ /* 34..39 pad */
+ int64_t ii; /* 40..47 */
+ int32_t i; /* 48..51 */
+ /* 52..55 pad */
+ int64_t iii; /* 56..63 */
+};
+```
+*Good:*
+```
+struct good {
+ int64_t ii; /* explicit 64-bit types */
+ void *p; /* may be 64- or 32-bit */
+ long l; /* may be 64- or 32-bit */
+ int i; /* 32-bit */
+ short s; /* 16-bit */
+ char c; /* 8-bit */
+ bool b; /* 8-bit */
+ char a[1024];
+);
+```
+Make sure the items with the most stringent alignment requirements will need
+to come earliest (ie, pointers and perhaps uint64_t etc), and those with less
+stringent alignment requirements at the end (uint16/uint8 and char). Also note
+that the long array (if any) should be at the end of the structure, regardless
+of the type.
+
+Also note, if your structure's overall size is crossing 1k-4k limit, it is
+recommended to mention the reason why the particular structure needs so much
+memory as a comment at the top.
+
+Use \_typename for struct tags and typename\_t for typedefs
+---------------------------------------------------------
+
+Being consistent here makes it possible to automate navigation from use of a
+type to its true definition (not just the typedef).
+
+*Bad:*
+
+```
+struct thing {...};
+struct thing_t {...};
+typedef struct _thing thing;
+```
*Good:*
```
-int ret = 0;
-char *databuf = NULL;
-int _fd = -1;
+typedef struct _thing {...} thing_t;
```
-Initialization should always be done with a constant value
-----------------------------------------------------------
+No double underscores
+---------------------
+
+Identifiers beginning with double underscores are supposed to reserved for the
+compiler.
-Never use a non-constant expression as the initialization value for a variable.
+http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
+When you need to define inner/outer functions, use a different prefix/suffix.
*Bad:*
```
+void __do_something (void);
+
+void
+do_something (void)
+{
+ LOCK ();
+ __do_something ();
+ UNLOCK ();
+}
+```
+
+*Good:*
+
+```
+void do_something_locked (void);
+```
+
+Only use safe pointers in initializers
+----------------------------------------------------------
+
+Some pointers, such as `this` in a fop function, can be assumed to be non-NULL.
+However, other parameters and further-derived values might be NULL.
+
+*Good:*
+
+```
pid_t pid = frame->root->pid;
-char *databuf = malloc (1024);
```
+
+*Bad:*
+
+```
+data_t *my_data = dict_get (xdata, "fubar");
+```
+
+No giant stack allocations
+--------------------------
+
+Synctasks have small finite stacks. To avoid overflowing these stacks, avoid
+allocating any large data structures on the stack. Use dynamic allocation
+instead.
+
+*Bad:*
+
+```
+gf_boolean_t port_inuse[65536]; /* 256KB, this actually happened */
+```
+
+NOTE: Ideal is to limit the stack array to less than 256 bytes.
+
+
+Character array initializing
+----------------------------
+
+It is recommended to keep the character array initializing to empty string.
+
+*Good:*
+```
+char msg[1024] = "";
+```
+
+Not so much recommended, even though it means the same.
+
+```
+char msg[1024] = {0,};
+```
+
+We recommend above to structure initialization.
+
+
+
Validate all arguments to a function
------------------------------------
All pointer arguments to a function must be checked for `NULL`.
-A macro named `VALIDATE` (in `common-utils.h`)
-takes one argument, and if it is `NULL`, writes a log message and
-jumps to a label called `err` after setting op_ret and op_errno
-appropriately. It is recommended to use this template.
+A macro named `GF_VALIDATE_OR_GOTO` (in `common-utils.h`)
+takes two arguments; if the first is `NULL`, it writes a log message and
+jumps to a label specified by the second aergument after setting errno
+appropriately. There are several variants of this function for more
+specific purposes, and their use is recommended.
+
+*Bad:*
+```
+/* top of function */
+ret = dict_get (xdata, ...)
+```
*Good:*
```
-VALIDATE(frame);
-VALIDATE(this);
-VALIDATE(inode);
+/* top of function */
+GF_VALIDATE_OR_GOTO(xdata,out);
+ret = dict_get (xdata, ...)
```
Never rely on precedence of operators
@@ -83,25 +233,34 @@ Never rely on precedence of operators
Never write code that relies on the precedence of operators to execute
correctly. Such code can be hard to read and someone else might not
-know the precedence of operators as accurately as you do.
+know the precedence of operators as accurately as you do. This includes
+precedence of increment/decrement vs. field/subscript. The only exceptions are
+arithmetic operators (which have had defined precedence since before computers
+even existed) and boolean negation.
*Bad:*
```
if (op_ret == -1 && errno != ENOENT)
+++foo->bar /* incrementing foo, or incrementing foo->bar? */
+a && b || !c
```
*Good:*
```
if ((op_ret == -1) && (errno != ENOENT))
+(++foo)->bar
+++(foo->bar)
+(a && b) || !c
+a && (b || !c)
```
Use exactly matching types
--------------------------
Use a variable of the exact type declared in the manual to hold the
-return value of a function. Do not use an ``equivalent'' type.
+return value of a function. Do not use an 'equivalent' type.
*Bad:*
@@ -116,42 +275,56 @@ int len = strlen (path);
size_t len = strlen (path);
```
-Never write code such as `foo->bar->baz`; check every pointer
+Avoid code such as `foo->bar->baz`; check every pointer
-------------------------------------------------------------
-Do not write code that blindly follows a chain of pointer
-references. Any pointer in the chain may be `NULL` and thus
-cause a crash. Verify that each pointer is non-null before following
-it.
+Do not write code that blindly follows a chain of pointer references. Any
+pointer in the chain may be `NULL` and thus cause a crash. Verify that each
+pointer is non-null before following it. Even if `foo->bar` has been checked
+and is known safe, repeating it can make code more verbose and less clear.
-Check return value of all functions and system calls
+This rule includes `[]` as well as `->` because both dereference pointers.
+
+*Bad:*
+
+```
+foo->bar->field1 = value1;
+xyz = foo->bar->field2 + foo->bar->field3 * foo->bar->field4;
+foo->bar[5].baz
+```
+
+*Good:*
+
+```
+my_bar = foo->bar;
+if (!my_bar) ... return;
+my_bar->field1 = value1;
+xyz = my_bar->field2 + my_bar->field3 * my_bar->field4;
+```
+
+Document unchecked return values
----------------------------------------------------
-The return value of all system calls and API functions must be checked
-for success or failure.
+In general, return values should be checked. If a function is being called
+for its side effects and the return value really doesn't matter, an explicit
+cast to void is required (to keep static analyzers happy) and a comment is
+recommended.
*Bad:*
```
close (fd);
+do_important_thing ();
```
-*Good:*
+*Good (or at least OK):*
```
-op_ret = close (_fd);
-if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "close on file %s failed (%s)", real_path,
- strerror (errno));
- op_errno = errno;
- goto out;
-}
+(void) sleep (1);
```
-
-Gracefully handle failure of malloc
------------------------------------
+Gracefully handle failure of malloc (and other allocation functions)
+--------------------------------------------------------------------
GlusterFS should never crash or exit due to lack of memory. If a
memory allocation fails, the call should be unwound and an error
@@ -176,7 +349,7 @@ int32_t dict_get_int32 (dict_t *this, char *key);
int dict_get_int32 (dict_t *this, char *key, int32_t *val);
```
-Always use the `n' versions of string functions
+Always use the 'n' versions of string functions
-----------------------------------------------
Unless impossible, use the length-limited versions of the string functions.
@@ -193,18 +366,43 @@ strcpy (entry_path, real_path);
strncpy (entry_path, real_path, entry_path_len);
```
+Do not use memset prior to sprintf/snprintf/vsnprintf etc...
+------------------------------------------------------------
+snprintf(and other similar string functions) terminates the buffer with a
+'\0'(null character). Hence, there is no need to do a memset before using
+snprintf. (Of course you need to account one extra byte for the null character
+in your allocation).
+
+Note: Similarly if you are doing pre-memory allocation for the buffer, use
+GF_MALLOC instead of GF_CALLOC, since the later is bit costlier.
+
+*Bad:*
+
+```
+char buffer[x];
+memset (buffer, 0, x);
+bytes_read = snprintf (buffer, sizeof buffer, "bad standard");
+```
+
+*Good:*
+```
+char buffer[x];
+bytes_read = snprintf (buffer, sizeof (buffer), "good standard");
+```
+
+And it is always to good initialize the char array if the string is static.
+
+E.g.
+```
+char buffer[] = "good standard";
+```
+
No dead or commented code
-------------------------
There must be no dead code (code to which control can never be passed) or
commented out code in the codebase.
-Only one unwind and return per function
----------------------------------------
-
-There must be only one exit out of a function. `UNWIND` and return
-should happen at only point in the function.
-
Function length or Keep functions small
---------------------------------------
@@ -226,20 +424,35 @@ same_owner (posix_lock_t *l1, posix_lock_t *l2)
}
```
-Defining functions as static
-----------------------------
+Define functions as static
+--------------------------
+
+Declare functions as static unless they're exposed via a module-level API for
+use from other modules.
+
+No nested functions
+-------------------
+
+Nested functions have proven unreliable, e.g. as callbacks in code that uses
+ucontext (green) threads,
+
+Use inline functions instead of macros whenever possible
+--------------------------------------------------------
-Define internal functions as static only if you're
-very sure that there will not be a crash(..of any kind..) emanating in
-that function. If there is even a remote possibility, perhaps due to
-pointer derefering, etc, declare the function as non-static. This
-ensures that when a crash does happen, the function name shows up the
-in the back-trace generated by libc. However, doing so has potential
-for polluting the function namespace, so to avoid conflicts with other
-components in other parts, ensure that the function names are
-prepended with a prefix that identify the component to which it
-belongs. For eg. non-static functions in io-threads translator start
-with iot_.
+Inline functions enforce type safety; macros do not. Use macros only for things
+that explicitly need to be type-agnostic (e.g. cases where one might use
+generics or templates in other languages), or that use other preprocessor
+features such as `#` for stringification or `##` for token pasting. In general,
+"static inline" is the preferred form.
+
+Avoid copypasta
+---------------
+
+Code that is copied and then pasted into multiple functions often creates
+maintenance problems later, e.g. updating all but one instance for a subsequent
+change. If you find yourself copying the same "boilerplate" many places,
+consider refactoring to use helper functions (including inline) or macros, or
+code generation.
Ensure function calls wrap around after 80-columns
--------------------------------------------------
@@ -335,13 +548,95 @@ pthread_mutex_lock (&mutex);
pthread_mutex_unlock (&mutex);
```
-*A skeleton fop function:*
+### Always use braces
+
+Even around single statements.
+
+*Bad:*
+
+```
+if (condition) action ();
+
+if (condition)
+ action ();
+```
+
+*Good:*
+
+```
+if (condition) {
+ action ();
+}
+```
+
+### Avoid multi-line conditionals
+
+These can be hard to read and even harder to modify later. Predicate functions
+and helper variables are always better for maintainability.
+
+*Bad:*
+
+```
+if ((thing1 && other_complex_condition (thing1, lots, of, args))
+ || (!thing2 || even_more_complex_condition (thing2))
+ || all_sorts_of_stuff_with_thing3) {
+ return;
+}
+
+```
+
+*Better:*
+
+```
+thing1_ok = predicate1 (thing1, lots, of, args
+thing2_ok = predicate2 (thing2);
+thing3_ok = predicate3 (thing3);
+
+if (!thing1_ok || !thing2_ok || !thing3_ok) {
+ return;
+}
+```
+
+*Best:*
+
+```
+if (thing1 && other_complex_condition (thing1, lots, of, args)) {
+ return;
+}
+if (!thing2 || even_more_complex_condition (thing2)) {
+ /* Note potential for a different message here. */
+ return;
+}
+if (all_sorts_of_stuff_with_thing3) {
+ /* And here too. */
+ return;
+}
+```
+
+### Use 'const' liberally
+
+If a value isn't supposed/expected to change, there's no cost to adding a
+'const' keyword and it will help prevent violation of expectations.
+
+### Avoid global variables (including 'static' auto variables)
+Almost all state in Gluster is contextual and should be contained in the
+appropriate structure reflecting its scope (e.g. `call\_frame\_t`, `call\_stack\_t`,
+`xlator\_t`, `glusterfs\_ctx\_t`). With dynamic loading and graph switches in play,
+each global requires careful consideration of when it should be initialized or
+reinitialized, when it might _accidentally_ be reinitialized, when its value
+might become stale, and so on. A few global variables are needed to serve as
+'anchor points' for these structures, and more exceptions to the rule might be
+approved in the future, but new globals should not be added to the codebase
+without explicit approval.
+
+## A skeleton fop function
-This is the recommended template for any fop. In the beginning come
-the initializations. After that, the `success' control flow should be
-linear. Any error conditions should cause a `goto` to a single
-point, `out`. At that point, the code should detect the error
-that has occurred and do appropriate cleanup.
+This is the recommended template for any fop. In the beginning come the
+initializations. After that, the 'success' control flow should be linear. Any
+error conditions should cause a `goto` to a label at the end. By convention
+this is 'out' if there is only one such label, but a cascade of such labels is
+allowable to support multi-stage cleanup. At that point, the code should detect
+the error that has occurred and do appropriate cleanup.
```
int32_t
diff --git a/doc/developer-guide/commit-guidelines.md b/doc/developer-guide/commit-guidelines.md
new file mode 100644
index 00000000000..38bbe525cbd
--- /dev/null
+++ b/doc/developer-guide/commit-guidelines.md
@@ -0,0 +1,136 @@
+## Git Commit Good Practice
+
+The following document is based on experience doing code development, bug troubleshooting and code review across a number of projects using Git. The document is mostly borrowed from [Open Stack](https://wiki.openstack.org/wiki/GitCommitMessages), but made more meaningful in the context of GlusterFS project.
+
+This topic can be split into two areas of concern
+
+* The structured set/split of the code changes
+* The information provided in the commit message
+
+### Executive Summary
+The points and examples that will be raised in this document ought to clearly demonstrate the value in splitting up changes into a sequence of individual commits, and the importance in writing good commit messages to go along with them. If these guidelines were widely applied it would result in a significant improvement in the quality of the GlusterFS Git history. Both a carrot & stick will be required to effect changes. This document intends to be the carrot by alerting people to the benefits, while anyone doing Gerrit code review can act as the stick ;-P
+
+In other words, when reviewing a change in Gerrit:
+* Do not simply look at the correctness of the code.
+* Review the commit message itself and request improvements to its content.
+* Look out for commits which are mixing multiple logical changes and require the submitter to split them into separate commits.
+* Ensure whitespace changes are not mixed in with functional changes.
+* Ensure no-op code refactoring is done separately from functional changes.
+
+And so on.
+
+It might be mentioned that Gerrit's handling of patch series is not entirely perfect. Let that not become a valid reason to avoid creating patch series. The tools being used should be subservient to developers needs, and since they are open source they can be fixed / improved. Software source code is "read mostly, write occassionally" and thus the most important criteria is to improve the long term maintainability by the large pool of developers in the community, and not to sacrifice too much for the sake of the single author who may never touch the code again.
+
+And now the long detailed guidelines & examples of good & bad practice
+
+### Structural split of changes
+The cardinal rule for creating good commits is to ensure there is only one "logical change" per commit. There are many reasons why this is an important rule:
+
+* The smaller the amount of code being changed, the quicker & easier it is to review & identify potential flaws.
+* If a change is found to be flawed later, it may be necessary to revert the broken commit. This is much easier to do if there are not other unrelated code changes entangled with the original commit.
+* When troubleshooting problems using Git's bisect capability, small well defined changes will aid in isolating exactly where the code problem was introduced.
+* When browsing history using Git annotate/blame, small well defined changes also aid in isolating exactly where & why a piece of code came from.
+
+#### Things to avoid when creating commits
+With the above points in mind, there are some commonly encountered examples of bad things to avoid
+
+* Mixing whitespace changes with functional code changes.
+
+The whitespace changes will obscure the important functional changes, making it harder for a reviewer to correctly determine whether the change is correct. Solution: Create 2 commits, one with the whitespace changes, one with the functional changes. Typically the whitespace change would be done first, but that need not be a hard rule.
+
+* Mixing two unrelated functional changes.
+
+Again the reviewer will find it harder to identify flaws if two unrelated changes are mixed together. If it becomes necessary to later revert a broken commit, the two unrelated changes will need to be untangled, with further risk of bug creation.
+
+* Sending large new features in a single giant commit.
+
+It may well be the case that the code for a new feature is only useful when all of it is present. This does not, however, imply that the entire feature should be provided in a single commit. New features often entail refactoring existing code. It is highly desirable that any refactoring is done in commits which are separate from those implementing the new feature. This helps reviewers and test suites validate that the refactoring has no unintentional functional changes.
+
+Even the newly written code can often be split up into multiple pieces that can be independently reviewed. For example, changes which add new internal fops or library functions, can be in self-contained commits. Again this leads to easier code review. It also allows other developers to cherry-pick small parts of the work, if the entire new feature is not immediately ready for merge. This will encourage the author & reviewers to think about the generic library functions' design, and not simply pick a design that is easier for their currently chosen internal implementation.
+
+The basic rule to follow is
+
+If a code change can be split into a sequence of patches/commits, then it should be split. Less is not more. More is more.
+
+##### Examples of bad practice
+
+TODO: Pick glusterfs specific example.
+
+
+##### Examples of good practice
+
+
+### Information in commit messages
+As important as the content of the change, is the content of the commit message describing it. When writing a commit message there are some important things to remember
+
+* Do not assume the reviewer understands what the original problem was.
+
+When reading bug reports, after a number of back & forth comments, it is often as clear as mud, what the root cause problem is. The commit message should have a clear statement as to what the original problem is. The bug is merely interesting historical background on /how/ the problem was identified. It should be possible to review a proposed patch for correctness without needing to read the bug ticket.
+
+* Do not assume the reviewer has access to external web services/site.
+
+In 6 months time when someone is on a train/plane/coach/beach/pub troubleshooting a problem & browsing Git history, there is no guarantee they will have access to the online bug tracker, or online blueprint documents. The great step forward with distributed SCM is that you no longer need to be "online" to have access to all information about the code repository. The commit message should be totally self-contained, to maintain that benefit.
+
+* Do not assume the code is self-evident/self-documenting.
+
+What is self-evident to one person, might be clear as mud to another person. Always document what the original problem was and how it is being fixed, for any change except the most obvious typos, or whitespace only commits.
+
+* Describe why a change is being made.
+
+A common mistake is to just document how the code has been written, without describing /why/ the developer chose to do it that way. By all means describe the overall code structure, particularly for large changes, but more importantly describe the intent/motivation behind the changes.
+
+* Read the commit message to see if it hints at improved code structure.
+
+Often when describing a large commit message, it becomes obvious that a commit should have in fact been split into 2 or more parts. Don't be afraid to go back and rebase the change to split it up into separate commits.
+
+* Ensure sufficient information to decide whether to review.
+
+When Gerrit sends out email alerts for new patch submissions there is minimal information included, principally the commit message and the list of files changes. Given the high volume of patches, it is not reasonable to expect all reviewers to examine the patches in detail. The commit message must thus contain sufficient information to alert the potential reviewers to the fact that this is a patch they need to look at.
+
+* The first commit line is the most important.
+
+In Git commits the first line of the commit message has special significance. It is used as email subject line, git annotate messages, gitk viewer annotations, merge commit messages and many more places where space is at a premium. As well as summarizing the change itself, it should take care to detail what part of the code is affected. eg if it is 'afr', 'dht' or any translator. Or in some cases, it can be touching all these components, but the commit message can be 'coverity:', 'txn-framework:', 'new-fop: ', etc.
+
+* Describe any limitations of the current code.
+
+If the code being changed still has future scope for improvements, or any known limitations then mention these in the commit message. This demonstrates to the reviewer that the broader picture has been considered and what tradeoffs have been done in terms of short term goals vs. long term wishes.
+
+* Do not include patch set-specific comments.
+
+In other words, if you rebase your change please don't add "Patch set 2: rebased" to your commit message. That isn't going to be relevant once your change has merged. Please do make a note of that in Gerrit as a comment on your change, however. It helps reviewers know what changed between patch sets. This also applies to comments such as "Added unit tests", "Fixed localization problems", or any other such patch set to patch set changes that don't affect the overall intent of your commit.
+
+**The main rule to follow is:**
+
+The commit message must contain all the information required to fully understand & review the patch for correctness. Less is not more. More is more.
+
+
+#### Including external references
+
+The commit message is primarily targeted towards human interpretation, but there is always some metadata provided for machine use. In the case of GlusterFS this includes at least the 'Change-id', "bug"/"feature" ID references and "Signed-off-by" tag (generated by 'git commit -s').
+
+The 'Change-id' line is a unique hash describing the change, which is generated by a Git commit hook. This should not be changed when rebasing a commit following review feedback, since it is used by Gerrit, to track versions of a patch.
+
+The 'bug' line can reference a bug in a few ways. Gerrit creates a link to the bug when viewing the patch on review.gluster.org so that reviewers can quickly access the bug/issue on Bugzilla or Github.
+
+**Fixes: bz#1601166** -- use 'Fixes: bz#NNNNN' if the commit is intended to fully fix and close the bug being referenced.
+**Fixes: #411** -- use 'Fixes: #NNN' if the patch fixes the github issue completely.
+
+**Updates: bz#1193929** -- use 'Updates: bz#NNNN' if the commit is only a partial fix and more work is needed.
+**Updates: #175** -- use 'Updates: #NNNN' if the commit is only a partial fix and more work is needed for the feature completion.
+
+We encourage the use of `Co-Authored-By: name <name@example.com>` in commit messages to indicate people who worked on a particular patch. It's a convention for recognizing multiple authors, and our projects would encourage the stats tools to observe it when collecting statistics.
+
+### Summary of Git commit message structure
+
+* Provide a brief description of the change in the first line.
+* The first line should be limited to 50 characters and should not end with a period.
+
+* Insert a single blank line after the first line.
+
+* Provide a detailed description of the change in the following lines, breaking paragraphs where needed.
+
+* Subsequent lines should be wrapped at 72 characters.
+
+Put the 'Change-id', 'Fixes bz#NNNNN' and 'Signed-off-by: <>' lines at the very end.
+
+TODO: Add good examples
diff --git a/doc/developer-guide/daemon-management-framework.md b/doc/developer-guide/daemon-management-framework.md
index cf29caa95ce..592192e665d 100644
--- a/doc/developer-guide/daemon-management-framework.md
+++ b/doc/developer-guide/daemon-management-framework.md
@@ -25,12 +25,9 @@ Data members & functions of different management objects
- connection object
- process object
- online status
- - Methods
- -- manager, start, stop which can be abstracted as a common
- methods or specific to service requirements
- -- init API is invoked on demand of the service and currently integrated
- into manager.
- -- build method is to initialize the method pointers
+ - Methods - manager, start, stop which can be abstracted as a common methods
+ or specific to service requirements
+ - init API can be invoked using the service management object
The above structures defines the skeleton of the daemon management framework.
Introduction of new daemons in GlusterFS needs to inherit these properties. Any
diff --git a/doc/developer-guide/data-structures/inode.md b/doc/developer-guide/datastructure-inode.md
index a340ab9ca8e..45d7a941e5f 100644
--- a/doc/developer-guide/data-structures/inode.md
+++ b/doc/developer-guide/datastructure-inode.md
@@ -1,6 +1,6 @@
-#Inode and dentry management in GlusterFS:
+# Inode and dentry management in GlusterFS:
-##Background
+## Background
Filesystems internally refer to files and directories via inodes. Inodes
are unique identifiers of the entities stored in a filesystem. Whenever an
application has to operate on a file/directory (read/modify), the filesystem
@@ -41,11 +41,10 @@ struct _inode_table {
};
```
-#Life-cycle
+# Life-cycle
```
-
inode_table_new (size_t lru_limit, xlator_t *xl)
-
+```
This is a function which allocates a new inode table. Usually the top xlators in
the graph such as protocol/server (for bricks), fuse and nfs (for fuse and nfs
mounts) and libgfapi do inode managements. Hence they are the ones which will
@@ -59,11 +58,8 @@ new inode table.
Thus an allocated inode table is destroyed only when the filesystem daemon is
killed or unmounted.
-```
-
-#what it contains.
-```
+# what it contains.
Inode table in glusterfs mainly contains a hash table for maintaining inodes.
In general a file/directory is considered to be existing if there is a
corresponding inode present in the inode table. If a inode for a file/directory
@@ -76,21 +72,21 @@ size of the hash table (as of now it is hard coded to 14057. The hash value of
a inode is calculated using its gfid).
Apart from the hash table, inode table also maintains 3 important list of inodes
-1) Active list:
+1. Active list:
Active list contains all the active inodes (i.e inodes which are currently part
of some fop).
-2) Lru list:
+2. Lru list:
Least recently used inodes list. A limit can be set for the size of the lru
list. For bricks it is 16384 and for clients it is infinity.
-3) Purge list:
+3. Purge list:
List of all the inodes which have to be purged (i.e inodes which have to be
deleted from the inode table due to unlink/rmdir/forget).
And at last it also contains the mem-pool for allocating inodes, dentries so
that frequent malloc/calloc and free of the data structures can be avoided.
-```
-#Data structure (inode)
+
+# Data structure (inode)
```
struct _inode {
inode_table_t *table; /* the table this inode belongs to */
@@ -108,7 +104,7 @@ struct _inode {
struct _inode_ctx *_ctx; /* place holder for keeping the
information about the inode by different xlators */
};
-
+```
As said above, inodes are internal way of identifying the files/directories. A
inode uniquely represents a file/directory. A new inode is created whenever a
create/mkdir/symlink/mknod operations are performed. Apart from that a new inode
@@ -128,9 +124,9 @@ inodes are those inodes whose refcount is greater than zero. Whenever some
operation comes on a file/directory, and the resolver tries to find the inode
for it, it increments the refcount of the inode before returning the inode. The
refcount of an inode can be incremented by calling the below function
-
+```
inode_ref (inode_t *inode)
-
+```
Any xlator which wants to operate on a inode as part of some fop (or wants the
inode in the callback), should hold a ref on the inode.
Once the fop is completed before sending the reply of the fop to the above
@@ -139,18 +135,18 @@ zero, it is removed from the active inodes list and put into LRU list maintained
by the inode table. Thus in short if some fop is happening on a file/directory,
the corresponding inode will be in the active list or it will be in the LRU
list.
-```
-#Life Cycle
+
+# Life Cycle
A new inode is created whenever a new file/directory/symlink is created OR a
successful lookup of an existing entry is done. The xlators which does inode
management (as of now protocol/server, fuse, nfs, gfapi) will perform inode_link
operation upon successful lookup or successful creation of a new entry.
-
+```
inode_link (inode_t *inode, inode_t *parent, const char *name,
struct iatt *buf);
-
+```
inode_link actually adds the inode to the inode table (to be precise it adds
the inode to the hash table maintained by the inode table. The hash value is
calculated based on the gfid). Copies the gfid to the inode (the gfid is
@@ -160,7 +156,7 @@ A inode is removed from the inode table and eventually destroyed when unlink
or rmdir operation is performed on a file/directory, or the the lru limit of
the inode table has been exceeded.
-#Data structure (dentry)
+# Data structure (dentry)
```
struct _dentry {
@@ -170,22 +166,22 @@ struct _dentry {
char *name; /* name of the directory entry */
inode_t *parent; /* directory of the entry */
};
-
+```
A dentry is the presence of an entry for a file/directory within its parent
directory. A dentry usually points to the inode to which it belongs to. In
glusterfs a dentry contains the following fields.
-1) a hook using which it can add itself to the list of
+1. a hook using which it can add itself to the list of
the dentries maintained by the inode to which it points to.
-2) A hash table pointer.
-3) Pointer to the inode to which it belongs to.
-4) Name of the dentry
-5) Pointer to the inode of the parent directory in which the dentry is present
+2. A hash table pointer.
+3. Pointer to the inode to which it belongs to.
+4. Name of the dentry
+5. Pointer to the inode of the parent directory in which the dentry is present
A new dentry is created when a new file/directory/symlink is created or a hard
link to an existing file is created.
-
+```
__dentry_create (inode_t *inode, inode_t *parent, const char *name);
-
+```
A dentry holds a refcount on the parent
directory so that the parent inode is never removed from the active inode's list
and put to the lru list (If the lru limit of the lru list is exceeded, there is
@@ -212,15 +208,14 @@ deleted due to file removal or lru limit being exceeded the inode is retired
purge list maintained by the inode table), the nlookup count is set to 0 via
inode_forget api. The inode table, then prunes all the inodes from the purge
list by destroying the inode contexts maintained by each xlator.
-
+```
unlinking of the dentry is done via inode_unlink;
void
inode_unlink (inode_t *inode, inode_t *parent, const char *name);
-
+```
If the inode has multiple hard links, then the unlink operation performed by
the application results just in the removal of the dentry with the name provided
by the application. For the inode to be removed, all the dentries of the inode
should be unlinked.
-```
diff --git a/doc/developer-guide/data-structures/iobuf.md b/doc/developer-guide/datastructure-iobuf.md
index 5f521f1485f..03604e3672c 100644
--- a/doc/developer-guide/data-structures/iobuf.md
+++ b/doc/developer-guide/datastructure-iobuf.md
@@ -1,6 +1,6 @@
-#Iobuf-pool
-##Datastructures
-###iobuf
+# Iobuf-pool
+## Datastructures
+### iobuf
Short for IO Buffer. It is one allocatable unit for the consumers of the IOBUF
API, each unit hosts @page_size(defined in arena structure) bytes of memory. As
initial step of processing a fop, the IO buffer passed onto GlusterFS by the
@@ -28,7 +28,7 @@ struct iobuf {
};
```
-###iobref
+### iobref
There may be need of multiple iobufs for a single fop, like in vectored read/write.
Hence multiple iobufs(default 16) are encapsulated under one iobref.
```
@@ -40,7 +40,7 @@ struct iobref {
int used; /* number of iobufs added to this iobref */
};
```
-###iobuf_arenas
+### iobuf_arenas
One region of memory MMAPed from the operating system. Each region MMAPs
@arena_size bytes of memory, and hosts @arena_size / @page_size IOBUFs.
The same sized iobufs are grouped into one arena, for sanity of access.
@@ -77,7 +77,7 @@ struct iobuf_arena {
};
```
-###iobuf_pool
+### iobuf_pool
Pool of Iobufs. As there may be many Io buffers required by the filesystem,
a pool of iobufs are preallocated and kept, if these preallocated ones are
exhausted only then the standard malloc/free is called, thus improving the
@@ -139,8 +139,8 @@ arenas in the purge list are destroyed only if there is atleast one arena in
(e.g: If there is an arena (page_size=128KB, count=32) in purge list, this arena
is destroyed(munmap) only if there is an arena in 'arenas' list with page_size=128KB).
-##APIs
-###iobuf_get
+## APIs
+### iobuf_get
```
struct iobuf *iobuf_get (struct iobuf_pool *iobuf_pool);
@@ -149,7 +149,7 @@ Creates a new iobuf of the default page size(128KB hard coded as of yet).
Also takes a reference(increments ref count), hence no need of doing it
explicitly after getting iobuf.
-###iobuf_get2
+### iobuf_get2
```
struct iobuf * iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size);
@@ -179,7 +179,7 @@ if (requested iobuf size > Max iobuf size in the pool(1MB as of yet))
Also takes a reference(increments ref count), hence no need of doing it
explicitly after getting iobuf.
-###iobuf_ref
+### iobuf_ref
```
struct iobuf *iobuf_ref (struct iobuf *iobuf);
@@ -188,7 +188,7 @@ struct iobuf *iobuf_ref (struct iobuf *iobuf);
xlator/function/, its a good practice to take a reference so that iobuf is not
deleted by the allocator.
-###iobuf_unref
+### iobuf_unref
```
void iobuf_unref (struct iobuf *iobuf);
```
@@ -203,33 +203,33 @@ Unreference the iobuf, if the ref count is zero iobuf is considered free.
Every iobuf_ref should have a corresponding iobuf_unref, and also every
iobuf_get/2 should have a correspondning iobuf_unref.
-###iobref_new
+### iobref_new
```
struct iobref *iobref_new ();
```
Creates a new iobref structure and returns its pointer.
-###iobref_ref
+### iobref_ref
```
struct iobref *iobref_ref (struct iobref *iobref);
```
Take a reference on the iobref.
-###iobref_unref
+### iobref_unref
```
void iobref_unref (struct iobref *iobref);
```
Decrements the reference count of the iobref. If the ref count is 0, then unref
all the iobufs(iobuf_unref) in the iobref, and destroy the iobref.
-###iobref_add
+### iobref_add
```
int iobref_add (struct iobref *iobref, struct iobuf *iobuf);
```
Adds the given iobuf into the iobref, it takes a ref on the iobuf before adding
it, hence explicit iobuf_ref is not required if adding to the iobref.
-###iobref_merge
+### iobref_merge
```
int iobref_merge (struct iobref *to, struct iobref *from);
```
@@ -239,13 +239,13 @@ on all the iobufs added to the 'to' iobref. Hence iobref_unref should be
performed both on 'from' and 'to' iobrefs (performing iobref_unref only on 'to'
will not free the iobufs and may result in leak).
-###iobref_clear
+### iobref_clear
```
void iobref_clear (struct iobref *iobref);
```
Unreference all the iobufs in the iobref, and also unref the iobref.
-##Iobuf Leaks
+## Iobuf Leaks
If all iobuf_refs/iobuf_new do not have correspondning iobuf_unref, then the
iobufs are not freed and recurring execution of such code path may lead to huge
memory leaks. The easiest way to identify if a memory leak is caused by iobufs
diff --git a/doc/developer-guide/data-structures/mem-pool.md b/doc/developer-guide/datastructure-mem-pool.md
index c71aa2a8ddd..225567cbf9f 100644
--- a/doc/developer-guide/data-structures/mem-pool.md
+++ b/doc/developer-guide/datastructure-mem-pool.md
@@ -1,5 +1,5 @@
-#Mem-pool
-##Background
+# Mem-pool
+## Background
There was a time when every fop in glusterfs used to incur cost of allocations/de-allocations for every stack wind/unwind between xlators because stack/frame/*_localt_t in every wind/unwind was allocated and de-allocated. Because of all these system calls in the fop path there was lot of latency and the worst part is that most of the times the number of frames/stacks active at any time wouldn't cross a threshold. So it was decided that this threshold number of frames/stacks would be allocated in the beginning of the process only once. Get one of them from the pool of stacks/frames whenever `STACK_WIND` is performed and put it back into the pool in `STACK_UNWIND`/`STACK_DESTROY` without incurring any extra system calls. The data structures are allocated only when threshold number of such items are in active use i.e. pool is in complete use.% increase in the performance once this was added to all the common data structures (inode/fd/dict etc) in xlators throughout the stack was tremendous.
## Data structure
@@ -27,7 +27,7 @@ will be served from here until all the elements in the pool are in use i.e. cold
};
```
-##Life-cycle
+## Life-cycle
```
mem_pool_new (data_type, unsigned long count)
@@ -120,5 +120,5 @@ mem_pool_destroy (struct mem_pool *pool)
Deletes this pool from the `global_list` maintained by `glusterfs-ctx` and frees all the memory allocated in `mem_pool_new`.
-###How to pick pool-size
+### How to pick pool-size
This varies from work-load to work-load. Create the mem-pool with some random size and run the work-load. Take the statedump after the work-load is complete. In the statedump if `max_alloc` is always less than `cold_count` may be reduce the size of the pool closer to `max_alloc`. On the otherhand if there are lots of `pool-misses` then increase the `pool_size` by `max_stdalloc` to achieve better 'hit-rate' of the pool.
diff --git a/doc/developer-guide/dirops-transactions-in-dht.md b/doc/developer-guide/dirops-transactions-in-dht.md
new file mode 100644
index 00000000000..909a97001aa
--- /dev/null
+++ b/doc/developer-guide/dirops-transactions-in-dht.md
@@ -0,0 +1,273 @@
+# dirops transactions in dht
+Need for transactions during operations on directories arise from two
+basic design elements of DHT:
+
+ 1. A directory is created on all subvolumes of dht. Since glusterfs
+ associates each file-system object with an unique gfid, every
+ subvolume should have the same unique mapping of (path of directory,
+ gfid). To elaborate,
+ * Each subvolume should've same gfid associated with a path to
+ directory.
+ * A gfid should not be associated with more than one path in any
+ subvolume.
+
+ So, entire operations like mkdir, renamedir, rmdir and creation of
+ directories during self-heal need to be atomic in dht. In other words,
+ any of these operations shouldn't begin on an inode if one of them is
+ already in progress on the same inode, till it completes on all
+ subvolumes of dht. If not, more than one of these operations
+ happening in parallel can break any or all of the two requirements
+ listed above. This is referred in the rest of the document by the
+ name _Atomicity during namespace operations_.
+
+ 2. Each directory has an independent layout persisted on
+ subvolumes. Each subvolume contains only part of the layout relevant
+ to it. For performance reasons _and_ since _only_ dht has aggregated
+ view, this layout is cached in memory of client. To make sure dht
+ reads or modifies a single complete layout while parallel modifications of the layout are in progress, we need atomicity during layout modification and reading. This is referred in the rest of the document as _Atomicity during layout modification and reading_.
+
+Rest of the document explains how atomicity is achieved for each of
+the case above.
+
+**Atomicity during layout modification and reading**
+File operations a.k.a fops can be classified into two categories based on how they consume layout.
+
+ - Layout writer. Setting of layout during selfheal of a directory is
+ layout writer of _that_ directory.
+ - Layout reader.
+ * Any entry fop like create, unlink, rename, link, symlink,
+ unlink, mknod, rename, mkdir, rmdir, renamedir which needs layout of the parent directory. Each of these fops are readers of layout on parent directory.
+ * setting of layout during mkdir of a directory is considered as
+ a reader of the same directory's layout. The reason for this is that
+ only a parallel lookup on that directory can be a competing fop that modifies the layout (Other fops need gfid of the directory which can be got only after either lookup or mkdir completes). However, healing of layout is considered as a writer and a single writer blocks all readers.
+
+*Algorithm*
+Atomicity is achieved by locking on the inode of directory whose
+layout is being modified or read. The fop used is inodelk.
+ - Writer acquires blocking inodelk (directory-inode, write-lock) on
+ all subvolumes serially. The order of subvols in which they are
+ locked by different clients remains constant for a directory. If locking fails on any subvolume, layout modification is abandoned.
+ - Reader acquires an inodelk (directory-inode, read-lock) on _any_
+ one subvolume. If locking fails on a subvolume (say with
+ ESTALE/ENOTCONN error), locking can be tried on other subvolumes till
+ we get one lock. If we cannot get lock on at least one subvolume,
+ consistency of layout is not guaranteed. Based on the consistency
+ requirements of fops, they can be failed or continued.
+
+Reasons why writer has to lock on _all_ subvols:
+
+ - DHT don't have a metadata server and locking is implemented by brick. So, there is no well-defined subvol/brick that can be used as an arbitrator by different clients while acquiring locks.
+ - readers should acquire as minimum number of locks as possible. In
+ other words, the algorithm aims to have less synchronization cost to
+ readers.
+ - The subvolume to which a directory hashes could be used as a
+ lock server. However, in the case of an entry fop like create
+ (/a/b/c) where we want to block modification of layout of b for the
+ duration of create, we would be required to acquire lock on the
+ subvol to which /a/b hashes. To find out the hashed-subvol of
+ /a/b, we would need layout of /a. Note that how there is a dependency
+ of locking the layouts of ancestors all the way to root. So this
+ locking is not preferred. Also, note that only the immediate parent
+ inode is available in arguments of a fop like create.
+
+**Atomicity during namespace operations**
+
+ - We use locks on inode of parent directory in the namespace of
+ _"basename"_ during mkdir, rmdir, renamedir and directory
+ creation phase of self-heal. The exact fop we use is _entrylk
+ (parent-inode, "basename")_.
+ - refresh in-memory layout of parent-inode from values stored on backend
+ - _entrylk (parent-inode, "basename")_ is done on subvolume to which
+ _"basename" hashes_. So, this operation is a _reader_ of the
+ layout on _parent-inode_. Which means an _inodelk (parent-inode,
+ read-lock)_ has to be completed before _entrylk (parent-inode,
+ "basename")_ is issued. Both the locks have to be held till the
+ operation is tried on all subvolumes. If acquiring of any/all of
+ these locks fail, the operation should be failed.
+
+With the above details, algorithms for mkdir, rmdir, renamedir,
+self-heal of directory are explicitly detailed below.
+
+**Self-heal of a directory**
+
+ - creation of directories on subvolumes is done only during
+ _named-lookup_ of a directory as we need < parent-inode,
+ "basename" >.
+ - If a directory is missing on one or more subvolumes,
+ * acquire _inodelk (parent-inode, read-lock)_ on _any one_ of the
+ subvolumes.
+ * refresh the in-memory layout of parent-inode from values stored on backend
+ * acquire _entrylk (parent-inode, "basename")_ on the subvolume
+ to which _"basename"_ hashes.
+ * If any/all of the locks fail, self-heal is aborted.
+ * create directories on missing subvolumes.
+ * release _entrylk (parent-inode, "basename")_.
+ * release _inodelk (parent-inode, read-lock)_.
+
+ - If layout of a directory needs healing
+ * acquire _inodelk (directory-inode, write-lock)_ on _all_ the
+ subvolumes. If locking fails on any of the subvolumes,
+ self-heal is aborted. Blocking Locks are acquired serially across subvolumes in a _well-defined_ order which is _constant_ across all the healers of a directory. One order could be the order in which subvolumes are stored in the array _children_ of dht xlator.
+ * heal the layout.
+ * release _inodelk (directory-inode, write-lock)_ on _all_ the
+ subvolumes in parallel.
+ * Note that healing of layout can be done in both _named_ and
+ _nameless_ lookups of a directory as _only directory-inode_ is needed
+ for healing and it is available during both.
+
+**mkdir (parent-inode, "basename")**
+
+* while creating directory across subvolumes,
+
+ - acquire _inodelk (parent-inode, read-lock)_ on _any one_ of the
+ subvolumes.
+ - refresh in-memory layout of parent-inode from values stored on backend
+ - acquire _entrylk (parent-inode, "basename")_ on the subvolume to
+ which _"basename"_ hashes.
+ - If any/all of the above two locks fail, release the locks that
+ were acquired successfully and mkdir should be failed (as perceived by application).
+ - do _mkdir (parent-inode, "basename")_ on the subvolume to which
+ _"basename"_ hashes. If this mkdir fails, mkdir is failed.
+ - do _mkdir (parent-inode, "basename")_ on the remaining subvolumes.
+ - release _entrylk (parent-inode, "basename")_.
+ - release _inodelk (parent-inode, "read-lock")_.
+* while setting the layout of a directory,
+ - acquire _inodelk (directory-inode, read-lock)_ on _any one_ of the
+ subvolumes.
+ - If locking fails, cleanup the locks that were acquired
+ successfully and abort layout setting. Note that we'll have a
+ directory without a layout till a lookup happens on the
+ directory. This means entry operations within this directory fail
+ in this time window. We can also consider failing mkdir. The
+ problem of dealing with a directory without layout is out of the
+ scope of this document.
+ - set the layout on _directory-inode_.
+ - release _inodelk (directory-inode, read-lock)_.
+* Note that during layout setting we consider mkdir as a _reader_ not
+ _writer_, though it is setting the layout. Reasons are:
+ - Before any of other readers like create, link etc that operate on
+ this directory to happen, _gfid_ of this directory has to be
+ resolved. But _gfid_ is only available only if either of following
+ conditions are true:
+ * after mkdir is complete.
+ * a lookup on the same path happens parallel to in-progress
+ mkdir.
+
+ But, on completion of any of the above two operations, layout
+ will be healed. So, none of the _readers_ will happen on a
+ directory with partial layout.
+
+* Note that since we've an _entrylk (parent-inode, "basename")_ for
+ the entire duration of (attempting) creating directories, parallel
+ mkdirs will no longer contend on _mkdir_ on subvolume _to which "basename" hashes_. But instead, contend on _entrylk (parent-inode, "basename")_ on the subvolume _to which "basename" hashes_. So, we can attempt the _mkdir_ in _parallel_ on all subvolumes instead of two stage mkdir on hashed first and the rest of them in parallel later. However, we need to make sure that mkdir is successful on the subvolume _to which "basename" hashes_ for mkdir to be successful (as perceived by application). In the case of failed mkdir (as perceived by application), a cleanup should be performed on all the subvolumes before _entrylk (parent-inode, "basename")_ is released.
+
+**rmdir (parent-inode, "basename", directory-inode)**
+
+ - acquire _inodelk (parent-inode, read-lock)_ on _any one_
+ subvolume.
+ - refresh in-memory layout of parent-inode from values stored on backend
+ - acquire _entrylk (parent-inode, "basename")_ on the subvolume to
+ which _"basename" hashes_.
+ - If any/all of the above locks fail, rmdir is failed after cleanup
+ of the locks that were acquired successfully.
+ - do _rmdir (parent-inode, "basename")_ on the subvolumes to which
+ _"basename" doesn't hash to_.
+ * If successful, continue.
+ * Else,
+ * recreate directories on those subvolumes where rmdir
+ succeeded.
+ * heal the layout of _directory-inode_. Note that this will have
+ same synchronization requirements as discussed during layout
+ healing part of the section "Directoy self-heal" above.
+ * release _entrylk (parent-inode, "basename")_.
+ * release _inodelk (parent-inode, read-lock)_.
+ * fail _rmdir (parent-inode, "basename")_ to application.
+ - do _rmdir (parent-inode, "basename")_ on the subvolume to which
+ _"basename" hashes_.
+ - If successful, continue.
+ - Else, Go to the failure part of _rmdir (parent-inode, "basename")_
+ on subvolumes to which "basename" _doesn't hash to_.
+ - release _entrylk (parent-inode, "basename")_.
+ - release _inodelk (parent-inode, read-lock)_.
+ - return success to application.
+
+**renamedir (src-parent-inode, "src-basename", src-directory-inode, dst-parent-inode, "dst-basename", dst-directory-inode)**
+
+ - requirement is to prevent any operation in both _src-namespace_
+ and _dst-namespace_. So, we need to acquire locks on both
+ namespaces.We also need to have constant ordering while acquiring
+ locks during parallel renames of the form _rename (src, dst)_ and
+ _rename (dst, src)_ to prevent deadlocks. We can sort gfids of
+ _src-parent-inode_ and _dst-parent-inode_ and use that order to
+ acquire locks. For the sake of explanation lets say we ended up
+ with order of _src_ followed by _dst_.
+ - acquire _inodelk (src-parent-inode, read-lock)_.
+ - refresh in-memory layout of src-parent-inode from values stored on backend
+ - acquire _entrylk (src-parent-inode, "src-basename")_.
+ - acquire _inodelk (dst-parent-inode, read-lock)_.
+ - refresh in-memory layout of dst-parent-inode from values stored on backend
+ - acquire _entrylk (dst-parent-inode, "dst-basename")_.
+ - If acquiring any/all of the locks above fail,
+ * release the locks that were successfully acquired.
+ * fail the renamedir operation to application
+ * done
+ - do _renamedir ("src", "dst")_ on the subvolume _to which "dst-basename" hashes_.
+ * If failure, Goto point _If acquiring any/all of the locks above fail_.
+ * else, continue.
+ - do _renamedir ("src", "dst")_ on rest of the subvolumes.
+ * If there is any failure,
+ * revert the successful renames.
+ * Goto to point _If acquiring any/all of the locks above fail_.
+ * else,
+ - release all the locks acquired.
+ - return renamedir as success to application.
+
+**Some examples of races**
+This section gives concrete examples of races that can result in inconsistencies explained in the beginning of the document.
+
+Some assumptions are:
+
+* We consider an example distribute of three subvols s1, s2 and s3.
+* For examples of renamedir ("src", "dst"), _src_ hashes to s1 and _dst_ hashes to s2. _src_ and _dst_ are associated with _gfid-src_ and _gfid-dst_ respectively
+* For non renamedir examples, _dir_ is the name of directory and it hashes to s1.
+
+And the examples are:
+
+ - mkdir vs rmdir - inconsistency in namespace.
+ * mkdir ("dir", gfid1) is complete on s1
+ * rmdir is issued on same directory. Note that, since rmdir needs a gfid, a lookup should be complete before rmdir. lookup creates the directory on rest of the subvols as part of self-heal.
+ * rmdir (gfid1) deletes directory from all subvols.
+ * A new mkdir ("dir", gfid2) is issued. It is successful on s1 associating "dir" with gfid2.
+ * mkdir ("dir", gfid1) resumes and creates directory on s2 and s3 associating "dir" with gfid1.
+ * mkdir ("dir", gfid2) fails with EEXIST on s2 and s3. Since, EEXIST errors are ignored, mkdir is considered successful to application.
+ * In this example we have multiple inconsitencies
+ * "dir" is associated with gfid1 on s2, s3 and with gfid2 on s1
+ * Even if mkdir ("dir", gfid2) was not issued, we would've a case of a directory magically reappearing after a successful rmdir.
+ - lookup heal vs rmdir
+ * rmdir ("dir", gfid1) is issued. It is successful on s2 and s3 (non-hashed subvols for name "dir")
+ * lookup ("dir") is issued. Since directory is present on s1 yet, it is created on s2 and s3 associating with gfid1 as part of self-heal
+ * rmdir ("dir", gfid1) is complete on s1 and it is successful
+ * Another lookup ("dir") creates the directory on s1 too
+ * "dir" magically reappears after a successful rmdir
+ - lookup heal (src) vs renamedir ("src", "dst")
+ * renamedir ("src", "dst") complete on s2
+ * lookup ("src") recreates _src_ with _gfid-src_ on s2
+ * renamedir ("src", "dst") completes on s1, s3. After rename is complete path _dst_ will be associated with gfid _gfid-src_
+ * Another lookup ("src") recreates _src_ on subvols s1 and s3, associating it with gfid _gfid-src_
+ * Inconsistencies are
+ * after a successful renamedir ("src", "dst"), both src and dst exist
+ * Two directories - src and dst - are associated with same gfid. One common symptom is that some entries (of the earlier _src_ and current _dst_ directory) being missed out in readdir listing as the gfid handle might be pointing to the empty healed directory than the actual directory containing entries
+ - lookup heal (dst) vs renamedir ("src", "dst")
+ * dst exists and empty when renamdir started
+ * dst doesn't exist when renamedir started
+ - renamedir ("src", "dst") complete on s2 and s3
+ - lookup ("dst") creates _dst_ associating it with _gfid-src_ on s1
+ - An entry is created in _dst_ on either s1
+ - renamedir ("src", "dst") on s1 will result in a directory _dst/dst_ as _dst_ is no longer empty and _man 2 rename_ states that if _dst_ is not empty, _src_ is renamed _as a subdirectory of dst_
+ - A lookup ( _dst/dst_) creates _dst/dst_ on s2 and s3 associating with _gfid-src_ as part of self-heal
+ - Inconsistencies are:
+ * Two directories - _dst_ and _dst/dst_ - exist even though both of them didn't exist at the beginning of renamedir
+ * Both _dst_ and _dst/dst_ have same gfid - _gfid-src_. As observed earlier, symptom might be directory listing being incomplete
+ - mkdir (dst) vs renamedir ("src", "dst")
+ - rmdir (src) vs renamedir ("src", "dst")
+ - rmdir (dst) vs renamedir ("src", "dst")
diff --git a/doc/developer-guide/ec-implementation.md b/doc/developer-guide/ec-implementation.md
new file mode 100644
index 00000000000..77e62583caa
--- /dev/null
+++ b/doc/developer-guide/ec-implementation.md
@@ -0,0 +1,588 @@
+Erasure coding implementation
+=============================
+
+This document provides information about how [erasure code][1] has
+been implemented into ec translator. It describes the algorithm used
+and the optimizations made, but it doesn't contain a full description
+of the mathematical background needed to understand erasure coding in
+general. It either describes the other parts of ec not directly
+related to the encoding/decoding procedure, like synchronization or
+fop management.
+
+
+Introduction
+------------
+
+EC is based on [Reed-Solomon][2] erasure code. It's a very old code.
+It's not considered the best one nowadays, but is good enough and it's
+one of the few codes that is not covered by any patent and can be
+freely used.
+
+To define the Reed-Solomon code we use 3 parameters:
+
+ * __Key fragments (K)__
+ It represents the minimum number of healthy fragments that will be
+ needed to be able to recover the original data. Any subset of K
+ out of the total number of fragments will serve.
+
+ * __Redundancy fragments (R)__
+ It represents the number of extra fragments to compute for each
+ original data block. This value determines how many fragments can
+ be lost before being unable to recover the original data.
+
+ * __Fragment size (S)__
+ This determines the size of each fragment. The original data
+ block size is computed as S * K. Currently this values is fixed
+ to 512 bytes.
+
+ * __Total number of fragments (N = K + R)__
+ This isn't a real parameter but it will be useful to simplify
+ the following descriptions.
+
+From the point of view of the implementation, it only consists on
+matrix multiplications. There are two kinds of matrices to use for
+Reed-Solomon:
+
+ * __[Systematic][3]__
+ This kind of matrix has the particularity that K of the encoded
+ fragments are simply a copy of the original data, divided into K
+ pieces. Thus no real encoding needs to be done for them and only
+ the R redundancy fragments need to be computed.
+
+ This kind of matrices contain one KxK submatrix that is the
+ [identity matrix][4].
+
+ * __Non-systematic__
+ This kind of matrix doesn't contain an identity submatrix. This
+ means that all of the N fragments need to be encoded, requiring
+ more computation. On the other hand, these matrices have some nice
+ properties that allow faster implementations of some algorithms,
+ like the matrix inversion used to decode the data.
+
+ Another advantage of non-systematic matrices is that the decoding
+ time is constant, independently of how many fragments are lost,
+ while systematic approach can suffer from performance degradation
+ when one fragment is lost.
+
+All non-systematic matrices can be converted to systematic ones, but
+then we lose the good properties of the non-systematic. We have to
+choose betwee best peek performance (systematic) and performance
+stability (non-systematic).
+
+
+Encoding procedure
+------------------
+
+To encode a block of data we need a KxN matrix where each subset of K
+rows is [linearly independent][5]. In other words, the determinant of
+each KxK submatrix is not 0.
+
+There are some known ways to obtain this kind of matrices. EC uses a
+small variation of a matrix known as [Vandermonde Matrix][6] where
+each element of the matrix is defined as:
+
+ a(i, j) = i ^ (K - j)
+
+ where i is the row from 1 to N, and j is the column from 1 to K.
+
+This is exactly the Vandermonde Matrix but with the elements of each
+row in reverse order. This change is made to be able to implement a
+small optimization in the matrix multiplication.
+
+Once we have the matrix, we only need to compute the multiplication
+of this matrix by a vector composed of K elements of data coming from
+the original data block.
+
+ / \ / \
+ | 1 1 1 1 1 | / \ | a + b + c + d + e = t |
+ | 16 8 4 2 1 | | a | | 16a + 8b + 4c + 2d + e = u |
+ | 81 27 9 3 1 | | b | = | 81a + 27b + 9c + 3d + e = v |
+ | 256 64 16 4 1 | * | c | | 256a + 64b + 16c + 4d + e = w |
+ | 625 125 25 5 1 | | d | | 625a + 125b + 25c + 5d + e = x |
+ | 1296 216 36 6 1 | | e | | 1296a + 216b + 36c + 6d + e = y |
+ | 2401 343 49 7 1 | \ / | 2401a + 343b + 49c + 7d + e = z |
+ \ / \ /
+
+The optimization that can be done here is this:
+
+ 16a + 8b + 4c + 2d + e = 2(2(2(2a + b) + c) + d) + e
+
+So all the multiplications are always by the number of the row (2 in
+this case) and we don't need temporal storage for intermediate
+results:
+
+ a *= 2
+ a += b
+ a *= 2
+ a += c
+ a *= 2
+ a += d
+ a *= 2
+ a += e
+
+Once we have the result vector, each element is a fragment that needs
+to be stored in a separate place.
+
+
+Decoding procedure
+------------------
+
+To recover the data we need exactly K of the fragments. We need to
+know which K fragments we have (i.e. the original row number from
+which each fragment was calculated). Once we have this data we build
+a square KxK matrix composed by the rows corresponding to the given
+fragments and invert it.
+
+With the inverted matrix, we can recover the original data by
+multiplying it with the vector composed by the K fragments.
+
+In our previous example, if we consider that we have recovered
+fragments t, u, v, x and z, corresponding to rows 1, 2, 3, 5 and 7,
+we can build the following matrix:
+
+ / \
+ | 1 1 1 1 1 |
+ | 16 8 4 2 1 |
+ | 81 27 9 3 1 |
+ | 625 125 25 5 1 |
+ | 2401 343 49 7 1 |
+ \ /
+
+And invert it:
+
+ / \
+ | 1/48 -1/15 1/16 -1/48 1/240 |
+ | -17/48 16/15 -15/16 13/48 -11/240 |
+ | 101/48 -86/15 73/16 -53/48 41/240 |
+ | -247/48 176/15 -129/16 83/48 -61/240 |
+ | 35/8 -7 35/8 -7/8 1/8 |
+ \ /
+
+Multiplying it by the vector (t, u, v, x, z) we recover the original
+data (a, b, c, d, e):
+
+ / \ / \ / \
+ | 1/48 -1/15 1/16 -1/48 1/240 | | t | | a |
+ | -17/48 16/15 -15/16 13/48 -11/240 | | u | | b |
+ | 101/48 -86/15 73/16 -53/48 41/240 | * | v | = | c |
+ | -247/48 176/15 -129/16 83/48 -61/240 | | x | | d |
+ | 35/8 -7 35/8 -7/8 1/8 | | z | | e |
+ \ / \ / \ /
+
+
+Galois Field
+------------
+
+This encoding/decoding procedure is quite complex to compute using
+regular mathematical operations and it's not well suited for what
+we want to do (note that matrix elements can grow unboundly).
+
+To solve this problem, exactly the same procedure is done inside a
+[Galois Field][7] of characteristic 2, which is a finite field with
+some interesting properties that make it specially useful for fast
+operations using computers.
+
+There are two main differences when we use this specific Galois Field:
+
+ * __All regular additions are replaced by bitwise xor's__
+ For todays computers it's not really faster to execute an xor
+ compared to an addition, however replacing additions by xor's
+ inside a multiplication has many advantages (we will make use of
+ this to optimize the multiplication).
+
+ Another consequence of this change is that additions and
+ substractions are really the same xor operation.
+
+ * __The elements of the matrix are bounded__
+ The field uses a modulus that keep all possible elements inside
+ a delimited region, avoiding really big numbers and fixing the
+ number of bits needed to represent each value.
+
+ In the current implementation EC uses 8 bits per field element.
+
+It's very important to understand how multiplications are computed
+inside a Galois Field to be able to understand how has it been
+optimized.
+
+We'll start with a simple 'old school' multiplication but in base 2.
+For example, if we want to multiply 7 * 5 (111b * 101b in binary), we
+do the following:
+
+ 1 1 1 (= 7)
+ * 1 0 1 (= 5)
+ -----------
+ 1 1 1 (= 7)
+ + 0 0 0 (= 0)
+ + 1 1 1 (= 7)
+ -----------
+ 1 0 0 0 1 1 (= 35)
+
+This is quite simple. Note that the addition of the third column
+generates a carry that is propagated to all the other left columns.
+
+The next step is to define the modulus of the field. Suppose we use
+11 as the modulus. Then we convert the result into an element of the
+field by dividing by the modulus and taking the residue. We also use
+the 'old school' method in binary:
+
+
+ 1 0 0 0 1 1 (= 35) | 1 0 1 1 (= 11)
+ - 0 0 0 0 ----------------
+ --------- 0 1 1 (= 3)
+ 1 0 0 0 1
+ - 1 0 1 1
+ -----------
+ 0 0 1 1 0 1
+ - 1 0 1 1
+ -------------
+ 0 0 1 0 (= 2)
+
+So, 7 * 5 in a field with modulus 11 is 2. Note that the main
+objective in each iteration of the division is to make higher bits
+equal to 0 when possible (if it's not possible in one iteration, it
+will be zeroed on the next).
+
+If we do the same but changing additions with xors we get this:
+
+ 1 1 1 (= 7)
+ * 1 0 1 (= 5)
+ -----------
+ 1 1 1 (= 7)
+ x 0 0 0 (= 0)
+ x 1 1 1 (= 7)
+ -----------
+ 1 1 0 1 1 (= 27)
+
+In this case, the xor of the third column doesn't generate any carry.
+
+Now we need to divide by the modulus. We can also use 11 as the
+modulus since it still satisfies the needed conditions to work on a
+Galois Field of characteristic 2 with 3 bits:
+
+ 1 1 0 1 1 (= 27) | 1 0 1 1 (= 11)
+ x 1 0 1 1 ----------------
+ --------- 1 1 1 (= 7)
+ 0 1 1 0 1
+ x 1 0 1 1
+ -----------
+ 0 1 1 0 1
+ x 1 0 1 1
+ -------------
+ 0 1 1 0 (= 6)
+
+Note that, in this case, to make zero the higher bit we need to
+consider the result of the xor operation, not the addition operation.
+
+So, 7 * 5 in a Galois Field of 3 bits with modulus 11 is 6.
+
+
+Optimization
+------------
+
+To compute all these operations in a fast way some methods have been
+traditionally used. Maybe the most common is the [lookup table][8].
+
+The problem with this method is that it requires 3 lookups for each
+byte multiplication, greatly amplifying the needed memory bandwidth
+and making it difficult to take advantage of any SIMD support on the
+processor.
+
+What EC does to improve the performance is based on the following
+property (using the 3 bits Galois Field of the last example):
+
+ A * B mod N = (A * b{2} * 4 mod N) x
+ (A * b{1} * 2 mod N) x
+ (A * b{0} mod N)
+
+This is basically a rewrite of the steps made in the previous example
+to multiply two numbers but moving the modulus calculation inside each
+intermediate result. What we can see here is that each term of the
+xor can be zeroed if the corresponding bit of B is 0, so we can ignore
+that factor. If the bit is 1, we need to compute A multiplied by a
+power of two and take the residue of the division by the modulus. We
+can precompute these values:
+
+ A0 = A (we don't need to compute the modulus here)
+ A1 = A0 * 2 mod N
+ A2 = A1 * 2 mod N
+
+Having these values we only need to add those corresponding to bits
+set to 1 in B. Using our previous example:
+
+ A = 1 1 1 (= 7)
+ B = 1 0 1 (= 5)
+
+ A0 = 1 1 1 (= 7)
+ A1 = 1 1 1 * 1 0 mod 1 0 1 1 = 1 0 1 (= 5)
+ A2 = 1 0 1 * 1 0 mod 1 0 1 1 = 0 0 1 (= 1)
+
+ Since only bits 0 and 2 are 1 in B, we add A0 and A2:
+
+ A0 + A2 = 1 1 1 x 0 0 1 = 1 1 0 (= 6)
+
+If we carefully look at what we are doing when computing each Ax, we
+see that we do two basic things:
+
+ - Shift the original value one bit to the left
+ - If the highest bit is 1, xor with the modulus
+
+Let's write this in a detailed way (representing each bit):
+
+ Original value: a{2} a{1} a{0}
+ Shift 1 bit: a{2} a{1} a{0} 0
+
+ If a{2} is 0 we already have the result:
+ a{1} a{0} 0
+
+ If a{2} is 1 we need to xor with the modulus:
+ 1 a{1} a{0} 0 x 1 0 1 1 = a{1} (a{0} x 1) 1
+
+An important thing to see here is that if a{2} is 0, we can get the
+same result by xoring with all 0 instead of the modulus. For this
+reason we can rewrite the modulus as this:
+
+ Modulus: a{2} 0 a{2} a{2}
+
+This means that the modulus will be 0 0 0 0 is a{2} is 0, so the value
+won't change, and it will be 1 0 1 1 if a{2} is 1, giving the correct
+result. So, the computation is simply:
+
+ Original value: a{2} a{1} a{0}
+ Shift 1 bit: a{2} a{1} a{0} 0
+ Apply modulus: a{1} (a{0} x a{2}) a{2}
+
+We can compute all Ax using this method. We'll get this:
+
+ A0 = a{2} a{1} a{0}
+ A1 = a{1} (a{0} x a{2}) a{2}
+ A2 = (a{0} x a{2}) (a{1} x a{2}) a{1}
+
+Once we have all terms, we xor the ones corresponding to the bits set
+to 1 in B. In out example this will be A0 and A2:
+
+ Result: (a{2} x a{0} x a{2}) (a{1} x a{1} x a{2}) (a{0} x a{1})
+
+We can easily see that we can remove some redundant factors:
+
+ Result: a{0} a{2} (a{0} x a{1})
+
+This way we have come up with a simply set of equations to compute the
+multiplication of any number by 5. If A is 1 1 1 (= 7), the result
+must be 1 1 0 (= 6) using the equations, as we expected. If we try
+another numbe for A, like 0 1 0 (= 2), the result must be 0 0 1 (= 1).
+
+This seems a really fast way to compute the multiplication without
+using any table lookup. The problem is that this is only valid for
+B = 5. For other values of B another set of equations will be found.
+To solve this problem we can pregenerate the equations for all
+possible values of B. Since the Galois Field we use is small, this is
+feasible.
+
+One thing to be aware of is that, in general, two equations for
+different bits of the same B can share common subexpressions. This
+gives space for further optimizations to reduce the total number of
+xors used in the final equations for a given B. However this is not
+easy to find, since finding the smallest number of xors that give the
+correct result is an NP-Problem. For EC an exhaustive search has been
+made to find the best combinations for each possible value.
+
+
+Implementation
+--------------
+
+All this seems great from the hardware point of view, but implementing
+this using normal processor instructions is not so easy because we
+would need a lot of shifts, ands, xors and ors to move the bits of
+each number to the correct position to compute the equation and then
+another shift to put each bit back to its final place.
+
+For example, to implement the functions to multiply by 5, we would
+need something like this:
+
+ Bit 2: T2 = (A & 1) << 2
+ Bit 1: T1 = (A & 4) >> 1
+ Bit 0: T0 = ((A >> 1) x A) & 1
+ Result: T2 + T1 + T0
+
+This doesn't look good. So here we make a change in the way we get
+and process the data: instead of reading full numbers into variables
+and operate with them afterwards, we use a single independent variable
+for each bit of the number.
+
+Assume that we can read and write independent bits from memory (later
+we'll see how to solve this problem when this is not possible). In
+this case, the code would look something like this:
+
+ Bit 2: T2 = Mem[2]
+ Bit 1: T1 = Mem[1]
+ Bit 0: T0 = Mem[0]
+ Computation: T1 ^= T0
+ Store result: Mem[2] = T0
+ Mem[1] = T2
+ Mem[0] = T1
+
+Note that in this case we handle the final reordering of bits simply
+by storing the right variable to the right place, without any shifts,
+ands nor ors. In fact we only have memory loads, memory stores and
+xors. Note also that we can do all the computations directly using the
+variables themselves, without additional storage. This true for most
+of the values, but in some cases an additional one or two temporal
+variables will be needed to store intermediate results.
+
+The drawback of this approach is that additions, that are simply a
+xor of two numbers will need as many xors as bits are in each number.
+
+
+SIMD optimization
+-----------------
+
+So we have a good way to compute the multiplications, but even using
+this we'll need several operations for each byte of the original data.
+We can improve this by doing multiple multiplications using the same
+set of instructions.
+
+With the approach taken in the implementation section, we can see that
+in fact it's really easy to add SIMD support to this method. We only
+need to store in each variable one bit from multiple numbers. For
+example, when we load T2 from memory, instead of reading the bit 2 of
+the first number, we can read the bit 2 of the first, second, third,
+fourth, ... numbers. The same can be done when loading T1 and T0.
+
+Obviously this needs to have a special encoding of the numbers into
+memory to be able to do that in a single operation, but since we can
+choose whatever encoding we want for EC, we have chosen to have
+exactly that. We interpret the original data as a stream of bits, and
+we split it into subsequences of length L, each containing one bit of
+a number. Every S subsequences form a set of numbers of S bits that
+are encoded and decoded as a single group. This repeats for any
+remaining data.
+
+For example, in a simple case with L = 8 and S = 3, the original data
+would contain something like this (interpreted as a sequence of bits,
+offsets are also bit-based):
+
+ Offset 0: a{0} b{0} c{0} d{0} e{0} f{0} g{0} h{0}
+ Offset 8: a{1} b{1} c{1} d{1} e{1} f{1} g{1} h{1}
+ Offset 16: a{2} b{2} c{2} d{2} e{2} f{2} g{2} h{2}
+ Offset 24: i{0} j{0} k{0} l{0} m{0} n{0} o{0} p{0}
+ Offset 32: i{1} j{1} k{1} l{1} m{1} n{1} o{1} p{1}
+ Offset 40: i{2} j{2} k{2} l{2} m{2} n{2} o{2} p{2}
+
+Note: If the input file is not a multiple of S * L, 0-padding is done.
+
+Here we have 16 numbers encoded, from A to P. This way we can easily
+see that reading the first byte of the file will read all bits 0 of
+number A, B, C, D, E, F, G and H. The same happens with bits 1 and 2
+when we read the second and third bytes respectively. Using this
+encoding and the implementation described above, we can see that the
+same set of instructions will be computing the multiplication of 8
+numbers at the same time.
+
+This can be further improved if we use L = 64 with 64 bits variables
+on 64-bits processor. It's even faster if we use L = 128 using SSE
+registers or L = 256 using AVX registers on Intel processors.
+
+Currently EC uses L = 512 and S = 8. This means that numbers are
+packed in blocks of 512 bytes and gives space for even bigger
+processor registers up to 512 bits.
+
+
+Conclusions
+-----------
+
+This method requires a single variable/processor register for each
+bit. This can be challenging if we want to avoid additional memory
+accesses, even if we use modern processors that have many registers.
+However, the implementation we chose for the Vandermonde Matrix
+doesn't require temporary storage, so we don't need a full set of 8
+new registers (one for each bit) to store partial computations.
+Additionally, the computation of the multiplications requires, at
+most, 2 extra registers, but this is afordable.
+
+Xors are a really fast operation in modern processors. Intel CPU's
+can dispatch up to 3 xors per CPU cycle if there are no dependencies
+with ongoing previous instructions. Worst case is 1 xor per cycle. So,
+in some configurations, this method could be very near to the memory
+speed.
+
+Another interesting thing of this method is that all data it needs to
+operate is packed in small sequential blocks of memory, meaning that
+it can take advantage of the faster internal CPU caches.
+
+
+Results
+-------
+
+For the particular case of 8 bits, EC can compute each multiplication
+using 12.8 xors on average (without counting 0 and 1 that do not
+require any xor). Some numbers require less, like 2 that only requires
+3 xors.
+
+Having all this, we can check some numbers to see the performance of
+this method.
+
+Maybe the most interesting thing is the average number of xors needed
+to encode a single byte of data. To compute this we'll need to define
+some variables:
+
+ * K: Number of data fragments
+ * R: Number of redundancy fragments
+ * N: K + R
+ * B: Number of bits per number
+ * A: Average number of xors per number
+ * Z: Bits per CPU register (can be up to 256 for AVX registers)
+ * X: Average number of xors per CPU cycle
+ * L: Average cycles per load
+ * S: Average cycles per store
+ * G: Core speed in Hz
+
+_Total number of bytes processed for a single matrix multiplication_:
+
+ * __Read__: K * B * Z / 8
+ * __Written__: N * B * Z / 8
+
+_Total number of memory accesses_:
+
+ * __Loads__: K * B * N
+ * __Stores__: B * N
+
+> We need to read the same K * B * Z bits, in registers of Z bits, N
+> times, one for each row of the matrix. However the last N - 1 reads
+> could be made from the internal CPU caches if conditions are good.
+
+_Total number of operations_:
+
+ * __Additions__: (K - 1) * N
+ * __Multiplications__: K * N
+
+__Total number of xors__: B * (K - 1) * N + A * K * N =
+ N * ((A + B) * K - B)
+
+__Xors per byte__: 8 * N * ((A + B) * K - B) / (K * B * Z)
+
+__CPU cycles per byte__: 8 * N * ((A + B) * K - B) / (K * B * Z * X) +
+ 8 * L * N / Z + (loads)
+ 8 * S * N / (K * Z) (stores)
+
+__Bytes per second__: G / {CPU cycles per byte}
+
+Some xors per byte numbers for specific configurations (B=8):
+
+ Z=64 Z=128 Z=256
+ K=2/R=1 0.79 0.39 0.20
+ K=4/R=2 1.76 0.88 0.44
+ K=4/R=3 2.06 1.03 0.51
+ K=8/R=3 3.40 1.70 0.85
+ K=8/R=4 3.71 1.86 0.93
+ K=16/R=4 6.34 3.17 1.59
+
+
+
+[1]: https://en.wikipedia.org/wiki/Erasure_code
+[2]: https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction
+[3]: https://en.wikipedia.org/wiki/Systematic_code
+[4]: https://en.wikipedia.org/wiki/Identity_matrix
+[5]: https://en.wikipedia.org/wiki/Linear_independence
+[6]: https://en.wikipedia.org/wiki/Vandermonde_matrix
+[7]: https://en.wikipedia.org/wiki/Finite_field
+[8]: https://en.wikipedia.org/wiki/Finite_field_arithmetic#Implementation_tricks
diff --git a/doc/developer-guide/fuse-interrupt.md b/doc/developer-guide/fuse-interrupt.md
new file mode 100644
index 00000000000..ec991b81ec5
--- /dev/null
+++ b/doc/developer-guide/fuse-interrupt.md
@@ -0,0 +1,211 @@
+# Fuse interrupt handling
+
+## Conventions followed
+
+- *FUSE* refers to the "wire protocol" between kernel and userspace and
+ related specifications.
+- *fuse* refers to the kernel subsystem and also to the GlusterFs translator.
+
+## FUSE interrupt handling spec
+
+The [Linux kernel FUSE documentation](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/fuse.txt?h=v4.18#n148)
+desrcibes how interrupt handling happens in fuse.
+
+## Interrupt handling in the fuse translator
+
+### Declarations
+
+This document describes the internal API in the fuse translator with which
+interrupt can be handled.
+
+The API being internal (to be used only in fuse-bridge.c; the functions are
+not exported to a header file).
+
+```
+enum fuse_interrupt_state {
+ /* ... */
+ INTERRUPT_SQUELCHED,
+ INTERRUPT_HANDLED,
+ /* ... */
+};
+typedef enum fuse_interrupt_state fuse_interrupt_state_t;
+struct fuse_interrupt_record;
+typedef struct fuse_interrupt_record fuse_interrupt_record_t;
+typedef void (*fuse_interrupt_handler_t)(xlator_t *this,
+ fuse_interrupt_record_t *);
+struct fuse_interrupt_record {
+ fuse_in_header_t fuse_in_header;
+ void *data;
+ /*
+ ...
+ */
+};
+
+fuse_interrupt_record_t *
+fuse_interrupt_record_new(fuse_in_header_t *finh,
+ fuse_interrupt_handler_t handler);
+
+void
+fuse_interrupt_record_insert(xlator_t *this, fuse_interrupt_record_t *fir);
+
+gf_boolean_t
+fuse_interrupt_finish_fop(call_frame_t *frame, xlator_t *this,
+ gf_boolean_t sync, void **datap);
+
+void
+fuse_interrupt_finish_interrupt(xlator_t *this, fuse_interrupt_record_t *fir,
+ fuse_interrupt_state_t intstat,
+ gf_boolean_t sync, void **datap);
+```
+
+The code demonstrates the usage of the API through `fuse_flush()`. (It's a
+dummy implementation only for demonstration purposes.) Flush is chosen
+because a `FLUSH` interrupt is easy to trigger (see
+*tests/features/interrupt.t*). Interrupt handling for flush is switched on
+by `--fuse-flush-handle-interrupt` (a hidden glusterfs command line flag).
+The implementation of flush interrupt is contained in the
+`fuse_flush_interrupt_handler()` function and blocks guarded by the
+
+```
+if (priv->flush_handle_interrupt) { ...
+```
+
+conditional (where `priv` is a `*fuse_private_t`).
+
+### Overview
+
+"Regular" fuse fops and interrupt handlers interact via a list containing
+interrupt records.
+
+If a fop wishes to have its interrupts handled, it needs to set up an
+interrupt record and insert it into the list; also when it's to finish
+(ie. in its "cbk" stage) it needs to delete the record from the list.
+
+If no interrupt happens, basically that's all to it - a list insertion
+and deletion.
+
+However, if an interrupt comes for the fop, the interrupt FUSE request
+will carry the data identifying an ongoing fop (that is, its `unique`),
+and based on that, the interrupt record will be looked up in the list, and
+the specific interrupt handler (a member of the interrupt record) will be
+called.
+
+Usually the fop needs to share some data with the interrupt handler to
+enable it to perform its task (also shared via the interrupt record).
+The interrupt API offers two approaches to manage shared data:
+- _Async or reference-counting strategy_: from the point on when the interrupt
+ record is inserted to the list, it's owned jointly by the regular fop and
+ the prospective interrupt handler. Both of them need to check before they
+ return if the other is still holding a reference; if not, then they are
+ responsible for reclaiming the shared data.
+- _Sync or borrow strategy_: the interrupt handler is considered a borrower
+ of the shared data. The interrupt handler should not reclaim the shared
+ data. The fop will wait for the interrupt handler to finish (ie., the borrow
+ to be returned), then it has to reclaim the shared data.
+
+The user of the interrupt API need to call the following functions to
+instrument this control flow:
+- `fuse_interrupt_record_insert()` in the fop to insert the interrupt record to
+ the list;
+- `fuse_interrupt_finish_fop()`in the fop (cbk) and
+- `fuse_interrupt_finish_interrupt()`in the interrupt handler
+
+to perform needed synchronization at the end their tenure. The data management
+strategies are implemented by the `fuse_interrupt_finish_*()` functions (which
+have an argument to specify which strategy to use); these routines take care
+of freeing the interrupt record itself, while the reclamation of the shared data
+is left to the API user.
+
+### Usage
+
+A given FUSE fop can be enabled to handle interrupts via the following
+steps:
+
+- Define a handler function (of type `fuse_interrupt_handler_t`).
+ It should implement the interrupt handling logic and in the end
+ call (directly or as async callback) `fuse_interrupt_finish_interrupt()`.
+ The `intstat` argument to `fuse_interrupt_finish_interrupt` should be
+ either `INTERRUPT_SQUELCHED` or `INTERRUPT_HANDLED`.
+ - `INTERRUPT_SQUELCHED` means that the interrupt could not be delivered
+ and the fop is going on uninterrupted.
+ - `INTERRUPT_HANDLED` means that the interrupt was actually handled. In
+ this case the fop will be answered from interrupt context with errno
+ `EINTR` (that is, the fop should not send a response to the kernel).
+
+ (the enum `fuse_interrupt_state` includes further members, which are reserved
+ for internal use).
+
+ We return to the `sync` and `datap` arguments later.
+- In the `fuse_<FOP>` function create an interrupt record using
+ `fuse_interrupt_record_new()`, passing the incoming `fuse_in_header` and
+ the above handler function to it.
+ - Arbitrary further data can be referred to via the `data` member of the
+ interrupt record that is to be passed on from fop context to
+ interrupt context.
+- When it's set up, pass the interrupt record to
+ `fuse_interrupt_record_insert()`.
+- In `fuse_<FOP>_cbk` call `fuse_interrupt_finish_fop()`.
+ - `fuse_interrupt_finish_fop()` returns a Boolean according to whether the
+ interrupt was handled. If it was, then the FUSE request is already
+ answered and the stack gets destroyed in `fuse_interrupt_finish_fop` so
+ `fuse_<FOP>_cbk()` can just return (zero). Otherwise follow the standard
+ cbk logic (answer the FUSE request and destroy the stack -- these are
+ typically accomplished by `fuse_err_cbk()`).
+- The last two argument of `fuse_interrupt_finish_fop()` and
+ `fuse_interrupt_finish_interrupt()` are `gf_boolean_t sync` and
+ `void **datap`.
+ - `sync` represents the strategy for freeing the interrupt record. The
+ interrupt handler and the fop handler are in race to get at the interrupt
+ record first (interrupt handler for purposes of doing the interrupt
+ handling, fop handler for purposes of deactivating the interrupt record
+ upon completion of the fop handling).
+ - If `sync` is true, then the fop handler will wait for the interrupt
+ handler to finish and it takes care of freeing.
+ - If `sync` is false, the loser of the above race will perform freeing.
+
+ Freeing is done within the respective interrupt finish routines, except
+ for the `data` field of the interrupt record; with respect to that, see
+ the discussion of the `datap` parameter below. The strategy has to be
+ consensual, that is, `fuse_interrupt_finish_fop()` and
+ `fuse_interrupt_finish_interrupt()` must pass the same value for `sync`.
+ If dismantling the resources associated with the interrupt record is
+ simple, `sync = _gf_false` is the suggested choice; `sync = _gf_true` can
+ be useful in the opposite case, when dismantling those resources would
+ be inconvenient to implement in two places or to enact in non-fop context.
+ - If `datap` is `NULL`, the `data` member of the interrupt record will be
+ freed within the interrupt finish routine. If it points to a valid
+ `void *` pointer, and if caller is doing the cleanup (see `sync` above),
+ then that pointer will be directed to the `data` member of the interrupt
+ record and it's up to the caller what it's doing with it.
+ - If `sync` is true, interrupt handler can use `datap = NULL`, and
+ fop handler will have `datap` point to a valid pointer.
+ - If `sync` is false, and handlers pass a pointer to a pointer for
+ `datap`, they should check if the pointed pointer is NULL before
+ attempting to deal with the data.
+
+### FUSE answer for the interrupted fop
+
+The kernel acknowledges a successful interruption for a given FUSE request
+if the filesystem daemon answers it with errno EINTR; upon that, the syscall
+which induced the request will be abruptly terminated with an interrupt, rather
+than returning a value.
+
+In glusterfs, this can be arranged in two ways.
+
+- If the interrupt handler wins the race for the interrupt record, ie.
+ `fuse_interrupt_finish_fop()` returns true to `fuse_<FOP>_cbk()`, then, as
+ said above, `fuse_<FOP>_cbk()` does not need to answer the FUSE request.
+ That's because then the interrupt handler will take care about answering
+ it (with errno EINTR).
+- If `fuse_interrupt_finish_fop()` returns false to `fuse_<FOP>_cbk()`, then
+ this return value does not inform the fop handler whether there was an interrupt
+ or not. This return value occurs both when fop handler won the race for the
+ interrupt record against the interrupt handler, and when there was no interrupt
+ at all.
+
+ However, the internal logic of the fop handler might detect from other
+ circumstances that an interrupt was delivered. For example, the fop handler
+ might be sleeping, waiting for some data to arrive, so that a premature
+ wakeup (with no data present) occurs if the interrupt handler intervenes. In
+ such cases it's the responsibility of the fop handler to reply the FUSE
+ request with errro EINTR.
diff --git a/doc/developer-guide/gfapi-symbol-versions/gfapi-symbol-versions.md b/doc/developer-guide/gfapi-symbol-versions.md
index c7a3ac9380e..e4f4fe9f052 100644
--- a/doc/developer-guide/gfapi-symbol-versions/gfapi-symbol-versions.md
+++ b/doc/developer-guide/gfapi-symbol-versions.md
@@ -29,7 +29,7 @@ file remains libfoo.so.0 forever. Legacy APIs may or may not have an
associated symbol version. New APIs may or may not have an associated
symbol version either. In general symbol versions are reserved for APIs
that have changed. Either the function's signature has changed, i.e. the
-return type or the number of paramaters, and/or the parameter types have
+return time or the number of paramaters, and/or the parameter types have
changed. Another reason for using symbol versions on an API is when the
behaviour or functionality of the API changes dramatically. As with a
library that doesn't use versioned symbols, old and new applications
diff --git a/doc/developer-guide/identifying-resource-leaks.md b/doc/developer-guide/identifying-resource-leaks.md
new file mode 100644
index 00000000000..950cae79b0a
--- /dev/null
+++ b/doc/developer-guide/identifying-resource-leaks.md
@@ -0,0 +1,200 @@
+# Identifying Resource Leaks
+
+Like most other pieces of software, GlusterFS is not perfect in how it manages
+its resources like memory, threads and the like. Gluster developers try hard to
+prevent leaking resources but releasing and unallocating the used structures.
+Unfortunately every now and then some resource leaks are unintentionally added.
+
+This document tries to explain a few helpful tricks to identify resource leaks
+so that they can be addressed.
+
+
+## Debug Builds
+
+There are certain techniques used in GlusterFS that make it difficult to use
+tools like Valgrind for memory leak detection. There are some build options
+that make it more practical to use Valgrind and other tools. When running
+Valgrind, it is important to have GlusterFS builds that contain the
+debuginfo/symbols. Some distributions (try to) strip the debuginfo to get
+smaller executables. Fedora and RHEL based distributions have sub-packages
+called ...-debuginfo that need to be installed for symbol resolving.
+
+
+### Memory Pools
+
+By using memory pools, there are no allocation/freeing of single structures
+needed. This improves performance, but also makes it impossible to track the
+allocation and freeing of srtuctures.
+
+It is possible to disable the use of memory pools, and use standard `malloc()`
+and `free()` functions provided by the C library. Valgrind is then able to
+track the allocated areas and verify if they have been free'd. In order to
+disable memory pools, the Gluster sources needs to be configured with the
+`--enable-debug` option:
+
+```shell
+./configure --enable-debug
+```
+
+When building RPMs, the `.spec` handles the `--with=debug` option too:
+
+```shell
+make dist
+rpmbuild -ta --with=debug glusterfs-....tar.gz
+```
+
+### Dynamically Loaded xlators
+
+Valgrind tracks the call chain of functions that do memory allocations. The
+addresses of the functions are stored and before Valgrind exits the addresses
+are resolved into human readable function names and offsets (line numbers in
+source files). Because Gluster loads xlators dynamically, and unloads then
+before exiting, Valgrind is not able to resolve the function addresses into
+symbols anymore. Whenever this happend, Valgrind shows `???` in the output,
+like
+
+```
+ ==25170== 344 bytes in 1 blocks are definitely lost in loss record 233 of 324
+ ==25170== at 0x4C29975: calloc (vg_replace_malloc.c:711)
+ ==25170== by 0x52C7C0B: __gf_calloc (mem-pool.c:117)
+ ==25170== by 0x12B0638A: ???
+ ==25170== by 0x528FCE6: __xlator_init (xlator.c:472)
+ ==25170== by 0x528FE16: xlator_init (xlator.c:498)
+ ...
+```
+
+These `???` can be prevented by not calling `dlclose()` for unloading the
+xlator. This will cause a small leak of the handle that was returned with
+`dlopen()`, but for improved debugging this can be acceptible. For this and
+other Valgrind features, a `--enable-valgrind` option is available to
+`./configure`. When GlusterFS is built with this option, Valgrind will be able
+to resolve the symbol names of the functions that do memory allocations inside
+xlators.
+
+```shell
+./configure --enable-valgrind
+```
+
+When building RPMs, the `.spec` handles the `--with=valgrind` option too:
+
+```shell
+make dist
+rpmbuild -ta --with=valgrind glusterfs-....tar.gz
+```
+
+## Running Valgrind against a single xlator
+
+Debugging a single xlator is not trivial. But there are some tools to make it
+easier. The `sink` xlator does not do any memory allocations itself, but
+contains just enough functionality to mount a volume with only the `sink`
+xlator. There is a little gfapi application under `tests/basic/gfapi/` in the
+GlusterFS sources that can be used to run only gfapi and the core GlusterFS
+infrastructure with the `sink` xlator. By extending the `.vol` file to load
+more xlators, each xlator can be debugged pretty much separately (as long as
+the xlators have no dependencies on each other). A basic Valgrind run with the
+suitable configure options looks like this:
+
+```shell
+./autogen.sh
+./configure --enable-debug --enable-valgrind
+make && make install
+cd tests/basic/gfapi/
+make gfapi-load-volfile
+valgrind ./gfapi-load-volfile sink.vol
+```
+
+Combined with other very useful options to Valgrind, the following execution
+shows many more useful details:
+
+```shell
+valgrind \
+ --fullpath-after= --leak-check=full --show-leak-kinds=all \
+ ./gfapi-load-volfile sink.vol
+```
+
+Note that the `--fullpath-after=` option is left empty, this makes Valgrind
+print the full path and filename that contains the functions:
+
+```
+==2450== 80 bytes in 1 blocks are definitely lost in loss record 8 of 60
+==2450== at 0x4C29975: calloc (/builddir/build/BUILD/valgrind-3.11.0/coregrind/m_replacemalloc/vg_replace_malloc.c:711)
+==2450== by 0x52C6F73: __gf_calloc (/usr/src/debug/glusterfs-3.11dev/libglusterfs/src/mem-pool.c:117)
+==2450== by 0x12F10CDA: init (/usr/src/debug/glusterfs-3.11dev/xlators/meta/src/meta.c:231)
+==2450== by 0x528EFD5: __xlator_init (/usr/src/debug/glusterfs-3.11dev/libglusterfs/src/xlator.c:472)
+==2450== by 0x528F105: xlator_init (/usr/src/debug/glusterfs-3.11dev/libglusterfs/src/xlator.c:498)
+==2450== by 0x52D9D8B: glusterfs_graph_init (/usr/src/debug/glusterfs-3.11dev/libglusterfs/src/graph.c:321)
+...
+```
+
+In the above example, the `init` function in `xlators/meta/src/meta.c` does a
+memory allocation on line 231. This memory is never free'd again, and hence
+Valgrind logs this call stack. When looking in the code, it seems that the
+allocation of `priv` is assigned to the `this->private` member of the
+`xlator_t` structure. Because the allocation is done in `init()`, free'ing is
+expected to happen in `fini()`. Both functions are shown below, with the
+inclusion of the empty `fini()`:
+
+
+```
+226 int
+227 init (xlator_t *this)
+228 {
+229 meta_priv_t *priv = NULL;
+230
+231 priv = GF_CALLOC (sizeof(*priv), 1, gf_meta_mt_priv_t);
+232 if (!priv)
+233 return -1;
+234
+235 GF_OPTION_INIT ("meta-dir-name", priv->meta_dir_name, str, out);
+236
+237 this->private = priv;
+238 out:
+239 return 0;
+240 }
+241
+242
+243 int
+244 fini (xlator_t *this)
+245 {
+246 return 0;
+247 }
+```
+
+In this case, the resource leak can be addressed by adding a single line to the
+`fini()` function:
+
+```
+243 int
+244 fini (xlator_t *this)
+245 {
+246 GF_FREE (this->private);
+247 return 0;
+248 }
+```
+
+Running the same Valgrind command and comparing the output will show that the
+memory leak in `xlators/meta/src/meta.c:init` is not reported anymore.
+
+### Running DRD, the Valgrind thread error detector
+
+When configuring GlusterFS with:
+
+```shell
+./configure --enable-valgrind
+```
+
+the default Valgrind tool (Memcheck) is enabled. But it's also possble to select
+one of Memcheck or DRD by using:
+
+```shell
+./configure --enable-valgrind=memcheck
+```
+
+or:
+
+```shell
+./configure --enable-valgrind=drd
+```
+
+respectively. When using DRD, it's recommended to consult
+https://valgrind.org/docs/manual/drd-manual.html before running.
diff --git a/doc/developer-guide/logging-guidelines.md b/doc/developer-guide/logging-guidelines.md
index 58adf944b67..0e6b2588535 100644
--- a/doc/developer-guide/logging-guidelines.md
+++ b/doc/developer-guide/logging-guidelines.md
@@ -62,7 +62,7 @@ There are 2 interfaces provided to log messages,
headers (like the time stamp, dom, errnum etc.). The primary users of
the above interfaces are, when printing the final graph, or printing
the configuration when a process is about dump core or abort, or
- printing the backtrace when a process recieves a critical signal
+ printing the backtrace when a process receives a critical signal
- These interfaces should not be used outside the scope of the users
above, unless you know what you are doing
diff --git a/doc/developer-guide/network_compression.md b/doc/developer-guide/network_compression.md
index 7327591ef63..1222a765276 100644
--- a/doc/developer-guide/network_compression.md
+++ b/doc/developer-guide/network_compression.md
@@ -1,9 +1,9 @@
-#On-Wire Compression + Decompression
+# On-Wire Compression + Decompression
The 'compression translator' compresses and decompresses data in-flight
between client and bricks.
-###Working
+### Working
When a writev call occurs, the client compresses the data before sending it to
brick. On the brick, compressed data is decompressed. Similarly, when a readv
call occurs, the brick compresses the data before sending it to client. On the
@@ -19,7 +19,7 @@ During normal operation, this is the format of data sent over wire:
The trailer contains the CRC32 checksum and length of original uncompressed
data. This is used for validation.
-###Usage
+### Usage
Turning on compression xlator:
@@ -27,7 +27,7 @@ Turning on compression xlator:
gluster volume set <vol_name> network.compression on
~~~
-###Configurable parameters (optional)
+### Configurable parameters (optional)
**Compression level**
~~~
@@ -35,10 +35,10 @@ gluster volume set <vol_name> network.compression.compression-level 8
~~~
~~~
-0 : no compression
-1 : best speed
-9 : best compression
--1 : default compression
+ 0 : no compression
+ 1 : best speed
+ 9 : best compression
+-1 : default compression
~~~
**Minimum file size**
@@ -55,7 +55,7 @@ Other less frequently used parameters include `network.compression.mem-level`
and `network.compression.window-size`. More details can about these options
can be found by running `gluster volume set help` command.
-###Known Issues and Limitations
+### Known Issues and Limitations
* Compression translator cannot work with striped volumes.
* Mount point hangs when writing a file with write-behind xlator turned on. To
@@ -65,7 +65,7 @@ set`performance.strict-write-ordering` to on.
distribute volumes. This limitation is caused by AFR not being able to
propagate xdata. This issue has been fixed in glusterfs versions > 3.5
-###TODO
+### TODO
Although zlib offers high compression ratio, it is very slow. We can make the
translator pluggable to add support for other compression methods such as
[lz4 compression](https://code.google.com/p/lz4/)
diff --git a/doc/developer-guide/options-to-contribute.md b/doc/developer-guide/options-to-contribute.md
new file mode 100644
index 00000000000..3f0d84e7645
--- /dev/null
+++ b/doc/developer-guide/options-to-contribute.md
@@ -0,0 +1,212 @@
+# A guide for contributors
+
+While you have gone through 'how to contribute' guides, if you are
+not sure what to work on, but really want to help the project, you
+have now landed on the right document :-)
+
+### Basic
+
+Instead of planning to fix **all** the below issues in one patch,
+we recommend you to have a a constant, continuous flow of improvements
+for the project. We recommend you to pick 1 file (or just few files) at
+a time to address below issues.
+Pick any `.c` (or `.h`) file, and you can send a patch which fixes **any**
+of the below themes. Ideally, fix all such occurrences in the file, even
+though, the reviewers would review even a single line change patch
+from you.
+
+1. Check for variable definitions, and if there is an array definition,
+which is very large at the top of the function, see if you can re-scope
+the variable to relevant sections (if it helps).
+
+Most of the time, some of these arrays may be used for 'error' handling,
+and it is possible to use them only in that scope.
+
+Reference: https://review.gluster.org/20846/
+
+
+2. Check for complete string initialization at the beginning of a function.
+Ideally, there is no reason to initialize a string. Fix it across the file.
+
+Example:
+
+`char new_path_name[PATH_MAX] = {0};` to `char new_path_name[PATH_MAX];`
+
+
+3. Change `calloc()` to `malloc()` wherever it makes sense.
+
+In a case of allocating a structures, where you expect certain (or most of)
+variables to be 0 (or NULL), it makes sense to use calloc(). But otherwise,
+there is an extra cost to `memset()` the whole object after allocating it.
+While it is not a significant improvement in performance, code which gets
+hit 1000s of times in a second, it would add some value.
+
+Reference: https://review.gluster.org/20878/
+
+
+4. You can consider using `snprintf()`, instead of `strncpy()` while dealing
+with strings.
+
+strncpy() won't null terminate if the dest buffer isn't big enough; snprintf()
+does. While most of the string operations in the code is on array, and larger
+size than required, strncpy() does an extra copy of 0s at the end of
+string till the size of the array. It makes sense to use `snprintf()`,
+which doesn't suffer from that behavior.
+
+Also check the return value from snprintf() for buffer overflow and handle
+accordingly
+
+Reference: https://review.gluster.org/20925/
+
+
+5. Now, pick a `.h` file, and see if a structure is very large, and see
+if re-aligning them as per [coding-standard](./coding-standard.md) gives any size benefit,
+if yes, go ahead and change it. Make sure you check all the structures
+in the file for similar pattern.
+
+Reference: [Check this section](https://github.com/gluster/glusterfs/blob/master/doc/developer-guide/coding-standard.md#structure-members-should-be-aligned-based-on-the-padding-requirements
+
+
+### If you are up for more :-)
+
+Good progress! Glad you are interested to know more. We are surely interested
+in next level of contributions from you!
+
+#### Coverity
+
+Visit [Coverity Dashboard](https://scan.coverity.com/projects/gluster-glusterfs?tab=overview).
+
+Now, if the number of defect is not 0, you have an opportunity to contribute.
+
+You get all the detail on why the particular defect is mentioned there, and
+most probable hint on how to fix it. Do it!
+
+Reference: https://review.gluster.org/21394/
+
+Use the same reference Id (789278) as the patch, so we can capture it is in
+single bugzilla.
+
+#### Clang-Scan
+
+Clang-Scan is a tool which scans the .c files and reports the possible issues,
+similar to coverity, but a different tool. Over the years we have seen, they
+both report very different set of issues, and hence there is a value in fixing it.
+
+GlusterFS project gets tested with clang-scan job every night, and the report is
+posted in the [job details page](https://build.gluster.org/job/clang-scan/lastCompletedBuild/clangScanBuildBugs/).
+As long as the number is not 0 in the report here, you have an opportunity to
+contribute! Similar to coverity dashboard, click on 'Details' to find out the
+reason behind that report, and send a patch.
+
+Reference: https://review.gluster.org/21025
+
+Again, you can use reference Id (1622665) for these patches!
+
+
+### I am good with programming, I would like to do more than above!
+
+#### Locked regions / Critical sections
+
+In the file you open, see if the lock is taken only to increment or decrement
+a flag, counter etc. If yes, then recommend you to convert it to ATOMIC locks.
+It is simple activity, but, if you know programing, you would know the benefit
+here.
+
+NOTE: There may not always a possibility to do this! You may have to check
+with developers first before going ahead.
+
+Reference: https://review.gluster.org/21221/
+
+
+#### ASan (address sanitizer)
+
+[The job](https://build.gluster.org/job/asan/) runs regression with asan builds,
+and you can also run glusterfs with asan on your workload to identify the leaks.
+If there are any leaks reported, feel free to check it, and send us patch.
+
+You can also run `valgrind` and let us know what it reports.
+
+Reference: https://review.gluster.org/21397
+
+
+#### Porting to different architecture
+
+This is something which we are not focusing right now, happy to collaborate!
+
+Reference: https://review.gluster.org/21276
+
+
+#### Fix 'TODO/FIXME' in codebase
+
+There are few cases of pending features, or pending validations, which are
+pending from sometime. You can pick them in the given file, and choose to
+fix it.
+
+
+### I don't know C, but I am interested to contribute in some way!
+
+You are most welcome! Our community is open for your contribution! First thing
+which comes to our mind is **documentation**. Next is, **testing** or validation.
+
+If you have some hardware, and want to run some performance comparisons with
+different version, or options, and help us to tune better is also a great help.
+
+
+#### Documentation
+
+1. We have some documentation in [glusterfs repo](../), go through these, and
+see if you can help us to keep up-to-date.
+
+2. The https://docs.gluster.org is powered by https://github.com/gluster/glusterdocs
+repo. You can check out the repo, and help in keeping that up-to-date.
+
+3. [Our website](https://gluster.org) is maintained by https://github.com/gluster/glusterweb
+repo. Help us to keep this up-to-date, and add content there.
+
+4. Write blogs about Gluster, and your experience, and make world know little
+more about Gluster, and your use-case, and how it helped to solve the problem.
+
+
+#### Testing
+
+1. There is a regression test suite in glusterfs, which runs with every patch, and is
+triggered by just running `./run-tests.sh` from the root of the project repo.
+
+You can add more test case to match your use-case, and send it as a patch, so you
+can make sure all future patches in glusterfs would keep your usecase intact.
+
+2. [Glusto-Tests](https://github.com/gluster/glusto-tests): This is another testing
+framework written for gluster, and makes use of clustered setup to test different
+use-cases, and helps to validate many bugs.
+
+
+#### Ansible
+
+Gluster Organization has rich set of ansible roles, which are actively maintained.
+Feel free to check them out here - https://github.com/gluster/gluster-ansible
+
+
+#### Monitoring
+
+We have prometheus repo, and are actively working on adding more metrics. Add what
+you need @ https://github.com/gluster/gluster-prometheus
+
+
+#### Health-Report
+
+This is a project, where at any given point in time, you want to run some set of
+commands locally, and get an output to analyze the status, it can be added.
+Contribute @ https://github.com/gluster/gluster-health-report
+
+
+### All these C/bash/python is old-school, I want something in containers.
+
+We have something for you too :-)
+
+Please visit our https://github.com/gluster/gcs repo for checking how you can help,
+and how gluster can help you in container world.
+
+
+### Note
+
+For any queries, best way is to contact us through mailing-list, <mailto:gluster-devel@gluster.org>
diff --git a/doc/developer-guide/rpc-for-glusterfs.new-versions.md b/doc/developer-guide/rpc-for-glusterfs.new-versions.md
new file mode 100644
index 00000000000..e3da5efa4a2
--- /dev/null
+++ b/doc/developer-guide/rpc-for-glusterfs.new-versions.md
@@ -0,0 +1,32 @@
+# GlusterFS RPC program versions
+
+## Compatibility
+
+RPC layer of glusterfs is implemented with possible changes over the protocol layers in mind. If there are any changes in the FOPs from what is assumed to be client side, and whats in serverside, they are to be added as a separate program table.
+
+### Program tables and Versions
+
+A given RPC program has a specific Task, and Version along with actors belonging to the program. In any of the programs, if a new actor is added, it is very important to define one more program with different version, and then keep both, if both are supported. Or else, it is important to handle the 'handshake' properly.
+
+#### Server details
+
+More info on RPC program is at `rpc/rpc-lib/src/rpcsvc.h` and check for structure `rpcsvc_actor_t` and `struct rpcsvc_program`. For usage, check `xlators/protocol/server/src/server-rpc-fops.c`
+
+#### Client details
+
+For details on client structures check `rpc/rpc-lib/src/rpc-clnt.h` for `rpc_clnt_procedure_t` and `rpc_clnt_program_t`. For usage, check `xlators/protocol/client/src/client-rpc-fops.c`
+
+## Protocol
+
+A protocol is what is agreed between two parties. In glusterfs, a RPC protocol is defined as .x file, which then gets converted to .c/.h file using `rpcgen`. There are different protocols defined for communication between `xlators/mgmt/glusterd <==> glusterfsd`, `gluster CLI <==> glusterd`, and `client-protocol <==> server-protocol`
+
+Once a protocol is defined and a release is made with that protocol, make sure no one changes it. Any edits to a given structure there should be a new version of the structure, and also it should get used in new actor, and thus new program version.
+
+## Server and Client Handshake
+
+When a client succeeds to establish a connect (it can be any transport, socket, ib-verbs or unix), client sends a dump (GF_DUMP_DUMP) request to server, which will respond back with all the supported versions of the server RPC (the supported programs which are registered with `rpcsvc_program_register()`).
+
+A client which expects certain programs to be present in server, it should be taking care of looking for it in the handshake methods, and take appropriate action depending on what to do next. In general a compatibility issue should be handled at handshake level itself, thus we can clearly let user/admin know of any 'in-compatibilities'.
+As a developer of GlusterFS protocol layer, one just has to make sure *never to make changes to existing program structures*, but they have to add new programs if required. New programs can have the same actors as present in existing, and also little more. Or it can even have same actor behave differently, take different parameter.
+
+If this is followed properly, there would be smooth upgrade / downgrade of versions. If not, technically, it is 100% guarantee of getting compatibility related issues.
diff --git a/doc/developer-guide/syncop.md b/doc/developer-guide/syncop.md
new file mode 100644
index 00000000000..bcc8bd08e01
--- /dev/null
+++ b/doc/developer-guide/syncop.md
@@ -0,0 +1,72 @@
+# syncop framework
+A coroutines-based, cooperative multi-tasking framework.
+
+## Topics
+
+- Glossary
+- Lifecycle of a synctask
+- Existing usage
+
+
+## Glossary
+
+### syncenv
+
+syncenv is an object that provides access to a pool of worker threads.
+synctasks execute in a syncenv.
+
+### synctask
+
+synctask can be informally defined as a pair of function pointers, namely _the
+call_ and _the callback_ (see syncop.h for more details).
+
+ synctask_fn_t - 'the call'
+ synctask_cbk_t - 'the callback'
+
+synctask has two modes of operation,
+
+1. The calling thread waits for the synctask to complete.
+2. The calling thread schedules the synctask and continues.
+
+synctask guarantees that the callback is called _after_ the call completes.
+
+### Lifecycle of a synctask
+
+A synctask could go into the following stages while in execution.
+
+- CREATED - On calling synctask_create/synctask_new.
+
+- RUNNABLE - synctask is queued in env->runq.
+
+- RUNNING - When one of syncenv's worker threads calls synctask_switch_to.
+
+- WAITING - When a synctask calls synctask_yield.
+
+- DONE - When a synctask has run to completion.
+
+
+ +-------------------------------+
+ | CREATED |
+ +-------------------------------+
+ |
+ | synctask_new/synctask_create
+ v
+ +-------------------------------+
+ | RUNNABLE (in env->runq) | <+
+ +-------------------------------+ |
+ | |
+ | synctask_switch_to |
+ v |
+ +------+ on task completion +-------------------------------+ |
+ | DONE | <-------------------- | RUNNING | | synctask_wake/wake
+ +------+ +-------------------------------+ |
+ | |
+ | synctask_yield/yield |
+ v |
+ +-------------------------------+ |
+ | WAITING (in env->waitq) | -+
+ +-------------------------------+
+
+Note: A synctask is not guaranteed to run on the same thread throughout its
+lifetime. Every time a synctask yields, it is possible for it to run on a
+different thread.
diff --git a/doc/developer-guide/thread-naming.md b/doc/developer-guide/thread-naming.md
new file mode 100644
index 00000000000..513140d4437
--- /dev/null
+++ b/doc/developer-guide/thread-naming.md
@@ -0,0 +1,104 @@
+Thread Naming
+================
+Gluster processes spawn many threads; some threads are created by libglusterfs
+library, while others are created by xlators. When gfapi library is used in an
+application, some threads belong to the application and some are spawned by
+gluster libraries. We also have features where n number of threads are spawned
+to act as worker threads for same operation.
+
+In all the above cases, it is useful to be able to determine the list of threads
+that exist in runtime. Naming threads when you create them is the easiest way to
+provide that information to kernel so that it can then be queried by any means.
+
+How to name threads
+-------------------
+We have two wrapper functions in libglusterfs for creating threads. They take
+name as an argument and set thread name after its creation.
+
+```C
+gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg, const char *name)
+```
+
+```C
+gf_thread_create_detached (pthread_t *thread,
+ void *(*start_routine)(void *), void *arg,
+ const char *name)
+```
+
+As max name length for a thread in POSIX is only 16 characters including the
+'\0' character, you have to be a little creative with naming. Also, it is
+important that all Gluster threads have common prefix. Considering these
+conditions, we have "glfs_" as prefix for all the threads created by these
+wrapper functions. It is responsibility of the owner of thread to provide the
+suffix part of the name. It does not have to be a descriptive name, as it has
+only 10 letters to work with. However, it should be unique enough such that it
+can be matched with a table which describes it.
+
+If n number of threads are spwaned to perform same function, it is must that the
+threads are numbered.
+
+Table of thread names
+---------------------
+Thread names don't have to be a descriptive; however, it should be unique enough
+such that it can be matched with a table below without ambiguity.
+
+- bdaio - block device aio
+- brfsscan - bit rot fs scanner
+- brhevent - bit rot event handler
+- brmon - bit rot monitor
+- brosign - bit rot one shot signer
+- brpobj - bit rot object processor
+- brsproc - bit rot scrubber
+- brssign - bit rot stub signer
+- brswrker - bit rot worker
+- clogc - changelog consumer
+- clogcbki - changelog callback invoker
+- clogd - changelog dispatcher
+- clogecon - changelog reverse connection
+- clogfsyn - changelog fsync
+- cloghcon - changelog history consumer
+- clogjan - changelog janitor
+- clogpoll - changelog poller
+- clogproc - changelog process
+- clogro - changelog rollover
+- ctrcomp - change time recorder compaction
+- dhtdf - dht defrag task
+- dhtdg - dht defrag start
+- dhtfcnt - dht rebalance file counter
+- ecshd - ec heal daemon
+- epollN - epoll thread
+- fdlwrker - fdl worker
+- fusenoti - fuse notify
+- fuseproc - fuse main thread
+- gdhooks - glusterd hooks
+- glfspoll - gfapi poller thread
+- idxwrker - index worker
+- iosdump - io stats dump
+- iotwr - io thread worker
+- jbrflush - jbr flush
+- leasercl - lease recall
+- memsweep - sweeper thread for mem pools
+- nfsauth - nfs auth
+- nfsnsm - nfs nsm
+- nfsudp - nfs udp mount
+- nlmmon - nfs nlm/nsm mon
+- posixaio - posix aio
+- posixfsy - posix fsync
+- posixhc - posix heal
+- posixjan - posix janitor
+- posixrsv - posix reserve
+- quiesce - quiesce dequeue
+- rdmaAsyn - rdma async event handler
+- rdmaehan - rdma completion handler
+- rdmarcom - rdma receive completion handler
+- rdmascom - rdma send completion handler
+- rpcsvcrh - rpcsvc request handler
+- scleanup - socket cleanup
+- shdheal - self heal daemon
+- sigwait - glusterfsd sigwaiter
+- spoller - socket poller
+- sprocN - syncop worker thread
+- tbfclock - token bucket filter token generator thread
+- timer - timer thread
+- upreaper - upcall reaper
diff --git a/doc/developer-guide/translator-development.md b/doc/developer-guide/translator-development.md
index 9153c874d0f..f75935519f6 100644
--- a/doc/developer-guide/translator-development.md
+++ b/doc/developer-guide/translator-development.md
@@ -51,7 +51,7 @@ if (!(xl->fini = dlsym (handle, "fini"))) {
In this example, `xl` is a pointer to the in-memory object for the translator
we're loading. As you can see, it's looking up various symbols *by name* in the
shared object it just loaded, and storing pointers to those symbols. Some of
-them (e.g. init are functions, while others e.g. fops are dispatch tables
+them (e.g. init) are functions, while others (e.g. fops) are dispatch tables
containing pointers to many functions. Together, these make up the translator's
public interface.
@@ -102,7 +102,7 @@ various structures in logs. I've never used it myself, though I probably
should. What's noteworthy here is that we don't even define dumpops. That's
because all of the functions that might use these dispatch functions will check
for `xl->dumpops` being `NULL` before calling through it. This is in sharp
-contrast to the behavior for `fops` and `cbks1`, which *must* be present. If
+contrast to the behavior for `fops` and `cbks`, which *must* be present. If
they're not, translator loading will fail because these pointers are not
checked every time and if they're `NULL` then we'll segfault. That's why we
provide an empty definition for cbks; it's OK for the individual function
@@ -472,7 +472,7 @@ hello
Now let's interrupt the process and see where we are.
```
-^C
+
Program received signal SIGINT, Interrupt.
0x0000003a0060b3dc in pthread_cond_wait@@GLIBC_2.3.2 ()
from /lib64/libpthread.so.0
@@ -680,4 +680,4 @@ Original author's site:
Gluster community site:
- * [Translators](http://www.gluster.org/community/documentation/index.php/Translators)
+ * [Translators](https://docs.gluster.org/en/latest/Quick-Start-Guide/Architecture/#translators)
diff --git a/doc/developer-guide/writing-a-cloudsync-plugin.md b/doc/developer-guide/writing-a-cloudsync-plugin.md
new file mode 100644
index 00000000000..907860aaed8
--- /dev/null
+++ b/doc/developer-guide/writing-a-cloudsync-plugin.md
@@ -0,0 +1,164 @@
+## How to write your Cloudsync Plugin
+
+### Background
+
+Cloudsync translator is part of the archival feature in Gluster. This translator
+does the retrieval/download part. Each cold file will be archived to a remote
+storage (public or private cloud). On future access to the file, it will be
+retrieved from the remote storage by Cloudsync translator. Each remote storage
+would need a unique plugin. Cloudsync translator will load this plugin and
+call the necessary plugin functions.
+
+Upload can be done by a script or program. There are some basic mandatory steps
+for uploading the data. There is a sample script for crawl and upload given at
+the end of this guide.
+
+### Necessary changes to create a plugin
+
+1. Define store_methods:
+
+* This structure is the container of basic functions that will be called by
+ cloudsync xlator.
+
+ typedef struct store_methodds {
+ int (*fop_download) (call_frame_t *frame, void *config);
+ /* return type should be the store config */
+ void *(*fop_init) (xlator_t *this);
+ int (*fop_reconfigure) (xlator_t *this, dict_t *options);
+ void (*fop_fini) (void *config);
+ } store_methods_t;
+
+
+ Member details:
+ fop_download:
+ This is the download function pointer.
+
+ frame: This will have the fd to write data downloaded from
+ cloud to GlusterFS.(frame->local->fd)
+
+ config: This is the plugin configuration variable.
+
+ Note: Structure cs_local_t has member dlfd and dloffset which
+ can be used to manage the writes to Glusterfs.
+ Include cloudsync-common.h to access these structures.
+
+ fop_init:
+ This is similar to xlator init. But here the return value is
+ the plugin configuration pointer. This pointer will be stored
+ in the cloudsync private object (priv->stores->config). And
+ the cloudsync private object can be accessed by "this->private"
+ where "this" is of type xlator_t.
+
+ fop_reconfigure:
+ This is similar to xlator_reconfigure.
+
+ fop_fini:
+ Free plugin resources.
+
+ Note: Store_methods_t is part of cs_private_t which in turn part of
+ xlator_t. Create a store_methods_t object named "store_ops" in
+ your plugin. For example
+
+ store_methods_t store_ops = {
+ .fop_download = aws_download_s3,
+ .fop_init = aws_init,
+ .fop_reconfigure = aws_reconfigure,
+ .fop_fini = aws_fini,
+ };
+
+
+2 - Making Cloudsync xlator aware of the plugin:
+
+ Add an entry in to the cs_plugin structure. For example
+ struct cs_plugin plugins[] = {
+ {
+ .name = "amazons3",
+ .library = "libamazons3.so",
+ .description = "amazon s3 store."
+ },
+
+ {.name = NULL},
+ };
+
+ Description about individual members:
+ name: name of the plugin
+ library: This is the shared object created. Cloudsync will load
+ this library during init.
+ description: Describe about the plugin.
+
+3- Makefile Changes in Cloudsync:
+
+ Add <plugin.la> to cloudsync_la_LIBADD variable.
+
+4 - Configure.ac changes:
+
+ In cloudsync section add the necessary dependency checks for
+ the plugin.
+
+5 - Export symbols:
+
+ Cloudsync needs "store_ops" to resolve all plugin functions.
+ Create a file <plugin>.sym and add write "store_ops" to it.
+
+
+### Sample script for upload
+This script assumes amazon s3 is the target cloud and bucket name is
+gluster-bucket. User can do necessary aws configuration using command
+"aws configure". Currently for amazons3 there are four gluster settings
+available.
+1- features.s3plugin-seckey -> s3 secret key
+2- features.s3plugin-keyid -> s3 key id
+3- features.s3plugin-bucketid -> bucketid
+4- features.s3plugin-hostname -> hostname e.g. s3.amazonaws.com
+
+Additionally set cloudsync storetype to amazons3.
+
+gluster v set <VOLNAME> cloudsync-storetype amazons3
+
+Now create a mount dedicated for this upload task.
+
+That covers necessary configurations needed.
+
+Below is the sample script for upload. The script will crawl directly on the
+brick and will upload those files which are not modified for last one month.
+It needs two arguments.
+1st arguement - Gluster Brick path
+2nd arguement - coldness that is how many days since the file was modified.
+3rd argument - dedicated gluster mount point created for uploading.
+
+Once the cloud setup is done, run the following script on individual bricks.
+Note: For an AFR volume, pick only the fully synchronized brick among the
+replica bricks.
+
+```
+target_folder=$1
+coldness=$2
+mnt=$3
+
+cd $target_folder
+for i in `find . -type f | grep -v "glusterfs" | sed 's/..//'`
+do
+ echo "processing $mnt/$i"
+
+ #check whether the file is already archived
+ getfattr -n trusted.glusterfs.cs.remote $i &> /dev/null
+ if [ $? -eq 0 ]
+ then
+ echo "file $mnt/$i is already archived"
+ else
+ #upload to cloud
+ aws s3 cp $mnt/$i s3://gluster-bucket/
+ mtime=`stat -c "%Y" $mnt/$i`
+
+ #post processing of upload
+ setfattr -n trusted.glusterfs.csou.complete -v $mtime $mnt/$i
+ if [ $? -ne 0 ]
+ then
+ echo "archiving of file $mnt/$i failed"
+ else
+ echo "archiving of file $mnt/$i succeeded"
+ fi
+
+ fi
+done
+```
diff --git a/doc/developer-guide/xlator-classification.md b/doc/developer-guide/xlator-classification.md
new file mode 100644
index 00000000000..6073df9375f
--- /dev/null
+++ b/doc/developer-guide/xlator-classification.md
@@ -0,0 +1,221 @@
+# xlator categories and expectations
+
+The purpose of the document is to define a category for various xlators
+and expectations around what each category means from a perspective of
+health and maintenance of a xlator.
+
+The need to do this is to ensure certain categories are kept in good
+health, and helps the community and contributors focus their efforts around the
+same.
+
+This document also provides implementation details for xlator developers to
+declare a category for any xlator.
+
+## Table of contents
+1. Audience
+2. Categories (and expectations of each category)
+3. Implementation and usage details
+
+## Audience
+
+This document is intended for the following community participants,
+- New xlator contributors
+- Existing xlator maintainers
+- Packaging and gluster management stack maintainers
+
+For a more user facing understanding it is recommended to read section (TBD)
+in the gluster documentation.
+
+## Categories
+1. Experimental (E)
+2. TechPreview (TP)
+3. Maintained (M)
+4. Deprecated (D)
+5. Obsolete (O)
+
+### Experimental (E)
+
+Developed in the experimental branch, for exploring new features. These xlators
+are NEVER packaged as a part of releases, interested users and contributors can
+build and work with these from sources. In the future, these maybe available as
+an package based on a weekly build of the same.
+
+#### Quality expectations
+- Compiles or passes smoke tests
+- Does not break nightly experimental regressions
+ - NOTE: If a nightly is broken, then all patches that were merged are reverted
+ till the errant patch is found and subsequently fixed
+
+### TechPreview (TP)
+
+Xlators in master or release branches that are not deemed fit to be in
+production deployments, but are feature complete to invite feedback and host
+user data.
+
+These xlators will be worked upon with priority by maintainers/authors who are
+involved in making them more stable than xlators in the Experimental/Deprecated/
+Obsolete categories.
+
+There is no guarantee that these xlators will move to the Maintained state, and
+may just get Obsoleted based on feedback, or other project goals or technical
+alternatives.
+
+#### Quality expectations
+- Same as Maintained, minus
+ - Performance, Scale, other(?)
+ - *TBD* *NOTE* Need inputs, Intention is all quality goals as in Maintained,
+ other than the list above (which for now has scale and performance)
+
+### Maintained (M)
+
+These xltors are part of the core Gluster functionality and are maintained
+actively. These are part of master and release branches and are higher in
+priority of maintainers and other interested contributors.
+
+#### Quality expectations
+
+NOTE: A short note on what each of these mean are added here, details to follow.
+
+NOTE: Out of the gate all of the following are not mandated, consider the
+following a desirable state to reach as we progress on each
+
+- Bug backlog: Actively address bug backlog
+- Enhancement backlog: Actively maintain outstanding enhancement backlog (need
+ not be acted on, but should be visible to all)
+- Review backlog: Actively keep this below desired counts and states
+- Static code health: Actively meet near-zero issues in this regard
+ - Coverity, spellcheck and other checks
+- Runtime code health: Actively meet defined coverage levels in this regard
+ - Coverage, others?
+ - Per-patch regressions
+ - Glusto runs
+ - Performance
+ - Scalability
+- Technical specifications: Implementation details should be documented and
+ updated at regular cadence (even per patch that change assumptions in
+ here)
+- User documentation: User facing details should be maintained to current
+ status in the documentation
+- Debuggability: Steps, tools, procedures should be documented and maintained
+ each release/patch as applicable
+- Troubleshooting: Steps, tools, procedures should be documented and maintained
+ each release/patch as applicable
+ - Steps/guides for self service
+ - Knowledge base for problems
+- Other common criteria that will apply: Required metrics/desired states to be
+ defined per criteria
+ - Monitoring, usability, statedump, and other such xlator expectations
+
+### Deprecated (D)
+
+Xlators on master or release branches that would be obsoleted and/or replaced
+with similar or other functionality in the next major release.
+
+#### Quality expectations
+- Retain status-quo when moved to this state, till it is moved to obsoleted
+- Provide migration steps if feature provided by the xlator is replaced with
+other xlators
+
+### Obsolete (O)
+
+Xlator/code still in tree, but not packaged or shipped or maintained in any
+form. This is noted as a category till the code is removed from the tree.
+
+These xlators and their corresponding code and test health will not be executed.
+
+#### Quality expectations
+- None
+
+## Implementation and usage details
+
+### How to specify an xlators category
+
+While defining 'xlator_api_t' structure for the corresponding xlator, add a
+flag like below:
+
+```
+diff --git a/xlators/performance/nl-cache/src/nl-cache.c b/xlators/performance/nl-cache/src/nl-cache.c
+index 0f0e53bac2..8267d6897c 100644
+--- a/xlators/performance/nl-cache/src/nl-cache.c
++++ b/xlators/performance/nl-cache/src/nl-cache.c
+@@ -869,4 +869,5 @@ xlator_api_t xlator_api = {
+ .cbks = &nlc_cbks,
+ .options = nlc_options,
+ .identifier = "nl-cache",
++ .category = GF_TECH_PREVIEW,
+ };
+diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c
+index 8d39720e7f..235de27c19 100644
+--- a/xlators/performance/quick-read/src/quick-read.c
++++ b/xlators/performance/quick-read/src/quick-read.c
+@@ -1702,4 +1702,5 @@ xlator_api_t xlator_api = {
+ .cbks = &qr_cbks,
+ .options = qr_options,
+ .identifier = "quick-read",
++ .category = GF_MAINTAINED,
+ };
+```
+
+Similarly, if a particular option is in different state other than
+the xlator state, one can add the same flag in options structure too.
+
+```
+diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c
+index 0e86e33d03..81996743d1 100644
+--- a/xlators/cluster/afr/src/afr.c
++++ b/xlators/cluster/afr/src/afr.c
+@@ -772,6 +772,7 @@ struct volume_options options[] = {
+ .description = "Maximum latency for shd halo replication in msec."
+ },
+ { .key = {"halo-enabled"},
++ .category = GF_TECH_PREVIEW,
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "False",
+
+```
+
+
+### User experience using the categories
+
+#### Ability to use a category
+
+This section details which category of xlators can be used when and specifics
+around when each category is enabled.
+
+1. Maintained category xlators can be used by default, this implies, volumes
+created with these xlators enabled will throw no warnings, or need no user
+intervention to use the xlator.
+
+2. Tech Preview category xlators needs cluster configuration changes to allow
+these xlatorss to be used in volumes, further, logs will contain a message
+stating TP xlators are in use. Without the cluster configured to allow TP
+xlators, volumes created or edited to use such xlators would result in errors.
+ - (TBD) Cluster configuration option
+ - (TBD) Warning message
+ - (TBD) Code mechanics on how this is achieved
+
+3. Deprecated category xlators can be used by default, but will throw a warning
+in the logs that such are in use and will be deprecated in the future.
+ - (TBD) Warning message
+
+4. Obsolete category xlators will not be packaged and hence cannot be used from
+release builds.
+
+5. Experimental category xlators will not be packaged and hence cannot be used
+from release builds, if running experimental (weekly or other such) builds,
+these will throw a warning in the logs stating experimental xlators are in use.
+ - (TBD) Warning message
+
+#### Ability to query xlator category
+
+(TBD) Need to provide the ability to query xlator categories, or list xlators
+and their respective categories.
+
+#### User facing changes
+
+User facing changes that are expected due to this change include the following,
+- Cluster wide option to enable TP xlators, or more generically a category
+level of xlators
+- Errors in commands that fail due to invalid categories
+- Warning messages in logs to denote certain categories of xlators are in use
+- (TBD) Ability to query xlators and their respective categories
diff --git a/doc/features/ctime.md b/doc/features/ctime.md
new file mode 100644
index 00000000000..74a77abed4b
--- /dev/null
+++ b/doc/features/ctime.md
@@ -0,0 +1,68 @@
+# Consistent time attributes in gluster across replica/distribute
+
+
+#### Problem:
+Traditionally gluster has been using time attributes (ctime, atime, mtime) of files/dirs from bricks. The problem with this approach is that, it is not consisteant across replica and distribute bricks. And applications which depend on it breaks as replica might not always return time attributes from same brick.
+
+Tar especially gives "file changed as we read it" whenever it detects ctime differences when stat is served from different bricks. The way we have been trying to solve it is to serve the stat structures from same brick in afr, max-time in dht. But it doesn't avoid the problem completely. Because there is no way to change ctime at the moment(lutimes() only allows mtime, atime), there is little we can do to make sure ctimes match after self-heals/xattr updates/rebalance.
+
+#### Solution Proposed:
+Store time attribues (ctime, mtime, atime) as an xattr of the file. The xattr is updated based
+on the fop. If a filesystem fop changes only mtime and ctime, update only those in xattr for
+that file.
+
+#### Design Overview:
+1) As part of each fop, top layer will generate a time stamp and pass it to the down along
+ with other information
+ - This will bring a dependency for NTP synced clients along with servers
+ - There can be a diff in time if the fop stuck in the xlator for various reason,
+for ex: because of locks.
+
+ 2) On the server, posix layer stores the value in the memory (inode ctx) and will sync the data periodically to the disk as an extended attr
+ - Of course sync call also will force it. And fop comes for an inode which is not linked, we do the sync immediately.
+
+ 3) Each time when inodes are created or initialized it read the data from disk and store in inode ctx.
+
+ 4) Before setting to inode_ctx we compare the timestamp stored and the timestamp received, and only store if the stored value is lesser than the current value.
+
+ 5) So in best case data will be stored and retrieved from the memory. We replace the values in iatt with the values in inode_ctx.
+
+ 6) File ops that changes the parent directory attr time need to be consistent across all the distributed directories across the subvolumes. (for eg: a create call will change ctime and mtime of parent dir)
+
+ - This has to handle separately because we only send the fop to the hashed subvolume.
+ - We can asynchronously send the timeupdate setattr fop to the other subvoumes and change the values for parent directory if the file fops is successful on hashed subvolume.
+ - This will have a window where the times are inconsistent across dht subvolume (Please provide your suggestions)
+
+7) Currently we have couple of mount options for time attributes like noatime, relatime , nodiratime etc. But we are not explicitly handled those options even if it is given as mount option when gluster mount.
+
+
+#### Implementation Overview:
+This features involves changes in following xlators.
+ - utime xlator
+ - posix xlator
+
+##### utime xlator:
+This is a new client side xlator which does following tasks.
+
+1. It will generate a time stamp and passes it down in frame->root->ctime and over the network.
+2. Based on fop, it also decides the time attributes to be updated and this passed using "frame->root->flags"
+
+ Patches:
+ 1. https://review.gluster.org/#/c/19857/
+
+##### posix xlator:
+Following tasks are done in posix xlator:
+
+1. Provides APIs to set and get the xattr from backend. It also caches the xattr in inode context. During get, it updates time attributes stored in xattr into iatt structure.
+2. Based on the flags from utime xlator, relevant fops update the time attributes in the xattr.
+
+ Patches:
+ 1. https://review.gluster.org/#/c/19267/
+ 2. https://review.gluster.org/#/c/19795/
+ 3. https://review.gluster.org/#/c/19796/
+
+#### Pending Work:
+1. Handling of time related mount options (noatime, realatime,etc)
+2. flag based create (depending on flags in open, create behaviour might change)
+3. Changes in dht for direcotory sync acrosss multiple subvolumes
+4. readdirp stat need to be worked on.
diff --git a/doc/features/ganesha-ha.md b/doc/features/ganesha-ha.md
new file mode 100644
index 00000000000..4b226a22ccf
--- /dev/null
+++ b/doc/features/ganesha-ha.md
@@ -0,0 +1,43 @@
+# Overview of Ganesha HA Resource Agents in GlusterFS 3.7
+
+The ganesha_mon RA monitors its ganesha.nfsd daemon. While the
+daemon is running, it creates two attributes: ganesha-active and
+grace-active. When the daemon stops for any reason, the attributes
+are deleted. Deleting the ganesha-active attribute triggers the
+failover of the virtual IP (the IPaddr RA) to another node —
+according to constraint location rules — where ganesha.nfsd is
+still running.
+
+The ganesha_grace RA monitors the grace-active attribute. When
+the grace-active attibute is deleted, the ganesha_grace RA stops,
+and will not restart. This triggers pacemaker to invoke the notify
+action in the ganesha_grace RAs on the other nodes in the cluster;
+which send a DBUS message to their respective ganesha.nfsd.
+
+(N.B. grace-active is a bit of a misnomer. while the grace-active
+attribute exists, everything is normal and healthy. Deleting the
+attribute triggers putting the surviving ganesha.nfsds into GRACE.)
+
+To ensure that the remaining/surviving ganesha.nfsds are put into
+ NFS-GRACE before the IPaddr (virtual IP) fails over there is a
+short delay (sleep) between deleting the grace-active attribute
+and the ganesha-active attribute. To summarize, e.g. in a four
+node cluster:
+
+1. on node 2 ganesha_mon::monitor notices that ganesha.nfsd has died
+
+2. on node 2 ganesha_mon::monitor deletes its grace-active attribute
+
+3. on node 2 ganesha_grace::monitor notices that grace-active is gone
+and returns OCF_ERR_GENERIC, a.k.a. new error. When pacemaker tries
+to (re)start ganesha_grace, its start action will return
+OCF_NOT_RUNNING, a.k.a. known error, don't attempt further restarts.
+
+4. on nodes 1, 3, and 4, ganesha_grace::notify receives a post-stop
+notification indicating that node 2 is gone, and sends a DBUS message
+to its ganesha.nfsd, putting it into NFS-GRACE.
+
+5. on node 2 ganesha_mon::monitor waits a short period, then deletes
+its ganesha-active attribute. This triggers the IPaddr (virt IP)
+failover according to constraint location rules.
+
diff --git a/doc/gluster.8 b/doc/gluster.8
index 358b9aff9b9..ba595edca15 100644
--- a/doc/gluster.8
+++ b/doc/gluster.8
@@ -16,15 +16,14 @@ gluster - Gluster Console Manager (command line utility)
.PP
To run the program and display gluster prompt:
.PP
-.B gluster
+.B gluster [--remote-host=<gluster_node>] [--mode=script] [--xml]
.PP
(or)
.PP
To specify a command directly:
.PP
.B gluster
-.I [commands] [options]
-
+.I [commands] [options] [--remote-host=<gluster_node>] [--mode=script] [--xml]
.SH DESCRIPTION
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
@@ -36,7 +35,13 @@ The Gluster Console Manager is a command line utility for elastic volume managem
\fB\ volume info [all|<VOLNAME>] \fR
Display information about all volumes, or the specified volume.
.TP
-\fB\ volume create <NEW-VOLNAME> [stripe <COUNT>] [replica <COUNT>] [disperse [<COUNT>]] [redundancy <COUNT>] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ... \fR
+\fB\ volume list \fR
+List all volumes in cluster
+.TP
+\fB\ volume status [all | <VOLNAME> [nfs|shd|<BRICK>|quotad]] [detail|clients|mem|inode|fd|callpool|tasks|client-list] \fR
+Display status of all or specified volume(s)/brick
+.TP
+\fB\ volume create <NEW-VOLNAME> [stripe <COUNT>] [[replica <COUNT> [arbiter <COUNT>]]|[replica 2 thin-arbiter 1]] [disperse [<COUNT>]] [disperse-data <COUNT>] [redundancy <COUNT>] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ... <TA-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.
.TP
@@ -52,8 +57,17 @@ Stop the specified volume.
\fB\ volume set <VOLNAME> <OPTION> <PARAMETER> [<OPTION> <PARAMETER>] ... \fR
Set the volume options.
.TP
-\fB\ volume get <VOLNAME> <OPTION/all>\fR
-Get the volume options.
+\fB\ volume get <VOLNAME/all> <OPTION/all> \fR
+Get the value of the all options or given option for volume <VOLNAME> or all option. gluster volume get all all is to get all global options
+.TP
+\fB\ volume reset <VOLNAME> [option] [force] \fR
+Reset all the reconfigured options
+.TP
+\fB\ volume barrier <VOLNAME> {enable|disable} \fR
+Barrier/unbarrier file operations on a volume
+.TP
+\fB\ volume clear-locks <VOLNAME> <path> kind {blocked|granted|all}{inode [range]|entry [basename]|posix [range]} \fR
+Clear locks held on path
.TP
\fB\ volume help \fR
Display help for the volume command.
@@ -71,6 +85,9 @@ If you remove the brick, the data stored in that brick will not be available. Yo
.B replace-brick
option.
.TP
+\fB\ volume reset-brick <VOLNAME> <SOURCE-BRICK> {{start} | {<NEW-BRICK> commit}} \fR
+Brings down or replaces the specified source brick with the new brick.
+.TP
\fB\ volume replace-brick <VOLNAME> <SOURCE-BRICK> <NEW-BRICK> commit force \fR
Replace the specified source brick with a new brick.
.TP
@@ -92,6 +109,18 @@ Locate the log file for corresponding volume/brick.
.TP
\fB\ volume log rotate <VOLNAME> [BRICK] \fB
Rotate the log file for corresponding volume/brick.
+.TP
+\fB\ volume profile <VOLNAME> {start|info [peek|incremental [peek]|cumulative|clear]|stop} [nfs] \fR
+Profile operations on the volume. Once started, volume profile <volname> info provides cumulative statistics of the FOPs performed.
+.TP
+\fB\ volume top <VOLNAME> {open|read|write|opendir|readdir|clear} [nfs|brick <brick>] [list-cnt <value>] | {read-perf|write-perf} [bs <size> count <count>] [brick <brick>] [list-cnt <value>] \fR
+Generates a profile of a volume representing the performance and bottlenecks/hotspots of each brick.
+.TP
+\fB\ volume statedump <VOLNAME> [[nfs|quotad] [all|mem|iobuf|callpool|priv|fd|inode|history]... | [client <hostname:process-id>]] \fR
+Dumps the in memory state of the specified process or the bricks of the volume.
+.TP
+\fB\ volume sync <HOSTNAME> [all|<VOLNAME>] \fR
+Sync the volume information from a peer
.SS "Peer Commands"
.TP
\fB\ peer probe <HOSTNAME> \fR
@@ -103,23 +132,111 @@ Detach the specified peer.
\fB\ peer status \fR
Display the status of peers.
.TP
+\fB\ pool list \fR
+List all the nodes in the pool (including localhost)
+.TP
\fB\ peer help \fR
Display help for the peer command.
+.SS "Quota Commands"
+.TP
+\fB\ volume quota <VOLNAME> enable \fR
+Enable quota on the specified volume. This will cause all the directories in the filesystem hierarchy to be accounted and updated thereafter on each operation in the the filesystem. To kick start this accounting, a crawl is done over the hierarchy with an auxiliary client.
+.TP
+\fB\ volume quota <VOLNAME> disable \fR
+Disable quota on the volume. This will disable enforcement and accounting in the filesystem. Any configured limits will be lost.
+.TP
+\fB\ volume quota <VOLNAME> limit-usage <PATH> <SIZE> [<PERCENT>] \fR
+Set a usage limit on the given path. Any previously set limit is overridden to the new value. The soft limit can optionally be specified (as a percentage of hard limit). If soft limit percentage is not provided the default soft limit value for the volume is used to decide the soft limit.
+.TP
+\fB\ volume quota <VOLNAME> limit-objects <PATH> <SIZE> [<PERCENT>] \fR
+Set an inode limit on the given path. Any previously set limit is overridden to the new value. The soft limit can optionally be specified (as a percentage of hard limit). If soft limit percentage is not provided the default soft limit value for the volume is used to decide the soft limit.
+.TP
+NOTE: valid units of SIZE are : B, KB, MB, GB, TB, PB. If no unit is specified, the unit defaults to bytes.
+.TP
+\fB\ volume quota <VOLNAME> remove <PATH> \fR
+Remove any usage limit configured on the specified directory. Note that if any limit is configured on the ancestors of this directory (previous directories along the path), they will still be honored and enforced.
+.TP
+\fB\ volume quota <VOLNAME> remove-objects <PATH> \fR
+Remove any inode limit configured on the specified directory. Note that if any limit is configured on the ancestors of this directory (previous directories along the path), they will still be honored and enforced.
+.TP
+\fB\ volume quota <VOLNAME> list <PATH> \fR
+Lists the usage and limits configured on directory(s). If a path is given only the limit that has been configured on the directory(if any) is displayed along with the directory's usage. If no path is given, usage and limits are displayed for all directories that has limits configured.
+.TP
+\fB\ volume quota <VOLNAME> list-objects <PATH> \fR
+Lists the inode usage and inode limits configured on directory(s). If a path is given only the limit that has been configured on the directory(if any) is displayed along with the directory's inode usage. If no path is given, usage and limits are displayed for all directories that has limits configured.
+.TP
+\fB\ volume quota <VOLNAME> default-soft-limit <PERCENT> \fR
+Set the percentage value for default soft limit for the volume.
+.TP
+\fB\ volume quota <VOLNAME> soft-timeout <TIME> \fR
+Set the soft timeout for the volume. The interval in which limits are retested before the soft limit is breached.
+.TP
+\fB\ volume quota <VOLNAME> hard-timeout <TIME> \fR
+Set the hard timeout for the volume. The interval in which limits are retested after the soft limit is breached.
+.TP
+\fB\ volume quota <VOLNAME> alert-time <TIME> \fR
+Set the frequency in which warning messages need to be logged (in the brick logs) once soft limit is breached.
+.TP
+\fB\ volume inode-quota <VOLNAME> enable/disable \fR
+Enable/disable inode-quota for <VOLNAME>
+.TP
+\fB\ volume quota help \fR
+Display help for volume quota commands
+.TP
+NOTE: valid units of time and their symbols are : hours(h/hr), minutes(m/min), seconds(s/sec), weeks(w/wk), Days(d/days).
+.SS "Geo-replication Commands"
+.TP
+\fI\ Note\fR: password-less ssh, from the master node (where these commands are executed) to the slave node <SLAVE_HOST>, is a prerequisite for the geo-replication commands.
+.TP
+\fB\ system:: execute gsec_create\fR
+Generates pem keys which are required for push-pem
+.TP
+\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> create [[ssh-port n][[no-verify]|[push-pem]]] [force]\fR
+Create a new geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>.
+Use ssh-port n if custom SSH port is configured in slave nodes.
+Use no-verify if the rsa-keys of nodes in master volume is distributed to slave nodes through an external agent.
+Use push-pem to push the keys automatically.
+.TP
+\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> {start|stop} [force] \fR
+Start/stop the geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>.
+.TP
+\fB\ volume geo-replication [<MASTER_VOL> [<SLAVE_HOST>::<SLAVE_VOL>]] status [detail] \fR
+Query status of the geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>.
+.TP
+\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> {pause|resume} [force] \fR
+Pause/resume the geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>.
+.TP
+\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> delete [reset-sync-time]\fR
+Delete the geo-replication session from <MASTER_VOL> to <SLAVE_HOST> host machine having <SLAVE_VOL>.
+Optionally you can also reset the sync time in case you need to resync the entire volume on session recreate.
+.TP
+\fB\ volume geo-replication <MASTER_VOL> <SLAVE_HOST>::<SLAVE_VOL> config [[!]<options> [<value>]] \fR
+View (when no option provided) or set configuration for this geo-replication session.
+Use "!<OPTION>" to reset option <OPTION> to default value.
.SS "Bitrot Commands"
.TP
\fB\ volume bitrot <VOLNAME> {enable|disable} \fR
Enable/disable bitrot for volume <VOLNAME>
.TP
+\fB\ volume bitrot <VOLNAME> signing-time <time-in-secs> \fR
+Waiting time for an object after last fd is closed to start signing process.
+.TP
+\fB\ volume bitrot <VOLNAME> signer-threads <count> \fR
+Number of signing process threads. Usually set to number of available cores.
+.TP
\fB\ volume bitrot <VOLNAME> scrub-throttle {lazy|normal|aggressive} \fR
Scrub-throttle value is a measure of how fast or slow the scrubber scrubs the filesystem for volume <VOLNAME>
.TP
-\fB\ volume bitrot <VOLNAME> scrub-frequency {daily|weekly|biweekly|monthly} \fR
+\fB\ volume bitrot <VOLNAME> scrub-frequency {hourly|daily|weekly|biweekly|monthly} \fR
Scrub frequency for volume <VOLNAME>
.TP
-\fB\ volume bitrot <VOLNAME> scrub {pause|resume} \fR
-Pause/Resume scrub. Upon resume, scrubber continues where it left off.
+\fB\ volume bitrot <VOLNAME> scrub {pause|resume|status|ondemand} \fR
+Pause/Resume scrub. Upon resume, scrubber continues where it left off. status option shows the statistics of scrubber. ondemand option starts the scrubbing immediately if the scrubber is not paused or already running.
+.TP
+\fB\ volume bitrot help \fR
+Display help for volume bitrot commands
+.TP
.SS "Snapshot Commands"
-.PP
.TP
\fB\ snapshot create <snapname> <volname> [no-timestamp] [description <description>] [force] \fR
Creates a snapshot of a GlusterFS volume. User can provide a snap-name and a description to identify the snap. Snap will be created by appending timestamp in GMT. User can override this behaviour using "no-timestamp" option. The description cannot be more than 1024 characters. To be able to take a snapshot, volume should be present and it should be in started state.
@@ -222,6 +339,9 @@ Selects <HOSTNAME:BRICKNAME> as the source for all the files that are in split-b
Selects the split-brained <FILE> present in <HOSTNAME:BRICKNAME> as source and completes heal.
.SS "Other Commands"
.TP
+\fB\ get-state [<daemon>] [[odir </path/to/output/dir/>] [file <filename>]] [detail|volumeoptions] \fR
+Get local state representation of mentioned daemon and store data in provided path information
+.TP
\fB\ help \fR
Display the command options.
.TP
diff --git a/doc/glusterd.8 b/doc/glusterd.8
index 04a43481eec..e3768c78761 100644
--- a/doc/glusterd.8
+++ b/doc/glusterd.8
@@ -30,6 +30,9 @@ File to use for logging.
\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\-\-localtime\-logging\fR
+Enable localtime log timestamps.
+.TP
\fB\-\-debug\fR
Run the program in debug mode. This option sets \fB\-\-no\-daemon\fR, \fB\-\-log\-level\fR to DEBUG
and \fB\-\-log\-file\fR to console.
diff --git a/doc/glusterfs.8 b/doc/glusterfs.8
index fc28ef68be6..3d359ea85e4 100644
--- a/doc/glusterfs.8
+++ b/doc/glusterfs.8
@@ -53,6 +53,9 @@ Maximum number of connect attempts to server. This option should be provided wit
\fB\-\-acl\fR
Mount the filesystem with POSIX ACL support.
.TP
+\fB\-\-localtime\-logging\fR
+Enable localtime log timestamps.
+.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.
@@ -60,8 +63,8 @@ and \fB\-\-log\-file\fR to console.
\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.
+\fB\-\-fopen\-keep\-cache[=BOOL]\fR
+Do not purge the cache on file open (default: false).
.TP
\fB\-\-mac\-compat=BOOL\fR
Provide stubs for attributes needed for seamless operation on Macs (the default is off).
@@ -98,11 +101,17 @@ 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.
+.TP
+\fB\-\-subdir\-mount=SUBDIR\-MOUNT\-PATH\fR
+Mount subdirectory instead of the '/' of volume.
.SS "Fuse options"
.PP
.TP
+\fB\-\-attr\-times\-granularity=NANOSECONDS\fR
+Declare supported granularity of file attribute times (default is 0 which kernel handles as unspecified; valid real values are between 1 and 1000000000).
+.TP
\fB\-\-attribute\-timeout=SECONDS\fR
Set attribute timeout to SECONDS for inodes in fuse kernel module (the default is 1).
.TP
@@ -112,8 +121,8 @@ Set fuse module's background queue length to N (the default is 64).
\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).
+\fB\-\-direct\-io\-mode=BOOL|auto\fR
+Specify fuse direct I/O strategy (the default is auto).
.TP
\fB\-\-dump-fuse=PATH\f\R
Dump fuse traffic to PATH
@@ -124,9 +133,17 @@ Set entry timeout to SECONDS in fuse kernel module (the default is 1).
\fB\-\-gid\-timeout=SECONDS\fR
Set auxiliary group list timeout to SECONDS for fuse translator (the default is 0).
.TP
+\fB\-\-kernel-writeback-cache=BOOL\fR
+Enable fuse in-kernel writeback cache.
+.TP
\fB\-\-negative\-timeout=SECONDS\fR
Set negative timeout to SECONDS in fuse kernel module (the default is 0).
.TP
+\fB\-\-auto\-invalidation=BOOL\fR
+controls whether fuse-kernel can auto-invalidate attribute, dentry and
+page-cache. Disable this only if same files/directories are not
+accessed across two different mounts concurrently [default: on].
+.TP
\fB\-\-volfile-check\fR
Enable strict volume file checking.
diff --git a/doc/glusterfsd.8 b/doc/glusterfsd.8
index 88b667cb463..bc1de2a8c80 100644
--- a/doc/glusterfsd.8
+++ b/doc/glusterfsd.8
@@ -51,6 +51,9 @@ Server to get the volume from. This option overrides \fB\-\-volfile option
.PP
.TP
+\fB\-\-localtime\-logging\fR
+Enable localtime log timestamps.
+.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
@@ -103,7 +106,12 @@ Set entry timeout to SECONDS in fuse kernel module [default: 1]
Enable/Disable direct-io mode in fuse module [default: enable]
.TP
\fB\-\-resolve-gids\fR
-Resolve all auxilary groups in fuse translator (max 32 otherwise)
+Resolve all auxiliary groups in fuse translator (max 32 otherwise)
+.TP
+\fB\-\-auto\-invalidation=BOOL\fR
+controls whether fuse-kernel can auto-invalidate attribute, dentry and
+page-cache. Disable this only if same files/directories are not
+accessed across two different mounts concurrently [default: on]
.SS "Miscellaneous Options"
.PP
diff --git a/doc/mount.glusterfs.8 b/doc/mount.glusterfs.8
index 32260ced04f..ce16e9e40b7 100644
--- a/doc/mount.glusterfs.8
+++ b/doc/mount.glusterfs.8
@@ -12,11 +12,11 @@
.SH NAME
.B mount.glusterfs - script to mount native GlusterFS volume
.SH SYNOPSIS
-.B mount -t glusterfs [-o <options>] <volumeserver>:/<volume>
+.B mount -t glusterfs [-o <options>] <volumeserver>:/<volume>[/<subdir>]
.B <mountpoint>
.TP
.B mount -t glusterfs [-o <options>] <server1>,<server2>,
-.B <server3>,..<serverN>:/<volname> <mount_point>
+.B <server3>,..<serverN>:/<volname>[/<subdir>] <mount_point>
.TP
.TP
.B mount -t glusterfs [-o <options>] <path/to/volumefile> <mountpoint>
@@ -44,11 +44,8 @@ INFO and NONE [default: INFO]
\fBacl
Mount the filesystem with POSIX ACL support
.TP
-\fBfopen\-keep\-cache
-Do not purge the cache on file open
-.TP
-\fBselinux
-Enable SELinux label (extened attributes) support on inodes
+\fBfopen\-keep\-cache[=BOOL]
+Do not purge the cache on file open (default: false)
.TP
\fBworm
Mount the filesystem in 'worm' mode
@@ -65,6 +62,12 @@ support 64-bit inodes
.TP
\fBmem\-accounting
Enable internal memory accounting
+.TP
+\fBcapability
+Enable file capability setting and retrival
+.TP
+\fBthin-client
+Enables thin mount and connects via gfproxyd daemon
.PP
.SS "Advanced options"
@@ -80,7 +83,7 @@ Set entry timeout to SECONDS in fuse kernel module [default: 1]
Set fuse module's background queue length to N [default: 64]
.TP
\fBgid\-timeout=\fRSECONDS
-Set auxilary group list timeout to SECONDS for fuse translator [default: 0]
+Set auxiliary group list timeout to SECONDS for fuse translator [default: 0]
.TP
\fBnegative\-timeout=\fRSECONDS
Set negative timeout to SECONDS in fuse kernel module [default: 0]
@@ -89,17 +92,20 @@ Set negative timeout to SECONDS in fuse kernel module [default: 0]
Volume name to be used for MOUNT-POINT [default: top most volume in
VOLUME-FILE]
.TP
-\fBdirect\-io\-mode=\fRdisable
-Disable direct I/O mode in fuse kernel module
+\fBdirect\-io\-mode=\fRBOOL|auto
+Specify fuse direct I/O strategy [default: auto]
.TP
\fBcongestion\-threshold=\fRN
Set fuse module's congestion threshold to N [default: 48]
.TP
+\fsubdir\-mount=\fRN
+Set the subdirectory mount option [default: NULL, ie, no subdirectory mount]
+.TP
.TP
\fBbackup\-volfile\-servers=\fRSERVERLIST
Provide list of backup volfile servers in the following format [default: None]
-\fB$ mount -t glusterfs -obackup-volfile-servers=<server2>:\fR
+\fB$ mount \-t glusterfs \-obackup\-volfile\-servers=<server2>:\fR
\fB <server3>:...:<serverN> <server1>:/<volname> <mount_point>\fR
.TP
@@ -107,7 +113,7 @@ Provide list of backup volfile servers in the following format [default: None]
\fBbackupvolfile\-server=\fRSERVER
Provide list of backup volfile servers in the following format [default: None]
-\fB $ mount -t glusterfs -obackupvolfile-server=<server2>
+\fB $ mount \-t glusterfs \-obackupvolfile\-server=<server2>
\fB <server1>:/<volname> <mount_point>
.TP
@@ -116,6 +122,15 @@ Provide list of backup volfile servers in the following format [default: None]
\fBDeprecated\fR option - placed here for backward compatibility [default: 1]
.TP
.TP
+\fBlru-limit=\fRN
+Set fuse module's limit for number of inodes kept in LRU list to N [default: 65536]
+.TP
+.TP
+\fBinvalidate-limit=\fRN
+Suspend fuse invalidations implied by 'lru-limit' if number of outstanding
+invalidations reaches N
+.TP
+.TP
\fBbackground-qlen=\fRN
Set fuse module's background queue length to N [default: 64]
.TP
@@ -127,13 +142,27 @@ enable root squashing for the trusted client [default: on]
.TP
\fBuse\-readdirp=\fRBOOL
Use readdirp() mode in fuse kernel module [default: on]
+.TP
+\fBdump\-fuse=\fRPATH
+Dump fuse traffic to PATH
+.TP
+\fBkernel\-writeback\-cache=\fRBOOL
+Enable fuse in-kernel writeback cache [default: off]
+.TP
+\fBattr\-times\-granularity=\fRNS
+Declare supported granularity of file attribute [default: 0]
+.TP
+\fBauto\-invalidation=\fRBOOL
+controls whether fuse-kernel can auto-invalidate attribute, dentry and
+page-cache. Disable this only if same files/directories are not
+accessed across two different mounts concurrently [default: on]
.PP
.SH FILES
.TP
.I /etc/fstab
A typical GlusterFS entry in /etc/fstab looks like below
-\fBserver1:/mirror /mnt/mirror glusterfs log-file=/var/log/mirror.log,acl,selinux 0 0\fR
+\fBserver1:/mirror /mnt/mirror glusterfs log-file=/var/log/mirror.log,acl 0 0\fR
.TP
.I /proc/mounts
diff --git a/events/Makefile.am b/events/Makefile.am
new file mode 100644
index 00000000000..264bb742a80
--- /dev/null
+++ b/events/Makefile.am
@@ -0,0 +1,8 @@
+SUBDIRS = src tools
+EXTRA_DIST = eventskeygen.py
+noinst_PYTHON = eventskeygen.py
+
+if BUILD_EVENTS
+install-data-hook:
+ $(INSTALL) -d -m 755 $(DESTDIR)@GLUSTERD_WORKDIR@/events
+endif
diff --git a/events/eventskeygen.py b/events/eventskeygen.py
new file mode 100644
index 00000000000..e28ebe9b7e6
--- /dev/null
+++ b/events/eventskeygen.py
@@ -0,0 +1,243 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+import os
+import sys
+
+GLUSTER_SRC_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+eventtypes_h = os.path.join(GLUSTER_SRC_ROOT, "libglusterfs/src/eventtypes.h")
+eventtypes_py = os.path.join(GLUSTER_SRC_ROOT, "events/src/eventtypes.py")
+
+gen_header_type = sys.argv[1]
+
+# When adding new keys add it to the END
+keys = (
+ # user driven events
+ #peer and volume management events
+ "EVENT_PEER_ATTACH",
+ "EVENT_PEER_DETACH",
+ "EVENT_VOLUME_CREATE",
+ "EVENT_VOLUME_START",
+ "EVENT_VOLUME_STOP",
+ "EVENT_VOLUME_DELETE",
+ "EVENT_VOLUME_SET",
+ "EVENT_VOLUME_RESET",
+ "EVENT_BRICK_RESET_START",
+ "EVENT_BRICK_RESET_COMMIT",
+ "EVENT_BRICK_REPLACE",
+
+ #geo-rep events
+ "EVENT_GEOREP_CREATE",
+ "EVENT_GEOREP_START",
+ "EVENT_GEOREP_STOP",
+ "EVENT_GEOREP_PAUSE",
+ "EVENT_GEOREP_RESUME",
+ "EVENT_GEOREP_DELETE",
+ "EVENT_GEOREP_CONFIG_SET",
+ "EVENT_GEOREP_CONFIG_RESET",
+
+ #bitrot events
+ "EVENT_BITROT_ENABLE",
+ "EVENT_BITROT_DISABLE",
+ "EVENT_BITROT_SCRUB_THROTTLE",
+ "EVENT_BITROT_SCRUB_FREQ",
+ "EVENT_BITROT_SCRUB_OPTION",
+ "EVENT_BITROT_SCRUB_ONDEMAND",
+
+ #quota events
+ "EVENT_QUOTA_ENABLE",
+ "EVENT_QUOTA_DISABLE",
+ "EVENT_QUOTA_SET_USAGE_LIMIT",
+ "EVENT_QUOTA_SET_OBJECTS_LIMIT",
+ "EVENT_QUOTA_REMOVE_USAGE_LIMIT",
+ "EVENT_QUOTA_REMOVE_OBJECTS_LIMIT",
+ "EVENT_QUOTA_ALERT_TIME",
+ "EVENT_QUOTA_SOFT_TIMEOUT",
+ "EVENT_QUOTA_HARD_TIMEOUT",
+ "EVENT_QUOTA_DEFAULT_SOFT_LIMIT",
+
+ #snapshot events
+ "EVENT_SNAPSHOT_CREATED",
+ "EVENT_SNAPSHOT_CREATE_FAILED",
+ "EVENT_SNAPSHOT_ACTIVATED",
+ "EVENT_SNAPSHOT_ACTIVATE_FAILED",
+ "EVENT_SNAPSHOT_DEACTIVATED",
+ "EVENT_SNAPSHOT_DEACTIVATE_FAILED",
+ "EVENT_SNAPSHOT_SOFT_LIMIT_REACHED",
+ "EVENT_SNAPSHOT_HARD_LIMIT_REACHED",
+ "EVENT_SNAPSHOT_RESTORED",
+ "EVENT_SNAPSHOT_RESTORE_FAILED",
+ "EVENT_SNAPSHOT_DELETED",
+ "EVENT_SNAPSHOT_DELETE_FAILED",
+ "EVENT_SNAPSHOT_CLONED",
+ "EVENT_SNAPSHOT_CLONE_FAILED",
+ "EVENT_SNAPSHOT_CONFIG_UPDATED",
+ "EVENT_SNAPSHOT_CONFIG_UPDATE_FAILED",
+ "EVENT_SNAPSHOT_SCHEDULER_INITIALISED",
+ "EVENT_SNAPSHOT_SCHEDULER_INIT_FAILED",
+ "EVENT_SNAPSHOT_SCHEDULER_ENABLED",
+ "EVENT_SNAPSHOT_SCHEDULER_ENABLE_FAILED",
+ "EVENT_SNAPSHOT_SCHEDULER_DISABLED",
+ "EVENT_SNAPSHOT_SCHEDULER_DISABLE_FAILED",
+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADDED",
+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADD_FAILED",
+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDITED",
+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDIT_FAILED",
+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETED",
+ "EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETE_FAILED",
+
+ #async events
+ #glusterd events
+ "EVENT_SVC_MANAGER_FAILED",
+ "EVENT_SVC_RECONFIGURE_FAILED",
+ "EVENT_SVC_CONNECTED",
+ "EVENT_SVC_DISCONNECTED",
+ "EVENT_PEER_STORE_FAILURE",
+ "EVENT_PEER_RPC_CREATE_FAILED",
+ "EVENT_PEER_REJECT",
+ "EVENT_PEER_CONNECT",
+ "EVENT_PEER_DISCONNECT",
+ "EVENT_PEER_NOT_FOUND",
+ "EVENT_UNKNOWN_PEER",
+ "EVENT_BRICK_START_FAILED",
+ "EVENT_BRICK_STOP_FAILED",
+ "EVENT_BRICK_DISCONNECTED",
+ "EVENT_BRICK_CONNECTED",
+ "EVENT_BRICKPATH_RESOLVE_FAILED",
+ "EVENT_NOTIFY_UNKNOWN_OP",
+ "EVENT_QUORUM_LOST",
+ "EVENT_QUORUM_REGAINED",
+ "EVENT_REBALANCE_START_FAILED",
+ "EVENT_REBALANCE_STATUS_UPDATE_FAILED",
+ "EVENT_IMPORT_QUOTA_CONF_FAILED",
+ "EVENT_IMPORT_VOLUME_FAILED",
+ "EVENT_IMPORT_BRICK_FAILED",
+ "EVENT_COMPARE_FRIEND_VOLUME_FAILED",
+ "EVENT_NFS_GANESHA_EXPORT_FAILED",
+ #ec events
+ "EVENT_EC_MIN_BRICKS_NOT_UP",
+ "EVENT_EC_MIN_BRICKS_UP",
+ #georep async events
+ "EVENT_GEOREP_FAULTY",
+ "EVENT_GEOREP_CHECKPOINT_COMPLETED",
+ "EVENT_GEOREP_ACTIVE",
+ "EVENT_GEOREP_PASSIVE",
+
+ #quota async events
+ "EVENT_QUOTA_CROSSED_SOFT_LIMIT",
+ #bitrot async events
+ "EVENT_BITROT_BAD_FILE",
+ #protocol-server events
+ "EVENT_CLIENT_CONNECT",
+ "EVENT_CLIENT_AUTH_REJECT",
+ "EVENT_CLIENT_DISCONNECT",
+ #posix events
+ "EVENT_POSIX_SAME_GFID",
+ "EVENT_POSIX_ALREADY_PART_OF_VOLUME",
+ "EVENT_POSIX_BRICK_NOT_IN_VOLUME",
+ "EVENT_POSIX_BRICK_VERIFICATION_FAILED",
+ "EVENT_POSIX_ACL_NOT_SUPPORTED",
+ "EVENT_POSIX_HEALTH_CHECK_FAILED",
+ #afr events
+ "EVENT_AFR_QUORUM_MET",
+ "EVENT_AFR_QUORUM_FAIL",
+ "EVENT_AFR_SUBVOL_UP",
+ "EVENT_AFR_SUBVOLS_DOWN",
+ "EVENT_AFR_SPLIT_BRAIN",
+
+ #tier events
+ "EVENT_TIER_ATTACH",
+ "EVENT_TIER_ATTACH_FORCE",
+ "EVENT_TIER_DETACH_START",
+ "EVENT_TIER_DETACH_STOP",
+ "EVENT_TIER_DETACH_COMMIT",
+ "EVENT_TIER_DETACH_FORCE",
+ "EVENT_TIER_PAUSE",
+ "EVENT_TIER_RESUME",
+ "EVENT_TIER_WATERMARK_HI",
+ "EVENT_TIER_WATERMARK_DROPPED_TO_MID",
+ "EVENT_TIER_WATERMARK_RAISED_TO_MID",
+ "EVENT_TIER_WATERMARK_DROPPED_TO_LOW",
+
+ #dht events
+ #add/remove brick events
+ "EVENT_VOLUME_ADD_BRICK",
+ "EVENT_VOLUME_ADD_BRICK_FAILED",
+ "EVENT_VOLUME_REMOVE_BRICK_START",
+ "EVENT_VOLUME_REMOVE_BRICK_START_FAILED",
+ "EVENT_VOLUME_REMOVE_BRICK_COMMIT",
+ "EVENT_VOLUME_REMOVE_BRICK_COMMIT_FAILED",
+ "EVENT_VOLUME_REMOVE_BRICK_STOP",
+ "EVENT_VOLUME_REMOVE_BRICK_STOP_FAILED",
+ "EVENT_VOLUME_REMOVE_BRICK_FORCE",
+ "EVENT_VOLUME_REMOVE_BRICK_FORCE_FAILED",
+ "EVENT_VOLUME_REMOVE_BRICK_FAILED",
+
+ #rebalance events
+ "EVENT_VOLUME_REBALANCE_START",
+ "EVENT_VOLUME_REBALANCE_STOP",
+ "EVENT_VOLUME_REBALANCE_FAILED",
+ "EVENT_VOLUME_REBALANCE_COMPLETE",
+
+ #tier events
+ "EVENT_TIER_START",
+ "EVENT_TIER_START_FORCE",
+
+ #brick/inodes events
+ "EVENT_DHT_DISK_USAGE",
+ "EVENT_DHT_INODES_USAGE",
+)
+
+LAST_EVENT = "EVENT_LAST"
+
+ERRORS = (
+ "EVENT_SEND_OK",
+ "EVENT_ERROR_INVALID_INPUTS",
+ "EVENT_ERROR_SOCKET",
+ "EVENT_ERROR_CONNECT",
+ "EVENT_ERROR_SEND",
+ "EVENT_ERROR_RESOLVE",
+ "EVENT_ERROR_MSG_FORMAT",
+)
+
+if gen_header_type == "C_HEADER":
+ # Generate eventtypes.h
+ with open(eventtypes_h, "w") as f:
+ f.write("#ifndef __EVENTTYPES_H__\n")
+ f.write("#define __EVENTTYPES_H__\n\n")
+ f.write("typedef enum {\n")
+ for k in ERRORS:
+ f.write(" {0},\n".format(k))
+ f.write("} event_errors_t;\n")
+
+ f.write("\n")
+
+ f.write("typedef enum {\n")
+ for k in keys:
+ f.write(" {0},\n".format(k))
+
+ f.write(" {0}\n".format(LAST_EVENT))
+ f.write("} eventtypes_t;\n")
+ f.write("\n#endif /* __EVENTTYPES_H__ */\n")
+
+if gen_header_type == "PY_HEADER":
+ # Generate eventtypes.py
+ with open(eventtypes_py, "w") as f:
+ f.write("# -*- coding: utf-8 -*-\n")
+ f.write("all_events = [\n")
+ for ev in keys:
+ f.write(' "{0}",\n'.format(ev))
+
+ f.write("]\n\n")
+
+ for idx, ev in enumerate(keys):
+ f.write("{0} = {1}\n".format(ev.replace("EVENT_", ""), idx))
diff --git a/events/src/Makefile.am b/events/src/Makefile.am
new file mode 100644
index 00000000000..3b229691897
--- /dev/null
+++ b/events/src/Makefile.am
@@ -0,0 +1,41 @@
+noinst_PYTHON = $(top_srcdir)/events/eventskeygen.py
+EXTRA_DIST = glustereventsd.py __init__.py eventsapiconf.py.in \
+ handlers.py utils.py peer_eventsapi.py eventsconfig.json gf_event.py
+
+BUILT_SOURCES = eventtypes.py
+CLEANFILES = eventtypes.py
+
+eventsdir = $(GLUSTERFS_LIBEXECDIR)/gfevents
+if BUILD_EVENTS
+events_PYTHON = __init__.py gf_event.py eventsapiconf.py eventtypes.py \
+ utils.py
+endif
+# this does not work, see the Makefile.am in the root for a workaround
+#nodist_events_PYTHON = eventtypes.py
+
+eventtypes.py: $(top_srcdir)/events/eventskeygen.py
+ $(PYTHON) $(top_srcdir)/events/eventskeygen.py PY_HEADER
+
+if BUILD_EVENTS
+eventspeerscriptdir = $(GLUSTERFS_LIBEXECDIR)
+eventsconfdir = $(sysconfdir)/glusterfs
+eventsconf_DATA = eventsconfig.json
+
+events_PYTHON += handlers.py
+events_SCRIPTS = glustereventsd.py
+eventspeerscript_SCRIPTS = peer_eventsapi.py
+
+install-exec-hook:
+ $(mkdir_p) $(DESTDIR)$(sbindir)
+ rm -f $(DESTDIR)$(sbindir)/glustereventsd
+ ln -s $(GLUSTERFS_LIBEXECDIR)/gfevents/glustereventsd.py \
+ $(DESTDIR)$(sbindir)/glustereventsd
+ rm -f $(DESTDIR)$(sbindir)/gluster-eventsapi
+ ln -s $(GLUSTERFS_LIBEXECDIR)/peer_eventsapi.py \
+ $(DESTDIR)$(sbindir)/gluster-eventsapi
+
+uninstall-hook:
+ rm -f $(DESTDIR)$(sbindir)/glustereventsd
+ rm -f $(DESTDIR)$(sbindir)/gluster-eventsapi
+
+endif
diff --git a/events/src/__init__.py b/events/src/__init__.py
new file mode 100644
index 00000000000..f27c53a4df4
--- /dev/null
+++ b/events/src/__init__.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
diff --git a/events/src/eventsapiconf.py.in b/events/src/eventsapiconf.py.in
new file mode 100644
index 00000000000..700093bee60
--- /dev/null
+++ b/events/src/eventsapiconf.py.in
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+import subprocess
+glusterd_workdir = None
+
+# Methods
+def get_glusterd_workdir():
+ global glusterd_workdir
+ if glusterd_workdir is not None:
+ return glusterd_workdir
+ proc = subprocess.Popen(["gluster", "system::", "getwd"],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ universal_newlines = True)
+ out, err = proc.communicate()
+ if proc.returncode == 0:
+ glusterd_workdir = out.strip()
+ else:
+ glusterd_workdir = "@GLUSTERD_WORKDIR@"
+ return glusterd_workdir
+
+SERVER_ADDRESS = "0.0.0.0"
+SERVER_ADDRESSv4 = "0.0.0.0"
+SERVER_ADDRESSv6 = "::1"
+DEFAULT_CONFIG_FILE = "@SYSCONF_DIR@/glusterfs/eventsconfig.json"
+CUSTOM_CONFIG_FILE_TO_SYNC = "/events/config.json"
+CUSTOM_CONFIG_FILE = get_glusterd_workdir() + CUSTOM_CONFIG_FILE_TO_SYNC
+WEBHOOKS_FILE_TO_SYNC = "/events/webhooks.json"
+WEBHOOKS_FILE = get_glusterd_workdir() + WEBHOOKS_FILE_TO_SYNC
+LOG_FILE = "@localstatedir@/log/glusterfs/events.log"
+EVENTSD = "glustereventsd"
+CONFIG_KEYS = ["log-level", "port", "disable-events-log"]
+BOOL_CONFIGS = ["disable-events-log"]
+INT_CONFIGS = ["port"]
+RESTART_CONFIGS = ["port"]
+EVENTS_ENABLED = @EVENTS_ENABLED@
+UUID_FILE = get_glusterd_workdir() + "/glusterd.info"
+PID_FILE = "@localstatedir@/run/glustereventsd.pid"
+AUTO_BOOL_ATTRIBUTES = ["force", "push-pem", "no-verify"]
+AUTO_INT_ATTRIBUTES = ["ssh-port"]
+CERTS_DIR = get_glusterd_workdir() + "/events"
+
+# Errors
+ERROR_SAME_CONFIG = 2
+ERROR_ALL_NODES_STATUS_NOT_OK = 3
+ERROR_PARTIAL_SUCCESS = 4
+ERROR_WEBHOOK_ALREADY_EXISTS = 5
+ERROR_WEBHOOK_NOT_EXISTS = 6
+ERROR_INVALID_CONFIG = 7
+ERROR_WEBHOOK_SYNC_FAILED = 8
+ERROR_CONFIG_SYNC_FAILED = 9
diff --git a/events/src/eventsconfig.json b/events/src/eventsconfig.json
new file mode 100644
index 00000000000..89e5b9c1d68
--- /dev/null
+++ b/events/src/eventsconfig.json
@@ -0,0 +1,5 @@
+{
+ "log-level": "INFO",
+ "port": 24009,
+ "disable-events-log": false
+}
diff --git a/events/src/gf_event.py b/events/src/gf_event.py
new file mode 100644
index 00000000000..260b0d9aa48
--- /dev/null
+++ b/events/src/gf_event.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+import socket
+import time
+
+from gfevents.eventsapiconf import SERVER_ADDRESS, EVENTS_ENABLED
+from gfevents.eventtypes import all_events
+
+from gfevents.utils import logger, setup_logger, get_config
+
+# Run this when this lib loads
+setup_logger()
+
+
+def gf_event(event_type, **kwargs):
+ if EVENTS_ENABLED == 0:
+ return
+
+ if not isinstance(event_type, int) or event_type >= len(all_events):
+ logger.error("Invalid Event Type: {0}".format(event_type))
+ return
+
+ try:
+ client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ except socket.error as e:
+ logger.error("Unable to connect to events Server: {0}".format(e))
+ return
+
+ port = get_config("port")
+ if port is None:
+ logger.error("Unable to get eventsd port details")
+ return
+
+ # Convert key value args into KEY1=VALUE1;KEY2=VALUE2;..
+ msg = ""
+ for k, v in kwargs.items():
+ msg += "{0}={1};".format(k, v)
+
+ # <TIMESTAMP> <EVENT_TYPE> <MSG>
+ msg = "{0} {1} {2}".format(int(time.time()), event_type, msg.strip(";")).encode()
+
+ try:
+ sent = client.sendto(msg, (SERVER_ADDRESS, port))
+ assert sent == len(msg)
+ except socket.error as e:
+ logger.error("Unable to Send message: {0}".format(e))
+ except AssertionError:
+ logger.error("Unable to send message. Sent: {0}, Actual: {1}".format(
+ sent, len(msg)))
+ finally:
+ client.close()
diff --git a/events/src/glustereventsd.py b/events/src/glustereventsd.py
new file mode 100644
index 00000000000..341a3b60947
--- /dev/null
+++ b/events/src/glustereventsd.py
@@ -0,0 +1,159 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+from __future__ import print_function
+import sys
+import signal
+import threading
+try:
+ import socketserver
+except ImportError:
+ import SocketServer as socketserver
+import socket
+from argparse import ArgumentParser, RawDescriptionHelpFormatter
+
+from eventtypes import all_events
+import handlers
+import utils
+from eventsapiconf import SERVER_ADDRESSv4, SERVER_ADDRESSv6, PID_FILE
+from eventsapiconf import AUTO_BOOL_ATTRIBUTES, AUTO_INT_ATTRIBUTES
+from utils import logger, PidFile, PidFileLockFailed, boolify
+
+# Subclass so that specifically IPv4 packets are captured
+class UDPServerv4(socketserver.ThreadingUDPServer):
+ address_family = socket.AF_INET
+
+# Subclass so that specifically IPv6 packets are captured
+class UDPServerv6(socketserver.ThreadingUDPServer):
+ address_family = socket.AF_INET6
+
+class GlusterEventsRequestHandler(socketserver.BaseRequestHandler):
+
+ def handle(self):
+ data = self.request[0].strip()
+ if sys.version_info >= (3,):
+ data = self.request[0].strip().decode("utf-8")
+
+ logger.debug("EVENT: {0} from {1}".format(repr(data),
+ self.client_address[0]))
+ try:
+ # Event Format <TIMESTAMP> <TYPE> <DETAIL>
+ ts, key, value = data.split(" ", 2)
+ except ValueError:
+ logger.warn("Invalid Event Format {0}".format(data))
+ return
+
+ data_dict = {}
+ try:
+ # Format key=value;key=value
+ data_dict = dict(x.split('=') for x in value.split(';'))
+ except ValueError:
+ logger.warn("Unable to parse Event {0}".format(data))
+ return
+
+ for k, v in data_dict.items():
+ try:
+ if k in AUTO_BOOL_ATTRIBUTES:
+ data_dict[k] = boolify(v)
+ if k in AUTO_INT_ATTRIBUTES:
+ data_dict[k] = int(v)
+ except ValueError:
+ # Auto Conversion failed, Retain the old value
+ continue
+
+ try:
+ # Event Type to Function Map, Received event data will be in
+ # the form <TIMESTAMP> <TYPE> <DETAIL>, Get Event name for the
+ # received Type/Key and construct a function name starting with
+ # handle_ For example: handle_event_volume_create
+ func_name = "handle_" + all_events[int(key)].lower()
+ except IndexError:
+ # This type of Event is not handled?
+ logger.warn("Unhandled Event: {0}".format(key))
+ func_name = None
+
+ if func_name is not None:
+ # Get function from handlers module
+ func = getattr(handlers, func_name, None)
+ # If func is None, then handler unimplemented for that event.
+ if func is not None:
+ func(ts, int(key), data_dict)
+ else:
+ # Generic handler, broadcast whatever received
+ handlers.generic_handler(ts, int(key), data_dict)
+
+
+def signal_handler_sigusr2(sig, frame):
+ utils.load_all()
+ utils.restart_webhook_pool()
+
+
+def UDP_server_thread(sock):
+ sock.serve_forever()
+
+
+def init_event_server():
+ utils.setup_logger()
+ utils.load_all()
+ utils.init_webhook_pool()
+
+ port = utils.get_config("port")
+ if port is None:
+ sys.stderr.write("Unable to get Port details from Config\n")
+ sys.exit(1)
+
+ # Creating the Eventing Server, UDP Server for IPv4 packets
+ try:
+ serverv4 = UDPServerv4((SERVER_ADDRESSv4, port),
+ GlusterEventsRequestHandler)
+ except socket.error as e:
+ sys.stderr.write("Failed to start Eventsd for IPv4: {0}\n".format(e))
+ sys.exit(1)
+ # Creating the Eventing Server, UDP Server for IPv6 packets
+ try:
+ serverv6 = UDPServerv6((SERVER_ADDRESSv6, port),
+ GlusterEventsRequestHandler)
+ except socket.error as e:
+ sys.stderr.write("Failed to start Eventsd for IPv6: {0}\n".format(e))
+ sys.exit(1)
+ server_thread1 = threading.Thread(target=UDP_server_thread,
+ args=(serverv4,))
+ server_thread2 = threading.Thread(target=UDP_server_thread,
+ args=(serverv6,))
+ server_thread1.start()
+ server_thread2.start()
+
+
+def get_args():
+ parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter,
+ description=__doc__)
+ parser.add_argument("-p", "--pid-file", help="PID File",
+ default=PID_FILE)
+
+ return parser.parse_args()
+
+
+def main():
+ args = get_args()
+ try:
+ with PidFile(args.pid_file):
+ init_event_server()
+ except PidFileLockFailed as e:
+ sys.stderr.write("Failed to get lock for pid file({0}): {1}".format(
+ args.pid_file, e))
+ except KeyboardInterrupt:
+ sys.exit(1)
+
+
+if __name__ == "__main__":
+ signal.signal(signal.SIGUSR2, signal_handler_sigusr2)
+ main()
diff --git a/events/src/handlers.py b/events/src/handlers.py
new file mode 100644
index 00000000000..7746d488bf3
--- /dev/null
+++ b/events/src/handlers.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+import utils
+
+
+def generic_handler(ts, key, data):
+ """
+ Generic handler to broadcast message to all peers, custom handlers
+ can be created by func name handler_<event_name>
+ Ex: handle_event_volume_create(ts, key, data)
+ """
+ utils.publish(ts, key, data)
+
+
+def handle_event_volume_set(ts, key, data):
+ """
+ Received data will have all the options as one string, split into
+ list of options. "key1,value1,key2,value2" into
+ [[key1, value1], [key2, value2]]
+ """
+ opts = data.get("options", "").strip(",").split(",")
+ data["options"] = []
+ for i, opt in enumerate(opts):
+ if i % 2 == 0:
+ # Add new array with key
+ data["options"].append([opt])
+ else:
+ # Add to the last added array
+ data["options"][-1].append(opt)
+
+ utils.publish(ts, key, data)
diff --git a/events/src/peer_eventsapi.py b/events/src/peer_eventsapi.py
new file mode 100644
index 00000000000..4d2e5f35b1c
--- /dev/null
+++ b/events/src/peer_eventsapi.py
@@ -0,0 +1,669 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+from __future__ import print_function
+import os
+import json
+from errno import EEXIST
+import fcntl
+from errno import EACCES, EAGAIN
+import signal
+import sys
+import time
+
+import requests
+from prettytable import PrettyTable
+
+from gluster.cliutils import (Cmd, node_output_ok, node_output_notok,
+ sync_file_to_peers, GlusterCmdException,
+ output_error, execute_in_peers, runcli,
+ set_common_args_func)
+from gfevents.utils import LockedOpen, get_jwt_token, save_https_cert
+
+from gfevents.eventsapiconf import (WEBHOOKS_FILE_TO_SYNC,
+ WEBHOOKS_FILE,
+ DEFAULT_CONFIG_FILE,
+ CUSTOM_CONFIG_FILE,
+ CUSTOM_CONFIG_FILE_TO_SYNC,
+ EVENTSD,
+ CONFIG_KEYS,
+ BOOL_CONFIGS,
+ INT_CONFIGS,
+ PID_FILE,
+ RESTART_CONFIGS,
+ ERROR_INVALID_CONFIG,
+ ERROR_WEBHOOK_NOT_EXISTS,
+ ERROR_CONFIG_SYNC_FAILED,
+ ERROR_WEBHOOK_ALREADY_EXISTS,
+ ERROR_PARTIAL_SUCCESS,
+ ERROR_ALL_NODES_STATUS_NOT_OK,
+ ERROR_SAME_CONFIG,
+ ERROR_WEBHOOK_SYNC_FAILED,
+ CERTS_DIR)
+
+
+def handle_output_error(err, errcode=1, json_output=False):
+ if json_output:
+ print (json.dumps({
+ "output": "",
+ "error": err
+ }))
+ sys.exit(errcode)
+ else:
+ output_error(err, errcode)
+
+
+def file_content_overwrite(fname, data):
+ with open(fname + ".tmp", "w") as f:
+ f.write(json.dumps(data))
+
+ os.rename(fname + ".tmp", fname)
+
+
+def create_custom_config_file_if_not_exists(args):
+ try:
+ config_dir = os.path.dirname(CUSTOM_CONFIG_FILE)
+ mkdirp(config_dir)
+ except OSError as e:
+ handle_output_error("Failed to create dir %s: %s" % (config_dir, e),
+ json_output=args.json)
+
+ if not os.path.exists(CUSTOM_CONFIG_FILE):
+ with open(CUSTOM_CONFIG_FILE, "w") as f:
+ f.write("{}")
+
+
+def create_webhooks_file_if_not_exists(args):
+ try:
+ webhooks_dir = os.path.dirname(WEBHOOKS_FILE)
+ mkdirp(webhooks_dir)
+ except OSError as e:
+ handle_output_error("Failed to create dir %s: %s" % (webhooks_dir, e),
+ json_output=args.json)
+
+ if not os.path.exists(WEBHOOKS_FILE):
+ with open(WEBHOOKS_FILE, "w") as f:
+ f.write("{}")
+
+
+def boolify(value):
+ val = False
+ if value.lower() in ["enabled", "true", "on", "yes"]:
+ val = True
+ return val
+
+
+def mkdirp(path, exit_on_err=False, logger=None):
+ """
+ Try creating required directory structure
+ ignore EEXIST and raise exception for rest of the errors.
+ Print error in stderr and exit
+ """
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if e.errno != EEXIST or not os.path.isdir(path):
+ raise
+
+
+def is_active():
+ state = False
+ try:
+ with open(PID_FILE, "a+") as f:
+ fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
+ state = False
+ except (IOError, OSError) as e:
+ if e.errno in (EACCES, EAGAIN):
+ # cannot grab. so, process still running..move on
+ state = True
+ else:
+ state = False
+ return state
+
+
+def reload_service():
+ pid = None
+ if is_active():
+ with open(PID_FILE) as f:
+ try:
+ pid = int(f.read().strip())
+ except ValueError:
+ pid = None
+ if pid is not None:
+ os.kill(pid, signal.SIGUSR2)
+
+ return (0, "", "")
+
+
+def rows_to_json(json_out, column_name, rows):
+ num_ok_rows = 0
+ for row in rows:
+ num_ok_rows += 1 if row.ok else 0
+ json_out.append({
+ "node": row.hostname,
+ "node_status": "UP" if row.node_up else "DOWN",
+ column_name: "OK" if row.ok else "NOT OK",
+ "error": row.error
+ })
+ return num_ok_rows
+
+
+def rows_to_table(table, rows):
+ num_ok_rows = 0
+ for row in rows:
+ num_ok_rows += 1 if row.ok else 0
+ table.add_row([row.hostname,
+ "UP" if row.node_up else "DOWN",
+ "OK" if row.ok else "NOT OK: {0}".format(
+ row.error)])
+ return num_ok_rows
+
+
+def sync_to_peers(args):
+ if os.path.exists(WEBHOOKS_FILE):
+ try:
+ sync_file_to_peers(WEBHOOKS_FILE_TO_SYNC)
+ except GlusterCmdException as e:
+ # Print stdout if stderr is empty
+ errmsg = e.message[2] if e.message[2] else e.message[1]
+ handle_output_error("Failed to sync Webhooks file: [Error: {0}]"
+ "{1}".format(e.message[0], errmsg),
+ errcode=ERROR_WEBHOOK_SYNC_FAILED,
+ json_output=args.json)
+
+ if os.path.exists(CUSTOM_CONFIG_FILE):
+ try:
+ sync_file_to_peers(CUSTOM_CONFIG_FILE_TO_SYNC)
+ except GlusterCmdException as e:
+ # Print stdout if stderr is empty
+ errmsg = e.message[2] if e.message[2] else e.message[1]
+ handle_output_error("Failed to sync Config file: [Error: {0}]"
+ "{1}".format(e.message[0], errmsg),
+ errcode=ERROR_CONFIG_SYNC_FAILED,
+ json_output=args.json)
+
+ out = execute_in_peers("node-reload")
+ if not args.json:
+ table = PrettyTable(["NODE", "NODE STATUS", "SYNC STATUS"])
+ table.align["NODE STATUS"] = "r"
+ table.align["SYNC STATUS"] = "r"
+
+ json_out = []
+ if args.json:
+ num_ok_rows = rows_to_json(json_out, "sync_status", out)
+ else:
+ num_ok_rows = rows_to_table(table, out)
+
+ ret = 0
+ if num_ok_rows == 0:
+ ret = ERROR_ALL_NODES_STATUS_NOT_OK
+ elif num_ok_rows != len(out):
+ ret = ERROR_PARTIAL_SUCCESS
+
+ if args.json:
+ print (json.dumps({
+ "output": json_out,
+ "error": ""
+ }))
+ else:
+ print (table)
+
+ # If sync status is not ok for any node set error code as partial success
+ sys.exit(ret)
+
+
+def node_output_handle(resp):
+ rc, out, err = resp
+ if rc == 0:
+ node_output_ok(out)
+ else:
+ node_output_notok(err)
+
+
+def action_handle(action, json_output=False):
+ out = execute_in_peers("node-" + action)
+ column_name = action.upper()
+ if action == "status":
+ column_name = EVENTSD.upper()
+
+ if not json_output:
+ table = PrettyTable(["NODE", "NODE STATUS", column_name + " STATUS"])
+ table.align["NODE STATUS"] = "r"
+ table.align[column_name + " STATUS"] = "r"
+
+ json_out = []
+ if json_output:
+ rows_to_json(json_out, column_name.lower() + "_status", out)
+ else:
+ rows_to_table(table, out)
+
+ return json_out if json_output else table
+
+
+class NodeReload(Cmd):
+ name = "node-reload"
+
+ def run(self, args):
+ node_output_handle(reload_service())
+
+
+class ReloadCmd(Cmd):
+ name = "reload"
+
+ def run(self, args):
+ out = action_handle("reload", args.json)
+ if args.json:
+ print (json.dumps({
+ "output": out,
+ "error": ""
+ }))
+ else:
+ print (out)
+
+
+class NodeStatus(Cmd):
+ name = "node-status"
+
+ def run(self, args):
+ node_output_ok("UP" if is_active() else "DOWN")
+
+
+class StatusCmd(Cmd):
+ name = "status"
+
+ def run(self, args):
+ webhooks = {}
+ if os.path.exists(WEBHOOKS_FILE):
+ webhooks = json.load(open(WEBHOOKS_FILE))
+
+ json_out = {"webhooks": [], "data": []}
+ if args.json:
+ json_out["webhooks"] = webhooks.keys()
+ else:
+ print ("Webhooks: " + ("" if webhooks else "None"))
+ for w in webhooks:
+ print (w)
+
+ print ()
+
+ out = action_handle("status", args.json)
+ if args.json:
+ json_out["data"] = out
+ print (json.dumps({
+ "output": json_out,
+ "error": ""
+ }))
+ else:
+ print (out)
+
+
+class WebhookAddCmd(Cmd):
+ name = "webhook-add"
+
+ def args(self, parser):
+ parser.add_argument("url", help="URL of Webhook")
+ parser.add_argument("--bearer_token", "-t", help="Bearer Token",
+ default="")
+ parser.add_argument("--secret", "-s",
+ help="Secret to add JWT Bearer Token", default="")
+
+ def run(self, args):
+ create_webhooks_file_if_not_exists(args)
+
+ with LockedOpen(WEBHOOKS_FILE, 'r+'):
+ data = json.load(open(WEBHOOKS_FILE))
+ if data.get(args.url, None) is not None:
+ handle_output_error("Webhook already exists",
+ errcode=ERROR_WEBHOOK_ALREADY_EXISTS,
+ json_output=args.json)
+
+ data[args.url] = {"token": args.bearer_token,
+ "secret": args.secret}
+ file_content_overwrite(WEBHOOKS_FILE, data)
+
+ sync_to_peers(args)
+
+
+class WebhookModCmd(Cmd):
+ name = "webhook-mod"
+
+ def args(self, parser):
+ parser.add_argument("url", help="URL of Webhook")
+ parser.add_argument("--bearer_token", "-t", help="Bearer Token",
+ default="")
+ parser.add_argument("--secret", "-s",
+ help="Secret to add JWT Bearer Token", default="")
+
+ def run(self, args):
+ create_webhooks_file_if_not_exists(args)
+
+ with LockedOpen(WEBHOOKS_FILE, 'r+'):
+ data = json.load(open(WEBHOOKS_FILE))
+ if data.get(args.url, None) is None:
+ handle_output_error("Webhook does not exists",
+ errcode=ERROR_WEBHOOK_NOT_EXISTS,
+ json_output=args.json)
+
+ if isinstance(data[args.url], str):
+ data[args.url]["token"] = data[args.url]
+
+ if args.bearer_token != "":
+ data[args.url]["token"] = args.bearer_token
+
+ if args.secret != "":
+ data[args.url]["secret"] = args.secret
+
+ file_content_overwrite(WEBHOOKS_FILE, data)
+
+ sync_to_peers(args)
+
+
+class WebhookDelCmd(Cmd):
+ name = "webhook-del"
+
+ def args(self, parser):
+ parser.add_argument("url", help="URL of Webhook")
+
+ def run(self, args):
+ create_webhooks_file_if_not_exists(args)
+
+ with LockedOpen(WEBHOOKS_FILE, 'r+'):
+ data = json.load(open(WEBHOOKS_FILE))
+ if data.get(args.url, None) is None:
+ handle_output_error("Webhook does not exists",
+ errcode=ERROR_WEBHOOK_NOT_EXISTS,
+ json_output=args.json)
+
+ del data[args.url]
+ file_content_overwrite(WEBHOOKS_FILE, data)
+
+ sync_to_peers(args)
+
+
+class NodeWebhookTestCmd(Cmd):
+ name = "node-webhook-test"
+
+ def args(self, parser):
+ parser.add_argument("url")
+ parser.add_argument("bearer_token")
+ parser.add_argument("secret")
+
+ def run(self, args):
+ http_headers = {}
+ hashval = ""
+ if args.bearer_token != ".":
+ hashval = args.bearer_token
+
+ if args.secret != ".":
+ hashval = get_jwt_token(args.secret, "TEST", int(time.time()))
+
+ if hashval:
+ http_headers["Authorization"] = "Bearer " + hashval
+
+ urldata = requests.utils.urlparse(args.url)
+ parts = urldata.netloc.split(":")
+ domain = parts[0]
+ # Default https port if not specified
+ port = 443
+ if len(parts) == 2:
+ port = int(parts[1])
+
+ cert_path = os.path.join(CERTS_DIR, args.url.replace("/", "_").strip())
+ verify = True
+ while True:
+ try:
+ resp = requests.post(args.url, headers=http_headers,
+ verify=verify)
+ # Successful webhook push
+ break
+ except requests.exceptions.SSLError as e:
+ # If verify is equal to cert path, but still failed with
+ # SSLError, Looks like some issue with custom downloaded
+ # certificate, Try with verify = false
+ if verify == cert_path:
+ verify = False
+ continue
+
+ # If verify is instance of bool and True, then custom cert
+ # is required, download the cert and retry
+ try:
+ save_https_cert(domain, port, cert_path)
+ verify = cert_path
+ except Exception:
+ verify = False
+
+ # Done with collecting cert, continue
+ continue
+ except Exception as e:
+ node_output_notok("{0}".format(e))
+ break
+
+ if resp.status_code != 200:
+ node_output_notok("{0}".format(resp.status_code))
+
+ node_output_ok()
+
+
+class WebhookTestCmd(Cmd):
+ name = "webhook-test"
+
+ def args(self, parser):
+ parser.add_argument("url", help="URL of Webhook")
+ parser.add_argument("--bearer_token", "-t", help="Bearer Token")
+ parser.add_argument("--secret", "-s",
+ help="Secret to generate Bearer Token")
+
+ def run(self, args):
+ url = args.url
+ bearer_token = args.bearer_token
+ secret = args.secret
+
+ if not args.url:
+ url = "."
+ if not args.bearer_token:
+ bearer_token = "."
+ if not args.secret:
+ secret = "."
+
+ out = execute_in_peers("node-webhook-test", [url, bearer_token,
+ secret])
+
+ if not args.json:
+ table = PrettyTable(["NODE", "NODE STATUS", "WEBHOOK STATUS"])
+ table.align["NODE STATUS"] = "r"
+ table.align["WEBHOOK STATUS"] = "r"
+
+ num_ok_rows = 0
+ json_out = []
+ if args.json:
+ num_ok_rows = rows_to_json(json_out, "webhook_status", out)
+ else:
+ num_ok_rows = rows_to_table(table, out)
+
+ ret = 0
+ if num_ok_rows == 0:
+ ret = ERROR_ALL_NODES_STATUS_NOT_OK
+ elif num_ok_rows != len(out):
+ ret = ERROR_PARTIAL_SUCCESS
+
+ if args.json:
+ print (json.dumps({
+ "output": json_out,
+ "error": ""
+ }))
+ else:
+ print (table)
+
+ sys.exit(ret)
+
+
+class ConfigGetCmd(Cmd):
+ name = "config-get"
+
+ def args(self, parser):
+ parser.add_argument("--name", help="Config Name")
+
+ def run(self, args):
+ data = json.load(open(DEFAULT_CONFIG_FILE))
+ if os.path.exists(CUSTOM_CONFIG_FILE):
+ data.update(json.load(open(CUSTOM_CONFIG_FILE)))
+
+ if args.name is not None and args.name not in CONFIG_KEYS:
+ handle_output_error("Invalid Config item",
+ errcode=ERROR_INVALID_CONFIG,
+ json_output=args.json)
+
+ if args.json:
+ json_out = {}
+ if args.name is None:
+ json_out = data
+ else:
+ json_out[args.name] = data[args.name]
+
+ print (json.dumps({
+ "output": json_out,
+ "error": ""
+ }))
+ else:
+ table = PrettyTable(["NAME", "VALUE"])
+ if args.name is None:
+ for k, v in data.items():
+ table.add_row([k, v])
+ else:
+ table.add_row([args.name, data[args.name]])
+
+ print (table)
+
+
+def read_file_content_json(fname):
+ content = "{}"
+ with open(fname) as f:
+ content = f.read()
+ if content.strip() == "":
+ content = "{}"
+
+ return json.loads(content)
+
+
+class ConfigSetCmd(Cmd):
+ name = "config-set"
+
+ def args(self, parser):
+ parser.add_argument("name", help="Config Name")
+ parser.add_argument("value", help="Config Value")
+
+ def run(self, args):
+ if args.name not in CONFIG_KEYS:
+ handle_output_error("Invalid Config item",
+ errcode=ERROR_INVALID_CONFIG,
+ json_output=args.json)
+
+ create_custom_config_file_if_not_exists(args)
+
+ with LockedOpen(CUSTOM_CONFIG_FILE, 'r+'):
+ data = json.load(open(DEFAULT_CONFIG_FILE))
+ if os.path.exists(CUSTOM_CONFIG_FILE):
+ config_json = read_file_content_json(CUSTOM_CONFIG_FILE)
+ data.update(config_json)
+
+ # Do Nothing if same as previous value
+ if data[args.name] == args.value:
+ handle_output_error("Config value not changed. Same config",
+ errcode=ERROR_SAME_CONFIG,
+ json_output=args.json)
+
+ # TODO: Validate Value
+ new_data = read_file_content_json(CUSTOM_CONFIG_FILE)
+
+ v = args.value
+ if args.name in BOOL_CONFIGS:
+ v = boolify(args.value)
+
+ if args.name in INT_CONFIGS:
+ v = int(args.value)
+
+ new_data[args.name] = v
+ file_content_overwrite(CUSTOM_CONFIG_FILE, new_data)
+
+ # If any value changed which requires restart of REST server
+ restart = False
+ if args.name in RESTART_CONFIGS:
+ restart = True
+
+ if restart:
+ print ("\nRestart glustereventsd in all nodes")
+
+ sync_to_peers(args)
+
+
+class ConfigResetCmd(Cmd):
+ name = "config-reset"
+
+ def args(self, parser):
+ parser.add_argument("name", help="Config Name or all")
+
+ def run(self, args):
+ create_custom_config_file_if_not_exists(args)
+
+ with LockedOpen(CUSTOM_CONFIG_FILE, 'r+'):
+ changed_keys = []
+ data = {}
+ if os.path.exists(CUSTOM_CONFIG_FILE):
+ data = read_file_content_json(CUSTOM_CONFIG_FILE)
+
+ # If No data available in custom config or, the specific config
+ # item is not available in custom config
+ if not data or \
+ (args.name != "all" and data.get(args.name, None) is None):
+ handle_output_error("Config value not reset. Already "
+ "set to default value",
+ errcode=ERROR_SAME_CONFIG,
+ json_output=args.json)
+
+ if args.name.lower() == "all":
+ for k, v in data.items():
+ changed_keys.append(k)
+
+ # Reset all keys
+ file_content_overwrite(CUSTOM_CONFIG_FILE, {})
+ else:
+ changed_keys.append(args.name)
+ del data[args.name]
+ file_content_overwrite(CUSTOM_CONFIG_FILE, data)
+
+ # If any value changed which requires restart of REST server
+ restart = False
+ for key in changed_keys:
+ if key in RESTART_CONFIGS:
+ restart = True
+ break
+
+ if restart:
+ print ("\nRestart glustereventsd in all nodes")
+
+ sync_to_peers(args)
+
+
+class SyncCmd(Cmd):
+ name = "sync"
+
+ def run(self, args):
+ sync_to_peers(args)
+
+
+def common_args(parser):
+ parser.add_argument("--json", help="JSON Output", action="store_true")
+
+
+if __name__ == "__main__":
+ set_common_args_func(common_args)
+ runcli()
diff --git a/events/src/utils.py b/events/src/utils.py
new file mode 100644
index 00000000000..6d4e0791a2b
--- /dev/null
+++ b/events/src/utils.py
@@ -0,0 +1,445 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+import sys
+import json
+import os
+import logging
+import logging.handlers
+import fcntl
+from errno import EBADF
+from threading import Thread
+import multiprocessing
+try:
+ from queue import Queue
+except ImportError:
+ from Queue import Queue
+from datetime import datetime, timedelta
+import base64
+import hmac
+from hashlib import sha256
+from calendar import timegm
+
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+from gfevents.eventsapiconf import (LOG_FILE,
+ WEBHOOKS_FILE,
+ DEFAULT_CONFIG_FILE,
+ CUSTOM_CONFIG_FILE,
+ UUID_FILE,
+ CERTS_DIR)
+from gfevents import eventtypes
+
+
+# Webhooks list
+_webhooks = {}
+_webhooks_file_mtime = 0
+# Default Log Level
+_log_level = "INFO"
+# Config Object
+_config = {}
+
+# Init Logger instance
+logger = logging.getLogger(__name__)
+NodeID = None
+webhooks_pool = None
+
+
+def boolify(value):
+ value = str(value)
+ if value.lower() in ["1", "on", "true", "yes"]:
+ return True
+ else:
+ return False
+
+
+def log_event(data):
+ # Log all published events unless it is disabled
+ if not _config.get("disable-events-log", False):
+ logger.info(repr(data))
+
+
+def get_node_uuid():
+ val = None
+ with open(UUID_FILE) as f:
+ for line in f:
+ if line.startswith("UUID="):
+ val = line.strip().split("=")[-1]
+ break
+ return val
+
+
+def get_config(key, default_value=None):
+ if not _config:
+ load_config()
+ return _config.get(key, default_value)
+
+
+def get_event_type_name(idx):
+ """
+ Returns Event Type text from the index. For example, VOLUME_CREATE
+ """
+ return eventtypes.all_events[idx].replace("EVENT_", "")
+
+
+def setup_logger():
+ """
+ Logging initialization, Log level by default will be INFO, once config
+ file is read, respective log_level will be set.
+ """
+ global logger
+ logger.setLevel(logging.INFO)
+
+ # create the logging file handler
+ fh = logging.handlers.WatchedFileHandler(LOG_FILE)
+
+ formatter = logging.Formatter("[%(asctime)s] %(levelname)s "
+ "[%(module)s - %(lineno)s:%(funcName)s] "
+ "- %(message)s")
+
+ fh.setFormatter(formatter)
+
+ # add handler to logger object
+ logger.addHandler(fh)
+
+
+def load_config():
+ """
+ Load/Reload the config from REST Config files. This function will
+ be triggered during init and when SIGUSR2.
+ """
+ global _config
+ _config = {}
+ if os.path.exists(DEFAULT_CONFIG_FILE):
+ _config = json.load(open(DEFAULT_CONFIG_FILE))
+ if os.path.exists(CUSTOM_CONFIG_FILE):
+ _config.update(json.load(open(CUSTOM_CONFIG_FILE)))
+
+
+def load_log_level():
+ """
+ Reads log_level from Config file and sets accordingly. This function will
+ be triggered during init and when SIGUSR2.
+ """
+ global logger, _log_level
+ new_log_level = _config.get("log-level", "INFO")
+ if _log_level != new_log_level:
+ logger.setLevel(getattr(logging, new_log_level.upper()))
+ _log_level = new_log_level.upper()
+
+
+def load_webhooks():
+ """
+ Load/Reload the webhooks list. This function will
+ be triggered during init and when SIGUSR2.
+ """
+ global _webhooks, _webhooks_file_mtime
+ _webhooks = {}
+ if os.path.exists(WEBHOOKS_FILE):
+ _webhooks = json.load(open(WEBHOOKS_FILE))
+ st = os.lstat(WEBHOOKS_FILE)
+ _webhooks_file_mtime = st.st_mtime
+
+
+def load_all():
+ """
+ Wrapper function to call all load/reload functions. This function will
+ be triggered during init and when SIGUSR2.
+ """
+ load_config()
+ load_webhooks()
+ load_log_level()
+
+
+def publish(ts, event_key, data):
+ global NodeID
+ if NodeID is None:
+ NodeID = get_node_uuid()
+
+ autoload_webhooks()
+
+ message = {
+ "nodeid": NodeID,
+ "ts": int(ts),
+ "event": get_event_type_name(event_key),
+ "message": data
+ }
+
+ log_event(message)
+
+ if _webhooks:
+ plugin_webhook(message)
+ else:
+ # TODO: Default action?
+ pass
+
+
+def autoload_webhooks():
+ global _webhooks_file_mtime
+ try:
+ st = os.lstat(WEBHOOKS_FILE)
+ except OSError:
+ st = None
+
+ if st is not None:
+ # If Stat is available and mtime is not matching with
+ # previously recorded mtime, reload the webhooks file
+ if st.st_mtime != _webhooks_file_mtime:
+ load_webhooks()
+
+
+def base64_urlencode(inp):
+ return base64.urlsafe_b64encode(inp).replace("=", "").strip()
+
+
+def get_jwt_token(secret, event_type, event_ts, jwt_expiry_time_seconds=60):
+ exp = datetime.utcnow() + timedelta(seconds=jwt_expiry_time_seconds)
+ payload = {
+ "exp": timegm(exp.utctimetuple()),
+ "iss": "gluster",
+ "sub": event_type,
+ "iat": event_ts
+ }
+ header = '{"alg":"HS256","typ":"JWT"}'
+ payload = json.dumps(payload, separators=(',', ':'), sort_keys=True)
+ msg = base64_urlencode(header) + "." + base64_urlencode(payload)
+ return "%s.%s" % (
+ msg,
+ base64_urlencode(hmac.HMAC(str(secret), msg, sha256).digest())
+ )
+
+
+def save_https_cert(domain, port, cert_path):
+ import ssl
+
+ # Cert file already available for this URL
+ if os.path.exists(cert_path):
+ return
+
+ cert_data = ssl.get_server_certificate((domain, port))
+ with open(cert_path, "w") as f:
+ f.write(cert_data)
+
+
+def publish_to_webhook(url, token, secret, message_queue):
+ # Import requests here since not used in any other place
+ import requests
+
+ http_headers = {"Content-Type": "application/json"}
+ urldata = requests.utils.urlparse(url)
+ parts = urldata.netloc.split(":")
+ domain = parts[0]
+ # Default https port if not specified
+ port = 443
+ if len(parts) == 2:
+ port = int(parts[1])
+
+ cert_path = os.path.join(CERTS_DIR, url.replace("/", "_").strip())
+
+ while True:
+ hashval = ""
+ event_type, event_ts, message_json = message_queue.get()
+ if token != "" and token is not None:
+ hashval = token
+
+ if secret != "" and secret is not None:
+ hashval = get_jwt_token(secret, event_type, event_ts)
+
+ if hashval:
+ http_headers["Authorization"] = "Bearer " + hashval
+
+ verify = True
+ while True:
+ try:
+ resp = requests.post(url, headers=http_headers,
+ data=message_json,
+ verify=verify)
+ # Successful webhook push
+ message_queue.task_done()
+ if resp.status_code != 200:
+ logger.warn("Event push failed to URL: {url}, "
+ "Event: {event}, "
+ "Status Code: {status_code}".format(
+ url=url,
+ event=message_json,
+ status_code=resp.status_code))
+ break
+ except requests.exceptions.SSLError as e:
+ # If verify is equal to cert path, but still failed with
+ # SSLError, Looks like some issue with custom downloaded
+ # certificate, Try with verify = false
+ if verify == cert_path:
+ logger.warn("Event push failed with certificate, "
+ "ignoring verification url={0} "
+ "Error={1}".format(url, e))
+ verify = False
+ continue
+
+ # If verify is instance of bool and True, then custom cert
+ # is required, download the cert and retry
+ try:
+ save_https_cert(domain, port, cert_path)
+ verify = cert_path
+ except Exception as ex:
+ verify = False
+ logger.warn("Unable to get Server certificate, "
+ "ignoring verification url={0} "
+ "Error={1}".format(url, ex))
+
+ # Done with collecting cert, continue
+ continue
+ except Exception as e:
+ logger.warn("Event push failed to URL: {url}, "
+ "Event: {event}, "
+ "Status: {error}".format(
+ url=url,
+ event=message_json,
+ error=e))
+ message_queue.task_done()
+ break
+
+
+def plugin_webhook(message):
+ message_json = json.dumps(message, sort_keys=True)
+ logger.debug("EVENT: {0}".format(message_json))
+ webhooks_pool.send(message["event"], message["ts"], message_json)
+
+
+class LockedOpen(object):
+
+ def __init__(self, filename, *args, **kwargs):
+ self.filename = filename
+ self.open_args = args
+ self.open_kwargs = kwargs
+ self.fileobj = None
+
+ def __enter__(self):
+ """
+ If two processes compete to update a file, The first process
+ gets the lock and the second process is blocked in the fcntl.flock()
+ call. When first process replaces the file and releases the lock,
+ the already open file descriptor in the second process now points
+ to a "ghost" file(not reachable by any path name) with old contents.
+ To avoid that conflict, check the fd already opened is same or
+ not. Open new one if not same
+ """
+ f = open(self.filename, *self.open_args, **self.open_kwargs)
+ while True:
+ fcntl.flock(f, fcntl.LOCK_EX)
+ fnew = open(self.filename, *self.open_args, **self.open_kwargs)
+ if os.path.sameopenfile(f.fileno(), fnew.fileno()):
+ fnew.close()
+ break
+ else:
+ f.close()
+ f = fnew
+ self.fileobj = f
+ return f
+
+ def __exit__(self, _exc_type, _exc_value, _traceback):
+ self.fileobj.close()
+
+
+class PidFileLockFailed(Exception):
+ pass
+
+
+class PidFile(object):
+ def __init__(self, filename):
+ self.filename = filename
+ self.pid = os.getpid()
+ self.fh = None
+
+ def cleanup(self, remove_file=True):
+ try:
+ if self.fh is not None:
+ self.fh.close()
+ except IOError as exc:
+ if exc.errno != EBADF:
+ raise
+ finally:
+ if os.path.isfile(self.filename) and remove_file:
+ os.remove(self.filename)
+
+ def __enter__(self):
+ self.fh = open(self.filename, 'a+')
+ try:
+ fcntl.flock(self.fh.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
+ except IOError as exc:
+ self.cleanup(remove_file=False)
+ raise PidFileLockFailed(exc)
+
+ self.fh.seek(0)
+ self.fh.truncate()
+ self.fh.write("%d\n" % self.pid)
+ self.fh.flush()
+ self.fh.seek(0)
+ return self
+
+ def __exit__(self, _exc_type, _exc_value, _traceback):
+ self.cleanup()
+
+
+def webhook_monitor(proc_queue, webhooks):
+ queues = {}
+ for url, data in webhooks.items():
+ if isinstance(data, str):
+ token = data
+ secret = None
+ else:
+ token = data["token"]
+ secret = data["secret"]
+
+ queues[url] = Queue()
+ t = Thread(target=publish_to_webhook, args=(url, token, secret,
+ queues[url]))
+ t.start()
+
+ # Get the message sent to Process queue and distribute to all thread queues
+ while True:
+ message = proc_queue.get()
+ for _, q in queues.items():
+ q.put(message)
+
+
+class WebhookThreadPool(object):
+ def start(self):
+ # Separate process to emit messages to webhooks
+ # which maintains one thread per webhook. Separate
+ # process is required since on reload we need to stop
+ # and start the thread pool. In Python Threads can't be stopped
+ # so terminate the process and start again. Note: In transit
+ # events will be missed during reload
+ self.queue = multiprocessing.Queue()
+ self.proc = multiprocessing.Process(target=webhook_monitor,
+ args=(self.queue, _webhooks))
+ self.proc.start()
+
+ def restart(self):
+ # In transit messages are skipped, since webhooks monitor process
+ # is terminated.
+ self.proc.terminate()
+ self.start()
+
+ def send(self, event_type, event_ts, message):
+ self.queue.put((event_type, event_ts, message))
+
+
+def init_webhook_pool():
+ global webhooks_pool
+ webhooks_pool = WebhookThreadPool()
+ webhooks_pool.start()
+
+
+def restart_webhook_pool():
+ global webhooks_pool
+ if webhooks_pool is not None:
+ webhooks_pool.restart()
diff --git a/events/tools/Makefile.am b/events/tools/Makefile.am
new file mode 100644
index 00000000000..fb6770cf070
--- /dev/null
+++ b/events/tools/Makefile.am
@@ -0,0 +1,6 @@
+EXTRA_DIST = eventsdash.py
+
+if BUILD_EVENTS
+scriptsdir = $(datadir)/glusterfs/scripts
+scripts_SCRIPTS = eventsdash.py
+endif
diff --git a/events/tools/eventsdash.py b/events/tools/eventsdash.py
new file mode 100644
index 00000000000..6479ea59da6
--- /dev/null
+++ b/events/tools/eventsdash.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+from __future__ import print_function
+from argparse import ArgumentParser, RawDescriptionHelpFormatter
+import logging
+from datetime import datetime
+
+from flask import Flask, request
+
+app = Flask(__name__)
+app.logger.disabled = True
+log = logging.getLogger('werkzeug')
+log.disabled = True
+
+
+def human_time(ts):
+ return datetime.fromtimestamp(float(ts)).strftime("%Y-%m-%d %H:%M:%S")
+
+
+@app.route("/")
+def home():
+ return "OK"
+
+
+@app.route("/listen", methods=["POST"])
+def listen():
+ data = request.json
+ if data is None:
+ return "OK"
+
+ message = []
+ for k, v in data.get("message", {}).items():
+ message.append("{0}={1}".format(k, v))
+
+ print(("{0:20s} {1:20s} {2:36} {3}".format(
+ human_time(data.get("ts")),
+ data.get("event"),
+ data.get("nodeid"),
+ " ".join(message))))
+
+ return "OK"
+
+
+def main():
+ parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter,
+ description=__doc__)
+ parser.add_argument("--port", type=int, help="Port", default=9000)
+ parser.add_argument("--debug", help="Run Server in debug mode",
+ action="store_true")
+ args = parser.parse_args()
+
+ print(("{0:20s} {1:20s} {2:36} {3}".format(
+ "TIMESTAMP", "EVENT", "NODE ID", "MESSAGE"
+ )))
+ print(("{0:20s} {1:20s} {2:36} {3}".format(
+ "-"*20, "-"*20, "-"*36, "-"*20
+ )))
+ if args.debug:
+ app.debug = True
+
+ app.run(host="0.0.0.0", port=args.port)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/extras/LinuxRPM/Makefile.am b/extras/LinuxRPM/Makefile.am
index d1b78ea8974..f02853798c0 100644
--- a/extras/LinuxRPM/Makefile.am
+++ b/extras/LinuxRPM/Makefile.am
@@ -15,10 +15,10 @@ glusterrpms_without_autogen: prep srcrpm rpms
-rm -rf rpmbuild
autogen:
- cd ../.. \
- && rm -rf autom4te.cache \
- && ./autogen.sh \
- && ./configure --with-previous-options
+ cd ../.. && \
+ rm -rf autom4te.cache && \
+ ./autogen.sh && \
+ ./configure --enable-gnfs --with-previous-options
prep:
$(MAKE) -C ../.. dist;
@@ -36,7 +36,7 @@ srcrpm:
mv rpmbuild/SRPMS/* .
rpms:
- rpmbuild --define '_topdir $(shell pwd)/rpmbuild' -bb rpmbuild/SPECS/glusterfs.spec
+ rpmbuild --define '_topdir $(shell pwd)/rpmbuild' --with gnfs -bb rpmbuild/SPECS/glusterfs.spec
mv rpmbuild/RPMS/*/* .
# EPEL-5 does not like new versions of rpmbuild and requires some
diff --git a/extras/Makefile.am b/extras/Makefile.am
index 76dbb36ab9e..983f014cca6 100644
--- a/extras/Makefile.am
+++ b/extras/Makefile.am
@@ -1,35 +1,77 @@
-addonexecdir = $(libexecdir)/glusterfs
-addonexec_SCRIPTS = peer_add_secret_pub
+addonexecdir = $(GLUSTERFS_LIBEXECDIR)
+addonexec_SCRIPTS =
+if WITH_SERVER
+addonexec_SCRIPTS += peer_add_secret_pub
+if USE_SYSTEMD
+addonexec_SCRIPTS += mount-shared-storage.sh
+endif
+endif
EditorModedir = $(docdir)
EditorMode_DATA = glusterfs-mode.el glusterfs.vim
SUBDIRS = init.d systemd benchmarking hook-scripts $(OCF_SUBDIR) LinuxRPM \
- $(GEOREP_EXTRAS_SUBDIR) ganesha snap_scheduler firewalld
+ $(GEOREP_EXTRAS_SUBDIR) snap_scheduler firewalld cliutils python \
+ ganesha
confdir = $(sysconfdir)/glusterfs
+if WITH_SERVER
conf_DATA = glusterfs-logrotate gluster-rsyslog-7.2.conf gluster-rsyslog-5.8.conf \
- logger.conf.example glusterfs-georep-logrotate group-virt.example
+ logger.conf.example glusterfs-georep-logrotate group-virt.example \
+ group-metadata-cache group-gluster-block group-nl-cache \
+ group-db-workload group-distributed-virt group-samba
+endif
voldir = $(sysconfdir)/glusterfs
-vol_DATA = glusterd.vol
+vol_DATA = thin-arbiter/thin-arbiter.vol
+if WITH_SERVER
+vol_DATA += glusterd.vol
+endif
+
scriptsdir = $(datadir)/glusterfs/scripts
-scripts_SCRIPTS = post-upgrade-script-for-quota.sh \
+scripts_SCRIPTS = thin-arbiter/setup-thin-arbiter.sh
+if WITH_SERVER
+scripts_SCRIPTS += post-upgrade-script-for-quota.sh \
pre-upgrade-script-for-quota.sh stop-all-gluster-processes.sh
+if USE_SYSTEMD
+scripts_SCRIPTS += control-cpu-load.sh
+scripts_SCRIPTS += control-mem.sh
+endif
+endif
-EXTRA_DIST = $(conf_DATA) specgen.scm glusterfs-mode.el glusterfs.vim \
- migrate-unify-to-distribute.sh backend-xattr-sanitize.sh backend-cleanup.sh \
- disk_usage_sync.sh clear_xattrs.sh glusterd-sysconfig glusterd.vol \
- post-upgrade-script-for-quota.sh pre-upgrade-script-for-quota.sh \
- command-completion/gluster.bash command-completion/Makefile \
- command-completion/README stop-all-gluster-processes.sh
+EXTRA_DIST = glusterfs-logrotate gluster-rsyslog-7.2.conf gluster-rsyslog-5.8.conf \
+ logger.conf.example glusterfs-georep-logrotate group-virt.example \
+ group-metadata-cache group-gluster-block group-nl-cache \
+ group-db-workload group-samba specgen.scm glusterfs-mode.el glusterfs.vim \
+ migrate-unify-to-distribute.sh backend-xattr-sanitize.sh \
+ backend-cleanup.sh disk_usage_sync.sh clear_xattrs.sh \
+ glusterd-sysconfig glusterd.vol post-upgrade-script-for-quota.sh \
+ pre-upgrade-script-for-quota.sh command-completion/gluster.bash \
+ command-completion/Makefile command-completion/README \
+ stop-all-gluster-processes.sh clang-checker.sh mount-shared-storage.sh \
+ control-cpu-load.sh control-mem.sh group-distributed-virt \
+ thin-arbiter/thin-arbiter.vol thin-arbiter/setup-thin-arbiter.sh
+if WITH_SERVER
install-data-local:
if [ -n "$(tmpfilesdir)" ]; then \
- $(MKDIR_P) $(DESTDIR)$(tmpfilesdir); \
+ $(mkdir_p) $(DESTDIR)$(tmpfilesdir); \
$(INSTALL_DATA) run-gluster.tmpfiles \
$(DESTDIR)$(tmpfilesdir)/gluster.conf; \
fi
- $(MKDIR_P) $(DESTDIR)$(GLUSTERD_WORKDIR)/groups
+ $(mkdir_p) $(DESTDIR)$(GLUSTERD_WORKDIR)/groups
$(INSTALL_DATA) $(top_srcdir)/extras/group-virt.example \
$(DESTDIR)$(GLUSTERD_WORKDIR)/groups/virt
+ $(INSTALL_DATA) $(top_srcdir)/extras/group-metadata-cache \
+ $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/metadata-cache
+ $(INSTALL_DATA) $(top_srcdir)/extras/group-gluster-block \
+ $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/gluster-block
+ $(INSTALL_DATA) $(top_srcdir)/extras/group-nl-cache \
+ $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/nl-cache
+ $(INSTALL_DATA) $(top_srcdir)/extras/group-db-workload \
+ $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/db-workload
+ $(INSTALL_DATA) $(top_srcdir)/extras/group-distributed-virt \
+ $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/distributed-virt
+ $(INSTALL_DATA) $(top_srcdir)/extras/group-samba \
+ $(DESTDIR)$(GLUSTERD_WORKDIR)/groups/samba
+endif
diff --git a/extras/backend-cleanup.sh b/extras/backend-cleanup.sh
index dc504860b73..cb0a1d8871f 100644
--- a/extras/backend-cleanup.sh
+++ b/extras/backend-cleanup.sh
@@ -17,7 +17,7 @@ export_directory="/export/glusterfs"
clean_dir()
{
# Clean the 'link' files on backend
- find "${export_directory}" -type f -perm +01000 -exec rm -v '{}' \;
+ find "${export_directory}" -type f -perm /01000 -exec rm -v '{}' \;
}
main()
diff --git a/extras/benchmarking/glfs-bm.c b/extras/benchmarking/glfs-bm.c
index dc717f33c16..f7f5873f84d 100644
--- a/extras/benchmarking/glfs-bm.c
+++ b/extras/benchmarking/glfs-bm.c
@@ -25,365 +25,338 @@
#include <sys/time.h>
struct state {
- char need_op_write:1;
- char need_op_read:1;
+ char need_op_write : 1;
+ char need_op_read : 1;
- char need_iface_fileio:1;
- char need_iface_xattr:1;
+ char need_iface_fileio : 1;
+ char need_iface_xattr : 1;
- char need_mode_posix:1;
+ char need_mode_posix : 1;
- char prefix[512];
- long int count;
+ char prefix[512];
+ long int count;
- size_t block_size;
+ size_t block_size;
- char *specfile;
+ char *specfile;
- long int io_size;
+ long int io_size;
};
-
-#define MEASURE(func, arg) measure (func, #func, arg)
-
+#define MEASURE(func, arg) measure(func, #func, arg)
void
-tv_difference (struct timeval *tv_stop,
- struct timeval *tv_start,
- struct timeval *tv_diff)
+tv_difference(struct timeval *tv_stop, struct timeval *tv_start,
+ struct timeval *tv_diff)
{
- if (tv_stop->tv_usec < tv_start->tv_usec) {
- tv_diff->tv_usec = (tv_stop->tv_usec + 1000000) - tv_start->tv_usec;
- tv_diff->tv_sec = (tv_stop->tv_sec - 1 - tv_start->tv_sec);
- } else {
- tv_diff->tv_usec = tv_stop->tv_usec - tv_start->tv_usec;
- tv_diff->tv_sec = tv_stop->tv_sec - tv_start->tv_sec;
- }
+ if (tv_stop->tv_usec < tv_start->tv_usec) {
+ tv_diff->tv_usec = (tv_stop->tv_usec + 1000000) - tv_start->tv_usec;
+ tv_diff->tv_sec = (tv_stop->tv_sec - 1 - tv_start->tv_sec);
+ } else {
+ tv_diff->tv_usec = tv_stop->tv_usec - tv_start->tv_usec;
+ tv_diff->tv_sec = tv_stop->tv_sec - tv_start->tv_sec;
+ }
}
-
void
-measure (int (*func)(struct state *state),
- char *func_name, struct state *state)
+measure(int (*func)(struct state *state), char *func_name, struct state *state)
{
- struct timeval tv_start, tv_stop, tv_diff;
- state->io_size = 0;
- long int count;
+ struct timeval tv_start, tv_stop, tv_diff;
+ state->io_size = 0;
+ long int count;
- gettimeofday (&tv_start, NULL);
- count = func (state);
- gettimeofday (&tv_stop, NULL);
+ gettimeofday(&tv_start, NULL);
+ count = func(state);
+ gettimeofday(&tv_stop, NULL);
- tv_difference (&tv_stop, &tv_start, &tv_diff);
+ tv_difference(&tv_stop, &tv_start, &tv_diff);
- fprintf (stdout, "%s: count=%ld, size=%ld, time=%ld:%ld\n",
- func_name, count, state->io_size,
- tv_diff.tv_sec, tv_diff.tv_usec);
+ fprintf(stdout, "%s: count=%ld, size=%ld, time=%ld:%ld\n", func_name, count,
+ state->io_size, tv_diff.tv_sec, tv_diff.tv_usec);
}
-
static error_t
-parse_opts (int key, char *arg,
- struct argp_state *_state)
+parse_opts(int key, char *arg, struct argp_state *_state)
{
- struct state *state = _state->input;
+ struct state *state = _state->input;
- switch (key)
- {
+ switch (key) {
case 'o':
- if (strcasecmp (arg, "read") == 0) {
- state->need_op_write = 0;
- state->need_op_read = 1;
- } else if (strcasecmp (arg, "write") == 0) {
- state->need_op_write = 1;
- state->need_op_read = 0;
- } else if (strcasecmp (arg, "both") == 0) {
- state->need_op_write = 1;
- state->need_op_read = 1;
- } else {
- fprintf (stderr, "unknown op: %s\n", arg);
- return -1;
- }
- break;
+ if (strcasecmp(arg, "read") == 0) {
+ state->need_op_write = 0;
+ state->need_op_read = 1;
+ } else if (strcasecmp(arg, "write") == 0) {
+ state->need_op_write = 1;
+ state->need_op_read = 0;
+ } else if (strcasecmp(arg, "both") == 0) {
+ state->need_op_write = 1;
+ state->need_op_read = 1;
+ } else {
+ fprintf(stderr, "unknown op: %s\n", arg);
+ return -1;
+ }
+ break;
case 'i':
- if (strcasecmp (arg, "fileio") == 0) {
- state->need_iface_fileio = 1;
- state->need_iface_xattr = 0;
- } else if (strcasecmp (arg, "xattr") == 0) {
- state->need_iface_fileio = 0;
- state->need_iface_xattr = 1;
- } else if (strcasecmp (arg, "both") == 0) {
- state->need_iface_fileio = 1;
- state->need_iface_xattr = 1;
- } else {
- fprintf (stderr, "unknown interface: %s\n", arg);
- return -1;
- }
- break;
- case 'b':
- {
- size_t block_size = atoi (arg);
- if (!block_size) {
- fprintf (stderr, "incorrect size: %s\n", arg);
- return -1;
- }
- state->block_size = block_size;
- }
- break;
+ if (strcasecmp(arg, "fileio") == 0) {
+ state->need_iface_fileio = 1;
+ state->need_iface_xattr = 0;
+ } else if (strcasecmp(arg, "xattr") == 0) {
+ state->need_iface_fileio = 0;
+ state->need_iface_xattr = 1;
+ } else if (strcasecmp(arg, "both") == 0) {
+ state->need_iface_fileio = 1;
+ state->need_iface_xattr = 1;
+ } else {
+ fprintf(stderr, "unknown interface: %s\n", arg);
+ return -1;
+ }
+ break;
+ case 'b': {
+ size_t block_size = atoi(arg);
+ if (!block_size) {
+ fprintf(stderr, "incorrect size: %s\n", arg);
+ return -1;
+ }
+ state->block_size = block_size;
+ } break;
case 's':
- state->specfile = strdup (arg);
- break;
+ state->specfile = strdup(arg);
+ break;
case 'p':
- fprintf (stderr, "using prefix: %s\n", arg);
- strncpy (state->prefix, arg, 512);
- break;
- case 'c':
- {
- long count = atol (arg);
- if (!count) {
- fprintf (stderr, "incorrect count: %s\n", arg);
- return -1;
- }
- state->count = count;
- }
- break;
+ fprintf(stderr, "using prefix: %s\n", arg);
+ strncpy(state->prefix, arg, 512);
+ break;
+ case 'c': {
+ long count = atol(arg);
+ if (!count) {
+ fprintf(stderr, "incorrect count: %s\n", arg);
+ return -1;
+ }
+ state->count = count;
+ } break;
case ARGP_KEY_NO_ARGS:
- break;
+ break;
case ARGP_KEY_ARG:
- break;
- }
+ break;
+ }
- return 0;
+ return 0;
}
int
-do_mode_posix_iface_fileio_write (struct state *state)
+do_mode_posix_iface_fileio_write(struct state *state)
{
- long int i;
- int ret = -1;
- char block[state->block_size];
-
- for (i=0; i<state->count; i++) {
- int fd = -1;
- char filename[512];
-
- sprintf (filename, "%s.%06ld", state->prefix, i);
-
- fd = open (filename, O_CREAT|O_WRONLY, 00600);
- if (fd == -1) {
- fprintf (stderr, "open(%s) => %s\n", filename, strerror (errno));
- break;
- }
- ret = write (fd, block, state->block_size);
- if (ret != state->block_size) {
- fprintf (stderr, "write (%s) => %d/%s\n", filename, ret,
- strerror (errno));
- close (fd);
- break;
- }
- close (fd);
- state->io_size += ret;
+ long int i;
+ int ret = -1;
+ char block[state->block_size];
+
+ for (i = 0; i < state->count; i++) {
+ int fd = -1;
+ char filename[512];
+
+ sprintf(filename, "%s.%06ld", state->prefix, i);
+
+ fd = open(filename, O_CREAT | O_WRONLY, 00600);
+ if (fd == -1) {
+ fprintf(stderr, "open(%s) => %s\n", filename, strerror(errno));
+ break;
+ }
+ ret = write(fd, block, state->block_size);
+ if (ret != state->block_size) {
+ fprintf(stderr, "write (%s) => %d/%s\n", filename, ret,
+ strerror(errno));
+ close(fd);
+ break;
}
+ close(fd);
+ state->io_size += ret;
+ }
- return i;
+ return i;
}
-
int
-do_mode_posix_iface_fileio_read (struct state *state)
+do_mode_posix_iface_fileio_read(struct state *state)
{
- long int i;
- int ret = -1;
- char block[state->block_size];
-
- for (i=0; i<state->count; i++) {
- int fd = -1;
- char filename[512];
-
- sprintf (filename, "%s.%06ld", state->prefix, i);
-
- fd = open (filename, O_RDONLY);
- if (fd == -1) {
- fprintf (stderr, "open(%s) => %s\n", filename, strerror (errno));
- break;
- }
- ret = read (fd, block, state->block_size);
- if (ret == -1) {
- fprintf (stderr, "read(%s) => %d/%s\n", filename, ret, strerror (errno));
- close (fd);
- break;
- }
- close (fd);
- state->io_size += ret;
+ long int i;
+ int ret = -1;
+ char block[state->block_size];
+
+ for (i = 0; i < state->count; i++) {
+ int fd = -1;
+ char filename[512];
+
+ sprintf(filename, "%s.%06ld", state->prefix, i);
+
+ fd = open(filename, O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "open(%s) => %s\n", filename, strerror(errno));
+ break;
}
+ ret = read(fd, block, state->block_size);
+ if (ret == -1) {
+ fprintf(stderr, "read(%s) => %d/%s\n", filename, ret,
+ strerror(errno));
+ close(fd);
+ break;
+ }
+ close(fd);
+ state->io_size += ret;
+ }
- return i;
+ return i;
}
-
int
-do_mode_posix_iface_fileio (struct state *state)
+do_mode_posix_iface_fileio(struct state *state)
{
- if (state->need_op_write)
- MEASURE (do_mode_posix_iface_fileio_write, state);
+ if (state->need_op_write)
+ MEASURE(do_mode_posix_iface_fileio_write, state);
- if (state->need_op_read)
- MEASURE (do_mode_posix_iface_fileio_read, state);
+ if (state->need_op_read)
+ MEASURE(do_mode_posix_iface_fileio_read, state);
- return 0;
+ return 0;
}
-
int
-do_mode_posix_iface_xattr_write (struct state *state)
+do_mode_posix_iface_xattr_write(struct state *state)
{
- long int i;
- int ret = -1;
- char block[state->block_size];
- char *dname = NULL, *dirc = NULL;
- char *bname = NULL, *basec = NULL;
-
- dirc = strdup (state->prefix);
- basec = strdup (state->prefix);
- dname = dirname (dirc);
- bname = basename (basec);
-
- for (i=0; i<state->count; i++) {
- char key[512];
-
- sprintf (key, "glusterfs.file.%s.%06ld", bname, i);
-
- ret = lsetxattr (dname, key, block, state->block_size, 0);
-
- if (ret != 0) {
- fprintf (stderr, "lsetxattr (%s, %s, %p) => %s\n",
- dname, key, block, strerror (errno));
- break;
- }
- state->io_size += state->block_size;
+ long int i;
+ int ret = -1;
+ char block[state->block_size];
+ char *dname = NULL, *dirc = NULL;
+ char *bname = NULL, *basec = NULL;
+
+ dirc = strdup(state->prefix);
+ basec = strdup(state->prefix);
+ dname = dirname(dirc);
+ bname = basename(basec);
+
+ for (i = 0; i < state->count; i++) {
+ char key[512];
+
+ sprintf(key, "glusterfs.file.%s.%06ld", bname, i);
+
+ ret = lsetxattr(dname, key, block, state->block_size, 0);
+
+ if (ret != 0) {
+ fprintf(stderr, "lsetxattr (%s, %s, %p) => %s\n", dname, key, block,
+ strerror(errno));
+ break;
}
+ state->io_size += state->block_size;
+ }
- free (dirc);
- free (basec);
+ free(dirc);
+ free(basec);
- return i;
+ return i;
}
-
int
-do_mode_posix_iface_xattr_read (struct state *state)
+do_mode_posix_iface_xattr_read(struct state *state)
{
- long int i;
- int ret = -1;
- char block[state->block_size];
- char *dname = NULL, *dirc = NULL;
- char *bname = NULL, *basec = NULL;
-
- dirc = strdup (state->prefix);
- basec = strdup (state->prefix);
- dname = dirname (dirc);
- bname = basename (basec);
-
- for (i=0; i<state->count; i++) {
- char key[512];
-
- sprintf (key, "glusterfs.file.%s.%06ld", bname, i);
-
- ret = lgetxattr (dname, key, block, state->block_size);
-
- if (ret < 0) {
- fprintf (stderr, "lgetxattr (%s, %s, %p) => %s\n",
- dname, key, block, strerror (errno));
- break;
- }
- state->io_size += ret;
+ long int i;
+ int ret = -1;
+ char block[state->block_size];
+ char *dname = NULL, *dirc = NULL;
+ char *bname = NULL, *basec = NULL;
+
+ dirc = strdup(state->prefix);
+ basec = strdup(state->prefix);
+ dname = dirname(dirc);
+ bname = basename(basec);
+
+ for (i = 0; i < state->count; i++) {
+ char key[512];
+
+ sprintf(key, "glusterfs.file.%s.%06ld", bname, i);
+
+ ret = lgetxattr(dname, key, block, state->block_size);
+
+ if (ret < 0) {
+ fprintf(stderr, "lgetxattr (%s, %s, %p) => %s\n", dname, key, block,
+ strerror(errno));
+ break;
}
+ state->io_size += ret;
+ }
- return i;
+ return i;
}
-
int
-do_mode_posix_iface_xattr (struct state *state)
+do_mode_posix_iface_xattr(struct state *state)
{
- if (state->need_op_write)
- MEASURE (do_mode_posix_iface_xattr_write, state);
+ if (state->need_op_write)
+ MEASURE(do_mode_posix_iface_xattr_write, state);
- if (state->need_op_read)
- MEASURE (do_mode_posix_iface_xattr_read, state);
+ if (state->need_op_read)
+ MEASURE(do_mode_posix_iface_xattr_read, state);
- return 0;
+ return 0;
}
int
-do_mode_posix (struct state *state)
+do_mode_posix(struct state *state)
{
- if (state->need_iface_fileio)
- do_mode_posix_iface_fileio (state);
+ if (state->need_iface_fileio)
+ do_mode_posix_iface_fileio(state);
- if (state->need_iface_xattr)
- do_mode_posix_iface_xattr (state);
+ if (state->need_iface_xattr)
+ do_mode_posix_iface_xattr(state);
- return 0;
+ return 0;
}
-
int
-do_actions (struct state *state)
+do_actions(struct state *state)
{
- if (state->need_mode_posix)
- do_mode_posix (state);
+ if (state->need_mode_posix)
+ do_mode_posix(state);
- return 0;
+ return 0;
}
static struct argp_option options[] = {
- {"op", 'o', "OPERATIONS", 0,
- "WRITE|READ|BOTH - defaults to BOTH"},
- {"iface", 'i', "INTERFACE", 0,
- "FILEIO|XATTR|BOTH - defaults to FILEIO"},
- {"block", 'b', "BLOCKSIZE", 0,
- "<NUM> - defaults to 4096"},
- {"specfile", 's', "SPECFILE", 0,
- "absolute path to specfile"},
- {"prefix", 'p', "PREFIX", 0,
- "filename prefix"},
- {"count", 'c', "COUNT", 0,
- "number of files"},
- {0, 0, 0, 0, 0}
-};
+ {"op", 'o', "OPERATIONS", 0, "WRITE|READ|BOTH - defaults to BOTH"},
+ {"iface", 'i', "INTERFACE", 0, "FILEIO|XATTR|BOTH - defaults to FILEIO"},
+ {"block", 'b', "BLOCKSIZE", 0, "<NUM> - defaults to 4096"},
+ {"specfile", 's', "SPECFILE", 0, "absolute path to specfile"},
+ {"prefix", 'p', "PREFIX", 0, "filename prefix"},
+ {"count", 'c', "COUNT", 0, "number of files"},
+ {0, 0, 0, 0, 0}};
-static struct argp argp = {
- options,
- parse_opts,
- "tool",
- "tool to benchmark small file performance"
-};
+static struct argp argp = {options, parse_opts, "tool",
+ "tool to benchmark small file performance"};
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- struct state state = {0, };
+ struct state state = {
+ 0,
+ };
- state.need_op_write = 1;
- state.need_op_read = 1;
+ state.need_op_write = 1;
+ state.need_op_read = 1;
- state.need_iface_fileio = 1;
- state.need_iface_xattr = 0;
+ state.need_iface_fileio = 1;
+ state.need_iface_xattr = 0;
- state.need_mode_posix = 1;
+ state.need_mode_posix = 1;
- state.block_size = 4096;
+ state.block_size = 4096;
- strcpy (state.prefix, "tmpfile");
- state.count = 1048576;
+ strcpy(state.prefix, "tmpfile");
+ state.count = 1048576;
- if (argp_parse (&argp, argc, argv, 0, 0, &state) != 0) {
- fprintf (stderr, "argp_parse() failed\n");
- return 1;
- }
+ if (argp_parse(&argp, argc, argv, 0, 0, &state) != 0) {
+ fprintf(stderr, "argp_parse() failed\n");
+ return 1;
+ }
- do_actions (&state);
+ do_actions(&state);
- return 0;
+ return 0;
}
diff --git a/extras/benchmarking/rdd.c b/extras/benchmarking/rdd.c
index a667c6a1d65..efc9d342a37 100644
--- a/extras/benchmarking/rdd.c
+++ b/extras/benchmarking/rdd.c
@@ -20,633 +20,586 @@
#define TWO_POWER(power) (2UL << (power))
-#define RDD_INTEGER_VALUE ((TWO_POWER ((sizeof (int) * 8))) - 1)
+#define RDD_INTEGER_VALUE ((TWO_POWER((sizeof(int) * 8))) - 1)
#ifndef UNIX_PATH_MAX
#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_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"
+#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;
- ssize_t file_size;
+ 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)
+rdd_parse_opts(int key, char *arg, 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",
- 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",
- arg);
- 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"
- "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) ||
- (tmp && *tmp)) {
- 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) ||
- (tmp && *tmp)) {
- fprintf (stderr, "invalid argument for max-ops"
- "(%s)\n", arg);
- return -1;
- }
+ 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;
+ }
- rdd_config.max_ops_per_seq = max_ops;
- }
- break;
+ strncpy(rdd_config.out_file.path, arg, len);
+ } 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"
- "(%s)\n", arg);
- return -1;
- }
+ 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);
+ 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"
+ "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) || (tmp && *tmp)) {
+ 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) ||
+ (tmp && *tmp)) {
+ 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) ||
+ (tmp && *tmp)) {
+ fprintf(stderr,
+ "invalid argument for thread count"
+ "(%s)\n",
+ arg);
+ return -1;
+ }
- rdd_config.thread_count = threads;
- }
- break;
+ rdd_config.thread_count = threads;
+ } break;
case ARGP_KEY_NO_ARGS:
- break;
+ break;
case ARGP_KEY_ARG:
- break;
+ break;
case ARGP_KEY_END:
- if (_state->argc == 1) {
- argp_usage (_state);
- }
+ if (_state->argc == 1) {
+ argp_usage(_state);
+ }
+ }
- }
-
- return 0;
+ return 0;
}
int
-string2bytesize (const char *str, unsigned long long *n)
+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;
+ 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;
}
-
- old_errno = errno;
- errno = 0;
- value = strtoull (str, &tail, 10);
-
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
+ if (*s == '-') {
+ return -1;
}
-
- if (errno == 0)
- {
- errno = old_errno;
+ 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;
}
- 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;
- }
+ else {
+ return -1;
}
+ }
- *n = value;
+ *n = value;
- return 0;
+ 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)"},
- {"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}
-};
+ {"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 = {
- rdd_options,
- rdd_parse_opts,
- "",
- "random dd - tool to do a sequence of random block-sized continuous"
- "read writes starting at a random offset"
-};
-
+ rdd_options, rdd_parse_opts, "",
+ "random dd - tool to do a sequence of random block-sized continuous"
+ "read writes starting at a random offset"};
static void
-rdd_default_config (void)
+rdd_default_config(void)
{
- 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;
+ 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)
+rdd_valid_config(void)
{
- char ret = 1;
- int fd = -1;
+ 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;
- }
+ 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);
- }
+ 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)
+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));
+ 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", strerror(errno));
ret = -1;
- goto out;
- }
+ goto unlock;
+ }
- 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",
- strerror (errno));
- ret = -1;
- goto unlock;
- }
-
- 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",
- strerror (errno));
- ret = -1;
- goto unlock;
- }
-
- if (write (rdd_config.out_file.fd, buf, bytes)
- != bytes) {
- fprintf (stderr, "write failed (%s)\n",
- strerror (errno));
- ret = -1;
- goto unlock;
- }
- }
+ 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;
}
- unlock:
- pthread_mutex_unlock (&rdd_config.lock);
- if (ret == -1) {
- goto out;
+
+ if (bytes == -1) {
+ fprintf(stderr, "read failed (%s)\n", strerror(errno));
+ ret = -1;
+ goto unlock;
+ }
+
+ if (write(rdd_config.out_file.fd, buf, bytes) != bytes) {
+ fprintf(stderr, "write failed (%s)\n", strerror(errno));
+ ret = -1;
+ goto unlock;
}
- ret = 0;
+ }
}
+ 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)
+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;
+ 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)
+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))
+ 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;
-
- fd[1] = open (rdd_config.in_file.path, O_CREAT | O_WRONLY | O_TRUNC);
- if (fd[1] == -1)
+ ret = write(fd[1], buf, 4096);
+ if (ret == -1)
goto out;
-
- fd[0] = open ("/dev/urandom", O_RDONLY);
- if (fd[0] == -1)
+ total_size = total_size - 4096;
+ } else {
+ ret = read(fd[0], buf, total_size);
+ if (ret == -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 = write(fd[1], buf, total_size);
+ if (ret == -1)
+ goto out;
+ total_size = total_size - total_size;
}
+ }
- ret = 0;
+ ret = 0;
out:
- if (fd[0] > 0)
- close (fd[0]);
- if (fd[1] > 0)
- close (fd[1]);
- return ret;
+ if (fd[0] > 0)
+ close(fd[0]);
+ if (fd[1] > 0)
+ close(fd[1]);
+ return ret;
}
static int
-rdd_spawn_threads (void)
+rdd_spawn_threads(void)
{
- int i = 0, ret = -1, fd = -1;
- char buf[4096];
-
- 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",
- rdd_config.in_file.path, strerror (errno));
- ret = -1;
- goto out;
- }
- rdd_config.in_file.fd = fd;
-
- 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",
- 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",
- strerror (errno));
- 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));
-
- ret = -1;
- cleanup ();
- goto out;
- }
-
- ret = pthread_barrier_init (&rdd_config.barrier, NULL,
- rdd_config.thread_count + 1);
- if (ret != 0) {
- fprintf (stderr, "pthread_barrier_init() failed (%s)\n",
- strerror (ret));
-
- free (rdd_config.threads);
- cleanup ();
- ret = -1;
- goto out;
+ int i = 0, ret = -1, fd = -1;
+ char buf[4096];
+
+ 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", rdd_config.in_file.path,
+ strerror(errno));
+ ret = -1;
+ goto out;
+ }
+ rdd_config.in_file.fd = fd;
+
+ 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", 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", strerror(errno));
+ cleanup();
+ ret = -1;
+ goto out;
}
-
- ret = pthread_mutex_init (&rdd_config.lock, NULL);
+ }
+
+ rdd_config.threads = calloc(rdd_config.thread_count, sizeof(pthread_t));
+ if (rdd_config.threads == NULL) {
+ fprintf(stderr, "calloc() failed (%s)\n", strerror(errno));
+
+ ret = -1;
+ cleanup();
+ goto out;
+ }
+
+ ret = pthread_barrier_init(&rdd_config.barrier, NULL,
+ rdd_config.thread_count + 1);
+ if (ret != 0) {
+ fprintf(stderr, "pthread_barrier_init() failed (%s)\n", strerror(ret));
+
+ 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);
+ 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_mutex_init() failed (%s)\n",
- strerror (ret));
-
- 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",
- strerror (errno));
- exit (1);
- }
+ fprintf(stderr, "pthread_create failed (%s)\n", strerror(errno));
+ exit(1);
}
+ }
out:
- return ret;
+ return ret;
}
static void
-rdd_wait_for_completion (void)
+rdd_wait_for_completion(void)
{
- pthread_barrier_wait (&rdd_config.barrier);
+ pthread_barrier_wait(&rdd_config.barrier);
}
-
int
-main (int argc, char *argv[])
+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",
- argv[0]);
- goto err;
- }
+ if (!rdd_valid_config()) {
+ ret = -1;
+ fprintf(stderr, "%s: configuration validation failed\n", argv[0]);
+ 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/clang-checker.sh b/extras/clang-checker.sh
new file mode 100755
index 00000000000..4909d3adfcd
--- /dev/null
+++ b/extras/clang-checker.sh
@@ -0,0 +1,301 @@
+#!/usr/bin/env bash
+#*******************************************************************************
+# *
+# Copyright (c) 2016 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. *
+#------------------------------------------------------------------------------*
+# *
+# clang-checker.sh: This script runs clang static analyzer using 'scan-build' *
+# a perl wrapper. After you commit your patch i.e. right *
+# before executing rfc.sh in order to push the patch to *
+# repository, it is recommended that you execute *
+# clang-checker.sh to perform static analysis inorder to *
+# check if there are any possible bugs in the code. *
+# *
+# This script performs the static analysis with and *
+# without HEAD commit, it runs the analyzer only in the *
+# directory where changes have been made and finally diff's *
+# the number of bugs using both cases (i.e. with and *
+# without your commit) and gives a summary, which explain's *
+# about the eligibility of your patch. *
+# *
+# Usage: $ cd $PATH_TO_GLUSTERFS *
+# $ extras/clang-checker.sh (or) $ make clang-check *
+# *
+# Author: Prasanna Kumar Kalever <prasanna.kalever@redhat.com> *
+# *
+#*******************************************************************************
+
+REPORTS_DIR=$(pwd)
+BASELINE_DIR=${REPORTS_DIR}/baseline
+BRESULTS_DIR=${BASELINE_DIR}/results
+BBACKUP_DIR=${BASELINE_DIR}/backup
+TARGET_DIR=${REPORTS_DIR}/target
+TRESULTS_DIR=${TARGET_DIR}/results
+TBACKUP_DIR=${TARGET_DIR}/backup
+
+declare -A DICT_B
+declare -A DICT_T
+declare -A ARR
+declare -A FILES
+
+function identify_changes () {
+ MODIFIED_DATA=$(git show --name-status --oneline | tail -n +2)
+ FLAG=0
+ for i in ${MODIFIED_DATA}; do
+ if [ $FLAG -eq 1 ]; then
+ ARR+="$(dirname $i) ";
+ FLAG=0;
+ fi
+ if [ $i = 'M' ] || [ $i = 'A' ]; then
+ FLAG=1;
+ fi
+ done
+
+ MODIFIED_DIR=$(echo "${ARR[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')
+ for i in $MODIFIED_DIR; do
+ # run only in directories which has Makefile
+ if [ $(find ./$i -iname "makefile*" | wc -c) -gt 0 ]; then
+ # skip 'doc' and '.'(top) directory
+ if [ "xx$i" != "xxdoc" ] && [ "xx$i" != "xx." ]; then
+ FILES+="$i "
+ fi
+ fi
+ done
+ if [ -z $FILES ]; then
+ echo "Probably no changes made to 'c' files"
+ exit;
+ fi
+}
+
+function check_prerequisites () {
+ if ! type "clang" 2> /dev/null; then
+ echo -e "\ntry after installing clang and scan-build..."
+ echo "useful info at http://clang-analyzer.llvm.org/installation.html\n"
+ echo -e "hint: 'dnf -y install clang-analyzer.noarch'\n"
+ exit 1;
+ elif ! type "scan-build" 2> /dev/null; then
+ echo -e "\ntry after installing scan-build..."
+ echo "useful info at http://clang-analyzer.llvm.org/installation.html"
+ echo -e "hint: 'dnf -y install clang-analyzer.noarch'\n"
+ exit 1;
+ fi
+}
+
+function force_terminate () {
+ echo -e "\nreceived a signal to force terminate ..\n"
+ git am --abort 2> /dev/null
+ git am ${PATCH_NAME}
+ rm -f ${REPORTS_DIR}/${PATCH_NAME}
+ exit 1;
+}
+
+function run_scanbuild () {
+ local CLANG=$(which clang)
+ local SCAN_BUILD=$(which scan-build)
+ local ORIG_COMMIT=$(git rev-parse --verify HEAD^)
+ PATCH_NAME=$(git format-patch $ORIG_COMMIT)
+
+ echo -e "\n| Performing clang analysis on:" \
+ "$(git log --pretty=format:"%h - '%s' by %an" -1) ... |\n"
+ echo -e "Changes are identified in '${FILES[@]}' directorie[s]\n"
+
+ if [ -d "${BRESULTS_DIR}" ]; then
+ mkdir -p ${BBACKUP_DIR} ${TBACKUP_DIR}
+ mv ${BRESULTS_DIR} \
+ ${BBACKUP_DIR}/results_$(ls -l ${BBACKUP_DIR} | wc -l)
+ mv ${TRESULTS_DIR} \
+ ${TBACKUP_DIR}/results_$(ls -l ${TBACKUP_DIR} | wc -l)
+ fi
+ for DIR in ${FILES[@]}; do
+ mkdir -p ${BRESULTS_DIR}/$(echo ${DIR} | sed 's/\//_/g')
+ mkdir -p ${TRESULTS_DIR}/$(echo ${DIR} | sed 's/\//_/g')
+ done
+ # get nproc info
+ case $(uname -s) in
+ 'Linux')
+ local NPROC=$(getconf _NPROCESSORS_ONLN)
+ ;;
+ 'NetBSD')
+ local NPROC=$(getconf NPROCESSORS_ONLN)
+ ;;
+ esac
+
+ trap force_terminate INT TERM QUIT EXIT
+
+ git reset --hard HEAD^
+
+ # build complete source code for sake of dependencies
+ echo -e "\n# make -j${NPROC} ..."
+ make -j${NPROC} 1>/dev/null
+
+ for DIR in ${FILES[@]}; do
+ if [ $(find ./$i -iname "makefile*" | wc -c) -gt 0 ]; then
+ make clean -C ${DIR} 1>/dev/null
+ echo -e "\n| Analyzing ${DIR} without commit ... |\n"
+ # run only in directory where changes are made
+ ${SCAN_BUILD} -o ${BRESULTS_DIR}/$(echo ${DIR} | sed 's/\//_/g') \
+ --use-analyzer=${CLANG} make -j${NPROC} -C ${DIR}
+ fi
+ done
+
+ echo -e "\n| Analyzing without commit complete ... |\n"
+
+ git am ${PATCH_NAME}
+ trap - INT TERM QUIT EXIT
+
+ # In case commit has changes to configure stuff ?
+ echo -e "\n# make clean ..."
+ make clean 1>/dev/null
+ echo -e "\n# ./autogen.sh && ./configure --with-previous-options ..."
+ ${REPORTS_DIR}/autogen.sh 2>/dev/null
+ ${REPORTS_DIR}/configure --with-previous-options 1>/dev/null
+ echo -e "\n# make -j${NPROC} ..."
+ make -j${NPROC} 1>/dev/null
+
+ for DIR in ${FILES[@]}; do
+ if [ $(find ./$i -iname "makefile*" | wc -c) -gt 0 ]; then
+ make clean -C ${DIR} 1>/dev/null
+ echo -e "\n| Analyzing ${DIR} with commit ... |\n"
+ # run only in directory where changes are made
+ ${SCAN_BUILD} -o ${TRESULTS_DIR}/$(echo ${DIR} | sed 's/\//_/g') \
+ --use-analyzer=${CLANG} make -j${NPROC} -C ${DIR}
+ fi
+ done
+
+ echo -e "\n| Analyzing with commit complete ... |\n"
+
+ rm -f ${REPORTS_DIR}/${PATCH_NAME}
+}
+
+function count_for_baseline () {
+ for DIR in ${FILES[@]}; do
+ HTMLS_DIR=${BRESULTS_DIR}/$(echo ${DIR} |
+ sed 's/\//_/g')/$(ls ${BRESULTS_DIR}/$(echo ${DIR} |
+ sed 's/\//_/g')/);
+
+ local NAMES_OF_BUGS_B=$(grep -n "SUMM_DESC" ${HTMLS_DIR}/index.html |
+ cut -d"<" -f3 | cut -d">" -f2 |
+ sed 's/[^a-zA-Z0]/_/g' | tr '\n' ' ')
+ local NO_OF_BUGS_B=$(grep -n "SUMM_DESC" ${HTMLS_DIR}/index.html |
+ cut -d"<" -f5 | cut -d">" -f2 | tr '\n' ' ')
+ local count_B=0;
+
+ read -a BUG_NAME_B <<<$NAMES_OF_BUGS_B
+ read -a BUG_COUNT_B <<<$NO_OF_BUGS_B
+ for i in ${BUG_NAME_B[@]};
+ do
+ if [ ! -z ${DICT_B[$i]} ]; then
+ DICT_B[$i]=$(expr ${BUG_COUNT_B[count_B]} + ${DICT_B[$i]});
+ else
+ DICT_B+=([$i]=${BUG_COUNT_B[count_B]});
+ fi
+ count_B=$(expr $count_B + 1)
+ done
+ done
+
+ echo -e "\nBASELINE BUGS LIST (before applying patch):"
+ echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+ for key_B in ${!DICT_B[@]}; do
+ echo "${key_B} --> ${DICT_B[${key_B}]}" | sed 's/_/ /g' | tr -s ' '
+ done
+}
+
+function count_for_target () {
+ for DIR in ${FILES[@]}; do
+ HTMLS_DIR=${TRESULTS_DIR}/$(echo ${DIR} |
+ sed 's/\//_/g')/$(ls ${TRESULTS_DIR}/$(echo ${DIR} |
+ sed 's/\//_/g')/);
+
+ local NAME_OF_BUGS_T=$(grep -n "SUMM_DESC" ${HTMLS_DIR}/index.html |
+ cut -d"<" -f3 | cut -d">" -f2 |
+ sed 's/[^a-zA-Z0]/_/g'| tr '\n' ' ')
+ local NO_OF_BUGS_T=$(grep -n "SUMM_DESC" ${HTMLS_DIR}/index.html |
+ cut -d"<" -f5 | cut -d">" -f2 | tr '\n' ' ')
+ local count_T=0;
+
+ read -a BUG_NAME_T <<<$NAME_OF_BUGS_T
+ read -a BUG_COUNT_T <<<$NO_OF_BUGS_T
+
+ for i in ${BUG_NAME_T[@]};
+ do
+ if [ ! -z ${DICT_T[$i]} ]; then
+ DICT_T[$i]=$(expr ${BUG_COUNT_T[count_T]} + ${DICT_T[$i]});
+ else
+ DICT_T+=([$i]=${BUG_COUNT_T[count_T]});
+ fi
+ count_T=$(expr $count_T + 1)
+ done
+ done
+
+ echo -e "\nTARGET BUGS LIST (after applying patch):"
+ echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+ for key_T in ${!DICT_T[@]}; do
+ echo "${key_T} --> ${DICT_T[${key_T}]}" | sed 's/_/ /g' | tr -s ' '
+ done
+}
+
+function array_contains () {
+ local SEEKING=$1; shift
+ local IN=1
+ for ELEMENT; do
+ if [[ $ELEMENT == $SEEKING ]]; then
+ IN=0
+ break
+ fi
+ done
+ return $IN
+}
+
+function main () {
+ echo -e "\n================ Clang analyzer in progress ================\n"
+ check_prerequisites
+ identify_changes
+ run_scanbuild
+ clear
+ count_for_baseline
+ count_for_target
+ echo -e "\nSUMMARY OF CLANG-ANALYZER:"
+ echo "~~~~~~~~~~~~~~~~~~~~~~~~~~"
+
+ FLAG=0
+ for BUG in ${!DICT_T[@]}; do
+ array_contains $BUG "${!DICT_B[@]}"
+ if [ $? -eq 1 ]; then
+ echo "New ${DICT_T[${BUG}]} Bug[s] introduced: $(echo $BUG |
+ sed 's/_/ /g' |
+ tr -s ' ')"
+ FLAG=1
+ else
+ if [ ${BUG} != "All_Bugs" ]; then
+ if [ ${DICT_B[${BUG}]} -lt \
+ ${DICT_T[${BUG}]} ]; then
+ echo "Extra $(expr ${DICT_T[${BUG}]} - \
+ ${DICT_B[${BUG}]}) Bug[s] Introduced in: $(echo $BUG |
+ sed 's/_/ /g' | tr -s ' ')"
+ FLAG=1
+ fi
+ fi
+ fi
+ done
+
+ echo
+ if [ $FLAG -eq 0 ]; then
+ echo -e "Patch Value given by Clang analyzer '+1'\n"
+ else
+ echo -e "Patch Value given by Clang analyzer '-1'\n"
+ fi
+ echo -e "\nExplore complete results at:"
+ find ${BRESULTS_DIR}/ -iname "index.html"
+ find ${TRESULTS_DIR}/ -iname "index.html"
+ echo -e "\n================= Done with Clang Analysis =================\n"
+
+ exit ${FLAG}
+}
+
+main
diff --git a/extras/cliutils/Makefile.am b/extras/cliutils/Makefile.am
new file mode 100644
index 00000000000..7039703e275
--- /dev/null
+++ b/extras/cliutils/Makefile.am
@@ -0,0 +1,4 @@
+EXTRA_DIST= cliutils.py __init__.py
+
+cliutilsdir = @BUILD_PYTHON_SITE_PACKAGES@/gluster/cliutils
+cliutils_PYTHON = cliutils.py __init__.py
diff --git a/extras/cliutils/README.md b/extras/cliutils/README.md
new file mode 100644
index 00000000000..309beb1ca25
--- /dev/null
+++ b/extras/cliutils/README.md
@@ -0,0 +1,233 @@
+# CLI utility for creating Cluster aware CLI tools for Gluster
+cliutils is a Python library which provides wrapper around `gluster system::
+execute` command to extend the functionalities of Gluster.
+
+Example use cases:
+- Start a service in all peer nodes of Cluster
+- Collect the status of a service from all peer nodes
+- Collect the config values from each peer nodes and display latest
+ config based on version.
+- Copy a file present in GLUSTERD_WORKDIR from one peer node to all
+ other peer nodes.(Geo-replication create push-pem is using this to
+ distribute the SSH public keys from all master nodes to all slave
+ nodes)
+- Generate pem keys in all peer nodes and collect all the public keys
+ to one place(Geo-replication gsec_create is doing this)
+- Provide Config sync CLIs for new features like `gluster-eventsapi`,
+ `gluster-restapi`, `gluster-mountbroker` etc.
+
+## Introduction
+
+If a executable file present in `$GLUSTER_LIBEXEC` directory in all
+peer nodes(Filename startswith `peer_`) then it can be executed by
+running `gluster system:: execute` command from any one peer node.
+
+- This command will not copy any executables to peer nodes, Script
+ should exist in all peer nodes to use this infrastructure. Raises
+ error in case script not exists in any one of the peer node.
+- Filename should start with `peer_` and should exist in
+ `$GLUSTER_LIBEXEC` directory.
+- This command can not be called from outside the cluster.
+
+To understand the functionality, create a executable file `peer_hello`
+under $GLUSTER_LIBEXEC directory and copy to all peer nodes.
+
+ #!/usr/bin/env bash
+ echo "Hello from $(gluster system:: uuid get)"
+
+Now run the following command from any one gluster node,
+
+ gluster system:: execute hello
+
+**Note:** Gluster will not copy the executable script to all nodes,
+ copy `peer_hello` script to all peer nodes to use `gluster system::
+ execute` infrastructure.
+
+It will run `peer_hello` executable in all peer nodes and shows the
+output from each node(Below example shows output from my two nodes
+cluster)
+
+ Hello from UUID: e7a3c5c8-e7ad-47ad-aa9c-c13907c4da84
+ Hello from UUID: c680fc0a-01f9-4c93-a062-df91cc02e40f
+
+## cliutils
+A Python wrapper around `gluster system:: execute` command is created
+to address the following issues
+
+- If a node is down in the cluster, `system:: execute` just skips it
+ and runs only in up nodes.
+- `system:: execute` commands are not user friendly
+- It captures only stdout, so handling errors is tricky.
+
+**Advantages of cliutils:**
+
+- Single executable file will act as node component as well as User CLI.
+- `execute_in_peers` utility function will merge the `gluster system::
+ execute` output with `gluster peer status` to identify offline nodes.
+- Easy CLI Arguments handling.
+- If node component returns non zero return value then, `gluster
+ system:: execute` will fail to aggregate the output from other
+ nodes. `node_output_ok` or `node_output_notok` utility functions
+ returns zero both in case of success or error, but returns json
+ with ok: true or ok:false respectively.
+- Easy to iterate on the node outputs.
+- Better error handling - Geo-rep CLIs `gluster system:: execute
+ mountbroker`, `gluster system:: execute gsec_create` and `gluster
+ system:: add_secret_pub` are suffering from error handling. These
+ tools are not notifying user if any failures during execute or if a node
+ is down during execute.
+
+### Hello World
+Create a file in `$LIBEXEC/glusterfs/peer_message.py` with following
+content.
+
+ #!/usr/bin/python3
+ from gluster.cliutils import Cmd, runcli, execute_in_peers, node_output_ok
+
+ class NodeHello(Cmd):
+ name = "node-hello"
+
+ def run(self, args):
+ node_output_ok("Hello")
+
+ class Hello(Cmd):
+ name = "hello"
+
+ def run(self, args):
+ out = execute_in_peers("node-hello")
+ for row in out:
+ print ("{0} from {1}".format(row.output, row.hostname))
+
+ if __name__ == "__main__":
+ runcli()
+
+When we run `python peer_message.py`, it will have two subcommands,
+"node-hello" and "hello". This file should be copied to
+`$LIBEXEC/glusterfs` directory in all peer nodes. User will call
+subcommand "hello" from any one peer node, which internally call
+`gluster system:: execute message.py node-hello`(This runs in all peer
+nodes and collect the outputs)
+
+For node component do not print the output directly, use
+`node_output_ok` or `node_output_notok` functions. `node_output_ok`
+additionally collects the node UUID and prints in JSON
+format. `execute_in_peers` function will collect this output and
+merges with `peers list` so that we don't miss the node information if
+that node is offline.
+
+If you observed already, function `args` is optional, if you don't
+have arguments then no need to create a function. When we run the
+file, we will have two subcommands. For example,
+
+ python peer_message.py hello
+ python peer_message.py node-hello
+
+First subcommand calls second subcommand in all peer nodes. Basically
+`execute_in_peers(NAME, ARGS)` will be converted into
+
+ CMD_NAME = FILENAME without "peers_"
+ gluster system:: execute <CMD_NAME> <SUBCOMMAND> <ARGS>
+
+In our example,
+
+ filename = "peer_message.py"
+ cmd_name = "message.py"
+ gluster system:: execute ${cmd_name} node-hello
+
+Now create symlink in `/usr/bin` or `/usr/sbin` directory depending on
+the usecase.(Optional step for usability)
+
+ ln -s /usr/libexec/glusterfs/peer_message.py /usr/bin/gluster-message
+
+Now users can use `gluster-message` instead of calling
+`/usr/libexec/glusterfs/peer_message.py`
+
+ gluster-message hello
+
+### Showing CLI output as Table
+
+Following example uses prettytable library, which can be installed
+using `pip install prettytable` or `dnf install python-prettytable`
+
+ #!/usr/bin/python3
+ from prettytable import PrettyTable
+ from gluster.cliutils import Cmd, runcli, execute_in_peers, node_output_ok
+
+ class NodeHello(Cmd):
+ name = "node-hello"
+
+ def run(self, args):
+ node_output_ok("Hello")
+
+ class Hello(Cmd):
+ name = "hello"
+
+ def run(self, args):
+ out = execute_in_peers("node-hello")
+ # Initialize the CLI table
+ table = PrettyTable(["ID", "NODE", "NODE STATUS", "MESSAGE"])
+ table.align["NODE STATUS"] = "r"
+ for row in out:
+ table.add_row([row.nodeid,
+ row.hostname,
+ "UP" if row.node_up else "DOWN",
+ row.output if row.ok else row.error])
+
+ print table
+
+ if __name__ == "__main__":
+ runcli()
+
+
+Example output,
+
+ +--------------------------------------+-----------+-------------+---------+
+ | ID | NODE | NODE STATUS | MESSAGE |
+ +--------------------------------------+-----------+-------------+---------+
+ | e7a3c5c8-e7ad-47ad-aa9c-c13907c4da84 | localhost | UP | Hello |
+ | bb57a4c4-86eb-4af5-865d-932148c2759b | vm2 | UP | Hello |
+ | f69b918f-1ffa-4fe5-b554-ee10f051294e | vm3 | DOWN | N/A |
+ +--------------------------------------+-----------+-------------+---------+
+
+## How to package in Gluster
+If the project is created in `$GLUSTER_SRC/tools/message`
+
+Add "message" to SUBDIRS list in `$GLUSTER_SRC/tools/Makefile.am`
+
+and then create a `Makefile.am` in `$GLUSTER_SRC/tools/message`
+directory with following content.
+
+ EXTRA_DIST = peer_message.py
+
+ peertoolsdir = $(libexecdir)/glusterfs/
+ peertools_SCRIPTS = peer_message.py
+
+ install-exec-hook:
+ $(mkdir_p) $(DESTDIR)$(bindir)
+ rm -f $(DESTDIR)$(bindir)/gluster-message
+ ln -s $(libexecdir)/glusterfs/peer_message.py \
+ $(DESTDIR)$(bindir)/gluster-message
+
+ uninstall-hook:
+ rm -f $(DESTDIR)$(bindir)/gluster-message
+
+Thats all. Add following files in `glusterfs.spec.in` if packaging is
+required.(Under `%files` section)
+
+ %{_libexecdir}/glusterfs/peer_message.py*
+ %{_bindir}/gluster-message
+
+## Who is using cliutils
+- gluster-mountbroker http://review.gluster.org/14544
+- gluster-eventsapi http://review.gluster.org/14248
+- gluster-georep-sshkey http://review.gluster.org/14732
+- gluster-restapi https://github.com/gluster/restapi
+
+## Limitations/TODOs
+- Not yet possible to create CLI without any subcommand, For example
+ `gluster-message` without any arguments
+- Hiding node subcommands in `--help`(`gluster-message --help` will
+ show all subcommands including node subcommands)
+- Only positional arguments supported for node arguments, Optional
+ arguments can be used for other commands.
+- API documentation
diff --git a/extras/cliutils/__init__.py b/extras/cliutils/__init__.py
new file mode 100644
index 00000000000..8765cc85099
--- /dev/null
+++ b/extras/cliutils/__init__.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Reexporting the utility funcs and classes
+from .cliutils import (runcli,
+ sync_file_to_peers,
+ execute_in_peers,
+ execute,
+ node_output_ok,
+ node_output_notok,
+ output_error,
+ oknotok,
+ yesno,
+ get_node_uuid,
+ Cmd,
+ GlusterCmdException,
+ set_common_args_func)
+
+
+# This will be useful when `from cliutils import *`
+__all__ = ["runcli",
+ "sync_file_to_peers",
+ "execute_in_peers",
+ "execute",
+ "node_output_ok",
+ "node_output_notok",
+ "output_error",
+ "oknotok",
+ "yesno",
+ "get_node_uuid",
+ "Cmd",
+ "GlusterCmdException",
+ "set_common_args_func"]
diff --git a/extras/cliutils/cliutils.py b/extras/cliutils/cliutils.py
new file mode 100644
index 00000000000..55fbaf56704
--- /dev/null
+++ b/extras/cliutils/cliutils.py
@@ -0,0 +1,237 @@
+# -*- coding: utf-8 -*-
+from __future__ import print_function
+from argparse import ArgumentParser, RawDescriptionHelpFormatter
+import inspect
+import subprocess
+import os
+import xml.etree.cElementTree as etree
+import json
+import sys
+
+MY_UUID = None
+parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter,
+ description=__doc__)
+subparsers = parser.add_subparsers(dest="mode")
+
+subcommands = {}
+cache_data = {}
+ParseError = etree.ParseError if hasattr(etree, 'ParseError') else SyntaxError
+_common_args_func = lambda p: True
+
+
+class GlusterCmdException(Exception):
+ def __init__(self, message):
+ self.message = message
+ try:
+ # Python 3
+ super().__init__(message)
+ except TypeError:
+ # Python 2
+ super(GlusterCmdException, self).__init__(message)
+
+
+def get_node_uuid():
+ # Caches the Node UUID in global variable,
+ # Executes gluster system:: uuid get command only if
+ # calling this function for first time
+ global MY_UUID
+ if MY_UUID is not None:
+ return MY_UUID
+
+ cmd = ["gluster", "system::", "uuid", "get", "--xml"]
+ rc, out, err = execute(cmd)
+
+ if rc != 0:
+ return None
+
+ tree = etree.fromstring(out)
+ uuid_el = tree.find("uuidGenerate/uuid")
+ MY_UUID = uuid_el.text
+ return MY_UUID
+
+
+def yesno(flag):
+ return "Yes" if flag else "No"
+
+
+def oknotok(flag):
+ return "OK" if flag else "NOT OK"
+
+
+def output_error(message, errcode=1):
+ print (message, file=sys.stderr)
+ sys.exit(errcode)
+
+
+def node_output_ok(message=""):
+ # Prints Success JSON output and exits with returncode zero
+ out = {"ok": True, "nodeid": get_node_uuid(), "output": message}
+ print (json.dumps(out))
+ sys.exit(0)
+
+
+def node_output_notok(message):
+ # Prints Error JSON output and exits with returncode zero
+ out = {"ok": False, "nodeid": get_node_uuid(), "error": message}
+ print (json.dumps(out))
+ sys.exit(0)
+
+
+def execute(cmd):
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ universal_newlines=True)
+ out, err = p.communicate()
+ return p.returncode, out, err
+
+
+def get_pool_list():
+ cmd = ["gluster", "--mode=script", "pool", "list", "--xml"]
+ rc, out, err = execute(cmd)
+ if rc != 0:
+ output_error("Failed to get Pool Info: {0}".format(err))
+
+ tree = etree.fromstring(out)
+
+ pool = []
+ try:
+ for p in tree.findall('peerStatus/peer'):
+ pool.append({"nodeid": p.find("uuid").text,
+ "hostname": p.find("hostname").text,
+ "connected": (True if p.find("connected").text == "1"
+ else False)})
+ except (ParseError, AttributeError, ValueError) as e:
+ output_error("Failed to parse Pool Info: {0}".format(e))
+
+ return pool
+
+
+class NodeOutput(object):
+ def __init__(self, **kwargs):
+ self.nodeid = kwargs.get("nodeid", "")
+ self.hostname = kwargs.get("hostname", "")
+ self.node_up = kwargs.get("node_up", False)
+ self.ok = kwargs.get("ok", False)
+ self.output = kwargs.get("output", "N/A")
+ self.error = kwargs.get("error", "N/A")
+
+
+def execute_in_peers(name, args=[]):
+ # Get the file name of Caller function, If the file name is peer_example.py
+ # then Gluster peer command will be gluster system:: execute example.py
+ # Command name is without peer_
+ frame = inspect.stack()[1]
+ module = inspect.getmodule(frame[0])
+ actual_file = module.__file__
+ # If file is symlink then find actual file
+ if os.path.islink(actual_file):
+ actual_file = os.readlink(actual_file)
+
+ # Get the name of file without peer_
+ cmd_name = os.path.basename(actual_file).replace("peer_", "")
+ cmd = ["gluster", "system::", "execute", cmd_name, name] + args
+ rc, out, err = execute(cmd)
+ if rc != 0:
+ raise GlusterCmdException((rc, out, err, " ".join(cmd)))
+
+ out = out.strip().splitlines()
+
+ # JSON decode each line and construct one object with node id as key
+ all_nodes_data = {}
+ for node_data in out:
+ data = json.loads(node_data)
+ all_nodes_data[data["nodeid"]] = {
+ "nodeid": data.get("nodeid"),
+ "ok": data.get("ok"),
+ "output": data.get("output", ""),
+ "error": data.get("error", "")}
+
+ # gluster pool list
+ pool_list = get_pool_list()
+
+ data_out = []
+ # Iterate pool_list and merge all_nodes_data collected above
+ # If a peer node is down then set node_up = False
+ for p in pool_list:
+ p_data = all_nodes_data.get(p.get("nodeid"), None)
+ row_data = NodeOutput(node_up=False,
+ hostname=p.get("hostname"),
+ nodeid=p.get("nodeid"),
+ ok=False)
+
+ if p_data is not None:
+ # Node is UP
+ row_data.node_up = True
+ row_data.ok = p_data.get("ok")
+ row_data.output = p_data.get("output")
+ row_data.error = p_data.get("error")
+
+ data_out.append(row_data)
+
+ return data_out
+
+
+def sync_file_to_peers(fname):
+ # Copy file from current node to all peer nodes, fname
+ # is path after GLUSTERD_WORKDIR
+ cmd = ["gluster", "system::", "copy", "file", fname]
+ rc, out, err = execute(cmd)
+ if rc != 0:
+ raise GlusterCmdException((rc, out, err))
+
+
+class Cmd(object):
+ name = ""
+
+ def run(self, args):
+ # Must required method. Raise NotImplementedError if derived class
+ # not implemented this method
+ raise NotImplementedError("\"run(self, args)\" method is "
+ "not implemented by \"{0}\"".format(
+ self.__class__.__name__))
+
+
+def runcli():
+ # Get list of Classes derived from class "Cmd" and create
+ # a subcommand as specified in the Class name. Call the args
+ # method by passing subcommand parser, Derived class can add
+ # arguments to the subcommand parser.
+ metavar_data = []
+ for c in Cmd.__subclasses__():
+ cls = c()
+ if getattr(cls, "name", "") == "":
+ raise NotImplementedError("\"name\" is not added "
+ "to \"{0}\"".format(
+ cls.__class__.__name__))
+
+ # Do not show in help message if subcommand starts with node-
+ if not cls.name.startswith("node-"):
+ metavar_data.append(cls.name)
+
+ p = subparsers.add_parser(cls.name)
+ args_func = getattr(cls, "args", None)
+ if args_func is not None:
+ args_func(p)
+
+ # Apply common args if any
+ _common_args_func(p)
+
+ # A dict to save subcommands, key is name of the subcommand
+ subcommands[cls.name] = cls
+
+ # Hide node commands in Help message
+ subparsers.metavar = "{" + ",".join(metavar_data) + "}"
+
+ # Get all parsed arguments
+ args = parser.parse_args()
+
+ # Get the subcommand to execute
+ cls = subcommands.get(args.mode, None)
+
+ # Run
+ if cls is not None:
+ cls.run(args)
+
+
+def set_common_args_func(func):
+ global _common_args_func
+ _common_args_func = func
diff --git a/extras/collect-system-stats.sh b/extras/collect-system-stats.sh
new file mode 100755
index 00000000000..865e70bbc11
--- /dev/null
+++ b/extras/collect-system-stats.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+################################################################################
+# Usage: collect-system-stats.sh <delay-in-seconds>
+# This script starts sar/top/iostat/vmstat processes which collect system stats
+# with the interval <delay-in-seconds> given as argument to the script. When
+# the script is stopped either by entering any input or Ctrl+C the list of
+# files where output is captured will be printed on the screen which can be
+# observed to find any problems/bottlenecks.
+###############################################################################
+
+function stop_processes {
+ echo "Stopping the monitoring processes"
+ echo "sar pid:$sar_pid", "top pid: $top_pid", "iostat pid: $iostat_pid", "vmstat pid: $vmstat_pid"
+ kill "$sar_pid" "$top_pid" "$iostat_pid" "$vmstat_pid"
+ echo "Files created: ${timestamp}-network.out, ${timestamp}-top.out, ${timestamp}-iostat.out, ${timestamp}-vmstat.out"
+}
+
+function check_dependent_commands_exist()
+{
+ declare -a arr=("sar" "top" "iostat" "vmstat")
+ for i in "${arr[@]}"
+ do
+ if ! command -v "$i" > /dev/null 2>&1
+ then
+ echo "ERROR: '$i' command is not found"
+ exit 1
+ fi
+ done
+
+}
+
+case "$1" in
+ ''|*[!0-9]*) echo "Usage: $0 <delay-between-successive-metrics-collection-in-seconds>"; exit 1 ;;
+ *) interval="$1" ;;
+esac
+
+timestamp=$(date +"%s")
+
+check_dependent_commands_exist
+sar -n DEV "$interval" > "${timestamp}"-network.out &
+sar_pid="$!"
+top -bHd "$interval" > "${timestamp}"-top.out &
+top_pid="$!"
+iostat -Ntkdx "$interval" > "${timestamp}"-iostat.out &
+iostat_pid="$!"
+vmstat -t "$interval" > "${timestamp}"-vmstat.out &
+vmstat_pid="$!"
+echo "Started sar, vmstat, iostat, top for collecting stats"
+
+
+trap stop_processes EXIT
+read -r -p "Press anything and ENTER to exit";
diff --git a/extras/command-completion/gluster.bash b/extras/command-completion/gluster.bash
index 680ecd964d5..73d16098875 100644
--- a/extras/command-completion/gluster.bash
+++ b/extras/command-completion/gluster.bash
@@ -26,28 +26,28 @@ GLUSTER_TOP_SUBOPTIONS2="
"
GLUSTER_TOP_OPTIONS="
{open
- [ $TOP_SUBOPTIONS1 ]
+ [ $GLUSTER_TOP_SUBOPTIONS1 ]
},
{read
- [ $TOP_SUBOPTIONS1 ]
+ [ $GLUSTER_TOP_SUBOPTIONS1 ]
},
{write
- [ $TOP_SUBOPTIONS1 ]
+ [ $GLUSTER_TOP_SUBOPTIONS1 ]
},
{opendir
- [ $TOP_SUBOPTIONS1 ]
+ [ $GLUSTER_TOP_SUBOPTIONS1 ]
},
{readdir
- [ $TOP_SUBOPTIONS1 ]
+ [ $GLUSTER_TOP_SUBOPTIONS1 ]
},
{clear
- [ $TOP_SUBOPTIONS1 ]
+ [ $GLUSTER_TOP_SUBOPTIONS1 ]
},
{read-perf
- [ $TOP_SUBOPTIONS2 ]
+ [ $GLUSTER_TOP_SUBOPTIONS2 ]
},
{write-perf
- [ $TOP_SUBOPTIONS2 ]
+ [ $GLUSTER_TOP_SUBOPTIONS2 ]
}
"
@@ -282,16 +282,16 @@ _gluster_throw () {
exit
}
-declare FINAL_LIST=''
-declare LIST=''
-declare -i TOP=0
+declare GLUSTER_FINAL_LIST=''
+declare GLUSTER_LIST=''
+declare -i GLUSTER_TOP=0
_gluster_push () {
- TOP=$((TOP + 1))
- return $TOP
+ GLUSTER_TOP=$((GLUSTER_TOP + 1))
+ return $GLUSTER_TOP
}
_gluster_pop () {
- TOP=$((TOP - 1))
- return $TOP
+ GLUSTER_TOP=$((GLUSTER_TOP - 1))
+ return $GLUSTER_TOP
}
_gluster_goto_end ()
@@ -333,7 +333,7 @@ _gluster_form_list ()
top=$?
read -r key
if [ "X$cur_word" == "X" -o "${cur_word:0:1}" == "${key:0:1}" -o "${key:0:1}" == "_" ]; then
- LIST="$LIST $key"
+ GLUSTER_LIST="$GLUSTER_LIST $key"
fi
_gluster_goto_end $top
@@ -452,10 +452,10 @@ _gluster_parse ()
elif [ "$token" == '{' ]; then
read -r tmp_token
- LIST="$tmp_token"
+ GLUSTER_LIST="$tmp_token"
fi
- echo $LIST
+ echo $GLUSTER_LIST
}
_gluster_handle_list ()
@@ -479,12 +479,12 @@ _gluster_handle_list ()
_gluster_completion ()
{
- FINAL_LIST=`echo $GLUSTER_COMMAND_TREE | \
+ GLUSTER_FINAL_LIST=`echo $GLUSTER_COMMAND_TREE | \
egrep -ao --color=never "([A-Za-z0-9_.-]+)|[[:space:]]+|." | \
egrep -v --color=never "^[[:space:]]*$" | \
_gluster_parse`
- ARG="FINAL_LIST"
+ ARG="GLUSTER_FINAL_LIST"
_gluster_handle_list $ARG ${COMP_WORDS[COMP_CWORD]}
return
}
diff --git a/extras/control-cpu-load.sh b/extras/control-cpu-load.sh
new file mode 100755
index 00000000000..52dcf62fd9f
--- /dev/null
+++ b/extras/control-cpu-load.sh
@@ -0,0 +1,116 @@
+#!/bin/bash
+
+USAGE="This script provides a utility to control CPU utilization for any
+gluster daemon.In this, we use cgroup framework to configure CPU quota
+for a process(like selfheal daemon). Before running this script, make
+sure that daemon is running.Every time daemon restarts, it is required
+to rerun this command to set CPU quota on new daemon process id.
+User can enter any value between 10 to 100 for CPU quota.
+Recommended value of quota period is 25. 25 means, kernel will allocate
+25 ms period to this group of tasks in every 100 ms period. This 25ms
+could be considered as the maximum percentage of CPU quota daemon can take.
+This value will be reflected on CPU usage of "top" command.If provided pid
+is the only process and no other process is in competition to get CPU, more
+ than 25% could be allocated to daemon to speed up the process."
+
+if [ $# -ge 1 ]; then
+ case $1 in
+ -h|--help) echo " " "$USAGE" | sed -r -e 's/^[ ]+//g'
+ exit 0;
+ ;;
+ *) echo "Please Provide correct input for script."
+ echo "For help correct options are -h or --help."
+ exit 1;
+ ;;
+ esac
+fi
+
+DIR_EXIST=0
+LOC="/sys/fs/cgroup/cpu,cpuacct/system.slice/glusterd.service"
+echo "Enter gluster daemon pid for which you want to control CPU."
+read daemon_pid
+
+if expr ${daemon_pid} + 0 > /dev/null 2>&1 ;then
+ CHECK_PID=$(pgrep -f gluster | grep ${daemon_pid})
+ if [ -z "${CHECK_PID}" ]; then
+ echo "No daemon is running or pid ${daemon_pid} does not match."
+ echo "with running gluster processes."
+ exit 1
+ fi
+else
+ echo "Entered daemon_pid is not numeric so Rerun the script."
+ exit 1
+fi
+
+
+if [ -f ${LOC}/tasks ];then
+ CHECK_CGROUP=$(grep ${daemon_pid} ${LOC}/tasks)
+ if [ ${CHECK_CGROUP} ]; then
+ echo "pid ${daemon_pid} is attached with glusterd.service cgroup."
+ fi
+fi
+
+cgroup_name=cgroup_gluster_${daemon_pid}
+if [ -f ${LOC}/${cgroup_name}/tasks ]; then
+ CHECK_CGROUP=$(grep ${daemon_pid} ${LOC}/${cgroup_name}/tasks)
+ if [ ${CHECK_CGROUP} ]; then
+ val=`cat ${LOC}/${cgroup_name}/cpu.cfs_quota_us`
+ qval=$((val / 1000))
+ echo "pid ${daemon_pid} is already attached ${cgroup_name} with quota value ${qval}."
+ echo "Press n if you don't want to reassign ${daemon_pid} with new quota value."
+ DIR_EXIST=1
+ else
+ echo "pid ${daemon_pid} is not attached with ${cgroup_name}."
+ fi
+fi
+
+read -p "If you want to continue the script to attach ${daemon_pid} with new ${cgroup_name} cgroup Press (y/n)?" choice
+case "$choice" in
+ y|Y ) echo "yes";;
+ n|N ) echo "no";exit;;
+ * ) echo "invalid";exit;;
+esac
+
+systemctl set-property glusterd.service CPUShares=1024
+
+if [ ${DIR_EXIST} -eq 0 ];then
+ echo "Creating child cgroup directory '${cgroup_name} cgroup' for glusterd.service."
+ mkdir -p ${LOC}/${cgroup_name}
+ if [ ! -f ${LOC}/${cgroup_name}/tasks ];then
+ echo "Not able to create ${cgroup_name} directory so exit."
+ exit 1
+ fi
+fi
+
+echo "Enter quota value in range [10,100]: "
+
+read quota_value
+if expr ${quota_value} + 0 > /dev/null 2>&1 ;then
+ if [ ${quota_value} -lt 10 ] || [ ${quota_value} -gt 100 ]; then
+ echo "Entered quota value is not correct,it should be in the range ."
+ echo "10-100. Ideal value is 25."
+ echo "Rerun the sript with correct value."
+ exit 1
+ else
+ echo "Entered quota value is $quota_value"
+ fi
+else
+ echo "Entered quota value is not numeric so Rerun the script."
+ exit 1
+fi
+
+quota_value=$((quota_value * 1000))
+echo "Setting $quota_value to cpu.cfs_quota_us for gluster_cgroup."
+echo ${quota_value} > ${LOC}/${cgroup_name}/cpu.cfs_quota_us
+
+if ps -T -p ${daemon_pid} | grep gluster > /dev/null; then
+ for thid in `ps -T -p ${daemon_pid} | grep -v SPID | awk -F " " '{print $2}'`;
+ do
+ echo ${thid} > ${LOC}/${cgroup_name}/tasks ;
+ done
+ if cat /proc/${daemon_pid}/cgroup | grep -w ${cgroup_name} > /dev/null; then
+ echo "Tasks are attached successfully specific to ${daemon_pid} to ${cgroup_name}."
+ else
+ echo "Tasks are not attached successfully."
+ fi
+fi
diff --git a/extras/control-mem.sh b/extras/control-mem.sh
new file mode 100755
index 00000000000..91b36f8107a
--- /dev/null
+++ b/extras/control-mem.sh
@@ -0,0 +1,128 @@
+#!/bin/bash
+
+USAGE="This commands provides a utility to control MEMORY utilization for any
+gluster daemon.In this, we use cgroup framework to configure MEMORY limit for
+a process. Before running this script, make sure that daemon is running.Every
+time daemon restarts, it is required to rerun this command to set memory limit
+(in bytes) on new daemon process id.User can enter any value between 100
+(in Mega bytes) to 8000000000000 for Memory limit in Mega bytes.
+Memory limit value is depends on how much maximum memory user wants to restrict
+for specific daemon process.If a process will try to consume memore more than
+configured value then cgroup will hang/sleep this task and to resume the task
+rerun the script with new increase memory limit value ."
+
+if [ $# -ge 1 ]; then
+ case $1 in
+ -h|--help) echo " " "$USAGE" | sed -r -e 's/^[ ]+//g'
+ exit 0;
+ ;;
+ *) echo "Please Provide correct input for script."
+ echo "For help correct options are -h of --help."
+ exit 1;
+ ;;
+ esac
+fi
+
+DIR_EXIST=0
+LOC="/sys/fs/cgroup/memory/system.slice/glusterd.service"
+echo "Enter Any gluster daemon pid for that you want to control MEMORY."
+read daemon_pid
+
+if expr ${daemon_pid} + 0 > /dev/null 2>&1 ;then
+ CHECK_PID=$(pgrep -f gluster | grep ${daemon_pid})
+ if [ -z "${CHECK_PID}" ]; then
+ echo "No daemon is running or pid ${daemon_pid} does not match."
+ echo "with running gluster processes."
+ exit 1
+ fi
+else
+ echo "Entered daemon_pid is not numeric so Rerun the script."
+ exit 1
+fi
+
+
+if [ -f ${LOC}/tasks ]; then
+ CHECK_CGROUP=$(grep ${daemon_pid} ${LOC}/tasks)
+ if [ ${CHECK_CGROUP} ] ;then
+ echo "pid ${daemon_pid} is attached with default glusterd.service cgroup."
+ fi
+fi
+
+cgroup_name=cgroup_gluster_${daemon_pid}
+if [ -f ${LOC}/${cgroup_name}/tasks ];then
+ CHECK_CGROUP=$(grep ${daemon_pid} ${LOC}/${cgroup_name}/tasks)
+ if [ ${CHECK_CGROUP} ]; then
+ val=`cat ${LOC}/${cgroup_name}/memory.limit_in_bytes`
+ mval=$((val / 1024 / 1024))
+ echo "pid ${daemon_pid} is already attached ${cgroup_name} with mem value ${mval}."
+ echo "Press n if you don't want to reassign ${daemon_pid} with new mem value."
+ DIR_EXIST=1
+ else
+ echo "pid ${daemon_pid} is not attached with ${cgroup_name}."
+ fi
+fi
+
+read -p "If you want to continue the script to attach daeomon with new cgroup. Press (y/n)?" choice
+case "$choice" in
+ y|Y ) echo "yes";;
+ n|N ) echo "no";exit;;
+ * ) echo "invalid";exit;;
+esac
+
+systemctl set-property glusterd.service CPUShares=1024
+
+if [ ${DIR_EXIST} -eq 0 ];then
+ echo "Creating child cgroup directory '${cgroup_name} cgroup' for glusterd.service."
+ mkdir -p ${LOC}/${cgroup_name}
+ if [ ! -f ${LOC}/${cgroup_name}/tasks ];then
+ echo "Not able to create ${LOC}/${cgroup_name} directory so exit."
+ exit 1
+ fi
+fi
+
+echo "Enter Memory value in Mega bytes [100,8000000000000]: "
+
+read mem_value
+if expr ${mem_value} + 0 > /dev/null 2>&1 ;then
+ if [ ${mem_value} -lt 100 ] || [ ${mem_value} -gt 8000000000000 ]; then
+ echo "Entered memory value is not correct,it should be in the range ."
+ echo "100-8000000000000, Rerun the script with correct value ."
+ exit 1
+ else
+ echo "Entered memory limit value is ${mem_value}."
+ fi
+else
+ echo "Entered memory value is not numeric so Rerun the script."
+ exit 1
+fi
+
+mem_value=$(($mem_value * 1024 * 1024))
+if [ ${DIR_EXIST} -eq 0 ];then
+ echo "Setting ${mem_value} to memory.limit_in_bytes for ${LOC}/${cgroup_name}."
+ echo ${mem_value} > ${LOC}/${cgroup_name}/memory.limit_in_bytes
+ #Set memory value to memory.memsw.limit_in_bytes
+ echo ${mem_value} > ${LOC}/${cgroup_name}/memory.memsw.limit_in_bytes
+ # disable oom_control so that kernel will not send kill signal to the
+ # task once limit has reached
+ echo 1 > ${LOC}/${cgroup_name}/memory.oom_control
+else
+ #Increase mem_value to memory.memsw.limit_in_bytes
+ echo ${mem_value} > ${LOC}/${cgroup_name}/memory.memsw.limit_in_bytes
+ echo "Increase ${mem_value} to memory.limit_in_bytes for ${LOC}/${cgroup_name}."
+ echo ${mem_value} > ${LOC}/${cgroup_name}/memory.limit_in_bytes
+ # disable oom_control so that kernel will not send kill signal to the
+ # task once limit has reached
+ echo 1 > ${LOC}/${cgroup_name}/memory.oom_control
+fi
+
+if ps -T -p ${daemon_pid} | grep gluster > /dev/null; then
+ for thid in `ps -T -p ${daemon_pid} | grep -v SPID | awk -F " " '{print $2}'`;
+ do
+ echo ${thid} > ${LOC}/${cgroup_name}/tasks ;
+ done
+ if cat /proc/${daemon_pid}/cgroup | grep -iw ${cgroup_name} > /dev/null; then
+ echo "Tasks are attached successfully specific to ${daemon_pid} to ${cgroup_name}."
+ else
+ echo "Tasks are not attached successfully."
+ fi
+fi
diff --git a/extras/create_new_xlator/README.md b/extras/create_new_xlator/README.md
new file mode 100644
index 00000000000..fdc1ba00812
--- /dev/null
+++ b/extras/create_new_xlator/README.md
@@ -0,0 +1,24 @@
+####This document explains how to create a template for your new xlator.
+
+`$ python ./generate_xlator.py <XLATOR_DIRECTORY> <XLATOR_NAME> <FOP_PREFIX>`
+ * XLATOR_DIRECTORY: Directory path where the new xlator folder will reside
+ * XLATOR_NAME: Name of the xlator you wish to create
+ * FOP_PREFIX: This is the fop prefix that you wish to prefix every fop definition in your xlator, fop prefix is generally different than xlator name, if the xlator name is too long.
+
+Eg: `python ./generate_xlator.py /home/u1/glusterfs/xlators/features compression cmpr`
+This command will create the following files with some initial contents like copyright, fops definition etc.
+Note that there shouldn't be a "/" specified at the end of the <XLATOR_DIRECTORY>
+ `* /home/u1/glusterfs/xlators/features/compression/Makefile.am
+ * /home/u1/glusterfs/xlators/features/compression/src/Makefile.am
+ * /home/u1/glusterfs/xlators/features/compression/src/compression.c
+ * /home/u1/glusterfs/xlators/features/compression/src/compression.h
+ * /home/u1/glusterfs/xlators/features/compression/src/compression-mem-types.h
+ * /home/u1/glusterfs/xlators/features/compression/src/compression-messages.h`
+
+By default all the fops and functions are generated, if you wish to not implement certain fops and functions, comment those lines (by adding '#' at the start of the line) in libglusterfs/src/generate_xlator.py
+
+Few other manual steps required to get the new xlator completely functional:
+* Change configure.ac
+* Change `<XLATOR_DIRECTORY>/Makefile.am` to include the new xlator directory.
+ Eg: `/home/u1/glusterfs/xlators/features/Makefile.am`
+* Change vol file or glusterd volgen to include the new xlator in volfile
diff --git a/extras/create_new_xlator/generate_xlator.py b/extras/create_new_xlator/generate_xlator.py
new file mode 100755
index 00000000000..983868c04db
--- /dev/null
+++ b/extras/create_new_xlator/generate_xlator.py
@@ -0,0 +1,208 @@
+#!/usr/bin/python3
+
+from __future__ import print_function
+import os
+import re
+import sys
+import string
+import time
+path = os.path.abspath(os.path.dirname(__file__)) + '/../../libglusterfs/src'
+sys.path.append(path)
+from generator import ops, xlator_cbks, xlator_dumpops
+
+MAKEFILE_FMT = """
+xlator_LTLIBRARIES = @XL_NAME@.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/@XL_TYPE@
+@XL_NAME_NO_HYPHEN@_la_LDFLAGS = -module $(GF_XLATOR_DEFAULT_LDFLAGS)
+@XL_NAME_NO_HYPHEN@_la_SOURCES = @XL_NAME@.c
+@XL_NAME_NO_HYPHEN@_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+noinst_HEADERS = @XL_NAME@.h @XL_NAME@-mem-types.h @XL_NAME@-messages.h
+AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src
+AM_CFLAGS = -Wall -fno-strict-aliasing $(GF_CFLAGS)
+CLEANFILES =
+"""
+
+fop_subs = {}
+cbk_subs = {}
+fn_subs = {}
+
+
+def get_error_arg(type_str):
+ if type_str.find(" *") != -1:
+ return "NULL"
+ return "-1"
+
+
+def get_param(names, types):
+ # Convert two separate tuples to one of (name, type) sub-tuples.
+ as_tuples = list(zip(types, names))
+ # Convert each sub-tuple into a "type name" string.
+ as_strings = [' '.join(item) for item in as_tuples]
+ # Join all of those into one big string.
+ return ',\n\t'.join(as_strings)
+
+
+def generate(tmpl, name, table):
+ w_arg_names = [a[1] for a in table[name] if a[0] == 'fop-arg']
+ w_arg_types = [a[2] for a in table[name] if a[0] == 'fop-arg']
+ u_arg_names = [a[1] for a in table[name] if a[0] == 'cbk-arg']
+ u_arg_types = [a[2] for a in table[name] if a[0] == 'cbk-arg']
+ fn_arg_names = [a[1] for a in table[name] if a[0] == 'fn-arg']
+ fn_arg_types = [a[2] for a in table[name] if a[0] == 'fn-arg']
+ ret_type = [a[1] for a in table[name] if a[0] == 'ret-val']
+ ret_var = [a[2] for a in table[name] if a[0] == 'ret-val']
+
+ sdict = {}
+ #Parameters are (t1, var1), (t2, var2)...
+ #Args are (var1, var2,...)
+ sdict["@WIND_ARGS@"] = ', '.join(w_arg_names)
+ sdict["@UNWIND_ARGS@"] = ', '.join(u_arg_names)
+ sdict["@ERROR_ARGS@"] = ', '.join(list(map(get_error_arg, u_arg_types)))
+ sdict["@WIND_PARAMS@"] = get_param(w_arg_names, w_arg_types)
+ sdict["@UNWIND_PARAMS@"] = get_param(u_arg_names, u_arg_types)
+ sdict["@FUNC_PARAMS@"] = get_param(fn_arg_names, fn_arg_types)
+ sdict["@NAME@"] = name
+ sdict["@FOP_PREFIX@"] = fop_prefix
+ sdict["@RET_TYPE@"] = ''.join(ret_type)
+ sdict["@RET_VAR@"] = ''.join(ret_var)
+
+ for old, new in sdict.items():
+ tmpl = tmpl.replace(old, new)
+ # TBD: reindent/reformat the result for maximum readability.
+ return tmpl
+
+
+def gen_xlator():
+ xl = open(src_dir_path+"/"+xl_name+".c", 'w+')
+
+ print(COPYRIGHT, file=xl)
+ print(fragments["INCLUDE_IN_SRC_FILE"].replace("@XL_NAME@",
+ xl_name), file=xl)
+
+ #Generate cbks and fops
+ for fop in ops:
+ print(generate(fragments["CBK_TEMPLATE"], fop, ops), file=xl)
+ print(generate(fragments["FOP_TEMPLATE"], fop, ops), file=xl)
+
+ for cbk in xlator_cbks:
+ print(generate(fragments["FUNC_TEMPLATE"], cbk,
+ xlator_cbks), file=xl)
+
+ for dops in xlator_dumpops:
+ print(generate(fragments["FUNC_TEMPLATE"], dops,
+ xlator_dumpops), file=xl)
+
+ #Generate fop table
+ print("struct xlator_fops fops = {", file=xl)
+ for fop in ops:
+ print(" .{0:20} = {1}_{2},".format(fop, fop_prefix, fop), file=xl)
+ print("};", file=xl)
+
+ #Generate xlator_cbks table
+ print("struct xlator_cbks cbks = {", file=xl)
+ for cbk in xlator_cbks:
+ print(" .{0:20} = {1}_{2},".format(cbk, fop_prefix, cbk), file=xl)
+ print("};", file=xl)
+
+ #Generate xlator_dumpops table
+ print("struct xlator_dumpops dumpops = {", file=xl)
+ for dops in xlator_dumpops:
+ print(" .{0:20} = {1}_{2},".format(dops, fop_prefix, dops), file=xl)
+ print("};", file=xl)
+
+ xlator_methods = fragments["XLATOR_METHODS"].replace("@XL_NAME@", xl_name)
+ xlator_methods = xlator_methods.replace("@FOP_PREFIX@", fop_prefix)
+ print(xlator_methods, file=xl)
+
+ xl.close()
+
+
+def create_dir_struct():
+ if not os.path.exists(dir_path+"/src"):
+ os.makedirs(dir_path+"/src")
+
+
+def gen_header_files():
+ upname = xl_name_no_hyphen.upper()
+ h = open(src_dir_path+"/"+xl_name+".h", 'w+')
+ print(COPYRIGHT, file=h)
+ txt = fragments["HEADER_FMT"].replace("@HFL_NAME@", upname)
+ txt = txt.replace("@XL_NAME@", xl_name)
+ print(txt, file=h)
+ h.close()
+
+ h = open(src_dir_path+"/"+xl_name+"-mem-types.h", 'w+')
+ print(COPYRIGHT, file=h)
+ txt = fragments["MEM_HEADER_FMT"].replace("@HFL_NAME@", upname+"_MEM_TYPES")
+ txt = txt.replace("@FOP_PREFIX@", fop_prefix)
+ print(txt, file=h)
+ h.close()
+
+ h = open(src_dir_path+"/"+xl_name+"-messages.h", 'w+')
+ print(COPYRIGHT, file=h)
+ txt = fragments["MSG_HEADER_FMT"].replace("@HFL_NAME@", upname+"_MESSAGES")
+ txt = txt.replace("@FOP_PREFIX@", fop_prefix.upper())
+ print(txt, file=h)
+ h.close()
+
+
+def gen_makefiles():
+ m = open(dir_path+"/Makefile.am", 'w+')
+ print("SUBDIRS = src\n\nCLEANFILES =", file=m)
+ m.close()
+
+ m = open(src_dir_path+"/Makefile.am", 'w+')
+ txt = MAKEFILE_FMT.replace("@XL_NAME@", xl_name)
+ txt = txt.replace("@XL_NAME_NO_HYPHEN@", xl_name_no_hyphen)
+ txt = txt.replace("@XL_TYPE@", xlator_type)
+ print(txt, file=m)
+ m.close()
+
+def get_copyright ():
+ return fragments["CP"].replace("@CURRENT_YEAR@",
+ time.strftime("%Y"))
+
+def load_fragments ():
+ pragma_re = re.compile('pragma fragment (.*)')
+ cur_symbol = None
+ cur_value = ""
+ result = {}
+ basepath = os.path.abspath(os.path.dirname(__file__))
+ fragpath = basepath + "/new-xlator.c.tmpl"
+ for line in open(fragpath, "r").readlines():
+ m = pragma_re.search(line)
+ if m:
+ if cur_symbol:
+ result[cur_symbol] = cur_value
+ cur_symbol = m.group(1)
+ cur_value = ""
+ else:
+ cur_value += line
+ if cur_symbol:
+ result[cur_symbol] = cur_value
+ return result
+
+if __name__ == '__main__':
+
+ if len(sys.argv) < 3:
+ print("USAGE: ./gen_xlator <XLATOR_DIR> <XLATOR_NAME> <FOP_PREFIX>")
+ sys.exit(0)
+
+ xl_name = sys.argv[2]
+ xl_name_no_hyphen = xl_name.replace("-", "_")
+ if sys.argv[1].endswith('/'):
+ dir_path = sys.argv[1] + xl_name
+ else:
+ dir_path = sys.argv[1] + "/" + xl_name
+ xlator_type = os.path.basename(sys.argv[1])
+ fop_prefix = sys.argv[3]
+ src_dir_path = dir_path + "/src"
+
+ fragments = load_fragments()
+
+ COPYRIGHT = get_copyright()
+ create_dir_struct()
+ gen_xlator()
+ gen_header_files()
+ gen_makefiles()
diff --git a/extras/create_new_xlator/new-xlator.c.tmpl b/extras/create_new_xlator/new-xlator.c.tmpl
new file mode 100644
index 00000000000..fe9735bfcf1
--- /dev/null
+++ b/extras/create_new_xlator/new-xlator.c.tmpl
@@ -0,0 +1,151 @@
+#pragma fragment CBK_TEMPLATE
+int32_t @FOP_PREFIX@_@NAME@_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, @UNWIND_PARAMS@)
+{
+ STACK_UNWIND_STRICT(@NAME@, frame, op_ret, op_errno, @UNWIND_ARGS@);
+ return 0;
+}
+
+#pragma fragment COMMENT
+If you are generating the leaf xlators, remove the STACK_WIND and replace the
+ @ERROR_ARGS@ to @UNWIND_ARGS@ if necessary
+
+#pragma fragment FOP_TEMPLATE
+ int32_t @FOP_PREFIX@_@NAME@(call_frame_t *frame, xlator_t *this, @WIND_PARAMS@)
+{
+ STACK_WIND(frame, @FOP_PREFIX@_@NAME@_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->@NAME@, @WIND_ARGS@);
+ return 0;
+err:
+ STACK_UNWIND_STRICT(@NAME@, frame, -1, errno, @ERROR_ARGS@);
+ return 0;
+}
+
+#pragma fragment FUNC_TEMPLATE
+@RET_TYPE@ @FOP_PREFIX@_@NAME@(@FUNC_PARAMS@)
+{
+ return @RET_VAR@;
+}
+
+#pragma fragment CP
+/*
+ * Copyright (c) @CURRENT_YEAR@ 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.
+ */
+
+#pragma fragment INCLUDE_IN_SRC_FILE
+#include "@XL_NAME@.h"
+
+#pragma fragment XLATOR_METHODS
+
+static int32_t @FOP_PREFIX@_init(xlator_t *this)
+{
+ return 0;
+}
+
+static void @FOP_PREFIX@_fini(xlator_t *this)
+{
+ return;
+}
+
+static int32_t @FOP_PREFIX@_reconfigure(xlator_t *this, dict_t *dict)
+{
+ return 0;
+}
+
+static int @FOP_PREFIX@_notify(xlator_t *this, int event, void *data, ...)
+{
+ return default_notify(this, event, data);
+}
+
+static int32_t @FOP_PREFIX@_mem_acct_init(xlator_t *this)
+{
+ int ret = -1;
+
+ ret = xlator_mem_acct_init(this, gf_@FOP_PREFIX@_mt_end + 1);
+ return ret;
+}
+
+static int32_t @FOP_PREFIX@_dump_metrics(xlator_t *this, int fd)
+{
+ return 0;
+}
+
+struct volume_options @FOP_PREFIX@_options[] = {
+ /*{ .key = {""},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "",
+ .op_version = {GD_OP_VERSION_},
+ .flags = OPT_FLAG_SETTABLE | OPT_FLAG_DOC | OPT_FLAG_CLIENT_OPT,
+ .tags = {""},
+ .description = "",
+ .category = GF_EXPERIMENTAL,
+ },
+ { .key = {NULL} },
+ */
+};
+
+xlator_api_t xlator_api = {
+ .init = @FOP_PREFIX@_init,
+ .fini = @FOP_PREFIX@_fini,
+ .notify = @FOP_PREFIX@_notify,
+ .reconfigure = @FOP_PREFIX@_reconfigure,
+ .mem_acct_init = @FOP_PREFIX@_mem_acct_init,
+ .dump_metrics = @FOP_PREFIX@_dump_metrics,
+ .op_version = {GD_OP_VERSION_},
+ .dumpops = &@FOP_PREFIX@_dumpops,
+ .fops = &@FOP_PREFIX@_fops,
+ .cbks = &@FOP_PREFIX @_cbks,
+ .options = @FOP_PREFIX@_options,
+ .identifier = "@XL_NAME@",
+ .category = GF_EXPERIMENTAL,
+};
+#pragma fragment HEADER_FMT
+#ifndef __ @HFL_NAME@_H__
+#define __ @HFL_NAME@_H__
+
+#include "@XL_NAME@-mem-types.h"
+#include "@XL_NAME@-messages.h"
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/xlator.h>
+#include <glusterfs/defaults.h>
+
+#endif /* __@HFL_NAME@_H__ */
+
+#pragma fragment MEM_HEADER_FMT
+#ifndef __ @HFL_NAME@_H__
+#define __ @HFL_NAME@_H__
+
+#include <glusterfs/mem-types.h>
+
+enum gf_mdc_mem_types_ {
+ gf_@FOP_PREFIX@_mt_ = gf_common_mt_end + 1,
+ gf_@FOP_PREFIX@_mt_end
+};
+
+#endif /* __@HFL_NAME@_H__ */
+
+#pragma fragment MSG_HEADER_FMT
+#ifndef __@HFL_NAME@_H__
+#define __@HFL_NAME@_H__
+
+#include <glusterfs/glfs-message-id.h>
+
+/* To add new message IDs, append new identifiers at the end of the list.
+ *
+ * Never remove a message ID. If it's not used anymore, you can rename it or
+ * leave it as it is, but not delete it. This is to prevent reutilization of
+ * IDs by other messages.
+ *
+ * The component name must match one of the entries defined in
+ * glfs-message-id.h.
+ */
+
+GLFS_MSGID(@FOP_PREFIX@, @FOP_PREFIX@_MSG_NO_MEMORY);
+
+#endif /* __@HFL_NAME@_H__ */
diff --git a/extras/devel-tools/devel-vagrant/Vagrantfile b/extras/devel-tools/devel-vagrant/Vagrantfile
new file mode 100644
index 00000000000..78dc29bdc68
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/Vagrantfile
@@ -0,0 +1,165 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+#
+# Author: Rajesh Joseph (rjoseph@redhat.com)
+# Author: Christopher Blum (cblum@redhat.com)
+#
+
+
+#Variables
+box_name = "gluster-dev-fedora"
+box_url = "http://download.gluster.org/pub/gluster/glusterfs/vagrant/gluster-dev-fedora/boxes/gluster-dev-fedora.json"
+node_count = 0
+disk_count = -1
+node_name = "Node"
+ipbase="192.168.99."
+source_path = "/source/glusterfs"
+target_path = "/mnt/src"
+
+if ARGV[0] == "up"
+ environment = open('vagrant_env.conf', 'w')
+
+ print "\n\e[1;37mEnter Node (or VM) Count? Default: 1 \e[32m"
+ while node_count < 1 or node_count > 99
+ node_count = $stdin.gets.strip.to_i
+ if node_count == 0 # The user pressed enter without input or we cannot parse the input to a number
+ node_count = 1
+ elsif node_count < 1
+ print "\e[31mWe need at least 1 VM ;) Try again \e[32m"
+ elsif node_count > 99
+ print "\e[31mWe don't support more than 99 VMs - Try again \e[32m"
+ end
+ end
+
+ print "\e[1;37mEnter per Node Disc (Brick) Count? Default: 2 \e[32m"
+
+ while disk_count < 1
+ disk_count = $stdin.gets.strip.to_i
+ if disk_count == 0 # The user pressed enter without input or we cannot parse the input to a number
+ disk_count = 2
+ elsif disk_count < 1
+ print "\e[31mWe need at least 1 disk ;) Try again \e[32m"
+ end
+ end
+
+ print "\e[1;37mEnter GlusterFS source location? Default: \"#{source_path}\" : \e[32m"
+ tmploc = $stdin.gets.strip.to_s
+ if tmploc != ""
+ source_path = "#{tmploc}"
+ end
+
+ environment.puts("# BEWARE: Do NOT modify ANY settings in here or your vagrant environment will be messed up")
+ environment.puts(node_count.to_s)
+ environment.puts(disk_count.to_s)
+ environment.puts(source_path)
+
+ print "\e[32m\nOK I will provision #{node_count} VMs for you and each one will have #{disk_count} disks for bricks\e[37m\n\n"
+ system "sleep 1"
+else # So that we destroy and can connect to all VMs...
+ environment = open('vagrant_env.conf', 'r')
+
+ environment.readline # Skip the comment on top
+ node_count = environment.readline.to_i
+ disk_count = environment.readline.to_i
+ source_path = environment.readline.gsub(/\s+/, "")
+
+ if ARGV[0] != "ssh-config"
+ puts "Detected settings from previous vagrant up:"
+ puts " We deployed #{node_count} VMs with each #{disk_count} disks"
+ puts ""
+ end
+end
+
+environment.close
+
+$ansivar = Hash.new{ |hash,key| hash[key] = [] }
+$devnamecreated = false
+
+#
+# Function to create and attach disks
+#
+def attachDisks(numDisk, provider)
+ suffix = "bcdefghijklmn".split("")
+ for i in 1..numDisk.to_i
+ devname = "vd" + (suffix[i-1]).to_s
+ if $devnamecreated == false
+ $ansivar["device"].push "#{devname}"
+ end
+ provider.storage :file,
+ :size => '1G',
+ :device => "vd" + (suffix[i-1]).to_s,
+ :type => "qcow2",
+ :bus => "virtio",
+ :cache => "default"
+ end
+ $devnamecreated = true
+end
+
+
+$ansivar["src_path"].push "#{source_path}"
+$ansivar["trg_path"].push "#{target_path}"
+
+groups = Hash.new{ |hash,key| hash[key] = [] }
+
+groups["origin"].push "#{node_name}1"
+groups["all"].push "#{node_name}1"
+
+(2..node_count).each do |num|
+ $ansivar["peer_nodes"].push "#{node_name}#{num}"
+ groups["all"].push "#{node_name}#{num}"
+end
+
+hostsFile = "\n"
+(1..node_count).each do |num|
+ hostsFile += "#{ipbase}#{( 100 + num).to_s} #{node_name}#{num.to_s}\n"
+end
+
+Vagrant.configure("2") do |config|
+ (1..node_count).each do |num|
+ config.vm.define "#{node_name}#{num}" do |node|
+ ip_addr = "#{ipbase}#{(100 + num).to_s}"
+ node.vm.network "private_network", ip: "#{ip_addr}"
+ node.vm.box = box_name
+ node.vm.box_url = box_url
+ node.vm.hostname = "#{node_name}#{num}"
+ node.ssh.insert_key = false
+ node.vm.synced_folder "#{source_path}", "#{target_path}", type: "nfs"
+
+ # Define basic config for VM, memory, cpu, storage pool
+ node.vm.provider "libvirt" do |virt|
+ virt.storage_pool_name = "default"
+ virt.memory = 1024
+ virt.cpus = 1
+
+ attachDisks( disk_count, virt )
+ end
+
+ node.vm.post_up_message = "\e[37mBuilding of this VM is finished \n"
+ "You can access it now with: \n"
+ "vagrant ssh #{node_name}#{num.to_s}\n\n"
+ "#{target_path} directory in VM #{node_name}#{num.to_s}"
+ "is synced with Host machine. \nSo any changes done in this"
+ "directory will be reflected in the host machine as well\n"
+ "Beware of this when you delete content from this directory\e[32m"
+
+ node.vm.provision :shell, path: "bootstrap.sh"
+
+ node.vm.provision "shell", inline: <<-SHELL
+ echo '#{hostsFile}' | sudo tee -a /etc/hosts
+ SHELL
+
+ if num == node_count
+ # Let's provision
+ node.vm.provision "ansible" do |setup|
+ setup.verbose = "v"
+ setup.playbook = "ansible/setup.yml"
+ setup.limit = "all"
+ setup.sudo = "true"
+ setup.groups = groups
+ setup.extra_vars = $ansivar
+ end
+ end
+
+ end
+ end
+end
diff --git a/extras/devel-tools/devel-vagrant/ansible/roles/cluster/tasks/main.yml b/extras/devel-tools/devel-vagrant/ansible/roles/cluster/tasks/main.yml
new file mode 100644
index 00000000000..3306c7a3dc2
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/ansible/roles/cluster/tasks/main.yml
@@ -0,0 +1,5 @@
+---
+- name: gluster peer probe
+ shell: gluster peer probe {{ item }}
+ with_items: "{{ peer_nodes | default([]) }}"
+
diff --git a/extras/devel-tools/devel-vagrant/ansible/roles/compile-gluster/tasks/main.yml b/extras/devel-tools/devel-vagrant/ansible/roles/compile-gluster/tasks/main.yml
new file mode 100644
index 00000000000..6ee258c7780
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/ansible/roles/compile-gluster/tasks/main.yml
@@ -0,0 +1,29 @@
+---
+- name: autogen.sh
+ shell: chdir={{ item }} ./autogen.sh
+ with_items: "{{ trg_path }}"
+
+- name: configure
+ shell: chdir={{ item }} CFLAGS="-g -O0 -Werror -Wall -Wno-error=cpp -Wno-error=maybe-uninitialized" \
+ ./configure \
+ --prefix=/usr \
+ --exec-prefix=/usr \
+ --bindir=/usr/bin \
+ --sbindir=/usr/sbin \
+ --sysconfdir=/etc \
+ --datadir=/usr/share \
+ --includedir=/usr/include \
+ --libdir=/usr/lib64 \
+ --libexecdir=/usr/libexec \
+ --localstatedir=/var \
+ --sharedstatedir=/var/lib \
+ --mandir=/usr/share/man \
+ --infodir=/usr/share/info \
+ --libdir=/usr/lib64 \
+ --enable-debug
+ with_items: "{{ trg_path }}"
+
+- name: make install
+ shell: chdir={{ item }} make install
+ with_items: "{{ trg_path }}"
+
diff --git a/extras/devel-tools/devel-vagrant/ansible/roles/install-pkgs/tasks/main.yml b/extras/devel-tools/devel-vagrant/ansible/roles/install-pkgs/tasks/main.yml
new file mode 100644
index 00000000000..3944054dd25
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/ansible/roles/install-pkgs/tasks/main.yml
@@ -0,0 +1,72 @@
+---
+- name: install deltarpm
+ dnf: name=deltarpm state=present
+
+- name: update system
+ shell: dnf update -y
+
+- name: install other packages
+ dnf: name={{ item }} state=present
+ with_items:
+ - attr
+ - autoconf
+ - automake
+ - bison
+ - cifs-utils
+ - cscope
+ - ctags
+ - dbench
+ - dos2unix
+ - e2fsprogs
+ - findutils
+ - flex
+ - fuse-devel
+ - fuse-libs
+ - gcc
+ - gdb
+ - git
+ - glib2-devel
+ - hostname
+ - libacl-devel
+ - libaio-devel
+ - libattr-devel
+ - libibverbs-devel
+ - librdmacm-devel
+ - libtool
+ - libxml2-devel
+ - lvm2-devel
+ - make
+ - man-db
+ - mock
+ - net-tools
+ - nfs-utils
+ - openssh-server
+ - openssl-devel
+ - perl-Test-Harness
+ - pkgconfig
+ - procps-ng
+ - psmisc
+ - python-devel
+ - python-eventlet
+ - python-netifaces
+ - python-paste-deploy
+ - python-setuptools
+ - python-simplejson
+ - python-sphinx
+ - python-webob
+ - pyxattr
+ - readline-devel
+ - rpm-build
+ - screen
+ - strace
+ - supervisor
+ - systemtap-sdt-devel
+ - sqlite-devel
+ - samba*
+ - userspace-rcu-devel
+ - vim
+ - wget
+ - which
+ - xfsprogs
+ - yajl-devel
+
diff --git a/extras/devel-tools/devel-vagrant/ansible/roles/iptables/tasks/main.yml b/extras/devel-tools/devel-vagrant/ansible/roles/iptables/tasks/main.yml
new file mode 100644
index 00000000000..768cb0e8668
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/ansible/roles/iptables/tasks/main.yml
@@ -0,0 +1,3 @@
+---
+- name: disable iptables, need to add specific rules later
+ shell: iptables -F
diff --git a/extras/devel-tools/devel-vagrant/ansible/roles/prepare-brick/tasks/main.yml b/extras/devel-tools/devel-vagrant/ansible/roles/prepare-brick/tasks/main.yml
new file mode 100644
index 00000000000..a3a6c463468
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/ansible/roles/prepare-brick/tasks/main.yml
@@ -0,0 +1,30 @@
+---
+- name: Create physical device
+ shell: pvcreate /dev/{{ item }}
+ with_items: "{{ device }}"
+
+- name: Create volume group
+ shell: vgcreate vg{{ item }} /dev/{{ item }}
+ with_items: "{{ device }}"
+
+- name: Create thin pool
+ shell: lvcreate -L 950M -T vg{{ item }}/thinpool
+ with_items: "{{ device }}"
+
+- name: Create thin volume
+ shell: lvcreate -V900M -T vg{{ item }}/thinpool -n thinp1
+ with_items: "{{ device }}"
+
+- name: Format backend
+ filesystem: fstype=xfs dev=/dev/vg{{ item }}/thinp1
+ with_items: "{{ device }}"
+
+- name: Create mount directory
+ file: path=/bricks/br{{ item }} state=directory recurse=yes
+ with_items: "{{ device }}"
+
+- name: Add entry to fstab and mount
+ mount: name=/bricks/br{{ item }} src=/dev/vg{{ item }}/thinp1 fstype=xfs state=mounted
+ with_items: "{{ device }}"
+
+
diff --git a/extras/devel-tools/devel-vagrant/ansible/roles/selinux/tasks/main.yml b/extras/devel-tools/devel-vagrant/ansible/roles/selinux/tasks/main.yml
new file mode 100644
index 00000000000..c9ba9618428
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/ansible/roles/selinux/tasks/main.yml
@@ -0,0 +1,3 @@
+---
+- name: Allow gfapi in Samba to bind to other ports than well known smb ports
+ seboolean: name=samba_load_libgfapi state=yes persistent=yes
diff --git a/extras/devel-tools/devel-vagrant/ansible/roles/service/tasks/main.yml b/extras/devel-tools/devel-vagrant/ansible/roles/service/tasks/main.yml
new file mode 100644
index 00000000000..ef78a125ae8
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/ansible/roles/service/tasks/main.yml
@@ -0,0 +1,21 @@
+---
+- name: disable kernel nfs
+ service: name=nfs-server enabled=no
+
+- name: stop kernel nfs
+ service: name=nfs-server state=stopped
+
+- name: enable rpcbind
+ service: name=rpcbind enabled=yes
+
+- name: start rpcbind
+ service: name=rpcbind state=started
+
+- name: enable glusterd
+ service: name=glusterd enabled=yes
+
+- name: start glusterd
+ service: name=glusterd state=started
+
+
+
diff --git a/extras/devel-tools/devel-vagrant/ansible/setup.yml b/extras/devel-tools/devel-vagrant/ansible/setup.yml
new file mode 100644
index 00000000000..c26bd7d6051
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/ansible/setup.yml
@@ -0,0 +1,23 @@
+---
+- hosts: all
+ become: yes
+ become_method: sudo
+ roles:
+ - install-pkgs
+ - prepare-brick
+ - selinux
+ - iptables
+
+- hosts: all
+ become: yes
+ become_method: sudo
+ serial: 1
+ roles:
+ - compile-gluster
+ - service
+
+- hosts: origin
+ become: yes
+ become_method: sudo
+ roles:
+ - cluster
diff --git a/extras/devel-tools/devel-vagrant/bootstrap.sh b/extras/devel-tools/devel-vagrant/bootstrap.sh
new file mode 100644
index 00000000000..bbf9fa2c063
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/bootstrap.sh
@@ -0,0 +1,3 @@
+dnf install -y nfs-utils
+dnf install -y vim
+dnf install -y python2 python2-dnf libselinux-python libsemanage-python
diff --git a/extras/devel-tools/devel-vagrant/up.sh b/extras/devel-tools/devel-vagrant/up.sh
new file mode 100755
index 00000000000..35cbe79d835
--- /dev/null
+++ b/extras/devel-tools/devel-vagrant/up.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+vagrant up --no-provision $@
+vagrant provision
diff --git a/extras/devel-tools/gdb_macros b/extras/devel-tools/gdb_macros
new file mode 100644
index 00000000000..aae4ccb3b37
--- /dev/null
+++ b/extras/devel-tools/gdb_macros
@@ -0,0 +1,84 @@
+
+#
+# gdb_macros is a gdb script file which can assist
+# developer in debugging. This script provides
+# following functions for debugging gluster processes
+# effectively:
+#
+# pdict : This function will iterate through all the
+# dictionary (dict_t) members and print the
+# key-value pair.
+#
+# plist : This function will print address of each member
+# of gluster list (list_head).
+#
+# gdb script should be loaded in gdb before using these
+# functions. gdb script can be loaded on-demand or on gdb
+# start-up. Use the following command on gdb prompt for
+# loading it on-demand.
+# source <script filename>
+# e.g.
+# (gdb) source /mnt/gdb_macros
+#
+# To automatically load gdb script on startup use .gdbinit
+# file. This file is automatically loaded by gdb on start.
+# Edit (or create) ~/.gdbinit file and add the following
+# entry:
+# source /mnt/gdb_macros
+#
+
+
+
+# This is an internal helper function
+define _print_dict_data
+ set $data = ($arg0)
+ set $len = $data->len - 1
+ set $i = 0
+ set $ishex = 0
+ while ($i < $len)
+ set $ch = $data->data [$i]
+
+ # Print only alpha-numeric values as char
+ # and remaining as hex value. This is done
+ # in this way because using %s screws up
+ # the display if the string has non-displayable
+ # characters
+ if ($ishex == 0) && ($ch > 31) && ($ch < 127)
+ printf "%c", $ch
+ else
+ printf "%x", ($ch & 0xFF)
+ set $ishex = 1
+ end
+ set $i = $i + 1
+ end
+end
+
+
+define pdict
+ set $cnt = 1
+ set $temp = *($arg0->members)
+ while ($temp)
+ printf "[%d](%s::",$cnt, $temp->key
+ _print_dict_data ($temp)->value
+ printf ")\n"
+ set $temp = $temp->next
+ set $cnt = $cnt + 1
+ end
+ printf "Done\n"
+end
+
+
+define plist
+ set $node = &($arg0)
+ set $head = $node
+
+ printf "[0x%lx]", $node
+ set $node = $node->next
+
+ while ($node != $head)
+ printf "--> [0x%lx]", $node
+ set $node = $node->next
+ end
+ printf "\n"
+end
+
diff --git a/extras/devel-tools/print-backtrace.sh b/extras/devel-tools/print-backtrace.sh
new file mode 100755
index 00000000000..33fbae288bc
--- /dev/null
+++ b/extras/devel-tools/print-backtrace.sh
@@ -0,0 +1,115 @@
+#!/bin/bash
+# sample unresolved backtrace lines picked up from a brick log that should go
+# into a backtrace file eg. bt-file.txt:
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x3ec81)[0x7fe4bc271c81]
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x3eecd)[0x7fe4bc271ecd]
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x404cb)[0x7fe4bc2734cb]
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x3d2b6)[0x7fe4bc2702b6]
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x3d323)[0x7fe4bc270323]
+#
+# following is the output of the script for the above backtrace lines:
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x3ec81)[0x7fe4bc271c81] __afr_selfheal_data_finalize_source inlined at /usr/src/debug/glusterfs-3.8.4/xlators/cluster/afr/src/afr-self-heal-data.c:684 in __afr_selfheal_data_prepare /usr/src/debug/glusterfs-3.8.4/xlators/cluster/afr/src/afr-self-heal-data.c:603
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x3eecd)[0x7fe4bc271ecd] __afr_selfheal_data /usr/src/debug/glusterfs-3.8.4/xlators/cluster/afr/src/afr-self-heal-data.c:740
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x404cb)[0x7fe4bc2734cb] afr_selfheal_data /usr/src/debug/glusterfs-3.8.4/xlators/cluster/afr/src/afr-self-heal-data.c:883
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x3d2b6)[0x7fe4bc2702b6] afr_selfheal_do /usr/src/debug/glusterfs-3.8.4/xlators/cluster/afr/src/afr-self-heal-common.c:1968
+# /usr/lib64/glusterfs/3.8.4/xlator/cluster/replicate.so(+0x3d323)[0x7fe4bc270323] afr_selfheal /usr/src/debug/glusterfs-3.8.4/xlators/cluster/afr/src/afr-self-heal-common.c:2015
+#
+# Usage with debuginfo RPM:
+# print-backtrace.sh $HOME/Downloads/glusterfs-debuginfo-3.8.4-10.el7.x86_64.rpm bt-file.txt
+#
+# Usage with source install:
+# print-packtrace.sh none bt-file.txt
+
+function version_compare() { test $(echo $1|awk -F '.' '{print $1 $2 $3}') -gt $(echo $2|awk -F '.' '{print $1 $2 $3}'); }
+
+function Usage()
+{
+ echo -e "Usage:\n\t$0 { none | <debuginfo-rpm> } <backtrace-file>"
+ echo "none: implies we don't have a debuginfo rpm but want to resolve"
+ echo " against a source install which already has the debuginfo"
+ echo " NOTE: in this case you should have configured the build"
+ echo " with --enable-debug and the linker options should"
+ echo " have the option -rdynamic"
+}
+
+debuginfo_rpm=$1
+backtrace_file=$2
+
+if [ ! $debuginfo_rpm ] || [ ! $backtrace_file ]; then
+ Usage
+ exit 1
+fi
+
+if [ $debuginfo_rpm != "none" ]; then
+ if [ ! -f $debuginfo_rpm ]; then
+ echo "no such rpm file: $debuginfo_rpm"
+ exit 1
+ fi
+fi
+
+if [ ! -f $backtrace_file ]; then
+ echo "no such backtrace file: $backtrace_file"
+ exit 1
+fi
+
+if [ "$debuginfo_rpm" != "none" ]; then
+ if ! file $debuginfo_rpm | grep RPM >/dev/null 2>&1 ; then
+ echo "file does not look like an rpm: $debuginfo_rpm"
+ exit 1
+ fi
+fi
+
+cpio_version=$(cpio --version|grep cpio|cut -f 2 -d ')'|sed -e 's/^[[:space:]]*//')
+rpm_name=""
+debuginfo_path=""
+debuginfo_extension=""
+
+if [ $debuginfo_rpm != "none" ]; then
+ # extract the gluster debuginfo rpm to resolve the symbols against
+ rpm_name=$(basename $debuginfo_rpm '.rpm')
+ if [ -d $rpm_name ]; then
+ echo "directory already exists: $rpm_name"
+ echo "please remove/move it and reattempt"
+ exit 1
+ fi
+ mkdir -p $rpm_name
+ if version_compare $cpio_version "2.11"; then
+ rpm2cpio $debuginfo_rpm | cpio --quiet --extract --make-directories --preserve-modification-time --directory=$rpm_name
+ ret=$?
+ else
+ current_dir="$PWD"
+ cd $rpm_name
+ rpm2cpio $debuginfo_rpm | cpio --quiet --extract --make-directories --preserve-modification-time
+ ret=$?
+ cd $current_dir
+ fi
+ if [ $ret -eq 1 ]; then
+ echo "failed to extract rpm $debuginfo_rpm to $PWD/$rpm_name directory"
+ rm -rf $rpm_name
+ exit 1
+ fi
+ debuginfo_path="$PWD/$rpm_name/usr/lib/debug"
+ debuginfo_extension=".debug"
+else
+ debuginfo_path=""
+ debuginfo_extension=""
+fi
+
+# NOTE: backtrace file should contain only the lines which need to be resolved
+for bt in $(cat $backtrace_file)
+do
+ libname=$(echo $bt | cut -f 1 -d '(')
+ addr=$(echo $bt | cut -f 2 -d '(' | cut -f 1 -d ')')
+ libpath=${debuginfo_path}${libname}${debuginfo_extension}
+ if [ ! -f $libpath ]; then
+ continue
+ fi
+ newbt=( $(eu-addr2line --functions --exe=$libpath $addr) )
+ echo "$bt ${newbt[*]}"
+done
+
+# remove the temporary directory
+if [ -d $rpm_name ]; then
+ rm -rf $rpm_name
+fi
+
diff --git a/extras/devel-tools/strace-brick.sh b/extras/devel-tools/strace-brick.sh
new file mode 100755
index 00000000000..a140729111c
--- /dev/null
+++ b/extras/devel-tools/strace-brick.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# Usage:
+# nice -n -19 strace-brick.sh glusterfsd 50
+
+brick_process_name=$1
+min_watch_cpu=$2
+if [ ! $brick_process_name ]; then
+ brick_process_name=glusterfsd
+fi
+
+if [ ! $min_watch_cpu ]; then
+ min_watch_cpu=50
+fi
+
+echo "min_watch_cpu: $min_watch_cpu"
+
+break=false
+
+while ! $break;
+do
+ mypids=( $(pgrep $brick_process_name) )
+ echo "mypids: ${mypids[*]}"
+
+ pid_args=$(echo ${mypids[*]} | sed -e 's/ / -p /g;s/^/-p /')
+ echo "pid_args: $pid_args"
+
+ pcpu=( $(ps $pid_args -o pcpu -h ) )
+ echo "pcpu: ${pcpu[*]}"
+
+ wait_longer=false
+
+ for i in $( seq 0 $((${#pcpu[*]} - 1)) )
+ do
+ echo "i: $i"
+ echo "mypids[$i]: ${mypids[$i]}"
+
+ int_pcpu=$(echo ${pcpu[$i]} | cut -f 1 -d '.')
+ echo "int_pcpu: $int_pcpu"
+ if [ ! $int_pcpu ] || [ ! $min_watch_cpu ]; then
+ break=true
+ echo "breaking"
+ fi
+ if [ $int_pcpu -ge $min_watch_cpu ]; then
+ wait_longer=true
+ mydirname="${brick_process_name}-${mypids[$i]}-$(date --utc +'%Y%m%d-%H%M%S.%N')"
+ $(mkdir $mydirname && cd $mydirname && timeout --kill-after=5 --signal=KILL 60 nice -n -19 strace -p ${mypids[$i]} -ff -tt -T -o $brick_process_name) &
+ fi
+ done
+
+ if $wait_longer; then
+ sleep 90
+ else
+ sleep 15
+ fi
+done
diff --git a/extras/distributed-testing/README b/extras/distributed-testing/README
new file mode 100644
index 00000000000..928d943f211
--- /dev/null
+++ b/extras/distributed-testing/README
@@ -0,0 +1,28 @@
+PROBLEM
+
+The testing methodology of Gluster is extremely slow. It takes a very long time (6+ hrs) to run the basic tests on a single machine. It takes about 20+ hours to run code analysis version of tests like valgrind, asan, tsan etc.
+
+SOLUTION
+
+The fundamental problem is that the tests cannot be parallelized on a single machine. The natural solution is to run these tests on a cluster of machines. In a nutshell, apply map-reduce to run unit tests.
+
+WORK @ Facebook
+
+At Facebook we have applied the map-reduce approach to testing and have observed 10X improvements.
+
+The solution supports the following
+
+Distribute tests across machines, collect results/logs
+Share worker pool across different testers
+Try failure 3 times on 3 different machines before calling it a failure
+Support running asan, valgrind, asan-noleaks
+Self management of worker pools. The clients will manage the worker pool including version update, no manual maintenance required
+WORK
+
+Port the code from gluster-fb-3.8 to gluster master
+
+HOW TO RUN
+
+./extras/distributed-testing/distributed-test.sh --hosts '<h1> <h2> <h3>'
+
+All hosts should have no password for ssh via root. This can be achieved with keys setup on the client and the server machines.
diff --git a/extras/distributed-testing/distributed-test-build-env b/extras/distributed-testing/distributed-test-build-env
new file mode 100644
index 00000000000..cd68ff717da
--- /dev/null
+++ b/extras/distributed-testing/distributed-test-build-env
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+GF_CONF_OPTS="--localstatedir=/var --sysconfdir /var/lib --prefix /usr --libdir /usr/lib64 \
+ --enable-bd-xlator=yes --enable-debug --enable-gnfs"
+
+if [ -x /usr/lib/rpm/redhat/dist.sh ]; then
+ REDHAT_MAJOR=$(/usr/lib/rpm/redhat/dist.sh --distnum)
+else
+ REDHAT_MAJOR=0
+fi
+
+ASAN_ENABLED=${ASAN_ENABLED:=0}
+if [ "$ASAN_ENABLED" -eq "1" ]; then
+ GF_CONF_OPTS="$GF_CONF_OPTS --with-asan"
+fi
+
+GF_CONF_OPTS="$GF_CONF_OPTS --with-systemd"
+export GF_CONF_OPTS
+
+export CFLAGS="-O0 -ggdb -fPIC -Wall"
diff --git a/extras/distributed-testing/distributed-test-build.sh b/extras/distributed-testing/distributed-test-build.sh
new file mode 100755
index 00000000000..e8910d8425c
--- /dev/null
+++ b/extras/distributed-testing/distributed-test-build.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+set -e
+
+EXTRA_CONFIGURE_ARGS="$@"
+ASAN_REQUESTED=false
+for arg in $EXTRA_CONFIGURE_ARGS; do
+ if [ $arg == "--with-asan" ]; then
+ echo "Requested ASAN, cleaning build first."
+ make -j distclean || true
+ touch .with_asan
+ ASAN_REQUESTED=true
+ fi
+done
+
+if [ $ASAN_REQUESTED == false ]; then
+ if [ -f .with_asan ]; then
+ echo "Previous build was with ASAN, cleaning build first."
+ make -j distclean || true
+ rm -v .with_asan
+ fi
+fi
+
+source extras/distributed-testing/distributed-test-build-env
+./autogen.sh
+./configure $GF_CONF_OPTS $EXTRA_CONFIGURE_ARGS
+make -j
diff --git a/extras/distributed-testing/distributed-test-env b/extras/distributed-testing/distributed-test-env
new file mode 100644
index 00000000000..36fdd82e5dd
--- /dev/null
+++ b/extras/distributed-testing/distributed-test-env
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+SMOKE_TESTS="\
+ tests/basic/*.t\
+ tests/basic/afr/*.t\
+ tests/basic/distribute/*.t\
+ tests/bugs/fb*.t\
+ tests/features/brick-min-free-space.t\
+"
+
+KNOWN_FLAKY_TESTS="\
+"
+
+BROKEN_TESTS="\
+ tests/features/lock_revocation.t\
+ tests/features/recon.t\
+ tests/features/fdl-overflow.t\
+ tests/features/fdl.t\
+ tests/features/ipc.t\
+ tests/bugs/distribute/bug-1247563.t\
+ tests/bugs/distribute/bug-1543279.t\
+ tests/bugs/distribute/bug-1066798.t\
+ tests/bugs/ec/bug-1304988.t\
+ tests/bugs/unclassified/bug-1357397.t\
+ tests/bugs/quota/bug-1235182.t\
+ tests/bugs/fuse/bug-1309462.t\
+ tests/bugs/glusterd/bug-1238706-daemons-stop-on-peer-cleanup.t\
+ tests/bugs/stripe/bug-1002207.t\
+ tests/bugs/stripe/bug-1111454.t\
+ tests/bugs/snapshot/bug-1140162-file-snapshot-features-encrypt-opts-validation.t\
+ tests/bugs/write-behind/bug-1279730.t\
+ tests/bugs/gfapi/bug-1093594.t\
+ tests/bugs/replicate/bug-1473026.t\
+ tests/bugs/replicate/bug-802417.t\
+ tests/basic/inode-leak.t\
+ tests/basic/distribute/force-migration.t\
+ tests/basic/ec/heal-info.t\
+ tests/basic/ec/ec-seek.t\
+ tests/basic/jbr/jbr-volgen.t\
+ tests/basic/jbr/jbr.t\
+ tests/basic/afr/tarissue.t\
+ tests/basic/tier/tierd_check.t\
+ tests/basic/gfapi/bug1291259.t\
+"
+
+SMOKE_TESTS=$(echo $SMOKE_TESTS | tr -s ' ' ' ')
+KNOWN_FLAKY_TESTS=$(echo $KNOWN_FLAKY_TESTS | tr -s ' ' ' ')
+BROKEN_TESTS=$(echo $BROKEN_TESTS | tr -s ' ' ' ')
diff --git a/extras/distributed-testing/distributed-test-runner.py b/extras/distributed-testing/distributed-test-runner.py
new file mode 100755
index 00000000000..5a07e2feab1
--- /dev/null
+++ b/extras/distributed-testing/distributed-test-runner.py
@@ -0,0 +1,859 @@
+#!/usr/bin/python3
+
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import unicode_literals
+from __future__ import print_function
+import re
+import sys
+import fcntl
+import base64
+import threading
+import socket
+import os
+import shlex
+import argparse
+import subprocess
+import time
+import SimpleXMLRPCServer
+import xmlrpclib
+import md5
+import httplib
+import uuid
+
+DEFAULT_PORT = 9999
+TEST_TIMEOUT_S = 15 * 60
+CLIENT_CONNECT_TIMEOUT_S = 10
+CLIENT_TIMEOUT_S = 60
+PATCH_FILE_UID = str(uuid.uuid4())
+SSH_TIMEOUT_S = 10
+MAX_ATTEMPTS = 3
+ADDRESS_FAMILY = 'IPv4'
+
+
+def socket_instance(address_family):
+ if address_family.upper() == 'ipv4'.upper():
+ return socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ elif address_family.upper() == 'ipv6'.upper():
+ return socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+ else:
+ Log.error("Invalid IP address family")
+ sys.exit(1)
+
+
+def patch_file():
+ return "/tmp/%s-patch.tar.gz" % PATCH_FILE_UID
+
+# ..............................................................................
+# SimpleXMLRPCServer IPvX Wrapper
+# ..............................................................................
+
+
+class GeneralXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
+ def __init__(self, addr):
+ SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, addr)
+
+ def server_bind(self):
+ if self.socket:
+ self.socket.close()
+ self.socket = socket_instance(args.address_family)
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ SimpleXMLRPCServer.SimpleXMLRPCServer.server_bind(self)
+
+
+class HTTPConnection(httplib.HTTPConnection):
+ def __init__(self, host):
+ self.host = host
+ httplib.HTTPConnection.__init__(self, host)
+
+ def connect(self):
+ old_timeout = socket.getdefaulttimeout()
+ self.sock = socket.create_connection((self.host, self.port),
+ timeout=CLIENT_CONNECT_TIMEOUT_S)
+ self.sock.settimeout(old_timeout)
+
+
+class IPTransport(xmlrpclib.Transport):
+ def __init__(self, *args, **kwargs):
+ xmlrpclib.Transport.__init__(self, *args, **kwargs)
+
+ def make_connection(self, host):
+ return HTTPConnection(host)
+
+
+# ..............................................................................
+# Common
+# ..............................................................................
+
+
+class Timer:
+ def __init__(self):
+ self.start = time.time()
+
+ def elapsed_s(self):
+ return int(time.time() - self.start)
+
+ def reset(self):
+ ret = self.elapsed_s()
+ self.start = time.time()
+ return ret
+
+
+def encode(buf):
+ return base64.b16encode(buf)
+
+
+def decode(buf):
+ return base64.b16decode(buf)
+
+
+def get_file_content(path):
+ with open(path, "r") as f:
+ return f.read()
+
+
+def write_to_file(path, data):
+ with open(path, "w") as f:
+ f.write(data)
+
+
+def failsafe(fn, args=()):
+ try:
+ return (True, fn(*args))
+ except (xmlrpclib.Fault, xmlrpclib.ProtocolError, xmlrpclib.ResponseError,
+ Exception) as err:
+ Log.debug(str(err))
+ return (False, None)
+
+
+class LogLevel:
+ DEBUG = 2
+ ERROR = 1
+ CLI = 0
+
+
+class Log:
+ LOGLEVEL = LogLevel.ERROR
+
+ @staticmethod
+ def _normalize(msg):
+ return msg[:100]
+
+ @staticmethod
+ def debug(msg):
+ if Log.LOGLEVEL >= LogLevel.DEBUG:
+ sys.stdout.write("<debug> %s\n" % Log._normalize(msg))
+ sys.stdout.flush()
+
+ @staticmethod
+ def error(msg):
+ sys.stderr.write("<error> %s\n" % Log._normalize(msg))
+
+ @staticmethod
+ def header(msg):
+ sys.stderr.write("* %s *\n" % Log._normalize(msg))
+
+ @staticmethod
+ def cli(msg):
+ sys.stderr.write("%s\n" % msg)
+
+
+class Shell:
+ def __init__(self, cwd=None, logpath=None):
+ self.cwd = cwd
+ self.shell = True
+ self.redirect = open(os.devnull if not logpath else logpath, "wr+")
+
+ def __del__(self):
+ self.redirect.close()
+
+ def cd(self, cwd):
+ Log.debug("cd %s" % cwd)
+ self.cwd = cwd
+
+ def truncate(self):
+ self.redirect.truncate(0)
+
+ def read_logs(self):
+ self.redirect.seek(0)
+ return self.redirect.read()
+
+ def check_call(self, cmd):
+ status = self.call(cmd)
+ if status:
+ raise Exception("Error running command %s. status=%s"
+ % (cmd, status))
+
+ def call(self, cmd):
+ if isinstance(cmd, list):
+ return self._calls(cmd)
+
+ return self._call(cmd)
+
+ def ssh(self, hostname, cmd, id_rsa=None):
+ flags = "" if not id_rsa else "-i " + id_rsa
+ return self.call("timeout %s ssh %s root@%s \"%s\"" %
+ (SSH_TIMEOUT_S, flags, hostname, cmd))
+
+ def scp(self, hostname, src, dest, id_rsa=None):
+ flags = "" if not id_rsa else "-i " + id_rsa
+ return self.call("timeout %s scp %s %s root@%s:%s" %
+ (SSH_TIMEOUT_S, flags, src, hostname, dest))
+
+ def output(self, cmd, cwd=None):
+ Log.debug("%s> %s" % (cwd, cmd))
+ return subprocess.check_output(shlex.split(cmd), cwd=self.cwd)
+
+ def _calls(self, cmds):
+ Log.debug("Running commands. %s" % cmds)
+ for c in cmds:
+ status = self.call(c)
+ if status:
+ Log.error("Commands failed with %s" % status)
+ return status
+ return 0
+
+ def _call(self, cmd):
+ if not self.shell:
+ cmd = shlex.split(cmd)
+
+ Log.debug("%s> %s" % (self.cwd, cmd))
+
+ status = subprocess.call(cmd, cwd=self.cwd, shell=self.shell,
+ stdout=self.redirect, stderr=self.redirect)
+
+ Log.debug("return %s" % status)
+ return status
+
+
+# ..............................................................................
+# Server role
+# ..............................................................................
+
+class TestServer:
+ def __init__(self, port, scratchdir):
+ self.port = port
+ self.scratchdir = scratchdir
+ self.shell = Shell()
+ self.rpc = None
+ self.pidf = None
+
+ self.shell.check_call("mkdir -p %s" % self.scratchdir)
+ self._process_lock()
+
+ def __del__(self):
+ if self.pidf:
+ self.pidf.close()
+
+ def init(self):
+ Log.debug("Starting xmlrpc server on port %s" % self.port)
+ self.rpc = GeneralXMLRPCServer(("", self.port))
+ self.rpc.register_instance(Handlers(self.scratchdir))
+
+ def serve(self):
+ (status, _) = failsafe(self.rpc.serve_forever)
+ Log.cli("== End ==")
+
+ def _process_lock(self):
+ pid_filename = os.path.basename(__file__).replace("/", "-")
+ pid_filepath = "%s/%s.pid" % (self.scratchdir, pid_filename)
+ self.pidf = open(pid_filepath, "w")
+ try:
+ fcntl.lockf(self.pidf, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ # We have the lock, kick anybody listening on this port
+ self.shell.call("kill $(lsof -t -i:%s)" % self.port)
+ except IOError:
+ Log.error("Another process instance is running")
+ sys.exit(0)
+
+#
+# Server Handler
+#
+
+
+handler_lock = threading.Lock()
+handler_serving_since = Timer()
+
+
+def synchronized(func):
+ def decorator(*args, **kws):
+ handler_lock.acquire()
+ h = args[0]
+ try:
+ h.shell.truncate()
+ ret = func(*args, **kws)
+ return ret
+ except Exception() as err:
+ Log.error(str(err))
+ Log.error(decode(h._log_content()))
+ raise
+ finally:
+ handler_lock.release()
+ handler_serving_since.reset()
+
+ return decorator
+
+
+class Handlers:
+ def __init__(self, scratchdir):
+ self.client_id = None
+ self.scratchdir = scratchdir
+ self.gluster_root = "%s/glusterfs" % self.scratchdir
+ self.shell = Shell(logpath="%s/test-handlers.log" % self.scratchdir)
+
+ def hello(self, id):
+ if not handler_lock.acquire(False):
+ return False
+ try:
+ return self._hello_locked(id)
+ finally:
+ handler_lock.release()
+
+ def _hello_locked(self, id):
+ if handler_serving_since.elapsed_s() > CLIENT_TIMEOUT_S:
+ Log.debug("Disconnected client %s" % self.client_id)
+ self.client_id = None
+
+ if not self.client_id:
+ self.client_id = id
+ handler_serving_since.reset()
+ return True
+
+ return (id == self.client_id)
+
+ @synchronized
+ def ping(self, id=None):
+ if id:
+ return id == self.client_id
+ return True
+
+ @synchronized
+ def bye(self, id):
+ assert id == self.client_id
+ self.client_id = None
+ handler_serving_since.reset()
+ return True
+
+ @synchronized
+ def cleanup(self, id):
+ assert id == self.client_id
+ self.shell.cd(self.gluster_root)
+ self.shell.check_call("PATH=.:$PATH; sudo ./clean_gfs_devserver.sh")
+ return True
+
+ @synchronized
+ def copy(self, id, name, content):
+ with open("%s/%s" % (self.scratchdir, name), "w+") as f:
+ f.write(decode(content))
+ return True
+
+ @synchronized
+ def copygzip(self, id, content):
+ assert id == self.client_id
+ gzipfile = "%s/tmp.tar.gz" % self.scratchdir
+ tarfile = "%s/tmp.tar" % self.scratchdir
+ self.shell.check_call("rm -f %s" % gzipfile)
+ self.shell.check_call("rm -f %s" % tarfile)
+ write_to_file(gzipfile, decode(content))
+
+ self.shell.cd(self.scratchdir)
+ self.shell.check_call("rm -r -f %s" % self.gluster_root)
+ self.shell.check_call("mkdir -p %s" % self.gluster_root)
+
+ self.shell.cd(self.gluster_root)
+ cmds = [
+ "gunzip -f -q %s" % gzipfile,
+ "tar -xvf %s" % tarfile
+ ]
+ return self.shell.call(cmds) == 0
+
+ @synchronized
+ def build(self, id, asan=False):
+ assert id == self.client_id
+ self.shell.cd(self.gluster_root)
+ self.shell.call("make clean")
+ env = "ASAN_ENABLED=1" if asan else ""
+ return self.shell.call(
+ "%s ./extras/distributed-testing/distributed-test-build.sh" % env) == 0
+
+ @synchronized
+ def install(self, id):
+ assert id == self.client_id
+ self.shell.cd(self.gluster_root)
+ return self.shell.call("make install") == 0
+
+ @synchronized
+ def prove(self, id, test, timeout, valgrind="no", asan_noleaks=True):
+ assert id == self.client_id
+ self.shell.cd(self.gluster_root)
+ env = "DEBUG=1 "
+ if valgrind == "memcheck" or valgrind == "yes":
+ cmd = "valgrind"
+ cmd += " --tool=memcheck --leak-check=full --track-origins=yes"
+ cmd += " --show-leak-kinds=all -v prove -v"
+ elif valgrind == "drd":
+ cmd = "valgrind"
+ cmd += " --tool=drd -v prove -v"
+ elif asan_noleaks:
+ cmd = "prove -v"
+ env += "ASAN_OPTIONS=detect_leaks=0 "
+ else:
+ cmd = "prove -v"
+
+ status = self.shell.call(
+ "%s timeout %s %s %s" % (env, timeout, cmd, test))
+
+ if status != 0:
+ return (False, self._log_content())
+ return (True, "")
+
+ def _log_content(self):
+ return encode(self.shell.read_logs())
+
+# ..............................................................................
+# Cli role
+# ..............................................................................
+
+
+class RPCConnection((threading.Thread)):
+ def __init__(self, host, port, path, cb):
+ threading.Thread.__init__(self)
+ self.host = host
+ self.port = port
+ self.path = path
+ self.shell = Shell()
+ self.cb = cb
+ self.stop = False
+ self.proxy = None
+ self.logid = "%s:%s" % (self.host, self.port)
+
+ def connect(self):
+ (status, ret) = failsafe(self._connect)
+ return (status and ret)
+
+ def _connect(self):
+ url = "http://%s:%s" % (self.host, self.port)
+ self.proxy = xmlrpclib.ServerProxy(url, transport=IPTransport())
+ return self.proxy.hello(self.cb.id)
+
+ def disconnect(self):
+ self.stop = True
+
+ def ping(self):
+ return self.proxy.ping()
+
+ def init(self):
+ return self._copy() and self._compile_and_install()
+
+ def run(self):
+ (status, ret) = failsafe(self.init)
+ if not status:
+ self.cb.note_lost_connection(self)
+ return
+ elif not ret:
+ self.cb.note_setup_failed(self)
+ return
+
+ while not self.stop:
+ (status, ret) = failsafe(self._run)
+ if not status or not ret:
+ self.cb.note_lost_connection(self)
+ break
+ time.sleep(0)
+
+ failsafe(self.proxy.bye, (self.cb.id,))
+ Log.debug("%s connection thread stopped" % self.host)
+
+ def _run(self):
+ test = self.cb.next_test()
+ (status, _) = failsafe(self._execute_next, (test,))
+ if not status:
+ self.cb.note_retry(test)
+ return False
+ return True
+
+ def _execute_next(self, test):
+ if not test:
+ time.sleep(1)
+ return
+
+ (status, error) = self.proxy.prove(self.cb.id, test,
+ self.cb.test_timeout,
+ self.cb.valgrind,
+ self.cb.asan_noleaks)
+ if status:
+ self.cb.note_done(test)
+ else:
+ self.cb.note_error(test, error)
+
+ def _compile_and_install(self):
+ Log.debug("<%s> Build " % self.logid)
+ asan = self.cb.asan or self.cb.asan_noleaks
+ return (self.proxy.build(self.cb.id, asan) and
+ self.proxy.install(self.cb.id))
+
+ def _copy(self):
+ return self._copy_gzip()
+
+ def _copy_gzip(self):
+ Log.cli("<%s> copying and compiling %s to remote" %
+ (self.logid, self.path))
+ data = encode(get_file_content(patch_file()))
+ Log.debug("GZIP size = %s B" % len(data))
+ return self.proxy.copygzip(self.cb.id, data)
+
+
+class RPCConnectionPool:
+ def __init__(self, gluster_path, hosts, n, id_rsa):
+ self.gluster_path = gluster_path
+ self.hosts = hosts
+ self.conns = []
+ self.faulty = []
+ self.n = int(len(hosts) / 2) + 1 if not n else n
+ self.id_rsa = id_rsa
+ self.stop = False
+ self.scanner = threading.Thread(target=self._scan_hosts_loop)
+ self.kicker = threading.Thread(target=self._kick_hosts_loop)
+ self.shell = Shell()
+ self.since_start = Timer()
+
+ self.shell.check_call("rm -f %s" % patch_file())
+ self.shell.check_call("tar -zcvf %s ." % patch_file())
+ self.id = md5.new(get_file_content(patch_file())).hexdigest()
+ Log.cli("client UID %s" % self.id)
+ Log.cli("patch UID %s" % PATCH_FILE_UID)
+
+ def __del__(self):
+ self.shell.check_call("rm -f %s" % patch_file())
+
+ def pool_status(self):
+ elapsed_m = int(self.since_start.elapsed_s() / 60)
+ return "%s/%s connected, %smin elapsed" % (len(self.conns), self.n,
+ elapsed_m)
+
+ def connect(self):
+ Log.debug("Starting scanner")
+ self.scanner.start()
+ self.kicker.start()
+
+ def disconnect(self):
+ self.stop = True
+ for conn in self.conns:
+ conn.disconnect()
+
+ def note_lost_connection(self, conn):
+ Log.cli("lost connection to %s" % conn.host)
+ self.conns.remove(conn)
+ self.hosts.append((conn.host, conn.port))
+
+ def note_setup_failed(self, conn):
+ Log.error("Setup failed on %s:%s" % (conn.host, conn.port))
+ self.conns.remove(conn)
+ self.faulty.append((conn.host, conn.port))
+
+ def _scan_hosts_loop(self):
+ Log.debug("Scanner thread started")
+ while not self.stop:
+ failsafe(self._scan_hosts)
+ time.sleep(5)
+
+ def _scan_hosts(self):
+ if len(self.hosts) == 0 and len(self.conns) == 0:
+ Log.error("no more hosts available to loadbalance")
+ sys.exit(1)
+
+ for (host, port) in self.hosts:
+ if (len(self.conns) >= self.n) or self.stop:
+ break
+ self._scan_host(host, port)
+
+ def _scan_host(self, host, port):
+ Log.debug("scanning %s:%s" % (host, port))
+ c = RPCConnection(host, port, self.gluster_path, self)
+ (status, result) = failsafe(c.connect)
+ if status and result:
+ self.hosts.remove((host, port))
+ Log.debug("Connected to %s:%s" % (host, port))
+ self.conns.append(c)
+ c.start()
+ Log.debug("%s / %s connected" % (len(self.conns), self.n))
+ else:
+ Log.debug("Failed to connect to %s:%s" % (host, port))
+
+ def _kick_hosts_loop(self):
+ Log.debug("Kick thread started")
+ while not self.stop:
+ time.sleep(10)
+ failsafe(self._kick_hosts)
+
+ Log.debug("Kick thread stopped")
+
+ def _is_pingable(self, host, port):
+ c = RPCConnection(host, port, self.gluster_path, self)
+ failsafe(c.connect)
+ (status, result) = failsafe(c.ping)
+ return status and result
+
+ def _kick_hosts(self):
+ # Do not kick hosts if we have the optimal number of connections
+ if (len(self.conns) >= self.n) or self.stop:
+ Log.debug("Skip kicking hosts")
+ return
+
+ # Check and if dead kick all hosts
+ for (host, port) in self.hosts:
+ if self.stop:
+ Log.debug("Break kicking hosts")
+ break
+
+ if self._is_pingable(host, port):
+ Log.debug("Host=%s is alive. Won't kick" % host)
+ continue
+
+ Log.debug("Kicking %s" % host)
+ mypath = sys.argv[0]
+ myname = os.path.basename(mypath)
+ destpath = "/tmp/%s" % myname
+ sh = Shell()
+ sh.scp(host, mypath, destpath, self.id_rsa)
+ sh.ssh(host, "nohup %s --server &>> %s.log &" %
+ (destpath, destpath), self.id_rsa)
+
+ def join(self):
+ self.scanner.join()
+ self.kicker.join()
+ for c in self.conns:
+ c.join()
+
+
+# ..............................................................................
+# test role
+# ..............................................................................
+
+class TestRunner(RPCConnectionPool):
+ def __init__(self, gluster_path, hosts, n, tests, flaky_tests, valgrind,
+ asan, asan_noleaks, id_rsa, test_timeout):
+ RPCConnectionPool.__init__(self, gluster_path, self._parse_hosts(hosts),
+ n, id_rsa)
+ self.flaky_tests = flaky_tests.split(" ")
+ self.pending = []
+ self.done = []
+ self.error = []
+ self.retry = {}
+ self.error_logs = []
+ self.stats_timer = Timer()
+ self.valgrind = valgrind
+ self.asan = asan
+ self.asan_noleaks = asan_noleaks
+ self.test_timeout = test_timeout
+
+ self.tests = self._get_tests(tests)
+
+ Log.debug("tests: %s" % self.tests)
+
+ def _get_tests(self, tests):
+ if not tests or tests == "all":
+ return self._not_flaky(self._all())
+ elif tests == "flaky":
+ return self.flaky_tests
+ else:
+ return self._not_flaky(tests.strip().split(" "))
+
+ def run(self):
+ self.connect()
+ self.join()
+ return len(self.error)
+
+ def _pretty_print(self, data):
+ if isinstance(data, list):
+ str = ""
+ for i in data:
+ str = "%s %s" % (str, i)
+ return str
+ return "%s" % data
+
+ def print_result(self):
+ Log.cli("== RESULTS ==")
+ Log.cli("SUCCESS : %s" % len(self.done))
+ Log.cli("ERRORS : %s" % len(self.error))
+ Log.cli("== ERRORS ==")
+ Log.cli(self._pretty_print(self.error))
+ Log.cli("== LOGS ==")
+ Log.cli(self._pretty_print(self.error_logs))
+ Log.cli("== END ==")
+
+ def next_test(self):
+ if len(self.tests):
+ test = self.tests.pop()
+ self.pending.append(test)
+ return test
+
+ if not len(self.pending):
+ self.disconnect()
+
+ return None
+
+ def _pct_completed(self):
+ total = len(self.tests) + len(self.pending) + len(self.done)
+ total += len(self.error)
+ completed = len(self.done) + len(self.error)
+ return 0 if not total else int(completed / total * 100)
+
+ def note_done(self, test):
+ Log.cli("%s PASS (%s%% done) (%s)" % (test, self._pct_completed(),
+ self.pool_status()))
+ self.pending.remove(test)
+ self.done.append(test)
+ if test in self.retry:
+ del self.retry[test]
+
+ def note_error(self, test, errstr):
+ Log.cli("%s FAIL" % test)
+ self.pending.remove(test)
+ if test not in self.retry:
+ self.retry[test] = 1
+
+ if errstr:
+ path = "%s/%s-%s.log" % ("/tmp", test.replace("/", "-"),
+ self.retry[test])
+ failsafe(write_to_file, (path, decode(errstr),))
+ self.error_logs.append(path)
+
+ if self.retry[test] < MAX_ATTEMPTS:
+ self.retry[test] += 1
+ Log.debug("retry test %s attempt %s" % (test, self.retry[test]))
+ self.tests.append(test)
+ else:
+ Log.debug("giveup attempt test %s" % test)
+ del self.retry[test]
+ self.error.append(test)
+
+ def note_retry(self, test):
+ Log.cli("retry %s on another host" % test)
+ self.pending.remove(test)
+ self.tests.append(test)
+
+ #
+ # test classifications
+ #
+ def _all(self):
+ return self._list_tests(["tests"], recursive=True)
+
+ def _not_flaky(self, tests):
+ for t in self.flaky_tests:
+ if t in tests:
+ tests.remove(t)
+ return tests
+
+ def _list_tests(self, prefixes, recursive=False, ignore_ifnotexist=False):
+ tests = []
+ for prefix in prefixes:
+ real_path = "%s/%s" % (self.gluster_path, prefix)
+ if not os.path.exists(real_path) and ignore_ifnotexist:
+ continue
+ for f in os.listdir(real_path):
+ if os.path.isdir(real_path + "/" + f):
+ if recursive:
+ tests += self._list_tests([prefix + "/" + f], recursive)
+ else:
+ if re.match(r".*\.t$", f):
+ tests += [prefix + "/" + f]
+ return tests
+
+ def _parse_hosts(self, hosts):
+ ret = []
+ for h in args.hosts.split(" "):
+ ret.append((h, DEFAULT_PORT))
+ Log.debug(ret)
+ return ret
+
+# ..............................................................................
+# Roles entry point
+# ..............................................................................
+
+
+def run_as_server(args):
+ if not args.server_path:
+ Log.error("please provide server path")
+ return 1
+
+ server = TestServer(args.port, args.server_path)
+ server.init()
+ server.serve()
+ return 0
+
+
+def run_as_tester(args):
+ Log.header("GLUSTER TEST CLI")
+
+ Log.debug("args = %s" % args)
+
+ tests = TestRunner(args.gluster_path, args.hosts, args.n, args.tests,
+ args.flaky_tests, valgrind=args.valgrind,
+ asan=args.asan, asan_noleaks=args.asan_noleaks,
+ id_rsa=args.id_rsa, test_timeout=args.test_timeout)
+ result = tests.run()
+ tests.print_result()
+ return result
+
+# ..............................................................................
+# main
+# ..............................................................................
+
+
+def main(args):
+ if args.v:
+ Log.LOGLEVEL = LogLevel.DEBUG
+
+ if args.server and args.tester:
+ Log.error("Invalid arguments. More than one role specified")
+ sys.exit(1)
+
+ if args.server:
+ sys.exit(run_as_server(args))
+ elif args.tester:
+ sys.exit(run_as_tester(args))
+ else:
+ Log.error("please specify a mode for CI")
+ parser.print_help()
+ sys.exit(1)
+
+
+parser = argparse.ArgumentParser(description="Gluster CI")
+
+# server role
+parser.add_argument("--server", help="start server", action="store_true")
+parser.add_argument("--server_path", help="server scratch space",
+ default="/tmp/gluster-test")
+parser.add_argument("--host", help="server address to listen", default="")
+parser.add_argument("--port", help="server port to listen",
+ type=int, default=DEFAULT_PORT)
+# test role
+parser.add_argument("--tester", help="start tester", action="store_true")
+parser.add_argument("--valgrind[=memcheck,drd]",
+ help="run tests with valgrind tool 'memcheck' or 'drd'",
+ default="no")
+parser.add_argument("--asan", help="test with asan enabled",
+ action="store_true")
+parser.add_argument("--asan-noleaks", help="test with asan but no mem leaks",
+ action="store_true")
+parser.add_argument("--tests", help="all/flaky/list of tests", default=None)
+parser.add_argument("--flaky_tests", help="list of flaky tests", default=None)
+parser.add_argument("--n", help="max number of machines to use", type=int,
+ default=0)
+parser.add_argument("--hosts", help="list of worker machines")
+parser.add_argument("--gluster_path", help="gluster path to test",
+ default=os.getcwd())
+parser.add_argument("--id-rsa", help="private key to use for ssh",
+ default=None)
+parser.add_argument("--test-timeout",
+ help="test timeout in sec (default 15min)",
+ default=TEST_TIMEOUT_S)
+# general
+parser.add_argument("-v", help="verbose", action="store_true")
+parser.add_argument("--address_family", help="IPv6 or IPv4 to use",
+ default=ADDRESS_FAMILY)
+
+args = parser.parse_args()
+
+main(args)
diff --git a/extras/distributed-testing/distributed-test.sh b/extras/distributed-testing/distributed-test.sh
new file mode 100755
index 00000000000..8f1e0310f33
--- /dev/null
+++ b/extras/distributed-testing/distributed-test.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+source ./extras/distributed-testing/distributed-test-env
+
+N=0
+TESTS='all'
+FLAKY=$KNOWN_FLAKY_TESTS
+BROKEN=$BROKEN_TESTS
+TEST_TIMEOUT_S=900
+ADDRESS_FAMILY='IPv4'
+
+FLAGS=""
+
+function print_env {
+ echo "Settings:"
+ echo "N=$N"
+ echo -e "-------\nHOSTS\n$HOSTS\n-------"
+ echo -e "TESTS\n$TESTS\n-------"
+ echo -e "SKIP\n$FLAKY $BROKEN\n-------"
+ echo -e "TEST_TIMEOUT_S=$TEST_TIMEOUT_S s\n"
+}
+
+function cleanup {
+ rm -f /tmp/test*.log
+}
+
+function usage {
+ echo "Usage: $0 [-h or --help] [-v or --verbose]
+ [--all] [--flaky] [--smoke] [--broken]
+ [--valgrind] [--asan] [--asan-noleaks]
+ [--hosts <hosts>] [-n <parallelism>]
+ [--tests <tests>]
+ [--id-rsa <ssh private key>]
+ [--address_family <IPv4 or IPv6>]
+ "
+}
+
+function parse_args () {
+ args=`getopt \
+ -o hvn: \
+ --long help,verbose,address_family:,valgrind,asan,asan-noleaks,all,\
+smoke,flaky,broken,hosts:,tests:,id-rsa:,test-timeout: \
+ -n 'fb-remote-test.sh' -- "$@"`
+
+ if [ $? != 0 ]; then
+ echo "Error parsing getopt"
+ exit 1
+ fi
+
+ eval set -- "$args"
+
+ while true; do
+ case "$1" in
+ -h | --help) usage ; exit 1 ;;
+ -v | --verbose) FLAGS="$FLAGS -v" ; shift ;;
+ --address_family) ADDRESS_FAMILY=$2; shift 2 ;;
+ --valgrind) FLAGS="$FLAGS --valgrind" ; shift ;;
+ --asan-noleaks) FLAGS="$FLAGS --asan-noleaks"; shift ;;
+ --asan) FLAGS="$FLAGS --asan" ; shift ;;
+ --hosts) HOSTS=$2; shift 2 ;;
+ --tests) TESTS=$2; FLAKY= ; BROKEN= ; shift 2 ;;
+ --test-timeout) TEST_TIMEOUT_S=$2; shift 2 ;;
+ --all) TESTS='all' ; shift 1 ;;
+ --flaky) TESTS=$FLAKY; FLAKY= ; shift 1 ;;
+ --smoke) TESTS=$SMOKE_TESTS; shift 1 ;;
+ --broken) TESTS=$BROKEN_TESTS; FLAKY= ; BROKEN= ; shift 1 ;;
+ --id-rsa) FLAGS="$FLAGS --id-rsa $2" ; shift 2 ;;
+ -n) N=$2; shift 2 ;;
+ *) break ;;
+ esac
+ done
+ run_tests_args="$@"
+}
+
+function main {
+ parse_args "$@"
+
+ if [ -z "$HOSTS" ]; then
+ echo "Please provide hosts to run the tests in"
+ exit -1
+ fi
+
+ print_env
+
+ cleanup
+
+ "extras/distributed-testing/distributed-test-runner.py" $FLAGS --tester \
+ --n "$N" --hosts "$HOSTS" --tests "$TESTS" \
+ --flaky_tests "$FLAKY $BROKEN" --test-timeout "$TEST_TIMEOUT_S" \
+ --address_family "$ADDRESS_FAMILY"
+
+ exit $?
+}
+
+main "$@"
diff --git a/extras/ec-heal-script/README.md b/extras/ec-heal-script/README.md
new file mode 100644
index 00000000000..aaefd6681f6
--- /dev/null
+++ b/extras/ec-heal-script/README.md
@@ -0,0 +1,69 @@
+# gluster-heal-scripts
+Scripts to correct extended attributes of fragments of files to make them healble.
+
+Following are the guidelines/suggestions to use these scripts.
+
+1 - Passwordless ssh should be setup for all the nodes of the cluster.
+
+2 - Scripts should be executed from one of these nodes.
+
+3 - Make sure NO "IO" is going on for the files for which we are running
+these two scripts.
+
+4 - There should be no heal going on for the file for which xattrs are being
+set by correct_pending_heals.sh. Disable the self heal while running this script.
+
+5 - All the bricks of the volume should be UP to identify good and bad fragments
+and to decide if an entry is healble or not.
+
+6 - If correct_pending_heals.sh is stopped in the middle while it was processing
+healble entries, it is suggested to re-run gfid_needing_heal_parallel.sh to create
+latest list of healble and non healble entries and "potential_heal" "can_not_heal" files.
+
+7 - Based on the number of entries, these files might take time to get and set the
+stats and xattrs of entries.
+
+8 - A backup of the fragments will be taken on <brick path>/.glusterfs/correct_pending_heals
+ directory with a file name same as gfid.
+
+9 - Once the correctness of the file gets verified by user, these backup should be removed.
+
+10 - Make sure we have enough space on bricks to take these backups.
+
+11 - At the end this will create two files -
+ 1 - modified_and_backedup_files - Contains list of files which have been modified and should be healed.
+ 2 - can_not_heal - Contains list of files which can not be healed.
+
+12 - It is suggested that the integrity of the data of files, which were modified and healed,
+ should be checked by the user.
+
+
+Usage:
+
+Following are the sequence of steps to use these scripts -
+
+1 - ./gfid_needing_heal_parallel.sh <volume name>
+
+ Execute gfid_needing_heal_parallel.sh with volume name to create list of files which could
+ be healed and can not be healed. It creates "potential_heal" and "can_not_heal" files.
+ During execution, it also displays the list of files on consol with the verdict.
+
+2 - ./correct_pending_heals.sh
+
+ Execute correct_pending_heals.sh without any argument. This script processes entries present
+ in "heal" file. It asks user to enter how many files we want to process in one attempt.
+ Once the count is provided, this script will fetch the entries one by one from "potential_heal" file and takes necessary action.
+ If at this point also a file can not be healed, it will be pushed to "can_not_heal" file.
+ If a file can be healed, this script will modify the xattrs of that file fragments and create an entry in "modified_and_backedup_files" file
+
+3 - At the end, all the entries of "potential_heal" will be processed and based on the processing only two files will be left.
+
+ 1 - modified_and_backedup_files - Contains list of files which have been modified and should be healed.
+ 2 - can_not_heal - Contains list of files which can not be healed.
+
+Logs and other files -
+
+1 - modified_and_backedup_files - It contains all the files which could be healed and the location of backup of each fragments.
+2 - can_not_heal - It contains all the files which can not be healed.
+3 - potential_heal - List of files which could be healed and should be processed by "correct_pending_heals.sh"
+4 - /var/log/glusterfs/ec-heal-script.log - It contains logs of both the files.
diff --git a/extras/ec-heal-script/correct_pending_heals.sh b/extras/ec-heal-script/correct_pending_heals.sh
new file mode 100755
index 00000000000..c9f19dd7c89
--- /dev/null
+++ b/extras/ec-heal-script/correct_pending_heals.sh
@@ -0,0 +1,415 @@
+#!/bin/bash
+# Copyright (c) 2019-2020 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.
+
+# This script finally resets the xattrs of all the fragments of a file
+# which can be healed as per gfid_needing_heal_parallel.sh.
+# gfid_needing_heal_parallel.sh will produce two files, potential_heal and can_not_heal.
+# This script takes potential_heal as input and resets xattrs of all the fragments
+# of those files present in this file and which could be healed as per
+# trusted.ec.size xattar of the file else it will place the entry in can_not_heal
+# file. Those entries which must be healed will be place in must_heal file
+# after setting xattrs so that user can track those files.
+
+
+MOD_BACKUP_FILES="modified_and_backedup_files"
+CAN_NOT_HEAL="can_not_heal"
+LOG_DIR="/var/log/glusterfs"
+LOG_FILE="$LOG_DIR/ec-heal-script.log"
+LINE_SEP="==================================================="
+
+function heal_log()
+{
+ echo "$1" >> "$LOG_FILE"
+}
+
+function desc ()
+{
+ echo ""
+ echo "This script finally resets the xattrs of all the fragments of a file
+which can be healed as per gfid_needing_heal_parallel.sh.
+gfid_needing_heal_parallel.sh will produce two files, potential_heal and can_not_heal.
+This script takes potential_heal as input and resets xattrs of all the fragments
+of those files present in this file and which could be healed as per
+trusted.ec.size xattar of the file else it will place the entry in can_not_heal
+file. Those entries which must be healed will be place in must_heal file
+after setting xattrs so that user can track those files."
+}
+
+function _init ()
+{
+ if [ $# -ne 0 ]
+ then
+ echo "usage: $0"
+ desc
+ exit 2
+ fi
+
+ if [ ! -f "potential_heal" ]
+ then
+ echo "Nothing to correct. File "potential_heal" does not exist"
+ echo ""
+ desc
+ exit 2
+ fi
+}
+
+function total_file_size_in_hex()
+{
+ local frag_size=$1
+ local size=0
+ local hex_size=""
+
+ size=$((frag_size * 4))
+ hex_size=$(printf '0x%016x' $size)
+ echo "$hex_size"
+}
+
+function backup_file_fragment()
+{
+ local file_host=$1
+ local file_entry=$2
+ local gfid_actual_paths=$3
+ local brick_root=""
+ local temp=""
+ local backup_dir=""
+ local cmd=""
+ local gfid=""
+
+ brick_root=$(echo "$file_entry" | cut -d "#" -f 1)
+ temp=$(echo "$(basename "$BASH_SOURCE")" | cut -d '.' -f 1)
+ backup_dir=$(echo "${brick_root}/.glusterfs/${temp}")
+ file_entry=${file_entry//#}
+
+ gfid=$(echo "${gfid_actual_paths}" | cut -d '|' -f 1 | cut -d '/' -f 5)
+ echo "${file_host}:${backup_dir}/${gfid}" >> "$MOD_BACKUP_FILES"
+
+ cmd="mkdir -p ${backup_dir} && yes | cp -af ${file_entry} ${backup_dir}/${gfid} 2>/dev/null"
+ ssh -n "${file_host}" "${cmd}"
+}
+
+function set_frag_xattr ()
+{
+ local file_host=$1
+ local file_entry=$2
+ local good=$3
+ local cmd1=""
+ local cmd2=""
+ local cmd=""
+ local version="0x00000000000000010000000000000001"
+ local dirty="0x00000000000000010000000000000001"
+
+ if [[ $good -eq 0 ]]
+ then
+ version="0x00000000000000000000000000000000"
+ fi
+
+ cmd1=" setfattr -n trusted.ec.version -v ${version} ${file_entry} &&"
+ cmd2=" setfattr -n trusted.ec.dirty -v ${dirty} ${file_entry}"
+ cmd=${cmd1}${cmd2}
+ ssh -n "${file_host}" "${cmd}"
+}
+
+function set_version_dirty_xattr ()
+{
+ local file_paths=$1
+ local good=$2
+ local gfid_actual_paths=$3
+ local file_entry=""
+ local file_host=""
+ local bpath=""
+
+ for bpath in ${file_paths//,/ }
+ do
+ file_host=$(echo "$bpath" | cut -d ":" -f 1)
+ file_entry=$(echo "$bpath" | cut -d ":" -f 2)
+ backup_file_fragment "$file_host" "$file_entry" "$gfid_actual_paths"
+ file_entry=${file_entry//#}
+ set_frag_xattr "$file_host" "$file_entry" "$good"
+ done
+}
+
+function match_size_xattr_quorum ()
+{
+ local file_paths=$1
+ local file_entry=""
+ local file_host=""
+ local cmd=""
+ local size_xattr=""
+ local bpath=""
+ declare -A xattr_count
+
+ for bpath in ${file_paths//,/ }
+ do
+ size_xattr=""
+ file_host=$(echo "$bpath" | cut -d ":" -f 1)
+ file_entry=$(echo "$bpath" | cut -d ":" -f 2)
+ file_entry=${file_entry//#}
+
+ cmd="getfattr -n trusted.ec.size -d -e hex ${file_entry} 2>/dev/null | grep -w "trusted.ec.size" | cut -d '=' -f 2"
+ size_xattr=$(ssh -n "${file_host}" "${cmd}")
+ if [[ -n $size_xattr ]]
+ then
+ count=$((xattr_count["$size_xattr"] + 1))
+ xattr_count["$size_xattr"]=${count}
+ if [[ $count -ge 4 ]]
+ then
+ echo "${size_xattr}"
+ return
+ fi
+ fi
+ done
+ echo "False"
+}
+
+function match_version_xattr ()
+{
+ local file_paths=$1
+ local file_entry=""
+ local file_host=""
+ local cmd=""
+ local version=""
+ local bpath=""
+ declare -A ver_count
+
+ for bpath in ${file_paths//,/ }
+ do
+ version=""
+ file_host=$(echo "$bpath" | cut -d ":" -f 1)
+ file_entry=$(echo "$bpath" | cut -d ":" -f 2)
+ file_entry=${file_entry//#}
+
+ cmd="getfattr -n trusted.ec.version -d -e hex ${file_entry} 2>/dev/null | grep -w "trusted.ec.version" | cut -d '=' -f 2"
+ version=$(ssh -n "${file_host}" "${cmd}")
+ ver_count["$version"]=$((ver_count["$version"] + 1))
+ done
+ for key in "${ver_count[@]}"
+ do
+ if [[ $key -ge 4 ]]
+ then
+ echo "True"
+ return
+ else
+ echo "False"
+ return
+ fi
+ done
+}
+
+function match_stat_size_with_xattr ()
+{
+ local bpath=$1
+ local size=$2
+ local file_stat=$3
+ local xattr=$4
+ local file_entry=""
+ local file_host=""
+ local cmd=""
+ local stat_output=""
+ local hex_size=""
+
+ file_host=$(echo "$bpath" | cut -d ":" -f 1)
+ file_entry=$(echo "$bpath" | cut -d ":" -f 2)
+
+ file_entry=${file_entry//#}
+ cmd="stat --format=%F:%B:%s $file_entry 2>/dev/null"
+ stat_output=$(ssh -n "${file_host}" "${cmd}")
+ echo "$stat_output" | grep -w "${file_stat}" > /dev/null
+
+ if [[ $? -eq 0 ]]
+ then
+ cmd="getfattr -n trusted.ec.size -d -e hex ${file_entry} 2>/dev/null | grep -w "trusted.ec.size" | cut -d '=' -f 2"
+ hex_size=$(ssh -n "${file_host}" "${cmd}")
+
+ if [[ -z $hex_size || "$hex_size" != "$xattr" ]]
+ then
+ echo "False"
+ return
+ fi
+ size_diff=$(printf '%d' $(( size - hex_size )))
+ if [[ $size_diff -gt 2047 ]]
+ then
+ echo "False"
+ return
+ else
+ echo "True"
+ return
+ fi
+ else
+ echo "False"
+ return
+ fi
+}
+
+function find_file_paths ()
+{
+ local bpath=$1
+ local file_entry=""
+ local file_host=""
+ local cmd=""
+ local brick_root=""
+ local gfid=""
+ local actual_path=""
+ local gfid_path=""
+
+ file_host=$(echo "$bpath" | cut -d ":" -f 1)
+ file_entry=$(echo "$bpath" | cut -d ":" -f 2)
+ brick_root=$(echo "$file_entry" | cut -d "#" -f 1)
+
+ gfid=$(echo "${file_entry}" | grep ".glusterfs")
+ if [[ -n "$gfid" ]]
+ then
+ gfid_path=$(echo "$file_entry" | cut -d "#" -f 2)
+ file_entry=${file_entry//#}
+ cmd="find -L '$brick_root' -samefile '$file_entry' 2>/dev/null | grep -v '.glusterfs' "
+ actual_path=$(ssh -n "${file_host}" "${cmd}")
+ #removing absolute path so that user can refer this from mount point
+ actual_path=${actual_path#"$brick_root"}
+ else
+ actual_path=$(echo "$file_entry" | cut -d "#" -f 2)
+ file_entry=${file_entry//#}
+ cmd="find -L '$brick_root' -samefile '$file_entry' 2>/dev/null | grep '.glusterfs' "
+ gfid_path=$(ssh -n "${file_host}" "${cmd}")
+ gfid_path=${gfid_path#"$brick_root"}
+ fi
+
+ echo "${gfid_path}|${actual_path}"
+}
+
+function log_can_not_heal ()
+{
+ local gfid_actual_paths=$1
+ local file_paths=$2
+ file_paths=${file_paths//#}
+
+ echo "${LINE_SEP}" >> "$CAN_NOT_HEAL"
+ echo "Can Not Heal : $(echo "$gfid_actual_paths" | cut -d '|' -f 2)" >> "$CAN_NOT_HEAL"
+ for bpath in ${file_paths//,/ }
+ do
+ echo "${bpath}" >> "$CAN_NOT_HEAL"
+ done
+}
+
+function check_all_frag_and_set_xattr ()
+{
+ local file_paths=$1
+ local total_size=$2
+ local file_stat=$3
+ local bpath=""
+ local healthy_count=0
+ local match="False"
+ local matching_bricks=""
+ local bad_bricks=""
+ local gfid_actual_paths=""
+
+ for bpath in ${file_paths//,/ }
+ do
+ if [[ -n "$gfid_actual_paths" ]]
+ then
+ break
+ fi
+ gfid_actual_paths=$(find_file_paths "$bpath")
+ done
+
+ match=$(match_size_xattr_quorum "$file_paths")
+
+# echo "${match} : $bpath" >> "$MOD_BACKUP_FILES"
+
+ if [[ "$match" != "False" ]]
+ then
+ xattr="$match"
+ for bpath in ${file_paths//,/ }
+ do
+ match="False"
+ match=$(match_stat_size_with_xattr "$bpath" "$total_size" "$file_stat" "$xattr")
+ if [[ "$match" == "True" ]]
+ then
+ matching_bricks="${bpath},${matching_bricks}"
+ healthy_count=$((healthy_count + 1))
+ else
+ bad_bricks="${bpath},${bad_bricks}"
+ fi
+ done
+ fi
+
+ if [[ $healthy_count -ge 4 ]]
+ then
+ match="True"
+ echo "${LINE_SEP}" >> "$MOD_BACKUP_FILES"
+ echo "Modified : $(echo "$gfid_actual_paths" | cut -d '|' -f 2)" >> "$MOD_BACKUP_FILES"
+ set_version_dirty_xattr "$matching_bricks" 1 "$gfid_actual_paths"
+ set_version_dirty_xattr "$bad_bricks" 0 "$gfid_actual_paths"
+ else
+ log_can_not_heal "$gfid_actual_paths" "${file_paths}"
+ fi
+
+ echo "$match"
+}
+function set_xattr()
+{
+ local count=$1
+ local heal_entry=""
+ local file_stat=""
+ local frag_size=""
+ local total_size=""
+ local file_paths=""
+ local num=""
+ local can_heal_count=0
+
+ heal_log "Started $(basename $BASH_SOURCE) on $(date) "
+
+ while read -r heal_entry
+ do
+ heal_log "$LINE_SEP"
+ heal_log "${heal_entry}"
+
+ file_stat=$(echo "$heal_entry" | cut -d "|" -f 1)
+ frag_size=$(echo "$file_stat" | rev | cut -d ":" -f 1 | rev)
+ total_size="$(total_file_size_in_hex "$frag_size")"
+ file_paths=$(echo "$heal_entry" | cut -d "|" -f 2)
+ match=$(check_all_frag_and_set_xattr "$file_paths" "$total_size" "$file_stat")
+ if [[ "$match" == "True" ]]
+ then
+ can_heal_count=$((can_heal_count + 1))
+ fi
+
+ sed -i '1d' potential_heal
+ count=$((count - 1))
+ if [ $count == 0 ]
+ then
+ num=$(cat potential_heal | wc -l)
+ heal_log "$LINE_SEP"
+ heal_log "${1} : Processed"
+ heal_log "${can_heal_count} : Modified to Heal"
+ heal_log "$((${1} - can_heal_count)) : Moved to can_not_heal."
+ heal_log "${num} : Pending as Potential Heal"
+ exit 0
+ fi
+
+ done < potential_heal
+}
+
+function main ()
+{
+ local count=0
+
+ read -p "Number of files to correct: [choose between 1-1000] (0 for All):" count
+ if [[ $count -lt 0 || $count -gt 1000 ]]
+ then
+ echo "Provide correct value:"
+ exit 2
+ fi
+
+ if [[ $count -eq 0 ]]
+ then
+ count=$(cat potential_heal | wc -l)
+ fi
+ set_xattr "$count"
+}
+
+_init "$@" && main "$@"
diff --git a/extras/ec-heal-script/gfid_needing_heal_parallel.sh b/extras/ec-heal-script/gfid_needing_heal_parallel.sh
new file mode 100755
index 00000000000..d7f53c97c33
--- /dev/null
+++ b/extras/ec-heal-script/gfid_needing_heal_parallel.sh
@@ -0,0 +1,278 @@
+#!/bin/bash
+# Copyright (c) 2019-2020 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.
+
+# This script provides a list of all the files which can be healed or not healed.
+# It also generates two files, potential_heal and can_not_heal, which contains the information
+# of all theose files. These files could be used by correct_pending_heals.sh to correct
+# the fragmnets so that files could be healed by shd.
+
+CAN_NOT_HEAL="can_not_heal"
+CAN_HEAL="potential_heal"
+LINE_SEP="==================================================="
+LOG_DIR="/var/log/glusterfs"
+LOG_FILE="$LOG_DIR/ec-heal-script.log"
+
+function heal_log()
+{
+ echo "$1" >> "$LOG_FILE"
+}
+
+function _init ()
+{
+ if [ $# -ne 1 ]; then
+ echo "usage: $0 <gluster volume name>";
+ echo "This script provides a list of all the files which can be healed or not healed.
+It also generates two files, potential_heal and can_not_heal, which contains the information
+of all theose files. These files could be used by correct_pending_heals.sh to correct
+the fragmnets so that files could be healed by shd."
+ exit 2;
+ fi
+
+ volume=$1;
+}
+
+function get_pending_entries ()
+{
+ local volume_name=$1
+
+ gluster volume heal "$volume_name" info | grep -v ":/" | grep -v "Number of entries" | grep -v "Status:" | sort -u | sed '/^$/d'
+}
+
+function get_entry_path_on_brick()
+{
+ local path="$1"
+ local gfid_string=""
+ if [[ "${path:0:1}" == "/" ]];
+ then
+ echo "$path"
+ else
+ gfid_string="$(echo "$path" | cut -f2 -d':' | cut -f1 -d '>')"
+ echo "/.glusterfs/${gfid_string:0:2}/${gfid_string:2:2}/$gfid_string"
+ fi
+}
+
+function run_command_on_server()
+{
+ local subvolume="$1"
+ local host="$2"
+ local cmd="$3"
+ local output
+ output=$(ssh -n "${host}" "${cmd}")
+ if [ -n "$output" ]
+ then
+ echo "$subvolume:$output"
+ fi
+}
+
+function get_entry_path_all_bricks ()
+{
+ local entry="$1"
+ local bricks="$2"
+ local cmd=""
+ for brick in $bricks
+ do
+ echo "${brick}#$(get_entry_path_on_brick "$entry")"
+ done | tr '\n' ','
+}
+
+function get_stat_for_entry_from_all_bricks ()
+{
+ local entry="$1"
+ local bricks="$2"
+ local subvolume=0
+ local host=""
+ local bpath=""
+ local cmd=""
+
+ for brick in $bricks
+ do
+ if [[ "$((subvolume % 6))" == "0" ]]
+ then
+ subvolume=$((subvolume+1))
+ fi
+ host=$(echo "$brick" | cut -f1 -d':')
+ bpath=$(echo "$brick" | cut -f2 -d':')
+
+ cmd="stat --format=%F:%B:%s $bpath$(get_entry_path_on_brick "$entry") 2>/dev/null"
+ run_command_on_server "$subvolume" "${host}" "${cmd}" &
+ done | sort | uniq -c | sort -rnk1
+}
+
+function get_bricks_from_volume()
+{
+ local v=$1
+ gluster volume info "$v" | grep -E "^Brick[0-9][0-9]*:" | cut -f2- -d':'
+}
+
+function print_entry_gfid()
+{
+ local host="$1"
+ local dirpath="$2"
+ local entry="$3"
+ local gfid
+ gfid="$(ssh -n "${host}" "getfattr -d -m. -e hex $dirpath/$entry 2>/dev/null | grep trusted.gfid=|cut -f2 -d'='")"
+ echo "$entry" - "$gfid"
+}
+
+function print_brick_directory_info()
+{
+ local h="$1"
+ local dirpath="$2"
+ while read -r e
+ do
+ print_entry_gfid "${h}" "${dirpath}" "${e}"
+ done < <(ssh -n "${h}" "ls $dirpath 2>/dev/null")
+}
+
+function print_directory_info()
+{
+ local entry="$1"
+ local bricks="$2"
+ local h
+ local b
+ local gfid
+ for brick in $bricks;
+ do
+ h="$(echo "$brick" | cut -f1 -d':')"
+ b="$(echo "$brick" | cut -f2 -d':')"
+ dirpath="$b$(get_entry_path_on_brick "$entry")"
+ print_brick_directory_info "${h}" "${dirpath}" &
+ done | sort | uniq -c
+}
+
+function print_entries_needing_heal()
+{
+ local quorum=0
+ local entry="$1"
+ local bricks="$2"
+ while read -r line
+ do
+ quorum=$(echo "$line" | awk '{print $1}')
+ if [[ "$quorum" -lt 4 ]]
+ then
+ echo "$line - Not in Quorum"
+ else
+ echo "$line - In Quorum"
+ fi
+ done < <(print_directory_info "$entry" "$bricks")
+}
+
+function find_file_paths ()
+{
+ local bpath=$1
+ local file_entry=""
+ local file_host=""
+ local cmd=""
+ local brick_root=""
+ local gfid=""
+ local actual_path=""
+ local gfid_path=""
+
+ file_host=$(echo "$bpath" | cut -d ":" -f 1)
+ file_entry=$(echo "$bpath" | cut -d ":" -f 2)
+ brick_root=$(echo "$file_entry" | cut -d "#" -f 1)
+
+ gfid=$(echo "${file_entry}" | grep ".glusterfs")
+
+ if [[ -n "$gfid" ]]
+ then
+ gfid_path=$(echo "$file_entry" | cut -d "#" -f 2)
+ file_entry=${file_entry//#}
+ cmd="find -L '$brick_root' -samefile '$file_entry' 2>/dev/null | grep -v '.glusterfs' "
+ actual_path=$(ssh -n "${file_host}" "${cmd}")
+ #removing absolute path so that user can refer this from mount point
+ actual_path=${actual_path#"$brick_root"}
+ else
+ actual_path=$(echo "$file_entry" | cut -d "#" -f 2)
+ file_entry=${file_entry//#}
+ cmd="find -L '$brick_root' -samefile '$file_entry' 2>/dev/null | grep '.glusterfs' "
+ gfid_path=$(ssh -n "${file_host}" "${cmd}")
+ gfid_path=${gfid_path#"$brick_root"}
+ fi
+
+ echo "${gfid_path}|${actual_path}"
+}
+
+function log_can_not_heal ()
+{
+ local gfid_actual_paths=$1
+ local file_paths=$2
+ file_paths=${file_paths//#}
+
+ echo "${LINE_SEP}" >> "$CAN_NOT_HEAL"
+ echo "Can Not Heal : $(echo "$gfid_actual_paths" | cut -d '|' -f 2)" >> "$CAN_NOT_HEAL"
+ for bpath in ${file_paths//,/ }
+ do
+ echo "${bpath}" >> "$CAN_NOT_HEAL"
+ done
+}
+
+function main ()
+{
+ local bricks=""
+ local quorum=0
+ local stat_info=""
+ local file_type=""
+ local gfid_actual_paths=""
+ local bpath=""
+ local file_paths=""
+ local good=0
+ local bad=0
+ bricks=$(get_bricks_from_volume "$volume")
+ rm -f "$CAN_HEAL"
+ rm -f "$CAN_NOT_HEAL"
+ mkdir "$LOG_DIR" -p
+
+ heal_log "Started $(basename "$BASH_SOURCE") on $(date) "
+ while read -r heal_entry
+ do
+ heal_log "------------------------------------------------------------------"
+ heal_log "$heal_entry"
+
+ gfid_actual_paths=""
+ file_paths="$(get_entry_path_all_bricks "$heal_entry" "$bricks")"
+ stat_info="$(get_stat_for_entry_from_all_bricks "$heal_entry" "$bricks")"
+ heal_log "$stat_info"
+
+ quorum=$(echo "$stat_info" | head -1 | awk '{print $1}')
+ good_stat=$(echo "$stat_info" | head -1 | awk '{print $3}')
+ file_type="$(echo "$stat_info" | head -1 | cut -f2 -d':')"
+ if [[ "$file_type" == "directory" ]]
+ then
+ print_entries_needing_heal "$heal_entry" "$bricks"
+ else
+ if [[ "$quorum" -ge 4 ]]
+ then
+ good=$((good + 1))
+ heal_log "Verdict: Healable"
+
+ echo "${good_stat}|$file_paths" >> "$CAN_HEAL"
+ else
+ bad=$((bad + 1))
+ heal_log "Verdict: Not Healable"
+ for bpath in ${file_paths//,/ }
+ do
+ if [[ -z "$gfid_actual_paths" ]]
+ then
+ gfid_actual_paths=$(find_file_paths "$bpath")
+ else
+ break
+ fi
+ done
+ log_can_not_heal "$gfid_actual_paths" "${file_paths}"
+ fi
+ fi
+ done < <(get_pending_entries "$volume")
+ heal_log "========================================="
+ heal_log "Total number of potential heal : ${good}"
+ heal_log "Total number of can not heal : ${bad}"
+ heal_log "========================================="
+}
+
+_init "$@" && main "$@"
diff --git a/extras/failed-tests.py b/extras/failed-tests.py
new file mode 100755
index 00000000000..f7f110246b5
--- /dev/null
+++ b/extras/failed-tests.py
@@ -0,0 +1,180 @@
+#!/usr/bin/python3
+
+from __future__ import print_function
+import blessings
+import requests
+from requests.packages.urllib3.exceptions import InsecureRequestWarning
+import re
+import argparse
+from collections import defaultdict
+from datetime import timedelta, datetime
+from pystache import render
+
+# This tool goes though the Gluster regression links and checks for failures
+
+BASE = 'https://build.gluster.org'
+TERM = blessings.Terminal()
+MAX_BUILDS = 1000
+summary = defaultdict(list)
+VERBOSE = None
+
+
+def process_failure(url, node):
+ text = requests.get(url, verify=False).text
+ accum = []
+ for t in text.split('\n'):
+ if t.find("Result: FAIL") != -1:
+ for t2 in accum:
+ if VERBOSE:
+ print(t2.encode('utf-8'))
+ if t2.find("Wstat") != -1:
+ test_case = re.search('\./tests/.*\.t', t2)
+ if test_case:
+ summary[test_case.group()].append((url, node))
+ accum = []
+ elif t.find("cur_cores=/") != -1:
+ summary["core"].append([t.split("/")[1]])
+ summary["core"].append(url)
+ else:
+ accum.append(t)
+
+
+def print_summary(failed_builds, total_builds, html=False):
+ # All the templates
+ count = [
+ '{{failed}} of {{total}} regressions failed',
+ '<p><b>{{failed}}</b> of <b>{{total}}</b> regressions failed</p>'
+ ]
+ regression_link = [
+ '\tRegression Link: {{link}}\n'
+ '\tNode: {{node}}',
+ '<p>&emsp;Regression Link: {{link}}</p>'
+ '<p>&emsp;Node: {{node}}</p>'
+ ]
+ component = [
+ '\tComponent: {{comp}}',
+ '<p>&emsp;Component: {{comp}}</p>'
+ ]
+ failure_count = [
+ ''.join([
+ TERM.red,
+ '{{test}} ; Failed {{count}} times',
+ TERM.normal
+ ]),
+ (
+ '<p><font color="red"><b>{{test}};</b> Failed <b>{{count}}'
+ '</b> times</font></p>'
+ )
+ ]
+
+ template = 0
+ if html:
+ template = 1
+ print(render(
+ count[template],
+ {'failed': failed_builds, 'total': total_builds}
+ ))
+ for k, v in summary.items():
+ if k == 'core':
+ print(''.join([TERM.red, "Found cores:", TERM.normal]))
+ for comp, link in zip(v[::2], v[1::2]):
+ print(render(component[template], {'comp': comp}))
+ print(render(
+ regression_link[template],
+ {'link': link[0], 'node': link[1]}
+ ))
+ else:
+ print(render(failure_count[template], {'test': k, 'count': len(v)}))
+ for link in v:
+ print(render(
+ regression_link[template],
+ {'link': link[0], 'node': link[1]}
+ ))
+
+
+def get_summary(cut_off_date, reg_link):
+ '''
+ Get links to the failed jobs
+ '''
+ success_count = 0
+ failure_count = 0
+ for page in range(0, MAX_BUILDS, 100):
+ build_info = requests.get(''.join([
+ BASE,
+ reg_link,
+ 'api/json?depth=1&tree=allBuilds'
+ '[url,result,timestamp,builtOn]',
+ '{{{0},{1}}}'.format(page, page+100)
+ ]), verify=False).json()
+ for build in build_info.get('allBuilds'):
+ if datetime.fromtimestamp(build['timestamp']/1000) < cut_off_date:
+ # stop when timestamp older than cut off date
+ return failure_count, failure_count + success_count
+ if build['result'] in [None, 'SUCCESS']:
+ # pass when build is a success or ongoing
+ success_count += 1
+ continue
+ if VERBOSE:
+ print(''.join([
+ TERM.red,
+ 'FAILURE on {0}'.format(build['url']),
+ TERM.normal
+ ]))
+ url = ''.join([build['url'], 'consoleText'])
+ failure_count += 1
+ process_failure(url, build['builtOn'])
+ return failure_count, failure_count + success_count
+
+
+def main(num_days, regression_link, html_report):
+ cut_off_date = datetime.today() - timedelta(days=num_days)
+ failure = 0
+ total = 0
+ for reg in regression_link:
+ if reg == 'centos':
+ reg_link = '/job/centos6-regression/'
+ elif reg == 'netbsd':
+ reg_link = '/job/netbsd7-regression/'
+ else:
+ reg_link = reg
+ counts = get_summary(cut_off_date, reg_link)
+ failure += counts[0]
+ total += counts[1]
+ print_summary(failure, total, html_report)
+
+
+if __name__ == '__main__':
+ requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
+ parser = argparse.ArgumentParser()
+ parser.add_argument("get-summary")
+ parser.add_argument(
+ "last_no_of_days",
+ default=1,
+ type=int,
+ help="Regression summary of last number of days"
+ )
+ parser.add_argument(
+ "regression_link",
+ default="centos",
+ nargs='+',
+ help="\"centos\" | \"netbsd\" | any other regression link"
+ )
+ parser.add_argument(
+ "--verbose",
+ default=False,
+ action="store_true",
+ help="Print a detailed report of each test case that is failed"
+ )
+ parser.add_argument(
+ "--html-report",
+ default=False,
+ action="store_true",
+ help="Print a brief report of failed regressions in html format"
+ )
+ args = parser.parse_args()
+ VERBOSE = args.verbose
+ main(
+ num_days=args.last_no_of_days,
+ regression_link=args.regression_link,
+ html_report=args.html_report
+ )
diff --git a/extras/firewalld/Makefile.am b/extras/firewalld/Makefile.am
index a5c11b0b783..530881fb8eb 100644
--- a/extras/firewalld/Makefile.am
+++ b/extras/firewalld/Makefile.am
@@ -1,6 +1,8 @@
EXTRA_DIST = glusterfs.xml
if USE_FIREWALLD
+if WITH_SERVER
staticdir = /usr/lib/firewalld/services/
static_DATA = glusterfs.xml
endif
+endif
diff --git a/extras/firewalld/glusterfs.xml b/extras/firewalld/glusterfs.xml
index f8efd90c3b5..7e176442f5b 100644
--- a/extras/firewalld/glusterfs.xml
+++ b/extras/firewalld/glusterfs.xml
@@ -4,6 +4,7 @@
<description>Default ports for gluster-distributed storage</description>
<port protocol="tcp" port="24007"/> <!--For glusterd -->
<port protocol="tcp" port="24008"/> <!--For glusterd RDMA port management -->
+<port protocol="tcp" port="24009"/> <!--For glustereventsd -->
<port protocol="tcp" port="38465"/> <!--Gluster NFS service -->
<port protocol="tcp" port="38466"/> <!--Gluster NFS service -->
<port protocol="tcp" port="38467"/> <!--Gluster NFS service -->
diff --git a/extras/ganesha/config/ganesha-ha.conf.sample b/extras/ganesha/config/ganesha-ha.conf.sample
index 24054abfdff..c22892bde56 100644
--- a/extras/ganesha/config/ganesha-ha.conf.sample
+++ b/extras/ganesha/config/ganesha-ha.conf.sample
@@ -2,9 +2,6 @@
# must be unique within the subnet
HA_NAME="ganesha-ha-360"
#
-# The gluster server from which to mount the shared data volume.
-HA_VOL_SERVER="server1"
-#
# N.B. you may use short names or long names; you may not use IP addrs.
# Once you select one, stay with it as it will be mildly unpleasant to
# clean up if you switch later on. Ensure that all names - short and/or
@@ -18,5 +15,5 @@ HA_CLUSTER_NODES="server1,server2,..."
# Virtual IPs for each of the nodes specified above.
VIP_server1="10.0.2.1"
VIP_server2="10.0.2.2"
-#VIP_server1.lab.redhat.com="10.0.2.1"
-#VIP_server2.lab.redhat.com="10.0.2.2"
+#VIP_server1_lab_redhat_com="10.0.2.1"
+#VIP_server2_lab_redhat_com="10.0.2.2"
diff --git a/extras/ganesha/ocf/Makefile.am b/extras/ganesha/ocf/Makefile.am
index 6aed9548a0f..990a609f254 100644
--- a/extras/ganesha/ocf/Makefile.am
+++ b/extras/ganesha/ocf/Makefile.am
@@ -9,4 +9,3 @@ ocfdir = $(prefix)/lib/ocf
radir = $(ocfdir)/resource.d/heartbeat
ra_SCRIPTS = ganesha_grace ganesha_mon ganesha_nfsd
-
diff --git a/extras/ganesha/ocf/ganesha_grace b/extras/ganesha/ocf/ganesha_grace
index 75ec16c0fd1..825f7164597 100644
--- a/extras/ganesha/ocf/ganesha_grace
+++ b/extras/ganesha/ocf/ganesha_grace
@@ -30,14 +30,17 @@
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
if [ -n "$OCF_DEBUG_LIBRARY" ]; then
- . $OCF_DEBUG_LIBRARY
+ . $OCF_DEBUG_LIBRARY
else
- : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
-. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+ : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+ . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
fi
+OCF_RESKEY_grace_active_default="grace-active"
+: ${OCF_RESKEY_grace_active=${OCF_RESKEY_grace_active_default}}
+
ganesha_meta_data() {
- cat <<END
+ cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="ganesha_grace">
@@ -51,19 +54,25 @@ resource agent for nfs-ganesha.
<shortdesc lang="en">Manages the user-space nfs-ganesha NFS server</shortdesc>
<parameters>
+<parameter name="grace_active">
+<longdesc lang="en">NFS-Ganesha grace active attribute</longdesc>
+<shortdesc lang="en">NFS-Ganesha grace active attribute</shortdesc>
+<content type="string" default="grace-active" />
+</parameter>
</parameters>
<actions>
<action name="start" timeout="40s" />
<action name="stop" timeout="40s" />
-<action name="status" depth="0" timeout="20s" interval="5s" />
-<action name="monitor" depth="0" timeout="20s" interval="5s" />
+<action name="status" timeout="20s" interval="60s" />
+<action name="monitor" depth="0" timeout="10s" interval="5s" />
+<action name="notify" timeout="10s" />
<action name="meta-data" timeout="20s" />
</actions>
</resource-agent>
END
-return $OCF_SUCCESS
+return ${OCF_SUCCESS}
}
ganesha_grace_usage() {
@@ -73,10 +82,10 @@ ganesha_grace_usage() {
# Make sure meta-data and usage always succeed
case $__OCF_ACTION in
meta-data) ganesha_meta_data
- exit $OCF_SUCCESS
+ exit ${OCF_SUCCESS}
;;
usage|help) ganesha_usage
- exit $OCF_SUCCESS
+ exit ${OCF_SUCCESS}
;;
*)
;;
@@ -84,81 +93,112 @@ esac
ganesha_grace_start()
{
- local result=""
- local resourcename=""
- local deadserver=""
- local tmpIFS=${IFS}
- local pid_file="/var/run/ganesha.nfsd.pid"
-
- # RHEL6 /etc/init.d/nfs-ganesha adds "-p /var/run/ganesha.nfsd.pid"
- # RHEL7 systemd does not. Would be nicer if all distros used the
- # same pid file.
- if [ -e /usr/lib/systemd/system/nfs-ganesha.service ]; then
- pid_file="/var/run/ganesha.pid"
+ local rc=${OCF_ERR_GENERIC}
+ local host=$(hostname -s)
+
+ ocf_log debug "ganesha_grace_start()"
+ # give ganesha_mon RA a chance to set the crm_attr first
+ # I mislike the sleep, but it's not clear that looping
+ # with a small sleep is necessarily better
+ # start has a 40sec timeout, so a 5sec sleep here is okay
+ sleep 5
+ attr=$(crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} 2> /dev/null)
+ if [ $? -ne 0 ]; then
+ host=$(hostname)
+ attr=$(crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} 2> /dev/null )
+ if [ $? -ne 0 ]; then
+ ocf_log info "grace start: crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} failed"
+ fi
+ fi
+
+ # Three possibilities:
+ # 1. There is no attribute at all and attr_updater returns
+ # a zero length string. This happens when
+ # ganesha_mon::monitor hasn't run at least once to set
+ # the attribute. The assumption here is that the system
+ # is coming up. We pretend, for now, that the node is
+ # healthy, to allow the system to continue coming up.
+ # It will cure itself in a few seconds
+ # 2. There is an attribute, and it has the value "1"; this
+ # node is healthy.
+ # 3. There is an attribute, but it has no value or the value
+ # "0"; this node is not healthy.
+
+ # case 1
+ if [[ -z "${attr}" ]]; then
+ return ${OCF_SUCCESS}
fi
- # logger "ganesha_grace_start()"
- # we're here because somewhere in the cluster one or more
- # of the ganesha.nfsds have died, triggering a floating IP
- # address to move. Resource constraint location rules ensure
- # that this is invoked before the floating IP is moved.
- if [ -e ${pid_file} -a \
- -d /proc/$(cat ${pid_file} ) ]; then
- # my ganesha.nfsd is still running
- # find out which one died?
-
- pcs status | grep dead_ip-1 | sort > /tmp/.pcs_status
-
- result=$(diff /var/run/ganesha/pcs_status /tmp/.pcs_status | grep '^>')
- if [[ ${result} ]]; then
- # logger "ganesha_grace_start(), ${result}"
- IFS=$'\n'
- for line in ${result}; do
- resourcename=$(echo ${line} | cut -f 1 | cut -d ' ' -f 3)
- deadserver=${resourcename%"-dead_ip-1"}
-
- if [[ ${deadserver} ]]; then
- # logger "ganesha_grace_start(), ${line}"
- # logger "ganesha_grace_start(), dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace string:${deadserver}"
- dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace string:${deadserver}
- if [ $? -ne 0 ]; then
- logger "warning: dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace string:${deadserver} failed"
- fi
- fi
- done
- IFS=${tmpIFS}
- fi
-
+ # case 2
+ if [[ "${attr}" = *"value=1" ]]; then
+ return ${OCF_SUCCESS}
fi
- return $OCF_SUCCESS
+
+ # case 3
+ return ${OCF_NOT_RUNNING}
}
ganesha_grace_stop()
{
- # logger "ganesha_grace_stop()"
- return $OCF_SUCCESS
+ ocf_log debug "ganesha_grace_stop()"
+ return ${OCF_SUCCESS}
+}
+
+ganesha_grace_notify()
+{
+ # since this is a clone RA we should only ever see pre-start
+ # or post-stop
+ mode="${OCF_RESKEY_CRM_meta_notify_type}-${OCF_RESKEY_CRM_meta_notify_operation}"
+ case "${mode}" in
+ pre-start | post-stop)
+ dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace string:${OCF_RESKEY_CRM_meta_notify_stop_uname}
+ if [ $? -ne 0 ]; then
+ ocf_log info "dbus-send --print-reply --system --dest=org.ganesha.nfsd /org/ganesha/nfsd/admin org.ganesha.nfsd.admin.grace string:${OCF_RESKEY_CRM_meta_notify_stop_uname} failed"
+ fi
+ ;;
+ esac
+
+ return ${OCF_SUCCESS}
}
ganesha_grace_monitor()
{
- # logger "ganesha_grace_monitor()"
- if [ ! -d /var/run/ganesha ]; then
- mkdir -p /var/run/ganesha
+ local host=$(hostname -s)
+
+ ocf_log debug "monitor"
+
+ attr=$(crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} 2> /dev/null)
+ if [ $? -ne 0 ]; then
+ host=$(hostname)
+ attr=$(crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} 2> /dev/null)
+ if [ $? -ne 0 ]; then
+ ocf_log info "crm_attribute --query --node=${host} --name=${OCF_RESKEY_grace_active} failed"
+ fi
+ fi
+
+ # if there is no attribute (yet), maybe it's because
+ # this RA started before ganesha_mon (nfs-mon) has had
+ # chance to create it. In which case we'll pretend
+ # everything is okay this time around
+ if [[ -z "${attr}" ]]; then
+ return ${OCF_SUCCESS}
fi
- pcs status | grep dead_ip-1 | sort > /var/run/ganesha/pcs_status
- return $OCF_SUCCESS
+
+ if [[ "${attr}" = *"value=1" ]]; then
+ return ${OCF_SUCCESS}
+ fi
+
+ return ${OCF_NOT_RUNNING}
}
ganesha_grace_validate()
{
- return $OCF_SUCCESS
+ return ${OCF_SUCCESS}
}
ganesha_grace_validate
-# logger "ganesha_grace ${OCF_RESOURCE_INSTANCE} $__OCF_ACTION"
-
# Translate each action into the appropriate function call
case $__OCF_ACTION in
start) ganesha_grace_start
@@ -167,14 +207,15 @@ stop) ganesha_grace_stop
;;
status|monitor) ganesha_grace_monitor
;;
+notify) ganesha_grace_notify
+ ;;
*) ganesha_grace_usage
- exit $OCF_ERR_UNIMPLEMENTED
- ;;
+ exit ${OCF_ERR_UNIMPLEMENTED}
+ ;;
esac
rc=$?
# The resource agent may optionally log a debug message
-ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $rc"
+ocf_log debug "${OCF_RESOURCE_INSTANCE} ${__OCF_ACTION} returned $rc"
exit $rc
-
diff --git a/extras/ganesha/ocf/ganesha_mon b/extras/ganesha/ocf/ganesha_mon
index c8e7de9c45e..2b4a9d6da84 100644
--- a/extras/ganesha/ocf/ganesha_mon
+++ b/extras/ganesha/ocf/ganesha_mon
@@ -29,17 +29,24 @@
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
-if [ -n "$OCF_DEBUG_LIBRARY" ]; then
- . $OCF_DEBUG_LIBRARY
+if [ -n "${OCF_DEBUG_LIBRARY}" ]; then
+ . ${OCF_DEBUG_LIBRARY}
else
- : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
-. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+ : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+ . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
fi
-GRACE_DELAY=7
+# Defaults
+OCF_RESKEY_ganesha_active_default="ganesha-active"
+OCF_RESKEY_grace_active_default="grace-active"
+OCF_RESKEY_grace_delay_default="5"
+
+: ${OCF_RESKEY_ganesha_active=${OCF_RESKEY_ganesha_active_default}}
+: ${OCF_RESKEY_grace_active=${OCF_RESKEY_grace_active_default}}
+: ${OCF_RESKEY_grace_delay=${OCF_RESKEY_grace_delay_default}}
ganesha_meta_data() {
- cat <<END
+ cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="ganesha_mon">
@@ -53,19 +60,37 @@ resource agent for nfs-ganesha.
<shortdesc lang="en">Manages the user-space nfs-ganesha NFS server</shortdesc>
<parameters>
+<parameter name="ganesha_active">
+<longdesc lang="en">NFS-Ganesha daemon active attribute</longdesc>
+<shortdesc lang="en">NFS-Ganesha daemon active attribute</shortdesc>
+<content type="string" default="ganesha-active" />
+</parameter>
+<parameter name="grace_active">
+<longdesc lang="en">NFS-Ganesha grace active attribute</longdesc>
+<shortdesc lang="en">NFS-Ganesha grace active attribute</shortdesc>
+<content type="string" default="grace-active" />
+</parameter>
+<parameter name="grace_delay">
+<longdesc lang="en">
+NFS-Ganesha grace delay.
+When changing this, adjust the ganesha_grace RA's monitor interval to match.
+</longdesc>
+<shortdesc lang="en">NFS-Ganesha grace delay</shortdesc>
+<content type="string" default="5" />
+</parameter>
</parameters>
<actions>
<action name="start" timeout="40s" />
<action name="stop" timeout="40s" />
-<action name="status" depth="0" timeout="20s" interval="10s" />
+<action name="status" timeout="20s" interval="60s" />
<action name="monitor" depth="0" timeout="10s" interval="10s" />
<action name="meta-data" timeout="20s" />
</actions>
</resource-agent>
END
-return $OCF_SUCCESS
+return ${OCF_SUCCESS}
}
ganesha_mon_usage() {
@@ -73,12 +98,12 @@ ganesha_mon_usage() {
}
# Make sure meta-data and usage always succeed
-case $__OCF_ACTION in
+case ${__OCF_ACTION} in
meta-data) ganesha_meta_data
- exit $OCF_SUCCESS
+ exit ${OCF_SUCCESS}
;;
usage|help) ganesha_usage
- exit $OCF_SUCCESS
+ exit ${OCF_SUCCESS}
;;
*)
;;
@@ -86,72 +111,111 @@ esac
ganesha_mon_start()
{
+ ocf_log debug "ganesha_mon_start"
+ ganesha_mon_monitor
return $OCF_SUCCESS
}
ganesha_mon_stop()
{
+ ocf_log debug "ganesha_mon_stop"
return $OCF_SUCCESS
}
ganesha_mon_monitor()
{
- local short_host=$(hostname -s)
- local pid_file="/var/run/ganesha.nfsd.pid"
+ local host=$(hostname -s)
+ local pid_file="/var/run/ganesha.pid"
+ local rhel6_pid_file="/var/run/ganesha.nfsd.pid"
+ local proc_pid="/proc/"
# RHEL6 /etc/init.d/nfs-ganesha adds -p /var/run/ganesha.nfsd.pid
# RHEL7 systemd does not. Would be nice if all distros used the
# same pid file.
- if [ -e /usr/lib/systemd/system/nfs-ganesha.service ]; then
- pid_file="/var/run/ganesha.pid"
+ if [ -e ${rhel6_pid_file} ]; then
+ pid_file=${rhel6_pid_file}
+ fi
+ if [ -e ${pid_file} ]; then
+ proc_pid="${proc_pid}$(cat ${pid_file})"
fi
- if [ -e ${pid_file} -a \
- -d /proc/$(cat ${pid_file} ) ]; then
- ( pcs resource delete ${short_host}-dead_ip-1 > /dev/null 2>&1 )
+ if [ "x${proc_pid}" != "x/proc/" -a -d ${proc_pid} ]; then
- attrd_updater -n ganesha-active -v 1
+ attrd_updater -n ${OCF_RESKEY_ganesha_active} -v 1
if [ $? -ne 0 ]; then
- logger "warning: attrd_updater -n ganesha-active -v 1 failed"
+ ocf_log info "warning: attrd_updater -n ${OCF_RESKEY_ganesha_active} -v 1 failed"
fi
- else
- ( pcs resource create ${short_host}-dead_ip-1 ocf:heartbeat:Dummy > /dev/null 2>&1 )
+ # ganesha_grace (nfs-grace) RA follows grace-active attr
+ # w/ constraint location
+ attrd_updater -n ${OCF_RESKEY_grace_active} -v 1
if [ $? -ne 0 ]; then
- logger "warning: pcs resource create ${short_host}-dead_ip-1 ocf:heartbeat:Dummy failed"
+ ocf_log info "warning: attrd_updater -n ${OCF_RESKEY_grace_active} -v 1 failed"
fi
- # The ${this-node}-dead_ip-1 resource is used to indicate
- # that this ganesha.nfsd has died.
- # VIP fail-over is then triggered by clearing the
- # ganesha-active node attribute on this node.
- #
- # Meanwhile the ganesha_grace monitor() runs every 5
- # seconds. We need to allow time for it to run and put
- # the remaining ganesha.nfsds into grace before initiating
- # the VIP fail-over.
- sleep ${GRACE_DELAY}
-
- attrd_updater -D -n ganesha-active
+ # ganesha_mon (nfs-mon) and ganesha_grace (nfs-grace)
+ # track grace-active crm_attr (attr != crm_attr)
+ # we can't just use the attr as there's no way to query
+ # its value in RHEL6 pacemaker
+
+ crm_attribute --node=${host} --lifetime=forever --name=${OCF_RESKEY_grace_active} --update=1 2> /dev/null
if [ $? -ne 0 ]; then
- logger "warning: attrd_updater -D -n ganesha-active failed"
+ host=$(hostname)
+ crm_attribute --node=${host} --lifetime=forever --name=${OCF_RESKEY_grace_active} --update=1 2> /dev/null
+ if [ $? -ne 0 ]; then
+ ocf_log info "mon monitor warning: crm_attribute --node=${host} --lifetime=forever --name=${OCF_RESKEY_grace_active} --update=1 failed"
+ fi
fi
+
+ return ${OCF_SUCCESS}
fi
- return $OCF_SUCCESS
+ # VIP fail-over is triggered by clearing the
+ # ganesha-active node attribute on this node.
+ #
+ # Meanwhile the ganesha_grace notify() runs when its
+ # nfs-grace resource is disabled on a node; which
+ # is triggered by clearing the grace-active attribute
+ # on this node.
+ #
+ # We need to allow time for it to run and put
+ # the remaining ganesha.nfsds into grace before
+ # initiating the VIP fail-over.
+
+ attrd_updater -D -n ${OCF_RESKEY_grace_active}
+ if [ $? -ne 0 ]; then
+ ocf_log info "warning: attrd_updater -D -n ${OCF_RESKEY_grace_active} failed"
+ fi
+
+ host=$(hostname -s)
+ crm_attribute --node=${host} --name=${OCF_RESKEY_grace_active} --update=0 2> /dev/null
+ if [ $? -ne 0 ]; then
+ host=$(hostname)
+ crm_attribute --node=${host} --name=${OCF_RESKEY_grace_active} --update=0 2> /dev/null
+ if [ $? -ne 0 ]; then
+ ocf_log info "mon monitor warning: crm_attribute --node=${host} --name=${OCF_RESKEY_grace_active} --update=0 failed"
+ fi
+ fi
+
+ sleep ${OCF_RESKEY_grace_delay}
+
+ attrd_updater -D -n ${OCF_RESKEY_ganesha_active}
+ if [ $? -ne 0 ]; then
+ ocf_log info "warning: attrd_updater -D -n ${OCF_RESKEY_ganesha_active} failed"
+ fi
+
+ return ${OCF_SUCCESS}
}
ganesha_mon_validate()
{
- return $OCF_SUCCESS
+ return ${OCF_SUCCESS}
}
ganesha_mon_validate
-# logger "ganesha_mon ${OCF_RESOURCE_INSTANCE} $__OCF_ACTION"
-
# Translate each action into the appropriate function call
-case $__OCF_ACTION in
+case ${__OCF_ACTION} in
start) ganesha_mon_start
;;
stop) ganesha_mon_stop
@@ -159,13 +223,12 @@ stop) ganesha_mon_stop
status|monitor) ganesha_mon_monitor
;;
*) ganesha_mon_usage
- exit $OCF_ERR_UNIMPLEMENTED
- ;;
+ exit ${OCF_ERR_UNIMPLEMENTED}
+ ;;
esac
rc=$?
# The resource agent may optionally log a debug message
-ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $rc"
+ocf_log debug "${OCF_RESOURCE_INSTANCE} ${__OCF_ACTION} returned $rc"
exit $rc
-
diff --git a/extras/ganesha/ocf/ganesha_nfsd b/extras/ganesha/ocf/ganesha_nfsd
index e064183daef..f91e8b6b8f7 100644
--- a/extras/ganesha/ocf/ganesha_nfsd
+++ b/extras/ganesha/ocf/ganesha_nfsd
@@ -29,15 +29,18 @@
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
-if [ -n "$OCF_DEBUG_LIBRARY" ]; then
- . $OCF_DEBUG_LIBRARY
+if [ -n "${OCF_DEBUG_LIBRARY}" ]; then
+ . ${OCF_DEBUG_LIBRARY}
else
- : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
-. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+ : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+ . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
fi
+OCF_RESKEY_ha_vol_mnt_default="/run/gluster/shared_storage"
+: ${OCF_RESKEY_ha_vol_mnt=${OCF_RESKEY_ha_vol_mnt_default}}
+
ganesha_meta_data() {
- cat <<END
+ cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="ganesha_nfsd">
@@ -59,16 +62,16 @@ resource agent for nfs-ganesha.
</parameters>
<actions>
-<action name="start" timeout="40s" />
-<action name="stop" timeout="40s" />
-<action name="status" depth="0" timeout="20s" interval="1m" />
-<action name="monitor" depth="0" timeout="10s" interval="1m" />
+<action name="start" timeout="5s" />
+<action name="stop" timeout="5s" />
+<action name="status" depth="0" timeout="5s" interval="0" />
+<action name="monitor" depth="0" timeout="5s" interval="0" />
<action name="meta-data" timeout="20s" />
</actions>
</resource-agent>
END
-return $OCF_SUCCESS
+return ${OCF_SUCCESS}
}
ganesha_nfsd_usage() {
@@ -78,10 +81,10 @@ ganesha_nfsd_usage() {
# Make sure meta-data and usage always succeed
case $__OCF_ACTION in
meta-data) ganesha_meta_data
- exit $OCF_SUCCESS
+ exit ${OCF_SUCCESS}
;;
usage|help) ganesha_usage
- exit $OCF_SUCCESS
+ exit ${OCF_SUCCESS}
;;
*)
;;
@@ -89,58 +92,60 @@ esac
ganesha_nfsd_start()
{
- return $OCF_SUCCESS
+ local long_host=$(hostname)
+
+ if [[ -d /var/lib/nfs ]]; then
+ mv /var/lib/nfs /var/lib/nfs.backup
+ if [ $? -ne 0 ]; then
+ ocf_log notice "mv /var/lib/nfs /var/lib/nfs.backup failed"
+ fi
+ ln -s ${OCF_RESKEY_ha_vol_mnt}/nfs-ganesha/${long_host}/nfs /var/lib/nfs
+ if [ $? -ne 0 ]; then
+ ocf_log notice "ln -s ${OCF_RESKEY_ha_vol_mnt}/nfs-ganesha/${long_host}/nfs /var/lib/nfs failed"
+ fi
+ fi
+
+ return ${OCF_SUCCESS}
}
ganesha_nfsd_stop()
{
- local short_host=$(hostname -s)
- local long_host=""
-
- if [ "X${OCF_RESOURCE_INSTANCE:0:9}X" = "Xnfs_startX" ]; then
-
- # if this is any nfs_start, go ahead. worst case we
- # find the link already exists and do nothing
- long_host=$(hostname)
-
- if [ -d /var/lib/nfs ]; then
- mv /var/lib/nfs /var/lib/nfs.backup
- ln -s $OCF_RESKEY_ha_vol_mnt/nfs-ganesha/${long_host}/nfs /var/lib/nfs
- if [ $? -ne 0 ]; then
- logger "warning: ln -s $OCF_RESKEY_ha_vol_mnt/nfs-ganesha/${long_host}/nfs /var/lib/nfs failed"
- fi
+ if [ -L /var/lib/nfs -a -d /var/lib/nfs.backup ]; then
+ rm -f /var/lib/nfs
+ if [ $? -ne 0 ]; then
+ ocf_log notice "rm -f /var/lib/nfs failed"
fi
- else
-
- # if this is a clone resource or is specific to this node
- # remove the symlink and restore /var/lib/nfs
-
- if [ "X${OCF_RESOURCE_INSTANCE}X" = "Xnfs_stopX" ] ||
- [ "X${OCF_RESOURCE_INSTANCE}X" = "Xnfs_stop-${short_host}X" ]; then
- if [ -L /var/lib/nfs -a -d /var/lib/nfs.backup ]; then
- rm -f /var/lib/nfs
- mv /var/lib/nfs.backup /var/lib/nfs
- fi
+ mv /var/lib/nfs.backup /var/lib/nfs
+ if [ $? -ne 0 ]; then
+ ocf_log notice "mv /var/lib/nfs.backup /var/lib/nfs failed"
fi
fi
- return $OCF_SUCCESS
+ return ${OCF_SUCCESS}
}
ganesha_nfsd_monitor()
{
- return $OCF_SUCCESS
+ # pacemaker checks to see if RA is already running before starting it.
+ # if we return success, then it's presumed it's already running and
+ # doesn't need to be started, i.e. invoke the start action.
+ # return something other than success to make pacemaker invoke the
+ # start action
+ if [[ -L /var/lib/nfs ]]; then
+ return ${OCF_SUCCESS}
+ fi
+ return ${OCF_NOT_RUNNING}
}
ganesha_nfsd_validate()
{
- return $OCF_SUCCESS
+ return ${OCF_SUCCESS}
}
ganesha_nfsd_validate
-# logger "ganesha_nfsd ${OCF_RESOURCE_INSTANCE} $__OCF_ACTION"
+# ocf_log notice "ganesha_nfsd ${OCF_RESOURCE_INSTANCE} $__OCF_ACTION"
# Translate each action into the appropriate function call
case $__OCF_ACTION in
@@ -151,13 +156,12 @@ stop) ganesha_nfsd_stop
status|monitor) ganesha_nfsd_monitor
;;
*) ganesha_nfsd_usage
- exit $OCF_ERR_UNIMPLEMENTED
- ;;
+ exit ${OCF_ERR_UNIMPLEMENTED}
+ ;;
esac
rc=$?
# The resource agent may optionally log a debug message
-ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $rc"
+ocf_log debug "${OCF_RESOURCE_INSTANCE} ${__OCF_ACTION} returned $rc"
exit $rc
-
diff --git a/extras/ganesha/scripts/Makefile.am b/extras/ganesha/scripts/Makefile.am
index e71e2f6456b..7e345fd5f19 100644
--- a/extras/ganesha/scripts/Makefile.am
+++ b/extras/ganesha/scripts/Makefile.am
@@ -1,4 +1,6 @@
-EXTRA_DIST= ganesha-ha.sh dbus-send.sh create-export-ganesha.sh
+EXTRA_DIST= create-export-ganesha.sh generate-epoch.py dbus-send.sh \
+ ganesha-ha.sh
scriptsdir = $(libexecdir)/ganesha
-scripts_SCRIPTS = create-export-ganesha.sh dbus-send.sh ganesha-ha.sh
+scripts_SCRIPTS = create-export-ganesha.sh dbus-send.sh generate-epoch.py \
+ ganesha-ha.sh
diff --git a/extras/ganesha/scripts/create-export-ganesha.sh b/extras/ganesha/scripts/create-export-ganesha.sh
index ab7c282af79..3040e8138b0 100755
--- a/extras/ganesha/scripts/create-export-ganesha.sh
+++ b/extras/ganesha/scripts/create-export-ganesha.sh
@@ -1,20 +1,37 @@
-#/bin/bash
+#!/bin/bash
#This script is called by glusterd when the user
#tries to export a volume via NFS-Ganesha.
#An export file specific to a volume
#is created in GANESHA_DIR/exports.
+# Try loading the config from any of the distro
+# specific configuration locations
+if [ -f /etc/sysconfig/ganesha ]
+ then
+ . /etc/sysconfig/ganesha
+fi
+if [ -f /etc/conf.d/ganesha ]
+ then
+ . /etc/conf.d/ganesha
+fi
+if [ -f /etc/default/ganesha ]
+ then
+ . /etc/default/ganesha
+fi
+
GANESHA_DIR=${1%/}
-VOL=$2
-CONF=
-CONFFILE=
+OPTION=$2
+VOL=$3
+CONF=$GANESHA_DIR"/ganesha.conf"
+declare -i EXPORT_ID
function check_cmd_status()
{
if [ "$1" != "0" ]
then
rm -rf $GANESHA_DIR/exports/export.$VOL.conf
+ sed -i /$VOL.conf/d $CONF
exit 1
fi
}
@@ -26,34 +43,6 @@ if [ ! -d "$GANESHA_DIR/exports" ];
check_cmd_status `echo $?`
fi
-function find_rhel7_conf
-{
- while [[ $# > 0 ]]
- do
- key="$1"
- case $key in
- -f)
- CONFFILE="$2"
- ;;
- *)
- ;;
- esac
- shift
- done
-}
-
-cfgline=$(grep ^CONFFILE= /etc/sysconfig/ganesha)
-eval $(echo ${cfgline} | grep -F ^CONFFILE=)
-
-if [ -z $CONFFILE ]
- then
- cfgline=$(grep ^OPTIONS= /etc/sysconfig/ganesha)
- eval $(echo ${cfgline} | grep -F ^OPTIONS=)
- find_rhel7_conf $cfgline
-
-fi
-CONF=${CONFFILE:-/etc/ganesha/ganesha.conf}
-
function write_conf()
{
echo -e "# WARNING : Using Gluster CLI will overwrite manual
@@ -75,11 +64,29 @@ echo " Pseudo=\"/$VOL\";"
echo ' Protocols = "3", "4" ;'
echo ' Transports = "UDP","TCP";'
echo ' SecType = "sys";'
+echo ' Security_Label = False;'
echo " }"
}
-
-write_conf $@ > $GANESHA_DIR/exports/export.$VOL.conf
-if ! (cat $CONF | grep $VOL.conf$ )
+if [ "$OPTION" = "on" ];
then
-echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF
+ if ! (cat $CONF | grep $VOL.conf\"$ )
+ then
+ write_conf $@ > $GANESHA_DIR/exports/export.$VOL.conf
+ echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF
+ count=`ls -l $GANESHA_DIR/exports/*.conf | wc -l`
+ if [ "$count" = "1" ] ; then
+ EXPORT_ID=2
+ else
+ EXPORT_ID=`cat $GANESHA_DIR/.export_added`
+ check_cmd_status `echo $?`
+ EXPORT_ID=EXPORT_ID+1
+ sed -i s/Export_Id.*/"Export_Id= $EXPORT_ID ;"/ \
+ $GANESHA_DIR/exports/export.$VOL.conf
+ check_cmd_status `echo $?`
+ fi
+ echo $EXPORT_ID > $GANESHA_DIR/.export_added
+ fi
+else
+ rm -rf $GANESHA_DIR/exports/export.$VOL.conf
+ sed -i /$VOL.conf/d $CONF
fi
diff --git a/extras/ganesha/scripts/dbus-send.sh b/extras/ganesha/scripts/dbus-send.sh
index 4840be830d6..9d613a0e7ad 100755
--- a/extras/ganesha/scripts/dbus-send.sh
+++ b/extras/ganesha/scripts/dbus-send.sh
@@ -1,95 +1,62 @@
-#/bin/bash
+#!/bin/bash
-declare -i EXPORT_ID
-GANESHA_DIR=${1%/}
-OPTION=$2
-VOL=$3
-CONF=
-CONFFILE=
-
-function find_rhel7_conf
-{
- while [[ $# > 0 ]]
- do
- key="$1"
- case $key in
- -f)
- CONFFILE="$2"
- break;
- ;;
- *)
- ;;
- esac
- shift
- done
-}
-
-cfgline=$(grep ^CONFFILE= /etc/sysconfig/ganesha)
-eval $(echo ${cfgline} | grep -F ^CONFFILE=)
-
-if [ -z $CONFFILE ]
+# Try loading the config from any of the distro
+# specific configuration locations
+if [ -f /etc/sysconfig/ganesha ]
then
- cfgline=$(grep ^OPTIONS= /etc/sysconfig/ganesha)
- eval $(echo ${cfgline} | grep -F ^OPTIONS=)
- find_rhel7_conf $cfgline
-
+ . /etc/sysconfig/ganesha
+fi
+if [ -f /etc/conf.d/ganesha ]
+ then
+ . /etc/conf.d/ganesha
+fi
+if [ -f /etc/default/ganesha ]
+ then
+ . /etc/default/ganesha
fi
-CONF=${CONFFILE:-/etc/ganesha/ganesha.conf}
+GANESHA_DIR=${1%/}
+OPTION=$2
+VOL=$3
+CONF=$GANESHA_DIR"/ganesha.conf"
function check_cmd_status()
{
if [ "$1" != "0" ]
- then
- rm -rf $GANESHA_DIR/exports/export.$VOL.conf
- sed -i /$VOL.conf/d $CONF
- exit 1
+ then
+ logger "dynamic export failed on node :${hostname -s}"
fi
}
#This function keeps track of export IDs and increments it with every new entry
function dynamic_export_add()
{
- count=`ls -l $GANESHA_DIR/exports/*.conf | wc -l`
- if [ "$count" = "1" ] ;
- then
- EXPORT_ID=2
- else
- #if [ -s /var/lib/ganesha/export_removed ];
- # then
- # EXPORT_ID=`head -1 /var/lib/ganesha/export_removed`
- # sed -i -e "1d" /var/lib/ganesha/export_removed
- # else
-
- EXPORT_ID=`cat $GANESHA_DIR/.export_added`
- check_cmd_status `echo $?`
- EXPORT_ID=EXPORT_ID+1
- #fi
- fi
- echo $EXPORT_ID > $GANESHA_DIR/.export_added
- check_cmd_status `echo $?`
- sed -i s/Export_Id.*/"Export_Id= $EXPORT_ID ;"/ \
-$GANESHA_DIR/exports/export.$VOL.conf
- check_cmd_status `echo $?`
dbus-send --system \
--dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \
org.ganesha.nfsd.exportmgr.AddExport string:$GANESHA_DIR/exports/export.$VOL.conf \
string:"EXPORT(Path=/$VOL)"
+ check_cmd_status `echo $?`
}
#This function removes an export dynamically(uses the export_id of the export)
function dynamic_export_remove()
{
- removed_id=`cat $GANESHA_DIR/exports/export.$VOL.conf |\
-grep Export_Id | cut -d " " -f8`
- check_cmd_status `echo $?`
+ # Below bash fetch all the export from ShowExport command and search
+ # export entry based on path and then get its export entry.
+ # There are two possiblities for path, either entire volume will be
+ # exported or subdir. It handles both cases. But it remove only first
+ # entry from the list based on assumption that entry exported via cli
+ # has lowest export id value
+ removed_id=$(dbus-send --type=method_call --print-reply --system \
+ --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \
+ org.ganesha.nfsd.exportmgr.ShowExports | grep -B 1 -we \
+ "/"$VOL -e "/"$VOL"/" | grep uint16 | awk '{print $2}' \
+ | head -1)
+
dbus-send --print-reply --system \
--dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \
org.ganesha.nfsd.exportmgr.RemoveExport uint16:$removed_id
check_cmd_status `echo $?`
- sed -i /$VOL.conf/d $CONF
- rm -rf $GANESHA_DIR/exports/export.$VOL.conf
-
}
if [ "$OPTION" = "on" ];
@@ -101,4 +68,3 @@ if [ "$OPTION" = "off" ];
then
dynamic_export_remove $@
fi
-
diff --git a/extras/ganesha/scripts/ganesha-ha.sh b/extras/ganesha/scripts/ganesha-ha.sh
index 9c82c091304..9790a719e10 100644
--- a/extras/ganesha/scripts/ganesha-ha.sh
+++ b/extras/ganesha/scripts/ganesha-ha.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright 2015 Red Hat Inc. All Rights Reserved
+# Copyright 2015-2016 Red Hat Inc. All Rights Reserved
#
# Pacemaker+Corosync High Availability for NFS-Ganesha
#
@@ -20,18 +20,42 @@
# ensure that the NFS GRACE DBUS signal is sent after the VIP moves to
# the new host.
+GANESHA_HA_SH=$(realpath $0)
HA_NUM_SERVERS=0
HA_SERVERS=""
-HA_CONFDIR="/etc/ganesha"
HA_VOL_NAME="gluster_shared_storage"
-HA_VOL_MNT="/var/run/gluster/shared_storage"
+HA_VOL_MNT="/run/gluster/shared_storage"
+HA_CONFDIR=$HA_VOL_MNT"/nfs-ganesha"
SERVICE_MAN="DISTRO_NOT_FOUND"
-RHEL6_PCS_CNAME_OPTION="--name"
+# rhel, fedora id, version
+ID=""
+VERSION_ID=""
+
+PCS9OR10_PCS_CNAME_OPTION=""
+PCS9OR10_PCS_CLONE_OPTION="clone"
SECRET_PEM="/var/lib/glusterd/nfs/secret.pem"
+# UNBLOCK RA uses shared_storage which may become unavailable
+# during any of the nodes reboot. Hence increase timeout value.
+PORTBLOCK_UNBLOCK_TIMEOUT="60s"
+
+# Try loading the config from any of the distro
+# specific configuration locations
+if [ -f /etc/sysconfig/ganesha ]
+ then
+ . /etc/sysconfig/ganesha
+fi
+if [ -f /etc/conf.d/ganesha ]
+ then
+ . /etc/conf.d/ganesha
+fi
+if [ -f /etc/default/ganesha ]
+ then
+ . /etc/default/ganesha
+fi
+
GANESHA_CONF=
-CONFFILE=
function find_rhel7_conf
{
@@ -50,14 +74,9 @@ function find_rhel7_conf
done
}
-cfgline=$(grep ^CONFFILE= /etc/sysconfig/ganesha)
-eval $(echo ${cfgline} | grep -F ^CONFFILE=)
-
-if [ -z $CONFFILE ]
+if [ -z ${CONFFILE} ]
then
- cfgline=$(grep ^OPTIONS= /etc/sysconfig/ganesha)
- eval $(echo ${cfgline} | grep -F ^OPTIONS=)
- find_rhel7_conf $cfgline
+ find_rhel7_conf ${OPTIONS}
fi
@@ -65,20 +84,21 @@ GANESHA_CONF=${CONFFILE:-/etc/ganesha/ganesha.conf}
usage() {
- echo "Usage : add|delete|status"
- echo "Add-node : ganesha-ha.sh --add <HA_CONF_DIR> \
+ echo "Usage : add|delete|refresh-config|status"
+ echo "Add-node : ganesha-ha.sh --add <HA_CONF_DIR> \
<NODE-HOSTNAME> <NODE-VIP>"
- echo "Delete-node: ganesha-ha.sh --delete <HA_CONF_DIR> \
+ echo "Delete-node: ganesha-ha.sh --delete <HA_CONF_DIR> \
<NODE-HOSTNAME>"
- echo "Refresh-config : ganesha-ha.sh --refresh-config <HA_CONFDIR>\
- <volume>"
+ echo "Refresh-config : ganesha-ha.sh --refresh-config <HA_CONFDIR> \
+<volume>"
+ echo "Status : ganesha-ha.sh --status <HA_CONFDIR>"
}
determine_service_manager () {
- if [ -e "/usr/bin/systemctl" ];
+ if [ -e "/bin/systemctl" ];
then
- SERVICE_MAN="/usr/bin/systemctl"
+ SERVICE_MAN="/bin/systemctl"
elif [ -e "/sbin/invoke-rc.d" ];
then
SERVICE_MAN="/sbin/invoke-rc.d"
@@ -86,9 +106,9 @@ determine_service_manager () {
then
SERVICE_MAN="/sbin/service"
fi
- if [ "$SERVICE_MAN" == "DISTRO_NOT_FOUND" ]
+ if [[ "${SERVICE_MAN}X" == "DISTRO_NOT_FOUNDX" ]]
then
- echo "Service manager not recognized, exiting"
+ logger "Service manager not recognized, exiting"
exit 1
fi
}
@@ -97,16 +117,27 @@ manage_service ()
{
local action=${1}
local new_node=${2}
- if [ "$SERVICE_MAN" == "/usr/sbin/systemctl" ]
+ local option=
+
+ if [[ "${action}" == "start" ]]; then
+ option="yes"
+ else
+ option="no"
+ fi
+ ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
+${SECRET_PEM} root@${new_node} "${GANESHA_HA_SH} --setup-ganesha-conf-files $HA_CONFDIR $option"
+
+ if [[ "${SERVICE_MAN}" == "/bin/systemctl" ]]
then
ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} root@${new_node} "$SERVICE_MAN ${action} nfs-ganesha"
+${SECRET_PEM} root@${new_node} "${SERVICE_MAN} ${action} nfs-ganesha"
else
ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} root@${new_node} "$SERVICE_MAN nfs-ganesha ${action}"
+${SECRET_PEM} root@${new_node} "${SERVICE_MAN} nfs-ganesha ${action}"
fi
}
+
check_cluster_exists()
{
local name=${1}
@@ -114,7 +145,7 @@ check_cluster_exists()
if [ -e /var/run/corosync.pid ]; then
cluster_name=$(pcs status | grep "Cluster name:" | cut -d ' ' -f 3)
- if [ ${cluster_name} -a ${cluster_name} = ${name} ]; then
+ if [[ "${cluster_name}X" == "${name}X" ]]; then
logger "$name already exists, exiting"
exit 0
fi
@@ -129,7 +160,7 @@ determine_servers()
local tmp_ifs=${IFS}
local ha_servers=""
- if [[ "X${cmd}X" != "XsetupX" ]]; then
+ if [ "${cmd}X" != "setupX" -a "${cmd}X" != "statusX" ]; then
ha_servers=$(pcs status | grep "Online:" | grep -o '\[.*\]' | sed -e 's/\[//' | sed -e 's/\]//')
IFS=$' '
for server in ${ha_servers} ; do
@@ -149,6 +180,13 @@ determine_servers()
fi
}
+stop_ganesha_all()
+{
+ local serverlist=${1}
+ for node in ${serverlist} ; do
+ manage_service "stop" ${node}
+ done
+}
setup_cluster()
{
@@ -156,37 +194,54 @@ setup_cluster()
local num_servers=${2}
local servers=${3}
local unclean=""
+ local quorum_policy="stop"
logger "setting up cluster ${name} with the following ${servers}"
- pcs cluster auth ${servers}
-# fedora pcs cluster setup ${name} ${servers}
-# rhel6 pcs cluster setup --name ${name} ${servers}
- pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} ${servers}
+ # pcs cluster setup --force ${PCS9OR10_PCS_CNAME_OPTION} ${name} ${servers}
+ pcs cluster setup --force ${PCS9OR10_PCS_CNAME_OPTION} ${name} --enable ${servers}
if [ $? -ne 0 ]; then
- logger "pcs cluster setup ${RHEL6_PCS_CNAME_OPTION} ${name} ${servers} failed"
+ logger "pcs cluster setup ${PCS9OR10_PCS_CNAME_OPTION} ${name} --enable ${servers} failed, shutting down ganesha and bailing out"
+ #set up failed stop all ganesha process and clean up symlinks in cluster
+ stop_ganesha_all "${servers}"
exit 1;
fi
+
+ # pcs cluster auth ${servers}
+ pcs cluster auth
+ if [ $? -ne 0 ]; then
+ logger "pcs cluster auth failed"
+ fi
+
pcs cluster start --all
if [ $? -ne 0 ]; then
logger "pcs cluster start failed"
exit 1;
fi
- sleep 3
+ sleep 1
+ # wait for the cluster to elect a DC before querying or writing
+ # to the CIB. BZ 1334092
+ crmadmin --dc_lookup --timeout=5000 > /dev/null 2>&1
+ while [ $? -ne 0 ]; do
+ crmadmin --dc_lookup --timeout=5000 > /dev/null 2>&1
+ done
+
unclean=$(pcs status | grep -u "UNCLEAN")
- while [[ "${unclean}X" = "UNCLEANX" ]]; do
+ while [[ "${unclean}X" == "UNCLEANX" ]]; do
sleep 1
unclean=$(pcs status | grep -u "UNCLEAN")
done
sleep 1
if [ ${num_servers} -lt 3 ]; then
- pcs property set no-quorum-policy=ignore
- if [ $? -ne 0 ]; then
- logger "warning: pcs property set no-quorum-policy=ignore failed"
- fi
+ quorum_policy="ignore"
+ fi
+ pcs property set no-quorum-policy=${quorum_policy}
+ if [ $? -ne 0 ]; then
+ logger "warning: pcs property set no-quorum-policy=${quorum_policy} failed"
fi
+
pcs property set stonith-enabled=false
if [ $? -ne 0 ]; then
logger "warning: pcs property set stonith-enabled=false failed"
@@ -194,110 +249,68 @@ setup_cluster()
}
-setup_finalize()
+setup_finalize_ha()
{
local cibfile=${1}
local stopped=""
stopped=$(pcs status | grep -u "Stopped")
- while [[ "${stopped}X" = "StoppedX" ]]; do
+ while [[ "${stopped}X" == "StoppedX" ]]; do
sleep 1
stopped=$(pcs status | grep -u "Stopped")
done
-
- pcs status | grep dead_ip-1 | sort > /var/run/ganesha/pcs_status
-
}
-setup_copy_config()
-{
- local short_host=$(hostname -s)
- local tganesha_conf=$(mktemp -u)
-
- if [ -e ${SECRET_PEM} ]; then
- while [[ ${1} ]]; do
- current_host=`echo ${1} | cut -d "." -f 1`
- if [ ${short_host} != ${current_host} ]; then
- scp -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} ${HA_CONFDIR}/ganesha-ha.conf ${1}:${HA_CONFDIR}/
- if [ $? -ne 0 ]; then
- logger "warning: scp ganesha-ha.conf to ${1} failed"
- fi
- fi
- shift
- done
- else
- logger "warning: scp ganesha-ha.conf to ${1} failed"
- fi
-}
-
refresh_config ()
{
local short_host=$(hostname -s)
local VOL=${1}
local HA_CONFDIR=${2}
+ local short_host=$(hostname -s)
+
+ local export_id=$(grep ^[[:space:]]*Export_Id $HA_CONFDIR/exports/export.$VOL.conf |\
+ awk -F"[=,;]" '{print $2}' | tr -d '[[:space:]]')
- removed_id=`cat $HA_CONFDIR/exports/export.$VOL.conf |\
-grep Export_Id | cut -d " " -f8`
if [ -e ${SECRET_PEM} ]; then
while [[ ${3} ]]; do
current_host=`echo ${3} | cut -d "." -f 1`
- if [ ${short_host} != ${current_host} ]; then
- scp -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} ${HA_CONFDIR}/exports/export.$VOL.conf \
-${current_host}:${HA_CONFDIR}/exports/
- ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} root@${current_host} "dbus-send --print-reply --system \
---dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \
-org.ganesha.nfsd.exportmgr.RemoveExport uint16:$removed_id"
- sleep 1
- ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} root@${current_host} "dbus-send --system \
---dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \
-org.ganesha.nfsd.exportmgr.AddExport string:$HA_CONFDIR/exports/export.$VOL.conf \
-string:\"EXPORT(Path=/$VOL)\""
- if [ $? -ne 0 ]; then
- echo "warning: refresh-config failed on ${current_host}"
- fi
- fi
- shift
+ if [[ ${short_host} != ${current_host} ]]; then
+ output=$(ssh -oPasswordAuthentication=no \
+-oStrictHostKeyChecking=no -i ${SECRET_PEM} root@${current_host} \
+"dbus-send --print-reply --system --dest=org.ganesha.nfsd \
+/org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.UpdateExport \
+string:$HA_CONFDIR/exports/export.$VOL.conf \
+string:\"EXPORT(Export_Id=$export_id)\" 2>&1")
+ ret=$?
+ logger <<< "${output}"
+ if [ ${ret} -ne 0 ]; then
+ echo "Refresh-config failed on ${current_host}. Please check logs on ${current_host}"
+ else
+ echo "Refresh-config completed on ${current_host}."
+ fi
+
+ fi
+ shift
done
else
- echo "warning: refresh-config failed on ${1}"
- fi
-
-#Run the same command on the localhost,
- dbus-send --print-reply --system \
---dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \
-org.ganesha.nfsd.exportmgr.RemoveExport uint16:$removed_id
- sleep 1
- dbus-send --system \
---dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \
-org.ganesha.nfsd.exportmgr.AddExport string:$HA_CONFDIR/exports/export.$VOL.conf \
-string:"EXPORT(Path=/$VOL)"
-}
+ echo "Error: refresh-config failed. Passwordless ssh is not enabled."
+ exit 1
+ fi
-copy_export_config ()
-{
- local new_node=${1}
- local tganesha_conf=$(mktemp)
- local tganesha_exports=$(mktemp -d)
- local short_host=$(hostname -s)
- # avoid prompting for password, even with password-less scp
- # scp $host1:$file $host2:$file prompts for the password
- scp -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} ${HA_VOL_SERVER}:${GANESHA_CONF} $short_host:${tganesha_conf}
- scp -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} ${tganesha_conf} ${new_node}:${GANESHA_CONF}
- rm -f ${tganesha_conf}
-
- scp -r -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} ${HA_VOL_SERVER}:${HA_CONFDIR}/exports/ $short_host:${tganesha_exports}
- scp -r -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
-${SECRET_PEM} ${tganesha_exports}/exports ${new_node}:${HA_CONFDIR}/
- rm -rf ${tganesha_exports}
+ # Run the same command on the localhost,
+ output=$(dbus-send --print-reply --system --dest=org.ganesha.nfsd \
+/org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.UpdateExport \
+string:$HA_CONFDIR/exports/export.$VOL.conf \
+string:"EXPORT(Export_Id=$export_id)" 2>&1)
+ ret=$?
+ logger <<< "${output}"
+ if [ ${ret} -ne 0 ] ; then
+ echo "Refresh-config failed on localhost."
+ else
+ echo "Success: refresh-config completed."
+ fi
}
@@ -309,7 +322,7 @@ teardown_cluster()
if [[ ${HA_CLUSTER_NODES} != *${server}* ]]; then
logger "info: ${server} is not in config, removing"
- pcs cluster stop ${server}
+ pcs cluster stop ${server} --force
if [ $? -ne 0 ]; then
logger "warning: pcs cluster stop ${server} failed"
fi
@@ -321,13 +334,13 @@ teardown_cluster()
fi
done
-# BZ 1193433 - pcs doesn't reload cluster.conf after modification
-# after teardown completes, a subsequent setup will appear to have
-# 'remembered' the deleted node. You can work around this by
-# issuing another `pcs cluster node remove $node`,
-# `crm_node -f -R $server`, or
-# `cibadmin --delete --xml-text '<node id="$server"
-# uname="$server"/>'
+ # BZ 1193433 - pcs doesn't reload cluster.conf after modification
+ # after teardown completes, a subsequent setup will appear to have
+ # 'remembered' the deleted node. You can work around this by
+ # issuing another `pcs cluster node remove $node`,
+ # `crm_node -f -R $server`, or
+ # `cibadmin --delete --xml-text '<node id="$server"
+ # uname="$server"/>'
pcs cluster stop --all
if [ $? -ne 0 ]; then
@@ -344,11 +357,10 @@ teardown_cluster()
cleanup_ganesha_config ()
{
- rm -rf ${HA_CONFDIR}/exports/*.conf
- rm -rf ${HA_CONFDIR}/.export_added
- rm -rf /etc/cluster/cluster.conf*
- rm -rf /var/lib/pacemaker/cib/*
- sed -r -i -e '/^%include[[:space:]]+".+\.conf"$/d' ${GANESHA_CONF}
+ rm -f /etc/corosync/corosync.conf
+ rm -rf /etc/cluster/cluster.conf*
+ rm -rf /var/lib/pacemaker/cib/*
+ sed -r -i -e '/^%include[[:space:]]+".+\.conf"$/d' $HA_CONFDIR/ganesha.conf
}
do_create_virt_ip_constraints()
@@ -359,17 +371,17 @@ do_create_virt_ip_constraints()
# first a constraint location rule that says the VIP must be where
# there's a ganesha.nfsd running
- pcs -f ${cibfile} constraint location ${primary}-cluster_ip-1 rule score=-INFINITY ganesha-active ne 1
+ pcs -f ${cibfile} constraint location ${primary}-group rule score=-INFINITY ganesha-active ne 1
if [ $? -ne 0 ]; then
- logger "warning: pcs constraint location ${primary}-cluster_ip-1 rule score=-INFINITY ganesha-active ne 1 failed"
+ logger "warning: pcs constraint location ${primary}-group rule score=-INFINITY ganesha-active ne 1 failed"
fi
# then a set of constraint location prefers to set the prefered order
# for where a VIP should move
while [[ ${1} ]]; do
- pcs -f ${cibfile} constraint location ${primary}-cluster_ip-1 prefers ${1}=${weight}
+ pcs -f ${cibfile} constraint location ${primary}-group prefers ${1}=${weight}
if [ $? -ne 0 ]; then
- logger "warning: pcs constraint location ${primary}-cluster_ip-1 prefers ${1}=${weight} failed"
+ logger "warning: pcs constraint location ${primary}-group prefers ${1}=${weight} failed"
fi
weight=$(expr ${weight} + 1000)
shift
@@ -379,9 +391,9 @@ do_create_virt_ip_constraints()
# on Fedora setting appears to be additive, so to get the desired
# value we adjust the weight
# weight=$(expr ${weight} - 100)
- pcs -f ${cibfile} constraint location ${primary}-cluster_ip-1 prefers ${primary}=${weight}
+ pcs -f ${cibfile} constraint location ${primary}-group prefers ${primary}=${weight}
if [ $? -ne 0 ]; then
- logger "warning: pcs constraint location ${primary}-cluster_ip-1 prefers ${primary}=${weight} failed"
+ logger "warning: pcs constraint location ${primary}-group prefers ${primary}=${weight} failed"
fi
}
@@ -397,7 +409,7 @@ wrap_create_virt_ip_constraints()
# the result is "node2 node3 node4"; for node2, "node3 node4 node1"
# and so on.
while [[ ${1} ]]; do
- if [ "${1}" = "${primary}" ]; then
+ if [[ ${1} == ${primary} ]]; then
shift
while [[ ${1} ]]; do
tail=${tail}" "${1}
@@ -427,28 +439,31 @@ setup_create_resources()
{
local cibfile=$(mktemp -u)
- # mount the HA-state volume and start ganesha.nfsd on all nodes
- pcs resource create nfs_start ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone
+ # fixup /var/lib/nfs
+ logger "pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} ${PCS9OR10_PCS_CLONE_OPTION}"
+ pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} ${PCS9OR10_PCS_CLONE_OPTION}
if [ $? -ne 0 ]; then
- logger "warning: pcs resource create nfs_start ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone failed"
+ logger "warning: pcs resource create nfs_setup ocf:heartbeat:ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} ${PCS9OR10_PCS_CLONE_OPTION} failed"
fi
- sleep 1
- # cloned resources seem to never have their start() invoked when they
- # are created, but stop() is invoked when they are destroyed. Why???.
- # No matter, we don't want this resource agent hanging around anyway
- pcs resource delete nfs_start-clone
+
+ pcs resource create nfs-mon ocf:heartbeat:ganesha_mon ${PCS9OR10_PCS_CLONE_OPTION}
if [ $? -ne 0 ]; then
- logger "warning: pcs resource delete nfs_start-clone failed"
+ logger "warning: pcs resource create nfs-mon ocf:heartbeat:ganesha_mon ${PCS9OR10_PCS_CLONE_OPTION} failed"
fi
- pcs resource create nfs-mon ganesha_mon --clone
+ # see comment in (/usr/lib/ocf/resource.d/heartbeat/ganesha_grace
+ # start method. Allow time for ganesha_mon to start and set the
+ # ganesha-active crm_attribute
+ sleep 5
+
+ pcs resource create nfs-grace ocf:heartbeat:ganesha_grace ${PCS9OR10_PCS_CLONE_OPTION} notify=true
if [ $? -ne 0 ]; then
- logger "warning: pcs resource create nfs-mon ganesha_mon --clone failed"
+ logger "warning: pcs resource create nfs-grace ocf:heartbeat:ganesha_grace ${PCS9OR10_PCS_CLONE_OPTION} failed"
fi
- pcs resource create nfs-grace ganesha_grace --clone
+ pcs constraint location nfs-grace-clone rule score=-INFINITY grace-active ne 1
if [ $? -ne 0 ]; then
- logger "warning: pcs resource create nfs-grace ganesha_grace --clone failed"
+ logger "warning: pcs constraint location nfs-grace-clone rule score=-INFINITY grace-active ne 1"
fi
pcs cluster cib ${cibfile}
@@ -473,30 +488,32 @@ setup_create_resources()
eval tmp_ipaddr=\$${clean_name}
ipaddr=${tmp_ipaddr//_/.}
- pcs -f ${cibfile} resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} cidr_netmask=32 op monitor interval=15s
+ pcs -f ${cibfile} resource create ${1}-nfs_block ocf:heartbeat:portblock protocol=tcp \
+ portno=2049 action=block ip=${ipaddr} --group ${1}-group
if [ $? -ne 0 ]; then
- logger "warning pcs resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} cidr_netmask=32 op monitor interval=15s failed"
+ logger "warning pcs resource create ${1}-nfs_block failed"
fi
-
- pcs -f ${cibfile} resource create ${1}-trigger_ip-1 ocf:heartbeat:Dummy
+ pcs -f ${cibfile} resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} \
+ cidr_netmask=32 op monitor interval=15s --group ${1}-group --after ${1}-nfs_block
if [ $? -ne 0 ]; then
- logger "warning: pcs resource create ${1}-trigger_ip-1 ocf:heartbeat:Dummy failed"
+ logger "warning pcs resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} \
+ cidr_netmask=32 op monitor interval=15s failed"
fi
- pcs -f ${cibfile} constraint colocation add ${1}-cluster_ip-1 with ${1}-trigger_ip-1
+ pcs -f ${cibfile} constraint order nfs-grace-clone then ${1}-cluster_ip-1
if [ $? -ne 0 ]; then
- logger "warning: pcs constraint colocation add ${1}-cluster_ip-1 with ${1}-trigger_ip-1 failed"
+ logger "warning: pcs constraint order nfs-grace-clone then ${1}-cluster_ip-1 failed"
fi
- pcs -f ${cibfile} constraint order ${1}-trigger_ip-1 then nfs-grace-clone
+ pcs -f ${cibfile} resource create ${1}-nfs_unblock ocf:heartbeat:portblock protocol=tcp \
+ portno=2049 action=unblock ip=${ipaddr} reset_local_on_unblock_stop=true \
+ tickle_dir=${HA_VOL_MNT}/nfs-ganesha/tickle_dir/ --group ${1}-group --after ${1}-cluster_ip-1 \
+ op stop timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} op start timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} \
+ op monitor interval=10s timeout=${PORTBLOCK_UNBLOCK_TIMEOUT}
if [ $? -ne 0 ]; then
- logger "warning: pcs constraint order ${1}-trigger_ip-1 then nfs-grace-clone failed"
+ logger "warning pcs resource create ${1}-nfs_unblock failed"
fi
- pcs -f ${cibfile} constraint order nfs-grace-clone then ${1}-cluster_ip-1
- if [ $? -ne 0 ]; then
- logger "warning: pcs constraint order nfs-grace-clone then ${1}-cluster_ip-1 failed"
- fi
shift
done
@@ -515,6 +532,13 @@ teardown_resources()
{
# local mntpt=$(grep ha-vol-mnt ${HA_CONFIG_FILE} | cut -d = -f 2)
+ # restore /var/lib/nfs
+ logger "notice: pcs resource delete nfs_setup-clone"
+ pcs resource delete nfs_setup-clone
+ if [ $? -ne 0 ]; then
+ logger "warning: pcs resource delete nfs_setup-clone failed"
+ fi
+
# delete -clone resource agents
# in particular delete the ganesha monitor so we don't try to
# trigger anything when we shut down ganesha next.
@@ -528,31 +552,10 @@ teardown_resources()
logger "warning: pcs resource delete nfs-grace-clone failed"
fi
- # unmount the HA-state volume and terminate ganesha.nfsd on all nodes
- pcs resource create nfs_stop ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone
- if [ $? -ne 0 ]; then
- logger "warning: pcs resource create nfs_stop ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} --clone failed"
- fi
- sleep 1
- # cloned resources seem to never have their start() invoked when they
- # are created, but stop() is invoked when they are destroyed. Why???.
- pcs resource delete nfs_stop-clone
- if [ $? -ne 0 ]; then
- logger "warning: pcs resource delete nfs_stop-clone failed"
- fi
-
while [[ ${1} ]]; do
- pcs resource delete ${1}-cluster_ip-1
- if [ $? -ne 0 ]; then
- logger "warning: pcs resource delete ${1}-cluster_ip-1 failed"
- fi
- pcs resource delete ${1}-trigger_ip-1
+ pcs resource delete ${1}-group
if [ $? -ne 0 ]; then
- logger "warning: pcs resource delete ${1}-trigger_ip-1 failed"
- fi
- pcs resource delete ${1}-dead_ip-1
- if [ $? -ne 0 ]; then
- logger "info: pcs resource delete ${1}-dead_ip-1 failed"
+ logger "warning: pcs resource delete ${1}-group failed"
fi
shift
done
@@ -575,29 +578,30 @@ recreate_resources()
eval tmp_ipaddr=\$${clean_name}
ipaddr=${tmp_ipaddr//_/.}
- pcs -f ${cibfile} resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} cidr_netmask=32 op monitor interval=15s
+ pcs -f ${cibfile} resource create ${1}-nfs_block ocf:heartbeat:portblock protocol=tcp \
+ portno=2049 action=block ip=${ipaddr} --group ${1}-group
if [ $? -ne 0 ]; then
- logger "warning pcs resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} cidr_netmask=32 op monitor interval=10s failed"
+ logger "warning pcs resource create ${1}-nfs_block failed"
fi
-
- pcs -f ${cibfile} resource create ${1}-trigger_ip-1 ocf:heartbeat:Dummy
+ pcs -f ${cibfile} resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} \
+ cidr_netmask=32 op monitor interval=15s --group ${1}-group --after ${1}-nfs_block
if [ $? -ne 0 ]; then
- logger "warning: pcs resource create ${1}-trigger_ip-1 ocf:heartbeat:Dummy failed"
+ logger "warning pcs resource create ${1}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${ipaddr} \
+ cidr_netmask=32 op monitor interval=15s failed"
fi
- pcs -f ${cibfile} constraint colocation add ${1}-cluster_ip-1 with ${1}-trigger_ip-1
+ pcs -f ${cibfile} constraint order nfs-grace-clone then ${1}-cluster_ip-1
if [ $? -ne 0 ]; then
- logger "warning: pcs constraint colocation add ${1}-cluster_ip-1 with ${1}-trigger_ip-1 failed"
+ logger "warning: pcs constraint order nfs-grace-clone then ${1}-cluster_ip-1 failed"
fi
- pcs -f ${cibfile} constraint order ${1}-trigger_ip-1 then nfs-grace-clone
+ pcs -f ${cibfile} resource create ${1}-nfs_unblock ocf:heartbeat:portblock protocol=tcp \
+ portno=2049 action=unblock ip=${ipaddr} reset_local_on_unblock_stop=true \
+ tickle_dir=${HA_VOL_MNT}/nfs-ganesha/tickle_dir/ --group ${1}-group --after ${1}-cluster_ip-1 \
+ op stop timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} op start timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} \
+ op monitor interval=10s timeout=${PORTBLOCK_UNBLOCK_TIMEOUT}
if [ $? -ne 0 ]; then
- logger "warning: pcs constraint order ${1}-trigger_ip-1 then nfs-grace-clone failed"
- fi
-
- pcs -f ${cibfile} constraint order nfs-grace-clone then ${1}-cluster_ip-1
- if [ $? -ne 0 ]; then
- logger "warning: pcs constraint order nfs-grace-clone then ${1}-cluster_ip-1 failed"
+ logger "warning pcs resource create ${1}-nfs_unblock failed"
fi
shift
@@ -613,30 +617,32 @@ addnode_recreate_resources()
recreate_resources ${cibfile} ${HA_SERVERS}
- pcs -f ${cibfile} resource create ${add_node}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${add_vip} cidr_netmask=32 op monitor interval=15s
- if [ $? -ne 0 ]; then
- logger "warning pcs resource create ${add_node}-cluster_ip-1 ocf:heartbeat:IPaddr ip=${add_vip} cidr_netmask=32 op monitor interval=10s failed"
- fi
-
- pcs -f ${cibfile} resource create ${add_node}-trigger_ip-1 ocf:heartbeat:Dummy
- if [ $? -ne 0 ]; then
- logger "warning: pcs resource create ${add_node}-trigger_ip-1 ocf:heartbeat:Dummy failed"
- fi
-
- pcs -f ${cibfile} constraint colocation add ${add_node}-cluster_ip-1 with ${add_node}-trigger_ip-1
+ pcs -f ${cibfile} resource create ${add_node}-nfs_block ocf:heartbeat:portblock \
+ protocol=tcp portno=2049 action=block ip=${add_vip} --group ${add_node}-group
if [ $? -ne 0 ]; then
- logger "warning: pcs constraint colocation add ${add_node}-cluster_ip-1 with ${add_node}-trigger_ip-1 failed"
+ logger "warning pcs resource create ${add_node}-nfs_block failed"
fi
-
- pcs -f ${cibfile} constraint order ${add_node}-trigger_ip-1 then nfs-grace-clone
+ pcs -f ${cibfile} resource create ${add_node}-cluster_ip-1 ocf:heartbeat:IPaddr \
+ ip=${add_vip} cidr_netmask=32 op monitor interval=15s --group ${add_node}-group \
+ --after ${add_node}-nfs_block
if [ $? -ne 0 ]; then
- logger "warning: pcs constraint order ${add_node}-trigger_ip-1 then nfs-grace-clone failed"
+ logger "warning pcs resource create ${add_node}-cluster_ip-1 ocf:heartbeat:IPaddr \
+ ip=${add_vip} cidr_netmask=32 op monitor interval=15s failed"
fi
pcs -f ${cibfile} constraint order nfs-grace-clone then ${add_node}-cluster_ip-1
if [ $? -ne 0 ]; then
logger "warning: pcs constraint order nfs-grace-clone then ${add_node}-cluster_ip-1 failed"
fi
+ pcs -f ${cibfile} resource create ${add_node}-nfs_unblock ocf:heartbeat:portblock \
+ protocol=tcp portno=2049 action=unblock ip=${add_vip} reset_local_on_unblock_stop=true \
+ tickle_dir=${HA_VOL_MNT}/nfs-ganesha/tickle_dir/ --group ${add_node}-group --after \
+ ${add_node}-cluster_ip-1 op stop timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} op start \
+ timeout=${PORTBLOCK_UNBLOCK_TIMEOUT} op monitor interval=10s \
+ timeout=${PORTBLOCK_UNBLOCK_TIMEOUT}
+ if [ $? -ne 0 ]; then
+ logger "warning pcs resource create ${add_node}-nfs_unblock failed"
+ fi
}
@@ -645,14 +651,9 @@ clear_resources()
local cibfile=${1}; shift
while [[ ${1} ]]; do
- pcs -f ${cibfile} resource delete ${1}-cluster_ip-1
- if [ $? -ne 0 ]; then
- logger "warning: pcs -f ${cibfile} resource delete ${1}-cluster_ip-1"
- fi
-
- pcs -f ${cibfile} resource delete ${1}-trigger_ip-1
+ pcs -f ${cibfile} resource delete ${1}-group
if [ $? -ne 0 ]; then
- logger "warning: pcs -f ${cibfile} resource delete ${1}-trigger_ip-1"
+ logger "warning: pcs -f ${cibfile} resource delete ${1}-group"
fi
shift
@@ -666,52 +667,19 @@ addnode_create_resources()
local add_vip=${1}; shift
local cibfile=$(mktemp -u)
- # mount the HA-state volume and start ganesha.nfsd on the new node
- pcs cluster cib ${cibfile}
- if [ $? -ne 0 ]; then
- logger "warning: pcs cluster cib ${cibfile} failed"
- fi
-
- pcs -f ${cibfile} resource create nfs_start-${add_node} ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT}
- if [ $? -ne 0 ]; then
- logger "warning: pcs -f ${cibfile} resource create nfs_start-${add_node} ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} failed"
- fi
-
- pcs -f ${cibfile} constraint location nfs_start-${add_node} prefers ${add_node}=INFINITY
- if [ $? -ne 0 ]; then
- logger "warning: pcs -f ${cibfile} constraint location nfs_start-${add_node} prefers ${add_node}=INFINITY failed"
- fi
-
- pcs -f ${cibfile} constraint order nfs_start-${add_node} then nfs-mon-clone
- if [ $? -ne 0 ]; then
- logger "warning: pcs -f ${cibfile} constraint order nfs_start-${add_node} then nfs-mon-clone failed"
- fi
-
- pcs cluster cib-push ${cibfile}
- if [ $? -ne 0 ]; then
- logger "warning: pcs cluster cib-push ${cibfile} failed"
- fi
- rm -f ${cibfile}
-
# start HA on the new node
pcs cluster start ${add_node}
if [ $? -ne 0 ]; then
logger "warning: pcs cluster start ${add_node} failed"
fi
- pcs resource delete nfs_start-${add_node}
- if [ $? -ne 0 ]; then
- logger "warning: pcs resource delete nfs_start-${add_node} failed"
- fi
-
-
pcs cluster cib ${cibfile}
if [ $? -ne 0 ]; then
logger "warning: pcs cluster cib ${cibfile} failed"
fi
- # delete all the -cluster_ip-1 and -trigger_ip-1 resources,
- # clearing their constraints, then create them again so we can
+ # delete all the -cluster_ip-1 resources, clearing
+ # their constraints, then create them again so we can
# recompute their constraints
clear_resources ${cibfile} ${HA_SERVERS}
addnode_recreate_resources ${cibfile} ${add_node} ${add_vip}
@@ -753,31 +721,16 @@ deletenode_delete_resources()
fi
rm -f ${cibfile}
- pcs cluster cib ${cibfile}
- if [ $? -ne 0 ]; then
- logger "warning: pcs cluster cib ${cibfile} failed"
- fi
+}
- pcs -f ${cibfile} resource create nfs_stop-${node} ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT}
- if [ $? -ne 0 ]; then
- logger "warning: pcs -f ${cibfile} resource create nfs_stop-${node} ganesha_nfsd ha_vol_mnt=${HA_VOL_MNT} failed"
- fi
- pcs -f ${cibfile} constraint location nfs_stop-${node} prefers ${node}=INFINITY
- if [ $? -ne 0 ]; then
- logger "warning: pcs -f ${cibfile} constraint location nfs_stop-${node} prefers ${node}=INFINITY failed"
- fi
-
- pcs cluster cib-push ${cibfile}
- if [ $? -ne 0 ]; then
- logger "warning: pcs cluster cib-push ${cibfile} failed"
- fi
- rm -f ${cibfile}
+deletenode_update_haconfig()
+{
+ local name="VIP_${1}"
+ local clean_name=${name//[-.]/_}
- pcs resource delete nfs_stop-${node}
- if [ $? -ne 0 ]; then
- logger "warning: pcs resource delete nfs_stop-${node} failed"
- fi
+ ha_servers=$(echo ${HA_SERVERS} | sed -e "s/ /,/")
+ sed -i -e "s/^HA_CLUSTER_NODES=.*$/HA_CLUSTER_NODES=\"${ha_servers// /,}\"/" -e "s/^${name}=.*$//" -e "/^$/d" ${HA_CONFDIR}/ganesha-ha.conf
}
@@ -800,7 +753,9 @@ setup_state_volume()
dirname=${1}${dname}
fi
-
+ if [ ! -d ${mnt}/nfs-ganesha/tickle_dir ]; then
+ mkdir ${mnt}/nfs-ganesha/tickle_dir
+ fi
if [ ! -d ${mnt}/nfs-ganesha/${dirname} ]; then
mkdir ${mnt}/nfs-ganesha/${dirname}
fi
@@ -812,9 +767,11 @@ setup_state_volume()
fi
if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd ]; then
mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd
+ chown rpcuser:rpcuser ${mnt}/nfs-ganesha/${dirname}/nfs/statd
fi
if [ ! -e ${mnt}/nfs-ganesha/${dirname}/nfs/state ]; then
touch ${mnt}/nfs-ganesha/${dirname}/nfs/state
+ chown rpcuser:rpcuser ${mnt}/nfs-ganesha/${dirname}/nfs/state
fi
if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4recov ]; then
mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4recov
@@ -824,15 +781,17 @@ setup_state_volume()
fi
if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm ]; then
mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm
+ chown rpcuser:rpcuser ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm
fi
if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak ]; then
mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak
+ chown rpcuser:rpcuser ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak
fi
if [ ! -e ${mnt}/nfs-ganesha/${dirname}/nfs/statd/state ]; then
touch ${mnt}/nfs-ganesha/${dirname}/nfs/statd/state
fi
for server in ${HA_SERVERS} ; do
- if [ ${server} != ${dirname} ]; then
+ if [[ ${server} != ${dirname} ]]; then
ln -s ${mnt}/nfs-ganesha/${server}/nfs/ganesha ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/${server}
ln -s ${mnt}/nfs-ganesha/${server}/nfs/statd ${mnt}/nfs-ganesha/${dirname}/nfs/statd/${server}
fi
@@ -843,6 +802,214 @@ setup_state_volume()
}
+enable_pacemaker()
+{
+ while [[ ${1} ]]; do
+ if [[ "${SERVICE_MAN}" == "/bin/systemctl" ]]; then
+ ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
+${SECRET_PEM} root@${1} "${SERVICE_MAN} enable pacemaker"
+ else
+ ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i \
+${SECRET_PEM} root@${1} "${SERVICE_MAN} pacemaker enable"
+ fi
+ shift
+ done
+}
+
+
+addnode_state_volume()
+{
+ local newnode=${1}; shift
+ local mnt=${HA_VOL_MNT}
+ local longname=""
+ local dname=""
+ local dirname=""
+
+ longname=$(hostname)
+ dname=${longname#$(hostname -s)}
+
+ if [[ ${newnode} == *${dname} ]]; then
+ dirname=${newnode}
+ else
+ dirname=${newnode}${dname}
+ fi
+
+ if [ ! -d ${mnt}/nfs-ganesha/${dirname} ]; then
+ mkdir ${mnt}/nfs-ganesha/${dirname}
+ fi
+ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs ]; then
+ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs
+ fi
+ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha ]; then
+ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha
+ fi
+ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd ]; then
+ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd
+ chown rpcuser:rpcuser ${mnt}/nfs-ganesha/${dirname}/nfs/statd
+ fi
+ if [ ! -e ${mnt}/nfs-ganesha/${dirname}/nfs/state ]; then
+ touch ${mnt}/nfs-ganesha/${dirname}/nfs/state
+ chown rpcuser:rpcuser ${mnt}/nfs-ganesha/${dirname}/nfs/state
+ fi
+ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4recov ]; then
+ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4recov
+ fi
+ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4old ]; then
+ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/v4old
+ fi
+ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm ]; then
+ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm
+ chown rpcuser:rpcuser ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm
+ fi
+ if [ ! -d ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak ]; then
+ mkdir ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak
+ chown rpcuser:rpcuser ${mnt}/nfs-ganesha/${dirname}/nfs/statd/sm.bak
+ fi
+ if [ ! -e ${mnt}/nfs-ganesha/${dirname}/nfs/statd/state ]; then
+ touch ${mnt}/nfs-ganesha/${dirname}/nfs/statd/state
+ fi
+
+ for server in ${HA_SERVERS} ; do
+
+ if [[ ${server} != ${dirname} ]]; then
+ ln -s ${mnt}/nfs-ganesha/${server}/nfs/ganesha ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha/${server}
+ ln -s ${mnt}/nfs-ganesha/${server}/nfs/statd ${mnt}/nfs-ganesha/${dirname}/nfs/statd/${server}
+
+ ln -s ${mnt}/nfs-ganesha/${dirname}/nfs/ganesha ${mnt}/nfs-ganesha/${server}/nfs/ganesha/${dirname}
+ ln -s ${mnt}/nfs-ganesha/${dirname}/nfs/statd ${mnt}/nfs-ganesha/${server}/nfs/statd/${dirname}
+ fi
+ done
+
+}
+
+
+delnode_state_volume()
+{
+ local delnode=${1}; shift
+ local mnt=${HA_VOL_MNT}
+ local longname=""
+ local dname=""
+ local dirname=""
+
+ longname=$(hostname)
+ dname=${longname#$(hostname -s)}
+
+ if [[ ${delnode} == *${dname} ]]; then
+ dirname=${delnode}
+ else
+ dirname=${delnode}${dname}
+ fi
+
+ rm -rf ${mnt}/nfs-ganesha/${dirname}
+
+ for server in ${HA_SERVERS} ; do
+ if [[ ${server} != ${dirname} ]]; then
+ rm -f ${mnt}/nfs-ganesha/${server}/nfs/ganesha/${dirname}
+ rm -f ${mnt}/nfs-ganesha/${server}/nfs/statd/${dirname}
+ fi
+ done
+}
+
+
+status()
+{
+ local scratch=$(mktemp)
+ local regex_str="^${1}-cluster_ip-1"
+ local healthy=0
+ local index=1
+ local nodes
+
+ # change tabs to spaces, strip leading spaces, including any
+ # new '*' at the beginning of a line introduced in pcs-0.10.x
+ pcs status | sed -e "s/\t/ /g" -e "s/^[ ]*\*//" -e "s/^[ ]*//" > ${scratch}
+
+ nodes[0]=${1}; shift
+
+ # make a regex of the configured nodes
+ # and initalize the nodes array for later
+ while [[ ${1} ]]; do
+
+ regex_str="${regex_str}|^${1}-cluster_ip-1"
+ nodes[${index}]=${1}
+ ((index++))
+ shift
+ done
+
+ # print the nodes that are expected to be online
+ grep -E "Online:" ${scratch}
+
+ echo
+
+ # print the VIPs and which node they are on
+ grep -E "${regex_str}" < ${scratch} | cut -d ' ' -f 1,4
+
+ echo
+
+ # check if the VIP and port block/unblock RAs are on the expected nodes
+ for n in ${nodes[*]}; do
+
+ grep -E -x "${n}-nfs_block \(ocf::heartbeat:portblock\): Started ${n}" > /dev/null 2>&1 ${scratch}
+ result=$?
+ ((healthy+=${result}))
+ grep -E -x "${n}-cluster_ip-1 \(ocf::heartbeat:IPaddr\): Started ${n}" > /dev/null 2>&1 ${scratch}
+ result=$?
+ ((healthy+=${result}))
+ grep -E -x "${n}-nfs_unblock \(ocf::heartbeat:portblock\): Started ${n}" > /dev/null 2>&1 ${scratch}
+ result=$?
+ ((healthy+=${result}))
+ done
+
+ grep -E "\):\ Stopped|FAILED" > /dev/null 2>&1 ${scratch}
+ result=$?
+
+ if [ ${result} -eq 0 ]; then
+ echo "Cluster HA Status: BAD"
+ elif [ ${healthy} -eq 0 ]; then
+ echo "Cluster HA Status: HEALTHY"
+ else
+ echo "Cluster HA Status: FAILOVER"
+ fi
+
+ rm -f ${scratch}
+}
+
+create_ganesha_conf_file()
+{
+ if [[ "$1" == "yes" ]];
+ then
+ if [ -e $GANESHA_CONF ];
+ then
+ rm -rf $GANESHA_CONF
+ fi
+ # The symlink /etc/ganesha/ganesha.conf need to be
+ # created using ganesha conf file mentioned in the
+ # shared storage. Every node will only have this
+ # link and actual file will stored in shared storage,
+ # so that ganesha conf editing of ganesha conf will
+ # be easy as well as it become more consistent.
+
+ ln -s $HA_CONFDIR/ganesha.conf $GANESHA_CONF
+ else
+ # Restoring previous file
+ rm -rf $GANESHA_CONF
+ cp $HA_CONFDIR/ganesha.conf $GANESHA_CONF
+ sed -r -i -e '/^%include[[:space:]]+".+\.conf"$/d' $GANESHA_CONF
+ fi
+}
+
+set_quorum_policy()
+{
+ local quorum_policy="stop"
+ local num_servers=${1}
+
+ if [ ${num_servers} -lt 3 ]; then
+ quorum_policy="ignore"
+ fi
+ pcs property set no-quorum-policy=${quorum_policy}
+ if [ $? -ne 0 ]; then
+ logger "warning: pcs property set no-quorum-policy=${quorum_policy} failed"
+ fi
+}
main()
{
@@ -852,27 +1019,29 @@ main()
usage
exit 0
fi
- if [[ ${cmd} != *status ]]; then
- HA_CONFDIR=${1%/}; shift
- local ha_conf=${HA_CONFDIR}/ganesha-ha.conf
- local node=""
- local vip=""
- # ignore any comment lines
- cfgline=$(grep ^HA_NAME= ${ha_conf})
- eval $(echo ${cfgline} | grep -F HA_NAME=)
- cfgline=$(grep ^HA_VOL_SERVER= ${ha_conf})
- eval $(echo ${cfgline} | grep -F HA_VOL_SERVER=)
- cfgline=$(grep ^HA_CLUSTER_NODES= ${ha_conf})
- eval $(echo ${cfgline} | grep -F HA_CLUSTER_NODES=)
-
- # we'll pretend that nobody ever edits /etc/os-release
- if [ -e /etc/os-release ]; then
- eval $(grep -F "REDHAT_SUPPORT_PRODUCT=" /etc/os-release)
- [ "$REDHAT_SUPPORT_PRODUCT" == "Fedora" ] && RHEL6_PCS_CNAME_OPTION=""
- fi
+ if (selinuxenabled) ;then
+ semanage boolean -m gluster_use_execmem --on
fi
+ local osid=""
+
+ osid=$(grep ^ID= /etc/os-release)
+ eval $(echo ${osid} | grep -F ID=)
+ osid=$(grep ^VERSION_ID= /etc/os-release)
+ eval $(echo ${osid} | grep -F VERSION_ID=)
+
+ HA_CONFDIR=${1%/}; shift
+ local ha_conf=${HA_CONFDIR}/ganesha-ha.conf
+ local node=""
+ local vip=""
+
+ # ignore any comment lines
+ cfgline=$(grep ^HA_NAME= ${ha_conf})
+ eval $(echo ${cfgline} | grep -F HA_NAME=)
+ cfgline=$(grep ^HA_CLUSTER_NODES= ${ha_conf})
+ eval $(echo ${cfgline} | grep -F HA_CLUSTER_NODES=)
+
case "${cmd}" in
setup | --setup)
@@ -882,17 +1051,30 @@ main()
determine_servers "setup"
- if [ "X${HA_NUM_SERVERS}X" != "X1X" ]; then
+ # Fedora 29+ and rhel/centos 8 has PCS-0.10.x
+ # default is pcs-0.10.x options but check for
+ # rhel/centos 7 (pcs-0.9.x) and adjust accordingly
+ if [[ ! ${ID} =~ {rhel,centos} ]]; then
+ if [[ ${VERSION_ID} == 7.* ]]; then
+ PCS9OR10_PCS_CNAME_OPTION="--name"
+ PCS9OR10_PCS_CLONE_OPTION="--clone"
+ fi
+ fi
+
+ if [[ "${HA_NUM_SERVERS}X" != "1X" ]]; then
+
+ determine_service_manager
setup_cluster ${HA_NAME} ${HA_NUM_SERVERS} "${HA_SERVERS}"
setup_create_resources ${HA_SERVERS}
+ setup_finalize_ha
+
setup_state_volume ${HA_SERVERS}
- setup_copy_config ${HA_SERVERS}
+ enable_pacemaker ${HA_SERVERS}
- setup_finalize
else
logger "insufficient servers for HA, aborting"
@@ -907,6 +1089,8 @@ main()
teardown_resources ${HA_SERVERS}
teardown_cluster ${HA_NAME}
+
+ cleanup_ganesha_config ${HA_CONFDIR}
;;
cleanup | --cleanup)
@@ -919,8 +1103,6 @@ main()
logger "adding ${node} with ${vip} to ${HA_NAME}"
- copy_export_config ${node} ${HA_CONFDIR}
-
determine_service_manager
manage_service "start" ${node}
@@ -933,20 +1115,26 @@ main()
fi
addnode_create_resources ${node} ${vip}
- #Subsequent add-node recreates resources for all the nodes
- #that already exist in the cluster. The nodes are picked up
- #from the entries in the ganesha-ha.conf file. Adding the
- #newly added node to the file so that the resources specfic
- #to this node is correctly recreated in the future.
- echo "VIP_$node=\"$vip\"" >> ${HA_CONFDIR}/ganesha-ha.conf
+ # Subsequent add-node recreates resources for all the nodes
+ # that already exist in the cluster. The nodes are picked up
+ # from the entries in the ganesha-ha.conf file. Adding the
+ # newly added node to the file so that the resources specfic
+ # to this node is correctly recreated in the future.
+ clean_node=${node//[-.]/_}
+ echo "VIP_${node}=\"${vip}\"" >> ${HA_CONFDIR}/ganesha-ha.conf
- NEW_NODES="$HA_CLUSTER_NODES,$node"
+ NEW_NODES="$HA_CLUSTER_NODES,${node}"
sed -i s/HA_CLUSTER_NODES.*/"HA_CLUSTER_NODES=\"$NEW_NODES\""/ \
$HA_CONFDIR/ganesha-ha.conf
- HA_SERVERS="${HA_SERVERS} ${node}"
- setup_copy_config ${HA_SERVERS}
+ addnode_state_volume ${node}
+
+ # addnode_create_resources() already appended ${node} to
+ # HA_SERVERS, so only need to increment HA_NUM_SERVERS
+ # and set quorum policy
+ HA_NUM_SERVERS=$(expr ${HA_NUM_SERVERS} + 1)
+ set_quorum_policy ${HA_NUM_SERVERS}
;;
delete | --delete)
@@ -963,20 +1151,22 @@ $HA_CONFDIR/ganesha-ha.conf
logger "warning: pcs cluster node remove ${node} failed"
fi
- ha_servers=$(echo ${HA_SERVERS} | sed -e "s/ /,/")
- sed -i "s/^HA_CLUSTER_NODES=.*$/HA_CLUSTER_NODES=\"${ha_servers// /,}\"/" ${HA_CONFDIR}/ganesha-ha.conf
-
- setup_copy_config ${HA_SERVERS}
+ deletenode_update_haconfig ${node}
- rm -rf ${HA_VOL_MNT}/nfs-ganesha/{node}
+ delnode_state_volume ${node}
determine_service_manager
manage_service "stop" ${node}
+
+ HA_NUM_SERVERS=$(expr ${HA_NUM_SERVERS} - 1)
+ set_quorum_policy ${HA_NUM_SERVERS}
;;
status | --status)
- exec pcs status
+ determine_servers "status"
+
+ status ${HA_SERVERS}
;;
refresh-config | --refresh-config)
@@ -987,7 +1177,12 @@ $HA_CONFDIR/ganesha-ha.conf
refresh_config ${VOL} ${HA_CONFDIR} ${HA_SERVERS}
;;
- *)
+ setup-ganesha-conf-files | --setup-ganesha-conf-files)
+
+ create_ganesha_conf_file ${1}
+ ;;
+
+ *)
# setup and teardown are not intended to be used by a
# casual user
usage
@@ -995,7 +1190,10 @@ $HA_CONFDIR/ganesha-ha.conf
;;
esac
+
+ if (selinuxenabled) ;then
+ semanage boolean -m gluster_use_execmem --off
+ fi
}
main $*
-
diff --git a/extras/ganesha/scripts/generate-epoch.py b/extras/ganesha/scripts/generate-epoch.py
new file mode 100755
index 00000000000..77af014bab9
--- /dev/null
+++ b/extras/ganesha/scripts/generate-epoch.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python3
+#
+# Copyright (c) 2016 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.
+#
+# Generates unique epoch value on each gluster node to be used by
+# nfs-ganesha service on that node.
+#
+# Configure 'EPOCH_EXEC' option to this script path in
+# '/etc/sysconfig/ganesha' file used by nfs-ganesha service.
+#
+# Construct epoch as follows -
+# first 32-bit contains the now() time
+# rest 32-bit value contains the local glusterd node uuid
+
+import time
+import binascii
+
+# Calculate the now() time into a 64-bit integer value
+def epoch_now():
+ epoch_time = int(time.mktime(time.localtime())) << 32
+ return epoch_time
+
+# Read glusterd UUID and extract first 32-bit of it
+def epoch_uuid():
+ file_name = '/var/lib/glusterd/glusterd.info'
+
+ for line in open(file_name):
+ if "UUID" in line:
+ glusterd_uuid = line.split('=')[1].strip()
+
+ uuid_bin = binascii.unhexlify(glusterd_uuid.replace("-",""))
+
+ epoch_uuid = int(binascii.hexlify(uuid_bin), 32) & 0xFFFF0000
+ return epoch_uuid
+
+# Construct epoch as follows -
+# first 32-bit contains the now() time
+# rest 32-bit value contains the local glusterd node uuid
+epoch = (epoch_now() | epoch_uuid())
+print((str(epoch)))
+
+exit(0)
diff --git a/extras/geo-rep/Makefile.am b/extras/geo-rep/Makefile.am
index 662a84d4411..09eff308ac4 100644
--- a/extras/geo-rep/Makefile.am
+++ b/extras/geo-rep/Makefile.am
@@ -1,13 +1,16 @@
-scriptsdir = $(datadir)/glusterfs/scripts
+scriptsdir = $(libexecdir)/glusterfs/scripts
scripts_SCRIPTS = gsync-upgrade.sh generate-gfid-file.sh get-gfid.sh \
- slave-upgrade.sh
+ slave-upgrade.sh schedule_georep.py
scripts_PROGRAMS = gsync-sync-gfid
gsync_sync_gfid_CFLAGS = $(GF_CFLAGS) -Wall -I$(top_srcdir)/libglusterfs/src
gsync_sync_gfid_LDFLAGS = $(GF_LDFLAGS)
gsync_sync_gfid_LDADD = $(GF_LDADD) $(top_builddir)/libglusterfs/src/libglusterfs.la
gsync_sync_gfid_SOURCES = gsync-sync-gfid.c
-gsync_sync_gfid_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src
+gsync_sync_gfid_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src
EXTRA_DIST = gsync-sync-gfid.c gsync-upgrade.sh generate-gfid-file.sh \
- get-gfid.sh slave-upgrade.sh
+ get-gfid.sh slave-upgrade.sh schedule_georep.py.in
+
+CLEANFILES = schedule_georep.py
diff --git a/extras/geo-rep/gsync-sync-gfid.c b/extras/geo-rep/gsync-sync-gfid.c
index e9b9e633402..47dca0413e9 100644
--- a/extras/geo-rep/gsync-sync-gfid.c
+++ b/extras/geo-rep/gsync-sync-gfid.c
@@ -7,103 +7,103 @@
#include <libgen.h>
#include <ctype.h>
#include <stdlib.h>
-#include "glusterfs.h"
-#include "syscall.h"
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/syscall.h>
#ifndef UUID_CANONICAL_FORM_LEN
#define UUID_CANONICAL_FORM_LEN 36
#endif
#ifndef GF_FUSE_AUX_GFID_HEAL
-#define GF_FUSE_AUX_GFID_HEAL "glusterfs.gfid.heal"
+#define GF_FUSE_AUX_GFID_HEAL "glusterfs.gfid.heal"
#endif
-#define GLFS_LINE_MAX (PATH_MAX + (2 * UUID_CANONICAL_FORM_LEN))
+#define GLFS_LINE_MAX (PATH_MAX + (2 * UUID_CANONICAL_FORM_LEN))
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- char *file = NULL;
- char *tmp = NULL;
- char *tmp1 = NULL;
- char *parent_dir = NULL;
- char *gfid = NULL;
- char *bname = NULL;
- int ret = -1;
- int len = 0;
- FILE *fp = NULL;
- char line[GLFS_LINE_MAX] = {0,};
- char *path = NULL;
- void *blob = NULL;
- void *tmp_blob = NULL;
-
- if (argc != 2) {
- /* each line in the file has the following format
- * uuid-in-canonical-form path-relative-to-gluster-mount.
- * Both uuid and relative path are from master mount.
- */
- fprintf (stderr, "usage: %s <file-of-paths-to-be-synced>\n",
- argv[0]);
- goto out;
+ char *file = NULL;
+ char *tmp = NULL;
+ char *tmp1 = NULL;
+ char *parent_dir = NULL;
+ char *gfid = NULL;
+ char *bname = NULL;
+ int ret = -1;
+ int len = 0;
+ FILE *fp = NULL;
+ char line[GLFS_LINE_MAX] = {
+ 0,
+ };
+ char *path = NULL;
+ void *blob = NULL;
+ void *tmp_blob = NULL;
+
+ if (argc != 2) {
+ /* each line in the file has the following format
+ * uuid-in-canonical-form path-relative-to-gluster-mount.
+ * Both uuid and relative path are from master mount.
+ */
+ fprintf(stderr, "usage: %s <file-of-paths-to-be-synced>\n", argv[0]);
+ goto out;
+ }
+
+ file = argv[1];
+
+ fp = fopen(file, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "cannot open %s for reading (%s)\n", file,
+ strerror(errno));
+ goto out;
+ }
+
+ while (fgets(line, GLFS_LINE_MAX, fp) != NULL) {
+ tmp = line;
+ path = gfid = line;
+
+ path += UUID_CANONICAL_FORM_LEN + 1;
+
+ while (isspace(*path))
+ path++;
+
+ len = strlen(line);
+ if ((len < GLFS_LINE_MAX) && (line[len - 1] == '\n'))
+ line[len - 1] = '\0';
+
+ line[UUID_CANONICAL_FORM_LEN] = '\0';
+
+ tmp = strdup(path);
+ tmp1 = strdup(path);
+ parent_dir = dirname(tmp);
+ bname = basename(tmp1);
+
+ /* gfid + '\0' + bname + '\0' */
+ len = UUID_CANONICAL_FORM_LEN + 1 + strlen(bname) + 1;
+
+ blob = malloc(len);
+
+ memcpy(blob, gfid, UUID_CANONICAL_FORM_LEN);
+
+ tmp_blob = blob + UUID_CANONICAL_FORM_LEN + 1;
+
+ memcpy(tmp_blob, bname, strlen(bname));
+
+ ret = sys_lsetxattr(parent_dir, GF_FUSE_AUX_GFID_HEAL, blob, len, 0);
+ if (ret < 0) {
+ fprintf(stderr, "setxattr on %s/%s failed (%s)\n", parent_dir,
+ bname, strerror(errno));
}
+ memset(line, 0, GLFS_LINE_MAX);
- file = argv[1];
+ free(blob);
+ free(tmp);
+ free(tmp1);
+ blob = NULL;
+ }
- fp = fopen (file, "r");
- if (fp == NULL) {
- fprintf (stderr, "cannot open %s for reading (%s)\n",
- file, strerror (errno));
- goto out;
- }
-
- while (fgets (line, GLFS_LINE_MAX, fp) != NULL) {
- tmp = line;
- path = gfid = line;
-
- path += UUID_CANONICAL_FORM_LEN + 1;
-
- while(isspace (*path))
- path++;
-
- if ((strlen (line) < GLFS_LINE_MAX) &&
- (line[strlen (line) - 1] == '\n'))
- line[strlen (line) - 1] = '\0';
-
- line[UUID_CANONICAL_FORM_LEN] = '\0';
-
- tmp = strdup (path);
- tmp1 = strdup (path);
- parent_dir = dirname (tmp);
- bname = basename (tmp1);
-
- /* gfid + '\0' + bname + '\0' */
- len = UUID_CANONICAL_FORM_LEN + 1 + strlen (bname) + 1;
-
- blob = calloc (1, len);
-
- memcpy (blob, gfid, UUID_CANONICAL_FORM_LEN);
-
- tmp_blob = blob + UUID_CANONICAL_FORM_LEN + 1;
-
- memcpy (tmp_blob, bname, strlen (bname));
-
- ret = sys_lsetxattr (parent_dir, GF_FUSE_AUX_GFID_HEAL,
- blob, len, 0);
- if (ret < 0) {
- fprintf (stderr, "setxattr on %s/%s failed (%s)\n",
- parent_dir, bname, strerror (errno));
- }
- memset (line, 0, GLFS_LINE_MAX);
-
- free (blob);
- free (tmp); free (tmp1);
- blob = NULL;
- }
-
- ret = 0;
+ ret = 0;
out:
- if (fp)
- fclose(fp);
- return ret;
+ if (fp)
+ fclose(fp);
+ return ret;
}
-
diff --git a/extras/geo-rep/schedule_georep.py.in b/extras/geo-rep/schedule_georep.py.in
new file mode 100644
index 00000000000..48b2b507060
--- /dev/null
+++ b/extras/geo-rep/schedule_georep.py.in
@@ -0,0 +1,492 @@
+#!/usr/bin/python3
+"""
+Schedule Geo-replication
+------------------------
+A tool to run Geo-replication when required. This can be used to
+schedule the Geo-replication to run once in a day using
+
+ # Run daily at 08:30pm
+ 30 20 * * * root python /usr/share/glusterfs/scripts/schedule_georep.py \\
+ --no-color gv1 fvm1 gv2 >> /var/log/glusterfs/schedule_georep.log 2>&1
+
+This tool does the following,
+
+1. Stop Geo-replication if Started
+2. Start Geo-replication
+3. Set Checkpoint
+4. Check the Status and see Checkpoint is Complete.(LOOP)
+5. If checkpoint complete, Stop Geo-replication
+
+Usage:
+
+ python /usr/share/glusterfs/scripts/schedule_georep.py <MASTERVOL> \\
+ <SLAVEHOST> <SLAVEVOL>
+
+For example,
+
+ python /usr/share/glusterfs/scripts/schedule_georep.py gv1 fvm1 gv2
+
+"""
+import subprocess
+import time
+import xml.etree.cElementTree as etree
+import sys
+from contextlib import contextmanager
+import tempfile
+import os
+from argparse import ArgumentParser, RawDescriptionHelpFormatter
+
+ParseError = etree.ParseError if hasattr(etree, 'ParseError') else SyntaxError
+cache_data = {}
+
+SESSION_MOUNT_LOG_FILE = ("/var/log/glusterfs/geo-replication"
+ "/schedule_georep.mount.log")
+
+USE_CLI_COLOR = True
+mnt_list = []
+
+class GlusterBadXmlFormat(Exception):
+ """
+ Exception class for XML Parse Errors
+ """
+ pass
+
+
+def output_notok(msg, err="", exitcode=1):
+ if USE_CLI_COLOR:
+ out = "\033[31m[NOT OK]\033[0m {0}\n{1}\n"
+ else:
+ out = "[NOT OK] {0}\n{1}\n"
+ sys.stderr.write(out.format(msg, err))
+ sys.exit(exitcode)
+
+
+def output_warning(msg):
+ if USE_CLI_COLOR:
+ out = "\033[33m[ WARN]\033[0m {0}\n"
+ else:
+ out = "[ WARN] {0}\n"
+ sys.stderr.write(out.format(msg))
+
+
+def output_ok(msg):
+ if USE_CLI_COLOR:
+ out = "\033[32m[ OK]\033[0m {0}\n"
+ else:
+ out = "[ OK] {0}\n"
+ sys.stderr.write(out.format(msg))
+
+
+def execute(cmd, success_msg="", failure_msg="", exitcode=-1):
+ """
+ Generic wrapper to execute the CLI commands. Returns Output if success.
+ On success it can print message in stdout if specified.
+ On failure, exits after writing to stderr.
+ """
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
+ out, err = p.communicate()
+ if p.returncode == 0:
+ if success_msg:
+ output_ok(success_msg)
+ return out
+ else:
+ if exitcode == 0:
+ return
+ err_msg = err if err else out
+ output_notok(failure_msg, err=err_msg, exitcode=exitcode)
+
+
+def cache_output_with_args(func):
+ """
+ Decorator function to remember the output of any function
+ """
+ def wrapper(*args, **kwargs):
+ global cache_data
+ key = "_".join([func.func_name] + list(args))
+ if cache_data.get(key, None) is None:
+ cache_data[key] = func(*args, **kwargs)
+
+ return cache_data[key]
+ return wrapper
+
+
+def cleanup(hostname, volname, mnt):
+ """
+ Unmount the Volume and Remove the temporary directory
+ """
+ execute(["umount", "-l", mnt],
+ failure_msg="Unable to Unmount Gluster Volume "
+ "{0}:{1}(Mounted at {2})".format(hostname, volname, mnt))
+ execute(["rmdir", mnt],
+ failure_msg="Unable to Remove temp directory "
+ "{0}".format(mnt), exitcode=0)
+
+
+@contextmanager
+def glustermount(hostname, volname):
+ """
+ Context manager for Mounting Gluster Volume
+ Use as
+ with glustermount(HOSTNAME, VOLNAME) as MNT:
+ # Do your stuff
+ Automatically unmounts it in case of Exceptions/out of context
+ """
+ mnt = tempfile.mkdtemp(prefix="georepsetup_")
+ mnt_list.append(mnt)
+ execute(["@SBIN_DIR@/glusterfs",
+ "--volfile-server", hostname,
+ "--volfile-id", volname,
+ "-l", SESSION_MOUNT_LOG_FILE,
+ mnt],
+ failure_msg="Unable to Mount Gluster Volume "
+ "{0}:{1}".format(hostname, volname))
+ if os.path.ismount(mnt):
+ yield mnt
+ else:
+ output_notok("Unable to Mount Gluster Volume "
+ "{0}:{1}".format(hostname, volname))
+ cleanup(hostname, volname, mnt)
+
+
+@cache_output_with_args
+def get_bricks(volname):
+ """
+ Returns Bricks list, caches the Bricks list for a volume once
+ parsed.
+ """
+ value = []
+ cmd = ["@SBIN_DIR@/gluster", "volume", "info", volname, "--xml"]
+ info = execute(cmd)
+ try:
+ tree = etree.fromstring(info)
+ volume_el = tree.find('volInfo/volumes/volume')
+ for b in volume_el.findall('bricks/brick'):
+ value.append({"name": b.find("name").text,
+ "hostUuid": b.find("hostUuid").text})
+ except ParseError:
+ raise GlusterBadXmlFormat("Bad XML Format: %s" % " ".join(cmd))
+
+ return value
+
+
+def get_georep_status(mastervol, slave):
+ session_keys = set()
+ out = {}
+ cmd = ["@SBIN_DIR@/gluster", "volume", "geo-replication"]
+ if mastervol is not None:
+ cmd += [mastervol]
+ if slave:
+ cmd += [slave]
+
+ cmd += ["status", "--xml"]
+ info = execute(cmd)
+
+ try:
+ tree = etree.fromstring(info)
+ # Get All Sessions
+ for volume_el in tree.findall("geoRep/volume"):
+ sessions_el = volume_el.find("sessions")
+ # Master Volume name if multiple Volumes
+ mvol = volume_el.find("name").text
+
+ # For each session, collect the details
+ for session in sessions_el.findall("session"):
+ session_slave = "{0}:{1}".format(mvol, session.find(
+ "session_slave").text)
+ session_keys.add(session_slave)
+ out[session_slave] = {}
+
+ for pair in session.findall('pair'):
+ master_brick = "{0}:{1}".format(
+ pair.find("master_node").text,
+ pair.find("master_brick").text
+ )
+
+ out[session_slave][master_brick] = {
+ "mastervol": mvol,
+ "slavevol": pair.find("slave").text.split("::")[-1],
+ "master_node": pair.find("master_node").text,
+ "master_brick": pair.find("master_brick").text,
+ "slave_user": pair.find("slave_user").text,
+ "slave": pair.find("slave").text,
+ "slave_node": pair.find("slave_node").text,
+ "status": pair.find("status").text,
+ "crawl_status": pair.find("crawl_status").text,
+ "entry": pair.find("entry").text,
+ "data": pair.find("data").text,
+ "meta": pair.find("meta").text,
+ "failures": pair.find("failures").text,
+ "checkpoint_completed": pair.find(
+ "checkpoint_completed").text,
+ "master_node_uuid": pair.find("master_node_uuid").text,
+ "last_synced": pair.find("last_synced").text,
+ "checkpoint_time": pair.find("checkpoint_time").text,
+ "checkpoint_completion_time":
+ pair.find("checkpoint_completion_time").text
+ }
+ except ParseError:
+ raise GlusterBadXmlFormat("Bad XML Format: %s" % " ".join(cmd))
+
+ return session_keys, out
+
+
+def get_offline_status(volname, brick, node_uuid, slave):
+ node, brick = brick.split(":")
+ if "@" not in slave:
+ slave_user = "root"
+ else:
+ slave_user, _ = slave.split("@")
+
+ return {
+ "mastervol": volname,
+ "slavevol": slave.split("::")[-1],
+ "master_node": node,
+ "master_brick": brick,
+ "slave_user": slave_user,
+ "slave": slave,
+ "slave_node": "N/A",
+ "status": "Offline",
+ "crawl_status": "N/A",
+ "entry": "N/A",
+ "data": "N/A",
+ "meta": "N/A",
+ "failures": "N/A",
+ "checkpoint_completed": "N/A",
+ "master_node_uuid": node_uuid,
+ "last_synced": "N/A",
+ "checkpoint_time": "N/A",
+ "checkpoint_completion_time": "N/A"
+ }
+
+
+def get(mastervol=None, slave=None):
+ """
+ This function gets list of Bricks of Master Volume and collects
+ respective Geo-rep status. Output will be always ordered as the
+ bricks list in Master Volume. If Geo-rep status is not available
+ for any brick then it updates OFFLINE status.
+ """
+ out = []
+ session_keys, gstatus = get_georep_status(mastervol, slave)
+
+ for session in session_keys:
+ mvol, _, slave = session.split(":", 2)
+ slave = slave.replace("ssh://", "")
+ master_bricks = get_bricks(mvol)
+ out.append([])
+ for brick in master_bricks:
+ bname = brick["name"]
+ if gstatus.get(session) and gstatus[session].get(bname, None):
+ out[-1].append(gstatus[session][bname])
+ else:
+ out[-1].append(
+ get_offline_status(mvol, bname, brick["hostUuid"], slave))
+
+ return out
+
+
+def get_summary(mastervol, slave_url):
+ """
+ Wrapper function around Geo-rep Status and Gluster Volume Info
+ This combines the output from Bricks list and Geo-rep Status.
+ If a Master Brick node is down or Status is faulty then increments
+ the faulty counter. It also collects the checkpoint status from all
+ workers and compares with Number of Bricks.
+ """
+ down_rows = []
+ faulty_rows = []
+ out = []
+
+ status_data = get(mastervol, slave_url)
+
+ for session in status_data:
+ session_name = ""
+ summary = {
+ "active": 0,
+ "passive": 0,
+ "faulty": 0,
+ "initializing": 0,
+ "stopped": 0,
+ "created": 0,
+ "offline": 0,
+ "paused": 0,
+ "workers": 0,
+ "completed_checkpoints": 0,
+ "checkpoint": False,
+ "checkpoints_ok": False,
+ "ok": False
+ }
+
+ for row in session:
+ summary[row["status"].replace("...", "").lower()] += 1
+ summary["workers"] += 1
+ if row["checkpoint_completed"] == "Yes":
+ summary["completed_checkpoints"] += 1
+
+ session_name = "{0}=>{1}".format(
+ row["mastervol"],
+ row["slave"].replace("ssh://", "")
+ )
+
+ if row["status"] == "Faulty":
+ faulty_rows.append("{0}:{1}".format(row["master_node"],
+ row["master_brick"]))
+
+ if row["status"] == "Offline":
+ down_rows.append("{0}:{1}".format(row["master_node"],
+ row["master_brick"]))
+
+ if summary["active"] == summary["completed_checkpoints"] and \
+ summary["faulty"] == 0 and summary["offline"] == 0:
+ summary["checkpoints_ok"] = True
+
+ if summary["faulty"] == 0 and summary["offline"] == 0:
+ summary["ok"] = True
+
+ if session_name != "":
+ out.append([session_name, summary, faulty_rows, down_rows])
+
+ return out
+
+
+def touch_mount_root(mastervol):
+ # Create a Mount and Touch the Mount point root,
+ # Hack to make sure some event available after
+ # setting Checkpoint. Without this there is a chance of
+ # Checkpoint never completes.
+ with glustermount("localhost", mastervol) as mnt:
+ execute(["touch", mnt])
+
+
+def main(args):
+ turns = 1
+
+ # Stop Force
+ cmd = ["@SBIN_DIR@/gluster", "volume", "geo-replication", args.mastervol,
+ "%s::%s" % (args.slave, args.slavevol), "stop", "force"]
+ execute(cmd)
+ output_ok("Stopped Geo-replication")
+
+ # Set Checkpoint to NOW
+ cmd = ["@SBIN_DIR@/gluster", "volume", "geo-replication", args.mastervol,
+ "%s::%s" % (args.slave, args.slavevol), "config", "checkpoint",
+ "now"]
+ execute(cmd)
+ output_ok("Set Checkpoint")
+
+ # Start the Geo-replication
+ cmd = ["@SBIN_DIR@/gluster", "volume", "geo-replication", args.mastervol,
+ "%s::%s" % (args.slave, args.slavevol), "start"]
+ execute(cmd)
+ output_ok("Started Geo-replication and watching Status for "
+ "Checkpoint completion")
+
+ start_time = int(time.time())
+ duration = 0
+
+ # Sleep till Geo-rep initializes
+ time.sleep(60)
+
+ touch_mount_root(args.mastervol)
+
+ slave_url = "{0}::{1}".format(args.slave, args.slavevol)
+
+ # Loop to Check the Geo-replication Status and Checkpoint
+ # If All Status OK and all Checkpoints complete,
+ # Stop the Geo-replication and Log the Completeness
+ while True:
+ session_summary = get_summary(args.mastervol,
+ slave_url)
+ if len(session_summary) == 0:
+ # If Status command fails with another transaction error
+ # or any other error. Gluster cmd still produces XML output
+ # with different message
+ output_warning("Unable to get Geo-replication Status")
+ else:
+ session_name, summary, faulty_rows, down_rows = session_summary[0]
+ chkpt_status = "COMPLETE" if summary["checkpoints_ok"] else \
+ "NOT COMPLETE"
+ ok_status = "OK" if summary["ok"] else "NOT OK"
+
+ if summary["ok"]:
+ output_ok("All Checkpoints {1}, "
+ "All status {2} (Turns {0:>3})".format(
+ turns, chkpt_status, ok_status))
+ else:
+ output_warning("All Checkpoints {1}, "
+ "All status {2} (Turns {0:>3})".format(
+ turns, chkpt_status, ok_status))
+
+ output_warning("Geo-rep workers Faulty/Offline, "
+ "Faulty: {0} Offline: {1}".format(
+ repr(faulty_rows),
+ repr(down_rows)))
+
+ if summary["checkpoints_ok"]:
+ output_ok("Stopping Geo-replication session now")
+ cmd = ["@SBIN_DIR@/gluster", "volume", "geo-replication",
+ args.mastervol,
+ "%s::%s" % (args.slave, args.slavevol), "stop"]
+ execute(cmd)
+ break
+ else:
+ # If Checkpoint is not complete after a iteration means brick
+ # was down and came online now. SETATTR on mount is not
+ # recorded, So again issue touch on mount root So that
+ # Stime will increase and Checkpoint will complete.
+ touch_mount_root(args.mastervol)
+
+ # Increment the turns and Sleep for 10 sec
+ turns += 1
+ duration = int(time.time()) - start_time
+ if args.timeout > 0 and duration > (args.timeout * 60):
+ cmd = ["@SBIN_DIR@/gluster", "volume", "geo-replication",
+ args.mastervol,
+ "%s::%s" % (args.slave, args.slavevol), "stop", "force"]
+ execute(cmd)
+ output_notok("Timed out, Stopping Geo-replication("
+ "Duration: {0}sec)".format(duration))
+
+ time.sleep(args.interval)
+
+ for mnt in mnt_list:
+ execute(["rmdir", mnt],
+ failure_msg="Unable to Remove temp directory "
+ "{0}".format(mnt), exitcode=0)
+
+if __name__ == "__main__":
+ parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter,
+ description=__doc__)
+ parser.add_argument("mastervol", help="Master Volume Name")
+ parser.add_argument("slave",
+ help="Slave hostname "
+ "(<username>@SLAVEHOST or SLAVEHOST)",
+ metavar="SLAVE")
+ parser.add_argument("slavevol", help="Slave Volume Name")
+ parser.add_argument("--interval", help="Interval in Seconds. "
+ "Wait time before each status check",
+ type=int, default=10)
+ parser.add_argument("--timeout", help="Timeout in minutes. Script will "
+ "stop Geo-replication if Checkpoint is not complete "
+ "in the specified timeout time", type=int,
+ default=0)
+ parser.add_argument("--no-color", help="Don't use Color in CLI output",
+ action="store_true")
+ args = parser.parse_args()
+ if args.no_color:
+ USE_CLI_COLOR = False
+ try:
+ # Check for session existence
+ cmd = ["@SBIN_DIR@/gluster", "volume", "geo-replication",
+ args.mastervol, "%s::%s" % (args.slave, args.slavevol), "status"]
+ execute(cmd)
+ main(args)
+ except KeyboardInterrupt:
+ for mnt in mnt_list:
+ execute(["umount", "-l", mnt],
+ failure_msg="Unable to Unmount Gluster Volume "
+ "Mounted at {0}".format(mnt), exitcode=0)
+ execute(["rmdir", mnt],
+ failure_msg="Unable to Remove temp directory "
+ "{0}".format(mnt), exitcode=0)
+ output_notok("Exiting...")
diff --git a/extras/gfid-to-dirname.sh b/extras/gfid-to-dirname.sh
new file mode 100755
index 00000000000..fd359fab58a
--- /dev/null
+++ b/extras/gfid-to-dirname.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+function read_symlink()
+{
+ DOT_GLUSTERFS_PATH=$BRICK_PATH/.glusterfs
+ gfid_string=$1
+ symlink_path="$DOT_GLUSTERFS_PATH/${gfid_string:0:2}/${gfid_string:2:2}/$gfid_string"
+ #remove trailing '/'
+ symlink_path=${symlink_path%/}
+ linkname=$(readlink $symlink_path)
+ if [ $? -ne 0 ]; then
+ echo "readlink of $symlink_path returned an error." >&2
+ exit -1
+ fi
+ echo $linkname
+}
+
+main()
+{
+ if [ $# -lt 2 ] ;then
+ echo "Usage: $0 <brick-path> <gfid-string-of-directory>"
+ echo "Example: $0 /bricks/brick1 1b835012-1ae5-4f0d-9db4-64de574d891c"
+ exit -1
+ fi
+
+ BRICK_PATH=$1
+ name=$(read_symlink $2)
+ if [ $? -ne 0 ]; then
+ exit -1
+ fi
+
+ while [ ${name:12:36} != "00000000-0000-0000-0000-000000000001" ]
+ do
+ LOCATION=`basename $name`/$LOCATION
+ GFID_STRING=${name:12:36}
+ name=$(read_symlink $GFID_STRING)
+ if [ $? -ne 0 ]; then
+ exit -1
+ fi
+ done
+
+ LOCATION=`basename $name`/$LOCATION
+ echo "Location of the directory corresponding to gfid:$2 is $BRICK_PATH/$LOCATION"
+}
+
+main "$@"
diff --git a/extras/git-branch-diff.py b/extras/git-branch-diff.py
new file mode 100755
index 00000000000..382513e069e
--- /dev/null
+++ b/extras/git-branch-diff.py
@@ -0,0 +1,285 @@
+#!/bin/python2
+
+"""
+ Copyright (c) 2016 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.
+"""
+
+"""
+ ABOUT:
+ This script helps in visualizing backported and missed commits between two
+ different branches, tags or commit ranges. In the list of missed commits,
+ it will help you identify patches which are posted for reviews on gerrit server.
+
+ USAGE:
+ $ ./extras/git-branch-diff.py --help
+ usage: git-branch-diff.py [-h] [-s SOURCE] -t TARGET [-a AUTHOR] [-p PATH]
+ [-o OPTIONS]
+
+ git wrapper to diff local or remote branches/tags/commit-ranges
+
+ optional arguments:
+ -h, --help show this help message and exit
+ -s SOURCE, --source SOURCE
+ source pattern, it could be a branch, tag or a commit
+ range
+ -t TARGET, --target TARGET
+ target pattern, it could be a branch, tag or a commit
+ range
+ -a AUTHOR, --author AUTHOR
+ default: git config name/email, to provide multiple
+ specify comma separated values
+ -p PATH, --path PATH show source and target diff w.r.t given path, to
+ provide multiple specify space in between them
+ -o OPTIONS, --options OPTIONS
+ add other git options such as --after=<>, --before=<>
+ etc. experts use;
+
+ SAMPLE EXECUTIONS:
+ $ ./extras/git-branch-diff.py -t origin/release-3.8
+
+ $ ./extras/git-branch-diff.py -s local_branch -t origin/release-3.7
+
+ $ ./extras/git-branch-diff.py -s 4517bf8..e66add8 -t origin/release-3.7
+ $ ./extras/git-branch-diff.py -s HEAD..c4efd39 -t origin/release-3.7
+
+ $ ./extras/git-branch-diff.py -t v3.7.11 --author="author@redhat.com"
+ $ ./extras/git-branch-diff.py -t v3.7.11 --author="authorX, authorY, authorZ"
+
+ $ ./extras/git-branch-diff.py -t origin/release-3.8 --path="xlators/"
+ $ ./extras/git-branch-diff.py -t origin/release-3.8 --path="./xlators ./rpc"
+
+ $ ./extras/git-branch-diff.py -t origin/release-3.6 --author="*"
+ $ ./extras/git-branch-diff.py -t origin/release-3.6 --author="All"
+ $ ./extras/git-branch-diff.py -t origin/release-3.6 --author="Null"
+
+ $ ./extras/git-branch-diff.py -t v3.7.11 --options="--after=2015-03-01 \
+ --before=2016-01-30"
+
+ DECLARATION:
+ While backporting commit to another branch only subject of the patch may
+ remain unchanged, all others such as commit message, commit Id, change Id,
+ bug Id, may be changed. This script works by taking commit subject as the
+ key value for comparing two git branches, which can be local or remote.
+
+ Note: This script may ignore commits which have altered their commit subjects
+ while backporting patches. Also this script doesn't have any intelligence to
+ detect squashed commits.
+
+ AUTHOR:
+ Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
+"""
+
+from __future__ import print_function
+import os
+import sys
+import argparse
+import commands
+import subprocess
+import requests
+
+class GitBranchDiff:
+ def __init__ (self):
+ " color symbols"
+ self.tick = u'\033[1;32m[ \u2714 ]\033[0m'
+ self.cross = u'\033[1;31m[ \u2716 ]\033[0m'
+ self.green_set = u'\033[1;34m'
+ self.yello_set = u'\033[4;33m'
+ self.color_unset = '\033[0m'
+
+ self.parse_cmd_args()
+
+ " replace default values with actual values from command args"
+ self.g_author = self.argsdict['author']
+ self.s_pattern = self.argsdict['source']
+ self.t_pattern = self.argsdict['target']
+ self.r_path = self.argsdict['path']
+ self.options = ' '.join(self.argsdict['options'])
+
+ self.gerrit_server = "http://review.gluster.org"
+
+ def check_dir_exist (self, os_path):
+ " checks whether given path exist"
+ path_list = os_path.split()
+ for path in path_list:
+ if not os.path.exists(path):
+ raise argparse.ArgumentTypeError("'%s' path %s is not valid"
+ %(os_path, path))
+ return os_path
+
+ def check_pattern_exist (self):
+ " defend to check given branch[s] exit"
+ status_sbr, op = commands.getstatusoutput('git log ' +
+ self.s_pattern)
+ status_tbr, op = commands.getstatusoutput('git log ' +
+ self.t_pattern)
+ if status_sbr != 0:
+ print("Error: --source=" + self.s_pattern + " doesn't exit\n")
+ self.parser.print_help()
+ exit(status_sbr)
+ elif status_tbr != 0:
+ print("Error: --target=" + self.t_pattern + " doesn't exit\n")
+ self.parser.print_help()
+ exit(status_tbr)
+
+ def check_author_exist (self):
+ " defend to check given author exist, format in case of multiple"
+ contrib_list = ['', '*', 'all', 'All', 'ALL', 'null', 'Null', 'NULL']
+ if self.g_author in contrib_list:
+ self.g_author = ""
+ else:
+ ide_list = self.g_author.split(',')
+ for ide in ide_list:
+ cmd4 = 'git log ' + self.s_pattern + ' --author=' + ide
+ c_list = subprocess.check_output(cmd4, shell = True)
+ if len(c_list) is 0:
+ print("Error: --author=%s doesn't exit" %self.g_author)
+ print("see '%s --help'" %__file__)
+ exit(1)
+ if len(ide_list) > 1:
+ self.g_author = "\|".join(ide_list)
+
+ def connected_to_gerrit (self):
+ "check if gerrit server is reachable"
+ try:
+ r = requests.get(self.gerrit_server, timeout=3)
+ return True
+ except requests.Timeout as err:
+ " request timed out"
+ print("Warning: failed to get list of open review commits on " \
+ "gerrit.\n" \
+ "hint: Request timed out! gerrit server could possibly " \
+ "slow ...\n")
+ return False
+ except requests.RequestException as err:
+ " handle other errors"
+ print("Warning: failed to get list of open review commits on " \
+ "gerrit\n" \
+ "hint: check with internet connection ...\n")
+ return False
+
+ def parse_cmd_args (self):
+ " command line parser"
+ author = subprocess.check_output('git config user.email',
+ shell = True).rstrip('\n')
+ source = "remotes/origin/master"
+ options = [' --pretty=format:"%h %s" ']
+ path = subprocess.check_output('git rev-parse --show-toplevel',
+ shell = True).rstrip('\n')
+ self.parser = argparse.ArgumentParser(description = 'git wrapper to '
+ 'diff local or remote branches/'
+ 'tags/commit-ranges')
+ self.parser.add_argument('-s',
+ '--source',
+ help = 'source pattern, it could be a branch,'
+ ' tag or a commit range',
+ default = source,
+ dest = 'source')
+ self.parser.add_argument('-t',
+ '--target',
+ help = 'target pattern, it could be a branch,'
+ ' tag or a commit range',
+ required = True,
+ dest = 'target')
+ self.parser.add_argument('-a',
+ '--author',
+ help = 'default: git config name/email, '
+ 'to provide multiple specify comma'
+ ' separated values',
+ default = author,
+ dest = 'author')
+ self.parser.add_argument('-p',
+ '--path',
+ type = self.check_dir_exist,
+ help = 'show source and target diff w.r.t '
+ 'given path, to provide multiple '
+ 'specify space in between them',
+ default = path,
+ dest = 'path')
+ self.parser.add_argument('-o',
+ '--options',
+ help = 'add other git options such as '
+ '--after=<>, --before=<> etc. '
+ 'experts use;',
+ default = options,
+ dest = 'options',
+ action='append')
+ self.argsdict = vars(self.parser.parse_args())
+
+ def print_output (self):
+ " display the result list"
+ print("\n------------------------------------------------------------\n")
+ print(self.tick + " Successfully Backported changes:")
+ print(' {' + 'from: ' + self.s_pattern + \
+ ' to: '+ self.t_pattern + '}\n')
+ for key, value in self.s_dict.items():
+ if value in self.t_dict.itervalues():
+ print("[%s%s%s] %s" %(self.yello_set,
+ key,
+ self.color_unset,
+ value))
+ print("\n------------------------------------------------------------\n")
+ print(self.cross + " Missing patches in " + self.t_pattern + ':\n')
+ if self.connected_to_gerrit():
+ cmd3 = "git review -r origin -l"
+ review_list = subprocess.check_output(cmd3, shell = True).split('\n')
+ else:
+ review_list = []
+
+ for key, value in self.s_dict.items():
+ if value not in self.t_dict.itervalues():
+ if any(value in s for s in review_list):
+ print("[%s%s%s] %s %s(under review)%s" %(self.yello_set,
+ key,
+ self.color_unset,
+ value,
+ self.green_set,
+ self.color_unset))
+ else:
+ print("[%s%s%s] %s" %(self.yello_set,
+ key,
+ self.color_unset,
+ value))
+ print("\n------------------------------------------------------------\n")
+
+ def main (self):
+ self.check_pattern_exist()
+ self.check_author_exist()
+
+ " actual git commands"
+ cmd1 = 'git log' + self.options + ' ' + self.s_pattern + \
+ ' --author=\'' + self.g_author + '\' ' + self.r_path
+
+ " could be backported by anybody so --author doesn't apply here"
+ cmd2 = 'git log' + self.options + ' ' + self.t_pattern + \
+ ' ' + self.r_path
+
+ s_list = subprocess.check_output(cmd1, shell = True).split('\n')
+ t_list = subprocess.check_output(cmd2, shell = True)
+
+ if len(t_list) is 0:
+ print("No commits in the target: %s" %self.t_pattern)
+ print("see '%s --help'" %__file__)
+ exit()
+ else:
+ t_list = t_list.split('\n')
+
+ self.s_dict = dict()
+ self.t_dict = dict()
+
+ for item in s_list:
+ self.s_dict.update(dict([item.split(' ', 1)]))
+ for item in t_list:
+ self.t_dict.update(dict([item.split(' ', 1)]))
+
+ self.print_output()
+
+
+if __name__ == '__main__':
+ run = GitBranchDiff()
+ run.main()
diff --git a/extras/glusterd.vol.in b/extras/glusterd.vol.in
index 690dbe71823..5d7bad0e4c8 100644
--- a/extras/glusterd.vol.in
+++ b/extras/glusterd.vol.in
@@ -1,10 +1,15 @@
volume management
type mgmt/glusterd
option working-directory @GLUSTERD_WORKDIR@
- option transport-type socket,rdma
+ option transport-type socket
option transport.socket.keepalive-time 10
option transport.socket.keepalive-interval 2
option transport.socket.read-fail-log off
- option ping-timeout 30
+ option transport.socket.listen-port 24007
+ option ping-timeout 0
+ option event-threads 1
+# option lock-timer 180
+# option transport.address-family inet6
# option base-port 49152
+ option max-port 60999
end-volume
diff --git a/extras/glusterfs-georep-logrotate b/extras/glusterfs-georep-logrotate
index 6fdb8c65aaf..3e7ecf373a1 100644
--- a/extras/glusterfs-georep-logrotate
+++ b/extras/glusterfs-georep-logrotate
@@ -1,6 +1,12 @@
/var/log/glusterfs/geo-replication/*/*.log {
sharedscripts
- rotate 52
+ weekly
+ maxsize 10M
+ minsize 100k
+
+ # 6 months of logs are good enough
+ rotate 26
+
missingok
compress
delaycompress
@@ -15,7 +21,13 @@
/var/log/glusterfs/geo-replication-slaves/*.log {
sharedscripts
- rotate 52
+ weekly
+ maxsize 10M
+ minsize 100k
+
+ # 6 months of logs are good enough
+ rotate 26
+
missingok
compress
delaycompress
@@ -30,7 +42,13 @@
/var/log/glusterfs/geo-replication-slaves/*/*.log {
sharedscripts
- rotate 52
+ weekly
+ maxsize 10M
+ minsize 100k
+
+ # 6 months of logs are good enough
+ rotate 26
+
missingok
compress
delaycompress
diff --git a/extras/glusterfs-georep-upgrade.py b/extras/glusterfs-georep-upgrade.py
new file mode 100755
index 00000000000..634576058d6
--- /dev/null
+++ b/extras/glusterfs-georep-upgrade.py
@@ -0,0 +1,77 @@
+#!/usr/bin/python3
+"""
+
+Copyright (c) 2020 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.
+
+"""
+
+import argparse
+import errno
+import os, sys
+import shutil
+from datetime import datetime
+
+def find_htime_path(brick_path):
+ dirs = []
+ htime_dir = os.path.join(brick_path, '.glusterfs/changelogs/htime')
+ for file in os.listdir(htime_dir):
+ if os.path.isfile(os.path.join(htime_dir,file)) and file.startswith("HTIME"):
+ dirs.append(os.path.join(htime_dir, file))
+ else:
+ raise FileNotFoundError("%s unavailable" % (os.path.join(htime_dir, file)))
+ return dirs
+
+def modify_htime_file(brick_path):
+ htime_file_path_list = find_htime_path(brick_path)
+
+ for htime_file_path in htime_file_path_list:
+ changelog_path = os.path.join(brick_path, '.glusterfs/changelogs')
+ temp_htime_path = os.path.join(changelog_path, 'htime/temp_htime_file')
+ with open(htime_file_path, 'r') as htime_file, open(temp_htime_path, 'w') as temp_htime_file:
+ #extract epoch times from htime file
+ paths = htime_file.read().split("\x00")
+
+ for pth in paths:
+ epoch_no = pth.split(".")[-1]
+ changelog = os.path.basename(pth)
+ #convert epoch time to year, month and day
+ if epoch_no != '':
+ date=(datetime.fromtimestamp(float(int(epoch_no))).strftime("%Y/%m/%d"))
+ #update paths in temp htime file
+ temp_htime_file.write("%s/%s/%s\x00" % (changelog_path, date, changelog))
+ #create directory in the format year/month/days
+ path = os.path.join(changelog_path, date)
+
+ if changelog.startswith("CHANGELOG."):
+ try:
+ os.makedirs(path, mode = 0o600);
+ except OSError as exc:
+ if exc.errno == errno.EEXIST:
+ pass
+ else:
+ raise
+
+ #copy existing changelogs to new directory structure, delete old changelog files
+ shutil.copyfile(pth, os.path.join(path, changelog))
+ os.remove(pth)
+
+ #rename temp_htime_file with htime file
+ os.rename(htime_file_path, os.path.join('%s.bak'%htime_file_path))
+ os.rename(temp_htime_path, htime_file_path)
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument('brick_path', help="This upgrade script, which is to be run on\
+ server side, takes brick path as the argument, \
+ updates paths inside htime file and alters the directory structure \
+ above the changelog files inorder to support new optimised format \
+ of the directory structure as per \
+ https://review.gluster.org/#/c/glusterfs/+/23733/")
+ args = parser.parse_args()
+ modify_htime_file(args.brick_path)
diff --git a/extras/glusterfs-logrotate b/extras/glusterfs-logrotate
index e3319afaa96..6ba6ef18e9f 100644
--- a/extras/glusterfs-logrotate
+++ b/extras/glusterfs-logrotate
@@ -2,7 +2,12 @@
/var/log/glusterfs/*.log {
sharedscripts
weekly
- rotate 52
+ maxsize 10M
+ minsize 100k
+
+# 6 months of logs are good enough
+ rotate 26
+
missingok
compress
delaycompress
@@ -17,7 +22,12 @@
/var/log/glusterfs/bricks/*.log {
sharedscripts
weekly
- rotate 52
+ maxsize 10M
+ minsize 100k
+
+# 6 months of logs are good enough
+ rotate 26
+
missingok
compress
delaycompress
@@ -26,3 +36,33 @@
/usr/bin/killall -HUP glusterfsd > /dev/null 2>&1 || true
endscript
}
+
+/var/log/glusterfs/samples/*.samp {
+ daily
+ rotate 3
+ sharedscripts
+ missingok
+ compress
+ delaycompress
+}
+
+# Rotate snapd log
+/var/log/glusterfs/snaps/*/*.log {
+ sharedscripts
+ weekly
+ maxsize 10M
+ minsize 100k
+
+ # 6 months of logs are good enough
+ rotate 26
+
+ missingok
+ compress
+ delaycompress
+ notifempty
+ postrotate
+ for pid in `ps -aef | grep glusterfs | egrep "snapd" | awk '{print $2}'`; do
+ /usr/bin/kill -HUP $pid > /dev/null 2>&1 || true
+ done
+ endscript
+}
diff --git a/extras/glusterfs-mode.el b/extras/glusterfs-mode.el
index d4f6dc568b6..a9ed2335ab3 100644
--- a/extras/glusterfs-mode.el
+++ b/extras/glusterfs-mode.el
@@ -1,112 +1,113 @@
-;;; 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
-;;; 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.
-;;;
-
-(defvar glusterfs-mode-hook nil)
-
-;; (defvar glusterfs-mode-map
-;; (let ((glusterfs-mode-map (make-keymap)))
-;; (define-key glusterfs-mode-map "\C-j" 'newline-and-indent)
-;; glusterfs-mode-map)
-;; "Keymap for WPDL major mode")
-
-(add-to-list 'auto-mode-alist '("\\.vol\\'" . glusterfs-mode))
-
-(defconst glusterfs-font-lock-keywords-1
- (list
- ; "cluster/{unify,afr,stripe}"
- ; "performance/{io-cache,io-threads,write-behind,read-ahead,stat-prefetch}"
- ; "protocol/{client/server}"
- ; "features/{trash,posix-locks,fixed-id,filter}"
- ; "stroage/posix"
- ; "encryption/rot-13"
- ; "debug/trace"
- '("\\<\\(cluster/\\(unify\\|afr\\|replicate\\|stripe\\|ha\\|dht\\|distribute\\)\\|\\performance/\\(io-\\(cache\\|threads\\)\\|write-behind\\|read-ahead\\|symlink-cache\\)\\|protocol/\\(server\\|client\\)\\|features/\\(trash\\|posix-locks\\|locks\\|path-converter\\|filter\\)\\|storage/\\(posix\\|bdb\\)\\|encryption/rot-13\\|debug/trace\\)\\>" . font-lock-keyword-face))
-"Additional Keywords to highlight in GlusterFS mode.")
-
-(defconst glusterfs-font-lock-keywords-2
- (append glusterfs-font-lock-keywords-1
- (list
- ; "replicate" "namespace" "scheduler" "remote-subvolume" "remote-host"
- ; "auth.addr" "block-size" "remote-port" "listen-port" "transport-type"
- ; "limits.min-free-disk" "directory"
- ; TODO: add all the keys here.
- '("\\<\\(inode-lru-limit\\|replicate\\|namespace\\|scheduler\\|username\\|password\\|allow\\|reject\\|block-size\\|listen-port\\|transport-type\\|transport-timeout\\|directory\\|page-size\\|page-count\\|aggregate-size\\|non-blocking-io\\|client-volume-filename\\|bind-address\\|self-heal\\|read-only-subvolumes\\|read-subvolume\\|thread-count\\|cache-size\\|window-size\\|force-revalidate-timeout\\|priority\\|include\\|exclude\\|remote-\\(host\\|subvolume\\|port\\)\\|auth.\\(addr\\|login\\)\\|limits.\\(min-disk-free\\|transaction-size\\|ib-verbs-\\(work-request-\\(send-\\|recv-\\(count\\|size\\)\\)\\|port\\|mtu\\|device-name\\)\\)\\)\ \\>" . font-lock-constant-face)))
- "option keys in GlusterFS mode.")
-
-(defconst glusterfs-font-lock-keywords-3
- (append glusterfs-font-lock-keywords-2
- (list
- ; "option" "volume" "end-volume" "subvolumes" "type"
- '("\\<\\(option\ \\|volume\ \\|subvolumes\ \\|type\ \\|end-volume\\)\\>" . font-lock-builtin-face)))
- ;'((regexp-opt (" option " "^volume " "^end-volume" "subvolumes " " type ") t) . font-lock-builtin-face))
- "Minimal highlighting expressions for GlusterFS mode.")
-
-
-(defvar glusterfs-font-lock-keywords glusterfs-font-lock-keywords-3
- "Default highlighting expressions for GlusterFS mode.")
-
-(defvar glusterfs-mode-syntax-table
- (let ((glusterfs-mode-syntax-table (make-syntax-table)))
- (modify-syntax-entry ?\# "<" glusterfs-mode-syntax-table)
- (modify-syntax-entry ?* ". 23" glusterfs-mode-syntax-table)
- (modify-syntax-entry ?\n ">#" glusterfs-mode-syntax-table)
- glusterfs-mode-syntax-table)
- "Syntax table for glusterfs-mode")
-
-;; TODO: add an indentation table
-
-(defun glusterfs-indent-line ()
- "Indent current line as GlusterFS code"
- (interactive)
- (beginning-of-line)
- (if (bobp)
- (indent-line-to 0) ; First line is always non-indented
- (let ((not-indented t) cur-indent)
- (if (looking-at "^[ \t]*volume\ ")
- (progn
- (save-excursion
- (forward-line -1)
- (setq not-indented nil)
- (setq cur-indent 0))))
- (if (looking-at "^[ \t]*end-volume")
- (progn
- (save-excursion
- (forward-line -1)
- (setq cur-indent 0))
- (if (< cur-indent 0) ; We can't indent past the left margin
- (setq cur-indent 0)))
- (save-excursion
- (while not-indented ; Iterate backwards until we find an indentation hint
- (progn
- (setq cur-indent 2) ; Do the actual indenting
- (setq not-indented nil)))))
- (if cur-indent
- (indent-line-to cur-indent)
- (indent-line-to 0)))))
-
-(defun glusterfs-mode ()
- (interactive)
- (kill-all-local-variables)
- ;; (use-local-map glusterfs-mode-map)
- (set-syntax-table glusterfs-mode-syntax-table)
- (set (make-local-variable 'indent-line-function) 'glusterfs-indent-line)
- (set (make-local-variable 'font-lock-defaults) '(glusterfs-font-lock-keywords))
- (setq major-mode 'glusterfs-mode)
- (setq mode-name "GlusterFS")
- (run-hooks 'glusterfs-mode-hook))
-
-(provide 'glusterfs-mode)
+;;; Copyright (C) 2007-2017 Red Hat, Inc. <http://www.redhat.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 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.
+;;;
+
+(defvar glusterfs-mode-hook nil)
+
+;; (defvar glusterfs-mode-map
+;; (let ((glusterfs-mode-map (make-keymap)))
+;; (define-key glusterfs-mode-map "\C-j" 'newline-and-indent)
+;; glusterfs-mode-map)
+;; "Keymap for WPDL major mode")
+
+(add-to-list 'auto-mode-alist '("\\.vol\\'" . glusterfs-mode))
+
+(defconst glusterfs-font-lock-keywords-1
+ (list
+ ; "cluster/{unify,afr,stripe}"
+ ; "performance/{io-cache,io-threads,write-behind,read-ahead,stat-prefetch}"
+ ; "protocol/{client/server}"
+ ; "features/{trash,posix-locks,fixed-id,filter}"
+ ; "storage/posix"
+ ; "encryption/rot-13"
+ ; "debug/trace"
+ '("\\<\\(cluster/\\(unify\\|afr\\|replicate\\|stripe\\|ha\\|dht\\|distribute\\)\\|\\performance/\\(io-\\(cache\\|threads\\)\\|write-behind\\|read-ahead\\|symlink-cache\\)\\|protocol/\\(server\\|client\\)\\|features/\\(trash\\|posix-locks\\|locks\\|path-converter\\|filter\\)\\|storage/\\(posix\\|bdb\\)\\|encryption/rot-13\\|debug/trace\\)\\>" . font-lock-keyword-face))
+"Additional Keywords to highlight in GlusterFS mode.")
+
+(defconst glusterfs-font-lock-keywords-2
+ (append glusterfs-font-lock-keywords-1
+ (list
+ ; "replicate" "namespace" "scheduler" "remote-subvolume" "remote-host"
+ ; "auth.addr" "block-size" "remote-port" "listen-port" "transport-type"
+ ; "limits.min-free-disk" "directory"
+ ; TODO: add all the keys here.
+ '("\\<\\(inode-lru-limit\\|replicate\\|namespace\\|scheduler\\|username\\|password\\|allow\\|reject\\|block-size\\|listen-port\\|transport-type\\|transport-timeout\\|directory\\|page-size\\|page-count\\|aggregate-size\\|non-blocking-io\\|client-volume-filename\\|bind-address\\|self-heal\\|read-only-subvolumes\\|read-subvolume\\|thread-count\\|cache-size\\|window-size\\|force-revalidate-timeout\\|priority\\|include\\|exclude\\|remote-\\(host\\|subvolume\\|port\\)\\|auth.\\(addr\\|login\\)\\|limits.\\(min-disk-free\\|transaction-size\\|ib-verbs-\\(work-request-\\(send-\\|recv-\\(count\\|size\\)\\)\\|port\\|mtu\\|device-name\\)\\)\\)\ \\>" . font-lock-constant-face)))
+ "option keys in GlusterFS mode.")
+
+(defconst glusterfs-font-lock-keywords-3
+ (append glusterfs-font-lock-keywords-2
+ (list
+ ; "option" "volume" "end-volume" "subvolumes" "type"
+ '("\\<\\(option\ \\|volume\ \\|subvolumes\ \\|type\ \\|end-volume\\)\\>" . font-lock-builtin-face)))
+ ;'((regexp-opt (" option " "^volume " "^end-volume" "subvolumes " " type ") t) . font-lock-builtin-face))
+ "Minimal highlighting expressions for GlusterFS mode.")
+
+
+(defvar glusterfs-font-lock-keywords glusterfs-font-lock-keywords-3
+ "Default highlighting expressions for GlusterFS mode.")
+
+(defvar glusterfs-mode-syntax-table
+ (let ((glusterfs-mode-syntax-table (make-syntax-table)))
+ (modify-syntax-entry ?\# "<" glusterfs-mode-syntax-table)
+ (modify-syntax-entry ?* ". 23" glusterfs-mode-syntax-table)
+ (modify-syntax-entry ?\n ">#" glusterfs-mode-syntax-table)
+ glusterfs-mode-syntax-table)
+ "Syntax table for glusterfs-mode")
+
+;; TODO: add an indentation table
+
+(defun glusterfs-indent-line ()
+ "Indent current line as GlusterFS code"
+ (interactive)
+ (beginning-of-line)
+ (if (bobp)
+ (indent-line-to 0) ; First line is always non-indented
+ (let ((not-indented t) cur-indent)
+ (if (looking-at "^[ \t]*volume\ ")
+ (progn
+ (save-excursion
+ (forward-line -1)
+ (setq not-indented nil)
+ (setq cur-indent 0))))
+ (if (looking-at "^[ \t]*end-volume")
+ (progn
+ (save-excursion
+ (forward-line -1)
+ (setq cur-indent 0))
+ (if (< cur-indent 0) ; We can't indent past the left margin
+ (setq cur-indent 0)))
+ (save-excursion
+ (while not-indented ; Iterate backwards until we find an indentation hint
+ (progn
+ (setq cur-indent 2) ; Do the actual indenting
+ (setq not-indented nil)))))
+ (if cur-indent
+ (indent-line-to cur-indent)
+ (indent-line-to 0)))))
+
+(defun glusterfs-mode ()
+ (interactive)
+ (kill-all-local-variables)
+ ;; (use-local-map glusterfs-mode-map)
+ (set-syntax-table glusterfs-mode-syntax-table)
+ (set (make-local-variable 'indent-line-function) 'glusterfs-indent-line)
+ (set (make-local-variable 'font-lock-defaults) '(glusterfs-font-lock-keywords))
+ (setq major-mode 'glusterfs-mode)
+ (setq mode-name "GlusterFS")
+ (run-hooks 'glusterfs-mode-hook))
+
+(provide 'glusterfs-mode)
diff --git a/extras/gnfs-loganalyse.py b/extras/gnfs-loganalyse.py
index 71e79b6be4e..6341d007188 100644..100755
--- a/extras/gnfs-loganalyse.py
+++ b/extras/gnfs-loganalyse.py
@@ -10,6 +10,7 @@
"""
+from __future__ import print_function
import os
import string
import sys
@@ -72,7 +73,7 @@ class NFSRequest:
self.replygfid = tokens [gfididx + 1].strip(",")
def dump (self):
- print "ReqLine: " + str(self.calllinecount) + " TimeStamp: " + self.timestamp + ", 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:
@@ -149,7 +150,7 @@ class NFSLogAnalyzer:
return
rcount = len (self.xid_request_map.keys ())
orphancount = len (self.orphan_replies.keys ())
- print "Requests: " + str(rcount) + ", Orphans: " + str(orphancount)
+ print("Requests: " + str(rcount) + ", Orphans: " + str(orphancount))
def dump (self):
self.getStats ()
diff --git a/extras/group-db-workload b/extras/group-db-workload
new file mode 100644
index 00000000000..9334d6fb942
--- /dev/null
+++ b/extras/group-db-workload
@@ -0,0 +1,12 @@
+performance.open-behind=on
+performance.write-behind=off
+performance.stat-prefetch=off
+performance.quick-read=off
+performance.strict-o-direct=on
+performance.read-ahead=off
+performance.io-cache=off
+performance.readdir-ahead=off
+performance.client-io-threads=on
+server.event-threads=4
+client.event-threads=4
+performance.read-after-open=yes
diff --git a/extras/group-distributed-virt b/extras/group-distributed-virt
new file mode 100644
index 00000000000..a960b76c694
--- /dev/null
+++ b/extras/group-distributed-virt
@@ -0,0 +1,10 @@
+performance.quick-read=off
+performance.read-ahead=off
+performance.io-cache=off
+performance.low-prio-threads=32
+network.remote-dio=enable
+features.shard=on
+user.cifs=off
+client.event-threads=4
+server.event-threads=4
+performance.client-io-threads=on
diff --git a/extras/group-gluster-block b/extras/group-gluster-block
new file mode 100644
index 00000000000..1e398019e6b
--- /dev/null
+++ b/extras/group-gluster-block
@@ -0,0 +1,27 @@
+performance.quick-read=off
+performance.read-ahead=off
+performance.io-cache=off
+performance.stat-prefetch=off
+performance.open-behind=off
+performance.readdir-ahead=off
+performance.strict-o-direct=on
+performance.client-io-threads=on
+performance.io-thread-count=32
+performance.high-prio-threads=32
+performance.normal-prio-threads=32
+performance.low-prio-threads=32
+performance.least-prio-threads=4
+client.event-threads=8
+server.event-threads=8
+network.remote-dio=disable
+cluster.eager-lock=enable
+cluster.quorum-type=auto
+cluster.data-self-heal-algorithm=full
+cluster.locking-scheme=granular
+cluster.shd-max-threads=8
+cluster.shd-wait-qlength=10000
+features.shard=on
+features.shard-block-size=64MB
+user.cifs=off
+server.allow-insecure=on
+cluster.choose-local=off
diff --git a/extras/group-metadata-cache b/extras/group-metadata-cache
new file mode 100644
index 00000000000..b890b288fc7
--- /dev/null
+++ b/extras/group-metadata-cache
@@ -0,0 +1,6 @@
+features.cache-invalidation=on
+features.cache-invalidation-timeout=600
+performance.stat-prefetch=on
+performance.cache-invalidation=on
+performance.md-cache-timeout=600
+network.inode-lru-limit=200000
diff --git a/extras/group-nl-cache b/extras/group-nl-cache
new file mode 100644
index 00000000000..897807e8933
--- /dev/null
+++ b/extras/group-nl-cache
@@ -0,0 +1,5 @@
+features.cache-invalidation=on
+features.cache-invalidation-timeout=600
+performance.nl-cache=on
+performance.nl-cache-timeout=600
+network.inode-lru-limit=200000
diff --git a/extras/group-samba b/extras/group-samba
new file mode 100644
index 00000000000..eeee6e06031
--- /dev/null
+++ b/extras/group-samba
@@ -0,0 +1,11 @@
+features.cache-invalidation=on
+features.cache-invalidation-timeout=600
+performance.cache-samba-metadata=on
+performance.stat-prefetch=on
+performance.cache-invalidation=on
+performance.md-cache-timeout=600
+network.inode-lru-limit=200000
+performance.nl-cache=on
+performance.nl-cache-timeout=600
+performance.readdir-ahead=on
+performance.parallel-readdir=on
diff --git a/extras/group-virt.example b/extras/group-virt.example
index 0abe9f400a6..cc37c98a25c 100644
--- a/extras/group-virt.example
+++ b/extras/group-virt.example
@@ -1,8 +1,24 @@
-quick-read=off
-read-ahead=off
-io-cache=off
-stat-prefetch=off
-eager-lock=enable
-remote-dio=enable
-quorum-type=auto
-server-quorum-type=server
+performance.quick-read=off
+performance.read-ahead=off
+performance.io-cache=off
+performance.low-prio-threads=32
+network.remote-dio=disable
+performance.strict-o-direct=on
+cluster.eager-lock=enable
+cluster.quorum-type=auto
+cluster.server-quorum-type=server
+cluster.data-self-heal-algorithm=full
+cluster.locking-scheme=granular
+cluster.shd-max-threads=8
+cluster.shd-wait-qlength=10000
+features.shard=on
+user.cifs=off
+cluster.choose-local=off
+client.event-threads=4
+server.event-threads=4
+performance.client-io-threads=on
+network.ping-timeout=20
+server.tcp-user-timeout=20
+server.keepalive-time=10
+server.keepalive-interval=2
+server.keepalive-count=5
diff --git a/extras/hook-scripts/Makefile.am b/extras/hook-scripts/Makefile.am
index 771b37e3fdf..26059d7dbb9 100644
--- a/extras/hook-scripts/Makefile.am
+++ b/extras/hook-scripts/Makefile.am
@@ -1,5 +1,5 @@
EXTRA_DIST = S40ufo-stop.py S56glusterd-geo-rep-create-post.sh
-SUBDIRS = add-brick set start stop reset
+SUBDIRS = add-brick create delete set start stop reset
scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/gsync-create/post/
if USE_GEOREP
diff --git a/extras/hook-scripts/S40ufo-stop.py b/extras/hook-scripts/S40ufo-stop.py
index 107f1968355..2c79eb1d54a 100755
--- a/extras/hook-scripts/S40ufo-stop.py
+++ b/extras/hook-scripts/S40ufo-stop.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
import os
from optparse import OptionParser
diff --git a/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh b/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh
index 067dd7427da..7d6052315bb 100755
--- a/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh
+++ b/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh
@@ -1,10 +1,14 @@
#!/bin/bash
+#key_val_pair is the arguments passed to the script in the form of
+#key value pair
+
key_val_pair1=`echo $2 | cut -d ',' -f 1`
key_val_pair2=`echo $2 | cut -d ',' -f 2`
key_val_pair3=`echo $2 | cut -d ',' -f 3`
key_val_pair4=`echo $2 | cut -d ',' -f 4`
key_val_pair5=`echo $2 | cut -d ',' -f 5`
+key_val_pair6=`echo $2 | cut -d ',' -f 6`
mastervol=`echo $1 | cut -d '=' -f 2`
if [ "$mastervol" == "" ]; then
@@ -64,17 +68,37 @@ if [ "$val" == "" ]; then
fi
slavevol=`echo $val`
+key=`echo $key_val_pair6 | cut -d '=' -f 1`
+val=`echo $key_val_pair6 | cut -d '=' -f 2`
+if [ "$key" != "ssh_port" ]; then
+ exit;
+fi
+if [ "$val" == "" ]; then
+ exit;
+fi
+SSH_PORT=`echo $val`
+SSH_OPT="-oPasswordAuthentication=no -oStrictHostKeyChecking=no"
+
if [ -f $pub_file ]; then
# For a non-root user copy the pub file to the user's home directory
# For a root user copy the pub files to priv_dir->geo-rep.
if [ "$slave_user" != "root" ]; then
- slave_user_home_dir=`ssh $slave_user@$slave_ip "getent passwd $slave_user | cut -d ':' -f 6"`
- scp $pub_file $slave_user@$slave_ip:$slave_user_home_dir/common_secret.pem.pub_tmp
- ssh $slave_user@$slave_ip "mv $slave_user_home_dir/common_secret.pem.pub_tmp $slave_user_home_dir/${mastervol}_${slavevol}_common_secret.pem.pub"
+ slave_user_home_dir=`ssh -p ${SSH_PORT} ${SSH_OPT} $slave_user@$slave_ip "getent passwd $slave_user | cut -d ':' -f 6"`
+ scp -P ${SSH_PORT} ${SSH_OPT} $pub_file $slave_user@$slave_ip:$slave_user_home_dir/common_secret.pem.pub_tmp
+ ssh -p ${SSH_PORT} ${SSH_OPT} $slave_user@$slave_ip "mv $slave_user_home_dir/common_secret.pem.pub_tmp $slave_user_home_dir/${mastervol}_${slavevol}_common_secret.pem.pub"
else
- scp $pub_file $slave_ip:$pub_file_tmp
- ssh $slave_ip "mv $pub_file_tmp ${pub_file_dname}/${mastervol}_${slavevol}_${pub_file_bname}"
- ssh $slave_ip "gluster system:: copy file /geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null"
- ssh $slave_ip "gluster system:: execute add_secret_pub root geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null"
+ if [[ -z "${GR_SSH_IDENTITY_KEY}" ]]; then
+ scp -P ${SSH_PORT} ${SSH_OPT} $pub_file $slave_ip:$pub_file_tmp
+ ssh -p ${SSH_PORT} ${SSH_OPT} $slave_ip "mv $pub_file_tmp ${pub_file_dname}/${mastervol}_${slavevol}_${pub_file_bname}"
+ ssh -p ${SSH_PORT} ${SSH_OPT} $slave_ip "gluster system:: copy file /geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null"
+ ssh -p ${SSH_PORT} ${SSH_OPT} $slave_ip "gluster system:: execute add_secret_pub root geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null"
+ ssh -p ${SSH_PORT} ${SSH_OPT} $slave_ip "gluster vol set ${slavevol} features.read-only on"
+ else
+ scp -P ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $pub_file $slave_ip:$pub_file_tmp
+ ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $slave_ip "mv $pub_file_tmp ${pub_file_dname}/${mastervol}_${slavevol}_${pub_file_bname}"
+ ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $slave_ip "gluster system:: copy file /geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null"
+ ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $slave_ip "gluster system:: execute add_secret_pub root geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null"
+ ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $slave_ip "gluster vol set ${slavevol} features.read-only on"
+ fi
fi
fi
diff --git a/extras/hook-scripts/add-brick/post/Makefile.am b/extras/hook-scripts/add-brick/post/Makefile.am
index 12f510291a9..9b236df096d 100644
--- a/extras/hook-scripts/add-brick/post/Makefile.am
+++ b/extras/hook-scripts/add-brick/post/Makefile.am
@@ -1 +1,6 @@
-EXTRA_DIST = disabled-quota-root-xattr-heal.sh
+EXTRA_DIST = disabled-quota-root-xattr-heal.sh S10selinux-label-brick.sh S13create-subdir-mounts.sh
+
+hookdir = $(GLUSTERD_WORKDIR)/hooks/1/add-brick/post/
+if WITH_SERVER
+hook_SCRIPTS = disabled-quota-root-xattr-heal.sh S10selinux-label-brick.sh S13create-subdir-mounts.sh
+endif
diff --git a/extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh b/extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh
new file mode 100755
index 00000000000..4a17c993a77
--- /dev/null
+++ b/extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+#
+# Install to hooks/<HOOKS_VER>/add-brick/post
+#
+# Add an SELinux file context for each brick using the glusterd_brick_t type.
+# This ensures that the brick is relabeled correctly on an SELinux restart or
+# restore. Subsequently, run a restore on the brick path to set the selinux
+# labels.
+#
+###
+
+PROGNAME="Sselinux"
+OPTSPEC="volname:,version:,gd-workdir:,volume-op:"
+VOL=
+
+parse_args () {
+ ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@")
+ eval set -- "${ARGS}"
+
+ while true; do
+ case ${1} in
+ --volname)
+ shift
+ VOL=${1}
+ ;;
+ --gd-workdir)
+ shift
+ GLUSTERD_WORKDIR=$1
+ ;;
+ --version)
+ shift
+ ;;
+ --volume-op)
+ shift
+ ;;
+ *)
+ shift
+ break
+ ;;
+ esac
+ shift
+ done
+}
+
+set_brick_labels()
+{
+ local volname="${1}"
+ local fctx
+ local list=()
+
+ fctx="$(semanage fcontext --list -C)"
+
+ # wait for new brick path to be updated under
+ # ${GLUSTERD_WORKDIR}/vols/${volname}/bricks/
+ sleep 5
+
+ # grab the path for each local brick
+ brickpath="${GLUSTERD_WORKDIR}/vols/${volname}/bricks/"
+ brickdirs=$(
+ find "${brickpath}" -type f -exec grep '^path=' {} \; | \
+ cut -d= -f 2 | \
+ sort -u
+ )
+
+ # create a list of bricks for which custom SELinux
+ # label doesn't exist
+ for b in ${brickdirs}; do
+ pattern="${b}(/.*)?"
+ echo "${fctx}" | grep "^${pattern}\s" >/dev/null
+ if [[ $? -ne 0 ]]; then
+ list+=("${pattern}")
+ fi
+ done
+
+ # Add a file context for each brick path in the list and associate with the
+ # glusterd_brick_t SELinux type.
+ for p in ${list[@]}
+ do
+ semanage fcontext --add -t glusterd_brick_t -r s0 "${p}"
+ done
+
+ # Set the labels for which SELinux label was added above
+ for b in ${brickdirs}
+ do
+ echo "${list[@]}" | grep "${b}" >/dev/null
+ if [[ $? -eq 0 ]]; then
+ restorecon -R "${b}"
+ fi
+ done
+}
+
+SELINUX_STATE=$(which getenforce && getenforce)
+[ "${SELINUX_STATE}" = 'Disabled' ] && exit 0
+
+parse_args "$@"
+[ -z "${VOL}" ] && exit 1
+
+set_brick_labels "${VOL}"
+
+exit 0
diff --git a/extras/hook-scripts/add-brick/post/S13create-subdir-mounts.sh b/extras/hook-scripts/add-brick/post/S13create-subdir-mounts.sh
new file mode 100755
index 00000000000..1a6923ee7aa
--- /dev/null
+++ b/extras/hook-scripts/add-brick/post/S13create-subdir-mounts.sh
@@ -0,0 +1,86 @@
+#!/bin/bash
+
+##---------------------------------------------------------------------------
+## This script runs the self-heal of the directories which are expected to
+## be present as they are mounted as subdirectory mounts.
+##---------------------------------------------------------------------------
+
+MOUNT_DIR=`mktemp -d -t ${0##*/}.XXXXXX`;
+OPTSPEC="volname:,version:,gd-workdir:,volume-op:"
+PROGNAME="add-brick-create-subdir"
+VOL_NAME=test
+GLUSTERD_WORKDIR="/var/lib/glusterd"
+
+cleanup_mountpoint ()
+{
+ umount -f $MOUNT_DIR;
+ if [ 0 -ne $? ]
+ then
+ return $?
+ fi
+
+ rmdir $MOUNT_DIR;
+ if [ 0 -ne $? ]
+ then
+ return $?
+ fi
+}
+
+##------------------------------------------
+## Parse the arguments
+##------------------------------------------
+ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@)
+eval set -- "$ARGS"
+
+while true;
+do
+ case $1 in
+ --volname)
+ shift
+ VOL_NAME=$1
+ ;;
+ --gd-workdir)
+ shift
+ GLUSTERD_WORKDIR=$1
+ ;;
+ --version)
+ shift
+ ;;
+ --volume-op)
+ shift
+ ;;
+ *)
+ shift
+ break
+ ;;
+ esac
+ shift
+done
+
+## See if we have any subdirs to be healed before going further
+subdirs=$(grep 'auth.allow' ${GLUSTERD_WORKDIR}/vols/${VOL_NAME}/info | cut -f2 -d'=' | tr ',' '\n' | cut -f1 -d'(');
+
+if [ -z ${subdirs} ]; then
+ rmdir $MOUNT_DIR;
+ exit 0;
+fi
+
+##----------------------------------------
+## Mount the volume in temp directory.
+## -----------------------------------
+glusterfs -s localhost --volfile-id=$VOL_NAME --client-pid=-50 $MOUNT_DIR;
+if [ 0 -ne $? ]
+then
+ exit $?;
+fi
+
+## -----------------------------------
+# Do the 'stat' on all the directory for now. Ideal fix is to look at subdir
+# list from 'auth.allow' option and only stat them.
+for subdir in ${subdirs}
+do
+ stat ${MOUNT_DIR}/${subdir} > /dev/null;
+done
+
+## Clean up and exit
+cleanup_mountpoint;
diff --git a/extras/hook-scripts/add-brick/post/disabled-quota-root-xattr-heal.sh b/extras/hook-scripts/add-brick/post/disabled-quota-root-xattr-heal.sh
index 9e72464d161..ca17a903549 100755
--- a/extras/hook-scripts/add-brick/post/disabled-quota-root-xattr-heal.sh
+++ b/extras/hook-scripts/add-brick/post/disabled-quota-root-xattr-heal.sh
@@ -11,131 +11,135 @@
## 4. Disable itself
##---------------------------------------------------------------------------
-QUOTA_CONFIG_XATTR="trusted.glusterfs.quota.limit-set";
-MOUNT_DIR=`mktemp -d -t ${0##*/}.XXXXXX`;
+QUOTA_LIMIT_XATTR="trusted.glusterfs.quota.limit-set"
+QUOTA_OBJECT_LIMIT_XATTR="trusted.glusterfs.quota.limit-objects"
+MOUNT_DIR=$(mktemp -d -t "${0##*/}.XXXXXX");
OPTSPEC="volname:,version:,gd-workdir:,volume-op:"
PROGNAME="Quota-xattr-heal-add-brick"
VOL_NAME=
VERSION=
VOLUME_OP=
GLUSTERD_WORKDIR=
-ENABLED_NAME="S28Quota-root-xattr-heal.sh"
+ENABLED_NAME_PREFIX="S28"
+ENABLED_NAME="Quota-root-xattr-heal.sh"
+THIS_SCRIPT=$(echo "${0}" | awk -F'/' '{print $NF}')
cleanup_mountpoint ()
{
- umount -f $MOUNT_DIR;
- if [ 0 -ne $? ]
- then
- return $?
- fi
-
- rmdir $MOUNT_DIR;
- if [ 0 -ne $? ]
- then
- return $?
- fi
+
+ if umount -f "${MOUNT_DIR}"; then
+ return $?
+ fi
+
+ if rmdir "${MOUNT_DIR}"; then
+ return $?
+ fi
+}
+
+disable_and_exit ()
+{
+ if [ -e "${ENABLED_STATE}" ]
+ then
+ unlink "${ENABLED_STATE}";
+ exit $?
+ fi
+
+ exit 0
+}
+
+get_and_set_xattr ()
+{
+ XATTR=$1
+
+ VALUE=$(getfattr -n "${XATTR}" -e hex --absolute-names "${MOUNT_DIR}" 2>&1)
+ RET=$?
+ if [ 0 -eq ${RET} ]; then
+ VALUE=$(echo "${VALUE}" | grep "${XATTR}" | awk -F'=' '{print $NF}')
+ setfattr -n "${XATTR}" -v "${VALUE}" "${MOUNT_DIR}";
+ RET=$?
+ else
+ if echo "${VALUE}" | grep -iq "No such attribute" ; then
+ RET=0
+ fi
+ fi
+
+ return ${RET};
}
##------------------------------------------
## Parse the arguments
##------------------------------------------
-ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@)
+ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@")
eval set -- "$ARGS"
while true;
do
- case $1 in
- --volname)
- shift
- VOL_NAME=$1
- ;;
- --version)
- shift
- VERSION=$1
- ;;
- --gd-workdir)
- shift
- GLUSTERD_WORKDIR=$1
- ;;
- --volume-op)
- shift
- VOLUME_OP=$1
- ;;
- *)
- shift
- break
- ;;
- esac
- shift
+ case $1 in
+ --volname)
+ shift
+ VOL_NAME=$1
+ ;;
+ --version)
+ shift
+ VERSION=$1
+ ;;
+ --gd-workdir)
+ shift
+ GLUSTERD_WORKDIR=$1
+ ;;
+ --volume-op)
+ shift
+ VOLUME_OP=$1
+ ;;
+ *)
+ shift
+ break
+ ;;
+ esac
+ shift
done
##----------------------------------------
-ENABLED_STATE="$GLUSTERD_WORKDIR/hooks/$VERSION/$VOLUME_OP/post/$ENABLED_NAME"
+# Avoid long lines
+ENABLED_STATE_1="${GLUSTERD_WORKDIR}/hooks/${VERSION}/${VOLUME_OP}/"
+ENABLED_STATE_2="post/${ENABLED_NAME_PREFIX}${VOL_NAME}-${ENABLED_NAME}"
+ENABLED_STATE="${ENABLED_STATE_1}${ENABLED_STATE_2}"
+if [ "${THIS_SCRIPT}" != *"${VOL_NAME}"* ]; then
+ exit 0
+fi
-FLAG=`gluster volume quota $VOL_NAME list / 2>&1 | grep \
- '\(No quota configured on volume\)\|\(Limit not set\)'`;
-if ! [ -z $FLAG ]
+## Is quota enabled?
+FLAG=$(grep "^features.quota=" "${GLUSTERD_WORKDIR}/vols/${VOL_NAME}/info" \
+| awk -F'=' '{print $NF}');
+if [ "${FLAG}" != "on" ]
then
- ls $ENABLED_STATE;
- RET=$?
- if [ 0 -eq $RET ]
- then
- unlink $ENABLED_STATE;
- exit $?
- fi
-
- exit $RET;
+ disable_and_exit
fi
## -----------------------------------
## Mount the volume in temp directory.
## -----------------------------------
-glusterfs -s localhost --volfile-id=$VOL_NAME --client-pid=-42 $MOUNT_DIR;
-if [ 0 -ne $? ]
-then
- exit $?;
-fi
-## -----------------------------------
+# Avoid long lines
+CMD_1="glusterfs -s localhost"
+CMD_2="--volfile-id=${VOL_NAME} client-pid=-42 ${MOUNT_DIR}"
+CMD="${CMD_1}${CMD_2}"
-## ------------------
-## Getfattr the value
-## ------------------
-VALUE=`getfattr -n "$QUOTA_CONFIG_XATTR" -e hex --absolute-names $MOUNT_DIR \
- 2>&1 | grep $QUOTA_CONFIG_XATTR | awk -F'=' '{print $2}'`
-RET=$?
-if [ 0 -ne $RET ]
+if ${CMD}
then
- ## Clean up and exit
- cleanup_mountpoint;
-
- exit $RET;
+ exit $?;
fi
-## ------------------
-
-## ---------
-## Set xattr
-## ---------
-setfattr -n "$QUOTA_CONFIG_XATTR" -v $VALUE $MOUNT_DIR;
-RET=$?
-if [ 0 -ne $RET ]
-then
- ## Clean up and exit
- cleanup_mountpoint;
+## -----------------------------------
- exit $RET;
-fi
-## ---------
+RET1=$(get_and_set_xattr "${QUOTA_LIMIT_XATTR}")
+RET2=$(get_and_set_xattr "${QUOTA_OBJECT_LIMIT_XATTR}")
+## Clean up and exit
cleanup_mountpoint;
-## Disable
-ls $ENABLED_STATE;
-RET=$?
-if [ 0 -eq $RET ]
-then
- unlink $ENABLED_STATE;
- exit $?
+if [ "${RET1}" -ne 0 ] || [ "${RET2}" -ne 0 ]; then
+ exit 1
fi
-exit $?
+
+disable_and_exit;
diff --git a/extras/hook-scripts/add-brick/pre/Makefile.am b/extras/hook-scripts/add-brick/pre/Makefile.am
index 4d22d3c489b..3288581aa57 100644
--- a/extras/hook-scripts/add-brick/pre/Makefile.am
+++ b/extras/hook-scripts/add-brick/pre/Makefile.am
@@ -1 +1,6 @@
EXTRA_DIST = S28Quota-enable-root-xattr-heal.sh
+
+hookdir = $(GLUSTERD_WORKDIR)/hooks/1/add-brick/pre/
+if WITH_SERVER
+hook_SCRIPTS = S28Quota-enable-root-xattr-heal.sh
+endif
diff --git a/extras/hook-scripts/add-brick/pre/S28Quota-enable-root-xattr-heal.sh b/extras/hook-scripts/add-brick/pre/S28Quota-enable-root-xattr-heal.sh
index 348f34ec3db..27e85231f45 100755
--- a/extras/hook-scripts/add-brick/pre/S28Quota-enable-root-xattr-heal.sh
+++ b/extras/hook-scripts/add-brick/pre/S28Quota-enable-root-xattr-heal.sh
@@ -26,10 +26,11 @@ VOL_NAME=
GLUSTERD_WORKDIR=
VOLUME_OP=
VERSION=
-ENABLED_NAME="S28Quota-root-xattr-heal.sh"
+ENABLED_NAME_PREFIX="S28"
+ENABLED_NAME="Quota-root-xattr-heal.sh"
DISABLED_NAME="disabled-quota-root-xattr-heal.sh"
-enable ()
+activate ()
{
ln -sf $DISABLED_STATE $1;
}
@@ -37,7 +38,7 @@ enable ()
##------------------------------------------
## Parse the arguments
##------------------------------------------
-ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@)
+ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@")
eval set -- "$ARGS"
while true;
@@ -69,8 +70,8 @@ done
##----------------------------------------
DISABLED_STATE="$GLUSTERD_WORKDIR/hooks/$VERSION/add-brick/post/$DISABLED_NAME"
-ENABLED_STATE_START="$GLUSTERD_WORKDIR/hooks/$VERSION/start/post/$ENABLED_NAME"
-ENABLED_STATE_ADD_BRICK="$GLUSTERD_WORKDIR/hooks/$VERSION/add-brick/post/$ENABLED_NAME";
+ENABLED_STATE_START="$GLUSTERD_WORKDIR/hooks/$VERSION/start/post/""$ENABLED_NAME_PREFIX$VOL_NAME""-""$ENABLED_NAME"
+ENABLED_STATE_ADD_BRICK="$GLUSTERD_WORKDIR/hooks/$VERSION/add-brick/post/""$ENABLED_NAME_PREFIX""$VOL_NAME""-""$ENABLED_NAME";
## Why to proceed if the required script itself is not present?
ls $DISABLED_STATE;
@@ -92,9 +93,9 @@ FLAG=`cat $GLUSTERD_WORKDIR/vols/$VOL_NAME/info | grep "^status=" \
| awk -F'=' '{print $NF}'`;
if [ "$FLAG" != "1" ]
then
- enable $ENABLED_STATE_START;
+ activate $ENABLED_STATE_START;
exit $?
fi
-enable $ENABLED_STATE_ADD_BRICK;
+activate $ENABLED_STATE_ADD_BRICK;
exit $?
diff --git a/extras/hook-scripts/create/Makefile.am b/extras/hook-scripts/create/Makefile.am
new file mode 100644
index 00000000000..b083a9145d6
--- /dev/null
+++ b/extras/hook-scripts/create/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = post
diff --git a/extras/hook-scripts/create/post/Makefile.am b/extras/hook-scripts/create/post/Makefile.am
new file mode 100644
index 00000000000..fd1892e9589
--- /dev/null
+++ b/extras/hook-scripts/create/post/Makefile.am
@@ -0,0 +1,8 @@
+EXTRA_DIST = S10selinux-label-brick.sh
+
+scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/create/post/
+if WITH_SERVER
+if USE_SELINUX
+scripts_SCRIPTS = S10selinux-label-brick.sh
+endif
+endif
diff --git a/extras/hook-scripts/create/post/S10selinux-label-brick.sh b/extras/hook-scripts/create/post/S10selinux-label-brick.sh
new file mode 100755
index 00000000000..f9b4b1a57e3
--- /dev/null
+++ b/extras/hook-scripts/create/post/S10selinux-label-brick.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+#
+# Install to hooks/<HOOKS_VER>/create/post
+#
+# Add an SELinux file context for each brick using the glusterd_brick_t type.
+# This ensures that the brick is relabeled correctly on an SELinux restart or
+# restore. Subsequently, run a restore on the brick path to set the selinux
+# labels.
+#
+###
+
+PROGNAME="Sselinux"
+OPTSPEC="volname:"
+VOL=
+
+parse_args () {
+ ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@")
+ eval set -- "${ARGS}"
+
+ while true; do
+ case ${1} in
+ --volname)
+ shift
+ VOL=${1}
+ ;;
+ *)
+ shift
+ break
+ ;;
+ esac
+ shift
+ done
+}
+
+set_brick_labels()
+{
+ volname="${1}"
+
+ # grab the path for each local brick
+ brickpath="/var/lib/glusterd/vols/${volname}/bricks/"
+ brickdirs=$(
+ find "${brickpath}" -type f -exec grep '^path=' {} \; | \
+ cut -d= -f 2 | \
+ sort -u
+ )
+
+ for b in ${brickdirs}; do
+ # Add a file context for each brick path and associate with the
+ # glusterd_brick_t SELinux type.
+ pattern="${b}(/.*)?"
+ semanage fcontext --add -t glusterd_brick_t -r s0 "${pattern}"
+ # Set the labels on the new brick path.
+ restorecon -R "${b}"
+ done
+}
+
+SELINUX_STATE=$(which getenforce && getenforce)
+[ "${SELINUX_STATE}" = 'Disabled' ] && exit 0
+
+parse_args "$@"
+[ -z "${VOL}" ] && exit 1
+
+set_brick_labels "${VOL}"
+
+exit 0
diff --git a/extras/hook-scripts/delete/Makefile.am b/extras/hook-scripts/delete/Makefile.am
new file mode 100644
index 00000000000..c98a05d9205
--- /dev/null
+++ b/extras/hook-scripts/delete/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = pre
diff --git a/extras/hook-scripts/delete/pre/Makefile.am b/extras/hook-scripts/delete/pre/Makefile.am
new file mode 100644
index 00000000000..4fbfbe7311f
--- /dev/null
+++ b/extras/hook-scripts/delete/pre/Makefile.am
@@ -0,0 +1,8 @@
+EXTRA_DIST = S10selinux-del-fcontext.sh
+
+scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/delete/pre/
+if WITH_SERVER
+if USE_SELINUX
+scripts_SCRIPTS = S10selinux-del-fcontext.sh
+endif
+endif
diff --git a/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh b/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh
new file mode 100755
index 00000000000..056b52afe76
--- /dev/null
+++ b/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+#
+# Install to hooks/<HOOKS_VER>/delete/pre
+#
+# Delete the file context associated with the brick path on volume deletion. The
+# associated file context was added during volume creation.
+#
+# We do not explicitly relabel the brick, as this could be time consuming and
+# unnecessary.
+#
+###
+
+PROGNAME="Sselinux"
+OPTSPEC="volname:"
+VOL=
+
+function parse_args () {
+ ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@")
+ eval set -- "${ARGS}"
+
+ while true; do
+ case ${1} in
+ --volname)
+ shift
+ VOL=${1}
+ ;;
+ *)
+ shift
+ break
+ ;;
+ esac
+ shift
+ done
+}
+
+function delete_brick_fcontext()
+{
+ local volname=$1
+ local fctx
+ local list=()
+
+ fctx="$(semanage fcontext --list -C)"
+ # grab the path for each local brick
+ brickpath="/var/lib/glusterd/vols/${volname}/bricks/"
+ brickdirs=$(find "${brickpath}" -type f -exec grep '^path=' {} \; | \
+ cut -d= -f 2 | sort -u)
+ for b in ${brickdirs}
+ do
+ pattern="${b}(/.*)?"
+ echo "${fctx}" | grep "^${pattern}\s" >/dev/null
+ if [[ $? -eq 0 ]]; then
+ list+=("${pattern}")
+ fi
+ done
+ if [[ ${#list[@]} -gt 0 ]]; then
+ printf 'fcontext --delete %s\n' "${list[@]}" | semanage -i -
+ fi
+ for b in ${brickdirs}
+ do
+ restorecon -R "${b}"
+ done
+}
+
+SELINUX_STATE=$(which getenforce && getenforce)
+[ "${SELINUX_STATE}" = 'Disabled' ] && exit 0
+
+parse_args "$@"
+[ -z "${VOL}" ] && exit 1
+
+delete_brick_fcontext "${VOL}"
+
+# failure to delete the fcontext is not fatal
+exit 0
diff --git a/extras/hook-scripts/reset/post/Makefile.am b/extras/hook-scripts/reset/post/Makefile.am
index fcdd8ab55ba..1b336ac1a85 100644
--- a/extras/hook-scripts/reset/post/Makefile.am
+++ b/extras/hook-scripts/reset/post/Makefile.am
@@ -1 +1 @@
-EXTRA_DIST = S31ganesha-reset.sh
+EXTRA_DIST =
diff --git a/extras/hook-scripts/reset/post/S31ganesha-reset.sh b/extras/hook-scripts/reset/post/S31ganesha-reset.sh
deleted file mode 100755
index 8191d960592..00000000000
--- a/extras/hook-scripts/reset/post/S31ganesha-reset.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#/bin/bash
-PROGNAME="Sganesha-reset"
-OPTSPEC="volname:,gd-workdir:"
-VOL=
-GLUSTERD_WORKDIR=
-
-function parse_args () {
- ARGS=$(getopt -l $OPTSPEC -o "o" -name $PROGNAME $@)
- eval set -- "$ARGS"
- while true; do
- case $1 in
- --volname)
- shift
- VOL=$1
- ;;
- --gd-workdir)
- shift
- GLUSTERD_WORKDIR=$1
- ;;
- *)
- shift
- break
- ;;
- esac
- shift
- done
-}
-
-function is_volume_started () {
- volname=$1
- echo "$(grep status $GLUSTERD_WORKDIR/vols/"$volname"/info |\
- cut -d"=" -f2)"
-}
-
-parse_args $@
-if ps aux | grep -q "[g]anesha.nfsd"
- then
- kill -s TERM `cat /var/run/ganesha.pid`
- sleep 10
- rm -rf /var/lib/glusterfs-ganesha/exports
- rm -rf /var/lib/glusterfs-ganesha/.export_added
- sed -i /conf/d /var/lib/ganesha/nfs-ganesha.conf
- if [ "1" = $(is_volume_started "$VOL") ];
- then
- gluster volume start $VOL force
- fi
-fi
diff --git a/extras/hook-scripts/set/post/Makefile.am b/extras/hook-scripts/set/post/Makefile.am
index db86bc2eb51..506a25a8666 100644
--- a/extras/hook-scripts/set/post/Makefile.am
+++ b/extras/hook-scripts/set/post/Makefile.am
@@ -1 +1,6 @@
EXTRA_DIST = S30samba-set.sh S32gluster_enable_shared_storage.sh
+
+hookdir = $(GLUSTERD_WORKDIR)/hooks/1/set/post/
+if WITH_SERVER
+hook_SCRIPTS = $(EXTRA_DIST)
+endif
diff --git a/extras/hook-scripts/set/post/S30samba-set.sh b/extras/hook-scripts/set/post/S30samba-set.sh
index b8c5acf4cde..854f131f6c8 100755
--- a/extras/hook-scripts/set/post/S30samba-set.sh
+++ b/extras/hook-scripts/set/post/S30samba-set.sh
@@ -28,7 +28,7 @@ USERSMB_SET=""
USERCIFS_SET=""
function parse_args () {
- ARGS=$(getopt -l $OPTSPEC -o "o" -name $PROGNAME $@)
+ ARGS=$(getopt -o 'o:' -l $OPTSPEC -n $PROGNAME -- "$@")
eval set -- "$ARGS"
while true; do
@@ -41,10 +41,13 @@ function parse_args () {
shift
GLUSTERD_WORKDIR=$1
;;
- *)
+ --)
shift
- for pair in $@; do
- read key value < <(echo "$pair" | tr "=" " ")
+ break
+ ;;
+ -o)
+ shift
+ read key value < <(echo "$1" | tr "=" " ")
case "$key" in
"user.cifs")
USERCIFS_SET="YES"
@@ -55,7 +58,8 @@ function parse_args () {
*)
;;
esac
- done
+ ;;
+ *)
shift
break
;;
@@ -85,7 +89,7 @@ function add_samba_share () {
STRING+="glusterfs:loglevel = 7\n"
STRING+="path = /\n"
STRING+="read only = no\n"
- STRING+="guest ok = yes\n"
+ STRING+="kernel share modes = no\n"
printf "$STRING" >> ${CONFIGFILE}
}
@@ -95,13 +99,13 @@ function sighup_samba () {
then
kill -HUP "$pid";
else
- /etc/init.d/smb condrestart
+ service smb condrestart
fi
}
-function del_samba_share () {
+function deactivate_samba_share () {
volname=$1
- sed -i "/\[gluster-$volname\]/,/^$/d" ${CONFIGFILE}
+ sed -i -e '/^\[gluster-'"$volname"'\]/{ :a' -e 'n; /available = no/H; /^$/!{$!ba;}; x; /./!{ s/^/available = no/; $!{G;x}; $H; }; s/.*//; x; };' ${CONFIGFILE}
}
function is_volume_started () {
@@ -119,29 +123,39 @@ function get_smb () {
usersmbvalue=$(grep user.smb $GLUSTERD_WORKDIR/vols/"$volname"/info |\
cut -d"=" -f2)
- if [[ $usercifsvalue = "disable" || $usersmbvalue = "disable" ]]; then
- uservalue="disable"
+ if [ -n "$usercifsvalue" ]; then
+ if [ "$usercifsvalue" = "disable" ] || [ "$usercifsvalue" = "off" ]; then
+ uservalue="disable"
+ fi
+ fi
+
+ if [ -n "$usersmbvalue" ]; then
+ if [ "$usersmbvalue" = "disable" ] || [ "$usersmbvalue" = "off" ]; then
+ uservalue="disable"
+ fi
fi
+
echo "$uservalue"
}
-parse_args $@
-if [ "0" = $(is_volume_started "$VOL") ]; then
+parse_args "$@"
+if [ "0" = "$(is_volume_started "$VOL")" ]; then
exit 0
fi
-if [[ "$USERCIFS_SET" = "YES" || "$USERSMB_SET" = "YES" ]]; then
+if [ "$USERCIFS_SET" = "YES" ] || [ "$USERSMB_SET" = "YES" ]; then
#Find smb.conf, smbd pid directory and smbd logfile path
find_config_info
- if [ $(get_smb "$VOL") = "disable" ]; then
- del_samba_share $VOL
- sighup_samba
+ if [ "$(get_smb "$VOL")" = "disable" ]; then
+ deactivate_samba_share $VOL
else
if ! grep --quiet "\[gluster-$VOL\]" ${CONFIGFILE} ; then
add_samba_share $VOL
- sighup_samba
+ else
+ sed -i '/\[gluster-'"$VOL"'\]/,/^$/!b;/available = no/d' ${CONFIGFILE}
fi
fi
+ sighup_samba
fi
diff --git a/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh b/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh
index ad51babd5f7..1f2564b44ff 100755
--- a/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh
+++ b/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh
@@ -2,7 +2,7 @@
key=`echo $3 | cut -d '=' -f 1`
val=`echo $3 | cut -d '=' -f 2`
-if [ ! "$key" -eq "enable-shared-storage" -o "$key" -eq "cluster.enable-shared-storage" ]; then
+if [ "$key" != "cluster.enable-shared-storage" ] && [ "$key" != "enable-shared-storage" ]; then
exit;
fi
if [ "$val" != 'enable' ]; then
@@ -79,9 +79,9 @@ done
if [ "$option" == "disable" ]; then
# Unmount the volume on all the nodes
- umount /var/run/gluster/shared_storage
- cat /etc/fstab | grep -v "gluster_shared_storage /var/run/gluster/shared_storage/" > /var/run/gluster/fstab.tmp
- mv /var/run/gluster/fstab.tmp /etc/fstab
+ umount /run/gluster/shared_storage
+ cat /etc/fstab | grep -v "gluster_shared_storage /run/gluster/shared_storage/" > /run/gluster/fstab.tmp
+ mv /run/gluster/fstab.tmp /etc/fstab
fi
if [ "$is_originator" == 1 ]; then
@@ -104,8 +104,15 @@ function check_volume_status()
echo $status
}
-mount_cmd="mount -t glusterfs "$local_node_hostname":/gluster_shared_storage \
- /var/run/gluster/shared_storage"
+key=`echo $5 | cut -d '=' -f 1`
+val=`echo $5 | cut -d '=' -f 2`
+if [ "$key" == "transport.address-family" ]; then
+ mount_cmd="mount -t glusterfs -o xlator-option=transport.address-family=inet6 \
+ $local_node_hostname:/gluster_shared_storage /run/gluster/shared_storage"
+else
+ mount_cmd="mount -t glusterfs $local_node_hostname:/gluster_shared_storage \
+ /run/gluster/shared_storage"
+fi
if [ "$option" == "enable" ]; then
retry=0;
@@ -117,13 +124,13 @@ if [ "$option" == "enable" ]; then
if [ "$retry" == 3 ]; then
break;
fi
- status = check_volume_status;
+ status=$(check_volume_status)
done
# Mount the volume on all the nodes
- umount /var/run/gluster/shared_storage
- mkdir -p /var/run/gluster/shared_storage
+ umount /run/gluster/shared_storage
+ mkdir -p /run/gluster/shared_storage
$mount_cmd
- cp /etc/fstab /var/run/gluster/fstab.tmp
- echo "$local_node_hostname:/gluster_shared_storage /var/run/gluster/shared_storage/ glusterfs defaults 0 0" >> /var/run/gluster/fstab.tmp
- mv /var/run/gluster/fstab.tmp /etc/fstab
+ cp /etc/fstab /run/gluster/fstab.tmp
+ echo "$local_node_hostname:/gluster_shared_storage /run/gluster/shared_storage/ glusterfs defaults 0 0" >> /run/gluster/fstab.tmp
+ mv /run/gluster/fstab.tmp /etc/fstab
fi
diff --git a/extras/hook-scripts/start/post/Makefile.am b/extras/hook-scripts/start/post/Makefile.am
index ad53233b1c9..792019d3c9f 100644
--- a/extras/hook-scripts/start/post/Makefile.am
+++ b/extras/hook-scripts/start/post/Makefile.am
@@ -1 +1,6 @@
EXTRA_DIST = S29CTDBsetup.sh S30samba-start.sh S31ganesha-start.sh
+
+hookdir = $(GLUSTERD_WORKDIR)/hooks/1/start/post/
+if WITH_SERVER
+hook_SCRIPTS = $(EXTRA_DIST)
+endif
diff --git a/extras/hook-scripts/start/post/S29CTDBsetup.sh b/extras/hook-scripts/start/post/S29CTDBsetup.sh
index cbb76767eb9..69a0d89a3eb 100755
--- a/extras/hook-scripts/start/post/S29CTDBsetup.sh
+++ b/extras/hook-scripts/start/post/S29CTDBsetup.sh
@@ -1,21 +1,22 @@
#! /bin/bash
-# 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
+# Make sure ping-timeout is not default for CTDB volume
PING_TIMEOUT_SECS=10
PROGNAME="ctdb"
-OPTSPEC="volname:"
+OPTSPEC="volname:,gd-workdir:,version:,volume-op:,first:"
HOSTNAME=`hostname`
-MNTOPTS="_netdev,defaults"
-MNTOPTS_GLUSTERFS="transport=tcp,xlator-option=*client*.ping-timeout=${PING_TIMEOUT_SECS}"
+MNTOPTS="_netdev,transport=tcp,xlator-option=*client*.ping-timeout=${PING_TIMEOUT_SECS}"
VOL=
+GLUSTERD_WORKDIR=
+VERSION=
+VOLUME_OP=
+FIRST=
# $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)
@@ -24,7 +25,7 @@ VOL=
META="all"
function parse_args () {
- ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@)
+ ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@")
eval set -- "$ARGS"
while true; do
@@ -32,33 +33,37 @@ function parse_args () {
--volname)
shift
VOL=$1
- ;;
-
+ ;;
+ --gd-workdir)
+ shift
+ GLUSTERD_WORKDIR=$1
+ ;;
+ --version)
+ shift
+ VERSION=$1
+ ;;
+ --volume-op)
+ shift
+ VOLUME_OP=$1
+ ;;
+ --first)
+ shift
+ FIRST=$1
+ ;;
*)
- shift
- break
- ;;
-
+ 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"
- exists=`grep "clustering = yes" "$SMB_CONF"`
- if [ "$exists" == "" ]
- then
- sed -i /"$PAT"/i\ "$GLUSTER_CTDB_CONFIG" "$SMB_CONF"
- fi
-}
-
function add_fstab_entry () {
volname=$1
mntpt=$2
- mntopts="${MNTOPTS},${MNTOPTS_GLUSTERFS}"
+ mntopts="${MNTOPTS}"
mntent="${HOSTNAME}:/${volname} ${mntpt} glusterfs ${mntopts} 0 0"
exists=`grep "${mntpt}" /etc/fstab`
@@ -68,16 +73,12 @@ function add_fstab_entry () {
fi
}
-parse_args $@
+parse_args "$@"
if [ "$META" = "$VOL" ]
then
- # expects ctdb service to manage smb
- service smb stop
- add_glusterfs_ctdb_options
mkdir -p $CTDB_MNT
sleep 5
- # Make sure ping-timeout is not default for CTDB volume
- mount -t glusterfs -oxlator-option=*client*.ping-timeout=${PING_TIMEOUT_SECS} `hostname`:$VOL "$CTDB_MNT" && \
+ mount -t glusterfs -o${MNTOPTS} ${HOSTNAME}:/$VOL "$CTDB_MNT" && \
add_fstab_entry $VOL $CTDB_MNT
chkconfig ctdb on
fi
diff --git a/extras/hook-scripts/start/post/S30samba-start.sh b/extras/hook-scripts/start/post/S30samba-start.sh
index 43dc8e108da..cac0cbf1464 100755
--- a/extras/hook-scripts/start/post/S30samba-start.sh
+++ b/extras/hook-scripts/start/post/S30samba-start.sh
@@ -21,15 +21,18 @@
#volume.
PROGNAME="Ssamba-start"
-OPTSPEC="volname:,gd-workdir:"
+OPTSPEC="volname:,gd-workdir:,version:,volume-op:,first:"
VOL=
CONFIGFILE=
LOGFILEBASE=
PIDDIR=
GLUSTERD_WORKDIR=
+VERSION=
+VOLUME_OP=
+FIRST=
function parse_args () {
- ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@)
+ ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@")
eval set -- "$ARGS"
while true; do
@@ -42,24 +45,37 @@ function parse_args () {
shift
GLUSTERD_WORKDIR=$1
;;
+ --version)
+ shift
+ VERSION=$1
+ ;;
+ --volume-op)
+ shift
+ VOLUME_OP=$1
+ ;;
+ --first)
+ shift
+ FIRST=$1
+ ;;
*)
shift
break
;;
esac
+
shift
done
}
function find_config_info () {
- cmdout=`smbd -b | grep smb.conf`
- if [ $? -ne 0 ];then
+ cmdout=$(smbd -b 2> /dev/null)
+ CONFIGFILE=$(echo "$cmdout" | grep CONFIGFILE | awk '{print $2}')
+ if [ -z "$CONFIGFILE" ]; then
echo "Samba is not installed"
exit 1
fi
- CONFIGFILE=`echo $cmdout | awk {'print $2'}`
- PIDDIR=`smbd -b | grep PIDDIR | awk {'print $2'}`
- LOGFILEBASE=`smbd -b | grep 'LOGFILEBASE' | awk '{print $2}'`
+ PIDDIR=$(echo "$cmdout" | grep PIDDIR | awk '{print $2}')
+ LOGFILEBASE=$(echo "$cmdout" | grep 'LOGFILEBASE' | awk '{print $2}')
}
function add_samba_share () {
@@ -72,17 +88,17 @@ function add_samba_share () {
STRING+="glusterfs:loglevel = 7\n"
STRING+="path = /\n"
STRING+="read only = no\n"
- STRING+="guest ok = yes\n"
- printf "$STRING" >> ${CONFIGFILE}
+ STRING+="kernel share modes = no\n"
+ printf "$STRING" >> "${CONFIGFILE}"
}
function sighup_samba () {
- pid=`cat ${PIDDIR}/smbd.pid`
+ pid=$(cat "${PIDDIR}/smbd.pid" 2> /dev/null)
if [ "x$pid" != "x" ]
then
kill -HUP "$pid";
else
- /etc/init.d/smb condrestart
+ service smb condrestart
fi
}
@@ -90,26 +106,40 @@ function get_smb () {
volname=$1
uservalue=
- usercifsvalue=$(grep user.cifs $GLUSTERD_WORKDIR/vols/"$volname"/info |\
+ usercifsvalue=$(grep user.cifs "$GLUSTERD_WORKDIR"/vols/"$volname"/info |\
cut -d"=" -f2)
- usersmbvalue=$(grep user.smb $GLUSTERD_WORKDIR/vols/"$volname"/info |\
+ usersmbvalue=$(grep user.smb "$GLUSTERD_WORKDIR"/vols/"$volname"/info |\
cut -d"=" -f2)
- if [[ $usercifsvalue = "disable" || $usersmbvalue = "disable" ]]; then
- uservalue="disable"
+ if [ -n "$usercifsvalue" ]; then
+ if [ "$usercifsvalue" = "enable" ] || [ "$usercifsvalue" = "on" ]; then
+ uservalue="enable"
+ fi
+ fi
+
+ if [ -n "$usersmbvalue" ]; then
+ if [ "$usersmbvalue" = "enable" ] || [ "$usersmbvalue" = "on" ]; then
+ uservalue="enable"
+ fi
fi
+
echo "$uservalue"
}
-parse_args $@
-if [ $(get_smb "$VOL") = "disable" ]; then
+parse_args "$@"
+
+value=$(get_smb "$VOL")
+
+if [ -z "$value" ] || [ "$value" != "enable" ]; then
exit 0
fi
#Find smb.conf, smbd pid directory and smbd logfile path
find_config_info
-if ! grep --quiet "\[gluster-$VOL\]" ${CONFIGFILE} ; then
- add_samba_share $VOL
- sighup_samba
+if ! grep --quiet "\[gluster-$VOL\]" "${CONFIGFILE}" ; then
+ add_samba_share "$VOL"
+else
+ sed -i '/\[gluster-'"$VOL"'\]/,/^$/!b;/available = no/d' "${CONFIGFILE}"
fi
+sighup_samba
diff --git a/extras/hook-scripts/start/post/S31ganesha-start.sh b/extras/hook-scripts/start/post/S31ganesha-start.sh
index a657b00055f..7ad6f23ad06 100755
--- a/extras/hook-scripts/start/post/S31ganesha-start.sh
+++ b/extras/hook-scripts/start/post/S31ganesha-start.sh
@@ -4,7 +4,7 @@ OPTSPEC="volname:,gd-workdir:"
VOL=
declare -i EXPORT_ID
ganesha_key="ganesha.enable"
-GANESHA_DIR="/etc/ganesha"
+GANESHA_DIR="/run/gluster/shared_storage/nfs-ganesha"
CONF1="$GANESHA_DIR/ganesha.conf"
GLUSTERD_WORKDIR=
@@ -60,63 +60,63 @@ echo " SecType = \"sys\";"
echo "}"
}
-#This function keeps track of export IDs and increments it with every new entry
+#It adds the export dynamically by sending dbus signals
function export_add()
{
- count=`ls -l $GANESHA_DIR/exports/*.conf | wc -l`
- if [ "$count" = "1" ] ;
- then
- EXPORT_ID=2
- else
- #if [ -s /var/lib/ganesha/export_removed ];
- # then
- # EXPORT_ID=`head -1 /var/lib/ganesha/export_removed`
- # sed -i -e "1d" /var/lib/ganesha/export_removed
- # else
-
- EXPORT_ID=`cat $GANESHA_DIR/.export_added`
- EXPORT_ID=EXPORT_ID+1
- #fi
- fi
- echo $EXPORT_ID > $GANESHA_DIR/.export_added
- sed -i s/Export_Id.*/"Export_Id= $EXPORT_ID ;"/ \
-$GANESHA_DIR/exports/export.$VOL.conf
- echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF1
+ dbus-send --print-reply --system --dest=org.ganesha.nfsd \
+/org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.AddExport \
+string:$GANESHA_DIR/exports/export.$VOL.conf string:"EXPORT(Export_Id=$EXPORT_ID)"
+
}
-#This function adds a new export dynamically by sending dbus signals
-function dynamic_export_add()
+# based on src/scripts/ganeshactl/Ganesha/export_mgr.py
+function is_exported()
{
- dbus-send --print-reply --system --dest=org.ganesha.nfsd \
-/org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.AddExport \
-string:$GANESHA_DIR/exports/export.$VOL.conf string:"EXPORT(Path=/$VOL)"
+ local volume="${1}"
+
+ dbus-send --type=method_call --print-reply --system \
+ --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \
+ org.ganesha.nfsd.exportmgr.ShowExports \
+ | grep -w -q "/${volume}"
+ return $?
}
-function start_ganesha()
+# Check the info file (contains the volume options) to see if Ganesha is
+# enabled for this volume.
+function ganesha_enabled()
{
- #Remove export entry from nfs-ganesha.conf
- sed -i /$VOL.conf/d $CONF1
- #Create a new export entry
- export_add $VOL
- dynamic_export_add $VOL
+ local volume="${1}"
+ local info_file="${GLUSTERD_WORKDIR}/vols/${VOL}/info"
+ local enabled="off"
+
+ enabled=$(grep -w ${ganesha_key} ${info_file} | cut -d"=" -f2)
+ [ "${enabled}" == "on" ]
+
+ return $?
}
- parse_args $@
- is_exported="no"
- if showmount -e localhost | cut -d "" -f1 | grep -q "/$VOL[[:space:]]"
- then
- is_exported="yes"
- fi
- ganesha_value=$(grep $ganesha_key $GLUSTERD_WORKDIR/vols/$VOL/info |\
- cut -d"=" -f2)
- if [ "$ganesha_value" = "on" -a "$is_exported" = "no" ]
+parse_args $@
+
+if ganesha_enabled ${VOL} && ! is_exported ${VOL}
+then
+ if [ ! -e ${GANESHA_DIR}/exports/export.${VOL}.conf ]
then
- write_conf $VOL > $GANESHA_DIR/exports/export.$VOL.conf
- start_ganesha $VOL
+ #Remove export entry from nfs-ganesha.conf
+ sed -i /$VOL.conf/d $CONF1
+ write_conf ${VOL} > ${GANESHA_DIR}/exports/export.${VOL}.conf
+ EXPORT_ID=`cat $GANESHA_DIR/.export_added`
+ EXPORT_ID=EXPORT_ID+1
+ echo $EXPORT_ID > $GANESHA_DIR/.export_added
+ sed -i s/Export_Id.*/"Export_Id=$EXPORT_ID;"/ \
+ $GANESHA_DIR/exports/export.$VOL.conf
+ echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF1
else
- exit 0
+ EXPORT_ID=$(grep ^[[:space:]]*Export_Id $GANESHA_DIR/exports/export.$VOL.conf |\
+ awk -F"[=,;]" '{print $2}' | tr -d '[[:space:]]')
fi
+ export_add $VOL
+fi
-
+exit 0
diff --git a/extras/hook-scripts/stop/pre/Makefile.am b/extras/hook-scripts/stop/pre/Makefile.am
index 85243adbec9..9e8d1565e93 100644
--- a/extras/hook-scripts/stop/pre/Makefile.am
+++ b/extras/hook-scripts/stop/pre/Makefile.am
@@ -1 +1,6 @@
EXTRA_DIST = S29CTDB-teardown.sh S30samba-stop.sh
+
+hookdir = $(GLUSTERD_WORKDIR)/hooks/1/stop/pre/
+if WITH_SERVER
+hook_SCRIPTS = $(EXTRA_DIST)
+endif
diff --git a/extras/hook-scripts/stop/pre/S29CTDB-teardown.sh b/extras/hook-scripts/stop/pre/S29CTDB-teardown.sh
index 9125030bb7e..0975a00f18d 100755
--- a/extras/hook-scripts/stop/pre/S29CTDB-teardown.sh
+++ b/extras/hook-scripts/stop/pre/S29CTDB-teardown.sh
@@ -1,11 +1,10 @@
#! /bin/bash
-#non-portable - RHS-2.0 only
-SMB_CONF=/etc/samba/smb.conf
CTDB_MNT=/gluster/lock
PROGNAME="ctdb"
-OPTSPEC="volname:"
+OPTSPEC="volname:,last:"
VOL=
+LAST=
# $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)
@@ -13,18 +12,8 @@ VOL=
# 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 $@)
+ ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@")
eval set -- "$ARGS"
while true; do
@@ -32,31 +21,21 @@ function parse_args () {
--volname)
shift
VOL=$1
- ;;
-
+ ;;
+ --last)
+ shift
+ LAST=$1
+ ;;
*)
- shift
- break
- ;;
-
+ shift
+ break
+ ;;
esac
-
shift
done
}
-function remove_ctdb_options () {
- IFS=$'\n'
- GLUSTER_CTDB_CONFIG=$'# ctdb config for glusterfs\n\tclustering = yes\n\tidmap backend = tdb2\n'
-
- for line in $GLUSTER_CTDB_CONFIG
- do
- sed -i /"$line"/d $SMB_CONF
- done
- unset IFS
-}
-
function remove_fstab_entry () {
mntpt=$1
fstab="/etc/fstab"
@@ -74,12 +53,10 @@ function remove_fstab_entry () {
fi
}
-parse_args $@
+parse_args "$@"
if [ "$META" = "$VOL" ]
then
umount "$CTDB_MNT"
chkconfig ctdb off
remove_fstab_entry $CTDB_MNT
- remove_ctdb_options
- sighup_samba
fi
diff --git a/extras/hook-scripts/stop/pre/S30samba-stop.sh b/extras/hook-scripts/stop/pre/S30samba-stop.sh
index 8950eea436e..ea799381d62 100755
--- a/extras/hook-scripts/stop/pre/S30samba-stop.sh
+++ b/extras/hook-scripts/stop/pre/S30samba-stop.sh
@@ -16,27 +16,33 @@
#event by removing the volume related entries(if any) in smb.conf file.
PROGNAME="Ssamba-stop"
-OPTSPEC="volname:"
+OPTSPEC="volname:,last:"
VOL=
CONFIGFILE=
PIDDIR=
+LAST=
function parse_args () {
- ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@)
+ ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@")
eval set -- "$ARGS"
while true; do
- case $1 in
- --volname)
- shift
- VOL=$1
- ;;
- *)
- shift
- break
- ;;
- esac
- shift
+ case $1 in
+ --volname)
+ shift
+ VOL=$1
+ ;;
+ --last)
+ shift
+ LAST=$1
+ ;;
+ *)
+ shift
+ break
+ ;;
+ esac
+
+ shift
done
}
@@ -46,13 +52,13 @@ function find_config_info () {
echo "Samba is not installed"
exit 1
fi
- CONFIGFILE=`echo $cmdout | awk {'print $2'}`
- PIDDIR=`smbd -b | grep PIDDIR | awk {'print $2'}`
+ CONFIGFILE=`echo $cmdout | awk '{print $2}'`
+ PIDDIR=`smbd -b | grep PIDDIR | awk '{print $2}'`
}
-function del_samba_share () {
+function deactivate_samba_share () {
volname=$1
- sed -i "/\[gluster-$volname\]/,/^$/d" ${CONFIGFILE}
+ sed -i -e '/^\[gluster-'"$volname"'\]/{ :a' -e 'n; /available = no/H; /^$/!{$!ba;}; x; /./!{ s/^/available = no/; $!{G;x}; $H; }; s/.*//; x; };' ${CONFIGFILE}
}
function sighup_samba () {
@@ -61,11 +67,11 @@ function sighup_samba () {
then
kill -HUP $pid;
else
- /etc/init.d/smb condrestart
+ service smb condrestart
fi
}
-parse_args $@
+parse_args "$@"
find_config_info
-del_samba_share $VOL
+deactivate_samba_share $VOL
sighup_samba
diff --git a/extras/identify-hangs.sh b/extras/identify-hangs.sh
new file mode 100755
index 00000000000..ebc6bf144aa
--- /dev/null
+++ b/extras/identify-hangs.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+function get_statedump_fnames_without_timestamps
+{
+ ls | grep -E "[.]dump[.][0-9][0-9]*" | cut -f1-3 -d'.' | sort -u
+}
+
+function get_non_uniq_fields
+{
+ local statedump_fname_prefix=$1
+ print_stack_lkowner_unique_in_one_line "$statedump_fname_prefix" | sort | uniq -c | grep -vE "^\s*1 " | awk '{$1="repeats="$1; print $0}'
+}
+
+function print_stack_lkowner_unique_in_one_line
+{
+ local statedump_fname_prefix=$1
+ sed -e '/./{H;$!d;}' -e 'x;/unique=/!d;/stack=/!d;/lk-owner=/!d;/pid=/!d;' "${statedump_fname_prefix}"* | grep -E "(stack|lk-owner|unique|pid)=" | paste -d " " - - - -
+}
+
+function get_stacks_that_appear_in_multiple_statedumps
+{
+ #If a stack with same 'unique/lk-owner/stack' appears in multiple statedumps
+ #print the stack
+ local statedump_fname_prefix=$1
+ while read -r non_uniq_stack;
+ do
+ if [ -z "$printed" ];
+ then
+ printed="1"
+ fi
+ echo "$statedump_fname_prefix" "$non_uniq_stack"
+ done < <(get_non_uniq_fields "$statedump_fname_prefix")
+}
+
+statedumpdir=${1}
+if [ -z "$statedumpdir" ];
+then
+ echo "Usage: $0 <statedump-dir>"
+ exit 1
+fi
+
+if [ ! -d "$statedumpdir" ];
+then
+ echo "$statedumpdir: Is not a directory"
+ echo "Usage: $0 <statedump-dir>"
+ exit 1
+fi
+
+cd "$statedumpdir" || exit 1
+for statedump_fname_prefix in $(get_statedump_fnames_without_timestamps);
+do
+ get_stacks_that_appear_in_multiple_statedumps "$statedump_fname_prefix"
+done | column -t
+echo "NOTE: stacks with lk-owner=\"\"/lk-owner=0000000000000000/unique=0 may not be hung frames and need further inspection" >&2
diff --git a/extras/init.d/Makefile.am b/extras/init.d/Makefile.am
index 347545fe520..8d8cc69571a 100644
--- a/extras/init.d/Makefile.am
+++ b/extras/init.d/Makefile.am
@@ -1,5 +1,7 @@
-EXTRA_DIST = glusterd-Debian glusterd-FreeBSD glusterd-Redhat glusterd-SuSE glusterd.plist rhel5-load-fuse.modules
+EXTRA_DIST = glusterd-Debian glusterd-FreeBSD glusterd-Redhat \
+ glusterd-SuSE glusterd.plist glustereventsd-FreeBSD \
+ glustereventsd-Redhat glustereventsd-Debian
CLEANFILES =
@@ -8,15 +10,23 @@ SYSTEMD_DIR = @systemddir@
LAUNCHD_DIR = @launchddir@
$(GF_DISTRIBUTION):
+if WITH_SERVER
@if [ ! -d $(SYSTEMD_DIR) ]; then \
- $(MKDIR_P) $(DESTDIR)$(INIT_DIR); \
+ $(mkdir_p) $(DESTDIR)$(INIT_DIR); \
$(INSTALL_PROGRAM) glusterd-$(GF_DISTRIBUTION) $(DESTDIR)$(INIT_DIR)/glusterd; \
fi
+endif
+if BUILD_EVENTS
+ @if [ ! -d $(SYSTEMD_DIR) ]; then \
+ $(mkdir_p) $(DESTDIR)$(INIT_DIR); \
+ $(INSTALL_PROGRAM) glustereventsd-$(GF_DISTRIBUTION) $(DESTDIR)$(INIT_DIR)/glustereventsd; \
+ fi
+endif
install-exec-local: $(GF_DISTRIBUTION)
install-data-local:
if GF_DARWIN_HOST_OS
- $(MKDIR_P) $(DESTDIR)$(LAUNCHD_DIR)
+ $(mkdir_p) $(DESTDIR)$(LAUNCHD_DIR)
$(INSTALL_PROGRAM) glusterd.plist $(DESTDIR)$(LAUNCHD_DIR)/org.gluster.glusterd.plist
endif
diff --git a/extras/init.d/glusterd-Redhat.in b/extras/init.d/glusterd-Redhat.in
index c6254a066ad..94801fe31a5 100755
--- a/extras/init.d/glusterd-Redhat.in
+++ b/extras/init.d/glusterd-Redhat.in
@@ -76,6 +76,7 @@ stop()
killproc $BASE
fi
RETVAL=$?
+ echo
[ $RETVAL -eq 0 ] && rm -f $LOCKFILE
return $RETVAL
}
diff --git a/extras/init.d/glustereventsd-Debian.in b/extras/init.d/glustereventsd-Debian.in
new file mode 100644
index 00000000000..6eebdb2b8d8
--- /dev/null
+++ b/extras/init.d/glustereventsd-Debian.in
@@ -0,0 +1,91 @@
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides: glustereventsd
+# Required-Start: $local_fs $network
+# Required-Stop: $local_fs $network
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Gluster Events Server
+# Description: Gluster Events Server
+### END INIT INFO
+
+# Author: Chris AtLee <chris@atlee.ca>
+# Patched by: Matthias Albert < matthias@linux4experts.de>
+
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+NAME=glustereventsd
+SCRIPTNAME=/etc/init.d/$NAME
+DAEMON=@prefix@/sbin/$NAME
+PIDFILE=/var/run/$NAME.pid
+GLUSTEREVENTSD_OPTS=""
+PID=`test -f $PIDFILE && cat $PIDFILE`
+
+
+# Gracefully exit if the package has been removed.
+test -x $DAEMON || exit 0
+
+# Load the VERBOSE setting and other rcS variables
+. /lib/init/vars.sh
+
+# Define LSB log_* functions.
+. /lib/lsb/init-functions
+
+
+do_start()
+{
+ pidofproc -p $PIDFILE $DAEMON >/dev/null
+ status=$?
+ if [ $status -eq 0 ]; then
+ log_success_msg "glustereventsd service is already running with pid $PID"
+ else
+ log_daemon_msg "Starting glustereventsd service" "glustereventsd"
+ start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $GLUSTEREVENTSD_OPTS
+ log_end_msg $?
+ start_daemon -p $PIDFILE $DAEMON -f $CONFIGFILE
+ return $?
+ fi
+}
+
+do_stop()
+{
+ log_daemon_msg "Stopping glustereventsd service" "glustereventsd"
+ start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
+ log_end_msg $?
+ rm -f $PIDFILE
+ killproc -p $PIDFILE $DAEMON
+ return $?
+}
+
+do_status()
+{
+ pidofproc -p $PIDFILE $DAEMON >/dev/null
+ status=$?
+ if [ $status -eq 0 ]; then
+ log_success_msg "glustereventsd service is running with pid $PID"
+ else
+ log_failure_msg "glustereventsd service is not running."
+ fi
+ exit $status
+}
+
+case "$1" in
+ start)
+ do_start
+ ;;
+ stop)
+ do_stop
+ ;;
+ status)
+ do_status;
+ ;;
+ restart|force-reload)
+ do_stop
+ sleep 2
+ do_start
+ ;;
+ *)
+ echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+ exit 3
+ ;;
+esac
+
diff --git a/extras/init.d/glustereventsd-FreeBSD.in b/extras/init.d/glustereventsd-FreeBSD.in
new file mode 100644
index 00000000000..2e8303ec6c6
--- /dev/null
+++ b/extras/init.d/glustereventsd-FreeBSD.in
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# PROVIDE: glustereventsd
+
+. /etc/rc.subr
+
+name="glustereventsd"
+rcvar=`set_rcvar`
+command=@prefix@/sbin/${name}
+command_interpreter=/usr/local/bin/python
+pidfile="/var/run/${name}.pid"
+glustereventsd_flags="-p /var/run/${name}.pid"
+start_cmd="/usr/sbin/daemon $command ${glustereventsd_flags}"
+
+load_rc_config $name
+run_rc_command "$1"
diff --git a/extras/init.d/glustereventsd-Redhat.in b/extras/init.d/glustereventsd-Redhat.in
new file mode 100644
index 00000000000..d23ce4c244f
--- /dev/null
+++ b/extras/init.d/glustereventsd-Redhat.in
@@ -0,0 +1,129 @@
+#!/bin/bash
+#
+# glustereventsd Startup script for the glusterfs Events server
+#
+# chkconfig: - 20 80
+# description: Gluster Events Server
+
+### BEGIN INIT INFO
+# Provides: glustereventsd
+# Required-Start: $local_fs $network
+# Required-Stop: $local_fs $network
+# Should-Start:
+# Should-Stop:
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: glusterfs Events server
+# Description: GlusterFS Events Server
+### END INIT INFO
+#
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+BASE=glustereventsd
+
+# Fedora File System Layout dictates /run
+[ -e /run ] && RUNDIR="/run"
+PIDFILE="${RUNDIR:-/var/run}/${BASE}.pid"
+
+PID=`test -f $PIDFILE && cat $PIDFILE`
+
+GLUSTEREVENTSD_BIN=@prefix@/sbin/$BASE
+GLUSTEREVENTSD_OPTS="--pid-file=$PIDFILE"
+GLUSTEREVENTSD="$GLUSTEREVENTSD_BIN $GLUSTEREVENTSD_OPTS"
+RETVAL=0
+
+LOCKFILE=/var/lock/subsys/${BASE}
+
+# Start the service $BASE
+start()
+{
+ if pidofproc -p $PIDFILE $GLUSTEREVENTSD_BIN &> /dev/null; then
+ echo "glustereventsd service is already running with pid $PID"
+ return 0
+ else
+ echo -n $"Starting $BASE:"
+ daemon $GLUSTEREVENTSD &
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && touch $LOCKFILE
+ return $RETVAL
+ fi
+}
+
+# Stop the service $BASE
+stop()
+{
+ echo -n $"Stopping $BASE:"
+ if pidofproc -p $PIDFILE $GLUSTEREVENTSD_BIN &> /dev/null; then
+ killproc -p $PIDFILE $BASE
+ else
+ killproc $BASE
+ fi
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
+ return $RETVAL
+}
+
+restart()
+{
+ stop
+ start
+}
+
+reload()
+{
+ restart
+}
+
+force_reload()
+{
+ restart
+}
+
+rh_status()
+{
+ status $BASE
+}
+
+rh_status_q()
+{
+ rh_status &>/dev/null
+}
+
+
+### service arguments ###
+case $1 in
+ start)
+ rh_status_q && exit 0
+ $1
+ ;;
+ stop)
+ rh_status_q || exit 0
+ $1
+ ;;
+ restart)
+ $1
+ ;;
+ reload)
+ rh_status_q || exit 7
+ $1
+ ;;
+ force-reload)
+ force_reload
+ ;;
+ status)
+ rh_status
+ ;;
+ condrestart|try-restart)
+ rh_status_q || exit 0
+ restart
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
+ exit 1
+esac
+
+exit $?
diff --git a/extras/init.d/rhel5-load-fuse.modules b/extras/init.d/rhel5-load-fuse.modules
deleted file mode 100755
index ee194db99b8..00000000000
--- a/extras/init.d/rhel5-load-fuse.modules
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-#
-# fusermount-glusterfs requires the /dev/fuse character device. The fuse module
-# provides this and is loaded on demand in newer Linux distributions.
-#
-
-[ -c /dev/fuse ] || /sbin/modprobe fuse
diff --git a/extras/mount-shared-storage.sh b/extras/mount-shared-storage.sh
new file mode 100755
index 00000000000..cc40e13c3e3
--- /dev/null
+++ b/extras/mount-shared-storage.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+#Post reboot there is a chance in which mounting of shared storage will fail
+#This will impact starting of features like NFS-Ganesha. So this script will
+#try to mount the shared storage if it fails
+
+exitStatus=0
+
+while IFS= read -r glm
+do
+ IFS=$' \t' read -r -a arr <<< "$glm"
+
+ #Validate storage type is glusterfs
+ if [ "${arr[2]}" == "glusterfs" ]
+ then
+
+ #check whether shared storage is mounted
+ #if it is mounted then mountpoint -q will return a 0 success code
+ if mountpoint -q "${arr[1]}"
+ then
+ echo "${arr[1]} is already mounted"
+ continue
+ fi
+
+ mount -t glusterfs -o "${arr[3]}" "${arr[0]}" "${arr[1]}"
+ #wait for few seconds
+ sleep 10
+
+ #recheck mount got succeed
+ if mountpoint -q "${arr[1]}"
+ then
+ echo "${arr[1]} has been mounted"
+ continue
+ else
+ echo "${arr[1]} failed to mount"
+ exitStatus=1
+ fi
+ fi
+done <<< "$(sed '/^#/ d' </etc/fstab | grep 'glusterfs')"
+exit $exitStatus
diff --git a/extras/ocf/volume.in b/extras/ocf/volume.in
index 72fd1213af2..76cc649e55f 100755
--- a/extras/ocf/volume.in
+++ b/extras/ocf/volume.in
@@ -6,6 +6,7 @@
# HA resource
#
# Authors: Florian Haas (hastexo Professional Services GmbH)
+# Jiri Lunacek (Hosting90 Systems s.r.o.)
#
# License: GNU General Public License (GPL)
@@ -54,6 +55,14 @@ must have clone ordering enabled.
<shortdesc lang="en">gluster executable</shortdesc>
<content type="string" default="$OCF_RESKEY_binary_default"/>
</parameter>
+ <parameter name="peer_map">
+ <longdesc lang="en">
+ Mapping of hostname - peer name in the gluster cluster
+ in format hostname1:peername1,hostname2:peername2,...
+ </longdesc>
+ <shortdesc lang="en">gluster peer map</shortdesc>
+ <content type="string" default=""/>
+ </parameter>
</parameters>
<actions>
<action name="start" timeout="20" />
@@ -68,9 +77,13 @@ EOF
}
+if [ -n "${OCF_RESKEY_peer_map}" ]; then
+ SHORTHOSTNAME=`echo "${OCF_RESKEY_peer_map}" | egrep -o "$SHORTHOSTNAME\:[^,]+" | awk -F: '{print $2}'`
+fi
+
volume_getdir() {
local voldir
- voldir="@sysconfdir@/glusterd/vols/${OCF_RESKEY_volname}"
+ voldir="@GLUSTERD_WORKDIR@/vols/${OCF_RESKEY_volname}"
[ -d ${voldir} ] || return 1
@@ -78,6 +91,16 @@ volume_getdir() {
return 0
}
+volume_getpid_dir() {
+ local volpid_dir
+ volpid_dir="/var/run/gluster/vols/${OCF_RESKEY_volname}"
+
+ [ -d ${volpid_dir} ] || return 1
+
+ echo "${volpid_dir}"
+ return 0
+}
+
volume_getbricks() {
local infofile
local voldir
@@ -92,17 +115,19 @@ volume_getbricks() {
volume_getpids() {
local bricks
- local piddir
local pidfile
local infofile
- local voldir
+ local volpid_dir
- voldir=`volume_getdir`
+ volpid_dir=`volume_getpid_dir`
bricks=`volume_getbricks`
- piddir="${voldir}/run"
+
+ if [ -z "$bricks" ]; then
+ return 1
+ fi
for brick in ${bricks}; do
- pidfile="${piddir}/${SHORTHOSTNAME}${brick}.pid"
+ pidfile="${volpid_dir}/${SHORTHOSTNAME}${brick}.pid"
[ -e $pidfile ] || return 1
cat $pidfile
done
@@ -206,6 +231,11 @@ volume_validate_all() {
# Test for required binaries
check_binary $OCF_RESKEY_binary
+
+ if [ -z "$SHORTHOSTNAME" ]; then
+ ocf_log err 'Unable to get host in node map'
+ return $OCF_ERR_CONFIGURED
+ fi
return $OCF_SUCCESS
}
diff --git a/extras/profiler/glusterfs-profiler b/extras/profiler/glusterfs-profiler
index 65d445864aa..aaafd088648 100755
--- a/extras/profiler/glusterfs-profiler
+++ b/extras/profiler/glusterfs-profiler
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
# Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
@@ -291,7 +291,7 @@ class Texttable:
s = "%s%s%s" % (horiz, [horiz, self._char_corner][self._has_vlines()],
horiz)
# build the line
- l = string.join([horiz*n for n in self._width], s)
+ l = s.join([horiz*n for n in self._width])
# add border if needed
if self._has_border():
l = "%s%s%s%s%s\n" % (self._char_corner, horiz, l, horiz,
diff --git a/extras/prot_filter.py b/extras/prot_filter.py
deleted file mode 100755
index 7dccacf155e..00000000000
--- a/extras/prot_filter.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/python
-
-"""
- Copyright (c) 2013 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.
-"""
-
-"""
- INSTRUCTIONS
- Put this in /usr/lib64/glusterfs/$version/filter to have it run automatically,
- or else you'll have to run it by hand every time you change the volume
- configuration. Give it a list of volume names on which to enable the
- protection functionality; it will deliberately ignore client volfiles for
- other volumes, and all server volfiles. It *will* include internal client
- volfiles such as those used for NFS or rebalance/self-heal; this is a
- deliberate choice so that it will catch deletions from those sources as well.
-"""
-
-volume_list = [ "jdtest" ]
-
-import copy
-import string
-import sys
-import types
-
-class Translator:
- def __init__ (self, name):
- self.name = name
- self.xl_type = ""
- self.opts = {}
- self.subvols = []
- self.dumped = False
- def __repr__ (self):
- return "<Translator %s>" % self.name
-
-def load (path):
- # If it's a string, open it; otherwise, assume it's already a
- # file-like object (most notably from urllib*).
- if type(path) in types.StringTypes:
- fp = file(path,"r")
- else:
- fp = path
- all_xlators = {}
- xlator = None
- last_xlator = None
- while True:
- text = fp.readline()
- if text == "":
- break
- text = text.split()
- if not len(text):
- continue
- if text[0] == "volume":
- if xlator:
- raise RuntimeError, "nested volume definition"
- xlator = Translator(text[1])
- continue
- if not xlator:
- raise RuntimeError, "text outside volume definition"
- if text[0] == "type":
- xlator.xl_type = text[1]
- continue
- if text[0] == "option":
- xlator.opts[text[1]] = string.join(text[2:])
- continue
- if text[0] == "subvolumes":
- for sv in text[1:]:
- xlator.subvols.append(all_xlators[sv])
- continue
- if text[0] == "end-volume":
- all_xlators[xlator.name] = xlator
- last_xlator = xlator
- xlator = None
- continue
- raise RuntimeError, "unrecognized keyword %s" % text[0]
- if xlator:
- raise RuntimeError, "unclosed volume definition"
- return all_xlators, last_xlator
-
-def generate (graph, last, stream=sys.stdout):
- for sv in last.subvols:
- if not sv.dumped:
- generate(graph,sv,stream)
- print >> stream, ""
- sv.dumped = True
- print >> stream, "volume %s" % last.name
- print >> stream, " type %s" % last.xl_type
- for k, v in last.opts.iteritems():
- print >> stream, " option %s %s" % (k, v)
- if last.subvols:
- print >> stream, " subvolumes %s" % string.join(
- [ sv.name for sv in last.subvols ])
- print >> stream, "end-volume"
-
-def push_filter (graph, old_xl, filt_type, opts={}):
- new_type = "-" + filt_type.split("/")[1]
- old_type = "-" + old_xl.xl_type.split("/")[1]
- pos = old_xl.name.find(old_type)
- if pos >= 0:
- new_name = old_xl.name
- old_name = new_name[:pos] + new_type + new_name[len(old_type)+pos:]
- else:
- new_name = old_xl.name + old_type
- old_name = old_xl.name + new_type
- new_xl = Translator(new_name)
- new_xl.xl_type = old_xl.xl_type
- new_xl.opts = old_xl.opts
- new_xl.subvols = old_xl.subvols
- graph[new_xl.name] = new_xl
- old_xl.name = old_name
- old_xl.xl_type = filt_type
- old_xl.opts = opts
- old_xl.subvols = [new_xl]
- graph[old_xl.name] = old_xl
-
-if __name__ == "__main__":
- path = sys.argv[1]
- # Alow an override for debugging.
- for extra in sys.argv[2:]:
- volume_list.append(extra)
- graph, last = load(path)
- for v in volume_list:
- if graph.has_key(v):
- break
- else:
- print "No configured volumes found - aborting."
- sys.exit(0)
- for v in graph.values():
- if v.xl_type == "cluster/distribute":
- push_filter(graph,v,"features/prot_dht")
- elif v.xl_type == "protocol/client":
- push_filter(graph,v,"features/prot_client")
- # We push debug/trace so that every fop gets a real frame, because DHT
- # gets confused if STACK_WIND_TAIL causes certain fops to be invoked
- # from anything other than a direct child.
- for v in graph.values():
- if v.xl_type == "features/prot_client":
- push_filter(graph,v,"debug/trace")
- generate(graph,last,stream=open(path,"w"))
diff --git a/extras/python/Makefile.am b/extras/python/Makefile.am
new file mode 100644
index 00000000000..7d81fa0319b
--- /dev/null
+++ b/extras/python/Makefile.am
@@ -0,0 +1,7 @@
+if HAVE_PYTHON
+# Install __init__.py into the Python site-packages area
+pypkgdir = @BUILD_PYTHON_SITE_PACKAGES@/gluster
+pypkg_PYTHON = __init__.py
+endif
+
+EXTRA_DIST = __init__.py
diff --git a/xlators/features/glupy/src/__init__.py.in b/extras/python/__init__.py
index 3ad9513f40e..3ad9513f40e 100644
--- a/xlators/features/glupy/src/__init__.py.in
+++ b/extras/python/__init__.py
diff --git a/extras/contri-add.sh b/extras/quota/contri-add.sh
index 7db5edd5d20..7db5edd5d20 100755
--- a/extras/contri-add.sh
+++ b/extras/quota/contri-add.sh
diff --git a/extras/quota/log_accounting.sh b/extras/quota/log_accounting.sh
new file mode 100755
index 00000000000..e2dd87b84d7
--- /dev/null
+++ b/extras/quota/log_accounting.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# The script does an accounting of all directories using command 'du' and
+# using gluster. We can then compare the two to identify accounting mismatch
+# THere can be minor mismatch because gluster only accounts for the size of
+# files. Direcotries can take up upto 4kB space on FS per directory. THis
+# size is accounted by du and not by gluster. However the difference would
+# not be significant.
+
+mountpoint=$1
+volname=$2
+
+usage ()
+{
+ echo >&2 "usage: $0 <mountpoint> <volume name>"
+ exit
+}
+
+[ $# -lt 2 ] && usage
+
+cd $mountpoint
+du -h | head -n -1 | tr -d '.' |awk '{ for (i = 2; i <= NF; i++) { printf("%s ", $i);} print "" }' > /tmp/gluster_quota_1
+cat /tmp/gluster_quota_1 | sed 's/ $//' | sed 's/ /\\ /g' | sed 's/(/\\(/g' | sed 's/)/\\)/g' |xargs gluster v quota $volname list > /tmp/gluster_quota_2
+du -h | head -n -1 |awk '{ for (i = 2; i <= NF; i++) { printf("%s %s", $i, $1);} print "" }' | tr -d '.' > /tmp/gluster_quota_3
+cat /tmp/gluster_quota_2 /tmp/gluster_quota_3 | sort > /tmp/gluster_quota_4
+find . -type d > /tmp/gluster_quota_5
+tar -cvf /tmp/gluster_quota_files.tar /tmp/gluster_quota_*
diff --git a/extras/quota/quota_fsck.py b/extras/quota/quota_fsck.py
new file mode 100755
index 00000000000..e62f7fc52a3
--- /dev/null
+++ b/extras/quota/quota_fsck.py
@@ -0,0 +1,377 @@
+#!/usr/bin/python3
+# The following script enables, Detecting, Reporting and Fixing
+# anomalies in quota accounting. Run this script with -h option
+# for further details.
+
+'''
+ Copyright (c) 2018 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.
+'''
+from __future__ import print_function
+import os, sys, re
+from stat import *
+import subprocess
+import argparse
+import xattr
+
+aggr_size = {}
+verbose_mode = False
+mnt_path = None
+brick_path = None
+obj_fix_count = 0
+file_count = 0
+dir_count = 0
+
+#CONSTANTS
+KB = 1024
+MB = 1048576
+GB = 1048576 * 1024
+TB = 1048576 * 1048576
+
+QUOTA_VERBOSE = 0
+QUOTA_META_ABSENT = 1
+QUOTA_SIZE_MISMATCH = 2
+
+IS_DIRTY ='0x3100'
+IS_CLEAN ='0x3000'
+
+
+epilog_msg='''
+ The script attempts to find any gluster accounting issues in the
+ filesystem at the given subtree. The script crawls the given
+ subdirectory tree doing a stat for all files and compares the
+ size reported by gluster quota with the size reported by stat
+ calls. Any mismatch is reported. In addition integrity of marker
+ xattrs are verified.
+ '''
+
+def print_msg(log_type, path, xattr_dict = {}, stbuf = "", dir_size = None):
+ if log_type == QUOTA_VERBOSE:
+ print('%-24s %-60s\nxattr_values: %s\n%s\n' % ("Verbose", path, xattr_dict, stbuf))
+ elif log_type == QUOTA_META_ABSENT:
+ print('%-24s %-60s\n%s\n' % ("Quota-Meta Absent", path, xattr_dict))
+ elif log_type == QUOTA_SIZE_MISMATCH:
+ print("mismatch")
+ if dir_size is not None:
+ print('%24s %60s %12s %12s' % ("Size Mismatch", path,
+ xattr_dict, dir_size))
+ else:
+ print('%-24s %-60s %-12s %-12s' % ("Size Mismatch", path, xattr_dict,
+ stbuf.st_size))
+
+def size_differs_lot(s1, s2):
+ '''
+ There could be minor accounting differences between the stat based
+ accounting and gluster accounting. To avoid these from throwing lot
+ of false positives in our logs. using a threshold of 1M for now.
+ TODO: For a deeply nested directory, at higher levels in hierarchy
+ differences may not be significant, hence this check needs to be improved.
+ '''
+ if abs(s1-s2) > 0:
+ return True
+ else:
+ return False
+
+def fix_hardlink_accounting(curr_dict, accounted_dict, curr_size):
+ '''
+ Hard links are messy.. we have to account them for their parent
+ directory. But, stop accounting at the most common ancestor.
+ Eg:
+ say we have 3 hardlinks : /d1/d2/h1, /d1/d3/h2 and /d1/h3
+
+ suppose we encounter the hard links h1 first , then h2 and then h3.
+ while accounting for h1, we account the size until root(d2->d1->/)
+ while accounting for h2, we need to account only till d3. (as d1
+ and / are accounted for this inode).
+ while accounting for h3 we should not account at all.. as all
+ its ancestors are already accounted for same inode.
+
+ curr_dict : dict of hardlinks that were seen and
+ accounted by the current iteration.
+ accounted_dict : dict of hardlinks that has already been
+ accounted for.
+
+ size : size of the object as accounted by the
+ curr_iteration.
+
+ Return vale:
+ curr_size : size reduced by hardlink sizes for those
+ hardlinks that has already been accounted
+ in current subtree.
+ Also delete the duplicate link from curr_dict.
+ '''
+
+ dual_accounted_links = set(curr_dict.keys()) & set(accounted_dict.keys())
+ for link in dual_accounted_links:
+ curr_size = curr_size - curr_dict[link]
+ del curr_dict[link]
+ return curr_size
+
+
+def fix_xattr(file_name, mark_dirty):
+ global obj_fix_count
+ global mnt_path
+
+ if mnt_path is None:
+ return
+ if mark_dirty:
+ print("MARKING DIRTY: " + file_name)
+ out = subprocess.check_output (["/usr/bin/setfattr", "-n",
+ "trusted.glusterfs.quota.dirty",
+ "-v", IS_DIRTY, file_name])
+ rel_path = os.path.relpath(file_name, brick_path)
+ print("stat on " + mnt_path + "/" + rel_path)
+ stbuf = os.lstat(mnt_path + "/" + rel_path)
+
+ obj_fix_count += 1
+
+def get_quota_xattr_brick(dpath):
+ out = subprocess.check_output (["/usr/bin/getfattr", "--no-dereference",
+ "-d", "-m.", "-e", "hex", dpath])
+ pairs = out.splitlines()
+
+ '''
+ Sample output to be parsed:
+ [root@dhcp35-100 mnt]# getfattr -d -m. -e hex /export/b1/B0/d14/d13/
+ # file: export/b1/B0/d14/d13/
+ security.selinux=0x756e636f6e66696e65645f753a6f626a6563745f723a7573725f743a733000
+ trusted.gfid=0xbae5e0d2d05043de9fd851d91ecf63e8
+ trusted.glusterfs.dht=0x000000010000000000000000ffffffff
+ trusted.glusterfs.dht.mds=0x00000000
+ trusted.glusterfs.quota.6a7675a3-b85a-40c5-830b-de9229d702ce.contri.39=0x00000000000000000000000000000000000000000000000e
+ trusted.glusterfs.quota.dirty=0x3000
+ trusted.glusterfs.quota.size.39=0x00000000000000000000000000000000000000000000000e
+ '''
+
+ '''
+ xattr_dict dictionary holds quota related xattrs
+ eg:
+ '''
+
+ xattr_dict = {}
+ xattr_dict['parents'] = {}
+
+ for xattr in pairs[1:]:
+ xattr = xattr.decode("utf-8")
+ xattr_key = xattr.split("=")[0]
+ if xattr_key == "":
+ # skip any empty lines
+ continue
+ elif not re.search("quota", xattr_key):
+ # skip all non quota xattr.
+ continue
+
+ xattr_value = xattr.split("=")[1]
+ if re.search("contri", xattr_key):
+
+ xattr_version = xattr_key.split(".")[5]
+ if 'version' not in xattr_dict:
+ xattr_dict['version'] = xattr_version
+ else:
+ if xattr_version != xattr_dict['version']:
+ print("Multiple xattr version found")
+
+
+ cur_parent = xattr_key.split(".")[3]
+ if cur_parent not in xattr_dict['parents']:
+ xattr_dict['parents'][cur_parent] = {}
+
+ contri_dict = xattr_dict['parents'][cur_parent]
+ if len(xattr_value) == 34:
+ # 34 bytes implies file contri xattr
+ # contri format =0x< 16bytes file size><16bytes file count>
+ # size is obtained in iatt, file count = 1, dir count=0
+ contri_dict['contri_size'] = int(xattr_value[2:18], 16)
+ contri_dict['contri_file_count'] = int(xattr_value[18:34], 16)
+ contri_dict['contri_dir_count'] = 0
+ else:
+ # This is a directory contri.
+ contri_dict['contri_size'] = int(xattr_value[2:18], 16)
+ contri_dict['contri_file_count'] = int(xattr_value[18:34], 16)
+ contri_dict['contri_dir_count'] = int(xattr_value[34:], 16)
+
+ elif re.search("size", xattr_key):
+ xattr_dict['size'] = int(xattr_value[2:18], 16)
+ xattr_dict['file_count'] = int(xattr_value[18:34], 16)
+ xattr_dict['dir_count'] = int(xattr_value[34:], 16)
+ elif re.search("dirty", xattr_key):
+ if xattr_value == IS_CLEAN:
+ xattr_dict['dirty'] = False
+ elif xattr_value == IS_DIRTY:
+ xattr_dict['dirty'] = True
+ elif re.search("limit_objects", xattr_key):
+ xattr_dict['limit_objects'] = int(xattr_value[2:18], 16)
+ elif re.search("limit_set", xattr_key):
+ xattr_dict['limit_set'] = int(xattr_value[2:18], 16)
+
+ return xattr_dict
+
+def verify_file_xattr(path, stbuf = None):
+
+ global file_count
+ file_count += 1
+
+ if stbuf is None:
+ stbuf = os.lstat(path)
+
+ xattr_dict = get_quota_xattr_brick(path)
+
+ for parent in xattr_dict['parents']:
+ contri_dict = xattr_dict['parents'][parent]
+
+ if 'contri_size' not in contri_dict or \
+ 'contri_file_count' not in contri_dict or \
+ 'contri_dir_count' not in contri_dict:
+ print_msg(QUOTA_META_ABSENT, path, xattr_dict, stbuf)
+ fix_xattr(path, False)
+ return
+ elif size_differs_lot(contri_dict['contri_size'], stbuf.st_size):
+ print_msg(QUOTA_SIZE_MISMATCH, path, xattr_dict, stbuf)
+ fix_xattr(path, False)
+ return
+
+ if verbose_mode is True:
+ print_msg(QUOTA_VERBOSE, path, xattr_dict, stbuf)
+
+
+def verify_dir_xattr(path, dir_size):
+
+ global dir_count
+ dir_count += 1
+ xattr_dict = get_quota_xattr_brick(path)
+
+ stbuf = os.lstat(path)
+
+ for parent in xattr_dict['parents']:
+ contri_dict = xattr_dict['parents'][parent]
+
+ if 'size' not in xattr_dict or 'contri_size' not in contri_dict:
+ print_msg(QUOTA_META_ABSENT, path)
+ fix_xattr(path, True)
+ return
+ elif size_differs_lot(dir_size, xattr_dict['size']) or \
+ size_differs_lot(contri_dict['contri_size'], xattr_dict['size']):
+ print_msg(QUOTA_SIZE_MISMATCH, path, xattr_dict, stbuf, dir_size)
+ fix_xattr(path, True)
+ return
+
+ if verbose_mode is True:
+ print_msg("VERBOSE", path, xattr_dict, stbuf, dir_size)
+
+
+def walktree(t_dir, hard_link_dict):
+ '''recursively descend the directory tree rooted at dir,
+ aggregating the size
+ t_dir : directory to walk over.
+ hard_link_dict : dict of inodes with multiple hard_links under t_dir
+ '''
+ global aggr_size
+ aggr_size[t_dir] = 0
+
+ for entry in os.listdir(t_dir):
+ pathname = os.path.join(t_dir, entry)
+ stbuf = os.lstat(pathname)
+ if S_ISDIR(stbuf.st_mode):
+ # It's a directory, recurse into it
+ if entry == '.glusterfs':
+ print("skipping " + pathname)
+ continue
+ descendent_hardlinks = {}
+ subtree_size = walktree(pathname, descendent_hardlinks)
+
+ subtree_size = fix_hardlink_accounting(descendent_hardlinks,
+ hard_link_dict,
+ subtree_size)
+
+ aggr_size[t_dir] = aggr_size[t_dir] + subtree_size
+
+ elif S_ISREG(stbuf.st_mode) or S_ISLNK(stbuf.st_mode):
+ # Even a symbolic link file may have multiple hardlinks.
+
+ file_size = stbuf.st_size
+ if stbuf.st_nlink > 2:
+ # send a single element dict to check if file is accounted.
+ file_size = fix_hardlink_accounting({stbuf.st_ino:stbuf.st_size},
+ hard_link_dict,
+ stbuf.st_size)
+
+ if file_size == 0:
+ print_msg("HARD_LINK (skipped)", pathname, "",
+ stbuf)
+ else:
+ print_msg("HARD_LINK (accounted)", pathname, "",
+ stbuf)
+ hard_link_dict[stbuf.st_ino] = stbuf.st_size
+
+ if t_dir in aggr_size:
+ aggr_size[t_dir] = aggr_size[t_dir] + file_size
+ else:
+ aggr_size[t_dir] = file_size
+ verify_file_xattr(pathname, stbuf)
+
+ else:
+ # Unknown file type, print a message
+ print('Skipping %s, due to file mode' % (pathname))
+
+ if t_dir not in aggr_size:
+ aggr_size[t_dir] = 0
+
+ verify_dir_xattr(t_dir, aggr_size[t_dir])
+ # du also accounts for t_directory sizes
+ # aggr_size[t_dir] += 4096
+
+ #cleanup
+ ret = aggr_size[t_dir]
+ del aggr_size[t_dir]
+ return ret
+
+
+if __name__ == '__main__':
+
+ parser = argparse.ArgumentParser(description='Diagnose quota accounting issues.', epilog=epilog_msg)
+ parser.add_argument('brick_path', nargs=1,
+ help='The brick path (or any descendent sub-directory of brick path)',
+ )
+ parser.add_argument('--full-logs', dest='verbose', action='store_true',
+ help='''
+ log all the xattr values and stat values reported
+ for analysis. [CAUTION: This can give lot of output
+ depending on FS depth. So one has to make sure enough
+ disk space exists if redirecting to file]
+ '''
+ )
+ parser.add_argument('--fix-issues', metavar='mount_path', dest='mnt', action='store',
+ help='''
+ fix accounting issues where the xattr values disagree
+ with stat sizes reported by gluster. A mount is also
+ required for this option to be used.
+ [CAUTION: This will directly modify backend xattr]
+ '''
+ )
+ parser.add_argument('--sub-dir', metavar='sub_dir', dest='sub_dir', action='store',
+ help='''
+ limit the crawling and accounting verification/correction
+ to a specific subdirectory.
+ '''
+ )
+
+ args = parser.parse_args()
+ verbose_mode = args.verbose
+ brick_path = args.brick_path[0]
+ sub_dir = args.sub_dir
+ mnt_path = args.mnt
+ hard_link_dict = {}
+ if sub_dir is not None:
+ walktree(os.path.join(brick_path, sub_dir), hard_link_dict)
+ else:
+ walktree(brick_path, hard_link_dict)
+
+ print("Files verified : " + str(file_count))
+ print("Directories verified : " + str(dir_count))
+ if mnt_path is not None:
+ print("Objects Fixed : " + str(obj_fix_count))
diff --git a/extras/quota/xattr_analysis.py b/extras/quota/xattr_analysis.py
new file mode 100755
index 00000000000..7bd7d96374c
--- /dev/null
+++ b/extras/quota/xattr_analysis.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python3
+# Below script has two purposes
+# 1. Display xattr of entire FS tree in a human readable form
+# 2. Display all the directory where contri and size mismatch.
+# (If there are any directory with contri and size mismatch that are not dirty
+# then that highlights a propagation issue)
+# The script takes only one input LOG _FILE generated from the command,
+# find <brick_path> | xargs getfattr -d -m. -e hex > log_gluster_xattr
+
+from __future__ import print_function
+import re
+import subprocess
+import sys
+from hurry.filesize import size
+
+if len(sys.argv) < 2:
+ sys.exit('Usage: %s log_gluster_xattr \n'
+ 'to generate log_gluster_xattr use: \n'
+ 'find <brick_path> | xargs getfattr -d -m. -e hex > log_gluster_xattr'
+ % sys.argv[0])
+LOG_FILE=sys.argv[1]
+
+def get_quota_xattr_brick():
+ out = subprocess.check_output (["/usr/bin/cat", LOG_FILE])
+ pairs = out.splitlines()
+
+ xdict = {}
+ mismatch_size = [('====contri_size===', '====size====')]
+ for xattr in pairs:
+ k = xattr.split("=")[0]
+ if re.search("# file:", k):
+ print(xdict)
+ filename=k
+ print("=====" + filename + "=======")
+ xdict = {}
+ elif k is "":
+ pass
+ else:
+ print(xattr)
+ v = xattr.split("=")[1]
+ if re.search("contri", k):
+ if len(v) == 34:
+ # for files size is obtained in iatt, file count should be 1, dir count=0
+ xdict['contri_file_count'] = int(v[18:34], 16)
+ xdict['contri_dir_count'] = 0
+ else:
+ xdict['contri_size'] = size(int(v[2:18], 16))
+ xdict['contri_file_count'] = int(v[18:34], 16)
+ xdict['contri_dir_count'] = int(v[34:], 16)
+ elif re.search("size", k):
+ xdict['size'] = size(int(v[2:18], 16))
+ xdict['file_count'] = int(v[18:34], 16)
+ xdict['dir_count'] = int(v[34:], 16)
+ elif re.search("dirty", k):
+ if v == '0x3000':
+ xdict['dirty'] = False
+ elif v == '0x3100':
+ xdict['dirty'] = True
+ elif re.search("limit_objects", k):
+ xdict['limit_objects'] = int(v[2:18], 16)
+ elif re.search("limit_set", k):
+ xdict['limit_set'] = size(int(v[2:18], 16))
+
+ if 'size' in xdict and 'contri_size' in xdict and xdict['size'] != xdict['contri_size']:
+ mismatch_size.append((xdict['contri_size'], xdict['size'], filename))
+
+ for values in mismatch_size:
+ print(values)
+
+
+if __name__ == '__main__':
+ get_quota_xattr_brick()
+
diff --git a/extras/rebalance.py b/extras/rebalance.py
index 80c614c5dfe..37c68ebbb42 100755
--- a/extras/rebalance.py
+++ b/extras/rebalance.py
@@ -1,4 +1,6 @@
-#!/usr/bin/python
+#!/usr/bin/python3
+
+from __future__ import print_function
import atexit
import copy
@@ -11,6 +13,7 @@ import subprocess
import sys
import tempfile
import volfilter
+import platform
# It's just more convenient to have named fields.
class Brick:
@@ -37,20 +40,20 @@ class Brick:
def get_bricks (host, vol):
t = pipes.Template()
- t.prepend("gluster --remote-host=%s system getspec %s"%(host,vol),".-")
- return t.open(None,"r")
+ t.prepend("gluster --remote-host=%s system getspec %s"%(host, vol), ".-")
+ return t.open(None, "r")
def generate_stanza (vf, all_xlators, cur_subvol):
sv_list = []
for sv in cur_subvol.subvols:
- generate_stanza(vf,all_xlators,sv)
+ generate_stanza(vf, all_xlators, sv)
sv_list.append(sv.name)
- vf.write("volume %s\n"%cur_subvol.name)
- vf.write(" type %s\n"%cur_subvol.type)
- for kvpair in cur_subvol.opts.iteritems():
- vf.write(" option %s %s\n"%kvpair)
+ vf.write("volume %s\n" % cur_subvol.name)
+ vf.write(" type %s\n" % cur_subvol.type)
+ for kvpair in cur_subvol.opts.items():
+ vf.write(" option %s %s\n" % kvpair)
if sv_list:
- vf.write(" subvolumes %s\n"%string.join(sv_list))
+ vf.write(" subvolumes %s\n" % ''.join(sv_list))
vf.write("end-volume\n\n")
@@ -58,14 +61,14 @@ def mount_brick (localpath, all_xlators, dht_subvol):
# Generate a volfile.
vf_name = localpath + ".vol"
- vf = open(vf_name,"w")
- generate_stanza(vf,all_xlators,dht_subvol)
+ vf = open(vf_name, "w")
+ generate_stanza(vf, all_xlators, dht_subvol)
vf.flush()
vf.close()
# Create a brick directory and mount the brick there.
os.mkdir(localpath)
- subprocess.call(["glusterfs","-f",vf_name,localpath])
+ subprocess.call(["glusterfs", "-f", vf_name, localpath])
# We use the command-line tools because there's no getxattr support in the
# Python standard library (which is ridiculous IMO). Adding the xattr package
@@ -79,16 +82,16 @@ def mount_brick (localpath, all_xlators, dht_subvol):
def get_range (brick):
t = pipes.Template()
cmd = "getfattr -e hex -n trusted.glusterfs.dht %s 2> /dev/null"
- t.prepend(cmd%brick,".-")
- t.append("grep ^trusted.glusterfs.dht=","--")
- f = t.open(None,"r")
+ t.prepend(cmd%brick, ".-")
+ t.append("grep ^trusted.glusterfs.dht=", "--")
+ f = t.open(None, "r")
try:
value = f.readline().rstrip().split('=')[1][2:]
except:
- print "could not get layout for %s (might be OK)" % brick
+ print("could not get layout for %s (might be OK)" % brick)
return None
- v_start = int("0x"+value[16:24],16)
- v_end = int("0x"+value[24:32],16)
+ v_start = int("0x"+value[16:24], 16)
+ v_end = int("0x"+value[24:32], 16)
return (v_start, v_end)
def calc_sizes (bricks, total):
@@ -125,7 +128,7 @@ def normalize (in_bricks):
curr_hash = b.r_end + 1
break
else:
- print "gap found at 0x%08x" % curr_hash
+ print("gap found at 0x%08x" % curr_hash)
sys.exit(1)
return out_bricks + in_bricks, used
@@ -153,8 +156,8 @@ def get_score (bricks):
if __name__ == "__main__":
- my_usage = "%prog [options] server volume [directory]"
- parser = optparse.OptionParser(usage=my_usage)
+ my_usage = "%prog [options] server volume [directory]"
+ parser = optparse.OptionParser(usage=my_usage)
parser.add_option("-f", "--free-space", dest="free_space",
default=False, action="store_true",
help="use free space instead of total space")
@@ -164,7 +167,7 @@ if __name__ == "__main__":
parser.add_option("-v", "--verbose", dest="verbose",
default=False, action="store_true",
help="verbose output")
- options, args = parser.parse_args()
+ options, args = parser.parse_args()
if len(args) == 3:
fix_dir = args[2]
@@ -182,9 +185,9 @@ if __name__ == "__main__":
def cleanup_workdir ():
os.chdir(orig_dir)
if options.verbose:
- print "Cleaning up %s" % work_dir
+ print("Cleaning up %s" % work_dir)
for b in bricks:
- subprocess.call(["umount",b.path])
+ subprocess.call(["umount", b.path])
shutil.rmtree(work_dir)
if not options.leave_mounted:
atexit.register(cleanup_workdir)
@@ -192,44 +195,51 @@ if __name__ == "__main__":
# Mount each brick individually, so we can issue brick-specific calls.
if options.verbose:
- print "Mounting subvolumes..."
+ print("Mounting subvolumes...")
index = 0
- volfile_pipe = get_bricks(hostname,volname)
+ volfile_pipe = get_bricks(hostname, volname)
all_xlators, last_xlator = volfilter.load(volfile_pipe)
for dht_vol in all_xlators.itervalues():
if dht_vol.type == "cluster/distribute":
break
else:
- print "no DHT volume found"
+ print("no DHT volume found")
sys.exit(1)
for sv in dht_vol.subvols:
#print "found subvol %s" % sv.name
lpath = "%s/brick%s" % (work_dir, index)
index += 1
- mount_brick(lpath,all_xlators,sv)
- bricks.append(Brick(lpath,sv.name))
+ mount_brick(lpath, all_xlators, sv)
+ bricks.append(Brick(lpath, sv.name))
if index == 0:
- print "no bricks"
+ print("no bricks")
sys.exit(1)
# Collect all of the sizes.
if options.verbose:
- print "Collecting information..."
+ print("Collecting information...")
total = 0
for b in bricks:
info = os.statvfs(b.path)
+ # On FreeBSD f_bsize (info[0]) contains the optimal I/O size,
+ # not the block size as it's found on Linux. In this case we
+ # use f_frsize (info[1]).
+ if platform.system() == 'FreeBSD':
+ bsize = info[1]
+ else:
+ bsize = info[0]
# We want a standard unit even if different bricks use
# different block sizes. The size is chosen to avoid overflows
# for very large bricks with very small block sizes, but also
# accommodate filesystems which use very large block sizes to
# cheat on benchmarks.
- blocksper100mb = 104857600 / info[0]
+ blocksper100mb = 104857600 / bsize
if options.free_space:
size = info[3] / blocksper100mb
else:
size = info[2] / blocksper100mb
if size <= 0:
- print "brick %s has invalid size %d" % (b.path, size)
+ print("brick %s has invalid size %d" % (b.path, size))
sys.exit(1)
b.set_size(size)
total += size
@@ -240,13 +250,13 @@ if __name__ == "__main__":
if hash_range is not None:
rs, re = hash_range
if rs > re:
- print "%s has backwards hash range" % b.path
+ print("%s has backwards hash range" % b.path)
sys.exit(1)
- b.set_range(hash_range[0],hash_range[1])
+ b.set_range(hash_range[0], hash_range[1])
if options.verbose:
- print "Calculating new layouts..."
- calc_sizes(bricks,total)
+ print("Calculating new layouts...")
+ calc_sizes(bricks, total)
bricks, used = normalize(bricks)
# We can't afford O(n!) here, but O(n^2) should be OK and the result
@@ -254,10 +264,10 @@ if __name__ == "__main__":
while used < len(bricks):
best_place = used
best_score = get_score(bricks)
- for i in xrange(used):
+ for i in range(used):
new_bricks = bricks[:]
del new_bricks[used]
- new_bricks.insert(i,bricks[used])
+ new_bricks.insert(i, bricks[used])
new_score = get_score(new_bricks)
if new_score > best_score:
best_place = i
@@ -265,7 +275,7 @@ if __name__ == "__main__":
if best_place != used:
nb = bricks[used]
del bricks[used]
- bricks.insert(best_place,nb)
+ bricks.insert(best_place, nb)
used += 1
# Finalize whatever we decided on.
@@ -275,25 +285,25 @@ if __name__ == "__main__":
curr_hash += b.good_size
b.r_end = curr_hash - 1
- print "Here are the xattr values for your size-weighted layout:"
+ print("Here are the xattr values for your size-weighted layout:")
for b in bricks:
- print " %s: 0x0000000200000000%08x%08x" % (
- b.sv_name, b.r_start, b.r_end)
+ print(" %s: 0x0000000200000000%08x%08x" % (
+ b.sv_name, b.r_start, b.r_end))
if fix_dir:
if options.verbose:
- print "Fixing layout for %s" % fix_dir
+ print("Fixing layout for %s" % fix_dir)
for b in bricks:
value = "0x0000000200000000%08x%08x" % (
b.r_start, b.r_end)
path = "%s/%s" % (b.path, fix_dir)
cmd = "setfattr -n trusted.glusterfs.dht -v %s %s" % (
value, path)
- print cmd
+ print(cmd)
if options.leave_mounted:
- print "The following subvolumes are still mounted:"
+ print("The following subvolumes are still mounted:")
for b in bricks:
- print "%s on %s" % (b.sv_name, b.path)
- print "Don't forget to clean up when you're done."
+ print("%s on %s" % (b.sv_name, b.path))
+ print("Don't forget to clean up when you're done.")
diff --git a/extras/run-gluster.tmpfiles.in b/extras/run-gluster.tmpfiles.in
index 49a2662c4c8..329f2dde6db 100644
--- a/extras/run-gluster.tmpfiles.in
+++ b/extras/run-gluster.tmpfiles.in
@@ -1,2 +1,2 @@
# hardcoding /run for now, should be detected while building from source?
-d /run/gluster 0755 root root -
+d /run/gluster 0775 gluster gluster -
diff --git a/extras/snap_scheduler/Makefile.am b/extras/snap_scheduler/Makefile.am
index 896595f1504..782f139016f 100644
--- a/extras/snap_scheduler/Makefile.am
+++ b/extras/snap_scheduler/Makefile.am
@@ -1,7 +1,9 @@
snap_schedulerdir = $(sbindir)/
-snap_scheduler_SCRIPTS = gcron.py snap_scheduler.py
+if WITH_SERVER
+snap_scheduler_SCRIPTS = gcron.py snap_scheduler.py conf.py
+endif
-EXTRA_DIST = gcron.py snap_scheduler.py
+EXTRA_DIST = gcron.py snap_scheduler.py conf.py
CLEANFILES =
diff --git a/extras/snap_scheduler/conf.py.in b/extras/snap_scheduler/conf.py.in
new file mode 100644
index 00000000000..6dcca0534a7
--- /dev/null
+++ b/extras/snap_scheduler/conf.py.in
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2016 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.
+#
+
+GLUSTERFS_LIBEXECDIR = '@GLUSTERFS_LIBEXECDIR@'
diff --git a/extras/snap_scheduler/gcron.py b/extras/snap_scheduler/gcron.py
index d72057861ff..0e4df77d481 100755
--- a/extras/snap_scheduler/gcron.py
+++ b/extras/snap_scheduler/gcron.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
#
# Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
@@ -19,10 +19,10 @@ import logging.handlers
import fcntl
-GCRON_TASKS = "/var/run/gluster/shared_storage/snaps/glusterfs_snap_cron_tasks"
+GCRON_TASKS = "/run/gluster/shared_storage/snaps/glusterfs_snap_cron_tasks"
GCRON_CROND_TASK = "/etc/cron.d/glusterfs_snap_cron_tasks"
GCRON_RELOAD_FLAG = "/var/run/gluster/crond_task_reload_flag"
-LOCK_FILE_DIR = "/var/run/gluster/shared_storage/snaps/lock_files/"
+LOCK_FILE_DIR = "/run/gluster/shared_storage/snaps/lock_files/"
log = logging.getLogger("gcron-logger")
start_time = 0.0
@@ -38,7 +38,8 @@ def initLogger(script_name):
sh.setFormatter(formatter)
process = subprocess.Popen(["gluster", "--print-logdir"],
- stdout=subprocess.PIPE)
+ stdout=subprocess.PIPE,
+ universal_newlines=True)
out, err = process.communicate()
if process.returncode == 0:
logfile = os.path.join(out.strip(), script_name[:-3]+".log")
@@ -88,7 +89,7 @@ def takeSnap(volname="", snapname=""):
def doJob(name, lockFile, jobFunc, volname):
success = True
try:
- f = os.open(lockFile, os.O_RDWR | os.O_NONBLOCK)
+ f = os.open(lockFile, os.O_CREAT | os.O_RDWR | os.O_NONBLOCK)
try:
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
mtime = os.path.getmtime(lockFile)
@@ -105,11 +106,11 @@ def doJob(name, lockFile, jobFunc, volname):
else:
log.info("Job %s has been processed already", name)
fcntl.flock(f, fcntl.LOCK_UN)
- except IOError as (errno, strerror):
+ except (OSError, IOError):
log.info("Job %s is being processed by another agent", name)
os.close(f)
- except IOError as (errno, strerror):
- log.debug("Failed to open lock file %s : %s", lockFile, strerror)
+ except (OSError, IOError) as e:
+ log.debug("Failed to open lock file %s : %s", lockFile, e)
log.error("Failed to process job %s", name)
success = False
@@ -122,19 +123,20 @@ def main():
global start_time
if sys.argv[1] == "--update":
if not os.path.exists(GCRON_TASKS):
- # Create a flag in /var/run/gluster which indicates that this nodes
- # doesn't have access to GCRON_TASKS right now, so that
+ # Create a flag in /var/run/gluster which indicates that this
+ # node doesn't have access to GCRON_TASKS right now, so that
# when the mount is available and GCRON_TASKS is available
# the flag will tell this routine to reload GCRON_CROND_TASK
try:
- f = os.open(GCRON_RELOAD_FLAG, os.O_CREAT | os.O_NONBLOCK, 0644)
+ f = os.open(GCRON_RELOAD_FLAG,
+ os.O_CREAT | os.O_NONBLOCK, 0o644)
os.close(f)
- except OSError as (errno, strerror):
+ except OSError as e:
if errno != EEXIST:
log.error("Failed to create %s : %s",
- GCRON_RELOAD_FLAG, strerror)
+ GCRON_RELOAD_FLAG, e)
output("Failed to create %s. Error: %s"
- % (GCRON_RELOAD_FLAG, strerror))
+ % (GCRON_RELOAD_FLAG, e))
return
if not os.path.exists(GCRON_CROND_TASK):
@@ -153,9 +155,9 @@ def main():
if process.returncode != 0:
log.error("Failed to touch %s. Error: %s.",
GCRON_CROND_TASK, err)
- except (IOError, OSError) as (errno, strerror):
+ except (IOError, OSError) as e:
log.error("Failed to touch %s. Error: %s.",
- GCRON_CROND_TASK, strerror)
+ GCRON_CROND_TASK, e)
return
if os.lstat(GCRON_TASKS).st_mtime > \
os.lstat(GCRON_CROND_TASK).st_mtime:
@@ -167,9 +169,9 @@ def main():
if process.returncode != 0:
log.error("Failed to touch %s. Error: %s.",
GCRON_CROND_TASK, err)
- except IOError as (errno, strerror):
+ except IOError as e:
log.error("Failed to touch %s. Error: %s.",
- GCRON_CROND_TASK, strerror)
+ GCRON_CROND_TASK, e)
return
volname = sys.argv[1]
diff --git a/extras/snap_scheduler/snap_scheduler.py b/extras/snap_scheduler/snap_scheduler.py
index af092e2c341..e8fcc449a9b 100755
--- a/extras/snap_scheduler/snap_scheduler.py
+++ b/extras/snap_scheduler/snap_scheduler.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
#
# Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
@@ -19,12 +19,55 @@ import logging.handlers
import sys
import shutil
from errno import EEXIST
-
+from conf import GLUSTERFS_LIBEXECDIR
+sys.path.insert(1, GLUSTERFS_LIBEXECDIR)
+
+EVENTS_ENABLED = True
+try:
+ from events.eventtypes import SNAPSHOT_SCHEDULER_INITIALISED \
+ as EVENT_SNAPSHOT_SCHEDULER_INITIALISED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_INIT_FAILED \
+ as EVENT_SNAPSHOT_SCHEDULER_INIT_FAILED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_DISABLED \
+ as EVENT_SNAPSHOT_SCHEDULER_DISABLED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_DISABLE_FAILED \
+ as EVENT_SNAPSHOT_SCHEDULER_DISABLE_FAILED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_ENABLED \
+ as EVENT_SNAPSHOT_SCHEDULER_ENABLED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_ENABLE_FAILED \
+ as EVENT_SNAPSHOT_SCHEDULER_ENABLE_FAILED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_SCHEDULE_ADDED \
+ as EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADDED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_SCHEDULE_ADD_FAILED \
+ as EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADD_FAILED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_SCHEDULE_DELETED \
+ as EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_SCHEDULE_DELETE_FAILED \
+ as EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETE_FAILED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_SCHEDULE_EDITED \
+ as EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDITED
+ from events.eventtypes import SNAPSHOT_SCHEDULER_SCHEDULE_EDIT_FAILED \
+ as EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDIT_FAILED
+except ImportError:
+ # Events APIs not installed, dummy eventtypes with None
+ EVENTS_ENABLED = False
+ EVENT_SNAPSHOT_SCHEDULER_INITIALISED = None
+ EVENT_SNAPSHOT_SCHEDULER_INIT_FAILED = None
+ EVENT_SNAPSHOT_SCHEDULER_DISABLED = None
+ EVENT_SNAPSHOT_SCHEDULER_DISABLE_FAILED = None
+ EVENT_SNAPSHOT_SCHEDULER_ENABLED = None
+ EVENT_SNAPSHOT_SCHEDULER_ENABLE_FAILED = None
+ EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADDED = None
+ EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADD_FAILED = None
+ EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETED = None
+ EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETE_FAILED = None
+ EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDITED = None
+ EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDIT_FAILED = None
SCRIPT_NAME = "snap_scheduler"
scheduler_enabled = False
log = logging.getLogger(SCRIPT_NAME)
-SHARED_STORAGE_DIR="/var/run/gluster/shared_storage"
+SHARED_STORAGE_DIR="/run/gluster/shared_storage"
GCRON_DISABLED = SHARED_STORAGE_DIR+"/snaps/gcron_disabled"
GCRON_ENABLED = SHARED_STORAGE_DIR+"/snaps/gcron_enabled"
GCRON_TASKS = SHARED_STORAGE_DIR+"/snaps/glusterfs_snap_cron_tasks"
@@ -55,6 +98,42 @@ INVALID_SCHEDULE = 15
INVALID_ARG = 16
VOLUME_DOES_NOT_EXIST = 17
+def print_error (error_num):
+ if error_num == INTERNAL_ERROR:
+ return "Internal Error"
+ elif error_num == SHARED_STORAGE_DIR_DOESNT_EXIST:
+ return "The shared storage directory ("+SHARED_STORAGE_DIR+")" \
+ " does not exist."
+ elif error_num == SHARED_STORAGE_NOT_MOUNTED:
+ return "The shared storage directory ("+SHARED_STORAGE_DIR+")" \
+ " is not mounted."
+ elif error_num == ANOTHER_TRANSACTION_IN_PROGRESS:
+ return "Another transaction is in progress."
+ elif error_num == INIT_FAILED:
+ return "Initialisation failed."
+ elif error_num == SCHEDULING_ALREADY_DISABLED:
+ return "Snapshot scheduler is already disabled."
+ elif error_num == SCHEDULING_ALREADY_ENABLED:
+ return "Snapshot scheduler is already enabled."
+ elif error_num == NODE_NOT_INITIALISED:
+ return "The node is not initialised."
+ elif error_num == ANOTHER_SCHEDULER_ACTIVE:
+ return "Another scheduler is active."
+ elif error_num == JOB_ALREADY_EXISTS:
+ return "The job already exists."
+ elif error_num == JOB_NOT_FOUND:
+ return "The job cannot be found."
+ elif error_num == INVALID_JOBNAME:
+ return "The job name is invalid."
+ elif error_num == INVALID_VOLNAME:
+ return "The volume name is invalid."
+ elif error_num == INVALID_SCHEDULE:
+ return "The schedule is invalid."
+ elif error_num == INVALID_ARG:
+ return "The argument is invalid."
+ elif error_num == VOLUME_DOES_NOT_EXIST:
+ return "The volume does not exist."
+
def output(msg):
print("%s: %s" % (SCRIPT_NAME, msg))
@@ -70,7 +149,7 @@ def initLogger():
sh.setFormatter(formatter)
process = subprocess.Popen(["gluster", "--print-logdir"],
- stdout=subprocess.PIPE)
+ stdout=subprocess.PIPE, universal_newlines=True)
logfile = os.path.join(process.stdout.read()[:-1], SCRIPT_NAME + ".log")
fh = logging.FileHandler(logfile)
@@ -128,11 +207,11 @@ def enable_scheduler():
os.remove(GCRON_TASKS)
try:
f = os.open(GCRON_ENABLED, os.O_CREAT | os.O_NONBLOCK,
- 0644)
+ 0o644)
os.close(f)
- except OSError as (errno, strerror):
+ except OSError as e:
log.error("Failed to open %s. Error: %s.",
- GCRON_ENABLED, strerror)
+ GCRON_ENABLED, e)
ret = INTERNAL_ERROR
return ret
os.symlink(GCRON_ENABLED, GCRON_TASKS)
@@ -140,8 +219,9 @@ def enable_scheduler():
log.info("Snapshot scheduling is enabled")
output("Snapshot scheduling is enabled")
ret = 0
- except OSError as (errno, strerror):
- print_str = "Failed to enable snapshot scheduling. Error: "+strerror
+ except OSError as e:
+ print_str = ("Failed to enable snapshot scheduling."
+ "Error: {{}}" + e)
log.error(print_str)
output(print_str)
ret = INTERNAL_ERROR
@@ -183,14 +263,15 @@ def disable_scheduler():
os.remove(GCRON_DISABLED)
if os.path.lexists(GCRON_TASKS):
os.remove(GCRON_TASKS)
- f = os.open(GCRON_DISABLED, os.O_CREAT, 0644)
+ f = os.open(GCRON_DISABLED, os.O_CREAT, 0o644)
os.close(f)
os.symlink(GCRON_DISABLED, GCRON_TASKS)
log.info("Snapshot scheduling is disabled")
output("Snapshot scheduling is disabled")
ret = 0
- except OSError as (errno, strerror):
- print_str = "Failed to disable snapshot scheduling. Error: "+strerror
+ except OSError as e:
+ print_str = ("Failed to disable snapshot scheduling. Error: "
+ + e)
log.error(print_str)
output(print_str)
ret = INTERNAL_ERROR
@@ -229,8 +310,8 @@ def load_tasks_from_file():
tasks[jobname] = schedule+":"+volname
f.close()
ret = 0
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", GCRON_ENABLED, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", GCRON_ENABLED, e)
ret = INTERNAL_ERROR
return ret
@@ -243,8 +324,8 @@ def get_current_scheduler():
current_scheduler = f.readline().rstrip('\n')
f.close()
ret = 0
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", CURRENT_SCHEDULER, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", CURRENT_SCHEDULER, e)
ret = INTERNAL_ERROR
return ret
@@ -284,7 +365,7 @@ def list_schedules():
def write_tasks_to_file():
try:
- with open(TMP_FILE, "w", 0644) as f:
+ with open(TMP_FILE, "w", 0o644) as f:
# If tasks is empty, just create an empty tmp file
if len(tasks) != 0:
for key in sorted(tasks):
@@ -297,8 +378,8 @@ def write_tasks_to_file():
f.flush()
os.fsync(f.fileno())
f.close()
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", TMP_FILE, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", TMP_FILE, e)
ret = INTERNAL_ERROR
return ret
@@ -309,13 +390,13 @@ def write_tasks_to_file():
def update_current_scheduler(data):
try:
- with open(TMP_FILE, "w", 0644) as f:
+ with open(TMP_FILE, "w", 0o644) as f:
f.write("%s" % data)
f.flush()
os.fsync(f.fileno())
f.close()
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", TMP_FILE, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", TMP_FILE, e)
ret = INTERNAL_ERROR
return ret
@@ -378,11 +459,11 @@ def add_schedules(jobname, schedule, volname):
job_lockfile = LOCK_FILE_DIR + jobname
try:
f = os.open(job_lockfile, os.O_CREAT | os.O_NONBLOCK,
- 0644)
+ 0o644)
os.close(f)
- except OSError as (errno, strerror):
+ except OSError as e:
log.error("Failed to open %s. Error: %s.",
- job_lockfile, strerror)
+ job_lockfile, e)
ret = INTERNAL_ERROR
return ret
log.info("Successfully added snapshot schedule %s" %
@@ -410,9 +491,9 @@ def delete_schedules(jobname):
job_lockfile = LOCK_FILE_DIR+jobname
try:
os.remove(job_lockfile)
- except OSError as (errno, strerror):
+ except OSError as e:
log.error("Failed to open %s. Error: %s.",
- job_lockfile, strerror)
+ job_lockfile, e)
ret = INTERNAL_ERROR
return ret
log.info("Successfully deleted snapshot schedule %s"
@@ -466,18 +547,113 @@ def edit_schedules(jobname, schedule, volname):
return ret
+def get_bool_val():
+ getsebool_cli = ["getsebool",
+ "-a"]
+ p1 = subprocess.Popen(getsebool_cli, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ grep_cmd = ["grep",
+ "cron_system_cronjob_use_shares"]
+ p2 = subprocess.Popen(grep_cmd, stdin=p1.stdout,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ p1.stdout.close()
+ output, err = p2.communicate()
+ rv = p2.returncode
+
+ if rv:
+ log.error("Command output:")
+ log.error(err)
+ return -1
+
+ bool_val = output.split()[2]
+ log.debug("Bool value = '%s'", bool_val)
+
+ return bool_val
+
+def get_selinux_status():
+ getenforce_cli = ["getenforce"]
+ log.debug("Running command '%s'", " ".join(getenforce_cli))
+
+ try:
+ p1 = subprocess.Popen(getenforce_cli, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ except OSError as oserr:
+ log.error("Failed to run the command \"getenforce\". Error: %s" %\
+ oserr)
+ return -1
+
+ output, err = p1.communicate()
+ rv = p1.returncode
+
+ if rv:
+ log.error("Command output:")
+ log.error(err)
+ return -1
+ else:
+ selinux_status=output.rstrip()
+ log.debug("selinux status: %s", selinux_status)
+
+ return selinux_status
+
+def set_cronjob_user_share():
+ selinux_status = get_selinux_status()
+ if (selinux_status == -1):
+ log.error("Failed to get selinux status")
+ return -1
+ elif (selinux_status == "Disabled"):
+ return 0
+
+ bool_val = get_bool_val()
+ # In case of a failure (where the boolean value is not)
+ # present in the system, we should not proceed further
+ # We should only proceed when the value is "off"
+ if (bool_val == -1 or bool_val != "off"):
+ return 0
+
+ setsebool_cli = ["setsebool", "-P",
+ "cron_system_cronjob_use_shares",
+ "on"]
+ log.debug("Running command '%s'", " ".join(setsebool_cli))
+
+ p1 = subprocess.Popen(setsebool_cli, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ output, err = p1.communicate()
+ rv = p1.returncode
+
+ if rv:
+ log.error("Command output:")
+ log.error(err)
+ return rv
+
+ bool_val = get_bool_val()
+ if (bool_val == "on"):
+ return 0
+ else:
+ # In case of an error or if boolean is not on
+ # we return a failure here
+ return -1
def initialise_scheduler():
+ ret = set_cronjob_user_share()
+ if ret:
+ log.error("Failed to set selinux boolean "
+ "cron_system_cronjob_use_shares to 'on'")
+ return ret
+
try:
- with open(TMP_FILE, "w+", 0644) as f:
+ with open(TMP_FILE, "w+", 0o644) as f:
updater = ("* * * * * root PATH=$PATH:/usr/local/sbin:"
"/usr/sbin gcron.py --update\n")
f.write("%s\n" % updater)
f.flush()
os.fsync(f.fileno())
f.close()
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", TMP_FILE, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", TMP_FILE, e)
ret = INIT_FAILED
return ret
@@ -485,10 +661,10 @@ def initialise_scheduler():
if not os.path.lexists(GCRON_TASKS):
try:
- f = open(GCRON_TASKS, "w", 0644)
+ f = open(GCRON_TASKS, "w", 0o644)
f.close()
- except IOError as (errno, strerror):
- log.error("Failed to open %s. Error: %s.", GCRON_TASKS, strerror)
+ except IOError as e:
+ log.error("Failed to open %s. Error: %s.", GCRON_TASKS, e)
ret = INIT_FAILED
return ret
@@ -499,6 +675,7 @@ def initialise_scheduler():
log.info("Successfully initialised snapshot scheduler for this node")
output("Successfully initialised snapshot scheduler for this node")
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_INITIALISED, status="Success")
ret = 0
return ret
@@ -545,6 +722,8 @@ def perform_operation(args):
ret = initialise_scheduler()
if ret != 0:
output("Failed to initialise snapshot scheduling")
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_INIT_FAILED,
+ error=print_error(ret))
return ret
# Disable snapshot scheduler
@@ -552,6 +731,11 @@ def perform_operation(args):
ret = disable_scheduler()
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_DISABLED,
+ status="Successfully Disabled")
+ else:
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_DISABLE_FAILED,
+ error=print_error(ret))
return ret
# Check if the symlink to GCRON_TASKS is properly set in the shared storage
@@ -582,6 +766,11 @@ def perform_operation(args):
ret = enable_scheduler()
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_ENABLED,
+ status="Successfully Enabled")
+ else:
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_ENABLE_FAILED,
+ error=print_error(ret))
return ret
# Disable snapshot scheduler
@@ -589,6 +778,11 @@ def perform_operation(args):
ret = disable_scheduler()
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_DISABLED,
+ status="Successfully Disabled")
+ else:
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_DISABLE_FAILED,
+ error=print_error(ret))
return ret
# List snapshot schedules
@@ -604,6 +798,12 @@ def perform_operation(args):
ret = add_schedules(args.jobname, args.schedule, args.volname)
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADDED,
+ status="Successfully added job "+args.jobname)
+ else:
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_ADD_FAILED,
+ status="Failed to add job "+args.jobname,
+ error=print_error(ret))
return ret
# Delete snapshot schedules
@@ -614,6 +814,12 @@ def perform_operation(args):
ret = delete_schedules(args.jobname)
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETED,
+ status="Successfully deleted job "+args.jobname)
+ else:
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_DELETE_FAILED,
+ status="Failed to delete job "+args.jobname,
+ error=print_error(ret))
return ret
# Edit snapshot schedules
@@ -624,11 +830,22 @@ def perform_operation(args):
ret = edit_schedules(args.jobname, args.schedule, args.volname)
if ret == 0:
subprocess.Popen(["touch", "-h", GCRON_TASKS])
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDITED,
+ status="Successfully edited job "+args.jobname)
+ else:
+ gf_event (EVENT_SNAPSHOT_SCHEDULER_SCHEDULE_EDIT_FAILED,
+ status="Failed to edit job "+args.jobname,
+ error=print_error(ret))
return ret
ret = INVALID_ARG
return ret
+def gf_event(event_type, **kwargs):
+ if EVENTS_ENABLED:
+ from events.gf_event import gf_event as gfevent
+ gfevent(event_type, **kwargs)
+
def main(argv):
initLogger()
@@ -679,42 +896,42 @@ def main(argv):
if not os.path.exists(SHARED_STORAGE_DIR+"/snaps/"):
try:
os.makedirs(SHARED_STORAGE_DIR+"/snaps/")
- except OSError as (errno, strerror):
+ except OSError as e:
if errno != EEXIST:
- log.error("Failed to create %s : %s", SHARED_STORAGE_DIR+"/snaps/", strerror)
+ log.error("Failed to create %s : %s", SHARED_STORAGE_DIR+"/snaps/", e)
output("Failed to create %s. Error: %s"
- % (SHARED_STORAGE_DIR+"/snaps/", strerror))
+ % (SHARED_STORAGE_DIR+"/snaps/", e))
return INTERNAL_ERROR
if not os.path.exists(GCRON_ENABLED):
- f = os.open(GCRON_ENABLED, os.O_CREAT | os.O_NONBLOCK, 0644)
+ f = os.open(GCRON_ENABLED, os.O_CREAT | os.O_NONBLOCK, 0o644)
os.close(f)
if not os.path.exists(LOCK_FILE_DIR):
try:
os.makedirs(LOCK_FILE_DIR)
- except OSError as (errno, strerror):
+ except OSError as e:
if errno != EEXIST:
- log.error("Failed to create %s : %s", LOCK_FILE_DIR, strerror)
+ log.error("Failed to create %s : %s", LOCK_FILE_DIR, e)
output("Failed to create %s. Error: %s"
- % (LOCK_FILE_DIR, strerror))
+ % (LOCK_FILE_DIR, e))
return INTERNAL_ERROR
try:
- f = os.open(LOCK_FILE, os.O_CREAT | os.O_RDWR | os.O_NONBLOCK, 0644)
+ f = os.open(LOCK_FILE, os.O_CREAT | os.O_RDWR | os.O_NONBLOCK, 0o644)
try:
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
ret = perform_operation(args)
fcntl.flock(f, fcntl.LOCK_UN)
- except IOError as (errno, strerror):
+ except IOError:
log.info("%s is being processed by another agent.", LOCK_FILE)
output("Another snap_scheduler command is running. "
"Please try again after some time.")
return ANOTHER_TRANSACTION_IN_PROGRESS
os.close(f)
- except OSError as (errno, strerror):
- log.error("Failed to open %s : %s", LOCK_FILE, strerror)
- output("Failed to open %s. Error: %s" % (LOCK_FILE, strerror))
+ except OSError as e:
+ log.error("Failed to open %s : %s", LOCK_FILE, e)
+ output("Failed to open %s. Error: %s" % (LOCK_FILE, e))
return INTERNAL_ERROR
return ret
diff --git a/extras/statedumpparse.rb b/extras/statedumpparse.rb
new file mode 100755
index 00000000000..1aff43377db
--- /dev/null
+++ b/extras/statedumpparse.rb
@@ -0,0 +1,208 @@
+#!/usr/bin/env ruby
+
+require 'time'
+require 'optparse'
+
+unless Array.instance_methods.include? :to_h
+ class Array
+ def to_h
+ h = {}
+ each { |k,v| h[k]=v }
+ h
+ end
+ end
+end
+
+# statedump.c:gf_proc_dump_mempool_info uses a five-dash record separator,
+# client.c:client_fd_lk_ctx_dump uses a six-dash record separator.
+ARRSEP = /^(-{5,6}=-{5,6})?$/
+HEAD = /^\[(.*)\]$/
+INPUT_FORMATS = %w[statedump json]
+
+format = 'json'
+input_format = 'statedump'
+tz = '+0000'
+memstat_select,memstat_reject = //,/\Z./
+OptionParser.new do |op|
+ op.banner << " [<] <STATEDUMP>"
+ op.on("-f", "--format=F", "json/yaml/memstat(-[plain|human|json])") { |s| format = s }
+ op.on("--input-format=F", INPUT_FORMATS.join(?/)) { |s| input_format = s }
+ op.on("--timezone=T",
+ "time zone to apply to zoneless timestamps [default UTC]") { |s| tz = s }
+ op.on("--memstat-select=RX", "memstat: select memory types matching RX") { |s|
+ memstat_select = Regexp.new s
+ }
+ op.on("--memstat-reject=RX", "memstat: reject memory types matching RX") { |s|
+ memstat_reject = Regexp.new s
+ }
+end.parse!
+
+
+if format =~ /\Amemstat(?:-(.*))?/
+ memstat_type = $1 || 'plain'
+ unless %w[plain human json].include? memstat_type
+ raise "unknown memstat type #{memstat_type.dump}"
+ end
+ format = 'memstat'
+end
+
+repr, logsep = case format
+when 'yaml'
+ require 'yaml'
+
+ [proc { |e| e.to_yaml }, "\n"]
+when 'json', 'memstat'
+ require 'json'
+
+ [proc { |e| e.to_json }, " "]
+else
+ raise "unkonwn format '#{format}'"
+end
+formatter = proc { |e| puts repr.call(e) }
+
+INPUT_FORMATS.include? input_format or raise "unkwown input format '#{input_format}'"
+
+dumpinfo = {}
+
+# parse a statedump entry
+elem_cbk = proc { |s,&cbk|
+ arraylike = false
+ s.grep(/\S/).empty? and next
+ head = nil
+ while s.last =~ /^\s*$/
+ s.pop
+ end
+ body = catch { |misc2|
+ s[0] =~ HEAD ? (head = $1) : (throw misc2)
+ body = [[]]
+ s[1..-1].each { |l|
+ if l =~ ARRSEP
+ arraylike = true
+ body << []
+ next
+ end
+ body.last << l
+ }
+
+ body.reject(&:empty?).map { |e|
+ ea = e.map { |l|
+ k,v = l.split("=",2)
+ m = /\A(0|-?[1-9]\d*)(\.\d+)?\Z/.match v
+ [k, m ? (m[2] ? Float(v) : Integer(v)) : v]
+ }
+ begin
+ ea.to_h
+ rescue
+ throw misc2
+ end
+ }
+ }
+
+ if body
+ cbk.call [head, arraylike ? body : (body.empty? ? {} : body[0])]
+ else
+ STDERR.puts ["WARNING: failed to parse record:", repr.call(s)].join(logsep)
+ end
+}
+
+# aggregator routine
+aggr = case format
+when 'memstat'
+ meminfo = {}
+ # commit memory-related entries to meminfo
+ proc { |k,r|
+ case k
+ when /memusage/
+ (meminfo["GF_MALLOC"]||={})[k] ||= r["size"] if k =~ memstat_select and k !~ memstat_reject
+ when "mempool"
+ r.each {|e|
+ kk = "mempool:#{e['pool-name']}"
+ (meminfo["mempool"]||={})[kk] ||= e["size"] if kk =~ memstat_select and kk !~ memstat_reject
+ }
+ end
+ }
+else
+ # just format data, don't actually aggregate anything
+ proc { |pair| formatter.call pair }
+end
+
+# processing the data
+case input_format
+when 'statedump'
+ acc = []
+ $<.each { |l|
+ l = l.strip
+ if l =~ /^(DUMP-(?:START|END)-TIME):\s+(.*)/
+ dumpinfo["_meta"]||={}
+ (dumpinfo["_meta"]["date"]||={})[$1] = Time.parse([$2, tz].join " ")
+ next
+ end
+
+ if l =~ HEAD
+ elem_cbk.call(acc, &aggr)
+ acc = [l]
+ next
+ end
+
+ acc << l
+ }
+ elem_cbk.call(acc, &aggr)
+when 'json'
+ $<.each { |l|
+ r = JSON.load l
+ case r
+ when Array
+ aggr[r]
+ when Hash
+ dumpinfo.merge! r
+ end
+ }
+end
+
+# final actions: output aggregated data
+case format
+when 'memstat'
+ ma = meminfo.values.map(&:to_a).inject(:+)
+ totals = meminfo.map { |coll,h| [coll, h.values.inject(:+)] }.to_h
+ tt = ma.transpose[1].inject(:+)
+
+ summary_sep,showm = case memstat_type
+ when 'json'
+ ["", proc { |k,v| puts({type: k, value: v}.to_json) }]
+ when 'plain', 'human'
+ # human-friendly number representation
+ hr = proc { |n|
+ qa = %w[B kB MB GB]
+ q = ((1...qa.size).find {|i| n < (1 << i*10)} || qa.size) - 1
+ "%.2f%s" % [n.to_f / (1 << q*10), qa[q]]
+ }
+
+ templ = "%{val} %{key}"
+ tft = proc { |t| t }
+ nft = if memstat_type == 'human'
+ nw = [ma.transpose[1], totals.values, tt].flatten.map{|n| hr[n].size}.max
+ proc { |n|
+ hn = hr[n]
+ " " * (nw - hn.size) + hn
+ }
+ else
+ nw = tt.to_s.size
+ proc { |n| "%#{nw}d" % n }
+ end
+ ## Alternative template, key first:
+ # templ = "%{key} %{val}"
+ # tw = ma.transpose[0].map(&:size).max
+ # tft = proc { |t| t + " " * [tw - t.size, 0].max }
+ # nft = (memstat_type == 'human') ? hr : proc { |n| n }
+ ["\n", proc { |k,v| puts templ % {key: tft[k], val: nft[v]} }]
+ else
+ raise 'this should be impossible'
+ end
+
+ ma.sort_by { |k,v| v }.each(&showm)
+ print summary_sep
+ totals.each { |coll,t| showm.call "Total #{coll}", t }
+ showm.call "TOTAL", tt
+else
+ formatter.call dumpinfo
+end
diff --git a/extras/stop-all-gluster-processes.sh b/extras/stop-all-gluster-processes.sh
index 087afa4cf22..710aaf5fd3c 100755
--- a/extras/stop-all-gluster-processes.sh
+++ b/extras/stop-all-gluster-processes.sh
@@ -1,33 +1,193 @@
-#! /bin/sh
+#!/bin/bash
+#
+# Kill all the processes/services except glusterd
+#
+# Usage: ./extras/stop-all-gluster-processes.sh [-g] [-h]
+# options:
+# -g Terminate in graceful mode
+# -h Show this message, then exit
+#
+# eg:
+# 1. ./extras/stop-all-gluster-processes.sh
+# 2. ./extras/stop-all-gluster-processes.sh -g
+#
+# By default, this script executes in force mode, i.e. all of brick, gsyncd
+# and other glustershd services/processes are killed without checking for
+# ongoing tasks such as geo-rep, self-heal, rebalance and etc. which may lead
+# to inconsistency after the node is brought back.
+#
+# On specifying '-g' option this script works in graceful mode, to maintain
+# data consistency the script fails with a valid exit code incase if any of
+# the gluster processes are busy in doing their jobs.
+#
+# The author of page [1] proposes user-defined exit codes to the range 64 - 113
+# Find the better explanation behind the choice in the link
+#
+# The exit code returned by stop-all-gluster-processes.sh:
+# 0 No errors/Success
+# 64 Rebalance is in progress
+# 65 Self-Heal is in progress
+# 66 Tier daemon running on this node
+# 127 option not found
+#
+# [1] http://www.tldp.org/LDP/abs/html/exitcodes.html
-function main()
+
+# global
+errors=0
+
+# find the mounts and return their pids
+get_mount_pids()
{
- for pidfile in $(find /var/lib/glusterd/ -iname '*pid');
+ local opts
+ local pid
+
+ for opts in $(grep -w fuse.glusterfs /proc/mounts| awk '{print $1":/"$2}');
do
- pid=$(cat ${pidfile});
- echo "sending SIGTERM to process $pid";
- kill -TERM $pid;
+ IFS=' ' read -r -a volinfo <<< $(echo "${opts}" | sed 's/:\// /g')
+ pid+="$(ps -Ao pid,args | grep -w "volfile-server=${volinfo[0]}" |
+ grep -w "volfile-id=/${volinfo[1]}" | grep -w "${volinfo[2]}" |
+ awk '{print $1}') "
done
+ echo "${pid}"
+}
- # for geo-replication, only 'monitor' has pid file written, other
- # processes are not having a pid file, so get it through 'ps' and
- # handle these processes
- gsyncpid=`ps aux | grep gluster | grep gsync | awk '{print $2}'`;
- test -n "$gsyncpid" && kill -TERM $gsyncpid;
+# handle mount processes i.e. 'glusterfs'
+kill_mounts()
+{
+ local signal=${1}
+ local pid
- sleep 5;
+ for pid in $(get_mount_pids);
+ do
+ echo "sending SIG${signal} to mount process with pid: ${pid}";
+ kill -${signal} ${pid};
+ done
+}
+
+# handle brick processes and node services
+kill_bricks_and_services()
+{
+ local signal=${1}
+ local pidfile
+ local pid
+
+ for pidfile in $(find /var/run/gluster/ -name '*.pid');
+ do
+ local pid=$(cat ${pidfile});
+ echo "sending SIG${signal} to pid: ${pid}";
+ kill -${signal} ${pid};
+ done
+}
+
+# for geo-replication, only 'monitor' has pid file written, other
+# processes are not having a pid file, so get it through 'ps' and
+# handle these processes
+kill_georep_gsync()
+{
+ local signal=${1}
+
+ # FIXME: add strick/better check
+ local gsyncpid=$(ps -Ao pid,args | grep gluster | grep gsync |
+ awk '{print $1}');
+ if [ -n "${gsyncpid}" ]
+ then
+ echo "sending SIG${signal} to geo-rep gsync process ${gsyncpid}";
+ kill -${signal} ${gsyncpid} || errors=$((${errors} + 1));
+ fi
+}
- # if pid file still exists, its something to KILL
- for pidfile in $(find /var/lib/glusterd/ -iname '*pid');
+# check if all processes are ready to die
+check_background_tasks()
+{
+ volumes=$(gluster vol list)
+ quit=0
+ for volname in ${volumes};
do
- pid=$(cat ${pidfile});
- echo "sending SIGKILL to process $pid";
- kill -KILL $pid;
+ # tiering
+ if [[ $(gluster volume tier ${volname} status 2> /dev/null |
+ grep "localhost" | grep -c "in progress") -gt 0 ]]
+ then
+ quit=66
+ break;
+ fi
+
+ # rebalance
+ if [[ $(gluster volume rebalance ${volname} status 2> /dev/null |
+ grep -c "in progress") -gt 0 ]]
+ then
+ quit=64
+ break;
+ fi
+
+ # self heal
+ if [[ $(gluster volume heal ${volname} info | grep "Number of entries" |
+ awk '{ sum+=$4} END {print sum}') -gt 0 ]];
+ then
+ quit=65
+ break;
+ fi
+
+ # geo-rep, snapshot and quota doesn't need grace checks,
+ # as they ensures the consistancy on force kills
+ done
+
+ echo ${quit}
+}
+
+usage()
+{
+ cat <<EOM
+Usage: $0 [-g] [-h]
+ options:
+ -g Terminate in graceful mode
+ -h Show this message, then exit
+
+eg:
+ 1. $0
+ 2. $0 -g
+EOM
+}
+
+main()
+{
+ while getopts "gh" opt; do
+ case $opt in
+ g)
+ # graceful mode
+ quit=$(check_background_tasks)
+ if [[ ${quit} -ne 0 ]]
+ then
+ exit ${quit};
+ fi
+ # else safe to kill
+ ;;
+ h)
+ usage
+ exit 0;
+ ;;
+ *)
+ usage
+ exit 127;
+ ;;
+ esac
done
+ # remove all the options that have been parsed by getopts
+ shift $((OPTIND-1))
+
+ kill_mounts TERM
+ kill_georep_gsync TERM
+ kill_bricks_and_services TERM
+
+ sleep 5;
+ echo ""
+
+ # still not Terminated? let's pass SIGKILL
+ kill_mounts KILL
+ kill_georep_gsync KILL
+ kill_bricks_and_services KILL
- # handle 'KILL' of geo-replication
- gsyncpid=`ps aux | grep gluster | grep gsync | awk '{print $2}'`;
- test -n "$gsyncpid" && kill -KILL $gsyncpid;
+ exit ${errors};
}
-main "$@";
+main "$@"
diff --git a/extras/stripe-merge.c b/extras/stripe-merge.c
index 74bd47e303e..e013a6e6e8a 100644
--- a/extras/stripe-merge.c
+++ b/extras/stripe-merge.c
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <errno.h>
#include <string.h>
-#include <attr/xattr.h>
+#include <sys/xattr.h>
#include <fnmatch.h>
#define ATTRNAME_STRIPE_INDEX "trusted.*.stripe-index"
@@ -40,33 +40,33 @@
#define INVALID_MODE UINT32_MAX
struct file_stripe_info {
- int stripe_count;
- int stripe_size;
- int coalesce;
- mode_t mode;
- int fd[0];
+ int stripe_count;
+ int stripe_size;
+ int coalesce;
+ mode_t mode;
+ int fd[0];
};
-static int close_files(struct file_stripe_info *);
+static int
+close_files(struct file_stripe_info *);
-static struct
-file_stripe_info *alloc_file_stripe_info(int count)
+static struct file_stripe_info *
+alloc_file_stripe_info(int count)
{
- int i;
- struct file_stripe_info *finfo;
+ int i;
+ struct file_stripe_info *finfo;
- finfo = calloc(1, sizeof(struct file_stripe_info) +
- (sizeof(int) * count));
- if (!finfo)
- return NULL;
+ 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;
+ for (i = 0; i < count; i++)
+ finfo->fd[i] = INVALID_FD;
- finfo->mode = INVALID_MODE;
- finfo->coalesce = INVALID_FD;
+ finfo->mode = INVALID_MODE;
+ finfo->coalesce = INVALID_FD;
- return finfo;
+ return finfo;
}
/*
@@ -77,39 +77,39 @@ file_stripe_info *alloc_file_stripe_info(int count)
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;
- }
-
- if (match)
- *attrname = strdup(match);
-
- return match_count;
+ 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;
+ }
+
+ if (match)
+ *attrname = strdup(match);
+
+ return match_count;
}
/*
@@ -118,19 +118,19 @@ get_stripe_attr_name(const char *path, const char *pattern, char **attrname)
static int
get_stripe_attr_val(const char *path, const char *attr, int *val)
{
- char attrbuf[4096];
- int len;
+ char attrbuf[4096];
+ int len;
- if (!path || !attr || !val)
- return -1;
+ if (!path || !attr || !val)
+ return -1;
- len = getxattr(path, attr, attrbuf, sizeof(attrbuf));
- if (len < 0)
- return len;
+ len = getxattr(path, attr, attrbuf, sizeof(attrbuf));
+ if (len < 0)
+ return len;
- *val = atoi(attrbuf);
+ *val = atoi(attrbuf);
- return 0;
+ return 0;
}
/*
@@ -145,29 +145,31 @@ get_stripe_attr_val(const char *path, const char *attr, int *val)
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;
- }
- }
-
- if (get_stripe_attr_val(path, *buf, val) < 0)
- return -1;
-
- return count;
+ 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;
+ }
+ }
+
+ if (get_stripe_attr_val(path, *buf, val) < 0)
+ return -1;
+
+ return count;
}
/*
@@ -178,164 +180,168 @@ get_attr(const char *path, const char *pattern, char **buf, int *val)
* 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)
+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;
+ 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:
- free(stripe_count_attr);
- free(stripe_size_attr);
- free(stripe_index_attr);
- free(stripe_coalesce_attr);
+ free(stripe_count_attr);
+ free(stripe_size_attr);
+ free(stripe_index_attr);
+ free(stripe_coalesce_attr);
- if (finfo) {
- close_files(finfo);
- free(finfo);
- }
+ if (finfo) {
+ close_files(finfo);
+ free(finfo);
+ }
- return NULL;
+ return NULL;
}
static int
close_files(struct file_stripe_info *finfo)
{
- int i, ret;
+ int i, ret;
- if (!finfo)
- return -1;
+ if (!finfo)
+ return -1;
- for (i = 0; i < finfo->stripe_count; i++) {
- if (finfo->fd[i] == INVALID_FD)
- continue;
+ 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;
- }
+ ret = close(finfo->fd[i]);
+ if (ret < 0)
+ return ret;
+ }
- return ret;
+ return ret;
}
/*
@@ -351,43 +357,43 @@ close_files(struct file_stripe_info *finfo)
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;
+ 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;
}
/*
@@ -398,97 +404,100 @@ generate_file_coalesce(int target, struct file_stripe_info *finfo)
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, };
-
- max_ret = 0;
- 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 < finfo->stripe_count; j++)
- newbuf[i] |= buf[j][i];
- write(target, newbuf, max_ret);
- } while (max_ret);
-
- return 0;
+ int i, j, max_ret, ret;
+ char buf[finfo->stripe_count][4096];
+
+ do {
+ char newbuf[4096] = {
+ 0,
+ };
+
+ max_ret = 0;
+ 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 < finfo->stripe_count; j++)
+ newbuf[i] |= buf[j][i];
+ 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);
+ if (finfo->coalesce)
+ return generate_file_coalesce(target, finfo);
- return generate_file_traditional(target, finfo);
+ return generate_file_traditional(target, finfo);
}
static void
usage(char *name)
{
- fprintf(stderr, "Usage: %s [-o <outputfile>] <inputfile1> "
- "<inputfile2> ...\n", 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;
+ 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);
- }
+ if (finfo) {
+ close_files(finfo);
+ free(finfo);
+ }
- return -1;
+ return -1;
}
-
diff --git a/extras/systemd/Makefile.am b/extras/systemd/Makefile.am
index 1fbb74593bb..61446a9b84a 100644
--- a/extras/systemd/Makefile.am
+++ b/extras/systemd/Makefile.am
@@ -1,11 +1,17 @@
+CLEANFILES = glusterd.service glustereventsd.service glusterfssharedstorage.service gluster-ta-volume.service
+EXTRA_DIST = glusterd.service.in glustereventsd.service.in glusterfssharedstorage.service.in gluster-ta-volume.service.in
-CLEANFILES =
+if USE_SYSTEMD
+systemd_DATA = gluster-ta-volume.service
+endif
-SYSTEMD_DIR = @systemddir@
-
-install-exec-local:
- @if [ -d $(SYSTEMD_DIR) ]; then \
- $(MKDIR_P) $(DESTDIR)$(SYSTEMD_DIR); \
- $(INSTALL_PROGRAM) glusterd.service $(DESTDIR)$(SYSTEMD_DIR)/; \
- fi
+if WITH_SERVER
+if USE_SYSTEMD
+# systemddir is already defined through configure.ac
+systemd_DATA += glusterd.service glusterfssharedstorage.service
+if BUILD_EVENTS
+systemd_DATA += glustereventsd.service
+endif
+endif
+endif
diff --git a/extras/systemd/gluster-ta-volume.service.in b/extras/systemd/gluster-ta-volume.service.in
new file mode 100644
index 00000000000..2802bca05bf
--- /dev/null
+++ b/extras/systemd/gluster-ta-volume.service.in
@@ -0,0 +1,13 @@
+[Unit]
+Description=GlusterFS, Thin-arbiter process to maintain quorum for replica volume
+After=network.target
+
+[Service]
+Environment="LOG_LEVEL=WARNING"
+ExecStart=@prefix@/sbin/glusterfsd -N --volfile-id ta -f @GLUSTERD_WORKDIR@/thin-arbiter/thin-arbiter.vol --brick-port 24007 --xlator-option ta-server.transport.socket.listen-port=24007 -LWARNING
+Restart=always
+KillMode=process
+SuccessExitStatus=15
+
+[Install]
+WantedBy=multi-user.target
diff --git a/extras/systemd/glusterd.service.in b/extras/systemd/glusterd.service.in
index a5d260d86e7..abb0d82911f 100644
--- a/extras/systemd/glusterd.service.in
+++ b/extras/systemd/glusterd.service.in
@@ -1,14 +1,26 @@
[Unit]
Description=GlusterFS, a clustered file-system server
-After=network.target rpcbind.service
+Documentation=man:glusterd(8)
+StartLimitBurst=6
+StartLimitIntervalSec=3600
+Requires=@RPCBIND_SERVICE@
+After=network.target @RPCBIND_SERVICE@
Before=network-online.target
[Service]
Type=forking
PIDFile=@localstatedir@/run/glusterd.pid
LimitNOFILE=65536
-ExecStart=@prefix@/sbin/glusterd -p @localstatedir@/run/glusterd.pid
+Environment="LOG_LEVEL=INFO"
+EnvironmentFile=-@SYSCONF_DIR@/sysconfig/glusterd
+ExecStart=@prefix@/sbin/glusterd -p @localstatedir@/run/glusterd.pid --log-level $LOG_LEVEL $GLUSTERD_OPTIONS
KillMode=process
+TimeoutSec=300
+SuccessExitStatus=15
+Restart=on-abnormal
+RestartSec=60
+StartLimitBurst=6
+StartLimitInterval=3600
[Install]
WantedBy=multi-user.target
diff --git a/extras/systemd/glustereventsd.service.in b/extras/systemd/glustereventsd.service.in
new file mode 100644
index 00000000000..f80b78199f6
--- /dev/null
+++ b/extras/systemd/glustereventsd.service.in
@@ -0,0 +1,16 @@
+[Unit]
+Description=Gluster Events Notifier
+After=network.target
+Documentation=man:glustereventsd(8)
+
+
+[Service]
+Environment=PYTHONPATH=@BUILD_PYTHON_SITE_PACKAGES_EXPANDED@:$PYTHONPATH
+Type=simple
+ExecStart=@SBIN_DIR@/glustereventsd --pid-file @localstatedir@/run/glustereventsd.pid
+ExecReload=/bin/kill -SIGUSR2 $MAINPID
+KillMode=control-group
+PIDFile=@localstatedir@/run/glustereventsd.pid
+
+[Install]
+WantedBy=multi-user.target
diff --git a/extras/systemd/glusterfssharedstorage.service.in b/extras/systemd/glusterfssharedstorage.service.in
new file mode 100644
index 00000000000..723ff49afb7
--- /dev/null
+++ b/extras/systemd/glusterfssharedstorage.service.in
@@ -0,0 +1,13 @@
+[Unit]
+Description=Mount glusterfs sharedstorage
+Requires=glusterd.service remote-fs-pre.target local-fs.target
+
+[Service]
+Type=forking
+ExecStart=@GLUSTERFS_LIBEXECDIR@/mount-shared-storage.sh
+Restart=on-failure
+RestartSec=3
+RestartForceExitStatus=1
+
+[Install]
+WantedBy=multi-user.target
diff --git a/extras/test/ld-preload-test/ld-preload-lib.c b/extras/test/ld-preload-test/ld-preload-lib.c
index 8f74a25cf68..d120c053a69 100644
--- a/extras/test/ld-preload-test/ld-preload-lib.c
+++ b/extras/test/ld-preload-test/ld-preload-lib.c
@@ -34,594 +34,582 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
-#include <attr/xattr.h>
+#include <sys/xattr.h>
#include <sys/sendfile.h>
/* Err number that is assigned to errno so that test application can
* verify that the function was intercepted correctly.
*/
-#define PRELOAD_ERRNO_VERF 6449
-#define set_errno() (errno = PRELOAD_ERRNO_VERF)
+#define PRELOAD_ERRNO_VERF 6449
+#define set_errno() (errno = PRELOAD_ERRNO_VERF)
void
-intercept (char *call, int tabs)
+intercept(char *call, int tabs)
{
- while (tabs > 0) {
- fprintf (stdout, "\t");
- --tabs;
- }
+ while (tabs > 0) {
+ fprintf(stdout, "\t");
+ --tabs;
+ }
- fprintf (stdout, "Intercepted by %s", call);
+ fprintf(stdout, "Intercepted by %s", call);
}
int
-creat64 (const char *pathname, mode_t mode)
+creat64(const char *pathname, mode_t mode)
{
- intercept ("creat64", 2);
- set_errno ();
- return -1;
+ intercept("creat64", 2);
+ set_errno();
+ return -1;
}
int
-creat (const char *pathname, mode_t mode)
+creat(const char *pathname, mode_t mode)
{
- intercept ("creat", 2);
- set_errno ();
- return -1;
+ intercept("creat", 2);
+ set_errno();
+ return -1;
}
-
int
-close (int fd)
+close(int fd)
{
- intercept ("close", 2);
- set_errno ();
- return -1;
+ intercept("close", 2);
+ set_errno();
+ return -1;
}
int
-open64 (const char *pathname, int flags, ...)
+open64(const char *pathname, int flags, ...)
{
- intercept ("open64", 2);
- set_errno ();
- return -1;
+ intercept("open64", 2);
+ set_errno();
+ return -1;
}
-
int
-open (const char *pathname, int flags, ...)
+open(const char *pathname, int flags, ...)
{
- intercept ("open", 2);
- set_errno ();
- return -1;
+ intercept("open", 2);
+ set_errno();
+ return -1;
}
ssize_t
-read (int fd, void *buf, size_t count)
+read(int fd, void *buf, size_t count)
{
- intercept ("read", 2);
- set_errno ();
- return -1;
+ intercept("read", 2);
+ set_errno();
+ return -1;
}
ssize_t
-readv (int fd, const struct iovec *vector, int count)
+readv(int fd, const struct iovec *vector, int count)
{
- intercept ("readv", 2);
- set_errno ();
- return -1;
+ intercept("readv", 2);
+ set_errno();
+ return -1;
}
ssize_t
-pread (int fd, void *buf, size_t count, unsigned long offset)
+pread(int fd, void *buf, size_t count, unsigned long offset)
{
- intercept ("pread", 2);
- set_errno ();
- return -1;
+ intercept("pread", 2);
+ set_errno();
+ return -1;
}
-
ssize_t
-pread64 (int fd, void *buf, size_t count, uint64_t offset)
+pread64(int fd, void *buf, size_t count, uint64_t offset)
{
- intercept ("pread64", 2);
- set_errno ();
- return -1;
+ intercept("pread64", 2);
+ set_errno();
+ return -1;
}
ssize_t
-write (int fd, const void *buf, size_t count)
+write(int fd, const void *buf, size_t count)
{
- intercept ("write", 2);
- set_errno ();
- return -1;
+ intercept("write", 2);
+ set_errno();
+ return -1;
}
ssize_t
-writev (int fd, const struct iovec *vector, int count)
+writev(int fd, const struct iovec *vector, int count)
{
- intercept ("writev", 2);
- set_errno ();
- return -1;
+ intercept("writev", 2);
+ set_errno();
+ return -1;
}
ssize_t
-pwrite (int fd, const void *buf, size_t count, unsigned long offset)
+pwrite(int fd, const void *buf, size_t count, unsigned long offset)
{
- intercept ("pwrite", 2);
- set_errno ();
- return -1;
+ intercept("pwrite", 2);
+ set_errno();
+ return -1;
}
ssize_t
-pwrite64 (int fd, const void *buf, size_t count, uint64_t offset)
+pwrite64(int fd, const void *buf, size_t count, uint64_t offset)
{
- intercept ("pwrite64", 2);
- set_errno ();
- return -1;
+ intercept("pwrite64", 2);
+ set_errno();
+ return -1;
}
-
off_t
-lseek (int fildes, unsigned long offset, int whence)
+lseek(int fildes, unsigned long offset, int whence)
{
- intercept ("lseek", 2);
- set_errno ();
- return -1;
+ intercept("lseek", 2);
+ set_errno();
+ return -1;
}
off_t
-lseek64 (int fildes, uint64_t offset, int whence)
+lseek64(int fildes, uint64_t offset, int whence)
{
- intercept ("lseek64", 2);
- set_errno ();
- return -1;
+ intercept("lseek64", 2);
+ set_errno();
+ return -1;
}
-
int
-dup (int fd)
+dup(int fd)
{
- intercept ("dup", 2);
- set_errno ();
- return -1;
+ intercept("dup", 2);
+ set_errno();
+ return -1;
}
int
-dup2 (int oldfd, int newfd)
+dup2(int oldfd, int newfd)
{
- intercept ("dup2", 2);
- set_errno ();
- return -1;
+ intercept("dup2", 2);
+ set_errno();
+ return -1;
}
int
-mkdir (const char *pathname, mode_t mode)
+mkdir(const char *pathname, mode_t mode)
{
- intercept ("mkdir", 2);
- set_errno ();
- return -1;
+ intercept("mkdir", 2);
+ set_errno();
+ return -1;
}
int
-rmdir (const char *pathname)
+rmdir(const char *pathname)
{
- intercept ("rmdir", 2);
- set_errno ();
- return -1;
+ intercept("rmdir", 2);
+ set_errno();
+ return -1;
}
int
-chmod (const char *pathname, mode_t mode)
+chmod(const char *pathname, mode_t mode)
{
- intercept ("chmod", 2);
- set_errno ();
- return -1;
+ intercept("chmod", 2);
+ set_errno();
+ return -1;
}
int
-chown (const char *pathname, uid_t owner, gid_t group)
+chown(const char *pathname, uid_t owner, gid_t group)
{
- intercept ("chown", 2);
- set_errno ();
- return -1;
+ intercept("chown", 2);
+ set_errno();
+ return -1;
}
int
-fchmod (int fd, mode_t mode)
+fchmod(int fd, mode_t mode)
{
- intercept ("fchmod", 2);
- set_errno ();
- return -1;
+ intercept("fchmod", 2);
+ set_errno();
+ return -1;
}
int
-fchown (int fd, uid_t uid, gid_t gid)
+fchown(int fd, uid_t uid, gid_t gid)
{
- intercept ("fchown", 2);
- set_errno ();
- return -1;
+ intercept("fchown", 2);
+ set_errno();
+ return -1;
}
-int fsync (int fd)
+int
+fsync(int fd)
{
- intercept ("fsync", 2);
- set_errno ();
- return -1;
+ intercept("fsync", 2);
+ set_errno();
+ return -1;
}
-
int
-ftruncate (int fd, off_t length)
+ftruncate(int fd, off_t length)
{
- intercept ("ftruncate", 1);
- set_errno ();
- return -1;
+ intercept("ftruncate", 1);
+ set_errno();
+ return -1;
}
-
int
-ftruncate64 (int fd, off_t length)
+ftruncate64(int fd, off_t length)
{
- intercept ("ftruncate64", 1);
- set_errno ();
- return -1;
+ intercept("ftruncate64", 1);
+ set_errno();
+ return -1;
}
int
-link (const char *oldpath, const char *newname)
+link(const char *oldpath, const char *newname)
{
- intercept ("link", 2);
- set_errno ();
- return -1;
+ intercept("link", 2);
+ set_errno();
+ return -1;
}
int
-rename (const char *oldpath, const char *newpath)
+rename(const char *oldpath, const char *newpath)
{
- intercept ("rename", 2);
- set_errno ();
- return -1;
+ intercept("rename", 2);
+ set_errno();
+ return -1;
}
int
-utimes (const char *path, const struct timeval times[2])
+utimes(const char *path, const struct timeval times[2])
{
- intercept ("utimes", 2);
- set_errno ();
- return -1;
+ intercept("utimes", 2);
+ set_errno();
+ return -1;
}
int
-utime (const char *path, const struct utimbuf *buf)
+futimes(int fd, const struct timeval times[2])
{
- intercept ("utime", 2);
- set_errno ();
- return -1;
+ intercept("futimes", 2);
+ set_errno();
+ return -1;
}
-
int
-mknod (const char *path, mode_t mode, dev_t dev)
+utime(const char *path, const struct utimbuf *buf)
{
- intercept ("mknod", 2);
- set_errno ();
- return -1;
+ intercept("utime", 2);
+ set_errno();
+ return -1;
}
int
-__xmknod (int ver, const char *path, mode_t mode, dev_t *dev)
+mknod(const char *path, mode_t mode, dev_t dev)
{
- intercept ("__xmknod", 2);
- set_errno ();
- return -1;
+ intercept("mknod", 2);
+ set_errno();
+ return -1;
}
int
-mkfifo (const char *path, mode_t mode)
+__xmknod(int ver, const char *path, mode_t mode, dev_t *dev)
{
- intercept ("mkfifo", 2);
- set_errno ();
- return -1;
+ intercept("__xmknod", 2);
+ set_errno();
+ return -1;
}
int
-unlink (const char *path)
+mkfifo(const char *path, mode_t mode)
{
- intercept ("unlink", 2);
- set_errno ();
- return -1;
+ intercept("mkfifo", 2);
+ set_errno();
+ return -1;
}
-
int
-symlink (const char *oldpath, const char *newpath)
+unlink(const char *path)
{
- intercept ("symlink", 2);
- set_errno ();
- return -1;
+ intercept("unlink", 2);
+ set_errno();
+ return -1;
}
int
-readlink (const char *path, char *buf, size_t bufsize)
+symlink(const char *oldpath, const char *newpath)
{
- intercept ("readlink", 1);
- set_errno ();
- return -1;
+ intercept("symlink", 2);
+ set_errno();
+ return -1;
}
+int
+readlink(const char *path, char *buf, size_t bufsize)
+{
+ intercept("readlink", 1);
+ set_errno();
+ return -1;
+}
char *
-realpath (const char *path, char *resolved)
+realpath(const char *path, char *resolved)
{
- intercept ("realpath", 1);
- set_errno ();
- return NULL;
+ intercept("realpath", 1);
+ set_errno();
+ return NULL;
}
-
DIR *
-opendir (const char *path)
+opendir(const char *path)
{
- intercept ("opendir", 2);
- set_errno ();
- return NULL;
+ intercept("opendir", 2);
+ set_errno();
+ return NULL;
}
-
struct dirent *
-readdir (DIR *dir)
+readdir(DIR *dir)
{
- intercept ("readdir\t", 2);
- set_errno ();
- return NULL;
+ intercept("readdir\t", 2);
+ set_errno();
+ return NULL;
}
struct dirent *
-readdir64 (DIR *dir)
+readdir64(DIR *dir)
{
- intercept ("readdir64", 2);
- set_errno ();
- return NULL;
+ intercept("readdir64", 2);
+ set_errno();
+ return NULL;
}
-
int
-readdir_r (DIR *dir, struct dirent *entry, struct dirent **result)
+readdir_r(DIR *dir, struct dirent *entry, struct dirent **result)
{
- intercept ("readdir_r", 1);
- set_errno ();
- return -1;
+ intercept("readdir_r", 1);
+ set_errno();
+ return -1;
}
int
-readdir64_r (DIR *dir, struct dirent *entry, struct dirent **result)
+readdir64_r(DIR *dir, struct dirent *entry, struct dirent **result)
{
- intercept ("readdir64_r", 1);
- set_errno ();
- return -1;
+ intercept("readdir64_r", 1);
+ set_errno();
+ return -1;
}
-
int
-closedir (DIR *dh)
+closedir(DIR *dh)
{
- intercept ("closedir", 1);
- set_errno ();
- return -1;
+ intercept("closedir", 1);
+ set_errno();
+ return -1;
}
int
-__xstat (int ver, const char *path, struct stat *buf)
+__xstat(int ver, const char *path, struct stat *buf)
{
- intercept ("__xstat\t", 2);
- set_errno ();
- return -1;
+ intercept("__xstat\t", 2);
+ set_errno();
+ return -1;
}
-
int
-__xstat64 (int ver, const char *path, struct stat *buf)
+__xstat64(int ver, const char *path, struct stat *buf)
{
- intercept ("__xstat64", 2);
- set_errno ();
- return -1;
+ intercept("__xstat64", 2);
+ set_errno();
+ return -1;
}
int
-stat (const char *path, struct stat *buf)
+stat(const char *path, struct stat *buf)
{
- intercept ("stat", 2);
- set_errno ();
- return -1;
+ intercept("stat", 2);
+ set_errno();
+ return -1;
}
int
-stat64 (const char *path, struct stat *buf)
+stat64(const char *path, struct stat *buf)
{
- intercept ("stat64", 2);
- set_errno ();
- return -1;
+ intercept("stat64", 2);
+ set_errno();
+ return -1;
}
int
-__fxstat (int ver, int fd, struct stat *buf)
+__fxstat(int ver, int fd, struct stat *buf)
{
- intercept ("__fxstat\t", 2);
- set_errno ();
- return -1;
+ intercept("__fxstat\t", 2);
+ set_errno();
+ return -1;
}
-
int
-__fxstat64 (int ver, int fd, struct stat *buf)
+__fxstat64(int ver, int fd, struct stat *buf)
{
- intercept ("__fxstat64", 2);
- set_errno ();
- return -1;
+ intercept("__fxstat64", 2);
+ set_errno();
+ return -1;
}
int
-fstat (int fd, struct stat *buf)
+fstat(int fd, struct stat *buf)
{
- intercept ("fstat", 2);
- set_errno ();
- return -1;
+ intercept("fstat", 2);
+ set_errno();
+ return -1;
}
int
-fstat64 (int fd , struct stat *buf)
+fstat64(int fd, struct stat *buf)
{
- intercept ("fstat64", 2);
- set_errno ();
- return -1;
+ intercept("fstat64", 2);
+ set_errno();
+ return -1;
}
int
-__lxstat (int ver, const char *path, struct stat *buf)
+__lxstat(int ver, const char *path, struct stat *buf)
{
- intercept ("__lxstat\t", 2);
- set_errno ();
- return -1;
+ intercept("__lxstat\t", 2);
+ set_errno();
+ return -1;
}
int
-__lxstat64 (int ver, const char *path, struct stat *buf)
+__lxstat64(int ver, const char *path, struct stat *buf)
{
- intercept ("__lxstat64", 2);
- set_errno ();
- return -1;
+ intercept("__lxstat64", 2);
+ set_errno();
+ return -1;
}
int
-lstat (const char *path, struct stat *buf)
+lstat(const char *path, struct stat *buf)
{
- intercept ("lstat", 2);
- set_errno ();
- return -1;
+ intercept("lstat", 2);
+ set_errno();
+ return -1;
}
int
-lstat64 (const char *path, struct stat *buf)
+lstat64(const char *path, struct stat *buf)
{
- intercept ("lstat64", 2);
- set_errno ();
- return -1;
+ intercept("lstat64", 2);
+ set_errno();
+ return -1;
}
int
-statfs (const char *path, struct statfs *buf)
+statfs(const char *path, struct statfs *buf)
{
- intercept ("statfs", 2);
- set_errno ();
- return -1;
+ intercept("statfs", 2);
+ set_errno();
+ return -1;
}
-
int
-statfs64 (const char *path, struct statfs *buf)
+statfs64(const char *path, struct statfs *buf)
{
- intercept ("statfs64", 2);
- set_errno ();
- return -1;
+ intercept("statfs64", 2);
+ set_errno();
+ return -1;
}
int
-statvfs (const char *path, struct statvfs *buf)
+statvfs(const char *path, struct statvfs *buf)
{
- intercept ("statvfs\t", 2);
- set_errno ();
- return -1;
+ intercept("statvfs\t", 2);
+ set_errno();
+ return -1;
}
-
int
-statvfs64 (const char *path, struct statvfs *buf)
+statvfs64(const char *path, struct statvfs *buf)
{
- intercept ("statvfs64", 2);
- set_errno ();
- return -1;
+ intercept("statvfs64", 2);
+ set_errno();
+ return -1;
}
ssize_t
-getxattr (const char *path, const char *name, void *value, size_t size)
+getxattr(const char *path, const char *name, void *value, size_t size)
{
- intercept ("getxattr", 1);
- set_errno ();
- return -1;
+ intercept("getxattr", 1);
+ set_errno();
+ return -1;
}
ssize_t
-lgetxattr (const char *path, const char *name, void *value, size_t size)
+lgetxattr(const char *path, const char *name, void *value, size_t size)
{
- intercept ("lgetxattr", 1);
- set_errno ();
- return -1;
+ intercept("lgetxattr", 1);
+ set_errno();
+ return -1;
}
-
int
-remove (const char* path)
+remove(const char *path)
{
- intercept ("remove", 2);
- set_errno ();
- return -1;
+ intercept("remove", 2);
+ set_errno();
+ return -1;
}
int
-lchown (const char *path, uid_t owner, gid_t group)
+lchown(const char *path, uid_t owner, gid_t group)
{
- intercept ("lchown", 2);
- set_errno ();
- return -1;
+ intercept("lchown", 2);
+ set_errno();
+ return -1;
}
void
-rewinddir (DIR *dirp)
+rewinddir(DIR *dirp)
{
- intercept ("rewinddir", 1);
- set_errno ();
- return;
+ intercept("rewinddir", 1);
+ set_errno();
+ return;
}
void
-seekdir (DIR *dirp, off_t offset)
+seekdir(DIR *dirp, off_t offset)
{
- intercept ("seekdir", 2);
- set_errno ();
- return;
+ intercept("seekdir", 2);
+ set_errno();
+ return;
}
off_t
-telldir (DIR *dirp)
+telldir(DIR *dirp)
{
- intercept ("telldir", 2);
- set_errno ();
- return -1;
+ intercept("telldir", 2);
+ set_errno();
+ return -1;
}
ssize_t
-sendfile (int out_fd, int in_fd, off_t *offset, size_t count)
+sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
- intercept ("sendfile\t", 1);
- set_errno ();
- return -1;
+ intercept("sendfile\t", 1);
+ set_errno();
+ return -1;
}
ssize_t
-sendfile64 (int out_fd, int in_fd, off_t *offset, size_t count)
+sendfile64(int out_fd, int in_fd, off_t *offset, size_t count)
{
- intercept ("sendfile64", 1);
- set_errno ();
- return -1;
+ intercept("sendfile64", 1);
+ set_errno();
+ return -1;
}
-
int
-fcntl (int fd, int cmd, ...)
+fcntl(int fd, int cmd, ...)
{
- intercept ("fcntl", 2);
- set_errno ();
- return -1;
+ intercept("fcntl", 2);
+ set_errno();
+ return -1;
}
-
diff --git a/extras/test/ld-preload-test/ld-preload-test.c b/extras/test/ld-preload-test/ld-preload-test.c
index cf8dd52c3e1..54dde8c7d54 100644
--- a/extras/test/ld-preload-test/ld-preload-test.c
+++ b/extras/test/ld-preload-test/ld-preload-test.c
@@ -46,322 +46,313 @@
#include <sys/uio.h>
#include <utime.h>
#include <sys/time.h>
-#include <attr/xattr.h>
+#include <sys/xattr.h>
#include <sys/sendfile.h>
-
-#define PRELOAD_ERRNO_VERF 6449
+#define PRELOAD_ERRNO_VERF 6449
void
check_err(int ret, char *call, int tabs)
{
- while (tabs > 0) {
- fprintf (stdout, "\t");
- --tabs;
- }
- if (ret != -1) {
- fprintf (stdout, "Not intercepted: %s\n", call);
- return;
- }
-
- if (errno != PRELOAD_ERRNO_VERF) {
- fprintf (stdout, "Not intercepted: %s: err: %s\n", call,
- strerror (errno));
- return;
- }
+ while (tabs > 0) {
+ fprintf(stdout, "\t");
+ --tabs;
+ }
+ if (ret != -1) {
+ fprintf(stdout, "Not intercepted: %s\n", call);
+ return;
+ }
- fprintf (stdout, "Intercept verified: %s\n", call);
+ if (errno != PRELOAD_ERRNO_VERF) {
+ fprintf(stdout, "Not intercepted: %s: err: %s\n", call,
+ strerror(errno));
return;
+ }
+
+ fprintf(stdout, "Intercept verified: %s\n", call);
+ return;
}
void
-usage (FILE *fp)
+usage(FILE *fp)
{
- fprintf (fp, "Usage: ld-preload-test <Options>\n");
- fprintf (fp, "Options\n");
- fprintf (fp, "\t--path\t\tPathname is used as the file/directory"
- " created for the test.\n");
-
+ fprintf(fp, "Usage: ld-preload-test <Options>\n");
+ fprintf(fp, "Options\n");
+ fprintf(fp,
+ "\t--path\t\tPathname is used as the file/directory"
+ " created for the test.\n");
}
-
int
-run_file_tests (char *testfile)
+run_file_tests(char *testfile)
{
- int ret = -1;
- struct stat buf;
+ int ret = -1;
+ struct stat buf;
- assert (testfile);
- fprintf (stdout, "Testing creat");
- ret = creat (testfile, S_IRWXU);
- check_err (ret, "creat", 2);
+ assert(testfile);
+ fprintf(stdout, "Testing creat");
+ ret = creat(testfile, S_IRWXU);
+ check_err(ret, "creat", 2);
- fprintf (stdout, "Testing close");
- ret = close (ret);
- check_err (ret, "close", 2);
+ fprintf(stdout, "Testing close");
+ ret = close(ret);
+ check_err(ret, "close", 2);
- fprintf (stdout, "Testing open");
- ret = open (testfile, O_RDONLY);
- check_err (ret, "open", 2);
+ fprintf(stdout, "Testing open");
+ ret = open(testfile, O_RDONLY);
+ check_err(ret, "open", 2);
- fprintf (stdout, "Testing read");
- ret = read (0, NULL, 0);
- check_err (ret, "read", 2);
+ fprintf(stdout, "Testing read");
+ ret = read(0, NULL, 0);
+ check_err(ret, "read", 2);
- fprintf (stdout, "Testing readv");
- ret = readv (0, NULL, 0);
- check_err (ret, "readv", 2);
+ fprintf(stdout, "Testing readv");
+ ret = readv(0, NULL, 0);
+ check_err(ret, "readv", 2);
- fprintf (stdout, "Testing pread");
- ret = pread (0, NULL, 0, 0);
- check_err (ret, "pread", 2);
+ fprintf(stdout, "Testing pread");
+ ret = pread(0, NULL, 0, 0);
+ check_err(ret, "pread", 2);
- fprintf (stdout, "Testing write");
- ret = write (0, NULL, 0);
- check_err (ret, "write", 2);
+ fprintf(stdout, "Testing write");
+ ret = write(0, NULL, 0);
+ check_err(ret, "write", 2);
- fprintf (stdout, "Testing writev");
- ret = writev (0, NULL, 0);
- check_err (ret, "writev", 2);
+ fprintf(stdout, "Testing writev");
+ ret = writev(0, NULL, 0);
+ check_err(ret, "writev", 2);
- fprintf (stdout, "Testing pwrite");
- ret = pwrite (0, NULL, 0, 0);
- check_err (ret, "pwrite", 2);
+ fprintf(stdout, "Testing pwrite");
+ ret = pwrite(0, NULL, 0, 0);
+ check_err(ret, "pwrite", 2);
- fprintf (stdout, "Testing lseek");
- ret = lseek (0, 0, 0);
- check_err (ret, "lseek", 2);
+ fprintf(stdout, "Testing lseek");
+ ret = lseek(0, 0, 0);
+ check_err(ret, "lseek", 2);
- fprintf (stdout, "Testing dup");
- ret = dup (0);
- check_err (ret, "dup", 2);
+ fprintf(stdout, "Testing dup");
+ ret = dup(0);
+ check_err(ret, "dup", 2);
- fprintf (stdout, "Testing dup2");
- ret = dup2 (0, 0);
- check_err (ret, "dup2", 2);
+ fprintf(stdout, "Testing dup2");
+ ret = dup2(0, 0);
+ check_err(ret, "dup2", 2);
- fprintf (stdout, "Testing fchmod");
- ret = fchmod (0, 0);
- check_err (ret, "fchmod", 2);
+ fprintf(stdout, "Testing fchmod");
+ ret = fchmod(0, 0);
+ check_err(ret, "fchmod", 2);
- fprintf (stdout, "Testing fchown");
- ret = fchown (0, 0, 0);
- check_err (ret, "fchown", 2);
+ fprintf(stdout, "Testing fchown");
+ ret = fchown(0, 0, 0);
+ check_err(ret, "fchown", 2);
- fprintf (stdout, "Testing fsync");
- ret = fsync (0);
- check_err (ret, "fsync", 2);
+ fprintf(stdout, "Testing fsync");
+ ret = fsync(0);
+ check_err(ret, "fsync", 2);
- fprintf (stdout, "Testing ftruncate");
- ret = ftruncate (0, 0);
- check_err (ret, "ftruncate", 1);
+ fprintf(stdout, "Testing ftruncate");
+ ret = ftruncate(0, 0);
+ check_err(ret, "ftruncate", 1);
- fprintf (stdout, "Testing fstat");
- ret = fstat (0, &buf);
- check_err (ret, "fstat", 1);
+ fprintf(stdout, "Testing fstat");
+ ret = fstat(0, &buf);
+ check_err(ret, "fstat", 1);
- fprintf (stdout, "Testing sendfile");
- ret = sendfile (0, 0, NULL, 0);
- check_err (ret, "sendfile", 1);
+ fprintf(stdout, "Testing sendfile");
+ ret = sendfile(0, 0, NULL, 0);
+ check_err(ret, "sendfile", 1);
- fprintf (stdout, "Testing fcntl");
- ret = fcntl (0, 0, NULL);
- check_err (ret, "fcntl", 2);
+ fprintf(stdout, "Testing fcntl");
+ ret = fcntl(0, 0, NULL);
+ check_err(ret, "fcntl", 2);
- fprintf (stdout, "Testing close");
- ret = close (ret);
- check_err (ret, "close", 2);
+ fprintf(stdout, "Testing close");
+ ret = close(ret);
+ check_err(ret, "close", 2);
- fprintf (stdout, "Testing remove");
- ret = remove (testfile);
- check_err (ret, "remove", 2);
+ fprintf(stdout, "Testing remove");
+ ret = remove(testfile);
+ check_err(ret, "remove", 2);
- return ret;
+ return ret;
}
-
int
-run_attr_tests (char *testfile)
+run_attr_tests(char *testfile)
{
- int ret = -1;
- char *res = NULL;
- struct stat buf;
- struct statfs sbuf;
- struct statvfs svbuf;
-
- assert (testfile);
-
- fprintf (stdout, "Testing chmod");
- ret = chmod (testfile, 0);
- check_err (ret, "chmod", 2);
-
- fprintf (stdout, "Testing chown");
- ret = chown (testfile, 0, 0);
- check_err (ret, "chown", 2);
-
- fprintf (stdout, "Testing link");
- ret = link (testfile, testfile);
- check_err (ret, "link", 2);
-
- fprintf (stdout, "Testing rename");
- ret = rename (testfile, testfile);
- check_err (ret, "rename", 2);
-
- fprintf (stdout, "Testing utimes");
- ret = utimes (testfile, NULL);
- check_err (ret, "utimes", 2);
-
- fprintf (stdout, "Testing utime");
- ret = utime (testfile, NULL);
- check_err (ret, "utime", 2);
-
- fprintf (stdout, "Testing unlink");
- ret = unlink (testfile);
- check_err (ret, "unlink", 2);
-
- fprintf (stdout, "Testing symlink");
- ret = symlink (testfile, testfile);
- check_err (ret, "symlink", 2);
-
- fprintf (stdout, "Testing readlink");
- ret = readlink (testfile, testfile, 0);
- check_err (ret, "readlink", 2);
-
- fprintf (stdout, "Testing realpath");
- ret = 0;
- res = realpath ((const char *)testfile, testfile);
- if (!res)
- ret = -1;
- check_err (ret, "realpath", 2);
-
- fprintf (stdout, "Testing stat");
- ret = stat (testfile, &buf);
- check_err (ret, "stat", 1);
-
- fprintf (stdout, "Testing lstat");
- ret = lstat (testfile, &buf);
- check_err (ret, "lstat", 1);
-
- fprintf (stdout, "Testing statfs");
- ret = statfs (testfile, &sbuf);
- check_err (ret, "statfs", 2);
-
- fprintf (stdout, "Testing statvfs");
- ret = statvfs (testfile, &svbuf);
- check_err (ret, "statvfs", 1);
-
- fprintf (stdout, "Testing getxattr");
- ret = getxattr (testfile, NULL, NULL, 0);
- check_err (ret, "getxattr", 2);
-
- fprintf (stdout, "Testing lgetxattr");
- ret = lgetxattr (testfile, NULL, NULL, 0);
- check_err (ret, "lgetxattr", 1);
-
- fprintf (stdout, "Testing lchown");
- ret = lchown (testfile, 0, 0);
- check_err (ret, "lchown", 2);
- return 0;
+ int ret = -1;
+ char *res = NULL;
+ struct stat buf;
+ struct statfs sbuf;
+ struct statvfs svbuf;
+
+ assert(testfile);
+
+ fprintf(stdout, "Testing chmod");
+ ret = chmod(testfile, 0);
+ check_err(ret, "chmod", 2);
+
+ fprintf(stdout, "Testing chown");
+ ret = chown(testfile, 0, 0);
+ check_err(ret, "chown", 2);
+
+ fprintf(stdout, "Testing link");
+ ret = link(testfile, testfile);
+ check_err(ret, "link", 2);
+
+ fprintf(stdout, "Testing rename");
+ ret = rename(testfile, testfile);
+ check_err(ret, "rename", 2);
+
+ fprintf(stdout, "Testing utimes");
+ ret = utimes(testfile, NULL);
+ check_err(ret, "utimes", 2);
+
+ fprintf(stdout, "Testing utime");
+ ret = utime(testfile, NULL);
+ check_err(ret, "utime", 2);
+
+ fprintf(stdout, "Testing unlink");
+ ret = unlink(testfile);
+ check_err(ret, "unlink", 2);
+
+ fprintf(stdout, "Testing symlink");
+ ret = symlink(testfile, testfile);
+ check_err(ret, "symlink", 2);
+
+ fprintf(stdout, "Testing readlink");
+ ret = readlink(testfile, testfile, 0);
+ check_err(ret, "readlink", 2);
+
+ fprintf(stdout, "Testing realpath");
+ ret = 0;
+ res = realpath((const char *)testfile, testfile);
+ if (!res)
+ ret = -1;
+ check_err(ret, "realpath", 2);
+
+ fprintf(stdout, "Testing stat");
+ ret = stat(testfile, &buf);
+ check_err(ret, "stat", 1);
+
+ fprintf(stdout, "Testing lstat");
+ ret = lstat(testfile, &buf);
+ check_err(ret, "lstat", 1);
+
+ fprintf(stdout, "Testing statfs");
+ ret = statfs(testfile, &sbuf);
+ check_err(ret, "statfs", 2);
+
+ fprintf(stdout, "Testing statvfs");
+ ret = statvfs(testfile, &svbuf);
+ check_err(ret, "statvfs", 1);
+
+ fprintf(stdout, "Testing getxattr");
+ ret = getxattr(testfile, NULL, NULL, 0);
+ check_err(ret, "getxattr", 2);
+
+ fprintf(stdout, "Testing lgetxattr");
+ ret = lgetxattr(testfile, NULL, NULL, 0);
+ check_err(ret, "lgetxattr", 1);
+
+ fprintf(stdout, "Testing lchown");
+ ret = lchown(testfile, 0, 0);
+ check_err(ret, "lchown", 2);
+ return 0;
}
-
int
-run_dev_tests (char *testfile)
+run_dev_tests(char *testfile)
{
- int ret = -1;
+ int ret = -1;
- assert (testfile);
+ assert(testfile);
- fprintf (stdout, "Testing mknod");
- ret = mknod (testfile, 0, 0);
- check_err (ret, "mknod", 2);
+ fprintf(stdout, "Testing mknod");
+ ret = mknod(testfile, 0, 0);
+ check_err(ret, "mknod", 2);
- fprintf (stdout, "Testing mkfifo");
- ret = mkfifo (testfile, 0);
- check_err (ret, "mkfifo", 2);
- return 0;
+ fprintf(stdout, "Testing mkfifo");
+ ret = mkfifo(testfile, 0);
+ check_err(ret, "mkfifo", 2);
+ return 0;
}
int
-run_dir_tests (char *testpath)
+run_dir_tests(char *testpath)
{
- int ret = -1;
- DIR *dh = NULL;
- struct dirent *dire = NULL;
-
- assert (testpath);
-
- fprintf (stdout, "Testing mkdir");
- ret = mkdir (testpath, 0);
- check_err (ret, "mkdir", 2);
-
- fprintf (stdout, "Testing rmdir");
- ret = rmdir (testpath);
- check_err (ret, "rmdir", 2);
-
- fprintf (stdout, "Testing opendir");
- ret = 0;
- dh = opendir (testpath);
- if (!dh)
- ret = -1;
- check_err (ret, "opendir", 2);
-
- fprintf (stdout, "Testing readdir");
- ret = 0;
- dire = readdir (dh);
- if (!dire)
- ret = -1;
- check_err (ret, "readdir", 1);
-
- fprintf (stdout, "Testing readdir_r");
- ret = readdir_r (dh, dire, &dire);
- check_err (ret, "readdir_r", 1);
-
- fprintf (stdout, "Testing rewinddir");
- rewinddir (dh);
- check_err (-1, "rewinddir", 1);
-
- fprintf (stdout, "Testing seekdir");
- seekdir (dh, 0);
- check_err (-1, "seekdir", 2);
-
- fprintf (stdout, "Testing telldir");
- ret = telldir (dh);
- check_err (ret, "telldir", 2);
-
- fprintf (stdout, "Testing closedir");
- ret = closedir (dh);
- check_err (ret, "closedir", 2);
- return 0;
+ int ret = -1;
+ DIR *dh = NULL;
+ struct dirent *dire = NULL;
+
+ assert(testpath);
+
+ fprintf(stdout, "Testing mkdir");
+ ret = mkdir(testpath, 0);
+ check_err(ret, "mkdir", 2);
+
+ fprintf(stdout, "Testing rmdir");
+ ret = rmdir(testpath);
+ check_err(ret, "rmdir", 2);
+
+ fprintf(stdout, "Testing opendir");
+ ret = 0;
+ dh = opendir(testpath);
+ if (!dh)
+ ret = -1;
+ check_err(ret, "opendir", 2);
+
+ fprintf(stdout, "Testing readdir");
+ ret = 0;
+ dire = readdir(dh);
+ if (!dire)
+ ret = -1;
+ check_err(ret, "readdir", 1);
+
+ fprintf(stdout, "Testing readdir_r");
+ ret = readdir_r(dh, dire, &dire);
+ check_err(ret, "readdir_r", 1);
+
+ fprintf(stdout, "Testing rewinddir");
+ rewinddir(dh);
+ check_err(-1, "rewinddir", 1);
+
+ fprintf(stdout, "Testing seekdir");
+ seekdir(dh, 0);
+ check_err(-1, "seekdir", 2);
+
+ fprintf(stdout, "Testing telldir");
+ ret = telldir(dh);
+ check_err(ret, "telldir", 2);
+
+ fprintf(stdout, "Testing closedir");
+ ret = closedir(dh);
+ check_err(ret, "closedir", 2);
+ return 0;
}
-
-
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- char *testpath = NULL;
- int x = 0;
-
- for (;x < argc; ++x) {
- if (strcmp (argv[x], "--path") == 0) {
- testpath = argv[x+1];
- continue;
- }
+ char *testpath = NULL;
+ int x = 0;
+ for (; x < argc; ++x) {
+ if (strcmp(argv[x], "--path") == 0) {
+ testpath = argv[x + 1];
+ continue;
}
+ }
- if (!testpath) {
- fprintf (stderr, "--path not specified\n");
- usage (stderr);
- return -1;
- }
+ if (!testpath) {
+ fprintf(stderr, "--path not specified\n");
+ usage(stderr);
+ return -1;
+ }
- run_file_tests (testpath);
- run_dir_tests (testpath);
- run_attr_tests (testpath);
- run_dev_tests (testpath);
+ run_file_tests(testpath);
+ run_dir_tests(testpath);
+ run_attr_tests(testpath);
+ run_dev_tests(testpath);
- return 0;
+ return 0;
}
-
-
diff --git a/extras/test/open-fd-tests.c b/extras/test/open-fd-tests.c
index 4184079d043..509952b4180 100644
--- a/extras/test/open-fd-tests.c
+++ b/extras/test/open-fd-tests.c
@@ -4,61 +4,64 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <attr/xattr.h>
+#include <sys/xattr.h>
#include <errno.h>
#include <string.h>
int
-main (int argc, char *argv[])
+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,};
+ 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 (argc > 1)
+ filename = argv[1];
- if (!filename)
- filename = "temp-fd-test-file";
+ 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);
+ fd = open(filename, O_RDWR | O_CREAT | O_TRUNC);
+ if (fd < 0) {
+ fd = 0;
+ fprintf(stderr, "open failed : %s\n", strerror(errno));
+ goto out;
+ }
- ret = write (fd, string, strlen (string));
- if (ret != strlen (string)) {
- fprintf (stderr, "write failed : %s (%s %d)\n",
- strerror (errno), string, loop);
- goto out;
- }
+ while (loop < 1000) {
+ /* Use it as a mechanism to test time delays */
+ memset(string, 0, 1024);
+ scanf("%s", string);
- ret = write (fd, "\n", 1);
- if (ret != 1) {
- fprintf (stderr, "write failed : %s (%d)\n",
- strerror (errno), loop);
- goto out;
- }
+ ret = write(fd, string, strlen(string));
+ if (ret != strlen(string)) {
+ fprintf(stderr, "write failed : %s (%s %d)\n", strerror(errno),
+ string, loop);
+ goto out;
+ }
- loop++;
+ ret = write(fd, "\n", 1);
+ if (ret != 1) {
+ fprintf(stderr, "write failed : %s (%d)\n", strerror(errno), loop);
+ goto out;
}
- fprintf (stdout, "finishing the test after %d loops\n", loop);
+ loop++;
+ }
+
+ fprintf(stdout, "finishing the test after %d loops\n", loop);
- ret = 0;
+ ret = 0;
out:
- if (fd)
- close (fd);
+ if (fd)
+ close(fd);
- return ret;
+ return ret;
}
diff --git a/extras/test/test-ffop.c b/extras/test/test-ffop.c
index 219dd6a2da2..1d9c125db67 100644
--- a/extras/test/test-ffop.c
+++ b/extras/test/test-ffop.c
@@ -3,777 +3,825 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <attr/xattr.h>
+#include <sys/xattr.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
-int fd_based_fops_1 (char *filename); //for fd based fops after unlink
-int fd_based_fops_2 (char *filename); //for fd based fops before unlink
-int dup_fd_based_fops (char *filename); // fops based on fd after dup
-int path_based_fops (char *filename); //for fops based on path
-int dir_based_fops (char *filename); // for fops which operate on directory
-int link_based_fops (char *filename); //for fops which operate in link files (symlinks)
-int test_open_modes (char *filename); // to test open syscall with open modes available.
-int generic_open_read_write (char *filename, int flag); // generic function which does open write and read.
+int
+fd_based_fops_1(char *filename); // for fd based fops after unlink
+int
+fd_based_fops_2(char *filename); // for fd based fops before unlink
+int
+dup_fd_based_fops(char *filename); // fops based on fd after dup
+int
+path_based_fops(char *filename); // for fops based on path
+int
+dir_based_fops(char *filename); // for fops which operate on directory
+int
+link_based_fops(
+ char *filename); // for fops which operate in link files (symlinks)
+int
+test_open_modes(
+ char *filename); // to test open syscall with open modes available.
+int
+generic_open_read_write(
+ char *filename,
+ int flag); // generic function which does open write and read.
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- int ret = -1;
- char filename[255] = {0,};
-
- if (argc > 1)
- strcpy(filename, argv[1]);
- else
- strcpy(filename, "temp-xattr-test-file");
-
- ret = fd_based_fops_1 (strcat(filename, "_1"));
- if (ret < 0)
- fprintf (stderr, "fd based file operation 1 failed\n");
- else
- fprintf (stdout, "fd based file operation 1 passed\n");
-
- ret = fd_based_fops_2 (strcat(filename, "_2"));
- if (ret < 0)
- fprintf (stderr, "fd based file operation 2 failed\n");
- else
- fprintf (stdout, "fd based file operation 2 passed\n");
-
- ret = dup_fd_based_fops (strcat (filename, "_3"));
- if (ret < 0)
- fprintf (stderr, "dup fd based file operation failed\n");
- else
- fprintf (stdout, "dup fd based file operation passed\n");
-
- ret = path_based_fops (strcat (filename, "_4"));
- if (ret < 0)
- fprintf (stderr, "path based file operation failed\n");
- else
- fprintf (stdout, "path based file operation passed\n");
-
- ret = dir_based_fops (strcat (filename, "_5"));
- if (ret < 0)
- fprintf (stderr, "directory based file operation failed\n");
- else
- fprintf (stdout, "directory based file operation passed\n");
-
- ret = link_based_fops (strcat (filename, "_5"));
- if (ret < 0)
- fprintf (stderr, "link based file operation failed\n");
- else
- fprintf (stdout, "link based file operation passed\n");
-
- ret = test_open_modes (strcat (filename, "_5"));
- if (ret < 0)
- fprintf (stderr, "testing modes of 'open' call failed\n");
- else
- fprintf (stdout, "testing modes of 'open' call passed\n");
+ int ret = -1;
+ char filename[255] = {
+ 0,
+ };
+
+ if (argc > 1)
+ strcpy(filename, argv[1]);
+ else
+ strcpy(filename, "temp-xattr-test-file");
+
+ ret = fd_based_fops_1(strcat(filename, "_1"));
+ if (ret < 0)
+ fprintf(stderr, "fd based file operation 1 failed\n");
+ else
+ fprintf(stdout, "fd based file operation 1 passed\n");
+
+ ret = fd_based_fops_2(strcat(filename, "_2"));
+ if (ret < 0)
+ fprintf(stderr, "fd based file operation 2 failed\n");
+ else
+ fprintf(stdout, "fd based file operation 2 passed\n");
+
+ ret = dup_fd_based_fops(strcat(filename, "_3"));
+ if (ret < 0)
+ fprintf(stderr, "dup fd based file operation failed\n");
+ else
+ fprintf(stdout, "dup fd based file operation passed\n");
+
+ ret = path_based_fops(strcat(filename, "_4"));
+ if (ret < 0)
+ fprintf(stderr, "path based file operation failed\n");
+ else
+ fprintf(stdout, "path based file operation passed\n");
+
+ ret = dir_based_fops(strcat(filename, "_5"));
+ if (ret < 0)
+ fprintf(stderr, "directory based file operation failed\n");
+ else
+ fprintf(stdout, "directory based file operation passed\n");
+
+ ret = link_based_fops(strcat(filename, "_5"));
+ if (ret < 0)
+ fprintf(stderr, "link based file operation failed\n");
+ else
+ fprintf(stdout, "link based file operation passed\n");
+
+ ret = test_open_modes(strcat(filename, "_5"));
+ if (ret < 0)
+ fprintf(stderr, "testing modes of 'open' call failed\n");
+ else
+ fprintf(stdout, "testing modes of 'open' call passed\n");
out:
- return ret;
+ return ret;
}
int
-fd_based_fops_1 (char *filename)
+fd_based_fops_1(char *filename)
{
- int fd = 0;
- int ret = -1;
- struct stat stbuf = {0,};
- char wstr[50] = {0,};
- char rstr[50] = {0,};
-
- 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;
- }
-
- strcpy (wstr, "This is my string\n");
- ret = write (fd, wstr, strlen(wstr));
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "write failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = lseek (fd, 0, SEEK_SET);
- if (ret < 0) {
- fprintf (stderr, "lseek failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = read (fd, rstr, strlen(wstr));
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "read failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = memcmp (rstr, wstr, strlen (wstr));
- if (ret != 0) {
- ret = -1;
- fprintf (stderr, "read returning junk\n");
- 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;
+ int fd = 0;
+ int ret = -1;
+ struct stat stbuf = {
+ 0,
+ };
+ char wstr[50] = {
+ 0,
+ };
+ char rstr[50] = {
+ 0,
+ };
+
+ 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;
+ }
+
+ strcpy(wstr, "This is my string\n");
+ ret = write(fd, wstr, strlen(wstr));
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "write failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = lseek(fd, 0, SEEK_SET);
+ if (ret < 0) {
+ fprintf(stderr, "lseek failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = read(fd, rstr, strlen(wstr));
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "read failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = memcmp(rstr, wstr, strlen(wstr));
+ if (ret != 0) {
+ ret = -1;
+ fprintf(stderr, "read returning junk\n");
+ 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);
+ if (fd)
+ close(fd);
- return ret;
+ return ret;
}
-
int
-fd_based_fops_2 (char *filename)
+fd_based_fops_2(char *filename)
{
- int fd = 0;
- int ret = -1;
- struct stat stbuf = {0,};
- char wstr[50] = {0,};
- char rstr[50] = {0,};
-
- fd = open (filename, O_RDWR|O_CREAT);
- if (fd < 0) {
- fd = 0;
- fprintf (stderr, "open failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = ftruncate (fd, 0);
-
- if (ret < 0) {
- fprintf (stderr, "ftruncate failed : %s\n", strerror (errno));
- goto out;
- }
-
- strcpy (wstr, "This is my second string\n");
- ret = write (fd, wstr, strlen (wstr));
- if (ret < 0) {
- ret = -1;
- fprintf (stderr, "write failed: %s\n", strerror (errno));
- goto out;
- }
-
- lseek (fd, 0, SEEK_SET);
- if (ret < 0) {
- fprintf (stderr, "lseek failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = read (fd, rstr, strlen (wstr));
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "read failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = memcmp (rstr, wstr, strlen (wstr));
- if (ret != 0) {
- ret = -1;
- fprintf (stderr, "read returning junk\n");
- 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;
- }
+ int fd = 0;
+ int ret = -1;
+ struct stat stbuf = {
+ 0,
+ };
+ char wstr[50] = {
+ 0,
+ };
+ char rstr[50] = {
+ 0,
+ };
+
+ fd = open(filename, O_RDWR | O_CREAT);
+ if (fd < 0) {
+ fd = 0;
+ fprintf(stderr, "open failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = ftruncate(fd, 0);
+
+ if (ret < 0) {
+ fprintf(stderr, "ftruncate failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ strcpy(wstr, "This is my second string\n");
+ ret = write(fd, wstr, strlen(wstr));
+ if (ret < 0) {
+ ret = -1;
+ fprintf(stderr, "write failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ lseek(fd, 0, SEEK_SET);
+ if (ret < 0) {
+ fprintf(stderr, "lseek failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = read(fd, rstr, strlen(wstr));
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "read failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = memcmp(rstr, wstr, strlen(wstr));
+ if (ret != 0) {
+ ret = -1;
+ fprintf(stderr, "read returning junk\n");
+ 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;
+ }
out:
- if (fd)
- close (fd);
- unlink (filename);
+ if (fd)
+ close(fd);
+ unlink(filename);
- return ret;
+ return ret;
}
int
-path_based_fops (char *filename)
+path_based_fops(char *filename)
{
- int ret = -1;
- int fd = 0;
- struct stat stbuf = {0,};
- char newfilename[255] = {0,};
-
- fd = creat (filename, 0644);
- if (fd < 0) {
- fprintf (stderr, "creat failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = truncate (filename, 0);
- if (ret < 0) {
- fprintf (stderr, "truncate failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = stat (filename, &stbuf);
- if (ret < 0) {
- fprintf (stderr, "stat failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = chmod (filename, 0640);
- if (ret < 0) {
- fprintf (stderr, "chmod failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = chown (filename, 10001, 10001);
- if (ret < 0) {
- fprintf (stderr, "chown failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = setxattr (filename, "trusted.xattr-test", "working", 8, 0);
- if (ret < 0) {
- fprintf (stderr, "setxattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = listxattr (filename, NULL, 0);
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "listxattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = getxattr (filename, "trusted.xattr-test", NULL, 0);
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "getxattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = removexattr (filename, "trusted.xattr-test");
- if (ret < 0) {
- fprintf (stderr, "removexattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = access (filename, R_OK|W_OK);
- if (ret < 0) {
- fprintf (stderr, "access failed: %s\n", strerror (errno));
- goto out;
- }
-
- strcpy (newfilename, filename);
- strcat(newfilename, "_new");
- ret = rename (filename, newfilename);
- if (ret < 0) {
- fprintf (stderr, "rename failed: %s\n", strerror (errno));
- goto out;
- }
- unlink (newfilename);
+ int ret = -1;
+ int fd = 0;
+ struct stat stbuf = {
+ 0,
+ };
+ char newfilename[255] = {
+ 0,
+ };
+
+ fd = creat(filename, 0644);
+ if (fd < 0) {
+ fprintf(stderr, "creat failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = truncate(filename, 0);
+ if (ret < 0) {
+ fprintf(stderr, "truncate failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = stat(filename, &stbuf);
+ if (ret < 0) {
+ fprintf(stderr, "stat failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = chmod(filename, 0640);
+ if (ret < 0) {
+ fprintf(stderr, "chmod failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = chown(filename, 10001, 10001);
+ if (ret < 0) {
+ fprintf(stderr, "chown failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = setxattr(filename, "trusted.xattr-test", "working", 8, 0);
+ if (ret < 0) {
+ fprintf(stderr, "setxattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = listxattr(filename, NULL, 0);
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "listxattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = getxattr(filename, "trusted.xattr-test", NULL, 0);
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "getxattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = removexattr(filename, "trusted.xattr-test");
+ if (ret < 0) {
+ fprintf(stderr, "removexattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = access(filename, R_OK | W_OK);
+ if (ret < 0) {
+ fprintf(stderr, "access failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ strcpy(newfilename, filename);
+ strcat(newfilename, "_new");
+ ret = rename(filename, newfilename);
+ if (ret < 0) {
+ fprintf(stderr, "rename failed: %s\n", strerror(errno));
+ goto out;
+ }
+ unlink(newfilename);
out:
- if (fd)
- close (fd);
+ if (fd)
+ close(fd);
- unlink (filename);
- return ret;
+ unlink(filename);
+ return ret;
}
int
-dup_fd_based_fops (char *filename)
+dup_fd_based_fops(char *filename)
{
- int fd = 0;
- int newfd = 0;
- int ret = -1;
- struct stat stbuf = {0,};
- char wstr[50] = {0,};
- char rstr[50] = {0,};
-
- fd = open (filename, O_RDWR|O_CREAT);
- if (fd < 0) {
- fd = 0;
- fprintf (stderr, "open failed : %s\n", strerror (errno));
- goto out;
- }
-
- newfd = dup (fd);
- if (newfd < 0) {
- ret = -1;
- fprintf (stderr, "dup failed: %s\n", strerror (errno));
- goto out;
- }
-
- close (fd);
-
- strcpy (wstr, "This is my string\n");
- ret = write (newfd, wstr, strlen(wstr));
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "write failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = lseek (newfd, 0, SEEK_SET);
- if (ret < 0) {
- fprintf (stderr, "lseek failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = read (newfd, rstr, strlen(wstr));
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "read failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = memcmp (rstr, wstr, strlen (wstr));
- if (ret != 0) {
- ret = -1;
- fprintf (stderr, "read returning junk\n");
- goto out;
- }
-
- ret = ftruncate (newfd, 0);
- if (ret < 0) {
- fprintf (stderr, "ftruncate failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = fstat (newfd, &stbuf);
- if (ret < 0) {
- fprintf (stderr, "fstat failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = fchmod (newfd, 0640);
- if (ret < 0) {
- fprintf (stderr, "fchmod failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = fchown (newfd, 10001, 10001);
- if (ret < 0) {
- fprintf (stderr, "fchown failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = fsync (newfd);
- if (ret < 0) {
- fprintf (stderr, "fsync failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = fsetxattr (newfd, "trusted.xattr-test", "working", 8, 0);
- if (ret < 0) {
- fprintf (stderr, "fsetxattr failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = fdatasync (newfd);
- if (ret < 0) {
- fprintf (stderr, "fdatasync failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = flistxattr (newfd, NULL, 0);
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "flistxattr failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = fgetxattr (newfd, "trusted.xattr-test", NULL, 0);
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "fgetxattr failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = fremovexattr (newfd, "trusted.xattr-test");
- if (ret < 0) {
- fprintf (stderr, "fremovexattr failed : %s\n", strerror (errno));
- goto out;
- }
-
- ret = 0;
+ int fd = 0;
+ int newfd = 0;
+ int ret = -1;
+ struct stat stbuf = {
+ 0,
+ };
+ char wstr[50] = {
+ 0,
+ };
+ char rstr[50] = {
+ 0,
+ };
+
+ fd = open(filename, O_RDWR | O_CREAT);
+ if (fd < 0) {
+ fd = 0;
+ fprintf(stderr, "open failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ newfd = dup(fd);
+ if (newfd < 0) {
+ ret = -1;
+ fprintf(stderr, "dup failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ close(fd);
+
+ strcpy(wstr, "This is my string\n");
+ ret = write(newfd, wstr, strlen(wstr));
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "write failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = lseek(newfd, 0, SEEK_SET);
+ if (ret < 0) {
+ fprintf(stderr, "lseek failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = read(newfd, rstr, strlen(wstr));
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "read failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = memcmp(rstr, wstr, strlen(wstr));
+ if (ret != 0) {
+ ret = -1;
+ fprintf(stderr, "read returning junk\n");
+ goto out;
+ }
+
+ ret = ftruncate(newfd, 0);
+ if (ret < 0) {
+ fprintf(stderr, "ftruncate failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = fstat(newfd, &stbuf);
+ if (ret < 0) {
+ fprintf(stderr, "fstat failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = fchmod(newfd, 0640);
+ if (ret < 0) {
+ fprintf(stderr, "fchmod failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = fchown(newfd, 10001, 10001);
+ if (ret < 0) {
+ fprintf(stderr, "fchown failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = fsync(newfd);
+ if (ret < 0) {
+ fprintf(stderr, "fsync failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = fsetxattr(newfd, "trusted.xattr-test", "working", 8, 0);
+ if (ret < 0) {
+ fprintf(stderr, "fsetxattr failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = fdatasync(newfd);
+ if (ret < 0) {
+ fprintf(stderr, "fdatasync failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = flistxattr(newfd, NULL, 0);
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "flistxattr failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = fgetxattr(newfd, "trusted.xattr-test", NULL, 0);
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "fgetxattr failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = fremovexattr(newfd, "trusted.xattr-test");
+ if (ret < 0) {
+ fprintf(stderr, "fremovexattr failed : %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = 0;
out:
- if (newfd)
- close (newfd);
- ret = unlink (filename);
- if (ret < 0)
- fprintf (stderr, "unlink failed : %s\n", strerror (errno));
+ if (newfd)
+ close(newfd);
+ ret = unlink(filename);
+ if (ret < 0)
+ fprintf(stderr, "unlink failed : %s\n", strerror(errno));
- return ret;
+ return ret;
}
int
-dir_based_fops (char *dirname)
+dir_based_fops(char *dirname)
{
- int ret = -1;
- DIR *dp = NULL;
- char buff[255] = {0,};
- struct dirent *dbuff = {0,};
- struct stat stbuff = {0,};
- char newdname[255] = {0,};
- char *cwd = NULL;
-
- ret = mkdir (dirname, 0755);
- if (ret < 0) {
- fprintf (stderr, "mkdir failed: %s\n", strerror (errno));
- goto out;
- }
-
- dp = opendir (dirname);
- if (dp == NULL) {
- fprintf (stderr, "opendir failed: %s\n", strerror (errno));
- goto out;
- }
-
- dbuff = readdir (dp);
- if (NULL == dbuff) {
- fprintf (stderr, "readdir failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = closedir (dp);
- if (ret < 0) {
- fprintf (stderr, "closedir failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = stat (dirname, &stbuff);
- if (ret < 0) {
- fprintf (stderr, "stat failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = chmod (dirname, 0744);
- if (ret < 0) {
- fprintf (stderr, "chmod failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = chown (dirname, 10001, 10001);
- if (ret < 0) {
- fprintf (stderr, "chmod failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = setxattr (dirname, "trusted.xattr-test", "working", 8, 0);
- if (ret < 0) {
- fprintf (stderr, "setxattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = listxattr (dirname, NULL, 0);
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "listxattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = getxattr (dirname, "trusted.xattr-test", NULL, 0);
- if (ret <= 0) {
- ret = -1;
- fprintf (stderr, "getxattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = removexattr (dirname, "trusted.xattr-test");
- if (ret < 0) {
- fprintf (stderr, "removexattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- strcpy (newdname, dirname);
- strcat (newdname, "/../");
- ret = chdir (newdname);
- if (ret < 0) {
- fprintf (stderr, "chdir failed: %s\n", strerror (errno));
- goto out;
- }
-
- cwd = getcwd (buff, 255);
- if (NULL == cwd) {
- fprintf (stderr, "getcwd failed: %s\n", strerror (errno));
- goto out;
- }
-
- strcpy (newdname, dirname);
- strcat (newdname, "new");
- ret = rename (dirname, newdname);
- if (ret < 0) {
- fprintf (stderr, "rename failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = rmdir (newdname);
- if (ret < 0) {
- fprintf (stderr, "rmdir failed: %s\n", strerror (errno));
- return ret;
- }
+ int ret = -1;
+ DIR *dp = NULL;
+ char buff[255] = {
+ 0,
+ };
+ struct dirent *dbuff = {
+ 0,
+ };
+ struct stat stbuff = {
+ 0,
+ };
+ char newdname[255] = {
+ 0,
+ };
+ char *cwd = NULL;
+
+ ret = mkdir(dirname, 0755);
+ if (ret < 0) {
+ fprintf(stderr, "mkdir failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ dp = opendir(dirname);
+ if (dp == NULL) {
+ fprintf(stderr, "opendir failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ dbuff = readdir(dp);
+ if (NULL == dbuff) {
+ fprintf(stderr, "readdir failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = closedir(dp);
+ if (ret < 0) {
+ fprintf(stderr, "closedir failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = stat(dirname, &stbuff);
+ if (ret < 0) {
+ fprintf(stderr, "stat failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = chmod(dirname, 0744);
+ if (ret < 0) {
+ fprintf(stderr, "chmod failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = chown(dirname, 10001, 10001);
+ if (ret < 0) {
+ fprintf(stderr, "chmod failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = setxattr(dirname, "trusted.xattr-test", "working", 8, 0);
+ if (ret < 0) {
+ fprintf(stderr, "setxattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = listxattr(dirname, NULL, 0);
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "listxattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = getxattr(dirname, "trusted.xattr-test", NULL, 0);
+ if (ret <= 0) {
+ ret = -1;
+ fprintf(stderr, "getxattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = removexattr(dirname, "trusted.xattr-test");
+ if (ret < 0) {
+ fprintf(stderr, "removexattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ strcpy(newdname, dirname);
+ strcat(newdname, "/../");
+ ret = chdir(newdname);
+ if (ret < 0) {
+ fprintf(stderr, "chdir failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ cwd = getcwd(buff, 255);
+ if (NULL == cwd) {
+ fprintf(stderr, "getcwd failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ strcpy(newdname, dirname);
+ strcat(newdname, "new");
+ ret = rename(dirname, newdname);
+ if (ret < 0) {
+ fprintf(stderr, "rename failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = rmdir(newdname);
+ if (ret < 0) {
+ fprintf(stderr, "rmdir failed: %s\n", strerror(errno));
+ return ret;
+ }
out:
- rmdir (dirname);
- return ret;
+ rmdir(dirname);
+ return ret;
}
int
-link_based_fops (char *filename)
+link_based_fops(char *filename)
{
- int ret = -1;
- int fd = 0;
- char newname[255] = {0,};
- char linkname[255] = {0,};
- struct stat lstbuf = {0,};
-
- fd = creat (filename, 0644);
- if (fd < 0) {
- fd = 0;
- fprintf (stderr, "creat failed: %s\n", strerror (errno));
- goto out;
- }
-
- strcpy (newname, filename);
- strcat (newname, "_hlink");
- ret = link (filename, newname);
- if (ret < 0) {
- fprintf (stderr, "link failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = unlink (filename);
- if (ret < 0) {
- fprintf (stderr, "unlink failed: %s\n", strerror (errno));
- goto out;
- }
-
- strcpy (linkname, filename);
- strcat (linkname, "_slink");
- ret = symlink (newname, linkname);
- if (ret < 0) {
- fprintf (stderr, "symlink failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = lstat (linkname, &lstbuf);
- if (ret < 0) {
- fprintf (stderr, "lstbuf failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = lchown (linkname, 10001, 10001);
- if (ret < 0) {
- fprintf (stderr, "lchown failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = lsetxattr (linkname, "trusted.lxattr-test", "working", 8, 0);
- if (ret < 0) {
- fprintf (stderr, "lsetxattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = llistxattr (linkname, NULL, 0);
- if (ret < 0) {
- ret = -1;
- fprintf (stderr, "llistxattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = lgetxattr (linkname, "trusted.lxattr-test", NULL, 0);
- if (ret < 0) {
- ret = -1;
- fprintf (stderr, "lgetxattr failed: %s\n", strerror (errno));
- goto out;
- }
-
- ret = lremovexattr (linkname, "trusted.lxattr-test");
- if (ret < 0) {
- fprintf (stderr, "lremovexattr failed: %s\n", strerror (errno));
- goto out;
- }
-
+ int ret = -1;
+ int fd = 0;
+ char newname[255] = {
+ 0,
+ };
+ char linkname[255] = {
+ 0,
+ };
+ struct stat lstbuf = {
+ 0,
+ };
+
+ fd = creat(filename, 0644);
+ if (fd < 0) {
+ fd = 0;
+ fprintf(stderr, "creat failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ strcpy(newname, filename);
+ strcat(newname, "_hlink");
+ ret = link(filename, newname);
+ if (ret < 0) {
+ fprintf(stderr, "link failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = unlink(filename);
+ if (ret < 0) {
+ fprintf(stderr, "unlink failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ strcpy(linkname, filename);
+ strcat(linkname, "_slink");
+ ret = symlink(newname, linkname);
+ if (ret < 0) {
+ fprintf(stderr, "symlink failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = lstat(linkname, &lstbuf);
+ if (ret < 0) {
+ fprintf(stderr, "lstbuf failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = lchown(linkname, 10001, 10001);
+ if (ret < 0) {
+ fprintf(stderr, "lchown failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = lsetxattr(linkname, "trusted.lxattr-test", "working", 8, 0);
+ if (ret < 0) {
+ fprintf(stderr, "lsetxattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = llistxattr(linkname, NULL, 0);
+ if (ret < 0) {
+ ret = -1;
+ fprintf(stderr, "llistxattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = lgetxattr(linkname, "trusted.lxattr-test", NULL, 0);
+ if (ret < 0) {
+ ret = -1;
+ fprintf(stderr, "lgetxattr failed: %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = lremovexattr(linkname, "trusted.lxattr-test");
+ if (ret < 0) {
+ fprintf(stderr, "lremovexattr failed: %s\n", strerror(errno));
+ goto out;
+ }
out:
- if (fd)
- close(fd);
- unlink (linkname);
- unlink (newname);
+ if (fd)
+ close(fd);
+ unlink(linkname);
+ unlink(newname);
}
int
-test_open_modes (char *filename)
+test_open_modes(char *filename)
{
- int ret = -1;
-
- ret = generic_open_read_write (filename, O_CREAT|O_WRONLY);
- if (3 != ret) {
- fprintf (stderr, "flag O_CREAT|O_WRONLY failed: \n");
- goto out;
- }
-
- ret = generic_open_read_write (filename, O_CREAT|O_RDWR);
- if (ret != 0) {
- fprintf (stderr, "flag O_CREAT|O_RDWR failed\n");
- goto out;
- }
-
- ret = generic_open_read_write (filename, O_CREAT|O_RDONLY);
- if (ret != 0) {
- fprintf (stderr, "flag O_CREAT|O_RDONLY failed\n");
- goto out;
- }
-
- ret = creat (filename, 0644);
- close (ret);
- ret = generic_open_read_write (filename, O_WRONLY);
- if (3 != ret) {
- fprintf (stderr, "flag O_WRONLY failed\n");
- goto out;
- }
-
- ret = creat (filename, 0644);
- close (ret);
- ret = generic_open_read_write (filename, O_RDWR);
- if (0 != ret) {
- fprintf (stderr, "flag O_RDWR failed\n");
- goto out;
- }
-
- ret = creat (filename, 0644);
- close (ret);
- ret = generic_open_read_write (filename, O_RDONLY);
- if (0 != ret) {
- fprintf (stderr, "flag O_RDONLY failed\n");
- goto out;
- }
-
- ret = creat (filename, 0644);
- close (ret);
- ret = generic_open_read_write (filename, O_TRUNC|O_WRONLY);
- if (3 != ret) {
- fprintf (stderr, "flag O_TRUNC|O_WRONLY failed\n");
- goto out;
- }
+ int ret = -1;
+
+ ret = generic_open_read_write(filename, O_CREAT | O_WRONLY);
+ if (3 != ret) {
+ fprintf(stderr, "flag O_CREAT|O_WRONLY failed: \n");
+ goto out;
+ }
+
+ ret = generic_open_read_write(filename, O_CREAT | O_RDWR);
+ if (ret != 0) {
+ fprintf(stderr, "flag O_CREAT|O_RDWR failed\n");
+ goto out;
+ }
+
+ ret = generic_open_read_write(filename, O_CREAT | O_RDONLY);
+ if (ret != 0) {
+ fprintf(stderr, "flag O_CREAT|O_RDONLY failed\n");
+ goto out;
+ }
+
+ ret = creat(filename, 0644);
+ close(ret);
+ ret = generic_open_read_write(filename, O_WRONLY);
+ if (3 != ret) {
+ fprintf(stderr, "flag O_WRONLY failed\n");
+ goto out;
+ }
+
+ ret = creat(filename, 0644);
+ close(ret);
+ ret = generic_open_read_write(filename, O_RDWR);
+ if (0 != ret) {
+ fprintf(stderr, "flag O_RDWR failed\n");
+ goto out;
+ }
+
+ ret = creat(filename, 0644);
+ close(ret);
+ ret = generic_open_read_write(filename, O_RDONLY);
+ if (0 != ret) {
+ fprintf(stderr, "flag O_RDONLY failed\n");
+ goto out;
+ }
+
+ ret = creat(filename, 0644);
+ close(ret);
+ ret = generic_open_read_write(filename, O_TRUNC | O_WRONLY);
+ if (3 != ret) {
+ fprintf(stderr, "flag O_TRUNC|O_WRONLY failed\n");
+ goto out;
+ }
#if 0 /* undefined behaviour, unable to reliably test */
ret = creat (filename, 0644);
@@ -785,84 +833,88 @@ test_open_modes (char *filename)
}
#endif
- ret = generic_open_read_write (filename, O_CREAT|O_RDWR|O_SYNC);
- if (0 != ret) {
- fprintf (stderr, "flag O_CREAT|O_RDWR|O_SYNC failed\n");
- goto out;
- }
+ ret = generic_open_read_write(filename, O_CREAT | O_RDWR | O_SYNC);
+ if (0 != ret) {
+ fprintf(stderr, "flag O_CREAT|O_RDWR|O_SYNC failed\n");
+ goto out;
+ }
- ret = creat (filename, 0644);
- close (ret);
- ret = generic_open_read_write (filename, O_CREAT|O_EXCL);
- if (0 != ret) {
- fprintf (stderr, "flag O_CREAT|O_EXCL failed\n");
- goto out;
- }
+ ret = creat(filename, 0644);
+ close(ret);
+ ret = generic_open_read_write(filename, O_CREAT | O_EXCL);
+ if (0 != ret) {
+ fprintf(stderr, "flag O_CREAT|O_EXCL failed\n");
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
-int generic_open_read_write (char *filename, int flag)
+int
+generic_open_read_write(char *filename, int flag)
{
- int fd = 0;
- int ret = -1;
- char wstring[50] = {0,};
- char rstring[50] = {0,};
-
- fd = open (filename, flag);
- if (fd < 0) {
- if (flag == O_CREAT|O_EXCL && errno == EEXIST) {
- unlink (filename);
- return 0;
- }
- else {
- fd = 0;
- fprintf (stderr, "open failed: %s\n", strerror (errno));
- return 1;
- }
- }
-
- strcpy (wstring, "My string to write\n");
- ret = write (fd, wstring, strlen(wstring));
- if (ret <= 0) {
- if (errno != EBADF) {
- fprintf (stderr, "write failed: %s\n", strerror (errno));
- close (fd);
- unlink(filename);
- return 2;
- }
- }
-
- ret = lseek (fd, 0, SEEK_SET);
- if (ret < 0) {
- close (fd);
- unlink(filename);
- return 4;
- }
-
- ret = read (fd, rstring, strlen(wstring));
- if (ret < 0) {
- close (fd);
- unlink (filename);
- return 3;
- }
-
- /* Compare the rstring with wstring. But we do not want to return
- * error when the flag is either O_RDONLY, O_CREAT|O_RDONLY or
- * O_TRUNC|O_RDONLY. Because in that case we are not writing
- * anything to the file.*/
-
- ret = memcmp (wstring, rstring, strlen (wstring));
- if (0 != ret && !(flag == O_CREAT|O_RDONLY || flag == O_RDONLY ||\
- flag == O_TRUNC|O_RDONLY)) {
- fprintf (stderr, "read is returning junk\n");
- close (fd);
- unlink (filename);
- return 4;
- }
-
- close (fd);
- unlink (filename);
- return 0;
+ int fd = 0;
+ int ret = -1;
+ char wstring[50] = {
+ 0,
+ };
+ char rstring[50] = {
+ 0,
+ };
+
+ fd = open(filename, flag);
+ if (fd < 0) {
+ if (flag == O_CREAT | O_EXCL && errno == EEXIST) {
+ unlink(filename);
+ return 0;
+ } else {
+ fd = 0;
+ fprintf(stderr, "open failed: %s\n", strerror(errno));
+ return 1;
+ }
+ }
+
+ strcpy(wstring, "My string to write\n");
+ ret = write(fd, wstring, strlen(wstring));
+ if (ret <= 0) {
+ if (errno != EBADF) {
+ fprintf(stderr, "write failed: %s\n", strerror(errno));
+ close(fd);
+ unlink(filename);
+ return 2;
+ }
+ }
+
+ ret = lseek(fd, 0, SEEK_SET);
+ if (ret < 0) {
+ close(fd);
+ unlink(filename);
+ return 4;
+ }
+
+ ret = read(fd, rstring, strlen(wstring));
+ if (ret < 0) {
+ close(fd);
+ unlink(filename);
+ return 3;
+ }
+
+ /* Compare the rstring with wstring. But we do not want to return
+ * error when the flag is either O_RDONLY, O_CREAT|O_RDONLY or
+ * O_TRUNC|O_RDONLY. Because in that case we are not writing
+ * anything to the file.*/
+
+ ret = memcmp(wstring, rstring, strlen(wstring));
+ if (0 != ret && !(flag == O_CREAT | O_RDONLY || flag == O_RDONLY ||
+ flag == O_TRUNC | O_RDONLY)) {
+ fprintf(stderr, "read is returning junk\n");
+ close(fd);
+ unlink(filename);
+ return 4;
+ }
+
+ close(fd);
+ unlink(filename);
+ return 0;
}
diff --git a/extras/thin-arbiter/setup-thin-arbiter.sh b/extras/thin-arbiter/setup-thin-arbiter.sh
new file mode 100755
index 00000000000..0681b30ef3f
--- /dev/null
+++ b/extras/thin-arbiter/setup-thin-arbiter.sh
@@ -0,0 +1,184 @@
+#!/bin/bash
+# Copyright (c) 2018-2019 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.
+
+
+# This tool has been developed to setup thin-arbiter process on a node.
+# Seting up a thin arbiter process involves following files -
+# 1 - thin-arbiter.vol
+# Thin-arbiter (TA) process will use the graph in this file to load the
+# required translators.
+# 2 - gluster-ta-volume.service (generated by gluster-ta-volume.service.in)
+# TA process would be running as systemd service.
+#
+# TA process uses a location to save TA id files for every subvolume.
+# This location can be taken as input from user. Once provided and the
+# TA process is started on a node, it can not be changed using this
+# script or by any other mean. The same location should be used in
+# the gluster CLI when creating thin-arbiter volumes.
+
+MYPATH=`dirname $0`
+
+volloc="/var/lib/glusterd/thin-arbiter"
+mkdir -p $volloc
+
+if [ -f /etc/glusterfs/thin-arbiter.vol ]; then
+ volfile=/etc/glusterfs/thin-arbiter.vol
+else
+ volfile=$MYPATH/thin-arbiter.vol
+fi
+
+tafile="$volloc/thin-arbiter.vol"
+
+
+help () {
+ echo " "
+ echo ' This tool helps to setup thin-arbiter (TA) process on a node.
+ TA process uses a location to save TA id files for every subvolume.
+ This location can be taken as input from user. Once provided and the
+ TA process is started on a node, it can not be changed using this script
+ or by any other mean. The same location should be used in gluster CLI
+ when creating thin-arbiter volumes.
+
+ usage: setup-thin-arbiter.sh [-s] [-h]
+ options:
+ -s - Setup thin-arbiter file path and start process
+ -h - Show this help message and exit
+'
+}
+
+volfile_set_brick_path () {
+ while read -r line
+ do
+ dir=`echo "$line" | cut -d' ' -f 2`
+ if [ "$dir" = "directory" ]; then
+ bpath=`echo "$line" | cut -d' ' -f 3`
+ sed -i -- 's?'$bpath'?'$1'?g' $tafile
+ return
+ fi
+ done < $tafile
+}
+
+check_ta_proc () {
+ pro=`ps aux | grep thin-arbiter.vol | grep "volfile-id"`
+ if [ "${pro}" = '' ]; then
+ echo ""
+ else
+ curr_loc=`cat $volloc/thin-arbiter.vol | grep option | grep directory`
+ loc=`echo "${curr_loc##* }"`
+ echo "******************************************************"
+ echo "Error:"
+ echo "Thin-arbiter process is running with thin-arbiter path = $loc"
+ echo "Can not change TA path on this host now."
+ echo "$pro"
+ echo "******************************************************"
+ exit 1
+ fi
+}
+
+getpath () {
+ check_ta_proc
+ echo "******************************************************"
+ echo "User will be required to enter a path/folder for arbiter volume."
+ echo "Please note that this path will be used for ALL VOLUMES using this"
+ echo "node to host thin-arbiter. After setting, if a volume"
+ echo "has been created using this host and path then path for"
+ echo "thin-arbiter can not be changed "
+ echo "******************************************************"
+ echo " "
+ while true;
+ do
+ echo -n "Enter brick path for thin arbiter volumes: "
+ echo " "
+ read tapath
+ if [ "${tapath}" = '' ]; then
+ echo "Please enter valid path"
+ continue
+ else
+ echo "Entered brick path : $tapath "
+ echo "Please note that this brick path will be used for ALL"
+ echo "VOLUMES using this node to host thin-arbiter brick"
+ echo -n "Want to continue? (y/N): "
+ echo " "
+ read cont
+
+ if [ "${cont}" = 'N' ] || [ "${cont}" = 'n' ]; then
+ exit 0
+ else
+ break
+ fi
+ fi
+ done
+}
+
+setup () {
+ getpath
+ mkdir -p $tapath/.glusterfs/indices
+ if [ -d $tapath/.glusterfs/indices ]; then
+ echo " "
+ else
+ echo "Could not create $tapath/.glusterfs/indices directory, check provided ta path."
+ exit 1
+ fi
+
+ cp -f --backup --suffix=_old $volfile $volloc/thin-arbiter.vol
+ volfile_set_brick_path "$tapath"
+
+ echo "Directory path to be used for thin-arbiter volume is: $tapath"
+ echo " "
+ echo "========================================================"
+
+ if [ -f /usr/lib/systemd/system/gluster-ta-volume.service ]; then
+ echo "Starting thin-arbiter process"
+ else
+ cp $MYPATH/../systemd/gluster-ta-volume.service /etc/systemd/system/
+ echo "Starting thin-arbiter process"
+ chmod 0644 /etc/systemd/system/gluster-ta-volume.service
+ fi
+
+ systemctl daemon-reload
+ systemctl enable gluster-ta-volume
+ systemctl stop gluster-ta-volume
+ systemctl start gluster-ta-volume
+
+ if [ $? == 0 ]; then
+ echo "thin-arbiter process has been setup and running"
+ else
+ echo "Failed to setup thin arbiter"
+ exit 1
+ fi
+
+}
+
+main()
+{
+
+ if [ "$#" -ne 1 ]; then
+ help
+ exit 0
+ fi
+
+ while getopts "sh" opt; do
+ case $opt in
+ h)
+ help
+ exit 0
+ ;;
+ s)
+ setup
+ exit 0
+ ;;
+ *)
+ help
+ exit 0
+ ;;
+ esac
+ done
+}
+
+main "$@"
diff --git a/extras/thin-arbiter/thin-arbiter.vol b/extras/thin-arbiter/thin-arbiter.vol
new file mode 100644
index 00000000000..c76babc7b3c
--- /dev/null
+++ b/extras/thin-arbiter/thin-arbiter.vol
@@ -0,0 +1,57 @@
+volume ta-posix
+ type storage/posix
+ option directory /mnt/thin-arbiter
+end-volume
+
+volume ta-thin-arbiter
+ type features/thin-arbiter
+ subvolumes ta-posix
+end-volume
+
+volume ta-locks
+ type features/locks
+ option notify-contention yes
+ subvolumes ta-thin-arbiter
+end-volume
+
+volume ta-upcall
+ type features/upcall
+ option cache-invalidation off
+ subvolumes ta-locks
+end-volume
+
+volume ta-io-threads
+ type performance/io-threads
+ subvolumes ta-upcall
+end-volume
+
+volume ta-index
+ type features/index
+ option xattrop-pending-watchlist trusted.afr.ta-
+ option xattrop-dirty-watchlist trusted.afr.dirty
+ option index-base /mnt/thin-arbiter/.glusterfs/indices
+ subvolumes ta-io-threads
+end-volume
+
+volume /mnt/thin-arbiter
+ type debug/io-stats
+ option count-fop-hits off
+ option latency-measurement off
+ option unique-id /mnt/thin-arbiter
+ subvolumes ta-index
+end-volume
+
+volume ta-server
+ type protocol/server
+ option transport.listen-backlog 10
+ option transport.socket.keepalive-count 9
+ option transport.socket.keepalive-interval 2
+ option transport.socket.keepalive-time 20
+ option transport.tcp-user-timeout 0
+ option transport.socket.keepalive 1
+ option auth.addr./mnt/thin-arbiter.allow *
+ option auth-path /mnt/thin-arbiter
+ option transport.address-family inet
+ option transport-type tcp
+ subvolumes /mnt/thin-arbiter
+end-volume
diff --git a/extras/volfilter.py b/extras/volfilter.py
index 0ca456a7882..5558a1beff4 100644
--- a/extras/volfilter.py
+++ b/extras/volfilter.py
@@ -13,6 +13,7 @@
# You should have received a copy of the GNU General Public License * along
# with HekaFS. If not, see <http://www.gnu.org/licenses/>.
+from __future__ import print_function
import copy
import string
import sys
@@ -35,7 +36,7 @@ good_xlators = [
"storage/posix",
]
-def copy_stack (old_xl,suffix,recursive=False):
+def copy_stack (old_xl, suffix, recursive=False):
if recursive:
new_name = old_xl.name + "-" + suffix
else:
@@ -45,7 +46,7 @@ def copy_stack (old_xl,suffix,recursive=False):
# The results with normal assignment here are . . . amusing.
new_xl.opts = copy.deepcopy(old_xl.opts)
for sv in old_xl.subvols:
- new_xl.subvols.append(copy_stack(sv,suffix,True))
+ new_xl.subvols.append(copy_stack(sv, suffix, True))
# Patch up the path at the bottom.
if new_xl.type == "storage/posix":
new_xl.opts["directory"] += ("/" + suffix)
@@ -63,10 +64,10 @@ def cleanup (parent, graph):
parent.opts["transport-type"] = "ssl"
sv = []
for child in parent.subvols:
- sv.append(cleanup(child,graph))
+ sv.append(cleanup(child, graph))
parent.subvols = sv
else:
- parent = cleanup(parent.subvols[0],graph)
+ parent = cleanup(parent.subvols[0], graph)
return parent
class Translator:
@@ -82,8 +83,8 @@ class Translator:
def load (path):
# If it's a string, open it; otherwise, assume it's already a
# file-like object (most notably from urllib*).
- if type(path) in types.StringTypes:
- fp = file(path,"r")
+ if type(path) in (str,):
+ fp = file(path, "r")
else:
fp = path
all_xlators = {}
@@ -98,16 +99,16 @@ def load (path):
continue
if text[0] == "volume":
if xlator:
- raise RuntimeError, "nested volume definition"
+ raise RuntimeError("nested volume definition")
xlator = Translator(text[1])
continue
if not xlator:
- raise RuntimeError, "text outside volume definition"
+ raise RuntimeError("text outside volume definition")
if text[0] == "type":
xlator.type = text[1]
continue
if text[0] == "option":
- xlator.opts[text[1]] = string.join(text[2:])
+ xlator.opts[text[1]] = ''.join(text[2:])
continue
if text[0] == "subvolumes":
for sv in text[1:]:
@@ -118,25 +119,25 @@ def load (path):
last_xlator = xlator
xlator = None
continue
- raise RuntimeError, "unrecognized keyword %s" % text[0]
+ raise RuntimeError("unrecognized keyword %s" % text[0])
if xlator:
- raise RuntimeError, "unclosed volume definition"
+ raise RuntimeError("unclosed volume definition")
return all_xlators, last_xlator
def generate (graph, last, stream=sys.stdout):
for sv in last.subvols:
if not sv.dumped:
- generate(graph,sv,stream)
- print >> stream, ""
+ generate(graph, sv, stream)
+ print("", file=stream)
sv.dumped = True
- print >> stream, "volume %s" % last.name
- print >> stream, " type %s" % last.type
- for k, v in last.opts.iteritems():
- print >> stream, " option %s %s" % (k, v)
+ print("volume %s" % last.name, file=stream)
+ print(" type %s" % last.type, file=stream)
+ for k, v in last.opts.items():
+ print(" option %s %s" % (k, v), file=stream)
if last.subvols:
- print >> stream, " subvolumes %s" % string.join(
- [ sv.name for sv in last.subvols ])
- print >> stream, "end-volume"
+ print(" subvolumes %s" % ''.join(
+ [ sv.name for sv in last.subvols ]), file=stream)
+ print("end-volume", file=stream)
def push_filter (graph, old_xl, filt_type, opts={}):
suffix = "-" + old_xl.type.split("/")[1]
@@ -156,7 +157,7 @@ def push_filter (graph, old_xl, filt_type, opts={}):
def delete (graph, victim):
if len(victim.subvols) != 1:
- raise RuntimeError, "attempt to delete non-unary translator"
+ raise RuntimeError("attempt to delete non-unary translator")
for xl in graph.itervalues():
while xl.subvols.count(victim):
i = xl.subvols.index(victim)
@@ -164,4 +165,4 @@ def delete (graph, victim):
if __name__ == "__main__":
graph, last = load(sys.argv[1])
- generate(graph,last)
+ generate(graph, last)
diff --git a/extras/who-wrote-glusterfs/gitdm.aliases b/extras/who-wrote-glusterfs/gitdm.aliases
index e19b99c79c8..901c12418e3 100644
--- a/extras/who-wrote-glusterfs/gitdm.aliases
+++ b/extras/who-wrote-glusterfs/gitdm.aliases
@@ -16,11 +16,13 @@ anush@gluster.com ashetty@redhat.com
csaba@gluster.com csaba@redhat.com
csaba@lowlife.hu csaba@redhat.com
csaba@zresearch.com csaba@redhat.com
+gd@samba.org gd@redhat.com
harsha@gluster.com fharshav@redhat.com
harsha@zresearch.com fharshav@redhat.com
harsha@dev.gluster.com fharshav@redhat.com
harsha@harshavardhana.net fharshav@redhat.com
jclift@redhat.com jclift@gluster.org
+kkeithle@linux.keithley.org kkeithle@redhat.com
kkeithle@f16node1.kkeithle.usersys.redhat.com kkeithle@redhat.com
kaushal@gluster.com kaushal@redhat.com
kaushikbv@gluster.com kbudiger@redhat.com
@@ -32,6 +34,9 @@ me@louiszuckerman.com louiszuckerman@gmail.com
msvbhat@gmail.com vbhat@redhat.com
nullpai@gmail.com ppai@redhat.com
vishwanath@gluster.com vbhat@redhat.com
+obnox@samba.org madam@redhat.com
+oleksandr@natalenko.name o.natalenko@lanet.ua
+patrick@puiterwijk.org puiterwijk@fedoraproject.org
pavan@dev.gluster.com pavan@gluster.com
zaitcev@yahoo.com zaitcev@kotori.zaitcev.us
pranithk@gluster.com pkarampu@redhat.com
@@ -41,6 +46,8 @@ raghavendra@zresearch.com rgowdapp@redhat.com
rahulcssjce@gmail.com rahulcs@redhat.com
rajesh@gluster.com rajesh@redhat.com
rajesh.amaravathi@gmail.com rajesh@redhat.com
+root@ravi2.(none) ravishankar@redhat.com
+sabansal@localhost.localdomain sabansal@redhat.com
shehjart@zresearch.com shehjart@gluster.com
venky@gluster.com vshankar@redhat.com
vijay@gluster.com vbellur@redhat.com
@@ -48,3 +55,4 @@ vijay@dev.gluster.com vbellur@redhat.com
vijaykumar.koppad@gmail.com vkoppad@redhat.com
vikas@zresearch.com vikas@gluster.com
shishirng@gluster.com sgowda@redhat.com
+potatogim@potatogim.net potatogim@gluesys.com
diff --git a/extras/who-wrote-glusterfs/gitdm.domain-map b/extras/who-wrote-glusterfs/gitdm.domain-map
index 39526f0f99c..7cd2bbd605b 100644
--- a/extras/who-wrote-glusterfs/gitdm.domain-map
+++ b/extras/who-wrote-glusterfs/gitdm.domain-map
@@ -2,15 +2,28 @@
# Here is a set of mappings of domain names onto employer names.
#
active.by ActiveCloud
+appeartv.com Appear TV
cern.ch CERN
+cmss.chinamobile.com China Mobile(Suzhou) Software Technology
+datalab.es DataLab S.L.
+fb.com Facebook
+fedoraproject.org Fedora Project
gluster.com Red Hat
-gmail.com (unknown)
+gmail.com (personal contributions)
gooddata.com GoodData
hastexo.com hastexo
+horde.com (personal contributions)
ibm.com IBM
+io.com IO
+lanet.ua Lanet Network
linbit.com LINBIT
+nectec.or.th NECTEC
netbsd.org NetBSD
netdirect.ca Net Direct
+nokia.com Nokia
redhat.com Red Hat
stepping-stone.ch stepping stone GmbH
+xtaotech.com XTAO Co.
+yahoo.in (personal contributions)
zresearch.com Red Hat
+gluesys.com Gluesys
diff --git a/geo-replication/Makefile.am b/geo-replication/Makefile.am
index 556951d9fb7..591b23d0eaf 100644
--- a/geo-replication/Makefile.am
+++ b/geo-replication/Makefile.am
@@ -1,3 +1,8 @@
SUBDIRS = syncdaemon src
CLEANFILES =
+
+EXTRA_DIST = gsyncd.conf.in
+
+gsyncdconfdir = $(sysconfdir)/glusterfs/
+gsyncdconf_DATA = gsyncd.conf
diff --git a/geo-replication/gsyncd.conf.in b/geo-replication/gsyncd.conf.in
new file mode 100644
index 00000000000..9688c79fab7
--- /dev/null
+++ b/geo-replication/gsyncd.conf.in
@@ -0,0 +1,349 @@
+[__meta__]
+version = 4.0
+
+[master-bricks]
+configurable=false
+
+[slave-bricks]
+configurable=false
+
+[master-volume-id]
+configurable=false
+
+[slave-volume-id]
+configurable=false
+
+[master-replica-count]
+configurable=false
+type=int
+value=1
+
+[master-disperse-count]
+configurable=false
+type=int
+value=1
+
+[master-distribution-count]
+configurable=false
+type=int
+value=1
+
+[glusterd-workdir]
+value = @GLUSTERD_WORKDIR@
+
+[gluster-logdir]
+value = /var/log/glusterfs
+
+[gluster-rundir]
+value = /var/run/gluster
+
+[gsyncd-miscdir]
+value = /var/lib/misc/gluster/gsyncd
+
+[stime-xattr-prefix]
+value=
+
+[checkpoint]
+value=0
+help=Set Checkpoint
+validation=unixtime
+type=int
+
+[gluster-cli-options]
+value=
+help=Gluster CLI Options
+
+[pid-file]
+value=${gluster_rundir}/gsyncd-${master}-${primary_slave_host}-${slavevol}.pid
+configurable=false
+template = true
+help=PID file path
+
+[state-file]
+value=${glusterd_workdir}/geo-replication/${master}_${primary_slave_host}_${slavevol}/monitor.status
+configurable=false
+template=true
+help=Status File path
+
+[georep-session-working-dir]
+value=${glusterd_workdir}/geo-replication/${master}_${primary_slave_host}_${slavevol}/
+template=true
+help=Session Working directory
+configurable=false
+
+[access-mount]
+value=false
+type=bool
+validation=bool
+help=Do not lazy unmount the master volume. This allows admin to access the mount for debugging.
+
+[slave-access-mount]
+value=false
+type=bool
+validation=bool
+help=Do not lazy unmount the slave volume. This allows admin to access the mount for debugging.
+
+[isolated-slaves]
+value=
+help=List of Slave nodes which are isolated
+
+[changelog-batch-size]
+# Max size of Changelogs to process per batch, Changelogs Processing is
+# not limited by the number of changelogs but instead based on
+# size of the changelog file, One sample changelog file size was 145408
+# with ~1000 CREATE and ~1000 DATA. 5 such files in one batch is 727040
+# If geo-rep worker crashes while processing a batch, it has to retry only
+# that batch since stime will get updated after each batch.
+value=727040
+help=Max size of Changelogs to process per batch.
+type=int
+
+[slave-timeout]
+value=120
+type=int
+help=Timeout in seconds for Slave Gsyncd. If no activity from master for this timeout, Slave gsyncd will be disconnected. Set Timeout to zero to skip this check.
+
+[connection-timeout]
+value=60
+type=int
+help=Timeout for mounts
+
+[replica-failover-interval]
+value=1
+type=int
+help=Minimum time interval in seconds for passive worker to become Active
+
+[changelog-archive-format]
+value=%Y%m
+help=Processed changelogs will be archived in working directory. Pattern for archive file
+
+[use-meta-volume]
+value=false
+type=bool
+help=Use this to set Active Passive mode to meta-volume.
+
+[meta-volume-mnt]
+value=/run/gluster/shared_storage
+help=Meta Volume or Shared Volume mount path
+
+[allow-network]
+value=
+
+[change-interval]
+value=5
+type=int
+
+[sync-method]
+value=rsync
+help=Sync method for data sync. Available methods are tar over ssh and rsync. Default is rsync.
+validation=choice
+allowed_values=tarssh,rsync
+
+[remote-gsyncd]
+value =
+help=If SSH keys are not secured with gsyncd prefix then use this configuration to set the actual path of gsyncd(Usually /usr/libexec/glusterfs/gsyncd)
+
+[gluster-command-dir]
+value=@SBIN_DIR@
+help=Directory where Gluster binaries exist on master
+
+[slave-gluster-command-dir]
+value=@SBIN_DIR@
+help=Directory where Gluster binaries exist on slave
+
+[gluster-params]
+value = aux-gfid-mount acl
+help=Parameters for Gluster Geo-rep mount in Master
+
+[slave-gluster-params]
+value = aux-gfid-mount acl
+help=Parameters for Gluster Geo-rep mount in Slave
+
+[ignore-deletes]
+value = false
+type=bool
+help=Do not sync deletes in Slave
+
+[special-sync-mode]
+# tunables for failover/failback mechanism:
+# None - gsyncd behaves as normal
+# blind - gsyncd works with xtime pairs to identify
+# candidates for synchronization
+# wrapup - same as normal mode but does not assign
+# xtimes to orphaned files
+# see crawl() for usage of the above tunables
+value =
+help=
+
+[gfid-conflict-resolution]
+value = true
+validation=bool
+type=bool
+help=Disables automatic gfid conflict resolution while syncing
+
+[working-dir]
+value = ${gsyncd_miscdir}/${master}_${primary_slave_host}_${slavevol}/
+template=true
+configurable=false
+help=Working directory for storing Changelogs
+
+[change-detector]
+value=changelog
+help=Change detector
+validation=choice
+allowed_values=changelog,xsync
+
+[cli-log-file]
+value=${gluster_logdir}/geo-replication/cli.log
+template=true
+configurable=false
+
+[cli-log-level]
+value=INFO
+help=Set CLI Log Level
+validation=choice
+allowed_values=ERROR,INFO,WARNING,DEBUG
+
+[log-file]
+value=${gluster_logdir}/geo-replication/${master}_${primary_slave_host}_${slavevol}/gsyncd.log
+configurable=false
+template=true
+
+[changelog-log-file]
+value=${gluster_logdir}/geo-replication/${master}_${primary_slave_host}_${slavevol}/changes-${local_id}.log
+configurable=false
+template=true
+
+[gluster-log-file]
+value=${gluster_logdir}/geo-replication/${master}_${primary_slave_host}_${slavevol}/mnt-${local_id}.log
+template=true
+configurable=false
+
+[slave-log-file]
+value=${gluster_logdir}/geo-replication-slaves/${master}_${primary_slave_host}_${slavevol}/gsyncd.log
+template=true
+configurable=false
+
+[slave-gluster-log-file]
+value=${gluster_logdir}/geo-replication-slaves/${master}_${primary_slave_host}_${slavevol}/mnt-${master_node}-${master_brick_id}.log
+template=true
+configurable=false
+
+[slave-gluster-log-file-mbr]
+value=${gluster_logdir}/geo-replication-slaves/${master}_${primary_slave_host}_${slavevol}/mnt-mbr-${master_node}-${master_brick_id}.log
+template=true
+configurable=false
+
+[log-level]
+value=INFO
+help=Set Log Level
+validation=choice
+allowed_values=ERROR,INFO,WARNING,DEBUG
+
+[gluster-log-level]
+value=INFO
+help=Set Gluster mount Log Level
+validation=choice
+allowed_values=ERROR,INFO,WARNING,DEBUG
+
+[changelog-log-level]
+value=INFO
+help=Set Changelog Log Level
+validation=choice
+allowed_values=ERROR,INFO,WARNING,DEBUG
+
+[slave-log-level]
+value=INFO
+help=Set Slave Gsyncd Log Level
+validation=choice
+allowed_values=ERROR,INFO,WARNING,DEBUG
+
+[slave-gluster-log-level]
+value=INFO
+help=Set Slave Gluster mount Log Level
+validation=choice
+allowed_values=ERROR,INFO,WARNING,DEBUG
+
+[ssh-port]
+value=22
+validation=minmax
+min=1
+max=65535
+help=Set SSH port
+type=int
+
+[ssh-command]
+value=ssh
+help=Set ssh binary path
+validation=execpath
+
+[tar-command]
+value=tar
+help=Set tar command path
+validation=execpath
+
+[ssh-options]
+value = -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i ${glusterd_workdir}/geo-replication/secret.pem
+template=true
+
+[ssh-options-tar]
+value = -oPasswordAuthentication=no -oStrictHostKeyChecking=no -i ${glusterd_workdir}/geo-replication/tar_ssh.pem
+template=true
+
+[gluster-command]
+value=gluster
+help=Set gluster binary path
+validation=execpath
+
+[sync-jobs]
+value=3
+help=Number of Syncer jobs
+validation=minmax
+min=1
+max=100
+type=int
+
+[rsync-command]
+value=rsync
+help=Set rsync command path
+validation=execpath
+
+[rsync-options]
+value=
+
+[rsync-ssh-options]
+value=
+
+[rsync-opt-ignore-missing-args]
+value=true
+type=bool
+
+[rsync-opt-existing]
+value=true
+type=bool
+
+[log-rsync-performance]
+value=false
+help=Log Rsync performance
+validation=bool
+type=bool
+
+[use-rsync-xattrs]
+value=false
+type=bool
+
+[sync-xattrs]
+value=true
+type=bool
+
+[sync-acls]
+value=true
+type=bool
+
+[max-rsync-retries]
+value=10
+type=int
+
+[state_socket_unencoded]
+# Unused, For backward compatibility
+value=
diff --git a/geo-replication/setup.py b/geo-replication/setup.py
index 6d678baa2f7..0eae469d2d6 100644
--- a/geo-replication/setup.py
+++ b/geo-replication/setup.py
@@ -1,7 +1,7 @@
#
# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
-
+#
# This file is licensed to you under your choice of the GNU Lesser
# General Public License, version 3 or any later version (LGPLv3 or
# later), or the GNU General Public License, version 2 (GPLv2), in all
@@ -20,11 +20,11 @@ setup(
name=name,
version="",
description='GlusterFS Geo Replication',
- license='',
+ license='GPLV2 and LGPLV3+',
author='Red Hat, Inc.',
author_email='gluster-devel@gluster.org',
url='http://www.gluster.org',
- packages=['syncdaemon', ],
+ packages=[name, ],
test_suite='nose.collector',
install_requires=[],
scripts=[],
diff --git a/geo-replication/src/Makefile.am b/geo-replication/src/Makefile.am
index 1572698f8ae..9937a0bd026 100644
--- a/geo-replication/src/Makefile.am
+++ b/geo-replication/src/Makefile.am
@@ -1,11 +1,13 @@
-gsyncddir = $(libexecdir)/glusterfs
+gsyncddir = $(GLUSTERFS_LIBEXECDIR)
gsyncd_SCRIPTS = gverify.sh peer_gsec_create \
- set_geo_rep_pem_keys.sh peer_mountbroker
+ set_geo_rep_pem_keys.sh peer_mountbroker peer_mountbroker.py \
+ peer_georep-sshkey.py
# peer_gsec_create and peer_add_secret_pub are not added to
# EXTRA_DIST as it's derived from a .in file
-EXTRA_DIST = gverify.sh set_geo_rep_pem_keys.sh
+EXTRA_DIST = gverify.sh set_geo_rep_pem_keys.sh peer_mountbroker.py.in \
+ peer_georep-sshkey.py.in
gsyncd_PROGRAMS = gsyncd
@@ -17,16 +19,30 @@ gsyncd_LDFLAGS = $(GF_LDFLAGS)
noinst_HEADERS = procdiggy.h
-AM_CPPFLAGS = $(GF_CPPFLAGS) \
- -I$(top_srcdir)/libglusterfs/src\
- -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\
- -DUSE_LIBGLUSTERFS\
+AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \
+ -DGSYNCD_PREFIX=\"$(GLUSTERFS_LIBEXECDIR)\" -DUSE_LIBGLUSTERFS \
-DSBIN_DIR=\"$(sbindir)\" -DPYTHON=\"$(PYTHON)\"
AM_CFLAGS = -Wall $(GF_CFLAGS)
-
CLEANFILES =
$(top_builddir)/libglusterfs/src/libglusterfs.la:
$(MAKE) -C $(top_builddir)/libglusterfs/src/ all
+
+
+install-exec-hook:
+ $(mkdir_p) $(DESTDIR)$(sbindir)
+ rm -f $(DESTDIR)$(sbindir)/gluster-mountbroker
+ ln -s $(GLUSTERFS_LIBEXECDIR)/peer_mountbroker.py \
+ $(DESTDIR)$(sbindir)/gluster-mountbroker
+
+ rm -f $(DESTDIR)$(sbindir)/gluster-georep-sshkey
+ ln -s $(GLUSTERFS_LIBEXECDIR)/peer_georep-sshkey.py \
+ $(DESTDIR)$(sbindir)/gluster-georep-sshkey
+
+
+uninstall-hook:
+ rm -f $(DESTDIR)$(sbindir)/gluster-mountbroker
+ rm -f $(DESTDIR)$(sbindir)/gluster-georep-sshkey
diff --git a/geo-replication/src/gsyncd.c b/geo-replication/src/gsyncd.c
index c9c863ca2fd..b5aeec5bf33 100644
--- a/geo-replication/src/gsyncd.c
+++ b/geo-replication/src/gsyncd.c
@@ -7,6 +7,8 @@
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
+#include <glusterfs/compat.h>
+#include <glusterfs/syscall.h>
#include <stdlib.h>
#include <stdio.h>
@@ -22,13 +24,13 @@
* We unconditionally pass then while building gsyncd binary.
*/
#ifdef USE_LIBGLUSTERFS
-#include "glusterfs.h"
-#include "globals.h"
-#include "defaults.h"
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/globals.h>
+#include <glusterfs/defaults.h>
#endif
-#include "common-utils.h"
-#include "run.h"
+#include <glusterfs/common-utils.h>
+#include <glusterfs/run.h>
#include "procdiggy.h"
#define _GLUSTERD_CALLED_ "_GLUSTERD_CALLED_"
@@ -40,387 +42,361 @@
int restricted = 0;
static int
-duplexpand (void **buf, size_t tsiz, size_t *len)
+duplexpand(void **buf, size_t tsiz, size_t *len)
{
- size_t osiz = tsiz * *len;
- char *p = realloc (*buf, osiz << 1);
- if (!p) {
- free(*buf);
- return -1;
- }
+ size_t osiz = tsiz * *len;
+ char *p = realloc(*buf, osiz << 1);
+ if (!p) {
+ return -1;
+ }
- memset (p + osiz, 0, osiz);
- *buf = p;
- *len <<= 1;
+ memset(p + osiz, 0, osiz);
+ *buf = p;
+ *len <<= 1;
- return 0;
+ return 0;
}
static int
-str2argv (char *str, char ***argv)
+str2argv(char *str, char ***argv)
{
- char *p = NULL;
- char *savetok = NULL;
- char *temp = NULL;
- char *temp1 = NULL;
- int argc = 0;
- size_t argv_len = 32;
- int ret = 0;
- int i = 0;
-
- assert (str);
- temp = str = strdup (str);
- if (!str)
+ char *p = NULL;
+ char *savetok = NULL;
+ char *temp = NULL;
+ char *temp1 = NULL;
+ int argc = 0;
+ size_t argv_len = 32;
+ int ret = 0;
+ int i = 0;
+
+ assert(str);
+ temp = str = strdup(str);
+ if (!str)
+ goto error;
+
+ *argv = calloc(argv_len, sizeof(**argv));
+ if (!*argv)
+ goto error;
+
+ while ((p = strtok_r(str, " ", &savetok))) {
+ str = NULL;
+
+ argc++;
+ if (argc == argv_len) {
+ ret = duplexpand((void *)argv, sizeof(**argv), &argv_len);
+ if (ret == -1)
goto error;
-
- *argv = calloc (argv_len, sizeof (**argv));
- if (!*argv)
- goto error;
-
- while ((p = strtok_r (str, " ", &savetok))) {
- str = NULL;
-
- argc++;
- if (argc == argv_len) {
- ret = duplexpand ((void *)argv,
- sizeof (**argv),
- &argv_len);
- if (ret == -1)
- goto error;
- }
- temp1 = strdup (p);
- if (!temp1)
- goto error;
- (*argv)[argc - 1] = temp1;
}
-
- free(temp);
- return argc;
-
- error:
- fprintf (stderr, "out of memory\n");
- free(temp);
- for (i = 0; i < argc - 1; i++)
- free((*argv)[i]);
- free(*argv);
- return -1;
+ temp1 = strdup(p);
+ if (!temp1)
+ goto error;
+ (*argv)[argc - 1] = temp1;
+ }
+
+ free(temp);
+ return argc;
+
+error:
+ fprintf(stderr, "out of memory\n");
+ free(temp);
+ for (i = 0; i < argc - 1; i++)
+ free((*argv)[i]);
+ free(*argv);
+ return -1;
}
static int
-invoke_gsyncd (int argc, char **argv)
+invoke_gsyncd(int argc, char **argv)
{
- char config_file[PATH_MAX] = {0,};
- size_t gluster_workdir_len = 0;
- runner_t runner = {0,};
- int i = 0;
- int j = 0;
- char *nargv[argc + 4];
- char *python = NULL;
-
- if (restricted) {
- size_t len;
- /* in restricted mode we forcibly use the system-wide config */
- runinit (&runner);
- runner_add_args (&runner, SBIN_DIR"/gluster",
- "--remote-host=localhost",
- "--log-file=-", "system::", "getwd",
- NULL);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- if (runner_start (&runner) == 0 &&
- fgets (config_file, PATH_MAX,
- runner_chio (&runner, STDOUT_FILENO)) != NULL &&
- (len = strlen (config_file)) &&
- config_file[len - 1] == '\n' &&
- runner_end (&runner) == 0)
- gluster_workdir_len = len - 1;
-
- if (gluster_workdir_len) {
- if (gluster_workdir_len + 1 + strlen (GSYNCD_CONF_TEMPLATE) + 1 >
- PATH_MAX)
- goto error;
- config_file[gluster_workdir_len] = '/';
- strcat (config_file, GSYNCD_CONF_TEMPLATE);
- } else
- goto error;
-
- if (setenv ("_GSYNCD_RESTRICTED_", "1", 1) == -1)
- goto error;
- }
+ int i = 0;
+ int j = 0;
+ char *nargv[argc + 4];
+ char *python = NULL;
- if (chdir ("/") == -1)
- goto error;
+ if (chdir("/") == -1)
+ goto error;
- j = 0;
- python = getenv("PYTHON");
- if(!python)
- python = PYTHON;
- nargv[j++] = python;
- nargv[j++] = GSYNCD_PREFIX"/python/syncdaemon/"GSYNCD_PY;
- for (i = 1; i < argc; i++)
- nargv[j++] = argv[i];
- if (config_file[0]) {
- nargv[j++] = "-c";
- nargv[j++] = config_file;
- }
- nargv[j++] = NULL;
+ j = 0;
+ python = getenv("PYTHON");
+ if (!python)
+ python = PYTHON;
+ nargv[j++] = python;
+ nargv[j++] = GSYNCD_PREFIX "/python/syncdaemon/" GSYNCD_PY;
+ for (i = 1; i < argc; i++)
+ nargv[j++] = argv[i];
- execvp (python, nargv);
+ nargv[j++] = NULL;
- fprintf (stderr, "exec of '%s' failed\n", python);
- return 127;
+ execvp(python, nargv);
- error:
- fprintf (stderr, "gsyncd initializaion failed\n");
- return 1;
-}
+ fprintf(stderr, "exec of '%s' failed\n", python);
+ return 127;
+error:
+ fprintf(stderr, "gsyncd initializaion failed\n");
+ return 1;
+}
static int
-find_gsyncd (pid_t pid, pid_t ppid, char *name, void *data)
+find_gsyncd(pid_t pid, pid_t ppid, char *name, void *data)
{
- char buf[NAME_MAX * 2] = {0,};
- char path[PATH_MAX] = {0,};
- char *p = NULL;
- int zeros = 0;
- int ret = 0;
- int fd = -1;
- pid_t *pida = (pid_t *)data;
-
- if (ppid != pida[0])
- return 0;
-
- sprintf (path, PROC"/%d/cmdline", pid);
- fd = open (path, O_RDONLY);
- if (fd == -1)
- return 0;
- ret = read (fd, buf, sizeof (buf));
- close (fd);
- if (ret == -1)
- return 0;
- for (zeros = 0, p = buf; zeros < 2 && p < buf + ret; p++)
- zeros += !*p;
-
- ret = 0;
- switch (zeros) {
+ char buf[NAME_MAX * 2] = {
+ 0,
+ };
+ char path[PATH_MAX] = {
+ 0,
+ };
+ char *p = NULL;
+ int zeros = 0;
+ int ret = 0;
+ int fd = -1;
+ pid_t *pida = (pid_t *)data;
+
+ if (ppid != pida[0])
+ return 0;
+
+ snprintf(path, sizeof path, PROC "/%d/cmdline", pid);
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return 0;
+ ret = sys_read(fd, buf, sizeof(buf));
+ sys_close(fd);
+ if (ret == -1)
+ return 0;
+ for (zeros = 0, p = buf; zeros < 2 && p < buf + ret; p++)
+ zeros += !*p;
+
+ ret = 0;
+ switch (zeros) {
case 2:
- if ((strcmp (basename (buf), basename (PYTHON)) ||
- strcmp (basename (buf + strlen (buf) + 1), GSYNCD_PY)) == 0) {
- ret = 1;
- break;
- }
- /* fallthrough */
+ if ((strcmp(basename(buf), basename(PYTHON)) ||
+ strcmp(basename(buf + strlen(buf) + 1), GSYNCD_PY)) == 0) {
+ ret = 1;
+ break;
+ }
+ /* fallthrough */
case 1:
- if (strcmp (basename (buf), GSYNCD_PY) == 0)
- ret = 1;
- }
-
- if (ret == 1) {
- if (pida[1] != -1) {
- fprintf (stderr, GSYNCD_PY" sibling is not unique");
- return -1;
- }
- pida[1] = pid;
+ if (strcmp(basename(buf), GSYNCD_PY) == 0)
+ ret = 1;
+ }
+
+ if (ret == 1) {
+ if (pida[1] != -1) {
+ fprintf(stderr, GSYNCD_PY " sibling is not unique");
+ return -1;
}
+ pida[1] = pid;
+ }
- return 0;
+ return 0;
}
static int
-invoke_rsync (int argc, char **argv)
+invoke_rsync(int argc, char **argv)
{
- int i = 0;
- char path[PATH_MAX] = {0,};
- pid_t pid = -1;
- pid_t ppid = -1;
- pid_t pida[] = {-1, -1};
- char *name = NULL;
- char buf[PATH_MAX + 1] = {0,};
- int ret = 0;
-
- assert (argv[argc] == NULL);
-
- if (argc < 2 || strcmp (argv[1], "--server") != 0)
- goto error;
-
- for (i = 2; i < argc && argv[i][0] == '-'; i++);
-
- if (!(i == argc - 2 && strcmp (argv[i], ".") == 0 && argv[i + 1][0] == '/')) {
- fprintf (stderr, "need an rsync invocation without protected args\n");
- goto error;
+ int i = 0;
+ char path[PATH_MAX] = {
+ 0,
+ };
+ pid_t pid = -1;
+ pid_t ppid = -1;
+ pid_t pida[] = {-1, -1};
+ char *name = NULL;
+ char buf[PATH_MAX + 1] = {
+ 0,
+ };
+ int ret = 0;
+
+ assert(argv[argc] == NULL);
+
+ if (argc < 2 || strcmp(argv[1], "--server") != 0)
+ goto error;
+
+ for (i = 2; i < argc && argv[i][0] == '-'; i++)
+ ;
+
+ if (!(i == argc - 2 && strcmp(argv[i], ".") == 0 &&
+ argv[i + 1][0] == '/')) {
+ fprintf(stderr, "need an rsync invocation without protected args\n");
+ goto error;
+ }
+
+ /* look up sshd we are spawned from */
+ for (pid = getpid();; pid = ppid) {
+ ppid = pidinfo(pid, &name);
+ if (ppid < 0) {
+ fprintf(stderr, "sshd ancestor not found\n");
+ goto error;
}
-
- /* look up sshd we are spawned from */
- for (pid = getpid () ;; pid = ppid) {
- ppid = pidinfo (pid, &name);
- if (ppid < 0) {
- fprintf (stderr, "sshd ancestor not found\n");
- goto error;
- }
- if (strcmp (name, "sshd") == 0) {
- GF_FREE (name);
- break;
- }
- GF_FREE (name);
+ if (strcmp(name, "sshd") == 0) {
+ GF_FREE(name);
+ break;
}
- /* look up "ssh-sibling" gsyncd */
- pida[0] = pid;
- ret = prociter (find_gsyncd, pida);
- if (ret == -1 || pida[1] == -1) {
- fprintf (stderr, "gsyncd sibling not found\n");
- goto error;
- }
- /* check if rsync target matches gsyncd target */
- sprintf (path, PROC"/%d/cwd", pida[1]);
- ret = readlink (path, buf, sizeof (buf));
- if (ret == -1 || ret == sizeof (buf))
- goto error;
- if (strcmp (argv[argc - 1], "/") == 0 /* root dir cannot be a target */ ||
- (strcmp (argv[argc - 1], path) /* match against gluster target */ &&
- strcmp (argv[argc - 1], buf) /* match against file target */) != 0) {
- fprintf (stderr, "rsync target does not match "GEOREP" session\n");
- goto error;
- }
-
- argv[0] = RSYNC;
-
- execvp (RSYNC, argv);
-
- fprintf (stderr, "exec of "RSYNC" failed\n");
- return 127;
-
- error:
- fprintf (stderr, "disallowed "RSYNC" invocation\n");
- return 1;
+ GF_FREE(name);
+ }
+ /* look up "ssh-sibling" gsyncd */
+ pida[0] = pid;
+ ret = prociter(find_gsyncd, pida);
+ if (ret == -1 || pida[1] == -1) {
+ fprintf(stderr, "gsyncd sibling not found\n");
+ goto error;
+ }
+ /* check if rsync target matches gsyncd target */
+ snprintf(path, sizeof path, PROC "/%d/cwd", pida[1]);
+ ret = sys_readlink(path, buf, sizeof(buf));
+ if (ret == -1 || ret == sizeof(buf))
+ goto error;
+ if (strcmp(argv[argc - 1], "/") == 0 /* root dir cannot be a target */ ||
+ (strcmp(argv[argc - 1], path) /* match against gluster target */ &&
+ strcmp(argv[argc - 1], buf) /* match against file target */) != 0) {
+ fprintf(stderr, "rsync target does not match " GEOREP " session\n");
+ goto error;
+ }
+
+ argv[0] = RSYNC;
+
+ execvp(RSYNC, argv);
+
+ fprintf(stderr, "exec of " RSYNC " failed\n");
+ return 127;
+
+error:
+ fprintf(stderr, "disallowed " RSYNC " invocation\n");
+ return 1;
}
static int
-invoke_gluster (int argc, char **argv)
+invoke_gluster(int argc, char **argv)
{
- int i = 0;
- int j = 0;
- int optsover = 0;
- char *ov = NULL;
-
- for (i = 1; i < argc; i++) {
- ov = strtail (argv[i], "--");
- if (ov && !optsover) {
- if (*ov == '\0')
- optsover = 1;
- continue;
- }
- switch (++j) {
- case 1:
- if (strcmp (argv[i], "volume") != 0)
- goto error;
- break;
- case 2:
- if (strcmp (argv[i], "info") != 0)
- goto error;
- break;
- case 3:
- break;
- default:
- goto error;
- }
+ int i = 0;
+ int j = 0;
+ int optsover = 0;
+ char *ov = NULL;
+
+ for (i = 1; i < argc; i++) {
+ ov = strtail(argv[i], "--");
+ if (ov && !optsover) {
+ if (*ov == '\0')
+ optsover = 1;
+ continue;
}
+ switch (++j) {
+ case 1:
+ if (strcmp(argv[i], "volume") != 0)
+ goto error;
+ break;
+ case 2:
+ if (strcmp(argv[i], "info") != 0)
+ goto error;
+ break;
+ case 3:
+ break;
+ default:
+ goto error;
+ }
+ }
- argv[0] = "gluster";
- execvp (SBIN_DIR"/gluster", argv);
- fprintf (stderr, "exec of gluster failed\n");
- return 127;
+ argv[0] = "gluster";
+ execvp(SBIN_DIR "/gluster", argv);
+ fprintf(stderr, "exec of gluster failed\n");
+ return 127;
- error:
- fprintf (stderr, "disallowed gluster invocation\n");
- return 1;
+error:
+ fprintf(stderr, "disallowed gluster invocation\n");
+ return 1;
}
struct invocable {
- char *name;
- int (*invoker) (int argc, char **argv);
+ char *name;
+ int (*invoker)(int argc, char **argv);
};
-struct invocable invocables[] = {
- { "rsync", invoke_rsync },
- { "gsyncd", invoke_gsyncd },
- { "gluster", invoke_gluster },
- { NULL, NULL}
-};
+struct invocable invocables[] = {{"rsync", invoke_rsync},
+ {"gsyncd", invoke_gsyncd},
+ {"gluster", invoke_gluster},
+ {NULL, NULL}};
int
-main (int argc, char **argv)
+main(int argc, char **argv)
{
- int ret = -1;
- char *evas = NULL;
- struct invocable *i = NULL;
- char *b = NULL;
- char *sargv = NULL;
- int j = 0;
+ int ret = -1;
+ char *evas = NULL;
+ struct invocable *i = NULL;
+ char *b = NULL;
+ char *sargv = NULL;
+ int j = 0;
#ifdef USE_LIBGLUSTERFS
- glusterfs_ctx_t *ctx = NULL;
+ glusterfs_ctx_t *ctx = NULL;
- ctx = glusterfs_ctx_new ();
- if (!ctx)
- return ENOMEM;
+ ctx = glusterfs_ctx_new();
+ if (!ctx)
+ return ENOMEM;
- if (glusterfs_globals_init (ctx))
- return 1;
+ if (glusterfs_globals_init(ctx))
+ return 1;
- THIS->ctx = ctx;
- ret = default_mem_acct_init (THIS);
- if (ret) {
- fprintf (stderr, "internal error: mem accounting failed\n");
- return 1;
- }
+ THIS->ctx = ctx;
+ ret = default_mem_acct_init(THIS);
+ if (ret) {
+ fprintf(stderr, "internal error: mem accounting failed\n");
+ return 1;
+ }
#endif
- evas = getenv (_GLUSTERD_CALLED_);
- if (evas && strcmp (evas, "1") == 0)
- /* OK, we know glusterd called us, no need to look for further config
- *...although this conclusion should not inherit to our children
- */
- unsetenv (_GLUSTERD_CALLED_);
- else {
- /* we regard all gsyncd invocations unsafe
- * that do not come from glusterd and
- * therefore restrict it
- */
- restricted = 1;
-
- if (!getenv (_GSYNCD_DISPATCHED_)) {
- evas = getenv ("SSH_ORIGINAL_COMMAND");
- if (evas)
- sargv = evas;
- else {
- evas = getenv ("SHELL");
- if (evas && strcmp (basename (evas), "gsyncd") == 0 &&
- argc == 3 && strcmp (argv[1], "-c") == 0)
- sargv = argv[2];
- }
- }
-
- }
-
- if (!(sargv && restricted))
- return invoke_gsyncd (argc, argv);
-
- argc = str2argv (sargv, &argv);
- if (argc == -1 || setenv (_GSYNCD_DISPATCHED_, "1", 1) == -1) {
- fprintf (stderr, "internal error\n");
- return 1;
+ evas = getenv(_GLUSTERD_CALLED_);
+ if (evas && strcmp(evas, "1") == 0)
+ /* OK, we know glusterd called us, no need to look for further config
+ *...although this conclusion should not inherit to our children
+ */
+ unsetenv(_GLUSTERD_CALLED_);
+ else {
+ /* we regard all gsyncd invocations unsafe
+ * that do not come from glusterd and
+ * therefore restrict it
+ */
+ restricted = 1;
+
+ if (!getenv(_GSYNCD_DISPATCHED_)) {
+ evas = getenv("SSH_ORIGINAL_COMMAND");
+ if (evas)
+ sargv = evas;
+ else {
+ evas = getenv("SHELL");
+ if (evas && strcmp(basename(evas), "gsyncd") == 0 &&
+ argc == 3 && strcmp(argv[1], "-c") == 0)
+ sargv = argv[2];
+ }
}
+ }
- b = basename (argv[0]);
- for (i = invocables; i->name; i++) {
- if (strcmp (b, i->name) == 0)
- return i->invoker (argc, argv);
- }
+ if (!(sargv && restricted))
+ return invoke_gsyncd(argc, argv);
- fprintf (stderr, "invoking %s in restricted SSH session is not allowed\n",
- b);
+ argc = str2argv(sargv, &argv);
- for (j = 1; j < argc; j++)
- free(argv[j]);
- free(argv);
+ if (argc == -1) {
+ fprintf(stderr, "internal error\n");
return 1;
+ }
+
+ if (setenv(_GSYNCD_DISPATCHED_, "1", 1) == -1) {
+ fprintf(stderr, "internal error\n");
+ goto out;
+ }
+
+ b = basename(argv[0]);
+ for (i = invocables; i->name; i++) {
+ if (strcmp(b, i->name) == 0)
+ return i->invoker(argc, argv);
+ }
+
+ fprintf(stderr, "invoking %s in restricted SSH session is not allowed\n",
+ b);
+
+out:
+ for (j = 1; j < argc; j++)
+ free(argv[j]);
+ free(argv);
+ return 1;
}
diff --git a/geo-replication/src/gverify.sh b/geo-replication/src/gverify.sh
index 5bd6a78664b..f5f70d245e0 100755
--- a/geo-replication/src/gverify.sh
+++ b/geo-replication/src/gverify.sh
@@ -1,20 +1,30 @@
#!/bin/bash
# Script to verify the Master and Slave Gluster compatibility.
-# To use ./gverify <master volume> <slave host> <slave volume>
+# To use ./gverify <master volume> <slave user> <slave host> <slave volume> <ssh port> <log file>
# Returns 0 if master and slave compatible.
# Considering buffer_size 100MB
BUFFER_SIZE=104857600;
-slave_log_file=`gluster --print-logdir`/geo-replication-slaves/slave.log
+SSH_PORT=$5;
+master_log_file=`gluster --print-logdir`/geo-replication/gverify-mastermnt.log
+slave_log_file=`gluster --print-logdir`/geo-replication/gverify-slavemnt.log
function SSHM()
{
- ssh -q \
- -oPasswordAuthentication=no \
- -oStrictHostKeyChecking=no \
- -oControlMaster=yes \
- "$@";
+ if [[ -z "${GR_SSH_IDENTITY_KEY}" ]]; then
+ ssh -p ${SSH_PORT} -q \
+ -oPasswordAuthentication=no \
+ -oStrictHostKeyChecking=no \
+ -oControlMaster=yes \
+ "$@";
+ else
+ ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} -q \
+ -oPasswordAuthentication=no \
+ -oStrictHostKeyChecking=no \
+ -oControlMaster=yes \
+ "$@";
+ fi
}
function get_inode_num()
@@ -59,9 +69,9 @@ function disk_usage()
esac
if [[ "X$os" = "XNetBSD" ]]; then
- echo $(df -P "$1")
+ echo $(df -P "$1" | tail -1)
else
- echo $(df -P -B1 "$1")
+ echo $(df -P -B1 "$1" | tail -1)
fi;
}
@@ -84,6 +94,7 @@ echo $cmd_line;
function master_stats()
{
MASTERVOL=$1;
+ local inet6=$2;
local d;
local i;
local disk_size;
@@ -92,15 +103,20 @@ function master_stats()
local m_status;
d=$(mktemp -d -t ${0##*/}.XXXXXX 2>/dev/null);
- glusterfs -s localhost --xlator-option="*dht.lookup-unhashed=off" --volfile-id $MASTERVOL -l $slave_log_file $d;
+ if [ "$inet6" = "inet6" ]; then
+ glusterfs -s localhost --xlator-option="*dht.lookup-unhashed=off" --xlator-option="transport.address-family=inet6" --volfile-id $MASTERVOL -l $master_log_file $d;
+ else
+ glusterfs -s localhost --xlator-option="*dht.lookup-unhashed=off" --volfile-id $MASTERVOL -l $master_log_file $d;
+ fi
+
i=$(get_inode_num $d);
if [[ "$i" -ne "1" ]]; then
echo 0:0;
exit 1;
fi;
cd $d;
- disk_size=$(disk_usage $d | tail -1 | awk "{print \$2}");
- used_size=$(disk_usage $d | tail -1 | awk "{print \$3}");
+ disk_size=$(disk_usage $d | awk "{print \$2}");
+ used_size=$(disk_usage $d | awk "{print \$3}");
umount_lazy $d;
rmdir $d;
ver=$(gluster --version | head -1 | cut -f2 -d " ");
@@ -114,20 +130,26 @@ function slave_stats()
SLAVEUSER=$1;
SLAVEHOST=$2;
SLAVEVOL=$3;
+ local inet6=$4;
local cmd_line;
local ver;
local status;
d=$(mktemp -d -t ${0##*/}.XXXXXX 2>/dev/null);
- glusterfs --xlator-option="*dht.lookup-unhashed=off" --volfile-server $SLAVEHOST --volfile-id $SLAVEVOL -l $slave_log_file $d;
+ if [ "$inet6" = "inet6" ]; then
+ glusterfs --xlator-option="*dht.lookup-unhashed=off" --xlator-option="transport.address-family=inet6" --volfile-server $SLAVEHOST --volfile-id $SLAVEVOL -l $slave_log_file $d;
+ else
+ glusterfs --xlator-option="*dht.lookup-unhashed=off" --volfile-server $SLAVEHOST --volfile-id $SLAVEVOL -l $slave_log_file $d;
+ fi
+
i=$(get_inode_num $d);
if [[ "$i" -ne "1" ]]; then
echo 0:0;
exit 1;
fi;
cd $d;
- disk_size=$(disk_usage $d | tail -1 | awk "{print \$2}");
- used_size=$(disk_usage $d | tail -1 | awk "{print \$3}");
+ disk_size=$(disk_usage $d | awk "{print \$2}");
+ used_size=$(disk_usage $d | awk "{print \$3}");
no_of_files=$(find $d -maxdepth 1 -path "$d/.trashcan" -prune -o -path "$d" -o -print0 -quit);
umount_lazy $d;
rmdir $d;
@@ -154,10 +176,13 @@ function ping_host ()
function main()
{
- log_file=$5
+ log_file=$6
> $log_file
- SSH_PORT=22
+ inet6=$7
+ local cmd_line
+ local ver
+
# Use FORCE_BLOCKER flag in the error message to differentiate
# between the errors which the force command should bypass
@@ -172,15 +197,32 @@ function main()
exit 1;
fi;
- ssh -oNumberOfPasswordPrompts=0 -oStrictHostKeyChecking=no $2@$3 "echo Testing_Passwordless_SSH";
+ if [[ -z "${GR_SSH_IDENTITY_KEY}" ]]; then
+ ssh -p ${SSH_PORT} -oNumberOfPasswordPrompts=0 -oStrictHostKeyChecking=no $2@$3 "echo Testing_Passwordless_SSH";
+ else
+ ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} -oNumberOfPasswordPrompts=0 -oStrictHostKeyChecking=no $2@$3 "echo Testing_Passwordless_SSH";
+ fi
+
if [ $? -ne 0 ]; then
echo "FORCE_BLOCKER|Passwordless ssh login has not been setup with $3 for user $2." > $log_file
exit 1;
fi;
+ cmd_line=$(cmd_slave);
+ if [[ -z "${GR_SSH_IDENTITY_KEY}" ]]; then
+ ver=$(ssh -p ${SSH_PORT} -oNumberOfPasswordPrompts=0 -oStrictHostKeyChecking=no $2@$3 bash -c "'$cmd_line'")
+ else
+ ver=$(ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} -oNumberOfPasswordPrompts=0 -oStrictHostKeyChecking=no $2@$3 bash -c "'$cmd_line'")
+ fi
+
+ if [ -z "$ver" ]; then
+ echo "FORCE_BLOCKER|gluster command not found on $3 for user $2." > $log_file
+ exit 1;
+ fi;
+
ERRORS=0;
- master_data=$(master_stats $1);
- slave_data=$(slave_stats $2 $3 $4);
+ master_data=$(master_stats $1 ${inet6});
+ slave_data=$(slave_stats $2 $3 $4 ${inet6});
master_disk_size=$(echo $master_data | cut -f1 -d':');
slave_disk_size=$(echo $slave_data | cut -f1 -d':');
master_used_size=$(echo $master_data | cut -f2 -d':');
@@ -190,12 +232,12 @@ function main()
slave_no_of_files=$(echo $slave_data | cut -f4 -d':');
if [[ "x$master_disk_size" = "x" || "x$master_version" = "x" || "$master_disk_size" -eq "0" ]]; then
- echo "FORCE_BLOCKER|Unable to fetch master volume details. Please check the master cluster and master volume." > $log_file;
+ echo "FORCE_BLOCKER|Unable to mount and fetch master volume details. Please check the log: $master_log_file" > $log_file;
exit 1;
fi;
if [[ "x$slave_disk_size" = "x" || "x$slave_version" = "x" || "$slave_disk_size" -eq "0" ]]; then
- echo "FORCE_BLOCKER|Unable to fetch slave volume details. Please check the slave cluster and slave volume." > $log_file;
+ echo "FORCE_BLOCKER|Unable to mount and fetch slave volume details. Please check the log: $slave_log_file" > $log_file;
exit 1;
fi;
@@ -222,8 +264,8 @@ function main()
ERRORS=$(($ERRORS + 1));
fi;
- if [[ $master_version > $slave_version ]]; then
- echo "Gluster version mismatch between master and slave." >> $log_file;
+ if [[ $master_version != $slave_version ]]; then
+ echo "Gluster version mismatch between master and slave. Master version: $master_version Slave version: $slave_version" >> $log_file;
ERRORS=$(($ERRORS + 1));
fi;
diff --git a/geo-replication/src/peer_georep-sshkey.py.in b/geo-replication/src/peer_georep-sshkey.py.in
new file mode 100644
index 00000000000..58696e9a616
--- /dev/null
+++ b/geo-replication/src/peer_georep-sshkey.py.in
@@ -0,0 +1,116 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+"""
+Usage:
+ gluster-georep-sshkey generate
+ or
+ gluster-georep-sshkey generate --no-prefix
+
+Generates two SSH keys(one for gsyncd access and other for tar) in all
+peer nodes and collects the public keys to the local node where it is
+initiated. Adds `command=` prefix to common_secret.pem.pub if `--no-prefix`
+argument is not passed.
+"""
+import os
+import glob
+
+from gluster.cliutils import (node_output_ok, execute, execute_in_peers,
+ Cmd, runcli)
+from prettytable import PrettyTable
+
+
+SECRET_PEM = "@GLUSTERD_WORKDIR@/geo-replication/secret.pem"
+TAR_SSH_PEM = "@GLUSTERD_WORKDIR@/geo-replication/tar_ssh.pem"
+GSYNCD_CMD = 'command="@GLUSTERFS_LIBEXECDIR@/gsyncd" '
+TAR_CMD = 'command="tar ${SSH_ORIGINAL_COMMAND#* }" '
+COMMON_SECRET_FILE = "@GLUSTERD_WORKDIR@/geo-replication/common_secret.pem.pub"
+
+
+class NodeGenCmd(Cmd):
+ name = "node-generate"
+
+ def args(self, parser):
+ parser.add_argument("no_prefix")
+
+ def run(self, args):
+ # Regenerate if secret.pem.pub not exists
+ if not os.path.exists(SECRET_PEM + ".pub"):
+ # Cleanup old files
+ for f in glob.glob(SECRET_PEM + "*"):
+ os.remove(f)
+
+ execute(["ssh-keygen", "-N", "", "-f", SECRET_PEM])
+
+ # Regenerate if ssh_tar.pem.pub not exists
+ if not os.path.exists(TAR_SSH_PEM + ".pub"):
+ # Cleanup old files
+ for f in glob.glob(TAR_SSH_PEM + "*"):
+ os.remove(f)
+
+ execute(["ssh-keygen", "-N", "", "-f", TAR_SSH_PEM])
+
+ # Add required prefixes if prefix is not "container"
+ prefix_secret_pem_pub = ""
+ prefix_tar_ssh_pem_pub = ""
+ if args.no_prefix != "no-prefix":
+ prefix_secret_pem_pub = GSYNCD_CMD
+ prefix_tar_ssh_pem_pub = TAR_CMD
+
+ data = {"default_pub": "", "tar_pub": ""}
+ with open(SECRET_PEM + ".pub") as f:
+ data["default_pub"] = prefix_secret_pem_pub + f.read().strip()
+
+ with open(TAR_SSH_PEM + ".pub") as f:
+ data["tar_pub"] = prefix_tar_ssh_pem_pub + f.read().strip()
+
+ node_output_ok(data)
+
+
+def color_status(value):
+ if value in ["UP", "OK"]:
+ return "green"
+ return "red"
+
+
+class GenCmd(Cmd):
+ name = "generate"
+
+ def args(self, parser):
+ parser.add_argument("--no-prefix", help="Do not use prefix in "
+ "generated pub keys", action="store_true")
+
+ def run(self, args):
+ prefix = "no-prefix" if args.no_prefix else "."
+ out = execute_in_peers("node-generate", [prefix])
+
+ common_secrets = []
+ table = PrettyTable(["NODE", "NODE STATUS", "KEYGEN STATUS"])
+ table.align["NODE STATUS"] = "r"
+ table.align["KEYGEN STATUS"] = "r"
+ for p in out:
+ if p.ok:
+ common_secrets.append(p.output["default_pub"])
+ common_secrets.append(p.output["tar_pub"])
+
+ table.add_row([p.hostname,
+ "UP" if p.node_up else "DOWN",
+ "OK" if p.ok else "NOT OK: {0}".format(
+ p.error)])
+
+ with open(COMMON_SECRET_FILE, "w") as f:
+ f.write("\n".join(common_secrets) + "\n")
+
+ print (table)
+
+
+if __name__ == "__main__":
+ runcli()
diff --git a/geo-replication/src/peer_gsec_create.in b/geo-replication/src/peer_gsec_create.in
index 9cadce56453..6d4a4847013 100755
--- a/geo-replication/src/peer_gsec_create.in
+++ b/geo-replication/src/peer_gsec_create.in
@@ -2,6 +2,7 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
+libexecdir=@libexecdir@
if [ ! -f "$GLUSTERD_WORKDIR"/geo-replication/secret.pem.pub ]; then
\rm -rf "$GLUSTERD_WORKDIR"/geo-replication/secret.pem*
@@ -13,6 +14,11 @@ if [ ! -f "$GLUSTERD_WORKDIR"/geo-replication/tar_ssh.pem.pub ]; then
ssh-keygen -N '' -f "$GLUSTERD_WORKDIR"/geo-replication/tar_ssh.pem > /dev/null
fi
-output1=`echo command=\"${exec_prefix}/libexec/glusterfs/gsyncd\" " "``cat "$GLUSTERD_WORKDIR"/geo-replication/secret.pem.pub`
-output2=`echo command=\"tar \$\{SSH_ORIGINAL_COMMAND#* \}\" " "``cat "$GLUSTERD_WORKDIR"/geo-replication/tar_ssh.pem.pub`
+if [ "Xcontainer" = "X$1" ]; then
+ output1=`cat "$GLUSTERD_WORKDIR"/geo-replication/secret.pem.pub`
+ output2=`cat "$GLUSTERD_WORKDIR"/geo-replication/tar_ssh.pem.pub`
+else
+ output1=`echo command=\"${libexecdir}/glusterfs/gsyncd\" ""``cat "$GLUSTERD_WORKDIR"/geo-replication/secret.pem.pub`
+ output2=`echo command=\"tar \$\{SSH_ORIGINAL_COMMAND#* \}\" ""``cat "$GLUSTERD_WORKDIR"/geo-replication/tar_ssh.pem.pub`
+fi
echo -e "$output1\n$output2"
diff --git a/geo-replication/src/peer_mountbroker.in b/geo-replication/src/peer_mountbroker.in
index 8573abdf122..8ecf38ded41 100644
--- a/geo-replication/src/peer_mountbroker.in
+++ b/geo-replication/src/peer_mountbroker.in
@@ -1,10 +1,12 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
+
+from __future__ import print_function
+
import os
from argparse import ArgumentParser, RawDescriptionHelpFormatter
import json
import sys
-
PROG_DESCRIPTION = """
GlusterFS Mountbroker user management
"""
@@ -14,19 +16,19 @@ args = None
def ok(message=""):
if (not args and "-j" in sys.argv) or (args and args.json):
- print json.dumps({"ok": True, "message": message})
+ print(json.dumps({"ok": True, "message": message}))
else:
if message:
- print message
+ print(message)
sys.exit(0)
def notok(message=""):
if (not args and "-j" in sys.argv) or (args and args.json):
- print json.dumps({"ok": False, "message": message})
+ print(json.dumps({"ok": False, "message": message}))
else:
- print "error: %s" % message
+ print("error: %s" % message)
# Always return zero due to limitation while executing
# as `gluster system:: execute`
@@ -64,7 +66,7 @@ class MountbrokerUserMgmt(object):
def _get_write_data(self):
op = "volume management\n"
op += " type mgmt/glusterd\n"
- for k, v in self._options.iteritems():
+ for k, v in self._options.items():
op += " option %s %s\n" % (k, v)
for line in self.commented_lines:
op += " %s\n" % line
@@ -87,7 +89,7 @@ class MountbrokerUserMgmt(object):
def add_user(self, user, volumes):
vols = set()
- for k, v in self._options.iteritems():
+ for k, v in self._options.items():
if k.startswith("mountbroker-geo-replication.") \
and user == k.split(".")[-1]:
vols.update(v.split(","))
@@ -98,7 +100,7 @@ class MountbrokerUserMgmt(object):
def remove_volume(self, user, volumes):
vols = set()
- for k, v in self._options.iteritems():
+ for k, v in self._options.items():
if k.startswith("mountbroker-geo-replication.") \
and user == k.split(".")[-1]:
vols.update(v.split(","))
@@ -118,7 +120,7 @@ class MountbrokerUserMgmt(object):
def info(self):
data = {"users": []}
- for k, v in self._options.iteritems():
+ for k, v in self._options.items():
if k.startswith("mountbroker-geo-replication."):
data["users"].append(
{"name": k.split(".")[-1], "volumes": v.split(",")}
@@ -132,7 +134,7 @@ class MountbrokerUserMgmt(object):
def format_info(data):
op = "%s %s\n" % ("Option".ljust(50), "Value".ljust(50))
op += ("-" * 101) + "\n"
- for key, value in data.iteritems():
+ for key, value in data.items():
if key != "users":
op += "%s %s\n" % (key.ljust(50), value)
@@ -159,11 +161,11 @@ def _get_args():
parser_useradd.add_argument('username', help="Username", type=str)
parser_useradd.add_argument('volumes', type=str, default='',
- help="Volumes list. ',' seperated")
+ help="Volumes list. ',' separated")
parser_volumedel.add_argument('username', help="Username", type=str)
parser_volumedel.add_argument('volumes', type=str, default='',
- help="Volumes list. ',' seperated")
+ help="Volumes list. ',' separated")
parser_userdel.add_argument('username', help="Username", type=str)
diff --git a/geo-replication/src/peer_mountbroker.py.in b/geo-replication/src/peer_mountbroker.py.in
new file mode 100644
index 00000000000..40b90ffc560
--- /dev/null
+++ b/geo-replication/src/peer_mountbroker.py.in
@@ -0,0 +1,401 @@
+#!/usr/bin/python3
+
+from __future__ import print_function
+
+import os
+from errno import EEXIST, ENOENT
+
+from gluster.cliutils import (execute, Cmd, node_output_ok,
+ node_output_notok, execute_in_peers,
+ runcli, oknotok)
+from prettytable import PrettyTable
+
+LOG_DIR = "@localstatedir@/log/glusterfs/geo-replication-slaves"
+CLI_LOG = "@localstatedir@/log/glusterfs/cli.log"
+GEOREP_DIR = "@GLUSTERD_WORKDIR@/geo-replication"
+GLUSTERD_VOLFILE = "@GLUSTERD_VOLFILE@"
+
+
+class MountbrokerUserMgmt(object):
+ def __init__(self, volfile):
+ self.volfile = volfile
+ self._options = {}
+ self.commented_lines = []
+ self.user_volumes = {}
+ self._parse()
+
+ def _parse(self):
+ """ Example glusterd.vol
+ volume management
+ type mgmt/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
+ option rpc-auth-allow-insecure on
+ option ping-timeout 0
+ option event-threads 1
+ # option base-port 49152
+ option mountbroker-root /var/mountbroker-root
+ option mountbroker-geo-replication.user1 vol1,vol2,vol3
+ option geo-replication-log-group geogroup
+ option rpc-auth-allow-insecure on
+ end-volume
+ """
+ with open(self.volfile, "r") as f:
+ for line in f:
+ line = line.strip()
+ if line.startswith("option "):
+ key, value = line.split()[1:]
+ self._options[key] = value
+ if line.startswith("#"):
+ self.commented_lines.append(line)
+
+ for k, v in self._options.items():
+ if k.startswith("mountbroker-geo-replication."):
+ user = k.split(".")[-1]
+ self.user_volumes[user] = set(v.split(","))
+
+ def get_group(self):
+ return self._options.get("geo-replication-log-group", None)
+
+ def _get_write_data(self):
+ op = "volume management\n"
+ op += " type mgmt/glusterd\n"
+ for k, v in self._options.items():
+ if k.startswith("mountbroker-geo-replication."):
+ # Users will be added seperately
+ continue
+
+ op += " option %s %s\n" % (k, v)
+
+ for k, v in self.user_volumes.items():
+ if v:
+ op += (" option mountbroker-geo-replication."
+ "%s %s\n" % (k, ",".join(v)))
+
+ for line in self.commented_lines:
+ op += " %s\n" % line
+
+ op += "end-volume"
+ return op
+
+ def save(self):
+ with open(self.volfile + "_tmp", "w") as f:
+ f.write(self._get_write_data())
+ f.flush()
+ os.fsync(f.fileno())
+ os.rename(self.volfile + "_tmp", self.volfile)
+
+ def set_mount_root_and_group(self, mnt_root, group):
+ self._options["mountbroker-root"] = mnt_root
+ self._options["geo-replication-log-group"] = group
+
+ def add(self, volume, user):
+ user_volumes = self.user_volumes.get(user, None)
+
+ if user_volumes is not None and volume in user_volumes:
+ # User and Volume already exists
+ return
+
+ if user_volumes is None:
+ # User not exists
+ self.user_volumes[user] = set()
+
+ self.user_volumes[user].add(volume)
+
+ def remove(self, volume=None, user=None):
+ if user is not None:
+ if volume is None:
+ self.user_volumes[user] = set()
+ else:
+ try:
+ self.user_volumes.get(user, set()).remove(volume)
+ except KeyError:
+ pass
+ else:
+ if volume is None:
+ return
+
+ for k, v in self.user_volumes.items():
+ try:
+ self.user_volumes[k].remove(volume)
+ except KeyError:
+ pass
+
+ def info(self):
+ # Convert Volumes set into Volumes list
+ users = {}
+ for k, v in self.user_volumes.items():
+ users[k] = list(v)
+
+ data = {
+ "mountbroker-root": self._options.get("mountbroker-root", "None"),
+ "geo-replication-log-group": self._options.get(
+ "geo-replication-log-group", ""),
+ "users": users
+ }
+
+ return data
+
+
+class NodeSetup(Cmd):
+ # Test if group exists using `getent group <grp>`
+ # and then group add using `groupadd <grp>`
+ # chgrp -R <grp> /var/log/glusterfs/geo-replication-slaves
+ # chgrp -R <grp> /var/lib/glusterd/geo-replication
+ # chmod -R 770 /var/log/glusterfs/geo-replication-slaves
+ # chmod 770 /var/lib/glusterd/geo-replication
+ # mkdir -p <mnt_root>
+ # chmod 0711 <mnt_root>
+ # If selinux,
+ # semanage fcontext -a -e /home /var/mountbroker-root
+ # restorecon -Rv /var/mountbroker-root
+ name = "node-setup"
+
+ def args(self, parser):
+ parser.add_argument("mount_root")
+ parser.add_argument("group")
+
+ def run(self, args):
+ m = MountbrokerUserMgmt(GLUSTERD_VOLFILE)
+
+ try:
+ os.makedirs(args.mount_root)
+ except OSError as e:
+ if e.errno == EEXIST:
+ pass
+ else:
+ node_output_notok("Unable to Create {0}".format(
+ args.mount_root))
+
+ execute(["chmod", "0711", args.mount_root])
+ try:
+ execute(["semanage", "fcontext", "-a", "-e",
+ "/home", args.mount_root])
+ except OSError as e:
+ if e.errno == ENOENT:
+ pass
+ else:
+ node_output_notok(
+ "Unable to run semanage: {0}".format(e))
+
+ try:
+ execute(["restorecon", "-Rv", args.mount_root])
+ except OSError as e:
+ if e.errno == ENOENT:
+ pass
+ else:
+ node_output_notok(
+ "Unable to run restorecon: {0}".format(e))
+
+ rc, out, err = execute(["getent", "group", args.group])
+ if rc != 0:
+ node_output_notok("User Group not exists")
+
+ execute(["chgrp", "-R", args.group, GEOREP_DIR])
+ execute(["chgrp", "-R", args.group, LOG_DIR])
+ execute(["chgrp", args.group, CLI_LOG])
+ execute(["chmod", "770", GEOREP_DIR])
+ execute(["find", LOG_DIR, "-type", "d", "-exec", "chmod", "770", "{}",
+ "+"])
+ execute(["find", LOG_DIR, "-type", "f", "-exec", "chmod", "660", "{}",
+ "+"])
+ execute(["chmod", "660", CLI_LOG])
+
+ m.set_mount_root_and_group(args.mount_root, args.group)
+ m.save()
+
+ node_output_ok()
+
+
+def color_status(value):
+ if value.lower() in ("up", "ok", "yes"):
+ return "green"
+ else:
+ return "red"
+
+
+class CliSetup(Cmd):
+ # gluster-mountbroker setup <MOUNT_ROOT> <GROUP>
+ name = "setup"
+
+ def args(self, parser):
+ parser.add_argument("mount_root",
+ help="Path to the mountbroker-root directory.")
+ parser.add_argument("group",
+ help="Group to be used for setup.")
+
+ def run(self, args):
+ out = execute_in_peers("node-setup", [args.mount_root,
+ args.group])
+ table = PrettyTable(["NODE", "NODE STATUS", "SETUP STATUS"])
+ table.align["NODE STATUS"] = "r"
+ table.align["SETUP STATUS"] = "r"
+ for p in out:
+ table.add_row([p.hostname,
+ "UP" if p.node_up else "DOWN",
+ "OK" if p.ok else "NOT OK: {0}".format(
+ p.error)])
+
+ print(table)
+
+
+class NodeStatus(Cmd):
+ # Check if Group exists
+ # Check if user exists
+ # Check directory permission /var/log/glusterfs/geo-replication-slaves
+ # and /var/lib/glusterd/geo-replication
+ # Check mount root and its permissions
+ # Check glusterd.vol file for user, group, dir existance
+ name = "node-status"
+
+ def run(self, args):
+ m = MountbrokerUserMgmt(GLUSTERD_VOLFILE)
+ data = m.info()
+ data["group_exists"] = False
+ data["path_exists"] = False
+
+ rc, out, err = execute(["getent", "group",
+ data["geo-replication-log-group"]])
+
+ if rc == 0:
+ data["group_exists"] = True
+
+ if os.path.exists(data["mountbroker-root"]):
+ data["path_exists"] = True
+
+ node_output_ok(data)
+
+
+class CliStatus(Cmd):
+ # gluster-mountbroker status
+ name = "status"
+
+ def run(self, args):
+ out = execute_in_peers("node-status")
+ table = PrettyTable(["NODE", "NODE STATUS", "MOUNT ROOT",
+ "GROUP", "USERS"])
+ table.align["NODE STATUS"] = "r"
+
+ for p in out:
+ node_data = p.output
+ if node_data == "" or node_data == "N/A":
+ node_data = {}
+
+ users_row_data = ""
+ for k, v in node_data.get("users", {}).items():
+ users_row_data += "{0}({1}) ".format(k, ", ".join(v))
+
+ if not users_row_data:
+ users_row_data = "None"
+
+ mount_root = node_data.get("mountbroker-root", "None")
+ if mount_root != "None":
+ mount_root += "({0})".format(oknotok(
+ node_data.get("path_exists", False)))
+
+ grp = node_data.get("geo-replication-log-group", "None")
+ if grp != "None":
+ grp += "({0})".format(oknotok(
+ node_data.get("group_exists", False)))
+
+ table.add_row([p.hostname,
+ "UP" if p.node_up else "DOWN",
+ mount_root,
+ grp,
+ users_row_data])
+
+ print(table)
+
+
+class NodeAdd(Cmd):
+ # useradd -m -g <grp> <usr>
+ # useradd to glusterd.vol
+ name = "node-add"
+
+ def args(self, parser):
+ parser.add_argument("volume")
+ parser.add_argument("user")
+
+ def run(self, args):
+ m = MountbrokerUserMgmt(GLUSTERD_VOLFILE)
+ grp = m.get_group()
+ if grp is None:
+ node_output_notok("Group is not available")
+
+ m.add(args.volume, args.user)
+ m.save()
+ node_output_ok()
+
+
+class CliAdd(Cmd):
+ # gluster-mountbroker add <VOLUME> <USER>
+ name = "add"
+
+ def args(self, parser):
+ parser.add_argument("volume",
+ help="Volume to be added.")
+ parser.add_argument("user",
+ help="User for which volume is to be added.")
+
+ def run(self, args):
+ out = execute_in_peers("node-add", [args.volume,
+ args.user])
+ table = PrettyTable(["NODE", "NODE STATUS", "ADD STATUS"])
+ table.align["NODE STATUS"] = "r"
+ table.align["ADD STATUS"] = "r"
+
+ for p in out:
+ table.add_row([p.hostname,
+ "UP" if p.node_up else "DOWN",
+ "OK" if p.ok else "NOT OK: {0}".format(
+ p.error)])
+
+ print(table)
+
+
+class NodeRemove(Cmd):
+ # userremove from glusterd.vol file
+ name = "node-remove"
+
+ def args(self, parser):
+ parser.add_argument("volume")
+ parser.add_argument("user")
+
+ def run(self, args):
+ m = MountbrokerUserMgmt(GLUSTERD_VOLFILE)
+ volume = None if args.volume == "." else args.volume
+ user = None if args.user == "." else args.user
+ m.remove(volume=volume, user=user)
+ m.save()
+ node_output_ok()
+
+
+class CliRemove(Cmd):
+ # gluster-mountbroker remove --volume <VOLUME> --user <USER>
+ name = "remove"
+
+ def args(self, parser):
+ parser.add_argument("--volume", default=".", help="Volume to be removed.")
+ parser.add_argument("--user", default=".",
+ help="User for which volume has to be removed.")
+
+ def run(self, args):
+ out = execute_in_peers("node-remove", [args.volume,
+ args.user])
+ table = PrettyTable(["NODE", "NODE STATUS", "REMOVE STATUS"])
+ table.align["NODE STATUS"] = "r"
+ table.align["REMOVE STATUS"] = "r"
+
+ for p in out:
+ table.add_row([p.hostname,
+ "UP" if p.node_up else "DOWN",
+ "OK" if p.ok else "NOT OK: {0}".format(
+ p.error)])
+
+ print(table)
+
+if __name__ == "__main__":
+ runcli()
diff --git a/geo-replication/src/procdiggy.c b/geo-replication/src/procdiggy.c
index d9253bbb89e..8068ef79a42 100644
--- a/geo-replication/src/procdiggy.c
+++ b/geo-replication/src/procdiggy.c
@@ -15,102 +15,122 @@
#include <ctype.h>
#include <sys/param.h> /* for PATH_MAX */
-#include "common-utils.h"
+#include <glusterfs/common-utils.h>
+#include <glusterfs/syscall.h>
#include "procdiggy.h"
pid_t
-pidinfo (pid_t pid, char **name)
+pidinfo(pid_t pid, char **name)
{
- char buf[NAME_MAX * 2] = {0,};
- FILE *f = NULL;
- char path[PATH_MAX] = {0,};
- char *p = NULL;
- int ret = 0;
-
- sprintf (path, PROC"/%d/status", pid);
-
- f = fopen (path, "r");
- if (!f)
- return -1;
-
- if (name)
- *name = NULL;
- for (;;) {
- size_t len;
- memset (buf, 0, sizeof (buf));
- if (fgets (buf, sizeof (buf), f) == NULL ||
- (len = strlen (buf)) == 0 ||
- buf[len - 1] != '\n') {
- pid = -1;
- goto out;
- }
- buf[len - 1] = '\0';
-
- if (name && !*name) {
- p = strtail (buf, "Name:");
- if (p) {
- while (isspace (*++p));
- *name = gf_strdup (p);
- if (!*name) {
- pid = -2;
- goto out;
- }
- continue;
- }
- }
+ char buf[NAME_MAX * 2] = {
+ 0,
+ };
+ FILE *f = NULL;
+ char path[PATH_MAX] = {
+ 0,
+ };
+ char *p = NULL;
+ int ret = 0;
+ pid_t lpid = -1;
+
+ if (name)
+ *name = NULL;
+
+ snprintf(path, sizeof path, PROC "/%d/status", pid);
- p = strtail (buf, "PPid:");
- if (p)
- break;
+ f = fopen(path, "r");
+ if (!f)
+ return -1;
+
+ for (;;) {
+ size_t len;
+ memset(buf, 0, sizeof(buf));
+ if (fgets(buf, sizeof(buf), f) == NULL || (len = strlen(buf)) == 0 ||
+ buf[len - 1] != '\n') {
+ lpid = -1;
+ goto out;
+ }
+ buf[len - 1] = '\0';
+
+ if (name && !*name) {
+ p = strtail(buf, "Name:");
+ if (p) {
+ while (isspace(*++p))
+ ;
+ *name = gf_strdup(p);
+ if (!*name) {
+ lpid = -2;
+ goto out;
+ }
+ continue;
+ }
}
- while (isspace (*++p));
- ret = gf_string2int (p, &pid);
- if (ret == -1)
- pid = -1;
-
- out:
- fclose (f);
- if (pid == -1 && name && *name)
- GF_FREE (name);
- if (pid == -2)
- fprintf (stderr, "out of memory\n");
- return pid;
+ p = strtail(buf, "PPid:");
+ if (p)
+ break;
+ }
+
+ while (isspace(*++p))
+ ;
+ ret = gf_string2int(p, &lpid);
+ if (ret == -1)
+ lpid = -1;
+
+out:
+ fclose(f);
+ if (lpid == -1 && name && *name)
+ GF_FREE(*name);
+ if (lpid == -2)
+ fprintf(stderr, "out of memory\n");
+ return lpid;
}
int
-prociter (int (*proch) (pid_t pid, pid_t ppid, char *tmpname, void *data),
- void *data)
+prociter(int (*proch)(pid_t pid, pid_t ppid, char *tmpname, void *data),
+ void *data)
{
- char *name = NULL;
- DIR *d = NULL;
- struct dirent *de = NULL;
- pid_t pid = -1;
- pid_t ppid = -1;
- int ret = 0;
-
- d = opendir (PROC);
- if (!d)
- return -1;
- while (errno = 0, de = readdir (d)) {
- if (gf_string2int (de->d_name, &pid) != -1 && pid >= 0) {
- ppid = pidinfo (pid, &name);
- switch (ppid) {
- case -1: continue;
- case -2: ret = -1; break;
- }
- ret = proch (pid, ppid, name, data);
- GF_FREE (name);
- if (ret)
- break;
- }
- }
- closedir (d);
- if (!de && errno) {
- fprintf (stderr, "failed to traverse "PROC" (%s)\n",
- strerror (errno));
- ret = -1;
+ char *name = NULL;
+ DIR *d = NULL;
+ struct dirent *de = NULL;
+ struct dirent scratch[2] = {
+ {
+ 0,
+ },
+ };
+ pid_t pid = -1;
+ pid_t ppid = -1;
+ int ret = 0;
+
+ d = sys_opendir(PROC);
+ if (!d)
+ return -1;
+
+ for (;;) {
+ errno = 0;
+ de = sys_readdir(d, scratch);
+ if (!de || errno != 0)
+ break;
+
+ if (gf_string2int(de->d_name, &pid) != -1 && pid >= 0) {
+ ppid = pidinfo(pid, &name);
+ switch (ppid) {
+ case -1:
+ continue;
+ case -2:
+ break;
+ }
+ ret = proch(pid, ppid, name, data);
+ GF_FREE(name);
+ if (ret)
+ break;
}
+ }
+ sys_closedir(d);
+ if (!de && errno) {
+ fprintf(stderr, "failed to traverse " PROC " (%s)\n", strerror(errno));
+ ret = -1;
+ }
- return ret;
+ return ret;
}
diff --git a/geo-replication/src/procdiggy.h b/geo-replication/src/procdiggy.h
index 56dfc4eb213..e17ccd31c89 100644
--- a/geo-replication/src/procdiggy.h
+++ b/geo-replication/src/procdiggy.h
@@ -13,8 +13,9 @@
#define PROC "/proc"
-pid_t pidinfo (pid_t pid, char **name);
-
-int prociter (int (*proch) (pid_t pid, pid_t ppid, char *name, void *data),
- void *data);
+pid_t
+pidinfo(pid_t pid, char **name);
+int
+prociter(int (*proch)(pid_t pid, pid_t ppid, char *name, void *data),
+ void *data);
diff --git a/geo-replication/src/set_geo_rep_pem_keys.sh b/geo-replication/src/set_geo_rep_pem_keys.sh
index ae23f4ff0c6..8a43fa39d1f 100755
--- a/geo-replication/src/set_geo_rep_pem_keys.sh
+++ b/geo-replication/src/set_geo_rep_pem_keys.sh
@@ -47,6 +47,7 @@ function main()
cp $home_dir/${COMMON_SECRET_PEM_PUB} ${GLUSTERD_WORKDIR}/geo-replication/
gluster system:: copy file /geo-replication/${COMMON_SECRET_PEM_PUB}
gluster system:: execute add_secret_pub $user geo-replication/${master_vol}_${slave_vol}_common_secret.pem.pub
+ gluster vol set ${slave_vol} features.read-only on
else
echo "$home_dir/common_secret.pem.pub not present. Please run geo-replication command on master with push-pem option to generate the file"
exit 1;
diff --git a/geo-replication/syncdaemon/Makefile.am b/geo-replication/syncdaemon/Makefile.am
index ed0f5e40924..d70e3368faf 100644
--- a/geo-replication/syncdaemon/Makefile.am
+++ b/geo-replication/syncdaemon/Makefile.am
@@ -1,8 +1,8 @@
-syncdaemondir = $(libexecdir)/glusterfs/python/syncdaemon
+syncdaemondir = $(GLUSTERFS_LIBEXECDIR)/python/syncdaemon
-syncdaemon_PYTHON = gconf.py gsyncd.py __init__.py master.py README.md repce.py \
- resource.py configinterface.py syncdutils.py monitor.py libcxattr.py \
- $(top_builddir)/contrib/ipaddr-py/ipaddr.py libgfchangelog.py changelogagent.py \
- gsyncdstatus.py
+syncdaemon_PYTHON = rconf.py gsyncd.py __init__.py master.py README.md repce.py \
+ resource.py syncdutils.py monitor.py libcxattr.py gsyncdconfig.py \
+ libgfchangelog.py gsyncdstatus.py conf.py logutils.py \
+ subcmds.py argsupgrade.py py2py3.py
CLEANFILES =
diff --git a/geo-replication/syncdaemon/README.md b/geo-replication/syncdaemon/README.md
index 2a202e3f99e..5ab785ae669 100644
--- a/geo-replication/syncdaemon/README.md
+++ b/geo-replication/syncdaemon/README.md
@@ -19,7 +19,6 @@ INSTALLATION
As of now, the supported way of operation is running from the source directory or using the RPMs given.
-If you use Python 2.4.x, you need to install the [Ctypes module](http://python.net/crew/theller/ctypes/).
CONFIGURATION
-------------
diff --git a/geo-replication/syncdaemon/__codecheck.py b/geo-replication/syncdaemon/__codecheck.py
index 45dbd26bb64..9437147f7d9 100644
--- a/geo-replication/syncdaemon/__codecheck.py
+++ b/geo-replication/syncdaemon/__codecheck.py
@@ -8,6 +8,7 @@
# cases as published by the Free Software Foundation.
#
+from __future__ import print_function
import os
import os.path
import sys
@@ -45,7 +46,7 @@ class IPNetwork(list):
gsyncd = sys.modules['gsyncd']
for a in [['--help'], ['--version'],
['--canonicalize-escape-url', '/foo']]:
- print('>>> invoking program with args: %s' % ' '.join(a))
+ print(('>>> invoking program with args: %s' % ' '.join(a)))
pid = os.fork()
if not pid:
sys_argv_set(a)
diff --git a/geo-replication/syncdaemon/argsupgrade.py b/geo-replication/syncdaemon/argsupgrade.py
new file mode 100644
index 00000000000..7af40633ef8
--- /dev/null
+++ b/geo-replication/syncdaemon/argsupgrade.py
@@ -0,0 +1,359 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+# Converts old style args into new style args
+
+from __future__ import print_function
+import sys
+from argparse import ArgumentParser
+import socket
+import os
+
+from syncdutils import GsyncdError
+from conf import GLUSTERD_WORKDIR
+
+
+def gethostbyname(hnam):
+ """gethostbyname wrapper"""
+ try:
+ return socket.gethostbyname(hnam)
+ except socket.gaierror:
+ ex = sys.exc_info()[1]
+ raise GsyncdError("failed to resolve %s: %s" %
+ (hnam, ex.strerror))
+
+
+def slave_url(urldata):
+ urldata = urldata.replace("ssh://", "")
+ host, vol = urldata.split("::")
+ vol = vol.split(":")[0]
+ return "%s::%s" % (host, vol)
+
+
+def init_gsyncd_template_conf():
+ path = GLUSTERD_WORKDIR + "/geo-replication/gsyncd_template.conf"
+ dname = os.path.dirname(path)
+ if not os.path.exists(dname):
+ try:
+ os.mkdir(dname)
+ except OSError:
+ pass
+
+ if not os.path.exists(path):
+ fd = os.open(path, os.O_CREAT | os.O_RDWR)
+ os.close(fd)
+
+
+def init_gsyncd_session_conf(master, slave):
+ slave = slave_url(slave)
+ master = master.strip(":")
+ slavehost, slavevol = slave.split("::")
+ slavehost = slavehost.split("@")[-1]
+
+ # Session Config File
+ path = "%s/geo-replication/%s_%s_%s/gsyncd.conf" % (
+ GLUSTERD_WORKDIR, master, slavehost, slavevol)
+
+ if os.path.exists(os.path.dirname(path)) and not os.path.exists(path):
+ fd = os.open(path, os.O_CREAT | os.O_RDWR)
+ os.close(fd)
+
+
+def init_gsyncd_conf(path):
+ dname = os.path.dirname(path)
+ if not os.path.exists(dname):
+ try:
+ os.mkdir(dname)
+ except OSError:
+ pass
+
+ if os.path.exists(dname) and not os.path.exists(path):
+ fd = os.open(path, os.O_CREAT | os.O_RDWR)
+ os.close(fd)
+
+
+def upgrade():
+ # Create dummy template conf(empty), hack to avoid glusterd
+ # fail when it does stat to check the existence.
+ init_gsyncd_template_conf()
+
+ inet6 = False
+ if "--inet6" in sys.argv:
+ inet6 = True
+
+ if "--monitor" in sys.argv:
+ # python gsyncd.py --path=/bricks/b1
+ # --monitor -c gsyncd.conf
+ # --iprefix=/var :gv1
+ # --glusterd-uuid=f26ac7a8-eb1b-4ea7-959c-80b27d3e43d0
+ # f241::gv2
+ p = ArgumentParser()
+ p.add_argument("master")
+ p.add_argument("slave")
+ p.add_argument("--glusterd-uuid")
+ p.add_argument("-c")
+ p.add_argument("--iprefix")
+ p.add_argument("--path", action="append")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ # Overwrite the sys.argv after rearrange
+ init_gsyncd_session_conf(pargs.master, pargs.slave)
+ sys.argv = [
+ sys.argv[0],
+ "monitor",
+ pargs.master.strip(":"),
+ slave_url(pargs.slave),
+ "--local-node-id",
+ pargs.glusterd_uuid
+ ]
+ elif "--status-get" in sys.argv:
+ # -c gsyncd.conf --iprefix=/var :gv1 f241::gv2
+ # --status-get --path /bricks/b1
+ p = ArgumentParser()
+ p.add_argument("master")
+ p.add_argument("slave")
+ p.add_argument("-c")
+ p.add_argument("--path")
+ p.add_argument("--iprefix")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ init_gsyncd_session_conf(pargs.master, pargs.slave)
+
+ sys.argv = [
+ sys.argv[0],
+ "status",
+ pargs.master.strip(":"),
+ slave_url(pargs.slave),
+ "--local-path",
+ pargs.path
+ ]
+ elif "--canonicalize-url" in sys.argv:
+ # This can accept multiple URLs and converts each URL to the
+ # format ssh://USER@IP:gluster://127.0.0.1:VOLUME
+ # This format not used in gsyncd, but added for glusterd compatibility
+ p = ArgumentParser()
+ p.add_argument("--canonicalize-url", nargs="+")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ for url in pargs.canonicalize_url:
+ host, vol = url.split("::")
+ host = host.replace("ssh://", "")
+ remote_addr = host
+ if "@" not in remote_addr:
+ remote_addr = "root@" + remote_addr
+
+ user, hname = remote_addr.split("@")
+
+ if not inet6:
+ hname = gethostbyname(hname)
+
+ print(("ssh://%s@%s:gluster://127.0.0.1:%s" % (
+ user, hname, vol)))
+
+ sys.exit(0)
+ elif "--normalize-url" in sys.argv:
+ # Adds schema prefix as ssh://
+ # This format not used in gsyncd, but added for glusterd compatibility
+ p = ArgumentParser()
+ p.add_argument("--normalize-url")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+ print(("ssh://%s" % slave_url(pargs.normalize_url)))
+ sys.exit(0)
+ elif "--config-get-all" in sys.argv:
+ # -c gsyncd.conf --iprefix=/var :gv1 f241::gv2 --config-get-all
+ p = ArgumentParser()
+ p.add_argument("master")
+ p.add_argument("slave")
+ p.add_argument("-c")
+ p.add_argument("--iprefix")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ init_gsyncd_session_conf(pargs.master, pargs.slave)
+
+ sys.argv = [
+ sys.argv[0],
+ "config-get",
+ pargs.master.strip(":"),
+ slave_url(pargs.slave),
+ "--show-defaults",
+ "--use-underscore"
+ ]
+ elif "--verify" in sys.argv and "spawning" in sys.argv:
+ # Just checks that able to spawn gsyncd or not
+ sys.exit(0)
+ elif "--slavevoluuid-get" in sys.argv:
+ # --slavevoluuid-get f241::gv2
+ p = ArgumentParser()
+ p.add_argument("--slavevoluuid-get")
+ p.add_argument("-c")
+ p.add_argument("--iprefix")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+ host, vol = pargs.slavevoluuid_get.split("::")
+
+ # Modified sys.argv
+ sys.argv = [
+ sys.argv[0],
+ "voluuidget",
+ host,
+ vol
+ ]
+ elif "--config-set-rx" in sys.argv:
+ # Not required since default conf is not generated
+ # and custom conf generated only when required
+ # -c gsyncd.conf --config-set-rx remote-gsyncd
+ # /usr/local/libexec/glusterfs/gsyncd . .
+ # Touch the gsyncd.conf file and create session
+ # directory if required
+ p = ArgumentParser()
+ p.add_argument("-c", dest="config_file")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ # If not template conf then it is trying to create
+ # session config, create a empty file instead
+ if pargs.config_file.endswith("gsyncd.conf"):
+ init_gsyncd_conf(pargs.config_file)
+ sys.exit(0)
+ elif "--create" in sys.argv:
+ # To update monitor status file
+ # --create Created -c gsyncd.conf
+ # --iprefix=/var :gv1 f241::gv2
+ p = ArgumentParser()
+ p.add_argument("--create")
+ p.add_argument("master")
+ p.add_argument("slave")
+ p.add_argument("-c")
+ p.add_argument("--iprefix")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ init_gsyncd_session_conf(pargs.master, pargs.slave)
+
+ # Modified sys.argv
+ sys.argv = [
+ sys.argv[0],
+ "monitor-status",
+ pargs.master.strip(":"),
+ slave_url(pargs.slave),
+ pargs.create
+ ]
+ elif "--config-get" in sys.argv:
+ # -c gsyncd.conf --iprefix=/var :gv1 f241::gv2 --config-get pid-file
+ p = ArgumentParser()
+ p.add_argument("--config-get")
+ p.add_argument("master")
+ p.add_argument("slave")
+ p.add_argument("-c")
+ p.add_argument("--iprefix")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ init_gsyncd_session_conf(pargs.master, pargs.slave)
+
+ # Modified sys.argv
+ sys.argv = [
+ sys.argv[0],
+ "config-get",
+ pargs.master.strip(":"),
+ slave_url(pargs.slave),
+ "--only-value",
+ "--show-defaults",
+ "--name",
+ pargs.config_get.replace("_", "-")
+ ]
+ elif "--config-set" in sys.argv:
+ # ignore session-owner
+ if "session-owner" in sys.argv:
+ sys.exit(0)
+
+ # --path=/bricks/b1 -c gsyncd.conf :gv1 f241::gv2
+ # --config-set log_level DEBUG
+ p = ArgumentParser()
+ p.add_argument("master")
+ p.add_argument("slave")
+ p.add_argument("--config-set", action='store_true')
+ p.add_argument("name")
+ p.add_argument("--value")
+ p.add_argument("-c")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ init_gsyncd_session_conf(pargs.master, pargs.slave)
+
+ # Modified sys.argv
+ sys.argv = [
+ sys.argv[0],
+ "config-set",
+ pargs.master.strip(":"),
+ slave_url(pargs.slave),
+ "--name=%s" % pargs.name,
+ "--value=%s" % pargs.value
+ ]
+ elif "--config-check" in sys.argv:
+ # --config-check georep_session_working_dir
+ p = ArgumentParser()
+ p.add_argument("--config-check")
+ p.add_argument("-c")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ # Modified sys.argv
+ sys.argv = [
+ sys.argv[0],
+ "config-check",
+ pargs.config_check.replace("_", "-")
+ ]
+ elif "--config-del" in sys.argv:
+ # -c gsyncd.conf --iprefix=/var :gv1 f241::gv2 --config-del log_level
+ p = ArgumentParser()
+ p.add_argument("--config-del")
+ p.add_argument("master")
+ p.add_argument("slave")
+ p.add_argument("-c")
+ p.add_argument("--iprefix")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ init_gsyncd_session_conf(pargs.master, pargs.slave)
+
+ # Modified sys.argv
+ sys.argv = [
+ sys.argv[0],
+ "config-reset",
+ pargs.master.strip(":"),
+ slave_url(pargs.slave),
+ pargs.config_del.replace("_", "-")
+ ]
+ elif "--delete" in sys.argv:
+ # --delete -c gsyncd.conf --iprefix=/var
+ # --path-list=--path=/bricks/b1 :gv1 f241::gv2
+ p = ArgumentParser()
+ p.add_argument("--reset-sync-time", action="store_true")
+ p.add_argument("--path-list")
+ p.add_argument("master")
+ p.add_argument("slave")
+ p.add_argument("--iprefix")
+ p.add_argument("-c")
+ pargs = p.parse_known_args(sys.argv[1:])[0]
+
+ init_gsyncd_session_conf(pargs.master, pargs.slave)
+
+ paths = pargs.path_list.split("--path=")
+ paths = ["--path=%s" % x.strip() for x in paths if x.strip() != ""]
+
+ # Modified sys.argv
+ sys.argv = [
+ sys.argv[0],
+ "delete",
+ pargs.master.strip(":"),
+ slave_url(pargs.slave)
+ ]
+ sys.argv += paths
+
+ if pargs.reset_sync_time:
+ sys.argv.append("--reset-sync-time")
+
+ if inet6:
+ # Add `--inet6` as first argument
+ sys.argv = [sys.argv[0], "--inet6"] + sys.argv[1:]
diff --git a/geo-replication/syncdaemon/changelogagent.py b/geo-replication/syncdaemon/changelogagent.py
deleted file mode 100644
index ad5f69cfb23..00000000000
--- a/geo-replication/syncdaemon/changelogagent.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
-# This file is part of GlusterFS.
-
-# This file is licensed to you under your choice of the GNU Lesser
-# General Public License, version 3 or any later version (LGPLv3 or
-# later), or the GNU General Public License, version 2 (GPLv2), in all
-# cases as published by the Free Software Foundation.
-#
-
-import os
-import logging
-import syncdutils
-from syncdutils import select, CHANGELOG_AGENT_SERVER_VERSION
-from repce import RepceServer
-
-
-class _MetaChangelog(object):
-
- def __getattr__(self, meth):
- from libgfchangelog import Changes as LChanges
- xmeth = [m for m in dir(LChanges) if m[0] != '_']
- if meth not in xmeth:
- return
- for m in xmeth:
- setattr(self, m, getattr(LChanges, m))
- return getattr(self, meth)
-
-Changes = _MetaChangelog()
-
-
-class Changelog(object):
- def version(self):
- return CHANGELOG_AGENT_SERVER_VERSION
-
- def init(self):
- return Changes.cl_init()
-
- def register(self, cl_brick, cl_dir, cl_log, cl_level, retries=0):
- return Changes.cl_register(cl_brick, cl_dir, cl_log, cl_level, retries)
-
- def scan(self):
- return Changes.cl_scan()
-
- def getchanges(self):
- return Changes.cl_getchanges()
-
- def done(self, clfile):
- return Changes.cl_done(clfile)
-
- def history(self, changelog_path, start, end, num_parallel):
- return Changes.cl_history_changelog(changelog_path, start, end,
- num_parallel)
-
- def history_scan(self):
- return Changes.cl_history_scan()
-
- def history_getchanges(self):
- return Changes.cl_history_getchanges()
-
- def history_done(self, clfile):
- return Changes.cl_history_done(clfile)
-
-
-class ChangelogAgent(object):
- def __init__(self, obj, fd_tup):
- (inf, ouf, rw, ww) = fd_tup.split(',')
- os.close(int(rw))
- os.close(int(ww))
- repce = RepceServer(obj, int(inf), int(ouf), 1)
- t = syncdutils.Thread(target=lambda: (repce.service_loop(),
- syncdutils.finalize()))
- t.start()
- logging.info('Agent listining...')
-
- select((), (), ())
-
-
-def agent(obj, fd_tup):
- return ChangelogAgent(obj, fd_tup)
diff --git a/geo-replication/syncdaemon/conf.py.in b/geo-replication/syncdaemon/conf.py.in
new file mode 100644
index 00000000000..2042fa9cdfb
--- /dev/null
+++ b/geo-replication/syncdaemon/conf.py.in
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2016 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.
+#
+
+GLUSTERFS_LIBEXECDIR = '@GLUSTERFS_LIBEXECDIR@'
+GLUSTERD_WORKDIR = "@GLUSTERD_WORKDIR@"
+
+LOCALSTATEDIR = "@localstatedir@"
+UUID_FILE = "@GLUSTERD_WORKDIR@/glusterd.info"
+GLUSTERFS_CONFDIR = "@SYSCONF_DIR@/glusterfs"
+GCONF_VERSION = 4.0
diff --git a/geo-replication/syncdaemon/configinterface.py.in b/geo-replication/syncdaemon/configinterface.py.in
deleted file mode 100644
index f8df49935f1..00000000000
--- a/geo-replication/syncdaemon/configinterface.py.in
+++ /dev/null
@@ -1,360 +0,0 @@
-#
-# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
-# This file is part of GlusterFS.
-
-# This file is licensed to you under your choice of the GNU Lesser
-# General Public License, version 3 or any later version (LGPLv3 or
-# later), or the GNU General Public License, version 2 (GPLv2), in all
-# cases as published by the Free Software Foundation.
-#
-
-try:
- import ConfigParser
-except ImportError:
- # py 3
- import configparser as ConfigParser
-import re
-from string import Template
-import os
-import errno
-import sys
-from stat import ST_DEV, ST_INO, ST_MTIME
-import tempfile
-import shutil
-
-from syncdutils import escape, unescape, norm, update_file, GsyncdError
-
-SECT_ORD = '__section_order__'
-SECT_META = '__meta__'
-config_version = 2.0
-
-re_type = type(re.compile(''))
-
-
-# (SECTION, OPTION, OLD VALUE, NEW VALUE)
-CONFIGS = (
- ("peersrx . .",
- "georep_session_working_dir",
- "",
- "@GLUSTERD_WORKDIR@/geo-replication/${mastervol}_${remotehost}_"
- "${slavevol}/"),
- ("peersrx .",
- "gluster_params",
- "aux-gfid-mount xlator-option=\*-dht.assert-no-child-down=true",
- "aux-gfid-mount"),
- ("peersrx .",
- "gluster_params",
- "aux-gfid-mount",
- "aux-gfid-mount acl"),
- ("peersrx . .",
- "ssh_command_tar",
- "",
- "ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no "
- "-i @GLUSTERD_WORKDIR@/geo-replication/tar_ssh.pem"),
- ("peersrx . .",
- "changelog_log_file",
- "",
- "${iprefix}/log/glusterfs/geo-replication/${mastervol}"
- "/${eSlave}${local_id}-changes.log"),
- ("peersrx . .",
- "working_dir",
- "@localstatedir@/run/gluster/${mastervol}/${eSlave}",
- "${iprefix}/lib/misc/glusterfsd/${mastervol}/${eSlave}"),
- ("peersrx . .",
- "ignore_deletes",
- "true",
- "false"),
-)
-
-
-def upgrade_config_file(path):
- config_change = False
- config = ConfigParser.RawConfigParser()
- config.read(path)
-
- for sec, opt, oldval, newval in CONFIGS:
- try:
- val = config.get(sec, opt)
- except ConfigParser.NoOptionError:
- # if new config opt not exists
- config_change = True
- config.set(sec, opt, newval)
- continue
- except ConfigParser.Error:
- """
- When gsyncd invoked at the time of create, config file
- will not be their. Ignore any ConfigParser errors
- """
- continue
-
- if val == newval:
- # value is same as new val
- continue
-
- if val == oldval:
- # config value needs update
- config_change = True
- config.set(sec, opt, newval)
-
- if config_change:
- tempConfigFile = tempfile.NamedTemporaryFile(mode="wb", delete=False)
- with open(tempConfigFile.name, 'wb') as configFile:
- config.write(configFile)
-
- # If src and dst are two different file system, then os.rename
- # fails, In this case if temp file created in /tmp and if /tmp is
- # separate fs then os.rename gives following error, so use shutil
- # OSError: [Errno 18] Invalid cross-device link
- # mail.python.org/pipermail/python-list/2005-February/342893.html
- shutil.move(tempConfigFile.name, path)
-
-
-class MultiDict(object):
-
- """a virtual dict-like class which functions as the union
- of underlying dicts"""
-
- def __init__(self, *dd):
- self.dicts = dd
-
- def __getitem__(self, key):
- val = None
- for d in self.dicts:
- if d.get(key) is not None:
- val = d[key]
- if val is None:
- raise KeyError(key)
- return val
-
-
-class GConffile(object):
-
- """A high-level interface to ConfigParser which flattens the two-tiered
- config layout by implenting automatic section dispatch based on initial
- parameters.
-
- Also ensure section ordering in terms of their time of addition -- a compat
- hack for Python < 2.7.
- """
-
- def _normconfig(self):
- """normalize config keys by s/-/_/g"""
- for n, s in self.config._sections.items():
- if n.find('__') == 0:
- continue
- s2 = type(s)()
- for k, v in s.items():
- if k.find('__') != 0:
- k = norm(k)
- s2[k] = v
- self.config._sections[n] = s2
-
- def __init__(self, path, peers, *dd):
- """
- - .path: location of config file
- - .config: underlying ConfigParser instance
- - .peers: on behalf of whom we flatten .config
- (master, or master-slave url pair)
- - .auxdicts: template subtituents
- """
- self.peers = peers
- self.path = path
- self.auxdicts = dd
- self.config = ConfigParser.RawConfigParser()
- self.config.read(path)
- self.dev, self.ino, self.mtime = -1, -1, -1
- self._normconfig()
-
- def _load(self):
- try:
- sres = os.stat(self.path)
- self.dev = sres[ST_DEV]
- self.ino = sres[ST_INO]
- self.mtime = sres[ST_MTIME]
- except (OSError, IOError):
- if sys.exc_info()[1].errno == errno.ENOENT:
- sres = None
-
- self.config = ConfigParser.RawConfigParser()
- self.config.read(self.path)
- self._normconfig()
-
- def get_realtime(self, opt):
- try:
- sres = os.stat(self.path)
- except (OSError, IOError):
- if sys.exc_info()[1].errno == errno.ENOENT:
- sres = None
- else:
- raise
-
- # compare file system stat with that of our stream file handle
- if not sres or sres[ST_DEV] != self.dev or \
- sres[ST_INO] != self.ino or self.mtime != sres[ST_MTIME]:
- self._load()
-
- return self.get(opt, printValue=False)
-
- def section(self, rx=False):
- """get the section name of the section representing .peers
- in .config"""
- peers = self.peers
- if not peers:
- peers = ['.', '.']
- rx = True
- if rx:
- st = 'peersrx'
- else:
- st = 'peers'
- return ' '.join([st] + [escape(u) for u in peers])
-
- @staticmethod
- def parse_section(section):
- """retrieve peers sequence encoded by section name
- (as urls or regexen, depending on section type)
- """
- sl = section.split()
- st = sl.pop(0)
- sl = [unescape(u) for u in sl]
- if st == 'peersrx':
- sl = [re.compile(u) for u in sl]
- return sl
-
- def ord_sections(self):
- """Return an ordered list of sections.
-
- Ordering happens based on the auxiliary
- SECT_ORD section storing indices for each
- section added through the config API.
-
- To not to go corrupt in case of manually
- written config files, we take care to append
- also those sections which are not registered
- in SECT_ORD.
-
- Needed for python 2.{4,5,6} where ConfigParser
- cannot yet order sections/options internally.
- """
- so = {}
- if self.config.has_section(SECT_ORD):
- so = self.config._sections[SECT_ORD]
- so2 = {}
- for k, v in so.items():
- if k != '__name__':
- so2[k] = int(v)
- tv = 0
- if so2:
- tv = max(so2.values()) + 1
- ss = [s for s in self.config.sections() if s.find('__') != 0]
- for s in ss:
- if s in so.keys():
- continue
- so2[s] = tv
- tv += 1
-
- def scmp(x, y):
- return cmp(*(so2[s] for s in (x, y)))
- ss.sort(scmp)
- return ss
-
- def update_to(self, dct, allow_unresolved=False):
- """update @dct from key/values of ours.
-
- key/values are collected from .config by filtering the regexp sections
- according to match, and from .section. The values are treated as
- templates, which are substituted from .auxdicts and (in case of regexp
- sections) match groups.
- """
- if not self.peers:
- raise GsyncdError('no peers given, cannot select matching options')
-
- def update_from_sect(sect, mud):
- for k, v in self.config._sections[sect].items():
- if k == '__name__':
- continue
- if allow_unresolved:
- dct[k] = Template(v).safe_substitute(mud)
- else:
- dct[k] = Template(v).substitute(mud)
- for sect in self.ord_sections():
- sp = self.parse_section(sect)
- if isinstance(sp[0], re_type) and len(sp) == len(self.peers):
- match = True
- mad = {}
- for i in range(len(sp)):
- m = sp[i].search(self.peers[i])
- if not m:
- match = False
- break
- for j in range(len(m.groups())):
- mad['match%d_%d' % (i + 1, j + 1)] = m.groups()[j]
- if match:
- update_from_sect(sect, MultiDict(dct, mad, *self.auxdicts))
- if self.config.has_section(self.section()):
- update_from_sect(self.section(), MultiDict(dct, *self.auxdicts))
-
- def get(self, opt=None, printValue=True):
- """print the matching key/value pairs from .config,
- or if @opt given, the value for @opt (according to the
- logic described in .update_to)
- """
- d = {}
- self.update_to(d, allow_unresolved=True)
- if opt:
- opt = norm(opt)
- v = d.get(opt)
- if v:
- if printValue:
- print(v)
- else:
- return v
- else:
- for k, v in d.iteritems():
- if k == '__name__':
- continue
- print("%s: %s" % (k, v))
-
- def write(self, trfn, opt, *a, **kw):
- """update on-disk config transactionally
-
- @trfn is the transaction function
- """
- def mergeconf(f):
- self.config = ConfigParser.RawConfigParser()
- self.config.readfp(f)
- self._normconfig()
- if not self.config.has_section(SECT_META):
- self.config.add_section(SECT_META)
- self.config.set(SECT_META, 'version', config_version)
- return trfn(norm(opt), *a, **kw)
-
- def updateconf(f):
- self.config.write(f)
- update_file(self.path, updateconf, mergeconf)
-
- def _set(self, opt, val, rx=False):
- """set @opt to @val in .section"""
- sect = self.section(rx)
- if not self.config.has_section(sect):
- self.config.add_section(sect)
- # regarding SECT_ORD, cf. ord_sections
- if not self.config.has_section(SECT_ORD):
- self.config.add_section(SECT_ORD)
- self.config.set(
- SECT_ORD, sect, len(self.config._sections[SECT_ORD]))
- self.config.set(sect, opt, val)
- return True
-
- def set(self, opt, *a, **kw):
- """perform ._set transactionally"""
- self.write(self._set, opt, *a, **kw)
-
- def _delete(self, opt, rx=False):
- """delete @opt from .section"""
- sect = self.section(rx)
- if self.config.has_section(sect):
- return self.config.remove_option(sect, opt)
-
- def delete(self, opt, *a, **kw):
- """perform ._delete transactionally"""
- self.write(self._delete, opt, *a, **kw)
diff --git a/geo-replication/syncdaemon/gsyncd.py b/geo-replication/syncdaemon/gsyncd.py
index b3c7e62506e..257ed72c6ae 100644
--- a/geo-replication/syncdaemon/gsyncd.py
+++ b/geo-replication/syncdaemon/gsyncd.py
@@ -1,664 +1,325 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
#
-# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
-# This file is part of GlusterFS.
-
-# This file is licensed to you under your choice of the GNU Lesser
-# General Public License, version 3 or any later version (LGPLv3 or
-# later), or the GNU General Public License, version 2 (GPLv2), in all
-# cases as published by the Free Software Foundation.
+# Copyright (c) 2016 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.
#
+from argparse import ArgumentParser
+import time
import os
-import os.path
-import glob
+from errno import EEXIST
import sys
-import time
import logging
-import shutil
-import optparse
-import fcntl
-import fnmatch
-from optparse import OptionParser, SUPPRESS_HELP
-from logging import Logger, handlers
-from errno import ENOENT
-
-from ipaddr import IPAddress, IPNetwork
-
-from gconf import gconf
-from syncdutils import FreeObject, norm, grabpidfile, finalize
-from syncdutils import log_raise_exception, privileged
-from syncdutils import GsyncdError, select, set_term_handler
-from configinterface import GConffile, upgrade_config_file
-import resource
-from monitor import monitor
-from changelogagent import agent, Changelog
-from gsyncdstatus import set_monitor_status, GeorepStatus
-
-
-class GLogger(Logger):
-
- """Logger customizations for gsyncd.
-
- It implements a log format similar to that of glusterfs.
- """
-
- def makeRecord(self, name, level, *a):
- rv = Logger.makeRecord(self, name, level, *a)
- rv.nsecs = (rv.created - int(rv.created)) * 1000000
- fr = sys._getframe(4)
- callee = fr.f_locals.get('self')
- if callee:
- ctx = str(type(callee)).split("'")[1].split('.')[-1]
- else:
- ctx = '<top>'
- if not hasattr(rv, 'funcName'):
- rv.funcName = fr.f_code.co_name
- rv.lvlnam = logging.getLevelName(level)[0]
- rv.ctx = ctx
- return rv
-
- @classmethod
- def setup(cls, **kw):
- lbl = kw.get('label', "")
- if lbl:
- lbl = '(' + lbl + ')'
- lprm = {'datefmt': "%Y-%m-%d %H:%M:%S",
- 'format': "[%(asctime)s.%(nsecs)d] %(lvlnam)s [%(module)s" +
- lbl + ":%(lineno)s:%(funcName)s] %(ctx)s: %(message)s"}
- lprm.update(kw)
- lvl = kw.get('level', logging.INFO)
- lprm['level'] = lvl
- logging.root = cls("root", lvl)
- logging.setLoggerClass(cls)
- logging.getLogger().handlers = []
- logging.getLogger().setLevel(lprm['level'])
-
- if 'filename' in lprm:
- try:
- logging_handler = handlers.WatchedFileHandler(lprm['filename'])
- formatter = logging.Formatter(fmt=lprm['format'],
- datefmt=lprm['datefmt'])
- logging_handler.setFormatter(formatter)
- logging.getLogger().addHandler(logging_handler)
- except AttributeError:
- # Python version < 2.6 will not have WatchedFileHandler
- # so fallback to logging without any handler.
- # Note: logrotate will not work if Python version is < 2.6
- logging.basicConfig(**lprm)
- else:
- # If filename not passed(not available in lprm) then it may be
- # streaming.(Ex: {"stream": "/dev/stdout"})
- logging.basicConfig(**lprm)
-
- @classmethod
- def _gsyncd_loginit(cls, **kw):
- lkw = {}
- if gconf.log_level:
- lkw['level'] = gconf.log_level
- if kw.get('log_file'):
- if kw['log_file'] in ('-', '/dev/stderr'):
- lkw['stream'] = sys.stderr
- elif kw['log_file'] == '/dev/stdout':
- lkw['stream'] = sys.stdout
- else:
- lkw['filename'] = kw['log_file']
-
- cls.setup(label=kw.get('label'), **lkw)
-
- lkw.update({'saved_label': kw.get('label')})
- gconf.log_metadata = lkw
- gconf.log_exit = True
-
-
-def startup(**kw):
- """set up logging, pidfile grabbing, daemonization"""
- if getattr(gconf, 'pid_file', None) and kw.get('go_daemon') != 'postconn':
- if not grabpidfile():
- sys.stderr.write("pidfile is taken, exiting.\n")
- sys.exit(2)
- gconf.pid_file_owned = True
-
- if kw.get('go_daemon') == 'should':
- x, y = os.pipe()
- gconf.cpid = os.fork()
- if gconf.cpid:
- os.close(x)
- sys.exit()
- os.close(y)
- os.setsid()
- dn = os.open(os.devnull, os.O_RDWR)
- for f in (sys.stdin, sys.stdout, sys.stderr):
- os.dup2(dn, f.fileno())
- if getattr(gconf, 'pid_file', None):
- if not grabpidfile(gconf.pid_file + '.tmp'):
- raise GsyncdError("cannot grab temporary pidfile")
- os.rename(gconf.pid_file + '.tmp', gconf.pid_file)
- # wait for parent to terminate
- # so we can start up with
- # no messing from the dirty
- # ol' bustard
- select((x,), (), ())
- os.close(x)
-
- GLogger._gsyncd_loginit(**kw)
-
-
-def _unlink(path):
- try:
- os.unlink(path)
- except (OSError, IOError):
- if sys.exc_info()[1].errno == ENOENT:
- pass
- else:
- raise GsyncdError('Unlink error: %s' % path)
+
+from logutils import setup_logging
+import gsyncdconfig as gconf
+from rconf import rconf
+import subcmds
+from conf import GLUSTERD_WORKDIR, GLUSTERFS_CONFDIR, GCONF_VERSION
+from syncdutils import (set_term_handler, finalize, lf,
+ log_raise_exception, FreeObject, escape)
+import argsupgrade
+
+
+GSYNCD_VERSION = "gsyncd.py %s.0" % GCONF_VERSION
def main():
- """main routine, signal/exception handling boilerplates"""
- gconf.starttime = time.time()
+ rconf.starttime = time.time()
+
+ # If old Glusterd sends commands in old format, below function
+ # converts the sys.argv to new format. This conversion is added
+ # temporarily for backward compatibility. This can be removed
+ # once integrated with Glusterd2
+ # This modifies sys.argv globally, so rest of the code works as usual
+ argsupgrade.upgrade()
+
+ # Default argparse version handler prints to stderr, which is fixed in
+ # 3.x series but not in 2.x, using custom parser to fix this issue
+ if "--version" in sys.argv:
+ print(GSYNCD_VERSION)
+ sys.exit(0)
+
+ parser = ArgumentParser()
+ parser.add_argument("--inet6", action="store_true")
+ sp = parser.add_subparsers(dest="subcmd")
+
+ # Monitor Status File update
+ p = sp.add_parser("monitor-status")
+ p.add_argument("master", help="Master Volume Name")
+ p.add_argument("slave", help="Slave details user@host::vol format")
+ p.add_argument("status", help="Update Monitor Status")
+ p.add_argument("-c", "--config-file", help="Config File")
+ p.add_argument("--debug", action="store_true")
+
+ # Monitor
+ p = sp.add_parser("monitor")
+ p.add_argument("master", help="Master Volume Name")
+ p.add_argument("slave", help="Slave details user@host::vol format")
+ p.add_argument("-c", "--config-file", help="Config File")
+ p.add_argument("--pause-on-start",
+ action="store_true",
+ help="Start with Paused state")
+ p.add_argument("--local-node-id", help="Local Node ID")
+ p.add_argument("--debug", action="store_true")
+ p.add_argument("--use-gconf-volinfo", action="store_true")
+
+ # Worker
+ p = sp.add_parser("worker")
+ p.add_argument("master", help="Master Volume Name")
+ p.add_argument("slave", help="Slave details user@host::vol format")
+ p.add_argument("--local-path", help="Local Brick Path")
+ p.add_argument("--feedback-fd", type=int,
+ help="feedback fd between monitor and worker")
+ p.add_argument("--local-node", help="Local master node")
+ p.add_argument("--local-node-id", help="Local Node ID")
+ p.add_argument("--subvol-num", type=int, help="Subvolume number")
+ p.add_argument("--is-hottier", action="store_true",
+ help="Is this brick part of hot tier")
+ p.add_argument("--resource-remote",
+ help="Remote node to connect to Slave Volume")
+ p.add_argument("--resource-remote-id",
+ help="Remote node ID to connect to Slave Volume")
+ p.add_argument("--slave-id", help="Slave Volume ID")
+ p.add_argument("-c", "--config-file", help="Config File")
+ p.add_argument("--debug", action="store_true")
+
+ # Slave
+ p = sp.add_parser("slave")
+ p.add_argument("master", help="Master Volume Name")
+ p.add_argument("slave", help="Slave details user@host::vol format")
+ p.add_argument("--session-owner")
+ p.add_argument("--master-brick",
+ help="Master brick which is connected to the Slave")
+ p.add_argument("--master-node",
+ help="Master node which is connected to the Slave")
+ p.add_argument("--master-node-id",
+ help="Master node ID which is connected to the Slave")
+ p.add_argument("--local-node", help="Local Slave node")
+ p.add_argument("--local-node-id", help="Local Slave ID")
+ p.add_argument("-c", "--config-file", help="Config File")
+ p.add_argument("--debug", action="store_true")
+
+ # All configurations which are configured via "slave-" options
+ # DO NOT add default values for these configurations, default values
+ # will be picked from template config file
+ p.add_argument("--slave-timeout", type=int,
+ help="Timeout to end gsyncd at Slave side")
+ p.add_argument("--use-rsync-xattrs", action="store_true")
+ p.add_argument("--slave-log-level", help="Slave Gsyncd Log level")
+ p.add_argument("--slave-gluster-log-level",
+ help="Slave Gluster mount Log level")
+ p.add_argument("--slave-gluster-command-dir",
+ help="Directory where Gluster binaries exist on slave")
+ p.add_argument("--slave-access-mount", action="store_true",
+ help="Do not lazy umount the slave volume")
+ p.add_argument("--master-dist-count", type=int,
+ help="Master Distribution count")
+
+ # Status
+ p = sp.add_parser("status")
+ p.add_argument("master", help="Master Volume Name")
+ p.add_argument("slave", help="Slave")
+ p.add_argument("-c", "--config-file", help="Config File")
+ p.add_argument("--local-path", help="Local Brick Path")
+ p.add_argument("--debug", action="store_true")
+ p.add_argument("--json", action="store_true")
+
+ # Config-check
+ p = sp.add_parser("config-check")
+ p.add_argument("name", help="Config Name")
+ p.add_argument("--value", help="Config Value")
+ p.add_argument("--debug", action="store_true")
+
+ # Config-get
+ p = sp.add_parser("config-get")
+ p.add_argument("master", help="Master Volume Name")
+ p.add_argument("slave", help="Slave")
+ p.add_argument("--name", help="Config Name")
+ p.add_argument("-c", "--config-file", help="Config File")
+ p.add_argument("--debug", action="store_true")
+ p.add_argument("--show-defaults", action="store_true")
+ p.add_argument("--only-value", action="store_true")
+ p.add_argument("--use-underscore", action="store_true")
+ p.add_argument("--json", action="store_true")
+
+ # Config-set
+ p = sp.add_parser("config-set")
+ p.add_argument("master", help="Master Volume Name")
+ p.add_argument("slave", help="Slave")
+ p.add_argument("-n", "--name", help="Config Name")
+ p.add_argument("-v", "--value", help="Config Value")
+ p.add_argument("-c", "--config-file", help="Config File")
+ p.add_argument("--debug", action="store_true")
+
+ # Config-reset
+ p = sp.add_parser("config-reset")
+ p.add_argument("master", help="Master Volume Name")
+ p.add_argument("slave", help="Slave")
+ p.add_argument("name", help="Config Name")
+ p.add_argument("-c", "--config-file", help="Config File")
+ p.add_argument("--debug", action="store_true")
+
+ # voluuidget
+ p = sp.add_parser("voluuidget")
+ p.add_argument("host", help="Hostname")
+ p.add_argument("volname", help="Volume Name")
+ p.add_argument("--debug", action="store_true")
+
+ # Delete
+ p = sp.add_parser("delete")
+ p.add_argument("master", help="Master Volume Name")
+ p.add_argument("slave", help="Slave")
+ p.add_argument("-c", "--config-file", help="Config File")
+ p.add_argument('--path', dest='paths', action="append")
+ p.add_argument("--reset-sync-time", action="store_true",
+ help="Reset Sync Time")
+ p.add_argument("--debug", action="store_true")
+
+ # Parse arguments
+ args = parser.parse_args()
+
+ # Extra template values, All arguments are already part of template
+ # variables, use this for adding extra variables
+ extra_tmpl_args = {}
+
+ # Add First/Primary Slave host, user and volume
+ if getattr(args, "slave", None) is not None:
+ hostdata, slavevol = args.slave.split("::")
+ hostdata = hostdata.split("@")
+ slavehost = hostdata[-1]
+ slaveuser = "root"
+ if len(hostdata) == 2:
+ slaveuser = hostdata[0]
+ extra_tmpl_args["primary_slave_host"] = slavehost
+ extra_tmpl_args["slaveuser"] = slaveuser
+ extra_tmpl_args["slavevol"] = slavevol
+
+ # Add Bricks encoded path
+ if getattr(args, "local_path", None) is not None:
+ extra_tmpl_args["local_id"] = escape(args.local_path)
+
+ # Add Master Bricks encoded path(For Slave)
+ if getattr(args, "master_brick", None) is not None:
+ extra_tmpl_args["master_brick_id"] = escape(args.master_brick)
+
+ # Load configurations
+ config_file = getattr(args, "config_file", None)
+
+ # Subcmd accepts config file argument but not passed
+ # Set default path for config file in that case
+ # If an subcmd accepts config file then it also accepts
+ # master and Slave arguments.
+ if config_file is None and hasattr(args, "config_file") \
+ and args.subcmd != "slave":
+ config_file = "%s/geo-replication/%s_%s_%s/gsyncd.conf" % (
+ GLUSTERD_WORKDIR,
+ args.master,
+ extra_tmpl_args["primary_slave_host"],
+ extra_tmpl_args["slavevol"])
+
+ # If Config file path not exists, log error and continue using default conf
+ config_file_error_msg = None
+ if config_file is not None and not os.path.exists(config_file):
+ # Logging not yet initialized, create the error message to
+ # log later and reset the config_file to None
+ config_file_error_msg = lf(
+ "Session config file not exists, using the default config",
+ path=config_file)
+ config_file = None
+
+ rconf.config_file = config_file
+
+ # Override gconf values from argument values only if it is slave gsyncd
+ override_from_args = False
+ if args.subcmd == "slave":
+ override_from_args = True
+
+ if config_file is not None and \
+ args.subcmd in ["monitor", "config-get", "config-set", "config-reset"]:
+ ret = gconf.is_config_file_old(config_file, args.master, extra_tmpl_args["slavevol"])
+ if ret is not None:
+ gconf.config_upgrade(config_file, ret)
+
+ # Load Config file
+ gconf.load(GLUSTERFS_CONFDIR + "/gsyncd.conf",
+ config_file,
+ vars(args),
+ extra_tmpl_args,
+ override_from_args)
+
+ # Default label to print in log file
+ label = args.subcmd
+ if args.subcmd in ("worker"):
+ # If Worker, then add brick path also to label
+ label = "%s %s" % (args.subcmd, args.local_path)
+ elif args.subcmd == "slave":
+ # If Slave add Master node and Brick details
+ label = "%s %s%s" % (args.subcmd, args.master_node, args.master_brick)
+
+ # Setup Logger
+ # Default log file
+ log_file = gconf.get("cli-log-file")
+ log_level = gconf.get("cli-log-level")
+ if getattr(args, "master", None) is not None and \
+ getattr(args, "slave", None) is not None:
+ log_file = gconf.get("log-file")
+ log_level = gconf.get("log-level")
+
+ # Use different log file location for Slave log file
+ if args.subcmd == "slave":
+ log_file = gconf.get("slave-log-file")
+ log_level = gconf.get("slave-log-level")
+
+ if args.debug:
+ log_file = "-"
+ log_level = "DEBUG"
+
+ # Create Logdir if not exists
+ try:
+ if log_file != "-":
+ os.mkdir(os.path.dirname(log_file))
+ except OSError as e:
+ if e.errno != EEXIST:
+ raise
+
+ setup_logging(
+ log_file=log_file,
+ level=log_level,
+ label=label
+ )
+
+ if config_file_error_msg is not None:
+ logging.warn(config_file_error_msg)
+
+ # Log message for loaded config file
+ if config_file is not None:
+ logging.debug(lf("Using session config file", path=config_file))
+
set_term_handler()
- GLogger.setup()
excont = FreeObject(exval=0)
+
+ # Gets the function name based on the input argument. For example
+ # if subcommand passed as argument is monitor then it looks for
+ # function with name "subcmd_monitor" in subcmds file
+ func = getattr(subcmds, "subcmd_" + args.subcmd.replace("-", "_"), None)
+
try:
try:
- main_i()
+ if func is not None:
+ rconf.args = args
+ func(args)
except:
log_raise_exception(excont)
finally:
finalize(exval=excont.exval)
-def main_i():
- """internal main routine
-
- parse command line, decide what action will be taken;
- we can either:
- - query/manipulate configuration
- - format gsyncd urls using gsyncd's url parsing engine
- - start service in following modes, in given stages:
- - agent: startup(), ChangelogAgent()
- - monitor: startup(), monitor()
- - master: startup(), connect_remote(), connect(), service_loop()
- - slave: startup(), connect(), service_loop()
- """
- rconf = {'go_daemon': 'should'}
-
- def store_abs(opt, optstr, val, parser):
- if val and val != '-':
- val = os.path.abspath(val)
- setattr(parser.values, opt.dest, val)
-
- def store_local(opt, optstr, val, parser):
- rconf[opt.dest] = val
-
- def store_local_curry(val):
- return lambda o, oo, vx, p: store_local(o, oo, val, p)
-
- def store_local_obj(op, dmake):
- return lambda o, oo, vx, p: store_local(
- o, oo, FreeObject(op=op, **dmake(vx)), p)
-
- op = OptionParser(
- usage="%prog [options...] <master> <slave>", version="%prog 0.0.1")
- op.add_option('--gluster-command-dir', metavar='DIR', default='')
- op.add_option('--gluster-log-file', metavar='LOGF',
- default=os.devnull, type=str, action='callback',
- callback=store_abs)
- op.add_option('--gluster-log-level', metavar='LVL')
- op.add_option('--gluster-params', metavar='PRMS', default='')
- op.add_option(
- '--glusterd-uuid', metavar='UUID', type=str, default='',
- help=SUPPRESS_HELP)
- op.add_option(
- '--gluster-cli-options', metavar='OPTS', default='--log-file=-')
- op.add_option('--mountbroker', metavar='LABEL')
- op.add_option('-p', '--pid-file', metavar='PIDF', type=str,
- action='callback', callback=store_abs)
- op.add_option('-l', '--log-file', metavar='LOGF', type=str,
- action='callback', callback=store_abs)
- op.add_option('--iprefix', metavar='LOGD', type=str,
- action='callback', callback=store_abs)
- op.add_option('--changelog-log-file', metavar='LOGF', type=str,
- action='callback', callback=store_abs)
- op.add_option('--log-file-mbr', metavar='LOGF', type=str,
- action='callback', callback=store_abs)
- op.add_option('--state-file', metavar='STATF', type=str,
- action='callback', callback=store_abs)
- op.add_option('--state-detail-file', metavar='STATF',
- type=str, action='callback', callback=store_abs)
- op.add_option('--georep-session-working-dir', metavar='STATF',
- type=str, action='callback', callback=store_abs)
- op.add_option('--ignore-deletes', default=False, action='store_true')
- op.add_option('--isolated-slave', default=False, action='store_true')
- op.add_option('--use-rsync-xattrs', default=False, action='store_true')
- op.add_option('--sync-xattrs', default=True, action='store_true')
- op.add_option('--sync-acls', default=True, action='store_true')
- op.add_option('--log-rsync-performance', default=False,
- action='store_true')
- op.add_option('--pause-on-start', default=False, action='store_true')
- op.add_option('-L', '--log-level', metavar='LVL')
- op.add_option('-r', '--remote-gsyncd', metavar='CMD',
- default=os.path.abspath(sys.argv[0]))
- op.add_option('--volume-id', metavar='UUID')
- op.add_option('--slave-id', metavar='ID')
- op.add_option('--session-owner', metavar='ID')
- op.add_option('--local-id', metavar='ID', help=SUPPRESS_HELP, default='')
- op.add_option(
- '--local-path', metavar='PATH', help=SUPPRESS_HELP, default='')
- op.add_option('-s', '--ssh-command', metavar='CMD', default='ssh')
- op.add_option('--ssh-command-tar', metavar='CMD', default='ssh')
- op.add_option('--rsync-command', metavar='CMD', default='rsync')
- op.add_option('--rsync-options', metavar='OPTS', default='')
- op.add_option('--rsync-ssh-options', metavar='OPTS', default='--compress')
- op.add_option('--timeout', metavar='SEC', type=int, default=120)
- op.add_option('--connection-timeout', metavar='SEC',
- type=int, default=60, help=SUPPRESS_HELP)
- op.add_option('--sync-jobs', metavar='N', type=int, default=3)
- op.add_option('--replica-failover-interval', metavar='N',
- type=int, default=1)
- op.add_option('--changelog-archive-format', metavar='N',
- type=str, default="%Y%m")
- op.add_option('--use-meta-volume', default=False, action='store_true')
- op.add_option('--meta-volume-mnt', metavar='N',
- type=str, default="/var/run/gluster/shared_storage")
- op.add_option(
- '--turns', metavar='N', type=int, default=0, help=SUPPRESS_HELP)
- op.add_option('--allow-network', metavar='IPS', default='')
- op.add_option('--socketdir', metavar='DIR')
- op.add_option('--state-socket-unencoded', metavar='SOCKF',
- type=str, action='callback', callback=store_abs)
- op.add_option('--checkpoint', metavar='LABEL', default='0')
-
- # tunables for failover/failback mechanism:
- # None - gsyncd behaves as normal
- # blind - gsyncd works with xtime pairs to identify
- # candidates for synchronization
- # wrapup - same as normal mode but does not assign
- # xtimes to orphaned files
- # see crawl() for usage of the above tunables
- op.add_option('--special-sync-mode', type=str, help=SUPPRESS_HELP)
-
- # changelog or xtime? (TODO: Change the default)
- op.add_option(
- '--change-detector', metavar='MODE', type=str, default='xtime')
- # sleep interval for change detection (xtime crawl uses a hardcoded 1
- # second sleep time)
- op.add_option('--change-interval', metavar='SEC', type=int, default=3)
- # working directory for changelog based mechanism
- op.add_option('--working-dir', metavar='DIR', type=str,
- action='callback', callback=store_abs)
- op.add_option('--use-tarssh', default=False, action='store_true')
-
- op.add_option('-c', '--config-file', metavar='CONF',
- type=str, action='callback', callback=store_local)
- # duh. need to specify dest or value will be mapped to None :S
- op.add_option('--monitor', dest='monitor', action='callback',
- callback=store_local_curry(True))
- op.add_option('--agent', dest='agent', action='callback',
- callback=store_local_curry(True))
- op.add_option('--resource-local', dest='resource_local',
- type=str, action='callback', callback=store_local)
- op.add_option('--resource-remote', dest='resource_remote',
- type=str, action='callback', callback=store_local)
- op.add_option('--feedback-fd', dest='feedback_fd', type=int,
- help=SUPPRESS_HELP, action='callback', callback=store_local)
- op.add_option('--rpc-fd', dest='rpc_fd', type=str, help=SUPPRESS_HELP)
- op.add_option('--subvol-num', dest='subvol_num', type=int,
- help=SUPPRESS_HELP)
- op.add_option('--listen', dest='listen', help=SUPPRESS_HELP,
- action='callback', callback=store_local_curry(True))
- op.add_option('-N', '--no-daemon', dest="go_daemon",
- action='callback', callback=store_local_curry('dont'))
- op.add_option('--verify', type=str, dest="verify",
- action='callback', callback=store_local)
- op.add_option('--create', type=str, dest="create",
- action='callback', callback=store_local)
- op.add_option('--delete', dest='delete', action='callback',
- callback=store_local_curry(True))
- op.add_option('--status-get', dest='status_get', action='callback',
- callback=store_local_curry(True))
- op.add_option('--debug', dest="go_daemon", action='callback',
- callback=lambda *a: (store_local_curry('dont')(*a),
- setattr(
- a[-1].values, 'log_file', '-'),
- setattr(a[-1].values, 'log_level',
- 'DEBUG'),
- setattr(a[-1].values,
- 'changelog_log_file', '-')))
- op.add_option('--path', type=str, action='append')
-
- for a in ('check', 'get'):
- op.add_option('--config-' + a, metavar='OPT', type=str, dest='config',
- action='callback',
- callback=store_local_obj(a, lambda vx: {'opt': vx}))
- op.add_option('--config-get-all', dest='config', action='callback',
- callback=store_local_obj('get', lambda vx: {'opt': None}))
- for m in ('', '-rx', '-glob'):
- # call this code 'Pythonic' eh?
- # have to define a one-shot local function to be able
- # to inject (a value depending on the)
- # iteration variable into the inner lambda
- def conf_mod_opt_regex_variant(rx):
- op.add_option('--config-set' + m, metavar='OPT VAL', type=str,
- nargs=2, dest='config', action='callback',
- callback=store_local_obj('set', lambda vx: {
- 'opt': vx[0], 'val': vx[1], 'rx': rx}))
- op.add_option('--config-del' + m, metavar='OPT', type=str,
- dest='config', action='callback',
- callback=store_local_obj('del', lambda vx: {
- 'opt': vx, 'rx': rx}))
- conf_mod_opt_regex_variant(m and m[1:] or False)
-
- op.add_option('--normalize-url', dest='url_print',
- action='callback', callback=store_local_curry('normal'))
- op.add_option('--canonicalize-url', dest='url_print',
- action='callback', callback=store_local_curry('canon'))
- op.add_option('--canonicalize-escape-url', dest='url_print',
- action='callback', callback=store_local_curry('canon_esc'))
-
- tunables = [norm(o.get_opt_string()[2:])
- for o in op.option_list
- if (o.callback in (store_abs, 'store_true', None) and
- o.get_opt_string() not in ('--version', '--help'))]
- remote_tunables = ['listen', 'go_daemon', 'timeout',
- 'session_owner', 'config_file', 'use_rsync_xattrs']
- rq_remote_tunables = {'listen': True}
-
- # precedence for sources of values: 1) commandline, 2) cfg file, 3)
- # defaults for this to work out we need to tell apart defaults from
- # explicitly set options... so churn out the defaults here and call
- # the parser with virgin values container.
- defaults = op.get_default_values()
- opts, args = op.parse_args(values=optparse.Values())
- args_orig = args[:]
- r = rconf.get('resource_local')
- if r:
- if len(args) == 0:
- args.append(None)
- args[0] = r
- r = rconf.get('resource_remote')
- if r:
- if len(args) == 0:
- raise GsyncdError('local resource unspecfied')
- elif len(args) == 1:
- args.append(None)
- args[1] = r
- confdata = rconf.get('config')
- if not (len(args) == 2 or
- (len(args) == 1 and rconf.get('listen')) or
- (len(args) <= 2 and confdata) or
- rconf.get('url_print')):
- sys.stderr.write("error: incorrect number of arguments\n\n")
- sys.stderr.write(op.get_usage() + "\n")
- sys.exit(1)
-
- verify = rconf.get('verify')
- if verify:
- logging.info(verify)
- logging.info("Able to spawn gsyncd.py")
- return
-
- restricted = os.getenv('_GSYNCD_RESTRICTED_')
-
- if restricted:
- allopts = {}
- allopts.update(opts.__dict__)
- allopts.update(rconf)
- bannedtuns = set(allopts.keys()) - set(remote_tunables)
- if bannedtuns:
- raise GsyncdError('following tunables cannot be set with '
- 'restricted SSH invocaton: ' +
- ', '.join(bannedtuns))
- for k, v in rq_remote_tunables.items():
- if not k in allopts or allopts[k] != v:
- raise GsyncdError('tunable %s is not set to value %s required '
- 'for restricted SSH invocaton' %
- (k, v))
-
- confrx = getattr(confdata, 'rx', None)
-
- def makersc(aa, check=True):
- if not aa:
- return ([], None, None)
- ra = [resource.parse_url(u) for u in aa]
- local = ra[0]
- remote = None
- if len(ra) > 1:
- remote = ra[1]
- if check and not local.can_connect_to(remote):
- raise GsyncdError("%s cannot work with %s" %
- (local.path, remote and remote.path))
- return (ra, local, remote)
- if confrx:
- # peers are regexen, don't try to parse them
- if confrx == 'glob':
- args = ['\A' + fnmatch.translate(a) for a in args]
- canon_peers = args
- namedict = {}
- else:
- dc = rconf.get('url_print')
- rscs, local, remote = makersc(args_orig, not dc)
- if dc:
- for r in rscs:
- print(r.get_url(**{'normal': {},
- 'canon': {'canonical': True},
- 'canon_esc': {'canonical': True,
- 'escaped': True}}[dc]))
- return
- pa = ([], [], [])
- urlprms = (
- {}, {'canonical': True}, {'canonical': True, 'escaped': True})
- for x in rscs:
- for i in range(len(pa)):
- pa[i].append(x.get_url(**urlprms[i]))
- _, canon_peers, canon_esc_peers = pa
- # creating the namedict, a dict representing various ways of referring
- # to / repreenting peers to be fillable in config templates
- mods = (lambda x: x, lambda x: x[
- 0].upper() + x[1:], lambda x: 'e' + x[0].upper() + x[1:])
- if remote:
- rmap = {local: ('local', 'master'), remote: ('remote', 'slave')}
- else:
- rmap = {local: ('local', 'slave')}
- namedict = {}
- for i in range(len(rscs)):
- x = rscs[i]
- for name in rmap[x]:
- for j in range(3):
- namedict[mods[j](name)] = pa[j][i]
- namedict[name + 'vol'] = x.volume
- if name == 'remote':
- namedict['remotehost'] = x.remotehost
- if not 'config_file' in rconf:
- rconf['config_file'] = os.path.join(
- os.path.dirname(sys.argv[0]), "conf/gsyncd_template.conf")
-
- upgrade_config_file(rconf['config_file'])
- gcnf = GConffile(
- rconf['config_file'], canon_peers,
- defaults.__dict__, opts.__dict__, namedict)
-
- checkpoint_change = False
- if confdata:
- opt_ok = norm(confdata.opt) in tunables + [None]
- if confdata.op == 'check':
- if opt_ok:
- sys.exit(0)
- else:
- sys.exit(1)
- elif not opt_ok:
- raise GsyncdError("not a valid option: " + confdata.opt)
- if confdata.op == 'get':
- gcnf.get(confdata.opt)
- elif confdata.op == 'set':
- gcnf.set(confdata.opt, confdata.val, confdata.rx)
- elif confdata.op == 'del':
- gcnf.delete(confdata.opt, confdata.rx)
- # when modifying checkpoint, it's important to make a log
- # of that, so in that case we go on to set up logging even
- # if its just config invocation
- if confdata.opt == 'checkpoint' and confdata.op in ('set', 'del') and \
- not confdata.rx:
- checkpoint_change = True
- if not checkpoint_change:
- return
-
- gconf.__dict__.update(defaults.__dict__)
- gcnf.update_to(gconf.__dict__)
- gconf.__dict__.update(opts.__dict__)
- gconf.configinterface = gcnf
-
- delete = rconf.get('delete')
- if delete:
- logging.info('geo-replication delete')
- # Delete pid file, status file, socket file
- cleanup_paths = []
- if getattr(gconf, 'pid_file', None):
- cleanup_paths.append(gconf.pid_file)
-
- if getattr(gconf, 'state_file', None):
- cleanup_paths.append(gconf.state_file)
-
- if getattr(gconf, 'state_detail_file', None):
- cleanup_paths.append(gconf.state_detail_file)
-
- if getattr(gconf, 'state_socket_unencoded', None):
- cleanup_paths.append(gconf.state_socket_unencoded)
-
- cleanup_paths.append(rconf['config_file'][:-11] + "*")
-
- # Cleanup changelog working dirs
- if getattr(gconf, 'working_dir', None):
- try:
- shutil.rmtree(gconf.working_dir)
- except (IOError, OSError):
- if sys.exc_info()[1].errno == ENOENT:
- pass
- else:
- raise GsyncdError(
- 'Error while removing working dir: %s' %
- gconf.working_dir)
-
- for path in cleanup_paths:
- # To delete temp files
- for f in glob.glob(path + "*"):
- _unlink(f)
- return
-
- if restricted and gconf.allow_network:
- ssh_conn = os.getenv('SSH_CONNECTION')
- if not ssh_conn:
- # legacy env var
- ssh_conn = os.getenv('SSH_CLIENT')
- if ssh_conn:
- allowed_networks = [IPNetwork(a)
- for a in gconf.allow_network.split(',')]
- client_ip = IPAddress(ssh_conn.split()[0])
- allowed = False
- for nw in allowed_networks:
- if client_ip in nw:
- allowed = True
- break
- if not allowed:
- raise GsyncdError("client IP address is not allowed")
-
- ffd = rconf.get('feedback_fd')
- if ffd:
- fcntl.fcntl(ffd, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
-
- # normalize loglevel
- lvl0 = gconf.log_level
- if isinstance(lvl0, str):
- lvl1 = lvl0.upper()
- lvl2 = logging.getLevelName(lvl1)
- # I have _never_ _ever_ seen such an utterly braindead
- # error condition
- if lvl2 == "Level " + lvl1:
- raise GsyncdError('cannot recognize log level "%s"' % lvl0)
- gconf.log_level = lvl2
-
- if not privileged() and gconf.log_file_mbr:
- gconf.log_file = gconf.log_file_mbr
-
- if checkpoint_change:
- try:
- GLogger._gsyncd_loginit(log_file=gconf.log_file, label='conf')
- if confdata.op == 'set':
- logging.info('checkpoint %s set' % confdata.val)
- elif confdata.op == 'del':
- logging.info('checkpoint info was reset')
- except IOError:
- if sys.exc_info()[1].errno == ENOENT:
- # directory of log path is not present,
- # which happens if we get here from
- # a peer-multiplexed "config-set checkpoint"
- # (as that directory is created only on the
- # original node)
- pass
- else:
- raise
- return
-
- create = rconf.get('create')
- if create:
- if getattr(gconf, 'state_file', None):
- set_monitor_status(gconf.state_file, create)
- return
-
- go_daemon = rconf['go_daemon']
- be_monitor = rconf.get('monitor')
- be_agent = rconf.get('agent')
-
- rscs, local, remote = makersc(args)
-
- status_get = rconf.get('status_get')
- if status_get:
- for brick in gconf.path:
- brick_status = GeorepStatus(gconf.state_file, brick,
- getattr(gconf, "pid_file", None))
- checkpoint_time = int(getattr(gconf, "checkpoint", "0"))
- brick_status.print_status(checkpoint_time=checkpoint_time)
- return
-
- if not be_monitor and isinstance(remote, resource.SSH) and \
- go_daemon == 'should':
- go_daemon = 'postconn'
- log_file = None
- else:
- log_file = gconf.log_file
- if be_monitor:
- label = 'monitor'
- elif be_agent:
- label = 'agent'
- elif remote:
- # master
- label = gconf.local_path
- else:
- label = 'slave'
- startup(go_daemon=go_daemon, log_file=log_file, label=label)
- resource.Popen.init_errhandler()
-
- if be_agent:
- os.setsid()
- logging.debug('rpc_fd: %s' % repr(gconf.rpc_fd))
- return agent(Changelog(), gconf.rpc_fd)
-
- if be_monitor:
- return monitor(*rscs)
-
- logging.info("syncing: %s" % " -> ".join(r.url for r in rscs))
- if remote:
- go_daemon = remote.connect_remote(go_daemon=go_daemon)
- if go_daemon:
- startup(go_daemon=go_daemon, log_file=gconf.log_file)
- # complete remote connection in child
- remote.connect_remote(go_daemon='done')
- local.connect()
- if ffd:
- os.close(ffd)
- local.service_loop(*[r for r in [remote] if r])
-
-
if __name__ == "__main__":
main()
diff --git a/geo-replication/syncdaemon/gsyncdconfig.py b/geo-replication/syncdaemon/gsyncdconfig.py
new file mode 100644
index 00000000000..8848071997a
--- /dev/null
+++ b/geo-replication/syncdaemon/gsyncdconfig.py
@@ -0,0 +1,485 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+try:
+ from ConfigParser import RawConfigParser, NoSectionError
+except ImportError:
+ from configparser import RawConfigParser, NoSectionError
+import os
+import shutil
+from string import Template
+from datetime import datetime
+from threading import Lock
+
+
+# Global object which can be used in other modules
+# once load_config is called
+_gconf = {}
+
+
+class GconfNotConfigurable(Exception):
+ pass
+
+
+class GconfInvalidValue(Exception):
+ pass
+
+
+class Gconf(object):
+ def __init__(self, default_conf_file, custom_conf_file=None,
+ args={}, extra_tmpl_args={}, override_from_args=False):
+ self.lock = Lock()
+ self.default_conf_file = default_conf_file
+ self.custom_conf_file = custom_conf_file
+ self.tmp_conf_file = None
+ self.gconf = {}
+ self.gconfdata = {}
+ self.gconf_typecast = {}
+ self.template_conf = []
+ self.non_configurable_configs = []
+ self.prev_mtime = 0
+ if custom_conf_file is not None:
+ self.tmp_conf_file = custom_conf_file + ".tmp"
+
+ self.session_conf_items = []
+ self.args = args
+ self.extra_tmpl_args = extra_tmpl_args
+ self.override_from_args = override_from_args
+ # Store default values only if overwritten, Only for JSON/CLI output
+ self.default_values = {}
+ self._load()
+
+ def _tmpl_substitute(self):
+ tmpl_values = {}
+ for k, v in self.gconf.items():
+ tmpl_values[k.replace("-", "_")] = v
+
+ # override the config file values with the one user passed
+ for k, v in self.args.items():
+ # override the existing value only if set by user
+ if v is not None:
+ tmpl_values[k] = v
+
+ for k, v in self.extra_tmpl_args.items():
+ tmpl_values[k] = v
+
+ for k, v in self.gconf.items():
+ if k in self.template_conf and \
+ (isinstance(v, str) or isinstance(v, unicode)):
+ self.gconf[k] = Template(v).safe_substitute(tmpl_values)
+
+ def _do_typecast(self):
+ for k, v in self.gconf.items():
+ cast_func = globals().get(
+ "to_" + self.gconf_typecast.get(k, "string"), None)
+ if cast_func is not None:
+ self.gconf[k] = cast_func(v)
+ if self.default_values.get(k, None) is not None:
+ self.default_values[k] = cast_func(v)
+
+ def reset(self, name):
+ # If custom conf file is not set then it is only read only configs
+ if self.custom_conf_file is None:
+ raise GconfNotConfigurable()
+
+ # If a config can not be modified
+ if name != "all" and not self._is_configurable(name):
+ raise GconfNotConfigurable()
+
+ cnf = RawConfigParser()
+ with open(self.custom_conf_file) as f:
+ cnf.readfp(f)
+
+ # Nothing to Reset, Not configured
+ if name != "all":
+ if not cnf.has_option("vars", name):
+ return True
+
+ # Remove option from custom conf file
+ cnf.remove_option("vars", name)
+ else:
+ # Remove and add empty section, do not disturb if config file
+ # already has any other section
+ try:
+ cnf.remove_section("vars")
+ except NoSectionError:
+ pass
+
+ cnf.add_section("vars")
+
+ with open(self.tmp_conf_file, "w") as fw:
+ cnf.write(fw)
+
+ os.rename(self.tmp_conf_file, self.custom_conf_file)
+
+ self.reload()
+
+ return True
+
+ def set(self, name, value):
+ if self.custom_conf_file is None:
+ raise GconfNotConfigurable()
+
+ if not self._is_configurable(name):
+ raise GconfNotConfigurable()
+
+ if not self._is_valid_value(name, value):
+ raise GconfInvalidValue()
+
+ curr_val = self.gconf.get(name, None)
+ if curr_val == value:
+ return True
+
+ cnf = RawConfigParser()
+ with open(self.custom_conf_file) as f:
+ cnf.readfp(f)
+
+ if not cnf.has_section("vars"):
+ cnf.add_section("vars")
+
+ cnf.set("vars", name, value)
+ with open(self.tmp_conf_file, "w") as fw:
+ cnf.write(fw)
+
+ os.rename(self.tmp_conf_file, self.custom_conf_file)
+
+ self.reload()
+
+ return True
+
+ def check(self, name, value=None, with_conffile=True):
+ if with_conffile and self.custom_conf_file is None:
+ raise GconfNotConfigurable()
+
+ if not self._is_configurable(name):
+ raise GconfNotConfigurable()
+
+ if value is not None and not self._is_valid_value(name, value):
+ raise GconfInvalidValue()
+
+
+ def _load_with_lock(self):
+ with self.lock:
+ self._load()
+
+ def _load(self):
+ self.gconf = {}
+ self.template_conf = []
+ self.gconf_typecast = {}
+ self.non_configurable_configs = []
+ self.session_conf_items = []
+ self.default_values = {}
+
+ conf = RawConfigParser()
+ # Default Template config file
+ with open(self.default_conf_file) as f:
+ conf.readfp(f)
+
+ # Custom Config file
+ if self.custom_conf_file is not None:
+ with open(self.custom_conf_file) as f:
+ conf.readfp(f)
+
+ # Get version from default conf file
+ self.version = conf.get("__meta__", "version")
+
+ # Populate default values
+ for sect in conf.sections():
+ if sect in ["__meta__", "vars"]:
+ continue
+
+ # Collect list of available options with help details
+ self.gconfdata[sect] = {}
+ for k, v in conf.items(sect):
+ self.gconfdata[sect][k] = v.strip()
+
+ # Collect the Type cast information
+ if conf.has_option(sect, "type"):
+ self.gconf_typecast[sect] = conf.get(sect, "type")
+
+ # Prepare list of configurable conf
+ if conf.has_option(sect, "configurable"):
+ if conf.get(sect, "configurable").lower() == "false":
+ self.non_configurable_configs.append(sect)
+
+ # if it is a template conf value which needs to be substituted
+ if conf.has_option(sect, "template"):
+ if conf.get(sect, "template").lower().strip() == "true":
+ self.template_conf.append(sect)
+
+ # Set default values
+ if conf.has_option(sect, "value"):
+ self.gconf[sect] = conf.get(sect, "value").strip()
+
+ # Load the custom conf elements and overwrite
+ if conf.has_section("vars"):
+ for k, v in conf.items("vars"):
+ self.session_conf_items.append(k)
+ self.default_values[k] = self.gconf.get(k, "")
+ self.gconf[k] = v.strip()
+
+ # Overwrite the Slave configurations which are sent as
+ # arguments to gsyncd slave
+ if self.override_from_args:
+ for k, v in self.args.items():
+ k = k.replace("_", "-")
+ if k.startswith("slave-") and k in self.gconf:
+ self.gconf[k] = v
+
+ self._tmpl_substitute()
+ self._do_typecast()
+
+ def reload(self, with_lock=True):
+ if self._is_config_changed():
+ if with_lock:
+ self._load_with_lock()
+ else:
+ self._load()
+
+ def get(self, name, default_value=None, with_lock=True):
+ if with_lock:
+ with self.lock:
+ return self.gconf.get(name, default_value)
+ else:
+ return self.gconf.get(name, default_value)
+
+ def getall(self, show_defaults=False, show_non_configurable=False):
+ cnf = {}
+ if not show_defaults:
+ for k in self.session_conf_items:
+ if k not in self.non_configurable_configs:
+ dv = self.default_values.get(k, "")
+ cnf[k] = {
+ "value": self.get(k),
+ "default": dv,
+ "configurable": True,
+ "modified": False if dv == "" else True
+ }
+ return cnf
+
+ # Show all configs including defaults
+ for k, v in self.gconf.items():
+ configurable = False if k in self.non_configurable_configs \
+ else True
+ dv = self.default_values.get(k, "")
+ modified = False if dv == "" else True
+ if show_non_configurable:
+ cnf[k] = {
+ "value": v,
+ "default": dv,
+ "configurable": configurable,
+ "modified": modified
+ }
+ else:
+ if k not in self.non_configurable_configs:
+ cnf[k] = {
+ "value": v,
+ "default": dv,
+ "configurable": configurable,
+ "modified": modified
+ }
+
+ return cnf
+
+ def getr(self, name, default_value=None):
+ with self.lock:
+ self.reload(with_lock=False)
+ return self.get(name, default_value, with_lock=False)
+
+ def get_help(self, name=None):
+ pass
+
+ def _is_configurable(self, name):
+ item = self.gconfdata.get(name, None)
+ if item is None:
+ return False
+
+ return item.get("configurable", True)
+
+ def _is_valid_value(self, name, value):
+ item = self.gconfdata.get(name, None)
+ if item is None:
+ return False
+
+ # If validation func not defined
+ if item.get("validation", None) is None:
+ return True
+
+ # minmax validation
+ if item["validation"] == "minmax":
+ return validate_minmax(value, item["min"], item["max"])
+
+ if item["validation"] == "choice":
+ return validate_choice(value, item["allowed_values"])
+
+ if item["validation"] == "bool":
+ return validate_bool(value)
+
+ if item["validation"] == "execpath":
+ return validate_execpath(value)
+
+ if item["validation"] == "unixtime":
+ return validate_unixtime(value)
+
+ if item["validation"] == "int":
+ return validate_int(value)
+
+ return False
+
+ def _is_config_changed(self):
+ if self.custom_conf_file is not None and \
+ os.path.exists(self.custom_conf_file):
+ st = os.lstat(self.custom_conf_file)
+ if st.st_mtime > self.prev_mtime:
+ self.prev_mtime = st.st_mtime
+ return True
+
+ return False
+
+def is_config_file_old(config_file, mastervol, slavevol):
+ cnf = RawConfigParser()
+ cnf.read(config_file)
+ session_section = "peers %s %s" % (mastervol, slavevol)
+ try:
+ return dict(cnf.items(session_section))
+ except NoSectionError:
+ return None
+
+def config_upgrade(config_file, ret):
+ config_file_backup = os.path.join(os.path.dirname(config_file), "gsyncd.conf.bkp")
+
+ #copy old config file in a backup file
+ shutil.copyfile(config_file, config_file_backup)
+
+ #write a new config file
+ config = RawConfigParser()
+ config.add_section('vars')
+
+ for key, value in ret.items():
+ #handle option name changes
+ if key == "use_tarssh":
+ new_key = "sync-method"
+ if value == "true":
+ new_value = "tarssh"
+ else:
+ new_value = "rsync"
+ config.set('vars', new_key, new_value)
+ elif key == "timeout":
+ new_key = "slave-timeout"
+ config.set('vars', new_key, value)
+ #for changes like: ignore_deletes to ignore-deletes
+ else:
+ new_key = key.replace("_", "-")
+ config.set('vars', new_key, value)
+
+ with open(config_file, 'w') as configfile:
+ config.write(configfile)
+
+
+def validate_int(value):
+ try:
+ _ = int(value)
+ return True
+ except ValueError:
+ return False
+
+
+def validate_unixtime(value):
+ try:
+ y = datetime.fromtimestamp(int(value)).strftime("%Y")
+ if y == "1970":
+ return False
+
+ return True
+ except ValueError:
+ return False
+
+
+def validate_minmax(value, minval, maxval):
+ try:
+ value = int(value)
+ minval = int(minval)
+ maxval = int(maxval)
+ return value >= minval and value <= maxval
+ except ValueError:
+ return False
+
+
+def validate_choice(value, allowed_values):
+ allowed_values = allowed_values.split(",")
+ allowed_values = [v.strip() for v in allowed_values]
+
+ return value in allowed_values
+
+
+def validate_bool(value):
+ return value in ["true", "false"]
+
+
+def validate_execpath(value):
+ return os.path.isfile(value) and os.access(value, os.X_OK)
+
+
+def validate_filepath(value):
+ return os.path.isfile(value)
+
+
+def validate_path(value):
+ return os.path.exists(value)
+
+
+def to_int(value):
+ return int(value)
+
+
+def to_float(value):
+ return float(value)
+
+
+def to_bool(value):
+ if isinstance(value, bool):
+ return value
+ return True if value in ["true", "True"] else False
+
+
+def get(name, default_value=None):
+ return _gconf.get(name, default_value)
+
+
+def getall(show_defaults=False, show_non_configurable=False):
+ return _gconf.getall(show_defaults=show_defaults,
+ show_non_configurable=show_non_configurable)
+
+
+def getr(name, default_value=None):
+ return _gconf.getr(name, default_value)
+
+
+def load(default_conf, custom_conf=None, args={}, extra_tmpl_args={},
+ override_from_args=False):
+ global _gconf
+ _gconf = Gconf(default_conf, custom_conf, args, extra_tmpl_args,
+ override_from_args)
+
+
+def setconfig(name, value):
+ global _gconf
+ _gconf.set(name, value)
+
+
+def resetconfig(name):
+ global _gconf
+ _gconf.reset(name)
+
+
+def check(name, value=None, with_conffile=True):
+ global _gconf
+ _gconf.check(name, value=value, with_conffile=with_conffile)
diff --git a/geo-replication/syncdaemon/gsyncdstatus.py b/geo-replication/syncdaemon/gsyncdstatus.py
index 77f3f9e7569..1a655ff8887 100644
--- a/geo-replication/syncdaemon/gsyncdstatus.py
+++ b/geo-replication/syncdaemon/gsyncdstatus.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
#
# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
@@ -9,14 +9,22 @@
# cases as published by the Free Software Foundation.
#
+from __future__ import print_function
import fcntl
import os
import tempfile
-import urllib
+try:
+ import urllib.parse as urllib
+except ImportError:
+ import urllib
import json
import time
from datetime import datetime
-from errno import EACCES, EAGAIN
+from errno import EACCES, EAGAIN, ENOENT
+import logging
+
+from syncdutils import (EVENT_GEOREP_ACTIVE, EVENT_GEOREP_PASSIVE, gf_event,
+ EVENT_GEOREP_CHECKPOINT_COMPLETED, lf)
DEFAULT_STATUS = "N/A"
MONITOR_STATUS = ("Created", "Started", "Paused", "Stopped")
@@ -52,6 +60,7 @@ def get_default_values():
"slave_node": DEFAULT_STATUS,
"worker_status": DEFAULT_STATUS,
"last_synced": 0,
+ "last_synced_entry": 0,
"crawl_status": DEFAULT_STATUS,
"entry": 0,
"data": 0,
@@ -94,6 +103,7 @@ class LockedOpen(object):
return f
def __exit__(self, _exc_type, _exc_value, _traceback):
+ fcntl.flock(self.fileobj, fcntl.LOCK_UN)
self.fileobj.close()
@@ -114,7 +124,12 @@ def set_monitor_status(status_file, status):
class GeorepStatus(object):
- def __init__(self, monitor_status_file, brick, monitor_pid_file=None):
+ def __init__(self, monitor_status_file, master_node, brick, master_node_id,
+ master, slave, monitor_pid_file=None):
+ self.master = master
+ slv_data = slave.split("::")
+ self.slave_host = slv_data[0]
+ self.slave_volume = slv_data[1].split(":")[0] # Remove Slave UUID
self.work_dir = os.path.dirname(monitor_status_file)
self.monitor_status_file = monitor_status_file
self.filename = os.path.join(self.work_dir,
@@ -125,18 +140,35 @@ class GeorepStatus(object):
os.close(fd)
fd = os.open(self.monitor_status_file, os.O_CREAT | os.O_RDWR)
os.close(fd)
+ self.master_node = master_node
+ self.master_node_id = master_node_id
self.brick = brick
self.default_values = get_default_values()
self.monitor_pid_file = monitor_pid_file
+ def send_event(self, event_type, **kwargs):
+ gf_event(event_type,
+ master_volume=self.master,
+ master_node=self.master_node,
+ master_node_id=self.master_node_id,
+ slave_host=self.slave_host,
+ slave_volume=self.slave_volume,
+ brick_path=self.brick,
+ **kwargs)
+
def _update(self, mergerfunc):
+ data = self.default_values
with LockedOpen(self.filename, 'r+') as f:
try:
- data = json.load(f)
+ data.update(json.load(f))
except ValueError:
- data = self.default_values
+ pass
data = mergerfunc(data)
+ # If Data is not changed by merger func
+ if not data:
+ return False
+
with tempfile.NamedTemporaryFile(
'w',
dir=os.path.dirname(self.filename),
@@ -149,6 +181,7 @@ class GeorepStatus(object):
os.O_DIRECTORY)
os.fsync(dirfd)
os.close(dirfd)
+ return True
def reset_on_worker_start(self):
def merger(data):
@@ -163,10 +196,20 @@ class GeorepStatus(object):
def set_field(self, key, value):
def merger(data):
+ # Current data and prev data is same
+ if data[key] == value:
+ return {}
+
data[key] = value
return json.dumps(data)
- self._update(merger)
+ return self._update(merger)
+
+ def trigger_gf_event_checkpoint_completion(self, checkpoint_time,
+ checkpoint_completion_time):
+ self.send_event(EVENT_GEOREP_CHECKPOINT_COMPLETED,
+ checkpoint_time=checkpoint_time,
+ checkpoint_completion_time=checkpoint_completion_time)
def set_last_synced(self, value, checkpoint_time):
def merger(data):
@@ -184,18 +227,30 @@ class GeorepStatus(object):
# previously then update the checkpoint completed time
if checkpoint_time > 0 and checkpoint_time <= value[0]:
if data["checkpoint_completed"] == "No":
+ curr_time = int(time.time())
data["checkpoint_time"] = checkpoint_time
- data["checkpoint_completion_time"] = int(time.time())
+ data["checkpoint_completion_time"] = curr_time
data["checkpoint_completed"] = "Yes"
+ logging.info(lf("Checkpoint completed",
+ checkpoint_time=human_time_utc(
+ checkpoint_time),
+ completion_time=human_time_utc(curr_time)))
+ self.trigger_gf_event_checkpoint_completion(
+ checkpoint_time, curr_time)
+
return json.dumps(data)
self._update(merger)
def set_worker_status(self, status):
- self.set_field("worker_status", status)
+ if self.set_field("worker_status", status):
+ logging.info(lf("Worker Status Change",
+ status=status))
def set_worker_crawl_status(self, status):
- self.set_field("crawl_status", status)
+ if self.set_field("crawl_status", status):
+ logging.info(lf("Crawl Status Change",
+ status=status))
def set_slave_node(self, slave_node):
def merger(data):
@@ -221,10 +276,16 @@ class GeorepStatus(object):
self._update(merger)
def set_active(self):
- self.set_field("worker_status", "Active")
+ if self.set_field("worker_status", "Active"):
+ logging.info(lf("Worker Status Change",
+ status="Active"))
+ self.send_event(EVENT_GEOREP_ACTIVE)
def set_passive(self):
- self.set_field("worker_status", "Passive")
+ if self.set_field("worker_status", "Passive"):
+ logging.info(lf("Worker Status Change",
+ status="Passive"))
+ self.send_event(EVENT_GEOREP_PASSIVE)
def get_monitor_status(self):
data = ""
@@ -239,6 +300,7 @@ class GeorepStatus(object):
slave_node N/A VALUE VALUE N/A
status Created VALUE Paused Stopped
last_synced N/A VALUE VALUE VALUE
+ last_synced_entry N/A VALUE VALUE VALUE
crawl_status N/A VALUE N/A N/A
entry N/A VALUE N/A N/A
data N/A VALUE N/A N/A
@@ -263,7 +325,11 @@ class GeorepStatus(object):
fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
monitor_status = "Stopped"
except (IOError, OSError) as e:
- if e.errno in (EACCES, EAGAIN):
+ # If pid file not exists, either monitor died or Geo-rep
+ # not even started once
+ if e.errno == ENOENT:
+ monitor_status = "Stopped"
+ elif e.errno in (EACCES, EAGAIN):
# cannot grab. so, monitor process still running..move on
pass
else:
@@ -272,6 +338,9 @@ class GeorepStatus(object):
if monitor_status in ["Created", "Paused", "Stopped"]:
data["worker_status"] = monitor_status
+ if monitor_status == "":
+ data["worker_status"] = "Stopped"
+
# Checkpoint adjustments
if checkpoint_time == 0:
data["checkpoint_completed"] = DEFAULT_STATUS
@@ -336,6 +405,15 @@ class GeorepStatus(object):
return data
- def print_status(self, checkpoint_time=0):
- for key, value in self.get_status(checkpoint_time).items():
- print ("%s: %s" % (key, value))
+ def print_status(self, checkpoint_time=0, json_output=False):
+ status_out = self.get_status(checkpoint_time)
+ if json_output:
+ out = {}
+ # Convert all values as string
+ for k, v in status_out.items():
+ out[k] = str(v)
+ print(json.dumps(out))
+ return
+
+ for key, value in status_out.items():
+ print(("%s: %s" % (key, value)))
diff --git a/geo-replication/syncdaemon/libcxattr.py b/geo-replication/syncdaemon/libcxattr.py
index b69773df469..e6406c36bd7 100644
--- a/geo-replication/syncdaemon/libcxattr.py
+++ b/geo-replication/syncdaemon/libcxattr.py
@@ -9,13 +9,14 @@
#
import os
-from ctypes import CDLL, create_string_buffer, get_errno
-from ctypes.util import find_library
+from ctypes import CDLL, get_errno
+from py2py3 import (bytearray_to_str, gr_create_string_buffer,
+ gr_query_xattr, gr_lsetxattr, gr_lremovexattr)
class Xattr(object):
- """singleton that wraps the extended attribues system
+ """singleton that wraps the extended attributes system
interface for python using ctypes
Just implement it to the degree we need it, in particular
@@ -25,7 +26,7 @@ class Xattr(object):
sizes we expect
"""
- libc = CDLL(find_library("libc"), use_errno=True)
+ libc = CDLL("libc.so.6", use_errno=True)
@classmethod
def geterrno(cls):
@@ -39,20 +40,23 @@ class Xattr(object):
@classmethod
def _query_xattr(cls, path, siz, syscall, *a):
if siz:
- buf = create_string_buffer('\0' * siz)
+ buf = gr_create_string_buffer(siz)
else:
buf = None
ret = getattr(cls.libc, syscall)(*((path,) + a + (buf, siz)))
if ret == -1:
cls.raise_oserr()
if siz:
- return buf.raw[:ret]
+ # py2 and py3 compatibility. Convert bytes array
+ # to string
+ result = bytearray_to_str(buf.raw)
+ return result[:ret]
else:
return ret
@classmethod
def lgetxattr(cls, path, attr, siz=0):
- return cls._query_xattr(path, siz, 'lgetxattr', attr)
+ return gr_query_xattr(cls, path, siz, 'lgetxattr', attr)
@classmethod
def lgetxattr_buf(cls, path, attr):
@@ -66,29 +70,43 @@ class Xattr(object):
@classmethod
def llistxattr(cls, path, siz=0):
- ret = cls._query_xattr(path, siz, 'llistxattr')
+ ret = gr_query_xattr(cls, path, siz, 'llistxattr')
if isinstance(ret, str):
- ret = ret.split('\0')
+ ret = ret.strip('\0')
+ ret = ret.split('\0') if ret else []
return ret
@classmethod
def lsetxattr(cls, path, attr, val):
- ret = cls.libc.lsetxattr(path, attr, val, len(val), 0)
+ ret = gr_lsetxattr(cls, path, attr, val)
if ret == -1:
cls.raise_oserr()
@classmethod
def lremovexattr(cls, path, attr):
- ret = cls.libc.lremovexattr(path, attr)
+ ret = gr_lremovexattr(cls, path, attr)
if ret == -1:
cls.raise_oserr()
@classmethod
def llistxattr_buf(cls, path):
"""listxattr variant with size discovery"""
- size = cls.llistxattr(path)
- if size == -1:
- cls.raise_oserr()
- if size == 0:
- return []
- return cls.llistxattr(path, size)
+ try:
+ # Assuming no more than 100 xattrs in a file/directory and
+ # each xattr key length will be less than 256 bytes
+ # llistxattr will be called with bigger size so that
+ # listxattr will not fail with ERANGE. OSError will be
+ # raised if fails even with the large size specified.
+ size = 256 * 100
+ return cls.llistxattr(path, size)
+ except OSError:
+ # If fixed length failed for getting list of xattrs then
+ # use the llistxattr call to get the size and use that
+ # size to get the list of xattrs.
+ size = cls.llistxattr(path)
+ if size == -1:
+ cls.raise_oserr()
+ if size == 0:
+ return []
+
+ return cls.llistxattr(path, size)
diff --git a/geo-replication/syncdaemon/libgfchangelog.py b/geo-replication/syncdaemon/libgfchangelog.py
index 1d580caf6e8..a3bda7282c0 100644
--- a/geo-replication/syncdaemon/libgfchangelog.py
+++ b/geo-replication/syncdaemon/libgfchangelog.py
@@ -9,126 +9,135 @@
#
import os
-from ctypes import CDLL, RTLD_GLOBAL, create_string_buffer, get_errno, byref, c_ulong
+from ctypes import CDLL, RTLD_GLOBAL, get_errno, byref, c_ulong
from ctypes.util import find_library
-from syncdutils import ChangelogException
-
-
-class Changes(object):
- libgfc = CDLL(find_library("gfchangelog"), mode=RTLD_GLOBAL, use_errno=True)
-
- @classmethod
- def geterrno(cls):
- return get_errno()
-
- @classmethod
- def raise_changelog_err(cls):
- errn = cls.geterrno()
- raise ChangelogException(errn, os.strerror(errn))
-
- @classmethod
- def _get_api(cls, call):
- return getattr(cls.libgfc, call)
-
- @classmethod
- def cl_init(cls):
- ret = cls._get_api('gf_changelog_init')(None)
- if ret == -1:
- cls.raise_changelog_err()
-
- @classmethod
- def cl_register(cls, brick, path, log_file, log_level, retries=0):
- ret = cls._get_api('gf_changelog_register')(brick, path,
- log_file,
- log_level, retries)
- if ret == -1:
- cls.raise_changelog_err()
-
- @classmethod
- def cl_scan(cls):
- ret = cls._get_api('gf_changelog_scan')()
- if ret == -1:
- cls.raise_changelog_err()
-
- @classmethod
- def cl_startfresh(cls):
- ret = cls._get_api('gf_changelog_start_fresh')()
- if ret == -1:
- cls.raise_changelog_err()
-
- @classmethod
- def cl_getchanges(cls):
- """ remove hardcoding for path name length """
- def clsort(f):
- return f.split('.')[-1]
- changes = []
- buf = create_string_buffer('\0', 4096)
- call = cls._get_api('gf_changelog_next_change')
-
- while True:
- ret = call(buf, 4096)
- if ret in (0, -1):
- break
- changes.append(buf.raw[:ret - 1])
- if ret == -1:
- cls.raise_changelog_err()
- # cleanup tracker
- cls.cl_startfresh()
- return sorted(changes, key=clsort)
-
- @classmethod
- def cl_done(cls, clfile):
- ret = cls._get_api('gf_changelog_done')(clfile)
- if ret == -1:
- cls.raise_changelog_err()
-
- @classmethod
- def cl_history_scan(cls):
- ret = cls._get_api('gf_history_changelog_scan')()
- if ret == -1:
- cls.raise_changelog_err()
-
- return ret
-
- @classmethod
- def cl_history_changelog(cls, changelog_path, start, end, num_parallel):
- actual_end = c_ulong()
- ret = cls._get_api('gf_history_changelog')(changelog_path, start, end,
- num_parallel,
- byref(actual_end))
- if ret == -1:
- cls.raise_changelog_err()
-
- return (ret, actual_end.value)
-
- @classmethod
- def cl_history_startfresh(cls):
- ret = cls._get_api('gf_history_changelog_start_fresh')()
- if ret == -1:
- cls.raise_changelog_err()
-
- @classmethod
- def cl_history_getchanges(cls):
- """ remove hardcoding for path name length """
- def clsort(f):
- return f.split('.')[-1]
-
- changes = []
- buf = create_string_buffer('\0', 4096)
- call = cls._get_api('gf_history_changelog_next_change')
-
- while True:
- ret = call(buf, 4096)
- if ret in (0, -1):
- break
- changes.append(buf.raw[:ret - 1])
- if ret == -1:
- cls.raise_changelog_err()
-
- return sorted(changes, key=clsort)
-
- @classmethod
- def cl_history_done(cls, clfile):
- ret = cls._get_api('gf_history_changelog_done')(clfile)
- if ret == -1:
- cls.raise_changelog_err()
+from syncdutils import ChangelogException, ChangelogHistoryNotAvailable
+from py2py3 import (gr_cl_history_changelog, gr_cl_done,
+ gr_create_string_buffer, gr_cl_register,
+ gr_cl_history_done, bytearray_to_str)
+
+
+libgfc = CDLL(
+ find_library("gfchangelog"),
+ mode=RTLD_GLOBAL,
+ use_errno=True
+)
+
+
+def _raise_changelog_err():
+ errn = get_errno()
+ raise ChangelogException(errn, os.strerror(errn))
+
+
+def _init():
+ if libgfc.gf_changelog_init(None) == -1:
+ _raise_changelog_err()
+
+
+def register(brick, path, log_file, log_level, retries=0):
+ _init()
+
+ ret = gr_cl_register(libgfc, brick, path, log_file, log_level, retries)
+
+ if ret == -1:
+ _raise_changelog_err()
+
+
+def scan():
+ ret = libgfc.gf_changelog_scan()
+ if ret == -1:
+ _raise_changelog_err()
+
+
+def startfresh():
+ ret = libgfc.gf_changelog_start_fresh()
+ if ret == -1:
+ _raise_changelog_err()
+
+
+def getchanges():
+ def clsort(cfile):
+ return cfile.split('.')[-1]
+
+ changes = []
+ buf = gr_create_string_buffer(4096)
+ call = libgfc.gf_changelog_next_change
+
+ while True:
+ ret = call(buf, 4096)
+ if ret in (0, -1):
+ break
+
+ # py2 and py3 compatibility
+ result = bytearray_to_str(buf.raw[:ret - 1])
+ changes.append(result)
+
+ if ret == -1:
+ _raise_changelog_err()
+
+ # cleanup tracker
+ startfresh()
+
+ return sorted(changes, key=clsort)
+
+
+def done(clfile):
+ ret = gr_cl_done(libgfc, clfile)
+ if ret == -1:
+ _raise_changelog_err()
+
+
+def history_scan():
+ ret = libgfc.gf_history_changelog_scan()
+ if ret == -1:
+ _raise_changelog_err()
+
+ return ret
+
+
+def history_changelog(changelog_path, start, end, num_parallel):
+ actual_end = c_ulong()
+ ret = gr_cl_history_changelog(libgfc, changelog_path, start, end,
+ num_parallel, byref(actual_end))
+ if ret == -1:
+ _raise_changelog_err()
+
+ if ret == -2:
+ raise ChangelogHistoryNotAvailable()
+
+ return (ret, actual_end.value)
+
+
+def history_startfresh():
+ ret = libgfc.gf_history_changelog_start_fresh()
+ if ret == -1:
+ _raise_changelog_err()
+
+
+def history_getchanges():
+ def clsort(cfile):
+ return cfile.split('.')[-1]
+
+ changes = []
+ buf = gr_create_string_buffer(4096)
+ call = libgfc.gf_history_changelog_next_change
+
+ while True:
+ ret = call(buf, 4096)
+ if ret in (0, -1):
+ break
+
+ # py2 and py3 compatibility
+ result = bytearray_to_str(buf.raw[:ret - 1])
+ changes.append(result)
+
+ if ret == -1:
+ _raise_changelog_err()
+
+ return sorted(changes, key=clsort)
+
+
+def history_done(clfile):
+ ret = gr_cl_history_done(libgfc, clfile)
+ if ret == -1:
+ _raise_changelog_err()
diff --git a/geo-replication/syncdaemon/logutils.py b/geo-replication/syncdaemon/logutils.py
new file mode 100644
index 00000000000..01ae7852f23
--- /dev/null
+++ b/geo-replication/syncdaemon/logutils.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+import logging
+from logging import Logger, handlers
+import sys
+import time
+
+
+class GLogger(Logger):
+
+ """Logger customizations for gsyncd.
+
+ It implements a log format similar to that of glusterfs.
+ """
+
+ def makeRecord(self, name, level, *a):
+ rv = Logger.makeRecord(self, name, level, *a)
+ rv.nsecs = (rv.created - int(rv.created)) * 1000000
+ fr = sys._getframe(4)
+ callee = fr.f_locals.get('self')
+ if callee:
+ ctx = str(type(callee)).split("'")[1].split('.')[-1]
+ else:
+ ctx = '<top>'
+ if not hasattr(rv, 'funcName'):
+ rv.funcName = fr.f_code.co_name
+ rv.lvlnam = logging.getLevelName(level)[0]
+ rv.ctx = ctx
+ return rv
+
+
+LOGFMT = ("[%(asctime)s.%(nsecs)d] %(lvlnam)s [%(module)s{0}"
+ ":%(lineno)s:%(funcName)s] %(ctx)s: %(message)s")
+
+
+def setup_logging(level="INFO", label="", log_file=""):
+ if label:
+ label = "(" + label + ")"
+
+ filename = None
+ stream = None
+ if log_file:
+ if log_file in ('-', '/dev/stderr'):
+ stream = sys.stderr
+ elif log_file == '/dev/stdout':
+ stream = sys.stdout
+ else:
+ filename = log_file
+
+ datefmt = "%Y-%m-%d %H:%M:%S"
+ fmt = LOGFMT.format(label)
+ logging.root = GLogger("root", level)
+ logging.setLoggerClass(GLogger)
+ logging.Formatter.converter = time.gmtime # Log in GMT/UTC time
+ logging.getLogger().handlers = []
+ logging.getLogger().setLevel(level)
+
+ if filename is not None:
+ logging_handler = handlers.WatchedFileHandler(filename)
+ formatter = logging.Formatter(fmt=fmt,
+ datefmt=datefmt)
+ logging_handler.setFormatter(formatter)
+ logging.getLogger().addHandler(logging_handler)
+ else:
+ logging.basicConfig(stream=stream,
+ format=fmt,
+ datefmt=datefmt,
+ level=level)
diff --git a/geo-replication/syncdaemon/master.py b/geo-replication/syncdaemon/master.py
index 1bc2450c101..9501aeae6b5 100644
--- a/geo-replication/syncdaemon/master.py
+++ b/geo-replication/syncdaemon/master.py
@@ -12,20 +12,23 @@ import os
import sys
import time
import stat
-import json
import logging
import fcntl
import string
import errno
import tarfile
-from errno import ENOENT, ENODATA, EEXIST, EACCES, EAGAIN, ESTALE
+from errno import ENOENT, ENODATA, EEXIST, EACCES, EAGAIN, ESTALE, EINTR
from threading import Condition, Lock
from datetime import datetime
-from gconf import gconf
-from syncdutils import Thread, GsyncdError, boolify, escape
-from syncdutils import unescape, gauxpfx, md5hex, selfkill
-from syncdutils import lstat, errno_wrap
-from syncdutils import NoPurgeTimeAvailable, PartialHistoryAvailable
+
+import gsyncdconfig as gconf
+import libgfchangelog
+from rconf import rconf
+from syncdutils import (Thread, GsyncdError, escape_space_newline,
+ unescape_space_newline, gauxpfx, escape,
+ lstat, errno_wrap, FreeObject, lf, matching_disk_gfid,
+ NoStimeAvailable, PartialHistoryAvailable,
+ host_brick_split)
URXTIME = (-1, 0)
@@ -37,14 +40,6 @@ URXTIME = (-1, 0)
# crawl before starting live changelog crawl.
CHANGELOG_ROLLOVER_TIME = 15
-# Max size of Changelogs to process per batch, Changelogs Processing is
-# not limited by the number of changelogs but instead based on
-# size of the changelog file, One sample changelog file size was 145408
-# with ~1000 CREATE and ~1000 DATA. 5 such files in one batch is 727040
-# If geo-rep worker crashes while processing a batch, it has to retry only
-# that batch since stime will get updated after each batch.
-MAX_CHANGELOG_BATCH_SIZE = 727040
-
# Utility functions to help us to get to closer proximity
# of the DRY principle (no, don't look for elevated or
# perspectivistic things here)
@@ -62,36 +57,75 @@ def _volinfo_hook_relax_foreign(self):
fgn_vi = volinfo_sys[self.KFGN]
if fgn_vi:
expiry = fgn_vi['timeout'] - int(time.time()) + 1
- logging.info('foreign volume info found, waiting %d sec for expiry' %
- expiry)
+ logging.info(lf('foreign volume info found, waiting for expiry',
+ expiry=expiry))
time.sleep(expiry)
volinfo_sys = self.get_sys_volinfo()
return volinfo_sys
+def edct(op, **ed):
+ dct = {}
+ dct['op'] = op
+ # This is used in automatic gfid conflict resolution.
+ # When marked True, it's skipped during re-processing.
+ dct['skip_entry'] = False
+ for k in ed:
+ if k == 'stat':
+ st = ed[k]
+ dst = dct['stat'] = {}
+ if st:
+ dst['uid'] = st.st_uid
+ dst['gid'] = st.st_gid
+ dst['mode'] = st.st_mode
+ dst['atime'] = st.st_atime
+ dst['mtime'] = st.st_mtime
+ else:
+ dct[k] = ed[k]
+ return dct
+
+
# The API!
def gmaster_builder(excrawl=None):
"""produce the GMaster class variant corresponding
to sync mode"""
this = sys.modules[__name__]
- modemixin = gconf.special_sync_mode
+ modemixin = gconf.get("special-sync-mode")
if not modemixin:
modemixin = 'normal'
- changemixin = 'xsync' if gconf.change_detector == 'xsync' \
- else excrawl or gconf.change_detector
- logging.info('setting up %s change detection mode' % changemixin)
+
+ if gconf.get("change-detector") == 'xsync':
+ changemixin = 'xsync'
+ elif excrawl:
+ changemixin = excrawl
+ else:
+ changemixin = gconf.get("change-detector")
+
+ logging.debug(lf('setting up change detection mode',
+ mode=changemixin))
modemixin = getattr(this, modemixin.capitalize() + 'Mixin')
crawlmixin = getattr(this, 'GMaster' + changemixin.capitalize() + 'Mixin')
- sendmarkmixin = boolify(
- gconf.use_rsync_xattrs) and SendmarkRsyncMixin or SendmarkNormalMixin
- purgemixin = boolify(
- gconf.ignore_deletes) and PurgeNoopMixin or PurgeNormalMixin
- syncengine = boolify(gconf.use_tarssh) and TarSSHEngine or RsyncEngine
+
+ if gconf.get("use-rsync-xattrs"):
+ sendmarkmixin = SendmarkRsyncMixin
+ else:
+ sendmarkmixin = SendmarkNormalMixin
+
+ if gconf.get("ignore-deletes"):
+ purgemixin = PurgeNoopMixin
+ else:
+ purgemixin = PurgeNormalMixin
+
+ if gconf.get("sync-method") == "tarssh":
+ syncengine = TarSSHEngine
+ else:
+ syncengine = RsyncEngine
class _GMaster(crawlmixin, modemixin, sendmarkmixin,
purgemixin, syncengine):
pass
+
return _GMaster
@@ -128,9 +162,9 @@ class NormalMixin(object):
return xt0 >= xt1
def make_xtime_opts(self, is_master, opts):
- if not 'create' in opts:
+ if 'create' not in opts:
opts['create'] = is_master
- if not 'default_xtime' in opts:
+ if 'default_xtime' not in opts:
opts['default_xtime'] = URXTIME
def xtime_low(self, rsc, path, **opts):
@@ -149,7 +183,9 @@ class NormalMixin(object):
xt = _xtime_now()
rsc.server.aggregated.set_xtime(path, self.uuid, xt)
else:
- xt = opts['default_xtime']
+ zero_zero = (0, 0)
+ if xt != zero_zero:
+ xt = opts['default_xtime']
return xt
def keepalive_payload_hook(self, timo, gap):
@@ -161,7 +197,7 @@ class NormalMixin(object):
vi = vi.copy()
vi['timeout'] = int(time.time()) + timo
else:
- # send keep-alives more frequently to
+ # send keep-alive more frequently to
# avoid a delay in announcing our volume info
# to slave if it becomes established in the
# meantime
@@ -199,9 +235,9 @@ class RecoverMixin(NormalMixin):
@staticmethod
def make_xtime_opts(is_master, opts):
- if not 'create' in opts:
+ if 'create' not in opts:
opts['create'] = False
- if not 'default_xtime' in opts:
+ if 'default_xtime' not in opts:
opts['default_xtime'] = URXTIME
def keepalive_payload_hook(self, timo, gap):
@@ -244,28 +280,24 @@ class TarSSHEngine(object):
"""
def a_syncdata(self, files):
- logging.debug('files: %s' % (files))
- self.current_files_skipped_count = 0
- del self.skipped_gfid_list[:]
+ logging.debug(lf("Files", files=files))
+
for f in files:
pb = self.syncer.add(f)
def regjob(se, xte, pb):
rv = pb.wait()
if rv[0]:
- logging.debug('synced ' + se)
+ logging.debug(lf('synced', file=se))
return True
else:
# stat check for file presence
st = lstat(se)
if isinstance(st, int):
# file got unlinked in the interim
- self.unlinked_gfids.append(se)
+ self.unlinked_gfids.add(se)
return True
- se_list = se.split('/')
- self.current_files_skipped_count += 1
- self.skipped_gfid_list.append(se_list[1])
self.add_job(self.FLAT_DIR_HIERARCHY, 'reg', regjob, f, None, pb)
def syncdata_wait(self):
@@ -282,29 +314,25 @@ class RsyncEngine(object):
"""Sync engine that uses rsync(1) for data transfers"""
def a_syncdata(self, files):
- logging.debug('files: %s' % (files))
- self.current_files_skipped_count = 0
- del self.skipped_gfid_list[:]
+ logging.debug(lf("files", files=files))
+
for f in files:
- logging.debug('candidate for syncing %s' % f)
+ logging.debug(lf('candidate for syncing', file=f))
pb = self.syncer.add(f)
def regjob(se, xte, pb):
rv = pb.wait()
if rv[0]:
- logging.debug('synced ' + se)
+ logging.debug(lf('synced', file=se))
return True
else:
# stat to check if the file exist
st = lstat(se)
if isinstance(st, int):
# file got unlinked in the interim
- self.unlinked_gfids.append(se)
+ self.unlinked_gfids.add(se)
return True
- se_list = se.split('/')
- self.current_files_skipped_count += 1
- self.skipped_gfid_list.append(se_list[1])
self.add_job(self.FLAT_DIR_HIERARCHY, 'reg', regjob, f, None, pb)
def syncdata_wait(self):
@@ -348,6 +376,18 @@ class GMasterCommon(object):
if self.volinfo:
return self.volinfo['volume_mark']
+ def get_entry_stime(self):
+ data = self.slave.server.entry_stime(".", self.uuid)
+ if isinstance(data, int):
+ data = None
+ return data
+
+ def get_data_stime(self):
+ data = self.slave.server.stime(".", self.uuid)
+ if isinstance(data, int):
+ data = None
+ return data
+
def xtime(self, path, *a, **opts):
"""get amended xtime
@@ -364,44 +404,13 @@ class GMasterCommon(object):
self.make_xtime_opts(rsc == self.master, opts)
return self.xtime_low(rsc, path, **opts)
- def get_initial_crawl_data(self):
- # while persisting only 'files_syncd' is non-zero, rest of
- # the stats are nulls. lets keep it that way in case they
- # are needed to be used some day...
- default_data = {'files_syncd': 0,
- 'files_remaining': 0,
- 'bytes_remaining': 0,
- 'purges_remaining': 0,
- 'total_files_skipped': 0}
- if getattr(gconf, 'state_detail_file', None):
- try:
- with open(gconf.state_detail_file, 'r+') as f:
- loaded_data = json.load(f)
- diff_data = set(default_data) - set(loaded_data)
- if len(diff_data):
- for i in diff_data:
- loaded_data[i] = default_data[i]
- return loaded_data
- except IOError:
- logging.warn('Creating new gconf.state_detail_file.')
- # Create file with initial data
- try:
- with open(gconf.state_detail_file, 'wb') as f:
- json.dump(default_data, f)
- return default_data
- except:
- raise
- return default_data
-
def __init__(self, master, slave):
self.master = master
self.slave = slave
self.jobtab = {}
- if boolify(gconf.use_tarssh):
- logging.info("using 'tar over ssh' as the sync engine")
+ if gconf.get("sync-method") == "tarssh":
self.syncer = Syncer(slave, self.slave.tarssh, [2])
else:
- logging.info("using 'rsync' as the sync engine")
# partial transfer (cf. rsync(1)), that's normal
self.syncer = Syncer(slave, self.slave.rsync, [23, 24])
# crawls vs. turns:
@@ -415,7 +424,7 @@ class GMasterCommon(object):
# 0.
self.crawls = 0
self.turns = 0
- self.total_turns = int(gconf.turns)
+ self.total_turns = rconf.turns
self.crawl_start = datetime.now()
self.lastreport = {'crawls': 0, 'turns': 0, 'time': 0}
self.start = None
@@ -424,13 +433,11 @@ class GMasterCommon(object):
self.volinfo = None
self.terminate = False
self.sleep_interval = 1
- self.current_files_skipped_count = 0
- self.skipped_gfid_list = []
- self.unlinked_gfids = []
+ self.unlinked_gfids = set()
def init_keep_alive(cls):
"""start the keep-alive thread """
- timo = int(gconf.timeout or 0)
+ timo = gconf.get("slave-timeout", 0)
if timo > 0:
def keep_alive():
while True:
@@ -443,12 +450,22 @@ class GMasterCommon(object):
def mgmt_lock(self):
"""Take management volume lock """
+ if rconf.mgmt_lock_fd:
+ try:
+ fcntl.lockf(rconf.mgmt_lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ return True
+ except:
+ ex = sys.exc_info()[1]
+ if isinstance(ex, IOError) and ex.errno in (EACCES, EAGAIN):
+ return False
+ raise
+
fd = None
- bname = str(self.uuid) + "_" + str(gconf.slave_id) + "_subvol_" \
- + str(gconf.subvol_num) + ".lock"
- mgmt_lock_dir = os.path.join(gconf.meta_volume_mnt, "geo-rep")
+ bname = str(self.uuid) + "_" + rconf.args.slave_id + "_subvol_" \
+ + str(rconf.args.subvol_num) + ".lock"
+ mgmt_lock_dir = os.path.join(gconf.get("meta-volume-mnt"), "geo-rep")
path = os.path.join(mgmt_lock_dir, bname)
- logging.debug("lock_file_path: %s" % path)
+ logging.debug(lf("lock file path", path=path))
try:
fd = os.open(path, os.O_CREAT | os.O_RDWR)
except OSError:
@@ -468,29 +485,23 @@ class GMasterCommon(object):
raise
try:
fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ # Save latest FD for future use
+ rconf.mgmt_lock_fd = fd
except:
ex = sys.exc_info()[1]
- if fd:
- os.close(fd)
if isinstance(ex, IOError) and ex.errno in (EACCES, EAGAIN):
# cannot grab, it's taken
- if not gconf.passive_earlier:
- gconf.passive_earlier = True
- logging.info("Didn't get lock : %s : Becoming PASSIVE"
- % gconf.local_path)
+ rconf.mgmt_lock_fd = fd
return False
raise
- if not gconf.active_earlier:
- gconf.active_earlier = True
- logging.info("Got lock : %s : Becoming ACTIVE" % gconf.local_path)
return True
def should_crawl(self):
- if not boolify(gconf.use_meta_volume):
- return gconf.glusterd_uuid in self.master.server.node_uuid()
+ if not gconf.get("use-meta-volume"):
+ return rconf.args.local_node_id in self.master.server.node_uuid()
- if not os.path.ismount(gconf.meta_volume_mnt):
+ if not os.path.ismount(gconf.get("meta-volume-mnt")):
logging.error("Meta-volume is not mounted. Worker Exiting...")
sys.exit(1)
return self.mgmt_lock()
@@ -507,8 +518,8 @@ class GMasterCommon(object):
# If crawlwrap is called when partial history available,
# then it sets register_time which is the time when geo-rep
- # worker registerd to changelog consumption. Since nsec is
- # not considered in register time, their are chances of skipping
+ # worker registered to changelog consumption. Since nsec is
+ # not considered in register time, there are chances of skipping
# changes detection in xsync crawl. This limit will be reset when
# crawlwrap is called again.
self.live_changelog_start_time = None
@@ -518,25 +529,24 @@ class GMasterCommon(object):
# no need to maintain volinfo state machine.
# in a cascading setup, each geo-replication session is
# independent (ie. 'volume-mark' and 'xtime' are not
- # propogated). This is because the slave's xtime is now
+ # propagated). This is because the slave's xtime is now
# stored on the master itself. 'volume-mark' just identifies
# that we are in a cascading setup and need to enable
# 'geo-replication.ignore-pid-check' option.
volinfo_sys = self.volinfo_hook()
self.volinfo = volinfo_sys[self.KNAT]
inter_master = volinfo_sys[self.KFGN]
- logging.info("%s master with volume id %s ..." %
- (inter_master and "intermediate" or "primary",
- self.uuid))
- gconf.configinterface.set('volume_id', self.uuid)
+ logging.debug("%s master with volume id %s ..." %
+ (inter_master and "intermediate" or "primary",
+ self.uuid))
+ rconf.volume_id = self.uuid
if self.volinfo:
if self.volinfo['retval']:
- logging.warn("master cluster's info may not be valid %d" %
- self.volinfo['retval'])
+ logging.warn(lf("master cluster's info may not be valid",
+ error=self.volinfo['retval']))
else:
raise GsyncdError("master volinfo unavailable")
self.lastreport['time'] = time.time()
- logging.info('crawl interval: %d seconds' % self.sleep_interval)
t0 = time.time()
crawl = self.should_crawl()
@@ -547,14 +557,14 @@ class GMasterCommon(object):
self.start = time.time()
should_display_info = self.start - self.lastreport['time'] >= 60
if should_display_info:
- logging.info("%d crawls, %d turns",
- self.crawls - self.lastreport['crawls'],
- self.turns - self.lastreport['turns'])
+ logging.debug("%d crawls, %d turns",
+ self.crawls - self.lastreport['crawls'],
+ self.turns - self.lastreport['turns'])
self.lastreport.update(crawls=self.crawls,
turns=self.turns,
time=self.start)
t1 = time.time()
- if int(t1 - t0) >= int(gconf.replica_failover_interval):
+ if int(t1 - t0) >= gconf.get("replica-failover-interval"):
crawl = self.should_crawl()
t0 = t1
self.update_worker_remote_node()
@@ -564,16 +574,19 @@ class GMasterCommon(object):
# which is min of cluster (but max of the replicas)
brick_stime = self.xtime('.', self.slave)
cluster_stime = self.master.server.aggregated.stime_mnt(
- '.', '.'.join([str(self.uuid), str(gconf.slave_id)]))
- logging.debug("Cluster stime: %s | Brick stime: %s" %
- (repr(cluster_stime), repr(brick_stime)))
+ '.', '.'.join([str(self.uuid), rconf.args.slave_id]))
+ logging.debug(lf("Crawl info",
+ cluster_stime=cluster_stime,
+ brick_stime=brick_stime))
+
if not isinstance(cluster_stime, int):
if brick_stime < cluster_stime:
self.slave.server.set_stime(
self.FLAT_DIR_HIERARCHY, self.uuid, cluster_stime)
+ self.upd_stime(cluster_stime)
# Purge all changelogs available in processing dir
# less than cluster_stime
- proc_dir = os.path.join(self.setup_working_dir(),
+ proc_dir = os.path.join(self.tempdir,
".processing")
if os.path.exists(proc_dir):
@@ -687,21 +700,44 @@ class GMasterChangelogMixin(GMasterCommon):
TYPE_GFID = "D "
TYPE_ENTRY = "E "
+ MAX_EF_RETRIES = 10
+ MAX_OE_RETRIES = 10
+
# flat directory hierarchy for gfid based access
FLAT_DIR_HIERARCHY = '.'
- # maximum retries per changelog before giving up
- MAX_RETRIES = 10
-
- CHANGELOG_LOG_LEVEL = 9
CHANGELOG_CONN_RETRIES = 5
+ def init_fop_batch_stats(self):
+ self.batch_stats = {
+ "CREATE": 0,
+ "MKNOD": 0,
+ "UNLINK": 0,
+ "MKDIR": 0,
+ "RMDIR": 0,
+ "LINK": 0,
+ "SYMLINK": 0,
+ "RENAME": 0,
+ "SETATTR": 0,
+ "SETXATTR": 0,
+ "XATTROP": 0,
+ "DATA": 0,
+ "ENTRY_SYNC_TIME": 0,
+ "META_SYNC_TIME": 0,
+ "DATA_START_TIME": 0
+ }
+
+ def update_fop_batch_stats(self, ty):
+ if ty in ['FSETXATTR']:
+ ty = 'SETXATTR'
+ self.batch_stats[ty] = self.batch_stats.get(ty, 0) + 1
+
def archive_and_purge_changelogs(self, changelogs):
# Creates tar file instead of tar.gz, since changelogs will
# be appended to existing tar. archive name is
# archive_<YEAR><MONTH>.tar
archive_name = "archive_%s.tar" % datetime.today().strftime(
- gconf.changelog_archive_format)
+ gconf.get("changelog-archive-format"))
try:
tar = tarfile.open(os.path.join(self.processed_changelogs_dir,
@@ -737,21 +773,218 @@ class GMasterChangelogMixin(GMasterCommon):
else:
raise
- def fallback_xsync(self):
- logging.info('falling back to xsync mode')
- gconf.configinterface.set('change-detector', 'xsync')
- selfkill()
-
def setup_working_dir(self):
- workdir = os.path.join(gconf.working_dir, md5hex(gconf.local_path))
+ workdir = os.path.join(gconf.get("working-dir"),
+ escape(rconf.args.local_path))
logging.debug('changelog working dir %s' % workdir)
return workdir
- def get_purge_time(self):
- purge_time = self.xtime('.', self.slave)
- if isinstance(purge_time, int):
- purge_time = None
- return purge_time
+ def log_failures(self, failures, entry_key, gfid_prefix, log_prefix):
+ num_failures = 0
+ for failure in failures:
+ st = lstat(os.path.join(gfid_prefix, failure[0][entry_key]))
+ if not isinstance(st, int):
+ num_failures += 1
+ logging.error(lf('%s FAILED' % log_prefix,
+ data=failure))
+ if failure[0]['op'] == 'MKDIR':
+ raise GsyncdError("The above directory failed to sync."
+ " Please fix it to proceed further.")
+
+ self.status.inc_value("failures", num_failures)
+
+ def fix_possible_entry_failures(self, failures, retry_count, entries):
+ pfx = gauxpfx()
+ fix_entry_ops = []
+ failures1 = []
+ remove_gfids = set()
+ for failure in failures:
+ if failure[2]['name_mismatch']:
+ pbname = failure[2]['slave_entry']
+ elif failure[2]['dst']:
+ pbname = failure[0]['entry1']
+ else:
+ pbname = failure[0]['entry']
+
+ op = failure[0]['op']
+ # name exists but gfid is different
+ if failure[2]['gfid_mismatch'] or failure[2]['name_mismatch']:
+ slave_gfid = failure[2]['slave_gfid']
+ st = lstat(os.path.join(pfx, slave_gfid))
+ # Takes care of scenarios with no hardlinks
+ if isinstance(st, int) and st == ENOENT:
+ logging.debug(lf('Entry not present on master. Fixing gfid '
+ 'mismatch in slave. Deleting the entry',
+ retry_count=retry_count,
+ entry=repr(failure)))
+ # Add deletion to fix_entry_ops list
+ if failure[2]['slave_isdir']:
+ fix_entry_ops.append(
+ edct('RMDIR',
+ gfid=failure[2]['slave_gfid'],
+ entry=pbname))
+ else:
+ fix_entry_ops.append(
+ edct('UNLINK',
+ gfid=failure[2]['slave_gfid'],
+ entry=pbname))
+ remove_gfids.add(slave_gfid)
+ if op in ['RENAME']:
+ # If renamed gfid doesn't exists on master, remove
+ # rename entry and unlink src on slave
+ st = lstat(os.path.join(pfx, failure[0]['gfid']))
+ if isinstance(st, int) and st == ENOENT:
+ logging.debug("Unlink source %s" % repr(failure))
+ remove_gfids.add(failure[0]['gfid'])
+ fix_entry_ops.append(
+ edct('UNLINK',
+ gfid=failure[0]['gfid'],
+ entry=failure[0]['entry']))
+ # Takes care of scenarios of hardlinks/renames on master
+ elif not isinstance(st, int):
+ if matching_disk_gfid(slave_gfid, pbname):
+ # Safe to ignore the failure as master contains same
+ # file with same gfid. Remove entry from entries list
+ logging.debug(lf('Fixing gfid mismatch in slave. '
+ ' Safe to ignore, take out entry',
+ retry_count=retry_count,
+ entry=repr(failure)))
+ remove_gfids.add(failure[0]['gfid'])
+ if op == 'RENAME':
+ fix_entry_ops.append(
+ edct('UNLINK',
+ gfid=failure[0]['gfid'],
+ entry=failure[0]['entry']))
+ # The file exists on master but with different name.
+ # Probably renamed and got missed during xsync crawl.
+ elif failure[2]['slave_isdir']:
+ realpath = os.readlink(os.path.join(
+ rconf.args.local_path,
+ ".glusterfs",
+ slave_gfid[0:2],
+ slave_gfid[2:4],
+ slave_gfid))
+ dst_entry = os.path.join(pfx, realpath.split('/')[-2],
+ realpath.split('/')[-1])
+ src_entry = pbname
+ logging.debug(lf('Fixing dir name/gfid mismatch in '
+ 'slave', retry_count=retry_count,
+ entry=repr(failure)))
+ if src_entry == dst_entry:
+ # Safe to ignore the failure as master contains
+ # same directory as in slave with same gfid.
+ # Remove the failure entry from entries list
+ logging.debug(lf('Fixing dir name/gfid mismatch'
+ ' in slave. Safe to ignore, '
+ 'take out entry',
+ retry_count=retry_count,
+ entry=repr(failure)))
+ try:
+ entries.remove(failure[0])
+ except ValueError:
+ pass
+ else:
+ rename_dict = edct('RENAME', gfid=slave_gfid,
+ entry=src_entry,
+ entry1=dst_entry, stat=st,
+ link=None)
+ logging.debug(lf('Fixing dir name/gfid mismatch'
+ ' in slave. Renaming',
+ retry_count=retry_count,
+ entry=repr(rename_dict)))
+ fix_entry_ops.append(rename_dict)
+ else:
+ # A hardlink file exists with different name or
+ # renamed file exists and we are sure from
+ # matching_disk_gfid check that the entry doesn't
+ # exist with same gfid so we can safely delete on slave
+ logging.debug(lf('Fixing file gfid mismatch in slave. '
+ 'Hardlink/Rename Case. Deleting entry',
+ retry_count=retry_count,
+ entry=repr(failure)))
+ fix_entry_ops.append(
+ edct('UNLINK',
+ gfid=failure[2]['slave_gfid'],
+ entry=pbname))
+ elif failure[1] == ENOENT:
+ if op in ['RENAME']:
+ pbname = failure[0]['entry1']
+ else:
+ pbname = failure[0]['entry']
+
+ pargfid = pbname.split('/')[1]
+ st = lstat(os.path.join(pfx, pargfid))
+ # Safe to ignore the failure as master doesn't contain
+ # parent directory.
+ if isinstance(st, int):
+ logging.debug(lf('Fixing ENOENT error in slave. Parent '
+ 'does not exist on master. Safe to '
+ 'ignore, take out entry',
+ retry_count=retry_count,
+ entry=repr(failure)))
+ try:
+ entries.remove(failure[0])
+ except ValueError:
+ pass
+ else:
+ logging.debug(lf('Fixing ENOENT error in slave. Create '
+ 'parent directory on slave.',
+ retry_count=retry_count,
+ entry=repr(failure)))
+ realpath = os.readlink(os.path.join(rconf.args.local_path,
+ ".glusterfs",
+ pargfid[0:2],
+ pargfid[2:4],
+ pargfid))
+ dir_entry = os.path.join(pfx, realpath.split('/')[-2],
+ realpath.split('/')[-1])
+ fix_entry_ops.append(
+ edct('MKDIR', gfid=pargfid, entry=dir_entry,
+ mode=st.st_mode, uid=st.st_uid, gid=st.st_gid))
+
+ logging.debug("remove_gfids: %s" % repr(remove_gfids))
+ if remove_gfids:
+ for e in entries:
+ if e['op'] in ['MKDIR', 'MKNOD', 'CREATE', 'RENAME'] \
+ and e['gfid'] in remove_gfids:
+ logging.debug("Removed entry op from retrial list: entry: %s" % repr(e))
+ e['skip_entry'] = True
+
+ if fix_entry_ops:
+ # Process deletions of entries whose gfids are mismatched
+ failures1 = self.slave.server.entry_ops(fix_entry_ops)
+
+ return (failures1, fix_entry_ops)
+
+ def handle_entry_failures(self, failures, entries):
+ retries = 0
+ pending_failures = False
+ failures1 = []
+ failures2 = []
+ entry_ops1 = []
+ entry_ops2 = []
+
+ if failures:
+ pending_failures = True
+ failures1 = failures
+ entry_ops1 = entries
+
+ while pending_failures and retries < self.MAX_EF_RETRIES:
+ retries += 1
+ (failures2, entry_ops2) = self.fix_possible_entry_failures(
+ failures1, retries, entry_ops1)
+ if not failures2:
+ pending_failures = False
+ logging.info(lf('Successfully fixed entry ops with gfid '
+ 'mismatch', retry_count=retries))
+ else:
+ pending_failures = True
+ failures1 = failures2
+ entry_ops1 = entry_ops2
+
+ if pending_failures:
+ for failure in failures1:
+ logging.error("Failed to fix entry ops %s", repr(failure))
def process_change(self, change, done, retry):
pfx = gauxpfx()
@@ -760,8 +993,28 @@ class GMasterChangelogMixin(GMasterCommon):
meta_gfid = set()
datas = set()
- # basic crawl stats: files and bytes
- files_pending = {'count': 0, 'purge': 0, 'bytes': 0, 'files': []}
+ change_ts = change.split(".")[-1]
+
+ # Ignore entry ops which are already processed in Changelog modes
+ ignore_entry_ops = False
+ entry_stime = None
+ data_stime = None
+ if self.name in ["live_changelog", "history_changelog"]:
+ entry_stime = self.get_entry_stime()
+ data_stime = self.get_data_stime()
+
+ if entry_stime is not None and data_stime is not None:
+ # if entry_stime is not None but data_stime > entry_stime
+ # This situation is caused by the stime update of Passive worker
+ # Consider data_stime in this case.
+ if data_stime[0] > entry_stime[0]:
+ entry_stime = data_stime
+
+ # Compare the entry_stime with changelog file suffix
+ # if changelog time is less than entry_stime then ignore
+ if int(change_ts) <= entry_stime[0]:
+ ignore_entry_ops = True
+
try:
f = open(change, "r")
clist = f.readlines()
@@ -769,46 +1022,27 @@ class GMasterChangelogMixin(GMasterCommon):
except IOError:
raise
- def edct(op, **ed):
- dct = {}
- dct['op'] = op
- for k in ed:
- if k == 'stat':
- st = ed[k]
- dst = dct['stat'] = {}
- if st:
- dst['uid'] = st.st_uid
- dst['gid'] = st.st_gid
- dst['mode'] = st.st_mode
- dst['atime'] = st.st_atime
- dst['mtime'] = st.st_mtime
- else:
- dct[k] = ed[k]
- return dct
-
- # entry counts (not purges)
- def entry_update():
- files_pending['count'] += 1
-
- # purge count
- def purge_update():
- files_pending['purge'] += 1
-
- def log_failures(failures, entry_key, gfid_prefix, log_prefix):
- num_failures = 0
- for failure in failures:
- st = lstat(os.path.join(gfid_prefix, failure[0][entry_key]))
- if not isinstance(st, int):
- num_failures += 1
- logging.warn('%s FAILED: %s' % (log_prefix, repr(failure)))
-
- self.status.inc_value("failures", num_failures)
-
for e in clist:
e = e.strip()
et = e[self.IDX_START:self.IDX_END] # entry type
ec = e[self.IDX_END:].split(' ') # rest of the bits
+ # skip ENTRY operation if hot tier brick
+ if self.name == 'live_changelog' or \
+ self.name == 'history_changelog':
+ if rconf.args.is_hottier and et == self.TYPE_ENTRY:
+ logging.debug(lf('skip ENTRY op if hot tier brick',
+ op=ec[self.POS_TYPE]))
+ continue
+
+ # Data and Meta operations are decided while parsing
+ # UNLINK/RMDIR/MKNOD except that case ignore all the other
+ # entry ops if ignore_entry_ops is True.
+ # UNLINK/RMDIR/MKNOD entry_ops are ignored in the end
+ if ignore_entry_ops and et == self.TYPE_ENTRY and \
+ ec[self.POS_TYPE] not in ["UNLINK", "RMDIR", "MKNOD"]:
+ continue
+
if et == self.TYPE_ENTRY:
# extract information according to the type of
# the entry operation. create(), mkdir() and mknod()
@@ -816,8 +1050,11 @@ class GMasterChangelogMixin(GMasterCommon):
# itself, so no need to stat()...
ty = ec[self.POS_TYPE]
+ self.update_fop_batch_stats(ec[self.POS_TYPE])
+
# PARGFID/BNAME
- en = unescape(os.path.join(pfx, ec[self.POS_ENTRY1]))
+ en = unescape_space_newline(
+ os.path.join(pfx, ec[self.POS_ENTRY1]))
# GFID of the entry
gfid = ec[self.POS_GFID]
@@ -825,53 +1062,116 @@ class GMasterChangelogMixin(GMasterCommon):
# The index of PARGFID/BNAME for UNLINK, RMDIR
# is no more the last index. It varies based on
# changelog.capture-del-path is enabled or not.
- en = unescape(os.path.join(pfx, ec[self.UNLINK_ENTRY]))
+ en = unescape_space_newline(
+ os.path.join(pfx, ec[self.UNLINK_ENTRY]))
# Remove from DATA list, so that rsync will
# not fail
pt = os.path.join(pfx, ec[0])
- if pt in datas:
+ st = lstat(pt)
+ if pt in datas and isinstance(st, int):
+ # file got unlinked, May be historical Changelog
datas.remove(pt)
- if not boolify(gconf.ignore_deletes):
- purge_update()
- entries.append(edct(ty, gfid=gfid, entry=en))
+ if ty in ['RMDIR'] and not isinstance(st, int):
+ logging.info(lf('Ignoring rmdir. Directory present in '
+ 'master', gfid=gfid, pgfid_bname=en))
+ continue
+
+ if not gconf.get("ignore-deletes"):
+ if not ignore_entry_ops:
+ entries.append(edct(ty, gfid=gfid, entry=en))
elif ty in ['CREATE', 'MKDIR', 'MKNOD']:
- entry_update()
- # stat information present in the changelog itself
+ # Special case: record mknod as link
+ if ty in ['MKNOD']:
+ mode = int(ec[2])
+ if mode & 0o1000:
+ # Avoid stat'ing the file as it
+ # may be deleted in the interim
+ st = FreeObject(st_mode=int(ec[2]),
+ st_uid=int(ec[3]),
+ st_gid=int(ec[4]),
+ st_atime=0,
+ st_mtime=0)
+
+ # So, it may be deleted, but still we are
+ # append LINK? Because, the file will be
+ # CREATED if source not exists.
+ entries.append(edct('LINK', stat=st, entry=en,
+ gfid=gfid))
+
+ # Here, we have the assumption that only
+ # tier-gfid.linkto causes this mknod. Add data
+ datas.add(os.path.join(pfx, ec[0]))
+ continue
+
+ # stat info. present in the changelog itself
entries.append(edct(ty, gfid=gfid, entry=en,
- mode=int(ec[2]),
- uid=int(ec[3]), gid=int(ec[4])))
+ mode=int(ec[2]),
+ uid=int(ec[3]), gid=int(ec[4])))
elif ty == "RENAME":
go = os.path.join(pfx, gfid)
st = lstat(go)
if isinstance(st, int):
st = {}
- entry_update()
- e1 = unescape(os.path.join(pfx, ec[self.POS_ENTRY1 - 1]))
+ rl = None
+ if st and stat.S_ISLNK(st.st_mode):
+ rl = errno_wrap(os.readlink, [en], [ENOENT],
+ [ESTALE, EINTR])
+ if isinstance(rl, int):
+ rl = None
+
+ e1 = unescape_space_newline(
+ os.path.join(pfx, ec[self.POS_ENTRY1 - 1]))
entries.append(edct(ty, gfid=gfid, entry=e1, entry1=en,
- stat=st))
+ stat=st, link=rl))
+ # If src doesn't exist while doing rename, destination
+ # is created. If data is not followed by rename, this
+ # remains zero byte file on slave. Hence add data entry
+ # for renames
+ datas.add(os.path.join(pfx, gfid))
else:
# stat() to get mode and other information
+ if not matching_disk_gfid(gfid, en):
+ logging.debug(lf('Ignoring entry, purged in the '
+ 'interim', file=en, gfid=gfid))
+ continue
+
go = os.path.join(pfx, gfid)
st = lstat(go)
if isinstance(st, int):
- logging.debug('file %s got purged in the interim' % go)
+ logging.debug(lf('Ignoring entry, purged in the '
+ 'interim', file=en, gfid=gfid))
continue
if ty == 'LINK':
- entry_update()
- entries.append(edct(ty, stat=st, entry=en, gfid=gfid))
+ rl = None
+ if st and stat.S_ISLNK(st.st_mode):
+ rl = errno_wrap(os.readlink, [en], [ENOENT],
+ [ESTALE, EINTR])
+ if isinstance(rl, int):
+ rl = None
+ entries.append(edct(ty, stat=st, entry=en, gfid=gfid,
+ link=rl))
+ # If src doesn't exist while doing link, destination
+ # is created based on file type. If data is not
+ # followed by link, this remains zero byte file on
+ # slave. Hence add data entry for links
+ if rl is None:
+ datas.add(os.path.join(pfx, gfid))
elif ty == 'SYMLINK':
- rl = errno_wrap(os.readlink, [en], [ENOENT], [ESTALE])
+ rl = errno_wrap(os.readlink, [en], [ENOENT],
+ [ESTALE, EINTR])
if isinstance(rl, int):
continue
- entry_update()
+
entries.append(
edct(ty, stat=st, entry=en, gfid=gfid, link=rl))
else:
- logging.warn('ignoring %s [op %s]' % (gfid, ty))
+ logging.warn(lf('ignoring op',
+ gfid=gfid,
+ type=ty))
elif et == self.TYPE_GFID:
# If self.unlinked_gfids is available, then that means it is
# retrying the changelog second time. Do not add the GFID's
@@ -882,6 +1182,7 @@ class GMasterChangelogMixin(GMasterCommon):
else:
datas.add(os.path.join(pfx, ec[0]))
elif et == self.TYPE_META:
+ self.update_fop_batch_stats(ec[self.POS_TYPE])
if ec[1] == 'SETATTR': # only setattr's for now...
if len(ec) == 5:
# In xsync crawl, we already have stat data
@@ -894,27 +1195,69 @@ class GMasterChangelogMixin(GMasterCommon):
st_mtime=ec[6])))
else:
meta_gfid.add((os.path.join(pfx, ec[0]), ))
- elif ec[1] == 'SETXATTR':
+ elif ec[1] in ['SETXATTR', 'XATTROP', 'FXATTROP']:
# To sync xattr/acls use rsync/tar, --xattrs and --acls
# switch to rsync and tar
- if not boolify(gconf.use_tarssh) and \
- (boolify(gconf.sync_xattrs) or boolify(gconf.sync_acls)):
+ if not gconf.get("sync-method") == "tarssh" and \
+ (gconf.get("sync-xattrs") or gconf.get("sync-acls")):
datas.add(os.path.join(pfx, ec[0]))
else:
- logging.warn('got invalid changelog type: %s' % (et))
+ logging.warn(lf('got invalid fop type',
+ type=et))
logging.debug('entries: %s' % repr(entries))
# Increment counters for Status
- self.status.inc_value("entry", len(entries))
self.files_in_batch += len(datas)
self.status.inc_value("data", len(datas))
+ self.batch_stats["DATA"] += self.files_in_batch - \
+ self.batch_stats["SETXATTR"] - \
+ self.batch_stats["XATTROP"]
+
+ entry_start_time = time.time()
# sync namespace
- if entries:
+ if entries and not ignore_entry_ops:
+ # Increment counters for Status
+ self.status.inc_value("entry", len(entries))
+
failures = self.slave.server.entry_ops(entries)
- log_failures(failures, 'gfid', gauxpfx(), 'ENTRY')
+
+ if gconf.get("gfid-conflict-resolution"):
+ count = 0
+ if failures:
+ logging.info(lf('Entry ops failed with gfid mismatch',
+ count=len(failures)))
+ while failures and count < self.MAX_OE_RETRIES:
+ count += 1
+ self.handle_entry_failures(failures, entries)
+ logging.info(lf('Retry original entries', count=count))
+ failures = self.slave.server.entry_ops(entries)
+ if not failures:
+ logging.info("Successfully fixed all entry ops with "
+ "gfid mismatch")
+ break
+
+ self.log_failures(failures, 'gfid', gauxpfx(), 'ENTRY')
self.status.dec_value("entry", len(entries))
+ # Update Entry stime in Brick Root only in case of Changelog mode
+ if self.name in ["live_changelog", "history_changelog"]:
+ entry_stime_to_update = (int(change_ts) - 1, 0)
+ self.upd_entry_stime(entry_stime_to_update)
+ self.status.set_field("last_synced_entry",
+ entry_stime_to_update[0])
+
+ self.batch_stats["ENTRY_SYNC_TIME"] += time.time() - entry_start_time
+
+ if ignore_entry_ops:
+ # Book keeping, to show in logs the range of Changelogs skipped
+ self.num_skipped_entry_changelogs += 1
+ if self.skipped_entry_changelogs_first is None:
+ self.skipped_entry_changelogs_first = change_ts
+
+ self.skipped_entry_changelogs_last = change_ts
+
+ meta_start_time = time.time()
# sync metadata
if meta_gfid:
meta_entries = []
@@ -924,29 +1267,41 @@ class GMasterChangelogMixin(GMasterCommon):
else:
st = lstat(go[0])
if isinstance(st, int):
- logging.debug('file %s got purged in the interim' % go[0])
+ logging.debug(lf('file got purged in the interim',
+ file=go[0]))
continue
meta_entries.append(edct('META', go=go[0], stat=st))
if meta_entries:
- self.status.inc_value("meta", len(entries))
+ self.status.inc_value("meta", len(meta_entries))
failures = self.slave.server.meta_ops(meta_entries)
- log_failures(failures, 'go', '', 'META')
- self.status.dec_value("meta", len(entries))
+ self.log_failures(failures, 'go', '', 'META')
+ self.status.dec_value("meta", len(meta_entries))
+
+ self.batch_stats["META_SYNC_TIME"] += time.time() - meta_start_time
+
+ if self.batch_stats["DATA_START_TIME"] == 0:
+ self.batch_stats["DATA_START_TIME"] = time.time()
# sync data
if datas:
self.a_syncdata(datas)
+ self.datas_in_batch.update(datas)
def process(self, changes, done=1):
tries = 0
retry = False
- self.unlinked_gfids = []
+ self.unlinked_gfids = set()
self.files_in_batch = 0
+ self.datas_in_batch = set()
+ # Error log disabled till the last round
+ self.syncer.disable_errorlog()
+ self.skipped_entry_changelogs_first = None
+ self.skipped_entry_changelogs_last = None
+ self.num_skipped_entry_changelogs = 0
+ self.batch_start_time = time.time()
+ self.init_fop_batch_stats()
while True:
- self.skipped_gfid_list = []
- self.current_files_skipped_count = 0
-
# first, fire all changelog transfers in parallel. entry and
# metadata are performed synchronously, therefore in serial.
# However at the end of each changelog, data is synchronized
@@ -954,12 +1309,27 @@ class GMasterChangelogMixin(GMasterCommon):
# entries/metadata of that changelog but happens in parallel
# with data of other changelogs.
- for change in changes:
- logging.debug('processing change %s' % change)
- self.process_change(change, done, retry)
- if not retry:
- # number of changelogs processed in the batch
- self.turns += 1
+ if retry:
+ if tries == (gconf.get("max-rsync-retries") - 1):
+ # Enable Error logging if it is last retry
+ self.syncer.enable_errorlog()
+
+ # Remove Unlinked GFIDs from Queue
+ for unlinked_gfid in self.unlinked_gfids:
+ if unlinked_gfid in self.datas_in_batch:
+ self.datas_in_batch.remove(unlinked_gfid)
+
+ # Retry only Sync. Do not retry entry ops
+ if self.datas_in_batch:
+ self.a_syncdata(self.datas_in_batch)
+ else:
+ for change in changes:
+ logging.debug(lf('processing change',
+ changelog=change))
+ self.process_change(change, done, retry)
+ if not retry:
+ # number of changelogs processed in the batch
+ self.turns += 1
# Now we wait for all the data transfers fired off in the above
# step to complete. Note that this is not ideal either. Ideally
@@ -982,52 +1352,36 @@ class GMasterChangelogMixin(GMasterCommon):
# @change is the last changelog (therefore max time for this batch)
if self.syncdata_wait():
- self.unlinked_gfids = []
+ self.unlinked_gfids = set()
if done:
xtl = (int(change.split('.')[-1]) - 1, 0)
self.upd_stime(xtl)
- chkpt_time = gconf.configinterface.get_realtime(
- "checkpoint")
- checkpoint_time = 0
- if chkpt_time is not None:
- checkpoint_time = int(chkpt_time)
-
- self.status.set_last_synced(xtl, checkpoint_time)
- map(self.changelog_done_func, changes)
+ list(map(self.changelog_done_func, changes))
self.archive_and_purge_changelogs(changes)
# Reset Data counter after sync
self.status.dec_value("data", self.files_in_batch)
self.files_in_batch = 0
+ self.datas_in_batch = set()
break
# We do not know which changelog transfer failed, retry everything.
retry = True
tries += 1
- if tries == self.MAX_RETRIES:
- logging.warn('changelogs %s could not be processed - '
- 'moving on...' %
- ' '.join(map(os.path.basename, changes)))
- self.status.inc_value("failures",
- self.current_files_skipped_count)
- logging.warn('SKIPPED GFID = %s' %
- ','.join(self.skipped_gfid_list))
+ if tries == gconf.get("max-rsync-retries"):
+ logging.error(lf('changelogs could not be processed '
+ 'completely - moving on...',
+ files=list(map(os.path.basename, changes))))
# Reset data counter on failure
self.status.dec_value("data", self.files_in_batch)
self.files_in_batch = 0
+ self.datas_in_batch = set()
if done:
xtl = (int(change.split('.')[-1]) - 1, 0)
self.upd_stime(xtl)
- chkpt_time = gconf.configinterface.get_realtime(
- "checkpoint")
- checkpoint_time = 0
- if chkpt_time is not None:
- checkpoint_time = int(chkpt_time)
-
- self.status.set_last_synced(xtl, checkpoint_time)
- map(self.changelog_done_func, changes)
+ list(map(self.changelog_done_func, changes))
self.archive_and_purge_changelogs(changes)
break
# it's either entry_ops() or Rsync that failed to do it's
@@ -1037,25 +1391,83 @@ class GMasterChangelogMixin(GMasterCommon):
# entry_ops() that failed... so we retry the _whole_ changelog
# again.
# TODO: remove entry retries when it's gets fixed.
- logging.warn('incomplete sync, retrying changelogs: %s' %
- ' '.join(map(os.path.basename, changes)))
+ logging.warn(lf('incomplete sync, retrying changelogs',
+ files=list(map(os.path.basename, changes))))
# Reset the Data counter before Retry
self.status.dec_value("data", self.files_in_batch)
self.files_in_batch = 0
+ self.init_fop_batch_stats()
time.sleep(0.5)
+ # Log the Skipped Entry ops range if any
+ if self.skipped_entry_changelogs_first is not None and \
+ self.skipped_entry_changelogs_last is not None:
+ logging.info(lf("Skipping already processed entry ops",
+ from_changelog=self.skipped_entry_changelogs_first,
+ to_changelog=self.skipped_entry_changelogs_last,
+ num_changelogs=self.num_skipped_entry_changelogs))
+
+ # Log Current batch details
+ if changes:
+ logging.info(
+ lf("Entry Time Taken",
+ UNL=self.batch_stats["UNLINK"],
+ RMD=self.batch_stats["RMDIR"],
+ CRE=self.batch_stats["CREATE"],
+ MKN=self.batch_stats["MKNOD"],
+ MKD=self.batch_stats["MKDIR"],
+ REN=self.batch_stats["RENAME"],
+ LIN=self.batch_stats["LINK"],
+ SYM=self.batch_stats["SYMLINK"],
+ duration="%.4f" % self.batch_stats["ENTRY_SYNC_TIME"]))
+
+ logging.info(
+ lf("Data/Metadata Time Taken",
+ SETA=self.batch_stats["SETATTR"],
+ meta_duration="%.4f" % self.batch_stats["META_SYNC_TIME"],
+ SETX=self.batch_stats["SETXATTR"],
+ XATT=self.batch_stats["XATTROP"],
+ DATA=self.batch_stats["DATA"],
+ data_duration="%.4f" % (
+ time.time() - self.batch_stats["DATA_START_TIME"])))
+
+ logging.info(
+ lf("Batch Completed",
+ mode=self.name,
+ duration="%.4f" % (time.time() - self.batch_start_time),
+ changelog_start=changes[0].split(".")[-1],
+ changelog_end=changes[-1].split(".")[-1],
+ num_changelogs=len(changes),
+ stime=self.get_data_stime(),
+ entry_stime=self.get_entry_stime()))
+
+ def upd_entry_stime(self, stime):
+ self.slave.server.set_entry_stime(self.FLAT_DIR_HIERARCHY,
+ self.uuid,
+ stime)
+
def upd_stime(self, stime, path=None):
if not path:
path = self.FLAT_DIR_HIERARCHY
if not stime == URXTIME:
self.sendmark(path, stime)
+ # Update last_synced_time in status file based on stime
+ # only update stime if stime xattr set to Brick root
+ if path == self.FLAT_DIR_HIERARCHY:
+ chkpt_time = gconf.getr("checkpoint")
+ checkpoint_time = 0
+ if chkpt_time is not None:
+ checkpoint_time = int(chkpt_time)
+
+ self.status.set_last_synced(stime, checkpoint_time)
+
def update_worker_remote_node(self):
- node = sys.argv[-1]
+ node = rconf.args.resource_remote
node_data = node.split("@")
node = node_data[-1]
- remote_node_ip = node.split(":")[0]
+ remote_node_ip, _ = host_brick_split(node)
self.status.set_slave_node(remote_node_ip)
def changelogs_batch_process(self, changes):
@@ -1063,7 +1475,7 @@ class GMasterChangelogMixin(GMasterCommon):
current_size = 0
for c in changes:
si = os.lstat(c).st_size
- if (si + current_size) > MAX_CHANGELOG_BATCH_SIZE:
+ if (si + current_size) > gconf.get("changelog-batch-size"):
# Create new batch if single Changelog file greater than
# Max Size! or current batch size exceeds Max size
changelogs_batches.append([c])
@@ -1077,7 +1489,8 @@ class GMasterChangelogMixin(GMasterCommon):
changelogs_batches[-1].append(c)
for batch in changelogs_batches:
- logging.debug('processing changes %s' % repr(batch))
+ logging.debug(lf('processing changes',
+ batch=batch))
self.process(batch)
def crawl(self):
@@ -1085,69 +1498,80 @@ class GMasterChangelogMixin(GMasterCommon):
changes = []
# get stime (from the brick) and purge changelogs
# that are _historical_ to that time.
- purge_time = self.get_purge_time()
+ data_stime = self.get_data_stime()
- self.changelog_agent.scan()
+ libgfchangelog.scan()
self.crawls += 1
- changes = self.changelog_agent.getchanges()
+ changes = libgfchangelog.getchanges()
if changes:
- if purge_time:
- logging.info("slave's time: %s" % repr(purge_time))
+ if data_stime:
+ logging.info(lf("slave's time",
+ stime=data_stime))
processed = [x for x in changes
- if int(x.split('.')[-1]) < purge_time[0]]
+ if int(x.split('.')[-1]) < data_stime[0]]
for pr in processed:
- logging.info(
- 'skipping already processed change: %s...' %
- os.path.basename(pr))
+ logging.debug(
+ lf('skipping already processed change',
+ changelog=os.path.basename(pr)))
self.changelog_done_func(pr)
changes.remove(pr)
self.archive_and_purge_changelogs(processed)
self.changelogs_batch_process(changes)
- def register(self, register_time, changelog_agent, status):
- self.changelog_agent = changelog_agent
- self.sleep_interval = int(gconf.change_interval)
- self.changelog_done_func = self.changelog_agent.done
- self.processed_changelogs_dir = os.path.join(self.setup_working_dir(),
+ def register(self, register_time, status):
+ self.sleep_interval = gconf.get("change-interval")
+ self.changelog_done_func = libgfchangelog.done
+ self.tempdir = self.setup_working_dir()
+ self.processed_changelogs_dir = os.path.join(self.tempdir,
".processed")
+ self.name = "live_changelog"
self.status = status
class GMasterChangeloghistoryMixin(GMasterChangelogMixin):
- def register(self, register_time, changelog_agent, status):
- self.changelog_agent = changelog_agent
+ def register(self, register_time, status):
self.changelog_register_time = register_time
self.history_crawl_start_time = register_time
- self.changelog_done_func = self.changelog_agent.history_done
+ self.changelog_done_func = libgfchangelog.history_done
self.history_turns = 0
- self.processed_changelogs_dir = os.path.join(self.setup_working_dir(),
+ self.tempdir = self.setup_working_dir()
+ self.processed_changelogs_dir = os.path.join(self.tempdir,
".history/.processed")
+ self.name = "history_changelog"
self.status = status
def crawl(self):
self.history_turns += 1
self.status.set_worker_crawl_status("History Crawl")
- purge_time = self.get_purge_time()
+ data_stime = self.get_data_stime()
end_time = int(time.time())
- logging.info('starting history crawl... turns: %s, stime: %s, etime: %s'
- % (self.history_turns, repr(purge_time), repr(end_time)))
- if not purge_time or purge_time == URXTIME:
- logging.info("stime not available, abandoning history crawl")
- raise NoPurgeTimeAvailable()
+ #as start of historical crawl marks Geo-rep worker restart
+ if gconf.get("ignore-deletes"):
+ logging.info(lf('ignore-deletes config option is set',
+ stime=data_stime))
+
+ logging.info(lf('starting history crawl',
+ turns=self.history_turns,
+ stime=data_stime,
+ etime=end_time,
+ entry_stime=self.get_entry_stime()))
+
+ if not data_stime or data_stime == URXTIME:
+ raise NoStimeAvailable()
# Changelogs backend path is hardcoded as
# <BRICK_PATH>/.glusterfs/changelogs, if user configured to different
# location then consuming history will not work(Known issue as of now)
- changelog_path = os.path.join(gconf.local_path,
+ changelog_path = os.path.join(rconf.args.local_path,
".glusterfs/changelogs")
- ret, actual_end = self.changelog_agent.history(
+ ret, actual_end = libgfchangelog.history_changelog(
changelog_path,
- purge_time[0],
+ data_stime[0],
end_time,
- int(gconf.sync_jobs))
+ gconf.get("sync-jobs"))
# scan followed by getchanges till scan returns zero.
# history_scan() is blocking call, till it gets the number
@@ -1155,18 +1579,19 @@ class GMasterChangeloghistoryMixin(GMasterChangelogMixin):
# to be processed. returns positive value as number of changelogs
# to be processed, which will be fetched using
# history_getchanges()
- while self.changelog_agent.history_scan() > 0:
+ while libgfchangelog.history_scan() > 0:
self.crawls += 1
- changes = self.changelog_agent.history_getchanges()
+ changes = libgfchangelog.history_getchanges()
if changes:
- if purge_time:
- logging.info("slave's time: %s" % repr(purge_time))
+ if data_stime:
+ logging.info(lf("slave's time",
+ stime=data_stime))
processed = [x for x in changes
- if int(x.split('.')[-1]) < purge_time[0]]
+ if int(x.split('.')[-1]) < data_stime[0]]
for pr in processed:
- logging.info('skipping already processed change: '
- '%s...' % os.path.basename(pr))
+ logging.debug(lf('skipping already processed change',
+ changelog=os.path.basename(pr)))
self.changelog_done_func(pr)
changes.remove(pr)
@@ -1174,8 +1599,10 @@ class GMasterChangeloghistoryMixin(GMasterChangelogMixin):
history_turn_time = int(time.time()) - self.history_crawl_start_time
- logging.info('finished history crawl syncing, endtime: %s, stime: %s'
- % (actual_end, repr(self.get_purge_time())))
+ logging.info(lf('finished history crawl',
+ endtime=actual_end,
+ stime=self.get_data_stime(),
+ entry_stime=self.get_entry_stime()))
# If TS returned from history_changelog is < register_time
# then FS crawl may be required, since history is only available
@@ -1189,7 +1616,7 @@ class GMasterChangeloghistoryMixin(GMasterChangelogMixin):
self.history_crawl_start_time = int(time.time())
self.crawl()
else:
- # This exeption will be catched in resource.py and
+ # This exception will be caught in resource.py and
# fallback to xsync for the small gap.
raise PartialHistoryAvailable(str(actual_end))
@@ -1208,16 +1635,18 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
XSYNC_MAX_ENTRIES = 1 << 13
- def register(self, register_time=None, changelog_agent=None, status=None):
+ def register(self, register_time=None, status=None):
self.status = status
self.counter = 0
self.comlist = []
self.stimes = []
self.sleep_interval = 60
self.tempdir = self.setup_working_dir()
+ logging.info(lf('Working dir',
+ path=self.tempdir))
self.tempdir = os.path.join(self.tempdir, 'xsync')
self.processed_changelogs_dir = self.tempdir
- logging.info('xsync temp directory: %s' % self.tempdir)
+ self.name = "xsync"
try:
os.makedirs(self.tempdir)
except OSError:
@@ -1226,6 +1655,11 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
pass
else:
raise
+ # Purge stale unprocessed xsync changelogs
+ for f in os.listdir(self.tempdir):
+ if f.startswith("XSYNC-CHANGELOG"):
+ os.remove(os.path.join(self.tempdir, f))
+
def crawl(self):
"""
@@ -1238,25 +1672,28 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
self.Xcrawl()
t = Thread(target=Xsyncer)
t.start()
- logging.info('starting hybrid crawl..., stime: %s'
- % repr(self.get_purge_time()))
+ logging.info(lf('starting hybrid crawl',
+ stime=self.get_data_stime()))
self.status.set_worker_crawl_status("Hybrid Crawl")
while True:
try:
item = self.comlist.pop(0)
if item[0] == 'finale':
- logging.info('finished hybrid crawl syncing, stime: %s'
- % repr(self.get_purge_time()))
+ logging.info(lf('finished hybrid crawl',
+ stime=self.get_data_stime()))
break
elif item[0] == 'xsync':
- logging.info('processing xsync changelog %s' % (item[1]))
+ logging.info(lf('processing xsync changelog',
+ path=item[1]))
self.process([item[1]], 0)
self.archive_and_purge_changelogs([item[1]])
elif item[0] == 'stime':
- logging.debug('setting slave time: %s' % repr(item[1]))
+ logging.debug(lf('setting slave time',
+ time=item[1]))
self.upd_stime(item[1][1], item[1][0])
else:
- logging.warn('unknown tuple in comlist (%s)' % repr(item))
+ logging.warn(lf('unknown tuple in comlist',
+ entry=item))
except IndexError:
time.sleep(1)
@@ -1316,7 +1753,7 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
def is_sticky(self, path, mo):
"""check for DHTs linkto sticky bit file"""
sticky = False
- if mo & 01000:
+ if mo & 0o1000:
sticky = self.master.server.linkto_check(path)
return sticky
@@ -1334,8 +1771,9 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
xtr_root = self.xtime('.', self.slave)
if isinstance(xtr_root, int):
if xtr_root != ENOENT:
- logging.warn("slave cluster not returning the "
- "correct xtime for root (%d)" % xtr_root)
+ logging.warn(lf("slave cluster not returning the "
+ "xtime for root",
+ error=xtr_root))
xtr_root = self.minus_infinity
xtl = self.xtime(path)
if isinstance(xtl, int):
@@ -1343,10 +1781,15 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
xtr = self.xtime(path, self.slave)
if isinstance(xtr, int):
if xtr != ENOENT:
- logging.warn("slave cluster not returning the "
- "correct xtime for %s (%d)" % (path, xtr))
+ logging.warn(lf("slave cluster not returning the "
+ "xtime for dir",
+ path=path,
+ error=xtr))
xtr = self.minus_infinity
xtr = max(xtr, xtr_root)
+ zero_zero = (0, 0)
+ if xtr_root == zero_zero:
+ xtr = self.minus_infinity
if not self.need_sync(path, xtl, xtr):
if path == '.':
self.sync_done([(path, xtl)], True)
@@ -1356,27 +1799,32 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
dem = self.master.server.entries(path)
pargfid = self.master.server.gfid(path)
if isinstance(pargfid, int):
- logging.warn('skipping directory %s' % (path))
+ logging.warn(lf('skipping directory',
+ path=path))
for e in dem:
bname = e
e = os.path.join(path, e)
xte = self.xtime(e)
if isinstance(xte, int):
- logging.warn("irregular xtime for %s: %s" %
- (e, errno.errorcode[xte]))
+ logging.warn(lf("irregular xtime",
+ path=e,
+ error=errno.errorcode[xte]))
continue
if not self.need_sync(e, xte, xtr):
continue
st = self.master.server.lstat(e)
if isinstance(st, int):
- logging.warn('%s got purged in the interim ...' % e)
+ logging.warn(lf('got purged in the interim',
+ path=e))
continue
if self.is_sticky(e, st.st_mode):
- logging.debug('ignoring sticky bit file %s' % e)
+ logging.debug(lf('ignoring sticky bit file',
+ path=e))
continue
gfid = self.master.server.gfid(e)
if isinstance(gfid, int):
- logging.warn('skipping entry %s..' % e)
+ logging.warn(lf('skipping entry',
+ path=e))
continue
mo = st.st_mode
self.counter += 1 if ((stat.S_ISDIR(mo) or
@@ -1386,9 +1834,10 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
self.sync_done(self.stimes, False)
self.stimes = []
if stat.S_ISDIR(mo):
- self.write_entry_change("E", [gfid, 'MKDIR', str(mo), str(
- st.st_uid), str(st.st_gid), escape(os.path.join(pargfid,
- bname))])
+ self.write_entry_change("E",
+ [gfid, 'MKDIR', str(mo),
+ str(0), str(0), escape_space_newline(
+ os.path.join(pargfid, bname))])
self.write_entry_change("M", [gfid, "SETATTR", str(st.st_uid),
str(st.st_gid), str(st.st_mode),
str(st.st_atime),
@@ -1407,8 +1856,8 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
self.stimes.append((e, stime_to_update))
elif stat.S_ISLNK(mo):
self.write_entry_change(
- "E", [gfid, 'SYMLINK', escape(os.path.join(pargfid,
- bname))])
+ "E", [gfid, 'SYMLINK', escape_space_newline(
+ os.path.join(pargfid, bname))])
elif stat.S_ISREG(mo):
nlink = st.st_nlink
nlink -= 1 # fixup backend stat link count
@@ -1418,14 +1867,14 @@ class GMasterXsyncMixin(GMasterChangelogMixin):
if nlink == 1:
self.write_entry_change("E",
[gfid, 'MKNOD', str(mo),
- str(st.st_uid),
- str(st.st_gid),
- escape(os.path.join(
- pargfid, bname))])
+ str(0), str(0),
+ escape_space_newline(
+ os.path.join(
+ pargfid, bname))])
else:
self.write_entry_change(
- "E", [gfid, 'LINK', escape(os.path.join(pargfid,
- bname))])
+ "E", [gfid, 'LINK', escape_space_newline(
+ os.path.join(pargfid, bname))])
self.write_entry_change("D", [gfid])
if path == '.':
stime_to_update = xtl
@@ -1516,16 +1965,17 @@ class Syncer(object):
def __init__(self, slave, sync_engine, resilient_errnos=[]):
"""spawn worker threads"""
+ self.log_err = False
self.slave = slave
self.lock = Lock()
self.pb = PostBox()
self.sync_engine = sync_engine
self.errnos_ok = resilient_errnos
- for i in range(int(gconf.sync_jobs)):
- t = Thread(target=self.syncjob)
+ for i in range(gconf.get("sync-jobs")):
+ t = Thread(target=self.syncjob, args=(i + 1, ))
t.start()
- def syncjob(self):
+ def syncjob(self, job_id):
"""the life of a worker"""
while True:
pb = None
@@ -1538,7 +1988,14 @@ class Syncer(object):
break
time.sleep(0.5)
pb.close()
- po = self.sync_engine(pb)
+ start = time.time()
+ po = self.sync_engine(pb, self.log_err)
+ logging.info(lf("Sync Time Taken",
+ job=job_id,
+ num_files=len(pb),
+ return_code=po.returncode,
+ duration="%.4f" % (time.time() - start)))
+
if po.returncode == 0:
ret = (True, 0)
elif po.returncode in self.errnos_ok:
@@ -1555,3 +2012,9 @@ class Syncer(object):
return pb
except BoxClosedErr:
pass
+
+ def enable_errorlog(self):
+ self.log_err = True
+
+ def disable_errorlog(self):
+ self.log_err = False
diff --git a/geo-replication/syncdaemon/monitor.py b/geo-replication/syncdaemon/monitor.py
index ba5c8e32514..6aa7b9dfc99 100644
--- a/geo-replication/syncdaemon/monitor.py
+++ b/geo-replication/syncdaemon/monitor.py
@@ -13,119 +13,49 @@ import sys
import time
import signal
import logging
-import uuid
import xml.etree.ElementTree as XET
-from subprocess import PIPE
-from resource import Popen, FILE, GLUSTER, SSH
from threading import Lock
-from errno import EEXIST
-import re
+from errno import ECHILD, ESRCH
import random
-from gconf import gconf
-from syncdutils import select, waitpid
-from syncdutils import set_term_handler, is_host_local, GsyncdError
-from syncdutils import escape, Thread, finalize, memoize
+from resource import SSH
+import gsyncdconfig as gconf
+import libgfchangelog
+from rconf import rconf
+from syncdutils import (select, waitpid, errno_wrap, lf, grabpidfile,
+ set_term_handler, GsyncdError,
+ Thread, finalize, Volinfo, VolinfoFromGconf,
+ gf_event, EVENT_GEOREP_FAULTY, get_up_nodes,
+ unshare_propagation_supported)
from gsyncdstatus import GeorepStatus, set_monitor_status
-
+import py2py3
+from py2py3 import pipe
ParseError = XET.ParseError if hasattr(XET, 'ParseError') else SyntaxError
-def get_subvol_num(brick_idx, replica_count, disperse_count):
+def get_subvol_num(brick_idx, vol, hot):
+ tier = vol.is_tier()
+ disperse_count = vol.disperse_count(tier, hot)
+ replica_count = vol.replica_count(tier, hot)
+ distribute_count = vol.distribution_count(tier, hot)
+ gconf.setconfig("master-distribution-count", distribute_count)
+
+ if (tier and not hot):
+ brick_idx = brick_idx - vol.get_hot_bricks_count(tier)
+
subvol_size = disperse_count if disperse_count > 0 else replica_count
cnt = int((brick_idx + 1) / subvol_size)
rem = (brick_idx + 1) % subvol_size
if rem > 0:
- return cnt + 1
+ cnt = cnt + 1
+
+ if (tier and hot):
+ return "hot_" + str(cnt)
+ elif (tier and not hot):
+ return "cold_" + str(cnt)
else:
- return cnt
-
-
-def get_slave_bricks_status(host, vol):
- po = Popen(['gluster', '--xml', '--remote-host=' + host,
- 'volume', 'status', vol, "detail"],
- stdout=PIPE, stderr=PIPE)
- vix = po.stdout.read()
- po.wait()
- po.terminate_geterr(fail_on_err=False)
- if po.returncode != 0:
- logging.info("Volume status command failed, unable to get "
- "list of up nodes of %s, returning empty list: %s" %
- (vol, po.returncode))
- return []
- vi = XET.fromstring(vix)
- if vi.find('opRet').text != '0':
- logging.info("Unable to get list of up nodes of %s, "
- "returning empty list: %s" %
- (vol, vi.find('opErrstr').text))
- return []
-
- up_hosts = set()
-
- try:
- for el in vi.findall('volStatus/volumes/volume/node'):
- if el.find('status').text == '1':
- up_hosts.add(el.find('hostname').text)
- except (ParseError, AttributeError, ValueError) as e:
- logging.info("Parsing failed to get list of up nodes of %s, "
- "returning empty list: %s" % (vol, e))
-
- return list(up_hosts)
-
-
-class Volinfo(object):
-
- def __init__(self, vol, host='localhost', prelude=[]):
- po = Popen(prelude + ['gluster', '--xml', '--remote-host=' + host,
- 'volume', 'info', vol],
- stdout=PIPE, stderr=PIPE)
- vix = po.stdout.read()
- po.wait()
- po.terminate_geterr()
- vi = XET.fromstring(vix)
- if vi.find('opRet').text != '0':
- if prelude:
- via = '(via %s) ' % prelude.join(' ')
- else:
- via = ' '
- raise GsyncdError('getting volume info of %s%s '
- 'failed with errorcode %s',
- (vol, via, vi.find('opErrno').text))
- self.tree = vi
- self.volume = vol
- self.host = host
-
- def get(self, elem):
- return self.tree.findall('.//' + elem)
-
- @property
- @memoize
- def bricks(self):
- def bparse(b):
- host, dirp = b.text.split(':', 2)
- return {'host': host, 'dir': dirp}
- return [bparse(b) for b in self.get('brick')]
-
- @property
- @memoize
- def uuid(self):
- ids = self.get('id')
- if len(ids) != 1:
- raise GsyncdError("volume info of %s obtained from %s: "
- "ambiguous uuid",
- self.volume, self.host)
- return ids[0].text
-
- @property
- @memoize
- def replica_count(self):
- return int(self.get('replicaCount')[0].text)
-
- @property
- @memoize
- def disperse_count(self):
- return int(self.get('disperseCount')[0].text)
+ return str(cnt)
class Monitor(object):
@@ -150,9 +80,10 @@ class Monitor(object):
# standard handler
set_term_handler(lambda *a: set_term_handler())
# give a chance to graceful exit
- os.kill(-os.getpid(), signal.SIGTERM)
+ errno_wrap(os.kill, [-os.getpid(), signal.SIGTERM], [ESRCH])
- def monitor(self, w, argv, cpids, agents, slave_vol, slave_host, master):
+ def monitor(self, w, argv, cpids, slave_vol, slave_host, master,
+ suuid, slavenodes):
"""the monitor loop
Basic logic is a blantantly simple blunt heuristics:
@@ -171,22 +102,32 @@ class Monitor(object):
blown worker blows up on EPIPE if the net goes down,
due to the keep-alive thread)
"""
- if not self.status.get(w[0], None):
- self.status[w[0]] = GeorepStatus(gconf.state_file, w[0])
-
- set_monitor_status(gconf.state_file, self.ST_STARTED)
- self.status[w[0]].set_worker_status(self.ST_INIT)
-
+ if not self.status.get(w[0]['dir'], None):
+ self.status[w[0]['dir']] = GeorepStatus(gconf.get("state-file"),
+ w[0]['host'],
+ w[0]['dir'],
+ w[0]['uuid'],
+ master,
+ "%s::%s" % (slave_host,
+ slave_vol))
ret = 0
def nwait(p, o=0):
- p2, r = waitpid(p, o)
- if not p2:
- return
- return r
+ try:
+ p2, r = waitpid(p, o)
+ if not p2:
+ return
+ return r
+ except OSError as e:
+ # no child process, this happens if the child process
+ # already died and has been cleaned up
+ if e.errno == ECHILD:
+ return -1
+ else:
+ raise
def exit_signalled(s):
- """ child teminated due to receipt of SIGUSR1 """
+ """ child terminated due to receipt of SIGUSR1 """
return (os.WIFSIGNALED(s) and (os.WTERMSIG(s) == signal.SIGUSR1))
def exit_status(s):
@@ -194,73 +135,76 @@ class Monitor(object):
return os.WEXITSTATUS(s)
return 1
- conn_timeout = int(gconf.connection_timeout)
+ conn_timeout = gconf.get("connection-timeout")
while ret in (0, 1):
- remote_host = w[1]
+ remote_user, remote_host = w[1][0].split("@")
+ remote_id = w[1][1]
# Check the status of the connected slave node
# If the connected slave node is down then try to connect to
# different up node.
- m = re.match("(ssh|gluster|file):\/\/(.+)@([^:]+):(.+)",
- remote_host)
- if m:
- current_slave_host = m.group(3)
- slave_up_hosts = get_slave_bricks_status(
- slave_host, slave_vol)
-
- if current_slave_host not in slave_up_hosts:
- if len(slave_up_hosts) > 0:
- remote_host = "%s://%s@%s:%s" % (m.group(1),
- m.group(2),
- random.choice(
- slave_up_hosts),
- m.group(4))
-
- # Spawn the worker and agent in lock to avoid fd leak
+ current_slave_host = remote_host
+ slave_up_hosts = get_up_nodes(slavenodes, gconf.get("ssh-port"))
+
+ if (current_slave_host, remote_id) not in slave_up_hosts:
+ if len(slave_up_hosts) > 0:
+ remote_new = random.choice(slave_up_hosts)
+ remote_host = "%s@%s" % (remote_user, remote_new[0])
+ remote_id = remote_new[1]
+
+ # Spawn the worker in lock to avoid fd leak
self.lock.acquire()
- logging.info('-' * conn_timeout)
- logging.info('starting gsyncd worker')
-
- # Couple of pipe pairs for RPC communication b/w
- # worker and changelog agent.
-
- # read/write end for agent
- (ra, ww) = os.pipe()
- # read/write end for worker
- (rw, wa) = os.pipe()
-
- # spawn the agent process
- apid = os.fork()
- if apid == 0:
- os.execv(sys.executable, argv + ['--local-path', w[0],
- '--agent',
- '--rpc-fd',
- ','.join([str(ra), str(wa),
- str(rw), str(ww)])])
- pr, pw = os.pipe()
+ self.status[w[0]['dir']].set_worker_status(self.ST_INIT)
+ logging.info(lf('starting gsyncd worker',
+ brick=w[0]['dir'],
+ slave_node=remote_host))
+
+ pr, pw = pipe()
cpid = os.fork()
if cpid == 0:
os.close(pr)
- os.execv(sys.executable, argv + ['--feedback-fd', str(pw),
- '--local-path', w[0],
- '--local-id',
- '.' + escape(w[0]),
- '--rpc-fd',
- ','.join([str(rw), str(ww),
- str(ra), str(wa)]),
- '--subvol-num', str(w[2]),
- '--resource-remote',
- remote_host])
+
+ args_to_worker = argv + [
+ 'worker',
+ rconf.args.master,
+ rconf.args.slave,
+ '--feedback-fd', str(pw),
+ '--local-path', w[0]['dir'],
+ '--local-node', w[0]['host'],
+ '--local-node-id', w[0]['uuid'],
+ '--slave-id', suuid,
+ '--subvol-num', str(w[2]),
+ '--resource-remote', remote_host,
+ '--resource-remote-id', remote_id
+ ]
+
+ if rconf.args.config_file is not None:
+ args_to_worker += ['-c', rconf.args.config_file]
+
+ if w[3]:
+ args_to_worker.append("--is-hottier")
+
+ if rconf.args.debug:
+ args_to_worker.append("--debug")
+
+ access_mount = gconf.get("access-mount")
+ if access_mount:
+ os.execv(sys.executable, args_to_worker)
+ else:
+ if unshare_propagation_supported():
+ logging.debug("Worker would mount volume privately")
+ unshare_cmd = ['unshare', '-m', '--propagation',
+ 'private']
+ cmd = unshare_cmd + args_to_worker
+ os.execvp("unshare", cmd)
+ else:
+ logging.debug("Mount is not private. It would be lazy"
+ " umounted")
+ os.execv(sys.executable, args_to_worker)
cpids.add(cpid)
- agents.add(apid)
os.close(pw)
- # close all RPC pipes in monitor
- os.close(ra)
- os.close(wa)
- os.close(rw)
- os.close(ww)
self.lock.release()
t0 = time.time()
@@ -269,127 +213,183 @@ class Monitor(object):
if so:
ret = nwait(cpid, os.WNOHANG)
+
if ret is not None:
- logging.info("worker(%s) died before establishing "
- "connection" % w[0])
- nwait(apid) #wait for agent
+ logging.info(lf("worker died before establishing "
+ "connection",
+ brick=w[0]['dir']))
else:
- logging.debug("worker(%s) connected" % w[0])
+ logging.debug("worker(%s) connected" % w[0]['dir'])
while time.time() < t0 + conn_timeout:
ret = nwait(cpid, os.WNOHANG)
+
if ret is not None:
- logging.info("worker(%s) died in startup "
- "phase" % w[0])
- nwait(apid) #wait for agent
+ logging.info(lf("worker died in startup phase",
+ brick=w[0]['dir']))
break
+
time.sleep(1)
else:
- logging.info("worker(%s) not confirmed in %d sec, "
- "aborting it" % (w[0], conn_timeout))
- os.kill(cpid, signal.SIGKILL)
- nwait(apid) #wait for agent
+ logging.info(
+ lf("Worker not confirmed after wait, aborting it. "
+ "Gsyncd invocation on remote slave via SSH or "
+ "gluster master mount might have hung. Please "
+ "check the above logs for exact issue and check "
+ "master or slave volume for errors. Restarting "
+ "master/slave volume accordingly might help.",
+ brick=w[0]['dir'],
+ timeout=conn_timeout))
+ errno_wrap(os.kill, [cpid, signal.SIGKILL], [ESRCH])
ret = nwait(cpid)
if ret is None:
- self.status[w[0]].set_worker_status(self.ST_STABLE)
- #If worker dies, agent terminates on EOF.
- #So lets wait for agent first.
- nwait(apid)
ret = nwait(cpid)
if exit_signalled(ret):
ret = 0
else:
ret = exit_status(ret)
if ret in (0, 1):
- self.status[w[0]].set_worker_status(self.ST_FAULTY)
+ self.status[w[0]['dir']].set_worker_status(self.ST_FAULTY)
+ gf_event(EVENT_GEOREP_FAULTY,
+ master_volume=master.volume,
+ master_node=w[0]['host'],
+ master_node_id=w[0]['uuid'],
+ slave_host=slave_host,
+ slave_volume=slave_vol,
+ current_slave_host=current_slave_host,
+ brick_path=w[0]['dir'])
time.sleep(10)
- self.status[w[0]].set_worker_status(self.ST_INCON)
+ self.status[w[0]['dir']].set_worker_status(self.ST_INCON)
return ret
- def multiplex(self, wspx, suuid, slave_vol, slave_host, master):
- argv = sys.argv[:]
- for o in ('-N', '--no-daemon', '--monitor'):
- while o in argv:
- argv.remove(o)
- argv.extend(('-N', '-p', '', '--slave-id', suuid))
- argv.insert(0, os.path.basename(sys.executable))
+ def multiplex(self, wspx, suuid, slave_vol, slave_host, master, slavenodes):
+ argv = [os.path.basename(sys.executable), sys.argv[0]]
cpids = set()
- agents = set()
ta = []
for wx in wspx:
def wmon(w):
- cpid, _ = self.monitor(w, argv, cpids, agents, slave_vol,
- slave_host, master)
+ cpid, _ = self.monitor(w, argv, cpids, slave_vol,
+ slave_host, master, suuid, slavenodes)
time.sleep(1)
self.lock.acquire()
for cpid in cpids:
- os.kill(cpid, signal.SIGKILL)
- for apid in agents:
- os.kill(apid, signal.SIGKILL)
+ errno_wrap(os.kill, [cpid, signal.SIGKILL], [ESRCH])
self.lock.release()
finalize(exval=1)
t = Thread(target=wmon, args=[wx])
t.start()
ta.append(t)
+
+ # monitor status was being updated in each monitor thread. It
+ # should not be done as it can cause deadlock for a worker start.
+ # set_monitor_status uses flock to synchronize multple instances
+ # updating the file. Since each monitor thread forks worker,
+ # these processes can hold the reference to fd of status
+ # file causing deadlock to workers which starts later as flock
+ # will not be release until all references to same fd is closed.
+ # It will also cause fd leaks.
+
+ self.lock.acquire()
+ set_monitor_status(gconf.get("state-file"), self.ST_STARTED)
+ self.lock.release()
for t in ta:
t.join()
-def distribute(*resources):
- master, slave = resources
- mvol = Volinfo(master.volume, master.host)
+def distribute(master, slave):
+ if rconf.args.use_gconf_volinfo:
+ mvol = VolinfoFromGconf(master.volume, master=True)
+ else:
+ mvol = Volinfo(master.volume, master.host, master=True)
logging.debug('master bricks: ' + repr(mvol.bricks))
prelude = []
- si = slave
slave_host = None
slave_vol = None
- if isinstance(slave, SSH):
- prelude = gconf.ssh_command.split() + [slave.remote_addr]
- si = slave.inner_rsc
- logging.debug('slave SSH gateway: ' + slave.remote_addr)
- if isinstance(si, FILE):
- sbricks = {'host': 'localhost', 'dir': si.path}
- suuid = uuid.uuid5(uuid.NAMESPACE_URL, slave.get_url(canonical=True))
- elif isinstance(si, GLUSTER):
- svol = Volinfo(si.volume, slave.remote_addr.split('@')[-1])
- sbricks = svol.bricks
- suuid = svol.uuid
- slave_host = slave.remote_addr.split('@')[-1]
- slave_vol = si.volume
- else:
- raise GsyncdError("unknown slave type " + slave.url)
- logging.info('slave bricks: ' + repr(sbricks))
- if isinstance(si, FILE):
- slaves = [slave.url]
- else:
- slavenodes = set(b['host'] for b in sbricks)
- if isinstance(slave, SSH) and not gconf.isolated_slave:
- rap = SSH.parse_ssh_address(slave)
- slaves = ['ssh://' + rap['user'] + '@' + h + ':' + si.url
- for h in slavenodes]
- else:
- slavevols = [h + ':' + si.volume for h in slavenodes]
- if isinstance(slave, SSH):
- slaves = ['ssh://' + rap.remote_addr + ':' + v
- for v in slavevols]
- else:
- slaves = slavevols
+ prelude = [gconf.get("ssh-command")] + \
+ gconf.get("ssh-options").split() + \
+ ["-p", str(gconf.get("ssh-port"))] + \
+ [slave.remote_addr]
- workerspex = [(brick['dir'], slaves[idx % len(slaves)],
- get_subvol_num(idx, mvol.replica_count, mvol.disperse_count))
- for idx, brick in enumerate(mvol.bricks)
- if is_host_local(brick['host'])]
- logging.info('worker specs: ' + repr(workerspex))
- return workerspex, suuid, slave_vol, slave_host, master
+ logging.debug('slave SSH gateway: ' + slave.remote_addr)
-
-def monitor(*resources):
+ if rconf.args.use_gconf_volinfo:
+ svol = VolinfoFromGconf(slave.volume, master=False)
+ else:
+ svol = Volinfo(slave.volume, "localhost", prelude, master=False)
+
+ sbricks = svol.bricks
+ suuid = svol.uuid
+ slave_host = slave.remote_addr.split('@')[-1]
+ slave_vol = slave.volume
+
+ # save this xattr for the session delete command
+ old_stime_xattr_prefix = gconf.get("stime-xattr-prefix", None)
+ new_stime_xattr_prefix = "trusted.glusterfs." + mvol.uuid + "." + \
+ svol.uuid
+ if not old_stime_xattr_prefix or \
+ old_stime_xattr_prefix != new_stime_xattr_prefix:
+ gconf.setconfig("stime-xattr-prefix", new_stime_xattr_prefix)
+
+ logging.debug('slave bricks: ' + repr(sbricks))
+
+ slavenodes = set((b['host'], b["uuid"]) for b in sbricks)
+ rap = SSH.parse_ssh_address(slave)
+ slaves = [(rap['user'] + '@' + h[0], h[1]) for h in slavenodes]
+
+ workerspex = []
+ for idx, brick in enumerate(mvol.bricks):
+ if rconf.args.local_node_id == brick['uuid']:
+ is_hot = mvol.is_hot(":".join([brick['host'], brick['dir']]))
+ workerspex.append((brick,
+ slaves[idx % len(slaves)],
+ get_subvol_num(idx, mvol, is_hot),
+ is_hot))
+ logging.debug('worker specs: ' + repr(workerspex))
+ return workerspex, suuid, slave_vol, slave_host, master, slavenodes
+
+
+def monitor(local, remote):
# Check if gsyncd restarted in pause state. If
# yes, send SIGSTOP to negative of monitor pid
# to go back to pause state.
- if gconf.pause_on_start:
- os.kill(-os.getpid(), signal.SIGSTOP)
+ if rconf.args.pause_on_start:
+ errno_wrap(os.kill, [-os.getpid(), signal.SIGSTOP], [ESRCH])
"""oh yeah, actually Monitor is used as singleton, too"""
- return Monitor().multiplex(*distribute(*resources))
+ return Monitor().multiplex(*distribute(local, remote))
+
+
+def startup(go_daemon=True):
+ """set up logging, pidfile grabbing, daemonization"""
+ pid_file = gconf.get("pid-file")
+ if not grabpidfile():
+ sys.stderr.write("pidfile is taken, exiting.\n")
+ sys.exit(2)
+ rconf.pid_file_owned = True
+
+ if not go_daemon:
+ return
+
+ x, y = pipe()
+ cpid = os.fork()
+ if cpid:
+ os.close(x)
+ sys.exit()
+ os.close(y)
+ os.setsid()
+ dn = os.open(os.devnull, os.O_RDWR)
+ for f in (sys.stdin, sys.stdout, sys.stderr):
+ os.dup2(dn, f.fileno())
+
+ if not grabpidfile(pid_file + '.tmp'):
+ raise GsyncdError("cannot grab temporary pidfile")
+
+ os.rename(pid_file + '.tmp', pid_file)
+
+ # wait for parent to terminate
+ # so we can start up with
+ # no messing from the dirty
+ # ol' bustard
+ select((x,), (), ())
+ os.close(x)
diff --git a/geo-replication/syncdaemon/py2py3.py b/geo-replication/syncdaemon/py2py3.py
new file mode 100644
index 00000000000..f9c76e1b50a
--- /dev/null
+++ b/geo-replication/syncdaemon/py2py3.py
@@ -0,0 +1,184 @@
+#
+# Copyright (c) 2018 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.
+#
+
+# All python2/python3 compatibility routines
+
+import sys
+import os
+import stat
+import struct
+from syncdutils import umask
+from ctypes import create_string_buffer
+
+if sys.version_info >= (3,):
+ def pipe():
+ (r, w) = os.pipe()
+ os.set_inheritable(r, True)
+ os.set_inheritable(w, True)
+ return (r, w)
+
+ # Raw conversion of bytearray to string. Used in the cases where
+ # buffer is created by create_string_buffer which is a 8-bit char
+ # array and passed to syscalls to fetch results. Using encode/decode
+ # doesn't work as it converts to string altering the size.
+ def bytearray_to_str(byte_arr):
+ return ''.join([chr(b) for b in byte_arr])
+
+ # Raw conversion of string to bytes. This is required to convert
+ # back the string into bytearray(c char array) to use in struc
+ # pack/unpacking. Again encode/decode can't be used as it
+ # converts it alters size.
+ def str_to_bytearray(string):
+ return bytes([ord(c) for c in string])
+
+ def gr_create_string_buffer(size):
+ return create_string_buffer(b'\0', size)
+
+ def gr_query_xattr(cls, path, size, syscall, attr=None):
+ if attr:
+ return cls._query_xattr(path.encode(), size, syscall,
+ attr.encode())
+ else:
+ return cls._query_xattr(path.encode(), size, syscall)
+
+ def gr_lsetxattr(cls, path, attr, val):
+ return cls.libc.lsetxattr(path.encode(), attr.encode(), val,
+ len(val), 0)
+
+ def gr_lremovexattr(cls, path, attr):
+ return cls.libc.lremovexattr(path.encode(), attr.encode())
+
+ def gr_cl_register(libgfapi, brick, path, log_file, log_level, retries):
+ return libgfapi.gf_changelog_register(brick.encode(),
+ path.encode(),
+ log_file.encode(),
+ log_level, retries)
+
+ def gr_cl_done(libgfapi, clfile):
+ return libgfapi.gf_changelog_done(clfile.encode())
+
+ def gr_cl_history_changelog(libgfapi, changelog_path, start, end, num_parallel,
+ actual_end):
+ return libgfapi.gf_history_changelog(changelog_path.encode(),
+ start, end, num_parallel,
+ actual_end)
+
+ def gr_cl_history_done(libgfapi, clfile):
+ return libgfapi.gf_history_changelog_done(clfile.encode())
+
+ # regular file
+
+ def entry_pack_reg(cls, gf, bn, mo, uid, gid):
+ bn_encoded = bn.encode()
+ blen = len(bn_encoded)
+ return struct.pack(cls._fmt_mknod(blen),
+ uid, gid, gf.encode(), mo, bn_encoded,
+ stat.S_IMODE(mo), 0, umask())
+
+ def entry_pack_reg_stat(cls, gf, bn, st):
+ bn_encoded = bn.encode()
+ blen = len(bn_encoded)
+ mo = st['mode']
+ return struct.pack(cls._fmt_mknod(blen),
+ st['uid'], st['gid'],
+ gf.encode(), mo, bn_encoded,
+ stat.S_IMODE(mo), 0, umask())
+ # mkdir
+
+ def entry_pack_mkdir(cls, gf, bn, mo, uid, gid):
+ bn_encoded = bn.encode()
+ blen = len(bn_encoded)
+ return struct.pack(cls._fmt_mkdir(blen),
+ uid, gid, gf.encode(), mo, bn_encoded,
+ stat.S_IMODE(mo), umask())
+ # symlink
+
+ def entry_pack_symlink(cls, gf, bn, lnk, st):
+ bn_encoded = bn.encode()
+ blen = len(bn_encoded)
+ lnk_encoded = lnk.encode()
+ llen = len(lnk_encoded)
+ return struct.pack(cls._fmt_symlink(blen, llen),
+ st['uid'], st['gid'],
+ gf.encode(), st['mode'], bn_encoded,
+ lnk_encoded)
+else:
+ def pipe():
+ (r, w) = os.pipe()
+ return (r, w)
+
+ # Raw conversion of bytearray to string
+ def bytearray_to_str(byte_arr):
+ return byte_arr
+
+ # Raw conversion of string to bytearray
+ def str_to_bytearray(string):
+ return string
+
+ def gr_create_string_buffer(size):
+ return create_string_buffer('\0', size)
+
+ def gr_query_xattr(cls, path, size, syscall, attr=None):
+ if attr:
+ return cls._query_xattr(path, size, syscall, attr)
+ else:
+ return cls._query_xattr(path, size, syscall)
+
+ def gr_lsetxattr(cls, path, attr, val):
+ return cls.libc.lsetxattr(path, attr, val, len(val), 0)
+
+ def gr_lremovexattr(cls, path, attr):
+ return cls.libc.lremovexattr(path, attr)
+
+ def gr_cl_register(libgfapi, brick, path, log_file, log_level, retries):
+ return libgfapi.gf_changelog_register(brick, path, log_file,
+ log_level, retries)
+
+ def gr_cl_done(libgfapi, clfile):
+ return libgfapi.gf_changelog_done(clfile)
+
+ def gr_cl_history_changelog(libgfapi, changelog_path, start, end, num_parallel,
+ actual_end):
+ return libgfapi.gf_history_changelog(changelog_path, start, end,
+ num_parallel, actual_end)
+
+ def gr_cl_history_done(libgfapi, clfile):
+ return libgfapi.gf_history_changelog_done(clfile)
+
+ # regular file
+
+ def entry_pack_reg(cls, gf, bn, mo, uid, gid):
+ blen = len(bn)
+ return struct.pack(cls._fmt_mknod(blen),
+ uid, gid, gf, mo, bn,
+ stat.S_IMODE(mo), 0, umask())
+
+ def entry_pack_reg_stat(cls, gf, bn, st):
+ blen = len(bn)
+ mo = st['mode']
+ return struct.pack(cls._fmt_mknod(blen),
+ st['uid'], st['gid'],
+ gf, mo, bn,
+ stat.S_IMODE(mo), 0, umask())
+ # mkdir
+
+ def entry_pack_mkdir(cls, gf, bn, mo, uid, gid):
+ blen = len(bn)
+ return struct.pack(cls._fmt_mkdir(blen),
+ uid, gid, gf, mo, bn,
+ stat.S_IMODE(mo), umask())
+ # symlink
+
+ def entry_pack_symlink(cls, gf, bn, lnk, st):
+ blen = len(bn)
+ llen = len(lnk)
+ return struct.pack(cls._fmt_symlink(blen, llen),
+ st['uid'], st['gid'],
+ gf, st['mode'], bn, lnk)
diff --git a/geo-replication/syncdaemon/gconf.py b/geo-replication/syncdaemon/rconf.py
index 39a70a650b3..ff716ee4d6d 100644
--- a/geo-replication/syncdaemon/gconf.py
+++ b/geo-replication/syncdaemon/rconf.py
@@ -9,9 +9,9 @@
#
-class GConf(object):
+class RConf(object):
- """singleton class to store globals
+ """singleton class to store runtime globals
shared between gsyncd modules"""
ssh_ctl_dir = None
@@ -21,11 +21,11 @@ class GConf(object):
log_exit = False
permanent_handles = []
log_metadata = {}
- """One variable is sufficient to track the
- switching of worker to ACTIVE. Two variables
- are intentionally used to track worker going
- to PASSIVE as well mainly for debugging"""
- active_earlier = False
- passive_earlier = False
+ mgmt_lock_fd = None
+ args = None
+ turns = 0
+ mountbroker = False
+ mount_point = None
+ mbr_umount_cmd = []
-gconf = GConf()
+rconf = RConf()
diff --git a/geo-replication/syncdaemon/repce.py b/geo-replication/syncdaemon/repce.py
index d7b17dda796..c622afa6373 100644
--- a/geo-replication/syncdaemon/repce.py
+++ b/geo-replication/syncdaemon/repce.py
@@ -14,30 +14,27 @@ import time
import logging
from threading import Condition
try:
- import thread
-except ImportError:
- # py 3
import _thread as thread
-try:
- from Queue import Queue
except ImportError:
- # py 3
+ import thread
+try:
from queue import Queue
+except ImportError:
+ from Queue import Queue
try:
import cPickle as pickle
except ImportError:
- # py 3
import pickle
-from syncdutils import Thread, select
+from syncdutils import Thread, select, lf
-pickle_proto = -1
+pickle_proto = 2
repce_version = 1.0
def ioparse(i, o):
if isinstance(i, int):
- i = os.fdopen(i)
+ i = os.fdopen(i, 'rb')
# rely on duck typing for recognizing
# streams as that works uniformly
# in py2 and py3
@@ -57,8 +54,15 @@ def send(out, *args):
def recv(inf):
- """load an object from input stream"""
- return pickle.load(inf)
+ """load an object from input stream
+ python2 and python3 compatibility, inf is sys.stdin
+ and is opened as text stream by default. Hence using the
+ buffer attribute in python3
+ """
+ if hasattr(inf, "buffer"):
+ return pickle.load(inf.buffer)
+ else:
+ return pickle.load(inf)
class RepceServer(object):
@@ -196,15 +200,17 @@ class RepceClient(object):
"""RePCe client is callabe, calling it implements a synchronous
remote call.
- We do a .push with a cbk which does a wakeup upon receiving anwser,
+ We do a .push with a cbk which does a wakeup upon receiving answer,
then wait on the RepceJob.
"""
rjob = self.push(
meth, *args, **{'cbk': lambda rj, res: rj.wakeup(res)})
exc, res = rjob.wait()
if exc:
- logging.error('call %s (%s) failed on peer with %s' %
- (repr(rjob), meth, str(type(res).__name__)))
+ logging.error(lf('call failed',
+ call=repr(rjob),
+ method=meth,
+ error=str(type(res).__name__)))
raise res
logging.debug("call %s %s -> %s" % (repr(rjob), meth, repr(res)))
return res
diff --git a/geo-replication/syncdaemon/resource.py b/geo-replication/syncdaemon/resource.py
index c73347aaf17..f12c7ceaa36 100644
--- a/geo-replication/syncdaemon/resource.py
+++ b/geo-replication/syncdaemon/resource.py
@@ -13,260 +13,43 @@ import os
import sys
import stat
import time
-import signal
import fcntl
-import errno
import types
import struct
-import socket
import logging
import tempfile
-import threading
import subprocess
-from errno import EEXIST, ENOENT, ENODATA, ENOTDIR, ELOOP
-from errno import EISDIR, ENOTEMPTY, ESTALE, EINVAL
-from select import error as SelectError
-import shutil
+from errno import (EEXIST, ENOENT, ENODATA, ENOTDIR, ELOOP, EACCES,
+ EISDIR, ENOTEMPTY, ESTALE, EINVAL, EBUSY, EPERM)
+import errno
+
+from rconf import rconf
+import gsyncdconfig as gconf
+import libgfchangelog
-from gconf import gconf
import repce
from repce import RepceServer, RepceClient
from master import gmaster_builder
import syncdutils
-from syncdutils import GsyncdError, select, privileged, boolify, funcode
-from syncdutils import umask, entry2pb, gauxpfx, errno_wrap, lstat
-from syncdutils import NoPurgeTimeAvailable, PartialHistoryAvailable
-from syncdutils import ChangelogException
-from syncdutils import CHANGELOG_AGENT_CLIENT_VERSION
+from syncdutils import (GsyncdError, select, privileged, funcode,
+ entry2pb, gauxpfx, errno_wrap, lstat,
+ NoStimeAvailable, PartialHistoryAvailable,
+ ChangelogException, ChangelogHistoryNotAvailable,
+ get_changelog_log_level, get_rsync_version,
+ GX_GFID_CANONICAL_LEN,
+ gf_mount_ready, lf, Popen, sup,
+ Xattr, matching_disk_gfid, get_gfid_from_mnt,
+ unshare_propagation_supported, get_slv_dir_path)
from gsyncdstatus import GeorepStatus
+from py2py3 import (pipe, str_to_bytearray, entry_pack_reg,
+ entry_pack_reg_stat, entry_pack_mkdir,
+ entry_pack_symlink)
-UrlRX = re.compile('\A(\w+)://([^ *?[]*)\Z')
-HostRX = re.compile('[a-z\d](?:[a-z\d.-]*[a-z\d])?', re.I)
-UserRX = re.compile("[\w!\#$%&'*+-\/=?^_`{|}~]+")
-
-
-def sup(x, *a, **kw):
- """a rubyesque "super" for python ;)
-
- invoke caller method in parent class with given args.
- """
- return getattr(super(type(x), x),
- sys._getframe(1).f_code.co_name)(*a, **kw)
-
-
-def desugar(ustr):
- """transform sugared url strings to standard <scheme>://<urlbody> form
-
- parsing logic enforces the constraint that sugared forms should contatin
- a ':' or a '/', which ensures that sugared urls do not conflict with
- gluster volume names.
- """
- m = re.match('([^:]*):(.*)', ustr)
- if m:
- if not m.groups()[0]:
- return "gluster://localhost" + ustr
- elif '@' in m.groups()[0] or re.search('[:/]', m.groups()[1]):
- return "ssh://" + ustr
- else:
- return "gluster://" + ustr
- else:
- if ustr[0] != '/':
- raise GsyncdError("cannot resolve sugared url '%s'" % ustr)
- ap = os.path.normpath(ustr)
- if ap.startswith('//'):
- ap = ap[1:]
- return "file://" + ap
-
-
-def gethostbyname(hnam):
- """gethostbyname wrapper"""
- try:
- return socket.gethostbyname(hnam)
- except socket.gaierror:
- ex = sys.exc_info()[1]
- raise GsyncdError("failed to resolve %s: %s" %
- (hnam, ex.strerror))
-
-
-def parse_url(ustr):
- """instantiate an url object by scheme-to-class dispatch
-
- The url classes taken into consideration are the ones in
- this module whose names are full-caps.
- """
- m = UrlRX.match(ustr)
- if not m:
- ustr = desugar(ustr)
- m = UrlRX.match(ustr)
- if not m:
- raise GsyncdError("malformed url")
- sch, path = m.groups()
- this = sys.modules[__name__]
- if not hasattr(this, sch.upper()):
- raise GsyncdError("unknown url scheme " + sch)
- return getattr(this, sch.upper())(path)
-
-
-class _MetaXattr(object):
-
- """singleton class, a lazy wrapper around the
- libcxattr module
-
- libcxattr (a heavy import due to ctypes) is
- loaded only when when the single
- instance is tried to be used.
-
- This reduces runtime for those invocations
- which do not need filesystem manipulation
- (eg. for config, url parsing)
- """
-
- def __getattr__(self, meth):
- from libcxattr import Xattr as LXattr
- xmeth = [m for m in dir(LXattr) if m[0] != '_']
- if not meth in xmeth:
- return
- for m in xmeth:
- setattr(self, m, getattr(LXattr, m))
- return getattr(self, meth)
-
-
-Xattr = _MetaXattr()
+ENOTSUP = getattr(errno, 'ENOTSUP', 'EOPNOTSUPP')
-
-class Popen(subprocess.Popen):
-
- """customized subclass of subprocess.Popen with a ring
- buffer for children error output"""
-
- @classmethod
- def init_errhandler(cls):
- """start the thread which handles children's error output"""
- cls.errstore = {}
-
- def tailer():
- while True:
- errstore = cls.errstore.copy()
- try:
- poe, _, _ = select(
- [po.stderr for po in errstore], [], [], 1)
- except (ValueError, SelectError):
- continue
- for po in errstore:
- if po.stderr not in poe:
- continue
- po.lock.acquire()
- try:
- if po.on_death_row:
- continue
- la = errstore[po]
- try:
- fd = po.stderr.fileno()
- except ValueError: # file is already closed
- continue
- l = os.read(fd, 1024)
- if not l:
- continue
- tots = len(l)
- for lx in la:
- tots += len(lx)
- while tots > 1 << 20 and la:
- tots -= len(la.pop(0))
- la.append(l)
- finally:
- po.lock.release()
- t = syncdutils.Thread(target=tailer)
- t.start()
- cls.errhandler = t
-
- @classmethod
- def fork(cls):
- """fork wrapper that restarts errhandler thread in child"""
- pid = os.fork()
- if not pid:
- cls.init_errhandler()
- return pid
-
- def __init__(self, args, *a, **kw):
- """customizations for subprocess.Popen instantiation
-
- - 'close_fds' is taken to be the default
- - if child's stderr is chosen to be managed,
- register it with the error handler thread
- """
- self.args = args
- if 'close_fds' not in kw:
- kw['close_fds'] = True
- self.lock = threading.Lock()
- self.on_death_row = False
- try:
- sup(self, args, *a, **kw)
- except:
- ex = sys.exc_info()[1]
- if not isinstance(ex, OSError):
- raise
- raise GsyncdError("""execution of "%s" failed with %s (%s)""" %
- (args[0], errno.errorcode[ex.errno],
- os.strerror(ex.errno)))
- if kw.get('stderr') == subprocess.PIPE:
- assert(getattr(self, 'errhandler', None))
- self.errstore[self] = []
-
- def errlog(self):
- """make a log about child's failure event"""
- filling = ""
- if self.elines:
- filling = ", saying:"
- logging.error("""command "%s" returned with %s%s""" %
- (" ".join(self.args), repr(self.returncode), filling))
- lp = ''
-
- def logerr(l):
- logging.error(self.args[0] + "> " + l)
- for l in self.elines:
- ls = l.split('\n')
- ls[0] = lp + ls[0]
- lp = ls.pop()
- for ll in ls:
- logerr(ll)
- if lp:
- logerr(lp)
-
- def errfail(self):
- """fail nicely if child did not terminate with success"""
- self.errlog()
- syncdutils.finalize(exval=1)
-
- def terminate_geterr(self, fail_on_err=True):
- """kill child, finalize stderr harvesting (unregister
- from errhandler, set up .elines), fail on error if
- asked for
- """
- self.lock.acquire()
- try:
- self.on_death_row = True
- finally:
- self.lock.release()
- elines = self.errstore.pop(self)
- if self.poll() is None:
- self.terminate()
- if self.poll() is None:
- time.sleep(0.1)
- self.kill()
- self.wait()
- while True:
- if not select([self.stderr], [], [], 0.1)[0]:
- break
- b = os.read(self.stderr.fileno(), 1024)
- if b:
- elines.append(b)
- else:
- break
- self.stderr.close()
- self.elines = elines
- if fail_on_err and self.returncode != 0:
- self.errfail()
+slv_volume = None
+slv_host = None
class Server(object):
@@ -283,7 +66,6 @@ class Server(object):
NTV_FMTSTR = "!" + "B" * 19 + "II"
FRGN_XTRA_FMT = "I"
FRGN_FMTSTR = NTV_FMTSTR + FRGN_XTRA_FMT
- GX_GFID_CANONICAL_LEN = 37 # canonical gfid len + '\0'
# for backend gfid fetch, do not use GX_NSPACE_PFX
GFID_XATTR = 'trusted.gfid'
@@ -293,15 +75,15 @@ class Server(object):
@classmethod
def _fmt_mknod(cls, l):
- return "!II%dsI%dsIII" % (cls.GX_GFID_CANONICAL_LEN, l + 1)
+ return "!II%dsI%dsIII" % (GX_GFID_CANONICAL_LEN, l + 1)
@classmethod
def _fmt_mkdir(cls, l):
- return "!II%dsI%dsII" % (cls.GX_GFID_CANONICAL_LEN, l + 1)
+ return "!II%dsI%dsII" % (GX_GFID_CANONICAL_LEN, l + 1)
@classmethod
def _fmt_symlink(cls, l1, l2):
- return "!II%dsI%ds%ds" % (cls.GX_GFID_CANONICAL_LEN, l1 + 1, l2 + 1)
+ return "!II%dsI%ds%ds" % (GX_GFID_CANONICAL_LEN, l1 + 1, l2 + 1)
def _pathguard(f):
"""decorator method that checks
@@ -313,14 +95,14 @@ class Server(object):
fc = funcode(f)
pi = list(fc.co_varnames).index('path')
- def ff(*a):
- path = a[pi]
+ def ff(*args):
+ path = args[pi]
ps = path.split('/')
if path[0] == '/' or '..' in ps:
raise ValueError('unsafe path')
- a = list(a)
- a[pi] = os.path.join(a[0].local_path, path)
- return f(*a)
+ args = list(args)
+ args[pi] = os.path.join(args[0].local_path, path)
+ return f(*args)
return ff
@classmethod
@@ -361,23 +143,15 @@ class Server(object):
@classmethod
@_pathguard
def gfid(cls, path):
- try:
- buf = Xattr.lgetxattr(path, cls.GFID_XATTR, 16)
+ buf = errno_wrap(Xattr.lgetxattr, [path, cls.GFID_XATTR, 16],
+ [ENOENT], [ESTALE, ENODATA])
+ if buf == ENOENT:
+ return buf
+ else:
+ buf = str_to_bytearray(buf)
m = re.match('(.{8})(.{4})(.{4})(.{4})(.{12})', "".join(
['%02x' % x for x in struct.unpack(cls.GFID_FMTSTR, buf)]))
return '-'.join(m.groups())
- except (IOError, OSError):
- ex = sys.exc_info()[1]
- if ex.errno == ENOENT:
- return ex.errno
- else:
- raise
-
- @classmethod
- def gfid_mnt(cls, gfidpath):
- return errno_wrap(Xattr.lgetxattr,
- [gfidpath, 'glusterfs.gfid.string',
- cls.GX_GFID_CANONICAL_LEN], [ENOENT], [ESTALE])
@classmethod
@_pathguard
@@ -465,6 +239,7 @@ class Server(object):
val = Xattr.lgetxattr(path,
'.'.join([cls.GX_NSPACE, uuid, 'xtime']),
8)
+ val = str_to_bytearray(val)
return struct.unpack('!II', val)
except OSError:
ex = sys.exc_info()[1]
@@ -487,6 +262,7 @@ class Server(object):
val = Xattr.lgetxattr(path,
'.'.join([cls.GX_NSPACE, uuid, 'stime']),
8)
+ val = str_to_bytearray(val)
return struct.unpack('!II', val)
except OSError:
ex = sys.exc_info()[1]
@@ -509,6 +285,31 @@ class Server(object):
val = Xattr.lgetxattr(path,
'.'.join([cls.GX_NSPACE, uuid, 'stime']),
8)
+ val = str_to_bytearray(val)
+ return struct.unpack('!II', val)
+ except OSError:
+ ex = sys.exc_info()[1]
+ if ex.errno in (ENOENT, ENODATA, ENOTDIR):
+ return ex.errno
+ else:
+ raise
+
+ @classmethod
+ @_pathguard
+ def entry_stime(cls, path, uuid):
+ """
+ entry_stime xattr to reduce the number of retry of Entry changes when
+ Geo-rep worker crashes and restarts. entry_stime is updated after
+ processing every changelog file. On failure and restart, worker only
+ have to reprocess the last changelog for Entry ops.
+ Xattr Key: <PFX>.<MASTERVOL_UUID>.<SLAVEVOL_UUID>.entry_stime
+ """
+ try:
+ val = Xattr.lgetxattr(path,
+ '.'.join([cls.GX_NSPACE, uuid,
+ 'entry_stime']),
+ 8)
+ val = str_to_bytearray(val)
return struct.unpack('!II', val)
except OSError:
ex = sys.exc_info()[1]
@@ -530,17 +331,34 @@ class Server(object):
@_pathguard
def set_stime(cls, path, uuid, mark):
"""set @mark as stime for @uuid on @path"""
- Xattr.lsetxattr(
- path, '.'.join([cls.GX_NSPACE, uuid, 'stime']),
- struct.pack('!II', *mark))
+ errno_wrap(Xattr.lsetxattr,
+ [path,
+ '.'.join([cls.GX_NSPACE, uuid, 'stime']),
+ struct.pack('!II', *mark)],
+ [ENOENT],
+ [ESTALE, EINVAL])
+
+ @classmethod
+ @_pathguard
+ def set_entry_stime(cls, path, uuid, mark):
+ """set @mark as stime for @uuid on @path"""
+ errno_wrap(Xattr.lsetxattr,
+ [path,
+ '.'.join([cls.GX_NSPACE, uuid, 'entry_stime']),
+ struct.pack('!II', *mark)],
+ [ENOENT],
+ [ESTALE, EINVAL])
@classmethod
@_pathguard
def set_xtime(cls, path, uuid, mark):
"""set @mark as xtime for @uuid on @path"""
- Xattr.lsetxattr(
- path, '.'.join([cls.GX_NSPACE, uuid, 'xtime']),
- struct.pack('!II', *mark))
+ errno_wrap(Xattr.lsetxattr,
+ [path,
+ '.'.join([cls.GX_NSPACE, uuid, 'xtime']),
+ struct.pack('!II', *mark)],
+ [ENOENT],
+ [ESTALE, EINVAL])
@classmethod
@_pathguard
@@ -560,80 +378,85 @@ class Server(object):
def entry_ops(cls, entries):
pfx = gauxpfx()
logging.debug('entries: %s' % repr(entries))
- # regular file
-
- def entry_pack_reg(gf, bn, mo, uid, gid):
- blen = len(bn)
- return struct.pack(cls._fmt_mknod(blen),
- uid, gid, gf, mo, bn,
- stat.S_IMODE(mo), 0, umask())
-
- def entry_pack_reg_stat(gf, bn, st):
- blen = len(bn)
- mo = st['mode']
- return struct.pack(cls._fmt_mknod(blen),
- st['uid'], st['gid'],
- gf, mo, bn,
- stat.S_IMODE(mo), 0, umask())
- # mkdir
-
- def entry_pack_mkdir(gf, bn, mo, uid, gid):
- blen = len(bn)
- return struct.pack(cls._fmt_mkdir(blen),
- uid, gid, gf, mo, bn,
- stat.S_IMODE(mo), umask())
- # symlink
-
- def entry_pack_symlink(gf, bn, lnk, st):
- blen = len(bn)
- llen = len(lnk)
- return struct.pack(cls._fmt_symlink(blen, llen),
- st['uid'], st['gid'],
- gf, st['mode'], bn, lnk)
-
- def entry_purge(entry, gfid):
+ dist_count = rconf.args.master_dist_count
+
+ def entry_purge(op, entry, gfid, e, uid, gid):
# This is an extremely racy code and needs to be fixed ASAP.
# The GFID check here is to be sure that the pargfid/bname
# to be purged is the GFID gotten from the changelog.
# (a stat(changelog_gfid) would also be valid here)
# The race here is between the GFID check and the purge.
- if not matching_disk_gfid(gfid, entry):
+
+ # If the entry or the gfid of the file to be deleted is not present
+ # on slave, we can ignore the unlink/rmdir
+ if isinstance(lstat(entry), int) or \
+ isinstance(lstat(os.path.join(pfx, gfid)), int):
return
- er = errno_wrap(os.unlink, [entry], [ENOENT, ESTALE, EISDIR])
- if isinstance(er, int):
- if er == EISDIR:
- er = errno_wrap(os.rmdir, [entry], [ENOENT, ESTALE,
- ENOTEMPTY])
- if er == ENOTEMPTY:
- return er
+ if not matching_disk_gfid(gfid, entry):
+ collect_failure(e, EEXIST, uid, gid)
+ return
- def collect_failure(e, cmd_ret):
+ if op == 'UNLINK':
+ er = errno_wrap(os.unlink, [entry], [ENOENT, ESTALE], [EBUSY])
+ # EISDIR is safe error, ignore. This can only happen when
+ # unlink is sent from master while fixing gfid conflicts.
+ if er != EISDIR:
+ return er
+
+ elif op == 'RMDIR':
+ er = errno_wrap(os.rmdir, [entry], [ENOENT, ESTALE,
+ ENOTEMPTY], [EBUSY])
+ if er == ENOTEMPTY:
+ return er
+
+ def collect_failure(e, cmd_ret, uid, gid, dst=False):
+ slv_entry_info = {}
+ slv_entry_info['gfid_mismatch'] = False
+ slv_entry_info['name_mismatch'] = False
+ slv_entry_info['dst'] = dst
+ slv_entry_info['slave_isdir'] = False
+ slv_entry_info['slave_name'] = None
+ slv_entry_info['slave_gfid'] = None
# We do this for failing fops on Slave
# Master should be logging this
if cmd_ret is None:
- return
-
- if cmd_ret == EEXIST:
- disk_gfid = cls.gfid_mnt(e['entry'])
- if isinstance(disk_gfid, basestring):
- if e['gfid'] != disk_gfid:
- failures.append((e, cmd_ret, disk_gfid))
- else:
- failures.append((e, cmd_ret))
-
- failures = []
-
- def matching_disk_gfid(gfid, entry):
- disk_gfid = cls.gfid_mnt(entry)
- if isinstance(disk_gfid, int):
return False
- if not gfid == disk_gfid:
- return False
+ if e.get("stat", {}):
+ # Copy actual UID/GID value back to entry stat
+ e['stat']['uid'] = uid
+ e['stat']['gid'] = gid
+
+ if cmd_ret in [EEXIST, ESTALE]:
+ if dst:
+ en = e['entry1']
+ else:
+ en = e['entry']
+ disk_gfid = get_gfid_from_mnt(en)
+ if isinstance(disk_gfid, str) and \
+ e['gfid'] != disk_gfid:
+ slv_entry_info['gfid_mismatch'] = True
+ st = lstat(en)
+ if not isinstance(st, int):
+ if st and stat.S_ISDIR(st.st_mode):
+ slv_entry_info['slave_isdir'] = True
+ dir_name = get_slv_dir_path(slv_host, slv_volume,
+ disk_gfid)
+ slv_entry_info['slave_name'] = dir_name
+ else:
+ slv_entry_info['slave_isdir'] = False
+ slv_entry_info['slave_gfid'] = disk_gfid
+ failures.append((e, cmd_ret, slv_entry_info))
+ else:
+ return False
+ else:
+ failures.append((e, cmd_ret, slv_entry_info))
return True
+ failures = []
+
def recursive_rmdir(gfid, entry, path):
"""disk_gfid check added for original path for which
recursive_delete is called. This disk gfid check executed
@@ -647,7 +470,7 @@ class Server(object):
return
names = []
- names = errno_wrap(os.listdir, [path], [ENOENT], [ESTALE])
+ names = errno_wrap(os.listdir, [path], [ENOENT], [ESTALE, ENOTSUP])
if isinstance(names, int):
return
@@ -656,7 +479,7 @@ class Server(object):
if not matching_disk_gfid(gfid, entry):
return
er = errno_wrap(os.remove, [fullname], [ENOENT, ESTALE,
- EISDIR])
+ EISDIR], [EBUSY])
if er == EISDIR:
recursive_rmdir(gfid, entry, fullname)
@@ -664,18 +487,50 @@ class Server(object):
if not matching_disk_gfid(gfid, entry):
return
- errno_wrap(os.rmdir, [path], [ENOENT, ESTALE])
+ errno_wrap(os.rmdir, [path], [ENOENT, ESTALE], [EBUSY])
+
+ def rename_with_disk_gfid_confirmation(gfid, entry, en, uid, gid):
+ if not matching_disk_gfid(gfid, entry):
+ logging.error(lf("RENAME ignored: source entry does not match "
+ "with on-disk gfid",
+ source=entry,
+ gfid=gfid,
+ disk_gfid=get_gfid_from_mnt(entry),
+ target=en))
+ collect_failure(e, EEXIST, uid, gid)
+ return
+
+ cmd_ret = errno_wrap(os.rename,
+ [entry, en],
+ [ENOENT, EEXIST], [ESTALE, EBUSY])
+ collect_failure(e, cmd_ret, uid, gid)
for e in entries:
blob = None
op = e['op']
gfid = e['gfid']
entry = e['entry']
+ uid = 0
+ gid = 0
+
+ # Skip entry processing if it's marked true during gfid
+ # conflict resolution
+ if e['skip_entry']:
+ continue
+
+ if e.get("stat", {}):
+ # Copy UID/GID value and then reset to zero. Copied UID/GID
+ # will be used to run chown once entry is created.
+ uid = e['stat']['uid']
+ gid = e['stat']['gid']
+ e['stat']['uid'] = 0
+ e['stat']['gid'] = 0
+
(pg, bname) = entry2pb(entry)
if op in ['RMDIR', 'UNLINK']:
# Try once, if rmdir failed with ENOTEMPTY
# then delete recursively.
- er = entry_purge(entry, gfid)
+ er = entry_purge(op, entry, gfid, e, uid, gid)
if isinstance(er, int):
if er == ENOTEMPTY and op == 'RMDIR':
# Retry if ENOTEMPTY, ESTALE
@@ -687,49 +542,179 @@ class Server(object):
logging.debug("Removed %s => %s/%s recursively" %
(gfid, pg, bname))
else:
- logging.warn("Recursive remove %s => %s/%s"
- "failed: %s" % (gfid, pg, bname,
- os.strerror(er1)))
+ logging.warn(lf("Recursive remove failed",
+ gfid=gfid,
+ pgfid=pg,
+ bname=bname,
+ error=os.strerror(er1)))
else:
- logging.warn("Failed to remove %s => %s/%s. %s" %
- (gfid, pg, bname, os.strerror(er)))
+ logging.warn(lf("Failed to remove",
+ gfid=gfid,
+ pgfid=pg,
+ bname=bname,
+ error=os.strerror(er)))
elif op in ['CREATE', 'MKNOD']:
- blob = entry_pack_reg(
- gfid, bname, e['mode'], e['uid'], e['gid'])
+ slink = os.path.join(pfx, gfid)
+ st = lstat(slink)
+ # don't create multiple entries with same gfid
+ if isinstance(st, int):
+ blob = entry_pack_reg(cls, gfid, bname,
+ e['mode'], e['uid'], e['gid'])
+ # Self healed hardlinks are recorded as MKNOD.
+ # So if the gfid already exists, it should be
+ # processed as hard link not mknod.
+ elif op in ['MKNOD']:
+ cmd_ret = errno_wrap(os.link,
+ [slink, entry],
+ [ENOENT, EEXIST], [ESTALE])
+ collect_failure(e, cmd_ret, uid, gid)
elif op == 'MKDIR':
- blob = entry_pack_mkdir(
- gfid, bname, e['mode'], e['uid'], e['gid'])
+ en = e['entry']
+ slink = os.path.join(pfx, gfid)
+ st = lstat(slink)
+ # don't create multiple entries with same gfid
+ if isinstance(st, int):
+ blob = entry_pack_mkdir(cls, gfid, bname,
+ e['mode'], e['uid'], e['gid'])
+ elif (isinstance(lstat(en), int) or
+ not matching_disk_gfid(gfid, en)):
+ # If gfid of a directory exists on slave but path based
+ # create is getting EEXIST. This means the directory is
+ # renamed in master but recorded as MKDIR during hybrid
+ # crawl. Get the directory path by reading the backend
+ # symlink and trying to rename to new name as said by
+ # master.
+ logging.info(lf("Special case: rename on mkdir",
+ gfid=gfid, entry=repr(entry)))
+ src_entry = get_slv_dir_path(slv_host, slv_volume, gfid)
+ if src_entry is None:
+ collect_failure(e, ENOENT, uid, gid)
+ if src_entry is not None and src_entry != entry:
+ slv_entry_info = {}
+ slv_entry_info['gfid_mismatch'] = False
+ slv_entry_info['name_mismatch'] = True
+ slv_entry_info['dst'] = False
+ slv_entry_info['slave_isdir'] = True
+ slv_entry_info['slave_gfid'] = gfid
+ slv_entry_info['slave_entry'] = src_entry
+
+ failures.append((e, EEXIST, slv_entry_info))
elif op == 'LINK':
slink = os.path.join(pfx, gfid)
st = lstat(slink)
if isinstance(st, int):
(pg, bname) = entry2pb(entry)
- blob = entry_pack_reg_stat(gfid, bname, e['stat'])
+ if stat.S_ISREG(e['stat']['mode']):
+ blob = entry_pack_reg_stat(cls, gfid, bname, e['stat'])
+ elif stat.S_ISLNK(e['stat']['mode']):
+ blob = entry_pack_symlink(cls, gfid, bname, e['link'],
+ e['stat'])
else:
cmd_ret = errno_wrap(os.link,
[slink, entry],
[ENOENT, EEXIST], [ESTALE])
- collect_failure(e, cmd_ret)
+ collect_failure(e, cmd_ret, uid, gid)
elif op == 'SYMLINK':
- blob = entry_pack_symlink(gfid, bname, e['link'], e['stat'])
- elif op == 'RENAME':
- en = e['entry1']
+ en = e['entry']
st = lstat(entry)
if isinstance(st, int):
+ blob = entry_pack_symlink(cls, gfid, bname, e['link'],
+ e['stat'])
+ elif not matching_disk_gfid(gfid, en):
+ collect_failure(e, EEXIST, uid, gid)
+ elif op == 'RENAME':
+ en = e['entry1']
+ # The matching disk gfid check validates two things
+ # 1. Validates name is present, return false otherwise
+ # 2. Validates gfid is same, returns false otherwise
+ # So both validations are necessary to decide src doesn't
+ # exist. We can't rely on only gfid stat as hardlink could
+ # be present and we can't rely only on name as name could
+ # exist with different gfid.
+ if not matching_disk_gfid(gfid, entry):
if e['stat'] and not stat.S_ISDIR(e['stat']['mode']):
- (pg, bname) = entry2pb(en)
- blob = entry_pack_reg_stat(gfid, bname, e['stat'])
+ if stat.S_ISLNK(e['stat']['mode']):
+ # src is not present, so don't sync symlink as
+ # we don't know target. It's ok to ignore. If
+ # it's unliked, it's fine. If it's renamed to
+ # something else, it will be synced then.
+ if e['link'] is not None:
+ st1 = lstat(en)
+ if isinstance(st1, int):
+ (pg, bname) = entry2pb(en)
+ blob = entry_pack_symlink(cls, gfid, bname,
+ e['link'],
+ e['stat'])
+ elif not matching_disk_gfid(gfid, en):
+ collect_failure(e, EEXIST, uid, gid, True)
+ else:
+ slink = os.path.join(pfx, gfid)
+ st = lstat(slink)
+ # don't create multiple entries with same gfid
+ if isinstance(st, int):
+ (pg, bname) = entry2pb(en)
+ blob = entry_pack_reg_stat(cls, gfid, bname,
+ e['stat'])
+ else:
+ cmd_ret = errno_wrap(os.link, [slink, en],
+ [ENOENT, EEXIST], [ESTALE])
+ collect_failure(e, cmd_ret, uid, gid)
else:
- cmd_ret = errno_wrap(os.rename,
- [entry, en],
- [ENOENT, EEXIST], [ESTALE])
- collect_failure(e, cmd_ret)
+ st = lstat(entry)
+ st1 = lstat(en)
+ if isinstance(st1, int):
+ rename_with_disk_gfid_confirmation(gfid, entry, en,
+ uid, gid)
+ else:
+ if st.st_ino == st1.st_ino:
+ # we have a hard link, we can now unlink source
+ try:
+ errno_wrap(os.unlink, [entry],
+ [ENOENT, ESTALE], [EBUSY])
+ except OSError as e:
+ if e.errno == EISDIR:
+ try:
+ errno_wrap(os.rmdir, [entry],
+ [ENOENT, ESTALE], [EBUSY])
+ except OSError as e:
+ if e.errno == ENOTEMPTY:
+ logging.error(
+ lf("Directory Rename failed. "
+ "Both Old and New"
+ " directories exists",
+ old=entry,
+ new=en))
+ else:
+ raise
+ else:
+ raise
+ elif not matching_disk_gfid(gfid, en) and dist_count > 1:
+ collect_failure(e, EEXIST, uid, gid, True)
+ else:
+ # We are here which means matching_disk_gfid for
+ # both source and destination has returned false
+ # and distribution count for master vol is greater
+ # then one. Which basically says both the source and
+ # destination exist and not hardlinks.
+ # So we are safe to go ahead with rename here.
+ rename_with_disk_gfid_confirmation(gfid, entry, en,
+ uid, gid)
if blob:
cmd_ret = errno_wrap(Xattr.lsetxattr,
[pg, 'glusterfs.gfid.newfile', blob],
- [EEXIST, ENOENT],
- [ESTALE, EINVAL])
- collect_failure(e, cmd_ret)
+ [EEXIST, ENOENT, ESTALE],
+ [ESTALE, EINVAL, EBUSY])
+ collect_failure(e, cmd_ret, uid, gid)
+
+ # If UID/GID is different than zero that means we are trying
+ # create Entry with different UID/GID. Create Entry with
+ # UID:0 and GID:0, and then call chown to set UID/GID
+ if uid != 0 or gid != 0:
+ path = os.path.join(pfx, gfid)
+ cmd_ret = errno_wrap(os.lchown, [path, uid, gid], [ENOENT],
+ [ESTALE, EINVAL])
+ collect_failure(e, cmd_ret, uid, gid)
+
return failures
@classmethod
@@ -743,17 +728,39 @@ class Server(object):
atime = e['stat']['atime']
mtime = e['stat']['mtime']
go = e['go']
- cmd_ret = errno_wrap(os.chmod, [go, mode],
- [ENOENT], [ESTALE, EINVAL])
- # This is a fail fast mechanism
- # We do this for failing fops on Slave
- # Master should be logging this
+ # Linux doesn't support chmod on symlink itself.
+ # It is always applied to the target file. So
+ # changelog would record target file's gfid
+ # and we are good. But 'chown' is supported on
+ # symlink file. So changelog would record symlink
+ # gfid in such cases. Since we do 'chown' 'chmod'
+ # 'utime' for each gfid recorded for metadata, and
+ # we know from changelog the metadata is on symlink's
+ # gfid or target file's gfid, we should be doing
+ # 'lchown' 'lchmod' 'utime with no-deference' blindly.
+ # But since 'lchmod' and 'utime with no de-reference' is
+ # not supported in python3, we have to rely on 'chmod'
+ # and 'utime with de-reference'. Hence avoiding 'chmod'
+ # and 'utime' if it's symlink file.
+
+ is_symlink = False
+ cmd_ret = errno_wrap(os.lchown, [go, uid, gid], [ENOENT],
+ [ESTALE, EINVAL])
if isinstance(cmd_ret, int):
- failures.append((e, cmd_ret))
continue
- errno_wrap(os.chown, [go, uid, gid], [ENOENT], [ESTALE, EINVAL])
- errno_wrap(os.utime, [go, (atime, mtime)],
- [ENOENT], [ESTALE, EINVAL])
+
+ is_symlink = os.path.islink(go)
+
+ if not is_symlink:
+ cmd_ret = errno_wrap(os.chmod, [go, mode],
+ [ENOENT, EACCES, EPERM], [ESTALE, EINVAL])
+ if isinstance(cmd_ret, int):
+ failures.append((e, cmd_ret, "chmod"))
+
+ cmd_ret = errno_wrap(os.utime, [go, (atime, mtime)],
+ [ENOENT, EACCES, EPERM], [ESTALE, EINVAL])
+ if isinstance(cmd_ret, int):
+ failures.append((e, cmd_ret, "utime"))
return failures
@classmethod
@@ -810,239 +817,273 @@ class Server(object):
return 1.0
-class SlaveLocal(object):
-
- """mix-in class to implement some factes of a slave server
+class Mounter(object):
- ("mix-in" is sort of like "abstract class", ie. it's not
- instantiated just included in the ancesty DAG. I use "mix-in"
- to indicate that it's not used as an abstract base class,
- rather just taken in to implement additional functionality
- on the basis of the assumed availability of certain interfaces.)
- """
-
- def can_connect_to(self, remote):
- """determine our position in the connectibility matrix"""
- return not remote
+ """Abstract base class for mounter backends"""
- def service_loop(self):
- """start a RePCe server serving self's server
-
- stop servicing if a timeout is configured and got no
- keep-alime in that inteval
- """
-
- if boolify(gconf.use_rsync_xattrs) and not privileged():
- raise GsyncdError(
- "using rsync for extended attributes is not supported")
-
- repce = RepceServer(
- self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs))
- t = syncdutils.Thread(target=lambda: (repce.service_loop(),
- syncdutils.finalize()))
- t.start()
- logging.info("slave listening")
- if gconf.timeout and int(gconf.timeout) > 0:
- while True:
- lp = self.server.last_keep_alive
- time.sleep(int(gconf.timeout))
- if lp == self.server.last_keep_alive:
- logging.info(
- "connection inactive for %d seconds, stopping" %
- int(gconf.timeout))
- break
- else:
- select((), (), ())
+ def __init__(self, params):
+ self.params = params
+ self.mntpt = None
+ self.umount_cmd = []
+ @classmethod
+ def get_glusterprog(cls):
+ gluster_cmd_dir = gconf.get("gluster-command-dir")
+ if rconf.args.subcmd == "slave":
+ gluster_cmd_dir = gconf.get("slave-gluster-command-dir")
+ return os.path.join(gluster_cmd_dir, cls.glusterprog)
+
+ def umount_l(self, d):
+ """perform lazy umount"""
+ po = Popen(self.make_umount_argv(d), stderr=subprocess.PIPE,
+ universal_newlines=True)
+ po.wait()
+ return po
-class SlaveRemote(object):
+ @classmethod
+ def make_umount_argv(cls, d):
+ raise NotImplementedError
- """mix-in class to implement an interface to a remote slave"""
+ def make_mount_argv(self, label=None):
+ raise NotImplementedError
- def connect_remote(self, rargs=[], **opts):
- """connects to a remote slave
+ def cleanup_mntpt(self, *a):
+ pass
- Invoke an auxiliary utility (slave gsyncd, possibly wrapped)
- which sets up the connection and set up a RePCe client to
- communicate throuh its stdio.
- """
- slave = opts.get('slave', self.url)
- extra_opts = []
- so = getattr(gconf, 'session_owner', None)
- if so:
- extra_opts += ['--session-owner', so]
- if boolify(gconf.use_rsync_xattrs):
- extra_opts.append('--use-rsync-xattrs')
- po = Popen(rargs + gconf.remote_gsyncd.split() + extra_opts +
- ['-N', '--listen', '--timeout', str(gconf.timeout),
- slave],
- stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- gconf.transport = po
- return self.start_fd_client(po.stdout, po.stdin, **opts)
+ def handle_mounter(self, po):
+ po.wait()
- def start_fd_client(self, i, o, **opts):
- """set up RePCe client, handshake with server
+ def inhibit(self, label):
+ """inhibit a gluster filesystem
- It's cut out as a separate method to let
- subclasses hook into client startup
+ Mount glusterfs over a temporary mountpoint,
+ change into the mount, and lazy unmount the
+ filesystem.
"""
- self.server = RepceClient(i, o)
- rv = self.server.__version__()
- exrv = {'proto': repce.repce_version, 'object': Server.version()}
- da0 = (rv, exrv)
- da1 = ({}, {})
- for i in range(2):
- for k, v in da0[i].iteritems():
- da1[i][k] = int(v)
- if da1[0] != da1[1]:
- raise GsyncdError(
- "RePCe major version mismatch: local %s, remote %s" %
- (exrv, rv))
+ mpi, mpo = pipe()
+ mh = Popen.fork()
+ if mh:
+ # Parent
+ os.close(mpi)
+ fcntl.fcntl(mpo, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
+ d = None
+ margv = self.make_mount_argv(label)
+ if self.mntpt:
+ # mntpt is determined pre-mount
+ d = self.mntpt
+ mnt_msg = d + '\0'
+ encoded_msg = mnt_msg.encode()
+ os.write(mpo, encoded_msg)
+ po = Popen(margv, **self.mountkw)
+ self.handle_mounter(po)
+ po.terminate_geterr()
+ logging.debug('auxiliary glusterfs mount in place')
+ if not d:
+ # mntpt is determined during mount
+ d = self.mntpt
+ mnt_msg = d + '\0'
+ encoded_msg = mnt_msg.encode()
+ os.write(mpo, encoded_msg)
+ encoded_msg = 'M'.encode()
+ os.write(mpo, encoded_msg)
+ t = syncdutils.Thread(target=lambda: os.chdir(d))
+ t.start()
+ tlim = rconf.starttime + gconf.get("connection-timeout")
+ while True:
+ if not t.isAlive():
+ break
- def rsync(self, files, *args):
- """invoke rsync"""
- if not files:
- raise GsyncdError("no files to sync")
- logging.debug("files: " + ", ".join(files))
- argv = gconf.rsync_command.split() + \
- ['-aR0', '--inplace', '--files-from=-', '--super',
- '--stats', '--numeric-ids', '--no-implied-dirs'] + \
- gconf.rsync_options.split() + \
- (boolify(gconf.sync_xattrs) and ['--xattrs'] or []) + \
- (boolify(gconf.sync_acls) and ['--acls'] or []) + \
- ['.'] + list(args)
-
- if gconf.log_rsync_performance:
- # use stdout=PIPE only when log_rsync_performance enabled
- # Else rsync will write to stdout and nobody is their
- # to consume. If PIPE is full rsync hangs.
- po = Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ if time.time() >= tlim:
+ syncdutils.finalize(exval=1)
+ time.sleep(1)
+ os.close(mpo)
+ _, rv = syncdutils.waitpid(mh, 0)
+ if rv:
+ rv = (os.WIFEXITED(rv) and os.WEXITSTATUS(rv) or 0) - \
+ (os.WIFSIGNALED(rv) and os.WTERMSIG(rv) or 0)
+ logging.warn(lf('stale mount possibly left behind',
+ path=d))
+ raise GsyncdError("cleaning up temp mountpoint %s "
+ "failed with status %d" %
+ (d, rv))
else:
- po = Popen(argv, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
-
- for f in files:
- po.stdin.write(f)
- po.stdin.write('\0')
-
- po.stdin.close()
-
- if gconf.log_rsync_performance:
- out = po.stdout.read()
- rsync_msg = []
- for line in out.split("\n"):
- if line.startswith("Number of files:") or \
- line.startswith("Number of regular files transferred:") or \
- line.startswith("Total file size:") or \
- line.startswith("Total transferred file size:") or \
- line.startswith("Literal data:") or \
- line.startswith("Matched data:") or \
- line.startswith("Total bytes sent:") or \
- line.startswith("Total bytes received:") or \
- line.startswith("sent "):
- rsync_msg.append(line)
- logging.info("rsync performance: %s" % ", ".join(rsync_msg))
- po.wait()
- po.terminate_geterr(fail_on_err=False)
+ rv = 0
+ try:
+ os.setsid()
+ os.close(mpo)
+ mntdata = ''
+ while True:
+ c = os.read(mpi, 1)
+ c = c.decode()
+ if not c:
+ break
+ mntdata += c
+ if mntdata:
+ mounted = False
+ if mntdata[-1] == 'M':
+ mntdata = mntdata[:-1]
+ assert(mntdata)
+ mounted = True
+ assert(mntdata[-1] == '\0')
+ mntpt = mntdata[:-1]
+ assert(mntpt)
+
+ umount_master = False
+ umount_slave = False
+ if rconf.args.subcmd == "worker" \
+ and not unshare_propagation_supported() \
+ and not gconf.get("access-mount"):
+ umount_master = True
+ if rconf.args.subcmd == "slave" \
+ and not gconf.get("slave-access-mount"):
+ umount_slave = True
+
+ if mounted and (umount_master or umount_slave):
+ po = self.umount_l(mntpt)
+ po.terminate_geterr(fail_on_err=False)
+ if po.returncode != 0:
+ po.errlog()
+ rv = po.returncode
+ logging.debug("Lazy umount done: %s" % mntpt)
+ if umount_master or umount_slave:
+ self.cleanup_mntpt(mntpt)
+ except:
+ logging.exception('mount cleanup failure:')
+ rv = 200
+ os._exit(rv)
+
+ #Polling the dht.subvol.status value.
+ RETRIES = 10
+ while not gf_mount_ready():
+ if RETRIES < 0:
+ logging.error('Subvols are not up')
+ break
+ RETRIES -= 1
+ time.sleep(0.2)
- return po
+ logging.debug('auxiliary glusterfs mount prepared')
- def tarssh(self, files, slaveurl):
- """invoke tar+ssh
- -z (compress) can be use if needed, but omitting it now
- as it results in weird error (tar+ssh errors out (errcode: 2)
- """
- if not files:
- raise GsyncdError("no files to sync")
- logging.debug("files: " + ", ".join(files))
- (host, rdir) = slaveurl.split(':')
- tar_cmd = ["tar"] + \
- ["-cf", "-", "--files-from", "-"]
- ssh_cmd = gconf.ssh_command_tar.split() + \
- [host, "tar"] + \
- ["--overwrite", "-xf", "-", "-C", rdir]
- p0 = Popen(tar_cmd, stdout=subprocess.PIPE,
- stdin=subprocess.PIPE, stderr=subprocess.PIPE)
- p1 = Popen(ssh_cmd, stdin=p0.stdout, stderr=subprocess.PIPE)
- for f in files:
- p0.stdin.write(f)
- p0.stdin.write('\n')
- p0.stdin.close()
-
- # wait() for tar to terminate, collecting any errors, further
- # waiting for transfer to complete
- p0.wait()
- p0.terminate_geterr(fail_on_err=False)
- p1.wait()
- p1.terminate_geterr(fail_on_err=False)
+class DirectMounter(Mounter):
- return p1
+ """mounter backend which calls mount(8), umount(8) directly"""
+ mountkw = {'stderr': subprocess.PIPE, 'universal_newlines': True}
+ glusterprog = 'glusterfs'
-class AbstractUrl(object):
+ @staticmethod
+ def make_umount_argv(d):
+ return ['umount', '-l', d]
- """abstract base class for url scheme classes"""
+ def make_mount_argv(self, label=None):
+ self.mntpt = tempfile.mkdtemp(prefix='gsyncd-aux-mount-')
+ rconf.mount_point = self.mntpt
+ return [self.get_glusterprog()] + \
+ ['--' + p for p in self.params] + [self.mntpt]
- def __init__(self, path, pattern):
- m = re.search(pattern, path)
- if not m:
- raise GsyncdError("malformed path")
- self.path = path
- return m.groups()
+ def cleanup_mntpt(self, mntpt=None):
+ if not mntpt:
+ mntpt = self.mntpt
+ errno_wrap(os.rmdir, [mntpt], [ENOENT, EBUSY])
- @property
- def scheme(self):
- return type(self).__name__.lower()
- def canonical_path(self):
- return self.path
+class MountbrokerMounter(Mounter):
- def get_url(self, canonical=False, escaped=False):
- """format self's url in various styles"""
- if canonical:
- pa = self.canonical_path()
- else:
- pa = self.path
- u = "://".join((self.scheme, pa))
- if escaped:
- u = syncdutils.escape(u)
- return u
+ """mounter backend using the mountbroker gluster service"""
- @property
- def url(self):
- return self.get_url()
+ mountkw = {'stderr': subprocess.PIPE, 'stdout': subprocess.PIPE,
+ 'universal_newlines': True}
+ glusterprog = 'gluster'
+ @classmethod
+ def make_cli_argv(cls):
+ return [cls.get_glusterprog()] + ['--remote-host=localhost'] + \
+ gconf.get("gluster-cli-options").split() + ['system::']
-class FILE(AbstractUrl, SlaveLocal, SlaveRemote):
+ @classmethod
+ def make_umount_argv(cls, d):
+ return cls.make_cli_argv() + ['umount', d, 'lazy']
- """scheme class for file:// urls
+ def make_mount_argv(self, label):
+ return self.make_cli_argv() + \
+ ['mount', label, 'user-map-root=' +
+ syncdutils.getusername()] + self.params
- can be used to represent a file slave server
- on slave side, or interface to a remote file
- file server on master side
- """
+ def handle_mounter(self, po):
+ self.mntpt = po.stdout.readline()[:-1]
+ rconf.mount_point = self.mntpt
+ rconf.mountbroker = True
+ self.umount_cmd = self.make_cli_argv() + ['umount']
+ rconf.mbr_umount_cmd = self.umount_cmd
+ po.stdout.close()
+ sup(self, po)
+ if po.returncode != 0:
+ # if cli terminated with error due to being
+ # refused by glusterd, what it put
+ # out on stdout is a diagnostic message
+ logging.error(lf('glusterd answered', mnt=self.mntpt))
- class FILEServer(Server):
- """included server flavor"""
- pass
+class GLUSTERServer(Server):
- server = FILEServer
+ "server enhancements for a glusterfs backend"""
- def __init__(self, path):
- sup(self, path, '^/')
+ @classmethod
+ def _attr_unpack_dict(cls, xattr, extra_fields=''):
+ """generic volume mark fetching/parsing backed"""
+ fmt_string = cls.NTV_FMTSTR + extra_fields
+ buf = Xattr.lgetxattr('.', xattr, struct.calcsize(fmt_string))
+ buf = str_to_bytearray(buf)
+ vm = struct.unpack(fmt_string, buf)
+ m = re.match(
+ '(.{8})(.{4})(.{4})(.{4})(.{12})',
+ "".join(['%02x' % x for x in vm[2:18]]))
+ uuid = '-'.join(m.groups())
+ volinfo = {'version': vm[0:2],
+ 'uuid': uuid,
+ 'retval': vm[18],
+ 'volume_mark': vm[19:21],
+ }
+ if extra_fields:
+ return volinfo, vm[-len(extra_fields):]
+ else:
+ return volinfo
- def connect(self):
- """inhibit the resource beyond"""
- os.chdir(self.path)
+ @classmethod
+ def foreign_volume_infos(cls):
+ """return list of valid (not expired) foreign volume marks"""
+ dict_list = []
+ xattr_list = Xattr.llistxattr_buf('.')
+ for ele in xattr_list:
+ if ele.find('.'.join([cls.GX_NSPACE, 'volume-mark', ''])) == 0:
+ d, x = cls._attr_unpack_dict(ele, cls.FRGN_XTRA_FMT)
+ now = int(time.time())
+ if x[0] > now:
+ logging.debug("volinfo[%s] expires: %d "
+ "(%d sec later)" %
+ (d['uuid'], x[0], x[0] - now))
+ d['timeout'] = x[0]
+ dict_list.append(d)
+ else:
+ try:
+ Xattr.lremovexattr('.', ele)
+ except OSError:
+ pass
+ return dict_list
- def rsync(self, files):
- return sup(self, files, self.path)
+ @classmethod
+ def native_volume_info(cls):
+ """get the native volume mark of the underlying gluster volume"""
+ try:
+ return cls._attr_unpack_dict('.'.join([cls.GX_NSPACE,
+ 'volume-mark']))
+ except OSError:
+ ex = sys.exc_info()[1]
+ if ex.errno != ENODATA:
+ raise
-class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
+class GLUSTER(object):
"""scheme class for gluster:// urls
@@ -1052,238 +1093,17 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
(slave-ish features come from the mixins, master
functionality is outsourced to GMaster from master)
"""
-
- class GLUSTERServer(Server):
-
- "server enhancements for a glusterfs backend"""
-
- @classmethod
- def _attr_unpack_dict(cls, xattr, extra_fields=''):
- """generic volume mark fetching/parsing backed"""
- fmt_string = cls.NTV_FMTSTR + extra_fields
- buf = Xattr.lgetxattr('.', xattr, struct.calcsize(fmt_string))
- vm = struct.unpack(fmt_string, buf)
- m = re.match(
- '(.{8})(.{4})(.{4})(.{4})(.{12})',
- "".join(['%02x' % x for x in vm[2:18]]))
- uuid = '-'.join(m.groups())
- volinfo = {'version': vm[0:2],
- 'uuid': uuid,
- 'retval': vm[18],
- 'volume_mark': vm[19:21],
- }
- if extra_fields:
- return volinfo, vm[-len(extra_fields):]
- else:
- return volinfo
-
- @classmethod
- def foreign_volume_infos(cls):
- """return list of valid (not expired) foreign volume marks"""
- dict_list = []
- xattr_list = Xattr.llistxattr_buf('.')
- for ele in xattr_list:
- if ele.find('.'.join([cls.GX_NSPACE, 'volume-mark', ''])) == 0:
- d, x = cls._attr_unpack_dict(ele, cls.FRGN_XTRA_FMT)
- now = int(time.time())
- if x[0] > now:
- logging.debug("volinfo[%s] expires: %d "
- "(%d sec later)" %
- (d['uuid'], x[0], x[0] - now))
- d['timeout'] = x[0]
- dict_list.append(d)
- else:
- try:
- Xattr.lremovexattr('.', ele)
- except OSError:
- pass
- return dict_list
-
- @classmethod
- def native_volume_info(cls):
- """get the native volume mark of the underlying gluster volume"""
- try:
- return cls._attr_unpack_dict('.'.join([cls.GX_NSPACE,
- 'volume-mark']))
- except OSError:
- ex = sys.exc_info()[1]
- if ex.errno != ENODATA:
- raise
-
server = GLUSTERServer
- def __init__(self, path):
- self.host, self.volume = sup(self, path, '^(%s):(.+)' % HostRX.pattern)
-
- def canonical_path(self):
- return ':'.join([gethostbyname(self.host), self.volume])
-
- def can_connect_to(self, remote):
- """determine our position in the connectibility matrix"""
- return not remote or \
- (isinstance(remote, SSH) and isinstance(remote.inner_rsc, GLUSTER))
-
- class Mounter(object):
-
- """Abstract base class for mounter backends"""
-
- def __init__(self, params):
- self.params = params
- self.mntpt = None
-
- @classmethod
- def get_glusterprog(cls):
- return os.path.join(gconf.gluster_command_dir, cls.glusterprog)
-
- def umount_l(self, d):
- """perform lazy umount"""
- po = Popen(self.make_umount_argv(d), stderr=subprocess.PIPE)
- po.wait()
- return po
-
- @classmethod
- def make_umount_argv(cls, d):
- raise NotImplementedError
-
- def make_mount_argv(self, *a):
- raise NotImplementedError
-
- def cleanup_mntpt(self, *a):
- pass
-
- def handle_mounter(self, po):
- po.wait()
-
- def inhibit(self, *a):
- """inhibit a gluster filesystem
-
- Mount glusterfs over a temporary mountpoint,
- change into the mount, and lazy unmount the
- filesystem.
- """
-
- mpi, mpo = os.pipe()
- mh = Popen.fork()
- if mh:
- os.close(mpi)
- fcntl.fcntl(mpo, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
- d = None
- margv = self.make_mount_argv(*a)
- if self.mntpt:
- # mntpt is determined pre-mount
- d = self.mntpt
- os.write(mpo, d + '\0')
- po = Popen(margv, **self.mountkw)
- self.handle_mounter(po)
- po.terminate_geterr()
- logging.debug('auxiliary glusterfs mount in place')
- if not d:
- # mntpt is determined during mount
- d = self.mntpt
- os.write(mpo, d + '\0')
- os.write(mpo, 'M')
- t = syncdutils.Thread(target=lambda: os.chdir(d))
- t.start()
- tlim = gconf.starttime + int(gconf.connection_timeout)
- while True:
- if not t.isAlive():
- break
- if time.time() >= tlim:
- syncdutils.finalize(exval=1)
- time.sleep(1)
- os.close(mpo)
- _, rv = syncdutils.waitpid(mh, 0)
- if rv:
- rv = (os.WIFEXITED(rv) and os.WEXITSTATUS(rv) or 0) - \
- (os.WIFSIGNALED(rv) and os.WTERMSIG(rv) or 0)
- logging.warn('stale mount possibly left behind on ' + d)
- raise GsyncdError("cleaning up temp mountpoint %s "
- "failed with status %d" %
- (d, rv))
- else:
- rv = 0
- try:
- os.setsid()
- os.close(mpo)
- mntdata = ''
- while True:
- c = os.read(mpi, 1)
- if not c:
- break
- mntdata += c
- if mntdata:
- mounted = False
- if mntdata[-1] == 'M':
- mntdata = mntdata[:-1]
- assert(mntdata)
- mounted = True
- assert(mntdata[-1] == '\0')
- mntpt = mntdata[:-1]
- assert(mntpt)
- if mounted:
- po = self.umount_l(mntpt)
- po.terminate_geterr(fail_on_err=False)
- if po.returncode != 0:
- po.errlog()
- rv = po.returncode
- self.cleanup_mntpt(mntpt)
- except:
- logging.exception('mount cleanup failure:')
- rv = 200
- os._exit(rv)
- logging.debug('auxiliary glusterfs mount prepared')
-
- class DirectMounter(Mounter):
-
- """mounter backend which calls mount(8), umount(8) directly"""
-
- mountkw = {'stderr': subprocess.PIPE}
- glusterprog = 'glusterfs'
-
- @staticmethod
- def make_umount_argv(d):
- return ['umount', '-l', d]
-
- def make_mount_argv(self):
- self.mntpt = tempfile.mkdtemp(prefix='gsyncd-aux-mount-')
- return [self.get_glusterprog()] + \
- ['--' + p for p in self.params] + [self.mntpt]
-
- def cleanup_mntpt(self, mntpt=None):
- if not mntpt:
- mntpt = self.mntpt
- os.rmdir(mntpt)
-
- class MountbrokerMounter(Mounter):
+ def __init__(self, host, volume):
+ self.path = "%s:%s" % (host, volume)
+ self.host = host
+ self.volume = volume
- """mounter backend using the mountbroker gluster service"""
-
- mountkw = {'stderr': subprocess.PIPE, 'stdout': subprocess.PIPE}
- glusterprog = 'gluster'
-
- @classmethod
- def make_cli_argv(cls):
- return [cls.get_glusterprog()] + ['--remote-host=localhost'] + \
- gconf.gluster_cli_options.split() + ['system::']
-
- @classmethod
- def make_umount_argv(cls, d):
- return cls.make_cli_argv() + ['umount', d, 'lazy']
-
- def make_mount_argv(self, label):
- return self.make_cli_argv() + \
- ['mount', label, 'user-map-root=' +
- syncdutils.getusername()] + self.params
-
- def handle_mounter(self, po):
- self.mntpt = po.stdout.readline()[:-1]
- po.stdout.close()
- sup(self, po)
- if po.returncode != 0:
- # if cli terminated with error due to being
- # refused by glusterd, what it put
- # out on stdout is a diagnostic message
- logging.error('glusterd answered: %s' % self.mntpt)
+ global slv_volume
+ global slv_host
+ slv_volume = self.volume
+ slv_host = self.host
def connect(self):
"""inhibit the resource beyond
@@ -1293,20 +1113,30 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
with given backend
"""
- label = getattr(gconf, 'mountbroker', None)
+ logging.info("Mounting gluster volume locally...")
+ t0 = time.time()
+ label = gconf.get('mountbroker', None)
if not label and not privileged():
label = syncdutils.getusername()
- mounter = label and self.MountbrokerMounter or self.DirectMounter
- params = gconf.gluster_params.split() + \
- (gconf.gluster_log_level and ['log-level=' +
- gconf.gluster_log_level] or []) + \
- ['log-file=' + gconf.gluster_log_file, 'volfile-server=' +
- self.host, 'volfile-id=' + self.volume, 'client-pid=-1']
- mounter(params).inhibit(*[l for l in [label] if l])
-
- def connect_remote(self, *a, **kw):
- sup(self, *a, **kw)
- self.slavedir = "/proc/%d/cwd" % self.server.pid()
+ mounter = label and MountbrokerMounter or DirectMounter
+
+ log_file = gconf.get("gluster-log-file")
+ if rconf.args.subcmd == "slave":
+ log_file = gconf.get("slave-gluster-log-file")
+
+ log_level = gconf.get("gluster-log-level")
+ if rconf.args.subcmd == "slave":
+ log_level = gconf.get("slave-gluster-log-level")
+
+ params = gconf.get("gluster-params").split() + \
+ ['log-level=' + log_level] + \
+ ['log-file=' + log_file, 'volfile-server=' + self.host] + \
+ ['volfile-id=' + self.volume, 'client-pid=-1']
+
+ self.mounter = mounter(params)
+ self.mounter.inhibit(label)
+ logging.info(lf("Mounted gluster volume",
+ duration="%.4f" % (time.time() - t0)))
def gmaster_instantiate_tuple(self, slave):
"""return a tuple of the 'one shot' and the 'main crawl'
@@ -1315,7 +1145,7 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
gmaster_builder()(self, slave),
gmaster_builder('changeloghistory')(self, slave))
- def service_loop(self, *args):
+ def service_loop(self, slave=None):
"""enter service loop
- if slave given, instantiate GMaster and
@@ -1323,146 +1153,173 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
master behavior
- else do that's what's inherited
"""
- if args:
- slave = args[0]
- if gconf.local_path:
- class brickserver(FILE.FILEServer):
- local_path = gconf.local_path
- aggregated = self.server
-
- @classmethod
- def entries(cls, path):
- e = super(brickserver, cls).entries(path)
- # on the brick don't mess with /.glusterfs
- if path == '.':
- try:
- e.remove('.glusterfs')
- e.remove('.trashcan')
- except ValueError:
- pass
- return e
-
- @classmethod
- def lstat(cls, e):
- """ path based backend stat """
- return super(brickserver, cls).lstat(e)
-
- @classmethod
- def gfid(cls, e):
- """ path based backend gfid fetch """
- return super(brickserver, cls).gfid(e)
-
- @classmethod
- def linkto_check(cls, e):
- return super(brickserver, cls).linkto_check(e)
- if gconf.slave_id:
- # define {,set_}xtime in slave, thus preempting
- # the call to remote, so that it takes data from
- # the local brick
- slave.server.xtime = types.MethodType(
- lambda _self, path, uuid: (
- brickserver.xtime(path,
- uuid + '.' + gconf.slave_id)
- ),
- slave.server)
- slave.server.stime = types.MethodType(
- lambda _self, path, uuid: (
- brickserver.stime(path,
- uuid + '.' + gconf.slave_id)
- ),
- slave.server)
- slave.server.set_stime = types.MethodType(
- lambda _self, path, uuid, mark: (
- brickserver.set_stime(path,
- uuid + '.' + gconf.slave_id,
- mark)
- ),
- slave.server)
- (g1, g2, g3) = self.gmaster_instantiate_tuple(slave)
- g1.master.server = brickserver
- g2.master.server = brickserver
- g3.master.server = brickserver
- else:
- (g1, g2, g3) = self.gmaster_instantiate_tuple(slave)
- g1.master.server.aggregated = gmaster.master.server
- g2.master.server.aggregated = gmaster.master.server
- g3.master.server.aggregated = gmaster.master.server
- # bad bad bad: bad way to do things like this
- # need to make this elegant
- # register the crawlers and start crawling
- # g1 ==> Xsync, g2 ==> config.change_detector(changelog by default)
- # g3 ==> changelog History
- changelog_register_failed = False
- (inf, ouf, ra, wa) = gconf.rpc_fd.split(',')
- os.close(int(ra))
- os.close(int(wa))
- changelog_agent = RepceClient(int(inf), int(ouf))
- status = GeorepStatus(gconf.state_file, gconf.local_path)
- status.reset_on_worker_start()
- rv = changelog_agent.version()
- if int(rv) != CHANGELOG_AGENT_CLIENT_VERSION:
+ if rconf.args.subcmd == "slave":
+ if gconf.get("use-rsync-xattrs") and not privileged():
raise GsyncdError(
- "RePCe major version mismatch(changelog agent): "
- "local %s, remote %s" %
- (CHANGELOG_AGENT_CLIENT_VERSION, rv))
+ "using rsync for extended attributes is not supported")
+
+ repce = RepceServer(
+ self.server, sys.stdin, sys.stdout, gconf.get("sync-jobs"))
+ t = syncdutils.Thread(target=lambda: (repce.service_loop(),
+ syncdutils.finalize()))
+ t.start()
+ logging.info("slave listening")
+ if gconf.get("slave-timeout") and gconf.get("slave-timeout") > 0:
+ while True:
+ lp = self.server.last_keep_alive
+ time.sleep(gconf.get("slave-timeout"))
+ if lp == self.server.last_keep_alive:
+ logging.info(
+ lf("connection inactive, stopping",
+ timeout=gconf.get("slave-timeout")))
+ break
+ else:
+ select((), (), ())
- try:
- workdir = g2.setup_working_dir()
- # Register only when change_detector is not set to
- # xsync, else agent will generate changelog files
- # in .processing directory of working dir
- if gconf.change_detector != 'xsync':
- # register with the changelog library
- # 9 == log level (DEBUG)
- # 5 == connection retries
- changelog_agent.init()
- changelog_agent.register(gconf.local_path,
- workdir, gconf.changelog_log_file,
- g2.CHANGELOG_LOG_LEVEL,
- g2.CHANGELOG_CONN_RETRIES)
-
- register_time = int(time.time())
- g2.register(register_time, changelog_agent, status)
- g3.register(register_time, changelog_agent, status)
- except ChangelogException as e:
- logging.error("Changelog register failed, %s" % e)
- sys.exit(1)
-
- g1.register(status=status)
- logging.info("Register time: %s" % register_time)
- # oneshot: Try to use changelog history api, if not
- # available switch to FS crawl
- # Note: if config.change_detector is xsync then
- # it will not use changelog history api
- try:
- g3.crawlwrap(oneshot=True)
- except PartialHistoryAvailable as e:
- logging.info('Partial history available, using xsync crawl'
- ' after consuming history till %s' % str(e))
- g1.crawlwrap(oneshot=True, register_time=register_time)
- except NoPurgeTimeAvailable:
- logging.info('No stime available, using xsync crawl')
- g1.crawlwrap(oneshot=True, register_time=register_time)
- except ChangelogException as e:
- logging.error("Changelog History Crawl failed, %s" % e)
- sys.exit(1)
+ return
- try:
- g2.crawlwrap()
- except ChangelogException as e:
- logging.error("Changelog crawl failed, %s" % e)
- sys.exit(1)
- else:
- sup(self, *args)
+ class brickserver(Server):
+ local_path = rconf.args.local_path
+ aggregated = self.server
+
+ @classmethod
+ def entries(cls, path):
+ e = super(brickserver, cls).entries(path)
+ # on the brick don't mess with /.glusterfs
+ if path == '.':
+ try:
+ e.remove('.glusterfs')
+ e.remove('.trashcan')
+ except ValueError:
+ pass
+ return e
+
+ @classmethod
+ def lstat(cls, e):
+ """ path based backend stat """
+ return super(brickserver, cls).lstat(e)
+
+ @classmethod
+ def gfid(cls, e):
+ """ path based backend gfid fetch """
+ return super(brickserver, cls).gfid(e)
+
+ @classmethod
+ def linkto_check(cls, e):
+ return super(brickserver, cls).linkto_check(e)
+
+ # define {,set_}xtime in slave, thus preempting
+ # the call to remote, so that it takes data from
+ # the local brick
+ slave.server.xtime = types.MethodType(
+ lambda _self, path, uuid: (
+ brickserver.xtime(path,
+ uuid + '.' + rconf.args.slave_id)
+ ),
+ slave.server)
+ slave.server.stime = types.MethodType(
+ lambda _self, path, uuid: (
+ brickserver.stime(path,
+ uuid + '.' + rconf.args.slave_id)
+ ),
+ slave.server)
+ slave.server.entry_stime = types.MethodType(
+ lambda _self, path, uuid: (
+ brickserver.entry_stime(
+ path,
+ uuid + '.' + rconf.args.slave_id)
+ ),
+ slave.server)
+ slave.server.set_stime = types.MethodType(
+ lambda _self, path, uuid, mark: (
+ brickserver.set_stime(path,
+ uuid + '.' + rconf.args.slave_id,
+ mark)
+ ),
+ slave.server)
+ slave.server.set_entry_stime = types.MethodType(
+ lambda _self, path, uuid, mark: (
+ brickserver.set_entry_stime(
+ path,
+ uuid + '.' + rconf.args.slave_id,
+ mark)
+ ),
+ slave.server)
+
+ (g1, g2, g3) = self.gmaster_instantiate_tuple(slave)
+ g1.master.server = brickserver
+ g2.master.server = brickserver
+ g3.master.server = brickserver
+
+ # bad bad bad: bad way to do things like this
+ # need to make this elegant
+ # register the crawlers and start crawling
+ # g1 ==> Xsync, g2 ==> config.change_detector(changelog by default)
+ # g3 ==> changelog History
+ status = GeorepStatus(gconf.get("state-file"),
+ rconf.args.local_node,
+ rconf.args.local_path,
+ rconf.args.local_node_id,
+ rconf.args.master,
+ rconf.args.slave)
+ status.reset_on_worker_start()
- def rsync(self, files):
- return sup(self, files, self.slavedir)
+ try:
+ workdir = g2.setup_working_dir()
+ # Register only when change_detector is not set to
+ # xsync, else agent will generate changelog files
+ # in .processing directory of working dir
+ if gconf.get("change-detector") != 'xsync':
+ # register with the changelog library
+ # 9 == log level (DEBUG)
+ # 5 == connection retries
+ libgfchangelog.register(rconf.args.local_path,
+ workdir,
+ gconf.get("changelog-log-file"),
+ get_changelog_log_level(
+ gconf.get("changelog-log-level")),
+ g2.CHANGELOG_CONN_RETRIES)
+
+ register_time = int(time.time())
+ g2.register(register_time, status)
+ g3.register(register_time, status)
+ except ChangelogException as e:
+ logging.error(lf("Changelog register failed", error=e))
+ sys.exit(1)
+
+ g1.register(status=status)
+ logging.info(lf("Register time",
+ time=register_time))
+ # oneshot: Try to use changelog history api, if not
+ # available switch to FS crawl
+ # Note: if config.change_detector is xsync then
+ # it will not use changelog history api
+ try:
+ g3.crawlwrap(oneshot=True)
+ except PartialHistoryAvailable as e:
+ logging.info(lf('Partial history available, using xsync crawl'
+ ' after consuming history',
+ till=e))
+ g1.crawlwrap(oneshot=True, register_time=register_time)
+ except ChangelogHistoryNotAvailable:
+ logging.info('Changelog history not available, using xsync')
+ g1.crawlwrap(oneshot=True, register_time=register_time)
+ except NoStimeAvailable:
+ logging.info('No stime available, using xsync crawl')
+ g1.crawlwrap(oneshot=True, register_time=register_time)
+ except ChangelogException as e:
+ logging.error(lf("Changelog History Crawl failed",
+ error=e))
+ sys.exit(1)
- def tarssh(self, files):
- return sup(self, files, self.slavedir)
+ try:
+ g2.crawlwrap()
+ except ChangelogException as e:
+ logging.error(lf("Changelog crawl failed", error=e))
+ sys.exit(1)
-class SSH(AbstractUrl, SlaveRemote):
+class SSH(object):
"""scheme class for ssh:// urls
@@ -1470,13 +1327,9 @@ class SSH(AbstractUrl, SlaveRemote):
implementing an ssh based proxy
"""
- def __init__(self, path):
- self.remote_addr, inner_url = sup(self, path,
- '^((?:%s@)?%s):(.+)' %
- tuple([r.pattern
- for r in (UserRX, HostRX)]))
- self.inner_rsc = parse_url(inner_url)
- self.volume = inner_url[1:]
+ def __init__(self, host, volume):
+ self.remote_addr = host
+ self.volume = volume
@staticmethod
def parse_ssh_address(self):
@@ -1488,35 +1341,28 @@ class SSH(AbstractUrl, SlaveRemote):
self.remotehost = h
return {'user': u, 'host': h}
- def canonical_path(self):
- rap = self.parse_ssh_address(self)
- remote_addr = '@'.join([rap['user'], gethostbyname(rap['host'])])
- return ':'.join([remote_addr, self.inner_rsc.get_url(canonical=True)])
-
- def can_connect_to(self, remote):
- """determine our position in the connectibility matrix"""
- return False
-
- def start_fd_client(self, *a, **opts):
- """customizations for client startup
+ def start_fd_client(self, i, o):
+ """set up RePCe client, handshake with server
- - be a no-op if we are to daemonize (client startup is deferred
- to post-daemon stage)
- - determine target url for rsync after consulting server
+ It's cut out as a separate method to let
+ subclasses hook into client startup
"""
- if opts.get('deferred'):
- return a
- sup(self, *a)
- ityp = type(self.inner_rsc)
- if ityp == FILE:
- slavepath = self.inner_rsc.path
- elif ityp == GLUSTER:
- slavepath = "/proc/%d/cwd" % self.server.pid()
- else:
- raise NotImplementedError
+ self.server = RepceClient(i, o)
+ rv = self.server.__version__()
+ exrv = {'proto': repce.repce_version, 'object': Server.version()}
+ da0 = (rv, exrv)
+ da1 = ({}, {})
+ for i in range(2):
+ for k, v in da0[i].items():
+ da1[i][k] = int(v)
+ if da1[0] != da1[1]:
+ raise GsyncdError(
+ "RePCe major version mismatch: local %s, remote %s" %
+ (exrv, rv))
+ slavepath = "/proc/%d/cwd" % self.server.pid()
self.slaveurl = ':'.join([self.remote_addr, slavepath])
- def connect_remote(self, go_daemon=None):
+ def connect_remote(self):
"""connect to inner slave url through outer ssh url
Wrap the connecting utility in ssh.
@@ -1534,41 +1380,204 @@ class SSH(AbstractUrl, SlaveRemote):
[NB. ATM gluster product does not makes use of interactive
authentication.]
"""
- if go_daemon == 'done':
- return self.start_fd_client(*self.fd_pair)
-
syncdutils.setup_ssh_ctl(tempfile.mkdtemp(prefix='gsyncd-aux-ssh-'),
self.remote_addr,
- self.inner_rsc.url)
-
- deferred = go_daemon == 'postconn'
- ret = sup(self, gconf.ssh_command.split() + gconf.ssh_ctl_args +
- [self.remote_addr],
- slave=self.inner_rsc.url, deferred=deferred)
-
- if deferred:
- # send a message to peer so that we can wait for
- # the answer from which we know connection is
- # established and we can proceed with daemonization
- # (doing that too early robs the ssh passwd prompt...)
- # However, we'd better not start the RepceClient
- # before daemonization (that's not preserved properly
- # in daemon), we just do a an ad-hoc linear put/get.
- i, o = ret
- inf = os.fdopen(i)
- repce.send(o, None, '__repce_version__')
- select((inf,), (), ())
- repce.recv(inf)
- # hack hack hack: store a global reference to the file
- # to save it from getting GC'd which implies closing it
- gconf.permanent_handles.append(inf)
- self.fd_pair = (i, o)
- return 'should'
-
- def rsync(self, files):
- return sup(self, files, '-e',
- " ".join(gconf.ssh_command.split() + gconf.ssh_ctl_args),
- *(gconf.rsync_ssh_options.split() + [self.slaveurl]))
-
- def tarssh(self, files):
- return sup(self, files, self.slaveurl)
+ self.volume)
+
+ logging.info("Initializing SSH connection between master and slave...")
+ t0 = time.time()
+
+ extra_opts = []
+ remote_gsyncd = gconf.get("remote-gsyncd")
+ if remote_gsyncd == "":
+ remote_gsyncd = "/nonexistent/gsyncd"
+
+ if gconf.get("use-rsync-xattrs"):
+ extra_opts.append('--use-rsync-xattrs')
+
+ args_to_slave = [gconf.get("ssh-command")] + \
+ gconf.get("ssh-options").split() + \
+ ["-p", str(gconf.get("ssh-port"))] + \
+ rconf.ssh_ctl_args + [self.remote_addr] + \
+ [remote_gsyncd, "slave"] + \
+ extra_opts + \
+ [rconf.args.master, rconf.args.slave] + \
+ [
+ '--master-node', rconf.args.local_node,
+ '--master-node-id', rconf.args.local_node_id,
+ '--master-brick', rconf.args.local_path,
+ '--local-node', rconf.args.resource_remote,
+ '--local-node-id', rconf.args.resource_remote_id] + \
+ [
+ # Add all config arguments here, slave gsyncd will not use
+ # config file in slave side, so all overriding options should
+ # be sent as arguments
+ '--slave-timeout', str(gconf.get("slave-timeout")),
+ '--slave-log-level', gconf.get("slave-log-level"),
+ '--slave-gluster-log-level',
+ gconf.get("slave-gluster-log-level"),
+ '--slave-gluster-command-dir',
+ gconf.get("slave-gluster-command-dir"),
+ '--master-dist-count',
+ str(gconf.get("master-distribution-count"))]
+
+ if gconf.get("slave-access-mount"):
+ args_to_slave.append('--slave-access-mount')
+
+ if rconf.args.debug:
+ args_to_slave.append('--debug')
+
+ po = Popen(args_to_slave,
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ rconf.transport = po
+ self.start_fd_client(po.stdout, po.stdin)
+ logging.info(lf("SSH connection between master and slave established.",
+ duration="%.4f" % (time.time() - t0)))
+
+ def rsync(self, files, *args, **kw):
+ """invoke rsync"""
+ if not files:
+ raise GsyncdError("no files to sync")
+ logging.debug("files: " + ", ".join(files))
+
+ extra_rsync_flags = []
+ # Performance flag, --ignore-missing-args, if rsync version is
+ # greater than 3.1.0 then include this flag.
+ if gconf.get("rsync-opt-ignore-missing-args") and \
+ get_rsync_version(gconf.get("rsync-command")) >= "3.1.0":
+ extra_rsync_flags = ["--ignore-missing-args"]
+
+ rsync_ssh_opts = [gconf.get("ssh-command")] + \
+ gconf.get("ssh-options").split() + \
+ ["-p", str(gconf.get("ssh-port"))] + \
+ rconf.ssh_ctl_args + \
+ gconf.get("rsync-ssh-options").split()
+
+ argv = [
+ gconf.get("rsync-command"),
+ '-aR0',
+ '--inplace',
+ '--files-from=-',
+ '--super',
+ '--stats',
+ '--numeric-ids',
+ '--no-implied-dirs'
+ ]
+
+ if gconf.get("rsync-opt-existing"):
+ argv += ["--existing"]
+
+ if gconf.get("sync-xattrs"):
+ argv += ['--xattrs']
+
+ if gconf.get("sync-acls"):
+ argv += ['--acls']
+
+ argv = argv + \
+ gconf.get("rsync-options").split() + \
+ extra_rsync_flags + ['.'] + \
+ ["-e", " ".join(rsync_ssh_opts)] + \
+ [self.slaveurl]
+
+ log_rsync_performance = gconf.getr("log-rsync-performance", False)
+
+ if log_rsync_performance:
+ # use stdout=PIPE only when log_rsync_performance enabled
+ # Else rsync will write to stdout and nobody is there
+ # to consume. If PIPE is full rsync hangs.
+ po = Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, universal_newlines=True)
+ else:
+ po = Popen(argv, stdin=subprocess.PIPE, stderr=subprocess.PIPE,
+ universal_newlines=True)
+
+ for f in files:
+ po.stdin.write(f)
+ po.stdin.write('\0')
+
+ stdout, stderr = po.communicate()
+
+ if kw.get("log_err", False):
+ for errline in stderr.strip().split("\n")[:-1]:
+ logging.error(lf("SYNC Error",
+ sync_engine="Rsync",
+ error=errline))
+
+ if log_rsync_performance:
+ rsync_msg = []
+ for line in stdout.split("\n"):
+ if line.startswith("Number of files:") or \
+ line.startswith("Number of regular files transferred:") or \
+ line.startswith("Total file size:") or \
+ line.startswith("Total transferred file size:") or \
+ line.startswith("Literal data:") or \
+ line.startswith("Matched data:") or \
+ line.startswith("Total bytes sent:") or \
+ line.startswith("Total bytes received:") or \
+ line.startswith("sent "):
+ rsync_msg.append(line)
+ logging.info(lf("rsync performance",
+ data=", ".join(rsync_msg)))
+
+ return po
+
+ def tarssh(self, files, log_err=False):
+ """invoke tar+ssh
+ -z (compress) can be use if needed, but omitting it now
+ as it results in weird error (tar+ssh errors out (errcode: 2)
+ """
+ if not files:
+ raise GsyncdError("no files to sync")
+ logging.debug("files: " + ", ".join(files))
+ (host, rdir) = self.slaveurl.split(':')
+
+ tar_cmd = ["tar"] + \
+ ["--sparse", "-cf", "-", "--files-from", "-"]
+ ssh_cmd = gconf.get("ssh-command").split() + \
+ gconf.get("ssh-options-tar").split() + \
+ ["-p", str(gconf.get("ssh-port"))] + \
+ [host, "tar"] + \
+ ["--overwrite", "-xf", "-", "-C", rdir]
+ p0 = Popen(tar_cmd, stdout=subprocess.PIPE,
+ stdin=subprocess.PIPE, stderr=subprocess.PIPE,
+ universal_newlines=True)
+ p1 = Popen(ssh_cmd, stdin=p0.stdout, stderr=subprocess.PIPE,
+ universal_newlines=True)
+ for f in files:
+ p0.stdin.write(f)
+ p0.stdin.write('\n')
+
+ p0.stdin.close()
+ p0.stdout.close() # Allow p0 to receive a SIGPIPE if p1 exits.
+
+ # stdin and stdout of p0 is already closed, Reset to None and
+ # wait for child process to complete
+ p0.stdin = None
+ p0.stdout = None
+
+ def wait_for_tar(p0):
+ _, stderr = p0.communicate()
+ if log_err:
+ for errline in stderr.strip().split("\n")[:-1]:
+ if "No such file or directory" not in errline:
+ logging.error(lf("SYNC Error",
+ sync_engine="Tarssh",
+ error=errline))
+
+ t = syncdutils.Thread(target=wait_for_tar, args=(p0, ))
+ # wait for tar to terminate, collecting any errors, further
+ # waiting for transfer to complete
+ t.start()
+
+ # wait for ssh process
+ _, stderr1 = p1.communicate()
+ t.join()
+
+ if log_err:
+ for errline in stderr1.strip().split("\n")[:-1]:
+ logging.error(lf("SYNC Error",
+ sync_engine="Tarssh",
+ error=errline))
+
+ return p1
diff --git a/geo-replication/syncdaemon/subcmds.py b/geo-replication/syncdaemon/subcmds.py
new file mode 100644
index 00000000000..b8508532e30
--- /dev/null
+++ b/geo-replication/syncdaemon/subcmds.py
@@ -0,0 +1,335 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016 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.
+#
+
+from __future__ import print_function
+from syncdutils import lf
+import logging
+import gsyncdconfig as gconf
+
+
+ERROR_CONFIG_INVALID = 2
+ERROR_CONFIG_INVALID_VALUE = 3
+ERROR_CONFIG_NOT_CONFIGURABLE = 4
+
+
+def subcmd_monitor_status(args):
+ from gsyncdstatus import set_monitor_status
+ from rconf import rconf
+
+ set_monitor_status(gconf.get("state-file"), args.status)
+ rconf.log_exit = False
+ logging.info(lf("Monitor Status Change", status=args.status))
+
+
+def subcmd_status(args):
+ from gsyncdstatus import GeorepStatus
+
+ master_name = args.master.replace(":", "")
+ slave_data = args.slave.replace("ssh://", "")
+
+ brick_status = GeorepStatus(gconf.get("state-file"),
+ "",
+ args.local_path,
+ "",
+ master_name,
+ slave_data,
+ gconf.get("pid-file"))
+ checkpoint_time = gconf.get("checkpoint", 0)
+ brick_status.print_status(checkpoint_time=checkpoint_time,
+ json_output=args.json)
+
+
+def subcmd_monitor(args):
+ import monitor
+ from resource import GLUSTER, SSH, Popen
+ go_daemon = False if args.debug else True
+
+ monitor.startup(go_daemon)
+ Popen.init_errhandler()
+ local = GLUSTER("localhost", args.master)
+ slavehost, slavevol = args.slave.split("::")
+ remote = SSH(slavehost, slavevol)
+ return monitor.monitor(local, remote)
+
+
+def subcmd_verify_spawning(args):
+ logging.info("Able to spawn gsyncd.py")
+
+
+def subcmd_worker(args):
+ import os
+ import fcntl
+
+ from resource import GLUSTER, SSH, Popen
+
+ Popen.init_errhandler()
+ fcntl.fcntl(args.feedback_fd, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
+ local = GLUSTER("localhost", args.master)
+ slave_url, slavevol = args.slave.split("::")
+ if "@" not in slave_url:
+ slavehost = args.resource_remote
+ else:
+ slavehost = "%s@%s" % (slave_url.split("@")[0], args.resource_remote)
+ remote = SSH(slavehost, slavevol)
+ remote.connect_remote()
+ local.connect()
+ logging.info("Worker spawn successful. Acknowledging back to monitor")
+ os.close(args.feedback_fd)
+ local.service_loop(remote)
+
+
+def subcmd_slave(args):
+ from resource import GLUSTER, Popen
+
+ Popen.init_errhandler()
+ slavevol = args.slave.split("::")[-1]
+ local = GLUSTER("localhost", slavevol)
+
+ local.connect()
+ local.service_loop()
+
+
+def subcmd_voluuidget(args):
+ from subprocess import Popen, PIPE
+ import xml.etree.ElementTree as XET
+
+ ParseError = XET.ParseError if hasattr(XET, 'ParseError') else SyntaxError
+
+ cmd = ['gluster', '--xml', '--remote-host=' + args.host,
+ 'volume', 'info', args.volname]
+
+ if args.inet6:
+ cmd.append("--inet6")
+
+ po = Popen(cmd, bufsize=0,
+ stdin=None, stdout=PIPE, stderr=PIPE,
+ universal_newlines=True)
+
+ vix, err = po.communicate()
+ if po.returncode != 0:
+ logging.info(lf("Volume info failed, unable to get "
+ "volume uuid of slavevol, "
+ "returning empty string",
+ slavevol=args.volname,
+ slavehost=args.host,
+ error=po.returncode))
+ return ""
+ vi = XET.fromstring(vix)
+ if vi.find('opRet').text != '0':
+ logging.info(lf("Unable to get volume uuid of slavevol, "
+ "returning empty string",
+ slavevol=args.volname,
+ slavehost=args.host,
+ error=vi.find('opErrstr').text))
+ return ""
+
+ try:
+ voluuid = vi.find("volInfo/volumes/volume/id").text
+ except (ParseError, AttributeError, ValueError) as e:
+ logging.info(lf("Parsing failed to volume uuid of slavevol, "
+ "returning empty string",
+ slavevol=args.volname,
+ slavehost=args.host,
+ error=e))
+ voluuid = ""
+
+ print(voluuid)
+
+
+def _unlink(path):
+ import os
+ from errno import ENOENT
+ from syncdutils import GsyncdError
+ import sys
+
+ try:
+ os.unlink(path)
+ except (OSError, IOError):
+ if sys.exc_info()[1].errno == ENOENT:
+ pass
+ else:
+ raise GsyncdError('Unlink error: %s' % path)
+
+
+def subcmd_delete(args):
+ import logging
+ import shutil
+ import glob
+ import sys
+ from errno import ENOENT, ENODATA
+ import struct
+
+ from syncdutils import GsyncdError, Xattr, errno_wrap
+ import gsyncdconfig as gconf
+
+ logging.info('geo-replication delete')
+ # remove the stime xattr from all the brick paths so that
+ # a re-create of a session will start sync all over again
+ stime_xattr_prefix = gconf.get('stime-xattr-prefix', None)
+
+ # Delete pid file, status file, socket file
+ cleanup_paths = []
+ cleanup_paths.append(gconf.get("pid-file"))
+
+ # Cleanup Session dir
+ try:
+ shutil.rmtree(gconf.get("georep-session-working-dir"))
+ except (IOError, OSError):
+ if sys.exc_info()[1].errno == ENOENT:
+ pass
+ else:
+ raise GsyncdError(
+ 'Error while removing working dir: %s' %
+ gconf.get("georep-session-working-dir"))
+
+ # Cleanup changelog working dirs
+ try:
+ shutil.rmtree(gconf.get("working-dir"))
+ except (IOError, OSError):
+ if sys.exc_info()[1].errno == ENOENT:
+ pass
+ else:
+ raise GsyncdError(
+ 'Error while removing working dir: %s' %
+ gconf.get("working-dir"))
+
+ for path in cleanup_paths:
+ # To delete temp files
+ for f in glob.glob(path + "*"):
+ _unlink(f)
+
+ if args.reset_sync_time and stime_xattr_prefix:
+ for p in args.paths:
+ if p != "":
+ # set stime to (0,0) to trigger full volume content resync
+ # to slave on session recreation
+ # look at master.py::Xcrawl hint: zero_zero
+ errno_wrap(Xattr.lsetxattr,
+ (p, stime_xattr_prefix + ".stime",
+ struct.pack("!II", 0, 0)),
+ [ENOENT, ENODATA])
+ errno_wrap(Xattr.lremovexattr,
+ (p, stime_xattr_prefix + ".entry_stime"),
+ [ENOENT, ENODATA])
+
+ return
+
+
+def print_config(name, value, only_value=False, use_underscore=False):
+ val = value
+ if isinstance(value, bool):
+ val = str(value).lower()
+
+ if only_value:
+ print(val)
+ else:
+ if use_underscore:
+ name = name.replace("-", "_")
+
+ print(("%s:%s" % (name, val)))
+
+
+def config_name_format(val):
+ return val.replace("_", "-")
+
+
+def subcmd_config_get(args):
+ import sys
+ import json
+
+ all_config = gconf.getall(show_defaults=args.show_defaults,
+ show_non_configurable=True)
+ if args.name is not None:
+ val = all_config.get(config_name_format(args.name), None)
+ if val is None:
+ sys.stderr.write("Invalid config name \"%s\"\n" % args.name)
+ sys.exit(ERROR_CONFIG_INVALID)
+
+ print_config(args.name, val["value"], only_value=args.only_value,
+ use_underscore=args.use_underscore)
+ return
+
+ if args.json:
+ out = []
+ # Convert all values as string
+ for k in sorted(all_config):
+ v = all_config[k]
+ out.append({
+ "name": k,
+ "value": str(v["value"]),
+ "default": str(v["default"]),
+ "configurable": v["configurable"],
+ "modified": v["modified"]
+ })
+
+ print((json.dumps(out)))
+ return
+
+ for k in sorted(all_config):
+ print_config(k, all_config[k]["value"],
+ use_underscore=args.use_underscore)
+
+
+def subcmd_config_check(args):
+ import sys
+
+ try:
+ gconf.check(config_name_format(args.name), value=args.value,
+ with_conffile=False)
+ except gconf.GconfNotConfigurable:
+ cnf_val = gconf.get(config_name_format(args.name), None)
+ if cnf_val is None:
+ sys.stderr.write("Invalid config name \"%s\"\n" % args.name)
+ sys.exit(ERROR_CONFIG_INVALID)
+
+ # Not configurable
+ sys.stderr.write("Not configurable \"%s\"\n" % args.name)
+ sys.exit(ERROR_CONFIG_NOT_CONFIGURABLE)
+ except gconf.GconfInvalidValue:
+ sys.stderr.write("Invalid config value \"%s=%s\"\n" % (args.name,
+ args.value))
+ sys.exit(ERROR_CONFIG_INVALID_VALUE)
+
+
+def subcmd_config_set(args):
+ import sys
+
+ try:
+ gconf.setconfig(config_name_format(args.name), args.value)
+ except gconf.GconfNotConfigurable:
+ cnf_val = gconf.get(config_name_format(args.name), None)
+ if cnf_val is None:
+ sys.stderr.write("Invalid config name \"%s\"\n" % args.name)
+ sys.exit(ERROR_CONFIG_INVALID)
+
+ # Not configurable
+ sys.stderr.write("Not configurable \"%s\"\n" % args.name)
+ sys.exit(ERROR_CONFIG_NOT_CONFIGURABLE)
+ except gconf.GconfInvalidValue:
+ sys.stderr.write("Invalid config value \"%s=%s\"\n" % (args.name,
+ args.value))
+ sys.exit(ERROR_CONFIG_INVALID_VALUE)
+
+
+def subcmd_config_reset(args):
+ import sys
+
+ try:
+ gconf.resetconfig(config_name_format(args.name))
+ except gconf.GconfNotConfigurable:
+ cnf_val = gconf.get(config_name_format(args.name), None)
+ if cnf_val is None:
+ sys.stderr.write("Invalid config name \"%s\"\n" % args.name)
+ sys.exit(ERROR_CONFIG_INVALID)
+
+ # Not configurable
+ sys.stderr.write("Not configurable \"%s\"\n" % args.name)
+ sys.exit(ERROR_CONFIG_NOT_CONFIGURABLE)
diff --git a/geo-replication/syncdaemon/syncdutils.py b/geo-replication/syncdaemon/syncdutils.py
index 3feadb83f32..a3df103e76c 100644
--- a/geo-replication/syncdaemon/syncdutils.py
+++ b/geo-replication/syncdaemon/syncdutils.py
@@ -15,52 +15,104 @@ import time
import fcntl
import shutil
import logging
+import errno
+import threading
+import subprocess
import socket
+from subprocess import PIPE
from threading import Lock, Thread as baseThread
-from errno import EACCES, EAGAIN, EPIPE, ENOTCONN, ECONNABORTED
-from errno import EINTR, ENOENT, EPERM, ESTALE, errorcode
+from errno import (EACCES, EAGAIN, EPIPE, ENOTCONN, ENOMEM, ECONNABORTED,
+ EINTR, ENOENT, ESTALE, EBUSY, ENODATA, errorcode, EIO)
from signal import signal, SIGTERM
import select as oselect
from os import waitpid as owaitpid
-
+import xml.etree.ElementTree as XET
+from select import error as SelectError
try:
from cPickle import PickleError
except ImportError:
- # py 3
from pickle import PickleError
-from gconf import gconf
-
+from conf import GLUSTERFS_LIBEXECDIR, UUID_FILE
+sys.path.insert(1, GLUSTERFS_LIBEXECDIR)
+EVENTS_ENABLED = True
try:
- # py 3
- from urllib import parse as urllib
+ from gfevents.eventtypes import GEOREP_FAULTY as EVENT_GEOREP_FAULTY
+ from gfevents.eventtypes import GEOREP_ACTIVE as EVENT_GEOREP_ACTIVE
+ from gfevents.eventtypes import GEOREP_PASSIVE as EVENT_GEOREP_PASSIVE
+ from gfevents.eventtypes import GEOREP_CHECKPOINT_COMPLETED \
+ as EVENT_GEOREP_CHECKPOINT_COMPLETED
except ImportError:
- import urllib
+ # Events APIs not installed, dummy eventtypes with None
+ EVENTS_ENABLED = False
+ EVENT_GEOREP_FAULTY = None
+ EVENT_GEOREP_ACTIVE = None
+ EVENT_GEOREP_PASSIVE = None
+ EVENT_GEOREP_CHECKPOINT_COMPLETED = None
-try:
- from hashlib import md5 as md5
-except ImportError:
- # py 2.4
- from md5 import new as md5
+import gsyncdconfig as gconf
+from rconf import rconf
+
+from hashlib import sha256 as sha256
+
+ENOTSUP = getattr(errno, 'ENOTSUP', 'EOPNOTSUPP')
# auxiliary gfid based access prefix
_CL_AUX_GFID_PFX = ".gfid/"
-GF_OP_RETRIES = 20
+ROOT_GFID = "00000000-0000-0000-0000-000000000001"
+GF_OP_RETRIES = 10
-CHANGELOG_AGENT_SERVER_VERSION = 1.0
-CHANGELOG_AGENT_CLIENT_VERSION = 1.0
+GX_GFID_CANONICAL_LEN = 37 # canonical gfid len + '\0'
+
+NodeID = None
+rsync_version = None
+unshare_mnt_propagation = None
+slv_bricks = None
+SPACE_ESCAPE_CHAR = "%20"
+NEWLINE_ESCAPE_CHAR = "%0A"
+PERCENTAGE_ESCAPE_CHAR = "%25"
+
+final_lock = Lock()
+
+def sup(x, *a, **kw):
+ """a rubyesque "super" for python ;)
+
+ invoke caller method in parent class with given args.
+ """
+ return getattr(super(type(x), x),
+ sys._getframe(1).f_code.co_name)(*a, **kw)
def escape(s):
"""the chosen flavor of string escaping, used all over
to turn whatever data to creatable representation"""
- return urllib.quote_plus(s)
+ return s.replace("/", "-").strip("-")
+
+
+def escape_space_newline(s):
+ return s.replace("%", PERCENTAGE_ESCAPE_CHAR)\
+ .replace(" ", SPACE_ESCAPE_CHAR)\
+ .replace("\n", NEWLINE_ESCAPE_CHAR)
+
+def unescape_space_newline(s):
+ return s.replace(SPACE_ESCAPE_CHAR, " ")\
+ .replace(NEWLINE_ESCAPE_CHAR, "\n")\
+ .replace(PERCENTAGE_ESCAPE_CHAR, "%")
-def unescape(s):
- """inverse of .escape"""
- return urllib.unquote_plus(s)
+# gf_mount_ready() returns 1 if all subvols are up, else 0
+def gf_mount_ready():
+ ret = errno_wrap(Xattr.lgetxattr,
+ ['.', 'dht.subvol.status', 16],
+ [ENOENT, ENOTSUP, ENODATA], [ENOMEM])
+ if isinstance(ret, int):
+ logging.error("failed to get the xattr value")
+ return 1
+ ret = ret.rstrip('\x00')
+ if ret == "1":
+ return 1
+ return 0
def norm(s):
if s:
@@ -119,17 +171,26 @@ def setup_ssh_ctl(ctld, remote_addr, resource_url):
"""
Setup GConf ssh control path parameters
"""
- gconf.ssh_ctl_dir = ctld
+ rconf.ssh_ctl_dir = ctld
content = "SLAVE_HOST=%s\nSLAVE_RESOURCE_URL=%s" % (remote_addr,
resource_url)
- content_md5 = md5hex(content)
- fname = os.path.join(gconf.ssh_ctl_dir,
- "%s.mft" % content_md5)
+ encoded_content = content.encode()
+ content_sha256 = sha256hex(encoded_content)
+ """
+ The length of ctl_path for ssh connection should not be > 108.
+ ssh fails with ctl_path too long if it is so. But when rsync
+ is piped to ssh, it is not taking > 90. Hence using first 32
+ bytes of hash. Hash collision doesn't matter as only one sock
+ file is created per directory.
+ """
+ content_sha256 = content_sha256[:32]
+ fname = os.path.join(rconf.ssh_ctl_dir,
+ "%s.mft" % content_sha256)
- create_manifest(fname, content)
- ssh_ctl_path = os.path.join(gconf.ssh_ctl_dir,
- "%s.sock" % content_md5)
- gconf.ssh_ctl_args = ["-oControlMaster=auto", "-S", ssh_ctl_path]
+ create_manifest(fname, encoded_content)
+ ssh_ctl_path = os.path.join(rconf.ssh_ctl_dir,
+ "%s.sock" % content_sha256)
+ rconf.ssh_ctl_args = ["-oControlMaster=auto", "-S", ssh_ctl_path]
def grabfile(fname, content=None):
@@ -139,7 +200,7 @@ def grabfile(fname, content=None):
"""
# damn those messy open() mode codes
fd = os.open(fname, os.O_CREAT | os.O_RDWR)
- f = os.fdopen(fd, 'r+b', 0)
+ f = os.fdopen(fd, 'r+')
try:
fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
except:
@@ -153,34 +214,34 @@ def grabfile(fname, content=None):
try:
f.truncate()
f.write(content)
+ f.flush()
except:
f.close()
raise
- gconf.permanent_handles.append(f)
+ rconf.permanent_handles.append(f)
return f
def grabpidfile(fname=None, setpid=True):
""".grabfile customization for pid files"""
if not fname:
- fname = gconf.pid_file
+ fname = gconf.get("pid-file")
content = None
if setpid:
content = str(os.getpid()) + '\n'
return grabfile(fname, content=content)
-final_lock = Lock()
-
-def finalize(*a, **kw):
+def finalize(*args, **kwargs):
"""all those messy final steps we go trough upon termination
Do away with pidfile, ssh control dir and logging.
"""
+
final_lock.acquire()
- if getattr(gconf, 'pid_file', None):
- rm_pidf = gconf.pid_file_owned
- if gconf.cpid:
+ if gconf.get('pid_file'):
+ rm_pidf = rconf.pid_file_owned
+ if rconf.cpid:
# exit path from parent branch of daemonization
rm_pidf = False
while True:
@@ -188,39 +249,50 @@ def finalize(*a, **kw):
if not f:
# child has already taken over pidfile
break
- if os.waitpid(gconf.cpid, os.WNOHANG)[0] == gconf.cpid:
+ if os.waitpid(rconf.cpid, os.WNOHANG)[0] == rconf.cpid:
# child has terminated
rm_pidf = True
break
time.sleep(0.1)
if rm_pidf:
try:
- os.unlink(gconf.pid_file)
+ os.unlink(rconf.pid_file)
except:
ex = sys.exc_info()[1]
if ex.errno == ENOENT:
pass
else:
raise
- if gconf.ssh_ctl_dir and not gconf.cpid:
+ if rconf.ssh_ctl_dir and not rconf.cpid:
def handle_rm_error(func, path, exc_info):
if exc_info[1].errno == ENOENT:
return
raise exc_info[1]
- shutil.rmtree(gconf.ssh_ctl_dir, onerror=handle_rm_error)
- if getattr(gconf, 'state_socket', None):
- try:
- os.unlink(gconf.state_socket)
- except:
- if sys.exc_info()[0] == OSError:
+ shutil.rmtree(rconf.ssh_ctl_dir, onerror=handle_rm_error)
+
+ """ Unmount if not done """
+ if rconf.mount_point:
+ if rconf.mountbroker:
+ umount_cmd = rconf.mbr_umount_cmd + [rconf.mount_point, 'lazy']
+ else:
+ umount_cmd = ['umount', '-l', rconf.mount_point]
+ p0 = subprocess.Popen(umount_cmd, stderr=subprocess.PIPE,
+ universal_newlines=True)
+ _, errdata = p0.communicate()
+ if p0.returncode == 0:
+ try:
+ os.rmdir(rconf.mount_point)
+ except OSError:
pass
+ else:
+ pass
- if gconf.log_exit:
+ if rconf.log_exit:
logging.info("exiting.")
sys.stdout.flush()
sys.stderr.flush()
- os._exit(kw.get('exval', 0))
+ os._exit(kwargs.get('exval', 0))
def log_raise_exception(excont):
@@ -230,6 +302,7 @@ def log_raise_exception(excont):
Translate some weird sounding but well understood exceptions
into human-friendly lingo
"""
+
is_filelog = False
for h in logging.getLogger().handlers:
fno = getattr(getattr(h, 'stream', None), 'fileno', None)
@@ -250,31 +323,45 @@ def log_raise_exception(excont):
((isinstance(exc, OSError) or isinstance(exc, IOError)) and
exc.errno == EPIPE):
logging.error('connection to peer is broken')
- if hasattr(gconf, 'transport'):
- gconf.transport.wait()
- if gconf.transport.returncode == 127:
- logging.warn("!!!!!!!!!!!!!")
- logging.warn('!!! getting "No such file or directory" '
- "errors is most likely due to "
- "MISCONFIGURATION"
- ", please consult https://access.redhat.com"
- "/site/documentation/en-US/Red_Hat_Storage"
- "/2.1/html/Administration_Guide"
- "/chap-User_Guide-Geo_Rep-Preparation-"
- "Settingup_Environment.html")
- logging.warn("!!!!!!!!!!!!!")
- gconf.transport.terminate_geterr()
+ if hasattr(rconf, 'transport'):
+ rconf.transport.wait()
+ if rconf.transport.returncode == 127:
+ logging.error("getting \"No such file or directory\""
+ "errors is most likely due to "
+ "MISCONFIGURATION, please remove all "
+ "the public keys added by geo-replication "
+ "from authorized_keys file in slave nodes "
+ "and run Geo-replication create "
+ "command again.")
+ logging.error("If `gsec_create container` was used, then "
+ "run `gluster volume geo-replication "
+ "<MASTERVOL> [<SLAVEUSER>@]<SLAVEHOST>::"
+ "<SLAVEVOL> config remote-gsyncd "
+ "<GSYNCD_PATH> (Example GSYNCD_PATH: "
+ "`/usr/libexec/glusterfs/gsyncd`)")
+ rconf.transport.terminate_geterr()
elif isinstance(exc, OSError) and exc.errno in (ENOTCONN,
ECONNABORTED):
- logging.error('glusterfs session went down [%s]',
- errorcode[exc.errno])
+ logging.error(lf('Gluster Mount process exited',
+ error=errorcode[exc.errno]))
+ elif isinstance(exc, OSError) and exc.errno == EIO:
+ logging.error("Getting \"Input/Output error\" "
+ "is most likely due to "
+ "a. Brick is down or "
+ "b. Split brain issue.")
+ logging.error("This is expected as per design to "
+ "keep the consistency of the file system. "
+ "Once the above issue is resolved "
+ "geo-replication would automatically "
+ "proceed further.")
+ logtag = "FAIL"
else:
logtag = "FAIL"
if not logtag and logging.getLogger().isEnabledFor(logging.DEBUG):
logtag = "FULL EXCEPTION TRACE"
if logtag:
logging.exception(logtag + ": ")
- sys.stderr.write("failed with %s.\n" % type(exc).__name__)
+ sys.stderr.write("failed with %s: %s.\n" % (type(exc).__name__, exc))
excont.exval = 1
sys.exit(excont.exval)
@@ -297,20 +384,20 @@ class Thread(baseThread):
function coughs up an exception
"""
- def __init__(self, *a, **kw):
- tf = kw.get('target')
+ def __init__(self, *args, **kwargs):
+ tf = kwargs.get('target')
if tf:
- def twrap(*aa):
+ def twrap(*aargs):
excont = FreeObject(exval=0)
try:
- tf(*aa)
+ tf(*aargs)
except:
try:
log_raise_exception(excont)
finally:
finalize(exval=excont.exval)
- kw['target'] = twrap
- baseThread.__init__(self, *a, **kw)
+ kwargs['target'] = twrap
+ baseThread.__init__(self, *args, **kwargs)
self.setDaemon(True)
@@ -318,6 +405,33 @@ class GsyncdError(Exception):
pass
+class _MetaXattr(object):
+
+ """singleton class, a lazy wrapper around the
+ libcxattr module
+
+ libcxattr (a heavy import due to ctypes) is
+ loaded only when when the single
+ instance is tried to be used.
+
+ This reduces runtime for those invocations
+ which do not need filesystem manipulation
+ (eg. for config, url parsing)
+ """
+
+ def __getattr__(self, meth):
+ from libcxattr import Xattr as LXattr
+ xmeth = [m for m in dir(LXattr) if m[0] != '_']
+ if meth not in xmeth:
+ return
+ for m in xmeth:
+ setattr(self, m, getattr(LXattr, m))
+ return getattr(self, meth)
+
+
+Xattr = _MetaXattr()
+
+
def getusername(uid=None):
if uid is None:
uid = os.geteuid()
@@ -348,81 +462,63 @@ def boolify(s):
lstr = s.lower()
if lstr in true_list:
rv = True
- elif not lstr in false_list:
- logging.warn("Unknown string (%s) in string to boolean conversion "
- "defaulting to False\n" % (s))
+ elif lstr not in false_list:
+ logging.warn(lf("Unknown string in \"string to boolean\" conversion, "
+ "defaulting to False",
+ str=s))
return rv
-def eintr_wrap(func, exc, *a):
+def eintr_wrap(func, exc, *args):
"""
wrapper around syscalls resilient to interrupt caused
by signals
"""
while True:
try:
- return func(*a)
+ return func(*args)
except exc:
ex = sys.exc_info()[1]
if not ex.args[0] == EINTR:
raise
-def select(*a):
- return eintr_wrap(oselect.select, oselect.error, *a)
+def select(*args):
+ return eintr_wrap(oselect.select, oselect.error, *args)
+
+
+def waitpid(*args):
+ return eintr_wrap(owaitpid, OSError, *args)
-def waitpid(*a):
- return eintr_wrap(owaitpid, OSError, *a)
+def term_handler_default_hook(signum, frame):
+ finalize(signum, frame, exval=1)
-def set_term_handler(hook=lambda *a: finalize(*a, **{'exval': 1})):
+def set_term_handler(hook=term_handler_default_hook):
signal(SIGTERM, hook)
-def is_host_local(host):
- locaddr = False
- for ai in socket.getaddrinfo(host, None):
- # cf. http://github.com/gluster/glusterfs/blob/ce111f47/xlators
- # /mgmt/glusterd/src/glusterd-utils.c#L125
- if ai[0] == socket.AF_INET:
- if ai[-1][0].split(".")[0] == "127":
- locaddr = True
- break
- elif ai[0] == socket.AF_INET6:
- if ai[-1][0] == "::1":
- locaddr = True
+def get_node_uuid():
+ global NodeID
+ if NodeID is not None:
+ return NodeID
+
+ NodeID = ""
+ with open(UUID_FILE) as f:
+ for line in f:
+ if line.startswith("UUID="):
+ NodeID = line.strip().split("=")[-1]
break
- else:
- continue
- try:
- # use ICMP socket to avoid net.ipv4.ip_nonlocal_bind issue,
- # cf. https://bugzilla.redhat.com/show_bug.cgi?id=890587
- s = socket.socket(ai[0], socket.SOCK_RAW, socket.IPPROTO_ICMP)
- except socket.error:
- ex = sys.exc_info()[1]
- if ex.errno != EPERM:
- raise
- f = None
- try:
- f = open("/proc/sys/net/ipv4/ip_nonlocal_bind")
- if int(f.read()) != 0:
- raise GsyncdError(
- "non-local bind is set and not allowed to create "
- "raw sockets, cannot determine if %s is local" % host)
- s = socket.socket(ai[0], socket.SOCK_DGRAM)
- finally:
- if f:
- f.close()
- try:
- s.bind(ai[-1])
- locaddr = True
- break
- except:
- pass
- s.close()
- return locaddr
+
+ if NodeID == "":
+ raise GsyncdError("Failed to get Host UUID from %s" % UUID_FILE)
+ return NodeID
+
+
+def is_host_local(host_id):
+ return host_id == get_node_uuid()
def funcode(f):
@@ -458,8 +554,8 @@ def gauxpfx():
return _CL_AUX_GFID_PFX
-def md5hex(s):
- return md5(s).hexdigest()
+def sha256hex(s):
+ return sha256(s).hexdigest()
def selfkill(sig=SIGTERM):
@@ -477,21 +573,39 @@ def errno_wrap(call, arg=[], errnos=[], retry_errnos=[]):
ex = sys.exc_info()[1]
if ex.errno in errnos:
return ex.errno
- if not ex.errno in retry_errnos:
+ if ex.errno not in retry_errnos:
raise
nr_tries += 1
if nr_tries == GF_OP_RETRIES:
# probably a screwed state, cannot do much...
- logging.warn('reached maximum retries (%s)...%s' %
- (repr(arg), ex))
- return ex.errno
+ logging.warn(lf('reached maximum retries',
+ args=repr(arg),
+ error=ex))
+ raise
time.sleep(0.250) # retry the call
def lstat(e):
- return errno_wrap(os.lstat, [e], [ENOENT], [ESTALE])
+ return errno_wrap(os.lstat, [e], [ENOENT], [ESTALE, EBUSY])
+
+def get_gfid_from_mnt(gfidpath):
+ return errno_wrap(Xattr.lgetxattr,
+ [gfidpath, 'glusterfs.gfid.string',
+ GX_GFID_CANONICAL_LEN], [ENOENT], [ESTALE])
+
-class NoPurgeTimeAvailable(Exception):
+def matching_disk_gfid(gfid, entry):
+ disk_gfid = get_gfid_from_mnt(entry)
+ if isinstance(disk_gfid, int):
+ return False
+
+ if not gfid == disk_gfid:
+ return False
+
+ return True
+
+
+class NoStimeAvailable(Exception):
pass
@@ -499,5 +613,503 @@ class PartialHistoryAvailable(Exception):
pass
+class ChangelogHistoryNotAvailable(Exception):
+ pass
+
+
class ChangelogException(OSError):
pass
+
+
+def gf_event(event_type, **kwargs):
+ if EVENTS_ENABLED:
+ from gfevents.gf_event import gf_event as gfevent
+ gfevent(event_type, **kwargs)
+
+
+class GlusterLogLevel(object):
+ NONE = 0
+ EMERG = 1
+ ALERT = 2
+ CRITICAL = 3
+ ERROR = 4
+ WARNING = 5
+ NOTICE = 6
+ INFO = 7
+ DEBUG = 8
+ TRACE = 9
+
+
+def get_changelog_log_level(lvl):
+ return getattr(GlusterLogLevel, lvl, GlusterLogLevel.INFO)
+
+
+def get_master_and_slave_data_from_args(args):
+ master_name = None
+ slave_data = None
+ for arg in args:
+ if arg.startswith(":"):
+ master_name = arg.replace(":", "")
+ if "::" in arg:
+ slave_data = arg.replace("ssh://", "")
+
+ return (master_name, slave_data)
+
+def unshare_propagation_supported():
+ global unshare_mnt_propagation
+ if unshare_mnt_propagation is not None:
+ return unshare_mnt_propagation
+
+ unshare_mnt_propagation = False
+ p = subprocess.Popen(["unshare", "--help"],
+ stderr=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ universal_newlines=True)
+ out, err = p.communicate()
+ if p.returncode == 0:
+ if "propagation" in out:
+ unshare_mnt_propagation = True
+
+ return unshare_mnt_propagation
+
+
+def get_rsync_version(rsync_cmd):
+ global rsync_version
+ if rsync_version is not None:
+ return rsync_version
+
+ rsync_version = "0"
+ p = subprocess.Popen([rsync_cmd, "--version"],
+ stderr=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ universal_newlines=True)
+ out, err = p.communicate()
+ if p.returncode == 0:
+ rsync_version = out.split(" ", 4)[3]
+
+ return rsync_version
+
+
+def get_slv_dir_path(slv_host, slv_volume, gfid):
+ global slv_bricks
+
+ dir_path = ENOENT
+ pfx = gauxpfx()
+
+ if not slv_bricks:
+ slv_info = Volinfo(slv_volume, slv_host, master=False)
+ slv_bricks = slv_info.bricks
+ # Result of readlink would be of format as below.
+ # readlink = "../../pgfid[0:2]/pgfid[2:4]/pgfid/basename"
+ for brick in slv_bricks:
+ dir_path = errno_wrap(os.path.join,
+ [brick['dir'],
+ ".glusterfs", gfid[0:2],
+ gfid[2:4],
+ gfid], [ENOENT], [ESTALE])
+ if dir_path != ENOENT:
+ try:
+ realpath = errno_wrap(os.readlink, [dir_path],
+ [ENOENT], [ESTALE])
+ if not isinstance(realpath, int):
+ realpath_parts = realpath.split('/')
+ pargfid = realpath_parts[-2]
+ basename = realpath_parts[-1]
+ dir_entry = os.path.join(pfx, pargfid, basename)
+ return dir_entry
+ except OSError:
+ # .gfid/GFID
+ gfidpath = unescape_space_newline(os.path.join(pfx, gfid))
+ realpath = errno_wrap(Xattr.lgetxattr_buf,
+ [gfidpath, 'glusterfs.gfid2path'], [ENOENT], [ESTALE])
+ if not isinstance(realpath, int):
+ basename = os.path.basename(realpath).rstrip('\x00')
+ dirpath = os.path.dirname(realpath)
+ if dirpath == "/":
+ pargfid = ROOT_GFID
+ else:
+ dirpath = dirpath.strip("/")
+ pargfid = get_gfid_from_mnt(dirpath)
+ if isinstance(pargfid, int):
+ return None
+ dir_entry = os.path.join(pfx, pargfid, basename)
+ return dir_entry
+
+ return None
+
+
+def lf(event, **kwargs):
+ """
+ Log Format helper function, log messages can be
+ easily modified to structured log format.
+ lf("Config Change", sync_jobs=4, brick=/bricks/b1) will be
+ converted as "Config Change [{brick=/bricks/b1}, {sync_jobs=4}]"
+ """
+ msgparts = []
+ for k, v in kwargs.items():
+ msgparts.append("{%s=%s}" % (k, v))
+ return "%s [%s]" % (event, ", ".join(msgparts))
+
+
+class Popen(subprocess.Popen):
+
+ """customized subclass of subprocess.Popen with a ring
+ buffer for children error output"""
+
+ @classmethod
+ def init_errhandler(cls):
+ """start the thread which handles children's error output"""
+ cls.errstore = {}
+
+ def tailer():
+ while True:
+ errstore = cls.errstore.copy()
+ try:
+ poe, _, _ = select(
+ [po.stderr for po in errstore], [], [], 1)
+ except (ValueError, SelectError):
+ # stderr is already closed wait for some time before
+ # checking next error
+ time.sleep(0.5)
+ continue
+ for po in errstore:
+ if po.stderr not in poe:
+ continue
+ po.lock.acquire()
+ try:
+ if po.on_death_row:
+ continue
+ la = errstore[po]
+ try:
+ fd = po.stderr.fileno()
+ except ValueError: # file is already closed
+ time.sleep(0.5)
+ continue
+
+ try:
+ l = os.read(fd, 1024)
+ except OSError:
+ time.sleep(0.5)
+ continue
+
+ if not l:
+ continue
+ tots = len(l)
+ for lx in la:
+ tots += len(lx)
+ while tots > 1 << 20 and la:
+ tots -= len(la.pop(0))
+ la.append(l)
+ finally:
+ po.lock.release()
+ t = Thread(target=tailer)
+ t.start()
+ cls.errhandler = t
+
+ @classmethod
+ def fork(cls):
+ """fork wrapper that restarts errhandler thread in child"""
+ pid = os.fork()
+ if not pid:
+ cls.init_errhandler()
+ return pid
+
+ def __init__(self, args, *a, **kw):
+ """customizations for subprocess.Popen instantiation
+
+ - 'close_fds' is taken to be the default
+ - if child's stderr is chosen to be managed,
+ register it with the error handler thread
+ """
+ self.args = args
+ if 'close_fds' not in kw:
+ kw['close_fds'] = True
+ self.lock = threading.Lock()
+ self.on_death_row = False
+ self.elines = []
+ try:
+ sup(self, args, *a, **kw)
+ except:
+ ex = sys.exc_info()[1]
+ if not isinstance(ex, OSError):
+ raise
+ raise GsyncdError("""execution of "%s" failed with %s (%s)""" %
+ (args[0], errno.errorcode[ex.errno],
+ os.strerror(ex.errno)))
+ if kw.get('stderr') == subprocess.PIPE:
+ assert(getattr(self, 'errhandler', None))
+ self.errstore[self] = []
+
+ def errlog(self):
+ """make a log about child's failure event"""
+ logging.error(lf("command returned error",
+ cmd=" ".join(self.args),
+ error=self.returncode))
+ lp = ''
+
+ def logerr(l):
+ logging.error(self.args[0] + "> " + l)
+ for l in self.elines:
+ ls = l.split('\n')
+ ls[0] = lp + ls[0]
+ lp = ls.pop()
+ for ll in ls:
+ logerr(ll)
+ if lp:
+ logerr(lp)
+
+ def errfail(self):
+ """fail nicely if child did not terminate with success"""
+ self.errlog()
+ finalize(exval=1)
+
+ def terminate_geterr(self, fail_on_err=True):
+ """kill child, finalize stderr harvesting (unregister
+ from errhandler, set up .elines), fail on error if
+ asked for
+ """
+ self.lock.acquire()
+ try:
+ self.on_death_row = True
+ finally:
+ self.lock.release()
+ elines = self.errstore.pop(self)
+ if self.poll() is None:
+ self.terminate()
+ if self.poll() is None:
+ time.sleep(0.1)
+ self.kill()
+ self.wait()
+ while True:
+ if not select([self.stderr], [], [], 0.1)[0]:
+ break
+ b = os.read(self.stderr.fileno(), 1024)
+ if b:
+ elines.append(b.decode())
+ else:
+ break
+ self.stderr.close()
+ self.elines = elines
+ if fail_on_err and self.returncode != 0:
+ self.errfail()
+
+
+def host_brick_split(value):
+ """
+ IPv6 compatible way to split and get the host
+ and brick information. Example inputs:
+ node1.example.com:/exports/bricks/brick1/brick
+ fe80::af0f:df82:844f:ef66%utun0:/exports/bricks/brick1/brick
+ """
+ parts = value.split(":")
+ brick = parts[-1]
+ hostparts = parts[0:-1]
+ return (":".join(hostparts), brick)
+
+
+class Volinfo(object):
+
+ def __init__(self, vol, host='localhost', prelude=[], master=True):
+ if master:
+ gluster_cmd_dir = gconf.get("gluster-command-dir")
+ else:
+ gluster_cmd_dir = gconf.get("slave-gluster-command-dir")
+
+ gluster_cmd = os.path.join(gluster_cmd_dir, 'gluster')
+ po = Popen(prelude + [gluster_cmd, '--xml', '--remote-host=' + host,
+ 'volume', 'info', vol],
+ stdout=PIPE, stderr=PIPE, universal_newlines=True)
+ vix = po.stdout.read()
+ po.wait()
+ po.terminate_geterr()
+ vi = XET.fromstring(vix)
+ if vi.find('opRet').text != '0':
+ if prelude:
+ via = '(via %s) ' % prelude.join(' ')
+ else:
+ via = ' '
+ raise GsyncdError('getting volume info of %s%s '
+ 'failed with errorcode %s' %
+ (vol, via, vi.find('opErrno').text))
+ self.tree = vi
+ self.volume = vol
+ self.host = host
+
+ def get(self, elem):
+ return self.tree.findall('.//' + elem)
+
+ def is_tier(self):
+ return (self.get('typeStr')[0].text == 'Tier')
+
+ def is_hot(self, brickpath):
+ logging.debug('brickpath: ' + repr(brickpath))
+ return brickpath in self.hot_bricks
+
+ @property
+ @memoize
+ def bricks(self):
+ def bparse(b):
+ host, dirp = host_brick_split(b.find("name").text)
+ return {'host': host, 'dir': dirp, 'uuid': b.find("hostUuid").text}
+ return [bparse(b) for b in self.get('brick')]
+
+ @property
+ @memoize
+ def uuid(self):
+ ids = self.get('id')
+ if len(ids) != 1:
+ raise GsyncdError("volume info of %s obtained from %s: "
+ "ambiguous uuid" % (self.volume, self.host))
+ return ids[0].text
+
+ def replica_count(self, tier, hot):
+ if (tier and hot):
+ return int(self.get('hotBricks/hotreplicaCount')[0].text)
+ elif (tier and not hot):
+ return int(self.get('coldBricks/coldreplicaCount')[0].text)
+ else:
+ return int(self.get('replicaCount')[0].text)
+
+ def disperse_count(self, tier, hot):
+ if (tier and hot):
+ # Tiering doesn't support disperse volume as hot brick,
+ # hence no xml output, so returning 0. In case, if it's
+ # supported later, we should change here.
+ return 0
+ elif (tier and not hot):
+ return int(self.get('coldBricks/colddisperseCount')[0].text)
+ else:
+ return int(self.get('disperseCount')[0].text)
+
+ def distribution_count(self, tier, hot):
+ if (tier and hot):
+ return int(self.get('hotBricks/hotdistCount')[0].text)
+ elif (tier and not hot):
+ return int(self.get('coldBricks/colddistCount')[0].text)
+ else:
+ return int(self.get('distCount')[0].text)
+
+ @property
+ @memoize
+ def hot_bricks(self):
+ return [b.text for b in self.get('hotBricks/brick')]
+
+ def get_hot_bricks_count(self, tier):
+ if (tier):
+ return int(self.get('hotBricks/hotbrickCount')[0].text)
+ else:
+ return 0
+
+
+class VolinfoFromGconf(object):
+ # Glusterd will generate following config items before Geo-rep start
+ # So that Geo-rep need not run gluster commands from inside
+ # Volinfo object API/interface kept as is so that caller need not
+ # change anything except calling this instead of Volinfo()
+ #
+ # master-bricks=
+ # master-bricks=NODEID:HOSTNAME:PATH,..
+ # slave-bricks=NODEID:HOSTNAME,..
+ # master-volume-id=
+ # slave-volume-id=
+ # master-replica-count=
+ # master-disperse_count=
+ def __init__(self, vol, host='localhost', master=True):
+ self.volume = vol
+ self.host = host
+ self.master = master
+
+ def is_tier(self):
+ return False
+
+ def is_hot(self, brickpath):
+ return False
+
+ def is_uuid(self, value):
+ try:
+ uuid.UUID(value)
+ return True
+ except ValueError:
+ return False
+
+ def possible_path(self, value):
+ return "/" in value
+
+ @property
+ @memoize
+ def bricks(self):
+ pfx = "master-" if self.master else "slave-"
+ bricks_data = gconf.get(pfx + "bricks")
+ if bricks_data is None:
+ return []
+
+ bricks_data = bricks_data.split(",")
+ bricks_data = [b.strip() for b in bricks_data]
+ out = []
+ for b in bricks_data:
+ parts = b.split(":")
+ b_uuid = None
+ if self.is_uuid(parts[0]):
+ b_uuid = parts[0]
+ # Set all parts except first
+ parts = parts[1:]
+
+ if self.possible_path(parts[-1]):
+ bpath = parts[-1]
+ # Set all parts except last
+ parts = parts[0:-1]
+
+ out.append({
+ "host": ":".join(parts), # if remaining parts are IPv6 name
+ "dir": bpath,
+ "uuid": b_uuid
+ })
+
+ return out
+
+ @property
+ @memoize
+ def uuid(self):
+ if self.master:
+ return gconf.get("master-volume-id")
+ else:
+ return gconf.get("slave-volume-id")
+
+ def replica_count(self, tier, hot):
+ return gconf.get("master-replica-count")
+
+ def disperse_count(self, tier, hot):
+ return gconf.get("master-disperse-count")
+
+ def distribution_count(self, tier, hot):
+ return gconf.get("master-distribution-count")
+
+ @property
+ @memoize
+ def hot_bricks(self):
+ return []
+
+ def get_hot_bricks_count(self, tier):
+ return 0
+
+
+def can_ssh(host, port=22):
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.connect((host, port))
+ flag = True
+ except socket.error:
+ flag = False
+
+ s.close()
+ return flag
+
+
+def get_up_nodes(hosts, port):
+ # List of hosts with Hostname/IP and UUID
+ up_nodes = []
+ for h in hosts:
+ if can_ssh(h[0], port):
+ up_nodes.append(h)
+
+ return up_nodes
diff --git a/geo-replication/tests/__init__.py b/geo-replication/tests/__init__.py
index 23adbfa5171..b4648b69645 100644
--- a/geo-replication/tests/__init__.py
+++ b/geo-replication/tests/__init__.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
diff --git a/geo-replication/tests/unit/__init__.py b/geo-replication/tests/unit/__init__.py
index 23adbfa5171..b4648b69645 100644
--- a/geo-replication/tests/unit/__init__.py
+++ b/geo-replication/tests/unit/__init__.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
diff --git a/geo-replication/tests/unit/test_gsyncdstatus.py b/geo-replication/tests/unit/test_gsyncdstatus.py
index a65d659e356..9c1aa2ad4ad 100644..100755
--- a/geo-replication/tests/unit/test_gsyncdstatus.py
+++ b/geo-replication/tests/unit/test_gsyncdstatus.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python3
#
# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
@@ -13,11 +13,11 @@ import unittest
import os
import urllib
-from syncdaemon.gstatus import GeorepStatus, set_monitor_status
-from syncdaemon.gstatus import get_default_values
-from syncdaemon.gstatus import MONITOR_STATUS, DEFAULT_STATUS
-from syncdaemon.gstatus import STATUS_VALUES, CRAWL_STATUS_VALUES
-from syncdaemon.gstatus import human_time, human_time_utc
+from syncdaemon.gstatus import (GeorepStatus, set_monitor_status,
+ get_default_values,
+ MONITOR_STATUS, DEFAULT_STATUS,
+ STATUS_VALUES, CRAWL_STATUS_VALUES,
+ human_time, human_time_utc)
class GeorepStatusTestCase(unittest.TestCase):
diff --git a/geo-replication/tests/unit/test_syncdutils.py b/geo-replication/tests/unit/test_syncdutils.py
index 736ae274b85..ff537ab2660 100644
--- a/geo-replication/tests/unit/test_syncdutils.py
+++ b/geo-replication/tests/unit/test_syncdutils.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
#
# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
# This file is part of GlusterFS.
diff --git a/glusterfs-api.pc.in b/glusterfs-api.pc.in
index 5d234543414..4a2edb7bf07 100644
--- a/glusterfs-api.pc.in
+++ b/glusterfs-api.pc.in
@@ -9,4 +9,4 @@ Description: GlusterFS API
Version: @GFAPI_VERSION@
Requires: @PKGCONFIG_UUID@
Libs: -L${libdir} @GFAPI_LIBS@ -lgfapi -lglusterfs -lgfrpc -lgfxdr
-Cflags: -I${includedir}/glusterfs -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -DUSE_POSIX_ACLS=@USE_POSIX_ACLS@
+Cflags: -I${includedir} -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D__USE_LARGEFILE64 -DUSE_POSIX_ACLS=@USE_POSIX_ACLS@
diff --git a/glusterfs-hadoop/0.20.2/conf/core-site.xml b/glusterfs-hadoop/0.20.2/conf/core-site.xml
deleted file mode 100644
index d7f75fca733..00000000000
--- a/glusterfs-hadoop/0.20.2/conf/core-site.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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
deleted file mode 100644
index fe661d40fdc..00000000000
--- a/glusterfs-hadoop/0.20.2/pom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<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
deleted file mode 100644
index e633b8aae80..00000000000
--- a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickClass.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- *
- * 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
deleted file mode 100644
index 11454e6368a..00000000000
--- a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSBrickRepl.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- *
- * 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
deleted file mode 100644
index 455dda97e9c..00000000000
--- a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFSXattr.java
+++ /dev/null
@@ -1,472 +0,0 @@
-/**
- *
- * 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
deleted file mode 100644
index e92237aeea2..00000000000
--- a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEInputStream.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- *
- * 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
deleted file mode 100644
index 5192a0a56cb..00000000000
--- a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFUSEOutputStream.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- *
- * 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
deleted file mode 100644
index b0501cced27..00000000000
--- a/glusterfs-hadoop/0.20.2/src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFileSystem.java
+++ /dev/null
@@ -1,492 +0,0 @@
-/**
- *
- * 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
deleted file mode 100644
index 21e188c52bc..00000000000
--- a/glusterfs-hadoop/0.20.2/src/test/java/org/apache/hadoop/fs/glusterfs/AppTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-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
deleted file mode 100755
index c20e53b39b2..00000000000
--- a/glusterfs-hadoop/0.20.2/tools/build-deploy-jar.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/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
deleted file mode 100644
index d6456956733..00000000000
--- a/glusterfs-hadoop/COPYING
+++ /dev/null
@@ -1,202 +0,0 @@
-
- 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
deleted file mode 100644
index 3026f11c035..00000000000
--- a/glusterfs-hadoop/README
+++ /dev/null
@@ -1,182 +0,0 @@
-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 109819f3ecf..b6d63146e14 100644
--- a/glusterfs.spec.in
+++ b/glusterfs.spec.in
@@ -9,83 +9,115 @@
## All argument definitions should be placed here and keep them sorted
##
-# if you wish to compile an rpm with debugging...
-# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with debug
-%{?_with_debug:%global _with_debug --enable-debug}
+# asan
+# if you wish to compile an rpm with address sanitizer...
+# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with asan
+%{?_with_asan:%global _with_asan --enable-asan}
+
+%if ( 0%{?rhel} && 0%{?rhel} < 7 )
+%global _with_asan %{nil}
+%endif
+# cmocka
# if you wish to compile an rpm with cmocka unit testing...
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with cmocka
%{?_with_cmocka:%global _with_cmocka --enable-cmocka}
-# 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:%global _without_rdma --disable-ibverbs}
-
-# No RDMA Support on s390(x)
-%ifarch s390 s390x
-%global _without_rdma --disable-ibverbs
-%endif
+# debug
+# if you wish to compile an rpm with debugging...
+# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with debug
+%{?_with_debug:%global _with_debug --enable-debug}
+# epoll
# if you wish to compile an rpm without epoll...
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without epoll
%{?_without_epoll:%global _without_epoll --disable-epoll}
+# fusermount
# if you wish to compile an rpm without fusermount...
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without fusermount
%{?_without_fusermount:%global _without_fusermount --disable-fusermount}
+# geo-rep
# if you wish to compile an rpm without geo-replication support, compile like this...
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without georeplication
%{?_without_georeplication:%global _without_georeplication --disable-georeplication}
-# Disable geo-replication on EL5, as its default Python is too old
-%if ( 0%{?rhel} && 0%{?rhel} < 6 )
-%global _without_georeplication --disable-georeplication
+# gnfs
+# if you wish to compile an rpm with the legacy gNFS server xlator
+# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with gnfs
+%{?_with_gnfs:%global _with_gnfs --enable-gnfs}
+
+# ipv6default
+# if you wish to compile an rpm with IPv6 default...
+# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with ipv6default
+%{?_with_ipv6default:%global _with_ipv6default --with-ipv6-default}
+
+# libtirpc
+# if you wish to compile an rpm without TIRPC (i.e. use legacy glibc rpc)
+# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without libtirpc
+%{?_without_libtirpc:%global _without_libtirpc --without-libtirpc}
+
+# Do not use libtirpc on EL6, it does not have xdr_uint64_t() and xdr_uint32_t
+# Do not use libtirpc on EL7, it does not have xdr_sizeof()
+%if ( 0%{?rhel} && 0%{?rhel} <= 7 )
+%global _without_libtirpc --without-libtirpc
%endif
+
+# ocf
# if you wish to compile an rpm without the OCF resource agents...
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without ocf
%{?_without_ocf:%global _without_ocf --without-ocf}
+# server
+# if you wish to build rpms without server components, compile like this
+# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without server
+%{?_without_server:%global _without_server --without-server}
+
+# disable server components forcefully as rhel <= 6
+%if ( 0%{?rhel} && 0%{?rhel} <= 6 )
+%global _without_server --without-server
+%endif
+
+# syslog
# if you wish to build rpms without syslog logging, compile like this
# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without syslog
%{?_without_syslog:%global _without_syslog --disable-syslog}
# disable syslog forcefully as rhel <= 6 doesn't have rsyslog or rsyslog-mmcount
-# Fedora deprecated syslog, see
+# Fedora deprecated syslog, see
# https://fedoraproject.org/wiki/Changes/NoDefaultSyslog
# (And what about RHEL7?)
%if ( 0%{?fedora} && 0%{?fedora} >= 20 ) || ( 0%{?rhel} && 0%{?rhel} <= 6 )
%global _without_syslog --disable-syslog
%endif
-# if you wish to compile an rpm without the BD map support...
-# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without bd
-%{?_without_bd:%global _without_bd --disable-bd-xlator}
-
-%if ( 0%{?rhel} && 0%{?rhel} < 6 || 0%{?sles_version} )
-%define _without_bd --disable-bd-xlator
-%endif
-
-# if you wish to compile an rpm without the qemu-block support...
-# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --without qemu-block
-%{?_without_qemu_block:%global _without_qemu_block --disable-qemu-block}
+# tsan
+# if you wish to compile an rpm with thread sanitizer...
+# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with tsan
+%{?_with_tsan:%global _with_tsan --enable-tsan}
-%if ( 0%{?rhel} && 0%{?rhel} < 6 )
-# xlators/features/qemu-block fails to build on RHEL5, disable it
-%define _without_qemu_block --disable-qemu-block
+%if ( 0%{?rhel} && 0%{?rhel} < 7 )
+%global _with_tsan %{nil}
%endif
-# Disable data-tiering on EL5, sqlite is too old
-%if ( 0%{?rhel} && 0%{?rhel} < 6 )
-%global _without_tiering --disable-tiering
-%endif
+# valgrind
+# if you wish to compile an rpm to run all processes under valgrind...
+# rpmbuild -ta @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz --with valgrind
+%{?_with_valgrind:%global _with_valgrind --enable-valgrind}
##-----------------------------------------------------------------------------
-## All %global definitions should be placed here and keep them sorted
+## All %%global definitions should be placed here and keep them sorted
##
-%if ( 0%{?fedora} && 0%{?fedora} > 16 ) || ( 0%{?rhel} && 0%{?rhel} > 6 )
+# selinux booleans whose defalut value needs modification
+# these booleans will be consumed by "%%selinux_set_booleans" macro.
+%if ( 0%{?rhel} && 0%{?rhel} >= 8 )
+%global selinuxbooleans rsync_full_access=1 rsync_client=1
+%endif
+
+%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} > 6 )
%global _with_systemd true
%endif
@@ -94,97 +126,104 @@
%endif
%if 0%{?_tmpfilesdir:1}
-%define _with_tmpfilesdir --with-tmpfilesdir=%{_tmpfilesdir}
+%global _with_tmpfilesdir --with-tmpfilesdir=%{_tmpfilesdir}
%else
-%define _with_tmpfilesdir --without-tmpfilesdir
+%global _with_tmpfilesdir --without-tmpfilesdir
%endif
-# there is no systemtap support! Perhaps some day there will be
-%global _without_systemtap --enable-systemtap=no
+# without server should also disable some server-only components
+%if 0%{?_without_server:1}
+%global _without_events --disable-events
+%global _without_georeplication --disable-georeplication
+%global _with_gnfs %{nil}
+%global _without_ocf --without-ocf
+%endif
+
+%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} > 7 )
+%global _usepython3 1
+%global _pythonver 3
+%else
+%global _usepython3 0
+%global _pythonver 2
+%endif
# From https://fedoraproject.org/wiki/Packaging:Python#Macros
-%if ( 0%{?rhel} && 0%{?rhel} <= 5 )
-%{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")}
-%{!?python_sitearch: %global python_sitearch %(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
+%if ( 0%{?rhel} && 0%{?rhel} <= 6 )
+%{!?python2_sitelib: %global python2_sitelib %(python2 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")}
+%{!?python2_sitearch: %global python2_sitearch %(python2 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
+%global _rundir %{_localstatedir}/run
%endif
%if ( 0%{?_with_systemd:1} )
-%define _init_enable() /bin/systemctl enable %1.service ;
-%define _init_disable() /bin/systemctl disable %1.service ;
-%define _init_restart() /bin/systemctl try-restart %1.service ;
-%define _init_start() /bin/systemctl start %1.service ;
-%define _init_stop() /bin/systemctl stop %1.service ;
-%define _init_install() install -D -p -m 0644 %1 %{buildroot}%{_unitdir}/%2.service ;
+%global service_start() /bin/systemctl --quiet start %1.service || : \
+%{nil}
+%global service_stop() /bin/systemctl --quiet stop %1.service || :\
+%{nil}
+%global service_install() install -D -p -m 0644 %1.service %{buildroot}%2 \
+%{nil}
# can't seem to make a generic macro that works
-%define _init_glusterd %{_unitdir}/glusterd.service
-%define _init_glusterfsd %{_unitdir}/glusterfsd.service
+%global glusterd_svcfile %{_unitdir}/glusterd.service
+%global glusterfsd_svcfile %{_unitdir}/glusterfsd.service
+%global glusterta_svcfile %{_unitdir}/gluster-ta-volume.service
+%global glustereventsd_svcfile %{_unitdir}/glustereventsd.service
+%global glusterfssharedstorage_svcfile %{_unitdir}/glusterfssharedstorage.service
%else
-%define _init_enable() /sbin/chkconfig --add %1 ;
-%define _init_disable() /sbin/chkconfig --del %1 ;
-%define _init_restart() /sbin/service %1 condrestart &>/dev/null ;
-%define _init_start() /sbin/service %1 start &>/dev/null ;
-%define _init_stop() /sbin/service %1 stop &>/dev/null ;
-%define _init_install() install -D -p -m 0755 %1 %{buildroot}%{_sysconfdir}/init.d/%2 ;
+%global systemd_post() /sbin/chkconfig --add %1 >/dev/null 2>&1 || : \
+%{nil}
+%global systemd_preun() /sbin/chkconfig --del %1 >/dev/null 2>&1 || : \
+%{nil}
+%global systemd_postun_with_restart() /sbin/service %1 condrestart >/dev/null 2>&1 || : \
+%{nil}
+%global service_start() /sbin/service %1 start >/dev/null 2>&1 || : \
+%{nil}
+%global service_stop() /sbin/service %1 stop >/dev/null 2>&1 || : \
+%{nil}
+%global service_install() install -D -p -m 0755 %1.init %{buildroot}%2 \
+%{nil}
# can't seem to make a generic macro that works
-%define _init_glusterd %{_sysconfdir}/init.d/glusterd
-%define _init_glusterfsd %{_sysconfdir}/init.d/glusterfsd
-%endif
-
-%if ( 0%{_for_fedora_koji_builds} )
-%if ( 0%{?_with_systemd:1} )
-%global glusterfsd_service glusterfsd.service
-%else
-%global glusterfsd_service glusterfsd.init
-%endif
+%global glusterd_svcfile %{_sysconfdir}/init.d/glusterd
+%global glusterfsd_svcfile %{_sysconfdir}/init.d/glusterfsd
+%global glustereventsd_svcfile %{_sysconfdir}/init.d/glustereventsd
%endif
%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}}
-%if ( 0%{?rhel} && 0%{?rhel} < 6 )
- # _sharedstatedir is not provided by RHEL5
- %define _sharedstatedir /var/lib
-%endif
-
# We do not want to generate useless provides and requires for xlator
# .so files to be set for glusterfs packages.
# Filter all generated:
#
# TODO: RHEL5 does not have a convenient solution
%if ( 0%{?rhel} == 6 )
- # filter_setup exists in RHEL6 only
- %filter_provides_in %{_libdir}/glusterfs/%{version}/
- %global __filter_from_req %{?__filter_from_req} | grep -v -P '^(?!lib).*\.so.*$'
- %filter_setup
+# filter_setup exists in RHEL6 only
+%filter_provides_in %{_libdir}/glusterfs/%{version}/
+%global __filter_from_req %{?__filter_from_req} | grep -v -P '^(?!lib).*\.so.*$'
+%filter_setup
%else
- # modern rpm and current Fedora do not generate requires when the
- # provides are filtered
- %global __provides_exclude_from ^%{_libdir}/glusterfs/%{version}/.*$
+# modern rpm and current Fedora do not generate requires when the
+# provides are filtered
+%global __provides_exclude_from ^%{_libdir}/glusterfs/%{version}/.*$
%endif
##-----------------------------------------------------------------------------
-## All package definitions should be placed here and keep them sorted
+## All package definitions should be placed here in alphabetical order
##
Summary: Distributed File System
%if ( 0%{_for_fedora_koji_builds} )
Name: glusterfs
-Version: 3.5.0
+Version: 3.8.0
Release: 0.1%{?prereltag:.%{prereltag}}%{?dist}
-Vendor: Fedora Project
%else
Name: @PACKAGE_NAME@
Version: @PACKAGE_VERSION@
Release: 0.@PACKAGE_RELEASE@%{?dist}
-Vendor: Gluster Community
%endif
License: GPLv2 or LGPLv3+
-Group: System Environment/Base
-URL: http://www.gluster.org/docs/index.php/GlusterFS
+URL: http://docs.gluster.org/
%if ( 0%{_for_fedora_koji_builds} )
Source0: http://bits.gluster.org/pub/gluster/glusterfs/src/glusterfs-%{version}%{?prereltag}.tar.gz
Source1: glusterd.sysconfig
Source2: glusterfsd.sysconfig
-Source6: rhel5-load-fuse-modules
Source7: glusterfsd.service
Source8: glusterfsd.init
%else
@@ -193,41 +232,45 @@ Source0: @PACKAGE_NAME@-@PACKAGE_VERSION@.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
-%if ( 0%{?rhel} && 0%{?rhel} <= 5 )
-BuildRequires: python-simplejson
-%endif
+Requires(pre): shadow-utils
%if ( 0%{?_with_systemd:1} )
-BuildRequires: systemd-units
+BuildRequires: systemd
%endif
-Requires: %{name}-libs = %{version}-%{release}
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Requires: libgfrpc0%{?_isa} = %{version}-%{release}
+Requires: libgfxdr0%{?_isa} = %{version}-%{release}
+%if ( 0%{?_with_systemd:1} )
+%{?systemd_requires}
+%endif
+%if 0%{?_with_asan:1} && !( 0%{?rhel} && 0%{?rhel} < 7 )
+BuildRequires: libasan
+%endif
+%if 0%{?_with_tsan:1} && !( 0%{?rhel} && 0%{?rhel} < 7 )
+BuildRequires: libtsan
+%endif
BuildRequires: bison flex
-BuildRequires: gcc make automake libtool
+BuildRequires: gcc make libtool
BuildRequires: ncurses-devel readline-devel
BuildRequires: libxml2-devel openssl-devel
BuildRequires: libaio-devel libacl-devel
-BuildRequires: python-devel
+BuildRequires: python%{_pythonver}-devel
+%if ( 0%{?rhel} && 0%{?rhel} < 8 )
BuildRequires: python-ctypes
-BuildRequires: userspace-rcu-devel >= 0.7
-%if ( 0%{?rhel} && 0%{?rhel} <= 5 )
-BuildRequires: e2fsprogs-devel
-%else
-BuildRequires: libuuid-devel
-%endif
-%if ( 0%{?_with_cmocka:1} )
-BuildRequires: libcmocka-devel >= 1.0.1
%endif
-%if ( 0%{!?_without_tiering:1} )
-BuildRequires: sqlite-devel
+%if ( 0%{?_with_ipv6default:1} ) || ( 0%{!?_without_libtirpc:1} )
+BuildRequires: libtirpc-devel
%endif
-%if ( 0%{!?_without_systemtap:1} )
-BuildRequires: systemtap-sdt-devel
+%if ( 0%{?fedora} && 0%{?fedora} > 27 ) || ( 0%{?rhel} && 0%{?rhel} > 7 )
+BuildRequires: rpcgen
%endif
-%if ( 0%{!?_without_bd:1} )
-BuildRequires: lvm2-devel
+BuildRequires: userspace-rcu-devel >= 0.7
+%if ( 0%{?rhel} && 0%{?rhel} <= 6 )
+BuildRequires: automake
%endif
-%if ( 0%{!?_without_qemu_block:1} )
-BuildRequires: glib2-devel
+BuildRequires: libuuid-devel
+%if ( 0%{?_with_cmocka:1} )
+BuildRequires: libcmocka-devel >= 1.0.1
%endif
%if ( 0%{!?_without_georeplication:1} )
BuildRequires: libattr-devel
@@ -237,148 +280,129 @@ BuildRequires: libattr-devel
BuildRequires: firewalld
%endif
-Obsoletes: hekafs
Obsoletes: %{name}-common < %{version}-%{release}
Obsoletes: %{name}-core < %{version}-%{release}
-Obsoletes: %{name}-ufo
+Obsoletes: %{name}-ganesha
+Obsoletes: %{name}-rdma < %{version}-%{release}
+%if ( 0%{!?_with_gnfs:1} )
+Obsoletes: %{name}-gnfs < %{version}-%{release}
+%endif
Provides: %{name}-common = %{version}-%{release}
Provides: %{name}-core = %{version}-%{release}
%description
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 includes the glusterfs binary, the glusterfsd daemon and the
libglusterfs and glusterfs translator modules common to both GlusterFS server
and client framework.
-%package api
-Summary: GlusterFS api library
-Group: System Environment/Daemons
-Requires: %{name} = %{version}-%{release}
-Requires: %{name}-client-xlators = %{version}-%{release}
-# we provide the Python package/namespace 'gluster'
-#Provides: python-gluster = %{version}-%{release}
-
-%description api
-GlusterFS is a distributed 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 libgfapi library.
-
-%package api-devel
-Summary: Development Libraries
-Group: Development/Libraries
-Requires: %{name} = %{version}-%{release}
-Requires: %{name}-devel = %{version}-%{release}
-Requires: libacl-devel
-
-%description api-devel
-GlusterFS is a distributed 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 api include files.
-
%package cli
Summary: GlusterFS CLI
-Group: Applications/File
-Requires: %{name}-libs = %{version}-%{release}
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Requires: libglusterd0%{?_isa} = %{version}-%{release}
%description cli
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 CLI application and its man page
-%package devel
-Summary: Development Libraries
-Group: Development/Libraries
-Requires: %{name} = %{version}-%{release}
-# Needed for the Glupy examples to work
-Requires: %{name}-extra-xlators = %{version}-%{release}
+%package cloudsync-plugins
+Summary: Cloudsync Plugins
+BuildRequires: libcurl-devel
-%description devel
+%description cloudsync-plugins
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 and include files.
+This package provides cloudsync plugins for archival feature.
%package extra-xlators
Summary: Extra Gluster filesystem Translators
-Group: Applications/File
# We need python-gluster rpm for gluster module's __init__.py in Python
# site-packages area
-Requires: python-gluster = %{version}-%{release}
-Requires: python python-ctypes
+Requires: python%{_pythonver}-gluster = %{version}-%{release}
+Requires: python%{_pythonver}
%description extra-xlators
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 extra filesystem Translators, such as Glupy,
for GlusterFS.
%package fuse
Summary: Fuse client
-Group: Applications/File
BuildRequires: fuse-devel
Requires: attr
+Requires: psmisc
-Requires: %{name} = %{version}-%{release}
-Requires: %{name}-client-xlators = %{version}-%{release}
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release}
Obsoletes: %{name}-client < %{version}-%{release}
Provides: %{name}-client = %{version}-%{release}
%description fuse
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 support to FUSE based clients and inlcudes the
glusterfs(d) binary.
+%if ( 0%{!?_without_server:1} )
%package ganesha
Summary: NFS-Ganesha configuration
Group: Applications/File
-Requires: %{name}-server = %{version}-%{release}
-Requires: nfs-ganesha-gluster
-Requires: pcs
+Requires: %{name}-server%{?_isa} = %{version}-%{release}
+Requires: nfs-ganesha-selinux >= 2.7.6
+Requires: nfs-ganesha-gluster >= 2.7.6
+Requires: pcs >= 0.10.0
+Requires: resource-agents >= 4.2.0
+Requires: dbus
+
+%if ( 0%{?rhel} && 0%{?rhel} == 6 )
+Requires: cman, pacemaker, corosync
+%endif
+
+%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} > 5 )
+# we need portblock resource-agent in 3.9.5 and later.
+Requires: net-tools
+%endif
+
+%if ( 0%{?fedora} && 0%{?fedora} > 25 || ( 0%{?rhel} && 0%{?rhel} > 6 ) )
+%if ( 0%{?rhel} && 0%{?rhel} < 8 )
+Requires: selinux-policy >= 3.13.1-160
+Requires(post): policycoreutils-python
+Requires(postun): policycoreutils-python
+%else
+Requires(post): policycoreutils-python-utils
+Requires(postun): policycoreutils-python-utils
+%endif
+%endif
%description ganesha
GlusterFS is a distributed file-system capable of scaling to several
@@ -391,104 +415,261 @@ is in user space and easily manageable.
This package provides the configuration and related files for using
NFS-Ganesha as the NFS server using GlusterFS
+%endif
%if ( 0%{!?_without_georeplication:1} )
%package geo-replication
Summary: GlusterFS Geo-replication
-Group: Applications/File
-Requires: %{name} = %{version}-%{release}
-Requires: %{name}-server = %{version}-%{release}
-Requires: python python-ctypes
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: %{name}-server%{?_isa} = %{version}-%{release}
+Requires: python%{_pythonver}
+Requires: python%{_pythonver}-prettytable
+Requires: python%{_pythonver}-gluster = %{version}-%{release}
+
Requires: rsync
+Requires: util-linux
+# required for setting selinux bools
+%if ( 0%{?rhel} && 0%{?rhel} >= 8 )
+Requires(post): policycoreutils-python-utils
+Requires(postun): policycoreutils-python-utils
+Requires: selinux-policy-targeted
+Requires(post): selinux-policy-targeted
+BuildRequires: selinux-policy-devel
+%endif
%description geo-replication
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 support to geo-replication.
%endif
-%package libs
-Summary: GlusterFS common libraries
-Group: Applications/File
-%if ( 0%{!?_without_syslog:1} )
-%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} > 6 )
-Requires: rsyslog-mmjsonparse
-%endif
-%if ( 0%{?rhel} && 0%{?rhel} == 6 )
-Requires: rsyslog-mmcount
-%endif
+%if ( 0%{?_with_gnfs:1} )
+%package gnfs
+Summary: GlusterFS gNFS server
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release}
+Requires: nfs-utils
+
+%description gnfs
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 legacy gNFS server xlator
%endif
-%description libs
+%package -n libglusterfs0
+Summary: GlusterFS libglusterfs library
+Requires: libgfrpc0%{?_isa} = %{version}-%{release}
+Requires: libgfxdr0%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-libs <= %{version}-%{release}
+Provides: %{name}-libs = %{version}-%{release}
+
+%description -n libglusterfs0
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 base libglusterfs library
+
+%package -n libglusterfs-devel
+Summary: GlusterFS libglusterfs library
+Requires: libgfrpc-devel%{?_isa} = %{version}-%{release}
+Requires: libgfxdr-devel%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-devel <= %{version}-%{release}
+Provides: %{name}-devel = %{version}-%{release}
+
+%description -n libglusterfs-devel
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 base GlusterFS libraries
+This package provides libglusterfs.so and the gluster C header files.
-%package -n python-gluster
-Summary: GlusterFS python library
-Group: Development/Tools
-%if ( ! ( 0%{?rhel} && 0%{?rhel} < 6 || 0%{?sles_version} ) )
-# EL5 does not support noarch sub-packages
-BuildArch: noarch
-%endif
-Requires: python
+%package -n libgfapi0
+Summary: GlusterFS api library
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-api <= %{version}-%{release}
+Provides: %{name}-api = %{version}-%{release}
-%description -n python-gluster
+%description -n libgfapi0
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 contains the python modules of GlusterFS and own gluster
-namespace.
+This package provides the glusterfs libgfapi library.
+
+%package -n libgfapi-devel
+Summary: Development Libraries
+Requires: libglusterfs-devel%{?_isa} = %{version}-%{release}
+Requires: libacl-devel
+Obsoletes: %{name}-api-devel <= %{version}-%{release}
+Provides: %{name}-api-devel = %{version}-%{release}
+%description -n libgfapi-devel
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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.
-%if ( 0%{!?_without_rdma:1} )
-%package rdma
-Summary: GlusterFS rdma support for ib-verbs
-Group: Applications/File
-BuildRequires: libibverbs-devel
-BuildRequires: librdmacm-devel >= 1.0.15
-Requires: %{name} = %{version}-%{release}
+This package provides libgfapi.so and the api C header files.
-%description rdma
+%package -n libgfchangelog0
+Summary: GlusterFS libchangelog library
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-libs <= %{version}-%{release}
+
+%description -n libgfchangelog0
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 libgfchangelog library
+
+%package -n libgfchangelog-devel
+Summary: GlusterFS libchangelog library
+Requires: libglusterfs-devel%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-devel <= %{version}-%{release}
+
+%description -n libgfchangelog-devel
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 support to ib-verbs library.
+This package provides libgfchangelog.so and changelog C header files.
+
+%package -n libgfrpc0
+Summary: GlusterFS libgfrpc0 library
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-libs <= %{version}-%{release}
+
+%description -n libgfrpc0
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 libgfrpc library
+
+%package -n libgfrpc-devel
+Summary: GlusterFS libgfrpc library
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-devel <= %{version}-%{release}
+
+%description -n libgfrpc-devel
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 libgfrpc.so and rpc C header files.
+
+%package -n libgfxdr0
+Summary: GlusterFS libgfxdr0 library
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-libs <= %{version}-%{release}
+
+%description -n libgfxdr0
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 libgfxdr library
+
+%package -n libgfxdr-devel
+Summary: GlusterFS libgfxdr library
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-devel <= %{version}-%{release}
+
+%description -n libgfxdr-devel
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 libgfxdr.so.
+
+%package -n libglusterd0
+Summary: GlusterFS libglusterd library
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-libs <= %{version}-%{release}
+
+%description -n libglusterd0
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 libglusterd library
+
+%package -n python%{_pythonver}-gluster
+Summary: GlusterFS python library
+Requires: python%{_pythonver}
+%if ( ! %{_usepython3} )
+%{?python_provide:%python_provide python-gluster}
+Provides: python-gluster = %{version}-%{release}
+Obsoletes: python-gluster < 3.10
%endif
+%description -n python%{_pythonver}-gluster
+GlusterFS is a distributed file-system capable of scaling to several
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 contains the python modules of GlusterFS and own gluster
+namespace.
+
%package regression-tests
Summary: Development Tools
-Group: Development/Tools
-Requires: %{name} = %{version}-%{release}
-Requires: %{name}-fuse = %{version}-%{release}
-Requires: %{name}-server = %{version}-%{release}
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: %{name}-fuse%{?_isa} = %{version}-%{release}
+Requires: %{name}-server%{?_isa} = %{version}-%{release}
## thin provisioning support
Requires: lvm2 >= 2.02.89
Requires: perl(App::Prove) perl(Test::Harness) gcc util-linux-ng
-Requires: python attr dbench file git libacl-devel net-tools
-Requires: nfs-utils xfsprogs yajl
+Requires: python%{_pythonver}
+Requires: attr dbench file git libacl-devel net-tools
+Requires: nfs-utils xfsprogs yajl psmisc bc
%description regression-tests
The Gluster Test Framework, is a suite of scripts used for
@@ -498,118 +679,169 @@ regression testing of Gluster.
%package resource-agents
Summary: OCF Resource Agents for GlusterFS
License: GPLv3+
-%if ( ! ( 0%{?rhel} && 0%{?rhel} < 6 || 0%{?sles_version} ) )
-# EL5 does not support noarch sub-packages
BuildArch: noarch
-%endif
# this Group handling comes from the Fedora resource-agents package
-%if ( 0%{?fedora} || 0%{?centos_version} || 0%{?rhel} )
-Group: System Environment/Base
-%else
-Group: Productivity/Clustering/HA
-%endif
# for glusterd
-Requires: %{name}-server
+Requires: %{name}-server = %{version}-%{release}
# depending on the distribution, we need pacemaker or resource-agents
Requires: %{_prefix}/lib/ocf/resource.d
%description resource-agents
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 resource agents which plug glusterd into
Open Cluster Framework (OCF) compliant cluster resource managers,
like Pacemaker.
%endif
+%if ( 0%{!?_without_server:1} )
%package server
Summary: Clustered file-system server
-Group: System Environment/Daemons
-Requires: %{name} = %{version}-%{release}
-Requires: %{name}-libs = %{version}-%{release}
-Requires: %{name}-cli = %{version}-%{release}
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: %{name}-cli%{?_isa} = %{version}-%{release}
+Requires: libglusterfs0%{?_isa} = %{version}-%{release}
+Requires: libgfchangelog0%{?_isa} = %{version}-%{release}
+%if ( 0%{?fedora} && 0%{?fedora} >= 30 || ( 0%{?rhel} && 0%{?rhel} >= 8 ) )
+Requires: glusterfs-selinux >= 0.1.0-2
+%endif
# some daemons (like quota) use a fuse-mount, glusterfsd is part of -fuse
-Requires: %{name}-fuse = %{version}-%{release}
+Requires: %{name}-fuse%{?_isa} = %{version}-%{release}
# self-heal daemon, rebalance, nfs-server etc. are actually clients
-Requires: %{name}-client-xlators = %{version}-%{release}
-# psmisc for killall, lvm2 for snapshot, and nfs-utils and
-# rpcbind/portmap for gnfs server
-Requires: psmisc
+Requires: libgfapi0%{?_isa} = %{version}-%{release}
+Requires: %{name}-client-xlators%{?_isa} = %{version}-%{release}
+# lvm2 for snapshot, and nfs-utils and rpcbind/portmap for gnfs server
Requires: lvm2
-Requires: nfs-utils
%if ( 0%{?_with_systemd:1} )
-Requires(post): systemd-units
-Requires(preun): systemd-units
-Requires(postun): systemd-units
+%{?systemd_requires}
%else
Requires(post): /sbin/chkconfig
Requires(preun): /sbin/service
Requires(preun): /sbin/chkconfig
Requires(postun): /sbin/service
%endif
+%if (0%{?_with_firewalld:1})
+# we install firewalld rules, so we need to have the directory owned
+%if ( 0%{!?rhel} )
+# not on RHEL because firewalld-filesystem appeared in 7.3
+# when EL7 rpm gets weak dependencies we can add a Suggests:
+Requires: firewalld-filesystem
+%endif
+%endif
%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} >= 6 )
Requires: rpcbind
%else
Requires: portmap
%endif
-%if ( 0%{?rhel} && 0%{?rhel} < 6 )
-Obsoletes: %{name}-geo-replication = %{version}-%{release}
-%endif
%if ( 0%{?rhel} && 0%{?rhel} <= 6 )
Requires: python-argparse
%endif
+%if ( 0%{?fedora} && 0%{?fedora} > 27 ) || ( 0%{?rhel} && 0%{?rhel} > 7 )
+Requires: python%{_pythonver}-pyxattr
+%else
Requires: pyxattr
+%endif
+%if (0%{?_with_valgrind:1})
+Requires: valgrind
+%endif
%description server
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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.
+%endif
+
+%package thin-arbiter
+Summary: GlusterFS thin-arbiter module
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: %{name}-server%{?_isa} = %{version}-%{release}
+
+%description thin-arbiter
+This package provides a tie-breaker functionality to GlusterFS
+replicate volume. It includes translators required to provide the
+functionality, and also few other scripts required for getting the setup done.
+
+This package provides the glusterfs thin-arbiter translator.
%package client-xlators
Summary: GlusterFS client-side translators
-Group: Applications/File
%description client-xlators
GlusterFS is a distributed 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.
+petabytes. It aggregates various storage bricks over TCP/IP interconnect
+into one large parallel network filesystem. 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 translators needed on any GlusterFS client.
+%if ( 0%{!?_without_events:1} )
+%package events
+Summary: GlusterFS Events
+Requires: %{name}-server%{?_isa} = %{version}-%{release}
+Requires: python%{_pythonver} python%{_pythonver}-prettytable
+Requires: python%{_pythonver}-gluster = %{version}-%{release}
+%if ( 0%{?rhel} && 0%{?rhel} < 8 )
+Requires: python-requests
+%else
+Requires: python%{_pythonver}-requests
+%endif
+%if ( 0%{?rhel} && 0%{?rhel} < 7 )
+Requires: python-argparse
+%endif
+%if ( 0%{?_with_systemd:1} )
+%{?systemd_requires}
+%endif
+
+%description events
+GlusterFS Events
+
+%endif
+
%prep
%setup -q -n %{name}-%{version}%{?prereltag}
+%if ( ! %{_usepython3} )
+echo "fixing python shebangs..."
+for f in api events extras geo-replication libglusterfs tools xlators; do
+find $f -type f -exec sed -i 's|/usr/bin/python3|/usr/bin/python2|' {} \;
+done
+%endif
%build
-./autogen.sh && %configure \
+
+# RHEL6 and earlier need to manually replace config.guess and config.sub
+%if ( 0%{?rhel} && 0%{?rhel} <= 6 )
+./autogen.sh
+%endif
+
+%configure \
+ %{?_with_asan} \
%{?_with_cmocka} \
%{?_with_debug} \
+ %{?_with_firewalld} \
+ %{?_with_gnfs} \
%{?_with_tmpfilesdir} \
- %{?_without_bd} \
+ %{?_with_tsan} \
+ %{?_with_valgrind} \
%{?_without_epoll} \
+ %{?_without_events} \
%{?_without_fusermount} \
%{?_without_georeplication} \
- %{?_with_firewalld} \
%{?_without_ocf} \
- %{?_without_qemu_block} \
- %{?_without_rdma} \
+ %{?_without_server} \
%{?_without_syslog} \
- %{?_without_systemtap} \
- %{?_without_tiering}
+ %{?_with_ipv6default} \
+ %{?_without_libtirpc}
# fix hardening and remove rpath in shlibs
%if ( 0%{?fedora} && 0%{?fedora} > 17 ) || ( 0%{?rhel} && 0%{?rhel} > 6 )
@@ -620,36 +852,13 @@ sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|' libtool
make %{?_smp_mflags}
-# Build Glupy
-pushd xlators/features/glupy/src
-FLAGS="$RPM_OPT_FLAGS" python setup.py build
-popd
-
%check
make check
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
-# install the Glupy Python library in /usr/lib/python*/site-packages
-pushd xlators/features/glupy/src
-python setup.py install --skip-build --verbose --root %{buildroot}
-popd
-# Install include directory
-mkdir -p %{buildroot}%{_includedir}/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/
+%if ( 0%{!?_without_server:1} )
%if ( 0%{_for_fedora_koji_builds} )
install -D -p -m 0644 %{SOURCE1} \
%{buildroot}%{_sysconfdir}/sysconfig/glusterd
@@ -659,20 +868,12 @@ install -D -p -m 0644 %{SOURCE2} \
install -D -p -m 0644 extras/glusterd-sysconfig \
%{buildroot}%{_sysconfdir}/sysconfig/glusterd
%endif
-
-%if ( 0%{_for_fedora_koji_builds} )
-%if ( 0%{?rhel} && 0%{?rhel} <= 5 )
-install -D -p -m 0755 %{SOURCE6} \
- %{buildroot}%{_sysconfdir}/sysconfig/modules/glusterfs-fuse.modules
-%endif
%endif
mkdir -p %{buildroot}%{_localstatedir}/log/glusterd
mkdir -p %{buildroot}%{_localstatedir}/log/glusterfs
mkdir -p %{buildroot}%{_localstatedir}/log/glusterfsd
-mkdir -p %{buildroot}%{_localstatedir}/run/gluster
-touch %{buildroot}%{python_sitelib}/gluster/__init__.py
-
+mkdir -p %{buildroot}%{_rundir}/gluster
# Remove unwanted files from all the shared libraries
find %{buildroot}%{_libdir} -name '*.a' -delete
@@ -695,33 +896,40 @@ https://forge.gluster.org/glusterfs-core/glusterfs/commits/v%{version}%{?prerelt
EOM
# Remove benchmarking and other unpackaged files
-%if ( 0%{?rhel} && 0%{?rhel} < 6 )
-rm -rf %{buildroot}/benchmarking
-rm -f %{buildroot}/glusterfs-mode.el
-rm -f %{buildroot}/glusterfs.vim
-%else
# make install always puts these in %%{_defaultdocdir}/%%{name} so don't
# use %%{_pkgdocdir}; that will be wrong on later Fedora distributions
rm -rf %{buildroot}%{_defaultdocdir}/%{name}/benchmarking
rm -f %{buildroot}%{_defaultdocdir}/%{name}/glusterfs-mode.el
rm -f %{buildroot}%{_defaultdocdir}/%{name}/glusterfs.vim
-%endif
+%if ( 0%{!?_without_server:1} )
# 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
+%endif
# Install glusterfsd .service or init.d file
+%if ( 0%{!?_without_server:1} )
%if ( 0%{_for_fedora_koji_builds} )
-%_init_install %{glusterfsd_service} glusterfsd
+%service_install glusterfsd %{glusterfsd_svcfile}
+%endif
%endif
install -D -p -m 0644 extras/glusterfs-logrotate \
%{buildroot}%{_sysconfdir}/logrotate.d/glusterfs
+# ganesha ghosts
+%if ( 0%{!?_without_server:1} )
+mkdir -p %{buildroot}%{_sysconfdir}/ganesha
+touch %{buildroot}%{_sysconfdir}/ganesha/ganesha-ha.conf
+mkdir -p %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/
+touch %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha.conf
+touch %{buildroot}%{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha-ha.conf
+%endif
+
%if ( 0%{!?_without_georeplication:1} )
# geo-rep ghosts
mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/geo-replication
@@ -730,78 +938,26 @@ install -D -p -m 0644 extras/glusterfs-georep-logrotate \
%{buildroot}%{_sysconfdir}/logrotate.d/glusterfs-georep
%endif
-%if ( 0%{!?_without_syslog:1} )
-%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} > 6 )
-install -D -p -m 0644 extras/gluster-rsyslog-7.2.conf \
- %{buildroot}%{_sysconfdir}/rsyslog.d/gluster.conf.example
-%endif
-
-%if ( 0%{?rhel} && 0%{?rhel} == 6 )
-install -D -p -m 0644 extras/gluster-rsyslog-5.8.conf \
- %{buildroot}%{_sysconfdir}/rsyslog.d/gluster.conf.example
-%endif
-
-%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} >= 6 )
-install -D -p -m 0644 extras/logger.conf.example \
- %{buildroot}%{_sysconfdir}/glusterfs/logger.conf.example
-%endif
-%endif
-
+%if ( 0%{!?_without_server:1} )
# the rest of the ghosts
touch %{buildroot}%{_sharedstatedir}/glusterd/glusterd.info
touch %{buildroot}%{_sharedstatedir}/glusterd/options
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/stop
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/stop/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/stop/pre
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/start
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/start/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/start/pre
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/reset
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/reset/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/reset/pre
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/remove-brick
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/remove-brick/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/remove-brick/pre
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/add-brick
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/add-brick/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/add-brick/pre
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/set
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/set/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/set/pre
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/create
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/create/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/create/pre
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/delete
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/delete/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/delete/pre
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/copy-file
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/copy-file/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/copy-file/pre
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/gsync-create
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/gsync-create/post
-mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/gsync-create/pre
+subdirs=(add-brick create copy-file delete gsync-create remove-brick reset set start stop)
+for dir in ${subdirs[@]}; do
+ mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/"$dir"/{pre,post}
+done
mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/glustershd
mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/peers
mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/vols
mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/nfs/run
+mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/bitd
+mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/quotad
+mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/scrub
+mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/snaps
+mkdir -p %{buildroot}%{_sharedstatedir}/glusterd/ss_brick
touch %{buildroot}%{_sharedstatedir}/glusterd/nfs/nfs-server.vol
touch %{buildroot}%{_sharedstatedir}/glusterd/nfs/run/nfs.pid
-
-%{__install} -p -m 0744 extras/hook-scripts/start/post/*.sh \
- %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/start/post
-%{__install} -p -m 0744 extras/hook-scripts/stop/pre/*.sh \
- %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/stop/pre
-%{__install} -p -m 0744 extras/hook-scripts/set/post/*.sh \
- %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/set/post
-%{__install} -p -m 0744 extras/hook-scripts/add-brick/post/*.sh \
- %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/add-brick/post
-%{__install} -p -m 0744 extras/hook-scripts/add-brick/pre/*.sh \
- %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/add-brick/pre
-%{__install} -p -m 0744 extras/hook-scripts/reset/post/*.sh \
- %{buildroot}%{_sharedstatedir}/glusterd/hooks/1/reset/post
-
+%endif
find ./tests ./run-tests.sh -type f | cpio -pd %{buildroot}%{_prefix}/share/glusterfs
@@ -809,43 +965,70 @@ find ./tests ./run-tests.sh -type f | cpio -pd %{buildroot}%{_prefix}/share/glus
install -p -m 0744 -D extras/command-completion/gluster.bash \
%{buildroot}%{_sysconfdir}/bash_completion.d/gluster
-
%clean
rm -rf %{buildroot}
##-----------------------------------------------------------------------------
-## All %post should be placed here and keep them sorted
+## All %%post should be placed here and keep them sorted
##
%post
+/sbin/ldconfig
%if ( 0%{!?_without_syslog:1} )
%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} >= 6 )
-%_init_restart rsyslog
+%systemd_postun_with_restart rsyslog
%endif
%endif
+exit 0
-%post api
-/sbin/ldconfig
+%if ( 0%{!?_without_events:1} )
+%post events
+%systemd_post glustereventsd
+%endif
-%post fuse
-%if ( 0%{?rhel} == 5 )
-modprobe fuse
+%if ( 0%{!?_without_server:1} )
+%if ( 0%{?fedora} && 0%{?fedora} > 25 || ( 0%{?rhel} && 0%{?rhel} > 6 ) )
+%post ganesha
+semanage boolean -m ganesha_use_fusefs --on
+exit 0
+%endif
%endif
%if ( 0%{!?_without_georeplication:1} )
%post geo-replication
-#restart glusterd.
+%if ( 0%{?rhel} && 0%{?rhel} >= 8 )
+%selinux_set_booleans %{selinuxbooleans}
+%endif
if [ $1 -ge 1 ]; then
- %_init_restart glusterd
+ %systemd_postun_with_restart glusterd
fi
+exit 0
%endif
-%post libs
+%post -n libglusterfs0
+/sbin/ldconfig
+
+%post -n libgfapi0
+/sbin/ldconfig
+
+%post -n libgfchangelog0
+/sbin/ldconfig
+
+%post -n libgfrpc0
+/sbin/ldconfig
+
+%post -n libgfxdr0
+/sbin/ldconfig
+
+%post -n libglusterd0
/sbin/ldconfig
+%if ( 0%{!?_without_server:1} )
%post server
# Legacy server
-%_init_enable glusterd
-%_init_enable glusterfsd
+%systemd_post glusterd
+%if ( 0%{_for_fedora_koji_builds} )
+%systemd_post glusterfsd
+%endif
# ".cmd_log_history" is renamed to "cmd_history.log" in GlusterFS-3.7 .
# While upgrading glusterfs-server package form GlusterFS version <= 3.6 to
# GlusterFS version 3.7, ".cmd_log_history" should be renamed to
@@ -886,11 +1069,7 @@ if [ -e /etc/ld.so.conf.d/glusterfs.conf ]; then
fi
%if (0%{?_with_firewalld:1})
-#reload service files if firewalld running
-if $(systemctl is-active firewalld 1>/dev/null 2>&1); then
- #firewalld-filesystem is not available for rhel7, so command used for reload.
- firewall-cmd --reload
-fi
+ %firewalld_reload
%endif
pidof -c -o %PPID -x glusterd &> /dev/null
@@ -902,246 +1081,366 @@ if [ $? -eq 0 ]; then
#Cleaning leftover glusterd socket file which is created by glusterd in
#rpm_script_t context.
- rm -rf /var/run/glusterd.socket
+ rm -f %{_rundir}/glusterd.socket
# glusterd _was_ running, we killed it, it exited after *.upgrade=on,
# so start it again
- %_init_start glusterd
+ %service_start glusterd
else
glusterd --xlator-option *.upgrade=on -N
#Cleaning leftover glusterd socket file which is created by glusterd in
#rpm_script_t context.
- rm -rf /var/run/glusterd.socket
+ rm -f %{_rundir}/glusterd.socket
fi
+exit 0
+%endif
##-----------------------------------------------------------------------------
-## All %preun should be placed here and keep them sorted
+## All %%pre should be placed here and keep them sorted
##
+%pre
+getent group gluster > /dev/null || groupadd -r gluster
+getent passwd gluster > /dev/null || useradd -r -g gluster -d %{_rundir}/gluster -s /sbin/nologin -c "GlusterFS daemons" gluster
+exit 0
+
+##-----------------------------------------------------------------------------
+## All %%preun should be placed here and keep them sorted
+##
+%if ( 0%{!?_without_events:1} )
+%preun events
+if [ $1 -eq 0 ]; then
+ if [ -f %glustereventsd_svcfile ]; then
+ %service_stop glustereventsd
+ %systemd_preun glustereventsd
+ fi
+fi
+exit 0
+%endif
+
+%if ( 0%{!?_without_server:1} )
%preun server
if [ $1 -eq 0 ]; then
- if [ -f %_init_glusterfsd ]; then
- %_init_stop glusterfsd
+ if [ -f %glusterfsd_svcfile ]; then
+ %service_stop glusterfsd
fi
- %_init_stop glusterd
- if [ -f %_init_glusterfsd ]; then
- %_init_disable glusterfsd
+ %service_stop glusterd
+ if [ -f %glusterfsd_svcfile ]; then
+ %systemd_preun glusterfsd
fi
- %_init_disable glusterd
+ %systemd_preun glusterd
fi
if [ $1 -ge 1 ]; then
- if [ -f %_init_glusterfsd ]; then
- %_init_restart glusterfsd
+ if [ -f %glusterfsd_svcfile ]; then
+ %systemd_postun_with_restart glusterfsd
+ fi
+ %systemd_postun_with_restart glusterd
+fi
+exit 0
+%endif
+
+%preun thin-arbiter
+if [ $1 -eq 0 ]; then
+ if [ -f %glusterta_svcfile ]; then
+ %service_stop gluster-ta-volume
+ %systemd_preun gluster-ta-volume
fi
- %_init_restart glusterd
fi
##-----------------------------------------------------------------------------
-## All %postun should be placed here and keep them sorted
+## All %%postun should be placed here and keep them sorted
##
%postun
-/sbin/ldconfig
%if ( 0%{!?_without_syslog:1} )
%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} >= 6 )
-%_init_restart rsyslog
+%systemd_postun_with_restart rsyslog
%endif
%endif
-%postun api
-/sbin/ldconfig
-
+%if ( 0%{!?_without_server:1} )
%postun server
%if (0%{?_with_firewalld:1})
-#reload service files if firewalld running
-if $(systemctl is-active firewalld 1>/dev/null 2>&1); then
- firewall-cmd --reload
-fi
+ %firewalld_reload
+%endif
+exit 0
%endif
+%if ( 0%{!?_without_server:1} )
+%if ( 0%{?fedora} && 0%{?fedora} > 25 || ( 0%{?rhel} && 0%{?rhel} > 6 ) )
+%postun ganesha
+semanage boolean -m ganesha_use_fusefs --off
+exit 0
+%endif
+%endif
-%postun libs
-/sbin/ldconfig
+##-----------------------------------------------------------------------------
+## All %%trigger should be placed here and keep them sorted
+##
+%if ( 0%{!?_without_server:1} )
+%if ( 0%{?fedora} && 0%{?fedora} > 25 || ( 0%{?rhel} && 0%{?rhel} > 6 ) )
+%trigger ganesha -- selinux-policy-targeted
+semanage boolean -m ganesha_use_fusefs --on
+exit 0
+%endif
+%endif
##-----------------------------------------------------------------------------
-## All files should be placed here and keep them grouped
+## All %%triggerun should be placed here and keep them sorted
##
-%files
-%doc ChangeLog COPYING-GPLV2 COPYING-LGPLV3 INSTALL README.md THANKS
-%if ( 0%{!?_without_syslog:1} )
-%if ( 0%{?fedora} ) || ( 0%{?rhel} && 0%{?rhel} >= 6 )
-%{_sysconfdir}/rsyslog.d/gluster.conf.example
+%if ( 0%{!?_without_server:1} )
+%if ( 0%{?fedora} && 0%{?fedora} > 25 || ( 0%{?rhel} && 0%{?rhel} > 6 ) )
+%triggerun ganesha -- selinux-policy-targeted
+semanage boolean -m ganesha_use_fusefs --off
+exit 0
%endif
%endif
+
+##-----------------------------------------------------------------------------
+## All %%files should be placed here and keep them grouped
+##
+%files
+%doc ChangeLog COPYING-GPLV2 COPYING-LGPLV3 INSTALL README.md THANKS COMMITMENT
%{_mandir}/man8/*gluster*.8*
+%if ( 0%{!?_without_server:1} )
%exclude %{_mandir}/man8/gluster.8*
-%dir %{_localstatedir}/log/glusterfs
-%if ( 0%{!?_without_rdma:1} )
-%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/rpc-transport/rdma*
%endif
+%dir %{_localstatedir}/log/glusterfs
+%if 0%{?!_without_server:1}
+%dir %{_datadir}/glusterfs
%dir %{_datadir}/glusterfs/scripts
-%{_datadir}/glusterfs/scripts/post-upgrade-script-for-quota.sh
-%{_datadir}/glusterfs/scripts/pre-upgrade-script-for-quota.sh
+ %{_datadir}/glusterfs/scripts/post-upgrade-script-for-quota.sh
+ %{_datadir}/glusterfs/scripts/pre-upgrade-script-for-quota.sh
+%endif
# xlators that are needed on the client- and on the server-side
+%dir %{_libdir}/glusterfs
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}
%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/auth
-%{_libdir}/glusterfs/%{version}%{?prereltag}/auth/addr.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/auth/login.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/auth/addr.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/auth/login.so
%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/rpc-transport
-%{_libdir}/glusterfs/%{version}%{?prereltag}/rpc-transport/socket.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/rpc-transport/socket.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator
%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/error-gen.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/io-stats.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/trace.so
-%if ( ! ( 0%{?rhel} && 0%{?rhel} < 6 ) )
-# RHEL-5 based distributions have a too old openssl
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption/crypt.so
-%endif
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/access-control.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/barrier.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/cdc.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/changelog.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/gfid-access.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/read-only.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/shard.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/snapview-client.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/worm.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/meta.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/io-cache.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/io-threads.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/md-cache.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/open-behind.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/quick-read.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/read-ahead.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/readdir-ahead.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/stat-prefetch.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/write-behind.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/system/posix-acl.so
-
-
-%files api
-%exclude %{_libdir}/*.so
-# libgfapi files
-%{_libdir}/libgfapi.*
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount/api.so
-
-%files api-devel
-%{_libdir}/pkgconfig/glusterfs-api.pc
-%{_libdir}/libgfapi.so
-%{_includedir}/glusterfs/api/*
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/error-gen.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/delay-gen.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/io-stats.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/sink.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/debug/trace.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/access-control.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/barrier.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/cdc.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/changelog.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/utime.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/gfid-access.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/namespace.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/read-only.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/shard.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/snapview-client.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/worm.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/cloudsync.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/meta.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/io-cache.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/io-threads.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/md-cache.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/open-behind.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/quick-read.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/read-ahead.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/readdir-ahead.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/stat-prefetch.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/write-behind.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/performance/nl-cache.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/system
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/system/posix-acl.so
+%dir %attr(0775,gluster,gluster) %{_rundir}/gluster
+%if 0%{?_tmpfilesdir:1} && 0%{!?_without_server:1}
+%{_tmpfilesdir}/gluster.conf
+%endif
+
+%if ( 0%{?_without_server:1} )
+#exclude ganesha related files
+%exclude %{_sysconfdir}/ganesha/ganesha-ha.conf.sample
+%exclude %{_libexecdir}/ganesha/*
+%exclude %{_prefix}/lib/ocf/resource.d/heartbeat/*
+%endif
%files cli
%{_sbindir}/gluster
%{_mandir}/man8/gluster.8*
%{_sysconfdir}/bash_completion.d/gluster
-%files devel
-%{_includedir}/glusterfs
-%exclude %{_includedir}/glusterfs/y.tab.h
-%exclude %{_includedir}/glusterfs/api
-%exclude %{_libdir}/libgfapi.so
-%{_libdir}/*.so
-# Glupy Translator examples
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/debug-trace.*
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/helloworld.*
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy/negative.*
+%files cloudsync-plugins
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/cloudsync-plugins
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/cloudsync-plugins/cloudsyncs3.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/cloudsync-plugins/cloudsynccvlt.so
+
+%files -n libglusterfs-devel
+%dir %{_includedir}/glusterfs
+ %{_includedir}/glusterfs/*.h
+ %{_includedir}/glusterfs/server/*.h
+%{_libdir}/libglusterfs.so
+
+%files -n libgfapi-devel
+%dir %{_includedir}/glusterfs/api
+ %{_includedir}/glusterfs/api/*.h
+%{_libdir}/libgfapi.so
+%{_libdir}/pkgconfig/glusterfs-api.pc
+
+
+%files -n libgfchangelog-devel
+%dir %{_includedir}/glusterfs/gfchangelog
+ %{_includedir}/glusterfs/gfchangelog/*.h
+%{_libdir}/libgfchangelog.so
%{_libdir}/pkgconfig/libgfchangelog.pc
-%if ( 0%{!?_without_tiering:1} )
-%{_libdir}/pkgconfig/libgfdb.pc
-%endif
+
+%files -n libgfrpc-devel
+%dir %{_includedir}/glusterfs/rpc
+ %{_includedir}/glusterfs/rpc/*.h
+%{_libdir}/libgfrpc.so
+
+%files -n libgfxdr-devel
+%{_libdir}/libgfxdr.so
%files client-xlators
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster/*.so
-%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster/pump.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/ganesha.so
-%if ( 0%{!?_without_qemu_block:1} )
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/qemu-block.so
-%endif
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/client.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster/*.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/client.so
%files extra-xlators
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/encryption/rot-13.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/glupy.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/mac-compat.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/prot_client.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/prot_dht.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/prot_server.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/quiesce.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/testing/features/template.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/testing/performance/symlink-cache.so
-# Glupy Python files
-%{python_sitelib}/gluster/glupy/*
-# Don't expect a .egg-info file on EL5
-%if ( ! ( 0%{?rhel} && 0%{?rhel} < 6 ) )
-%{python_sitelib}/glusterfs_glupy*.egg-info
-%endif
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/quiesce.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/playground
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/playground/template.so
%files fuse
# glusterfs is a symlink to glusterfsd, -server depends on -fuse.
%{_sbindir}/glusterfs
%{_sbindir}/glusterfsd
%config(noreplace) %{_sysconfdir}/logrotate.d/glusterfs
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount/fuse.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount/fuse.so
/sbin/mount.glusterfs
%if ( 0%{!?_without_fusermount:1} )
%{_bindir}/fusermount-glusterfs
%endif
-%if ( 0%{_for_fedora_koji_builds} )
-%if ( 0%{?rhel} && 0%{?rhel} <= 5 )
-%{_sysconfdir}/sysconfig/modules/glusterfs-fuse.modules
-%endif
+
+%if ( 0%{?_with_gnfs:1} && 0%{!?_without_server:1} )
+%files gnfs
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs/server.so
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs
+%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/nfs-server.vol
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs/run
+%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/run/nfs.pid
%endif
-%files ganesha
-%{_sysconfdir}/ganesha/*
-%attr(0755,-,-) %{_libexecdir}/ganesha/*
-%attr(0755,-,-) %{_prefix}/lib/ocf/resource.d/heartbeat/*
+%files thin-arbiter
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/thin-arbiter.so
+%dir %{_datadir}/glusterfs/scripts
+ %{_datadir}/glusterfs/scripts/setup-thin-arbiter.sh
+%config %{_sysconfdir}/glusterfs/thin-arbiter.vol
+
+%if ( 0%{?_with_systemd:1} )
+%{_unitdir}/gluster-ta-volume.service
+%endif
%if ( 0%{!?_without_georeplication:1} )
%files geo-replication
%config(noreplace) %{_sysconfdir}/logrotate.d/glusterfs-georep
-%{_libexecdir}/glusterfs/gsyncd
-%{_libexecdir}/glusterfs/python/syncdaemon/*
-%{_libexecdir}/glusterfs/gverify.sh
-%{_libexecdir}/glusterfs/set_geo_rep_pem_keys.sh
-%{_libexecdir}/glusterfs/peer_gsec_create
-%{_libexecdir}/glusterfs/peer_mountbroker
-%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/geo-replication
-%dir %{_sharedstatedir}/glusterd/hooks
-%dir %{_sharedstatedir}/glusterd/hooks/1
-%dir %{_sharedstatedir}/glusterd/hooks/1/gsync-create
-%dir %{_sharedstatedir}/glusterd/hooks/1/gsync-create/post
-%{_sharedstatedir}/glusterd/hooks/1/gsync-create/post/S56glusterd-geo-rep-create-post.sh
-%{_datadir}/glusterfs/scripts/get-gfid.sh
-%{_datadir}/glusterfs/scripts/slave-upgrade.sh
-%{_datadir}/glusterfs/scripts/gsync-upgrade.sh
-%{_datadir}/glusterfs/scripts/generate-gfid-file.sh
-%{_datadir}/glusterfs/scripts/gsync-sync-gfid
-%ghost %attr(0644,-,-) %{_sharedstatedir}/glusterd/geo-replication/gsyncd_template.conf
-%endif
-%{_libexecdir}/glusterfs/gfind_missing_files
-%{_sbindir}/gfind_missing_files
-%files libs
-%{_libdir}/*.so.*
-%exclude %{_libdir}/libgfapi.*
-%if ( 0%{!?_without_tiering:1} )
-# libgfdb is only needed server-side
-%exclude %{_libdir}/libgfdb.*
-%endif
-
-%files -n python-gluster
+%{_sbindir}/gfind_missing_files
+%{_sbindir}/gluster-mountbroker
+%dir %{_libexecdir}/glusterfs
+%dir %{_libexecdir}/glusterfs/python
+%dir %{_libexecdir}/glusterfs/python/syncdaemon
+ %{_libexecdir}/glusterfs/gsyncd
+ %{_libexecdir}/glusterfs/python/syncdaemon/*
+%dir %{_libexecdir}/glusterfs/scripts
+ %{_libexecdir}/glusterfs/scripts/get-gfid.sh
+ %{_libexecdir}/glusterfs/scripts/slave-upgrade.sh
+ %{_libexecdir}/glusterfs/scripts/gsync-upgrade.sh
+ %{_libexecdir}/glusterfs/scripts/generate-gfid-file.sh
+ %{_libexecdir}/glusterfs/scripts/gsync-sync-gfid
+ %{_libexecdir}/glusterfs/scripts/schedule_georep.py*
+ %{_libexecdir}/glusterfs/gverify.sh
+ %{_libexecdir}/glusterfs/set_geo_rep_pem_keys.sh
+ %{_libexecdir}/glusterfs/peer_gsec_create
+ %{_libexecdir}/glusterfs/peer_mountbroker
+ %{_libexecdir}/glusterfs/peer_mountbroker.py*
+ %{_libexecdir}/glusterfs/gfind_missing_files
+ %{_libexecdir}/glusterfs/peer_georep-sshkey.py*
+%{_sbindir}/gluster-georep-sshkey
+
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/geo-replication
+%ghost %attr(0644,-,-) %{_sharedstatedir}/glusterd/geo-replication/gsyncd_template.conf
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/gsync-create
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/gsync-create/post
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/gsync-create/post/S56glusterd-geo-rep-create-post.sh
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/gsync-create/pre
+
+%endif
+
+%files -n libglusterfs0
+%{_libdir}/libglusterfs.so.*
+
+%files -n libgfapi0
+%{_libdir}/libgfapi.so.*
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mount/api.so
+
+%files -n libgfchangelog0
+%{_libdir}/libgfchangelog.so.*
+
+%files -n libgfrpc0
+%{_libdir}/libgfrpc.so.*
+
+%files -n libgfxdr0
+%{_libdir}/libgfxdr.so.*
+
+%files -n libglusterd0
+%{_libdir}/libglusterd.so.*
+%exclude %{_libdir}/libglusterd.so
+
+%files -n python%{_pythonver}-gluster
# introducing glusterfs module in site packages.
# so that all other gluster submodules can reside in the same namespace.
-%{python_sitelib}/gluster/__init__.*
-
-%if ( 0%{!?_without_rdma:1} )
-%files rdma
-%{_libdir}/glusterfs/%{version}%{?prereltag}/rpc-transport/rdma*
+%if ( %{_usepython3} )
+%dir %{python3_sitelib}/gluster
+ %{python3_sitelib}/gluster/__init__.*
+ %{python3_sitelib}/gluster/__pycache__
+ %{python3_sitelib}/gluster/cliutils
+%else
+%dir %{python2_sitelib}/gluster
+ %{python2_sitelib}/gluster/__init__.*
+ %{python2_sitelib}/gluster/cliutils
%endif
%files regression-tests
-%{_prefix}/share/glusterfs/run-tests.sh
-%{_prefix}/share/glusterfs/tests
-%exclude %{_prefix}/share/glusterfs/tests/basic/rpm.t
+%dir %{_datadir}/glusterfs
+ %{_datadir}/glusterfs/run-tests.sh
+ %{_datadir}/glusterfs/tests
+%exclude %{_datadir}/glusterfs/tests/vagrant
+
+%if ( 0%{!?_without_server:1} )
+%files ganesha
+%dir %{_libexecdir}/ganesha
+%{_sysconfdir}/ganesha/ganesha-ha.conf.sample
+%{_libexecdir}/ganesha/*
+%{_prefix}/lib/ocf/resource.d/heartbeat/*
+%{_sharedstatedir}/glusterd/hooks/1/start/post/S31ganesha-start.sh
+%ghost %attr(0644,-,-) %config(noreplace) %{_sysconfdir}/ganesha/ganesha-ha.conf
+%ghost %dir %attr(0755,-,-) %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha
+%ghost %attr(0644,-,-) %config(noreplace) %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha.conf
+%ghost %attr(0644,-,-) %config(noreplace) %{_localstatedir}/run/gluster/shared_storage/nfs-ganesha/ganesha-ha.conf
+%endif
%if ( 0%{!?_without_ocf:1} )
%files resource-agents
@@ -1149,122 +1448,374 @@ fi
%{_prefix}/lib/ocf/resource.d/glusterfs
%endif
+%if ( 0%{!?_without_server:1} )
%files server
%doc extras/clear_xattrs.sh
-%config(noreplace) %{_sysconfdir}/sysconfig/glusterd
+# sysconf
%config(noreplace) %{_sysconfdir}/glusterfs
-%dir %{_localstatedir}/run/gluster
-%if 0%{?_tmpfilesdir:1}
-%{_tmpfilesdir}/gluster.conf
+%exclude %{_sysconfdir}/glusterfs/thin-arbiter.vol
+%exclude %{_sysconfdir}/glusterfs/eventsconfig.json
+%exclude %{_sharedstatedir}/glusterd/nfs/nfs-server.vol
+%exclude %{_sharedstatedir}/glusterd/nfs/run/nfs.pid
+%if ( 0%{?_with_gnfs:1} )
+%exclude %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs/*
%endif
-%dir %{_sharedstatedir}/glusterd
-%dir %{_sharedstatedir}/glusterd/groups
-%config(noreplace) %{_sharedstatedir}/glusterd/groups/virt
-# Legacy configs
+%config(noreplace) %{_sysconfdir}/sysconfig/glusterd
%if ( 0%{_for_fedora_koji_builds} )
%config(noreplace) %{_sysconfdir}/sysconfig/glusterfsd
%endif
-%config %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/disabled-quota-root-xattr-heal.sh
-%config %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre/S28Quota-enable-root-xattr-heal.sh
-%config %{_sharedstatedir}/glusterd/hooks/1/set/post/S30samba-set.sh
-%config %{_sharedstatedir}/glusterd/hooks/1/set/post/S32gluster_enable_shared_storage.sh
-%config %{_sharedstatedir}/glusterd/hooks/1/start/post/S29CTDBsetup.sh
-%config %{_sharedstatedir}/glusterd/hooks/1/start/post/S30samba-start.sh
-%config %{_sharedstatedir}/glusterd/hooks/1/start/post/S31ganesha-start.sh
-%config %{_sharedstatedir}/glusterd/hooks/1/stop/pre/S30samba-stop.sh
-%config %{_sharedstatedir}/glusterd/hooks/1/stop/pre/S29CTDB-teardown.sh
-%config %{_sharedstatedir}/glusterd/hooks/1/reset/post/S31ganesha-reset.sh
+
# init files
-%_init_glusterd
+%glusterd_svcfile
%if ( 0%{_for_fedora_koji_builds} )
-%_init_glusterfsd
+%glusterfsd_svcfile
%endif
+%if ( 0%{?_with_systemd:1} )
+%glusterfssharedstorage_svcfile
+%endif
+
# binaries
%{_sbindir}/glusterd
-%{_sbindir}/glfsheal
+%{_libexecdir}/glusterfs/glfsheal
+%{_sbindir}/gf_attach
+%{_sbindir}/gluster-setgfid2path
# {_sbindir}/glusterfsd is the actual binary, but glusterfs (client) is a
# symlink. The binary itself (and symlink) are part of the glusterfs-fuse
# package, because glusterfs-server depends on that anyway.
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/cluster/pump.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/arbiter.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/bit-rot.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/bitrot-stub.so
-%if ( 0%{!?_without_tiering:1} )
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/changetimerecorder.so
-%endif
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/index.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/locks.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/posix*
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/snapview-server.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/marker.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/quota*
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/trash.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/upcall.so
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mgmt*
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/nfs*
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/server*
-%{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/storage*
-%if ( 0%{!?_without_tiering:1} )
-%{_libdir}/libgfdb.so.*
-%endif
-
-#snap_scheduler
+
+# Manpages
+%{_mandir}/man8/gluster-setgfid2path.8*
+
+# xlators
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/arbiter.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/bit-rot.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/bitrot-stub.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/sdfs.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/index.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/locks.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/posix*
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/snapview-server.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/marker.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/quota*
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/selinux.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/trash.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/upcall.so
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/features/leases.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mgmt
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/mgmt/glusterd.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/protocol/server.so
+%dir %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/storage
+ %{_libdir}/glusterfs/%{version}%{?prereltag}/xlator/storage/posix.so
+
+# snap_scheduler
%{_sbindir}/snap_scheduler.py
%{_sbindir}/gcron.py
-
-#hookscripts
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/set
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/set/post
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start/post
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/pre
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete
-%dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/post
-
-%ghost %attr(0644,-,-) %config(noreplace) %{_sharedstatedir}/glusterd/glusterd.info
-%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/options
-# This is really ugly, but I have no idea how to mark these directories in
-# any 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/1/stop/post
-%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start/pre
+%{_sbindir}/conf.py
+
+# /var/lib/glusterd, e.g. hookscripts, etc.
+%ghost %attr(0644,-,-) %config(noreplace) %{_sharedstatedir}/glusterd/glusterd.info
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/bitd
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/groups
+ %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/virt
+ %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/metadata-cache
+ %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/gluster-block
+ %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/nl-cache
+ %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/db-workload
+ %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/distributed-virt
+ %attr(0644,-,-) %{_sharedstatedir}/glusterd/groups/samba
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glusterfind
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glusterfind/.keys
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glustershd
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/disabled-quota-root-xattr-heal.sh
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/S10selinux-label-brick.sh
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/post/S13create-subdir-mounts.sh
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/add-brick/pre/S28Quota-enable-root-xattr-heal.sh
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/post
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/post/S10selinux-label-brick.sh
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/create/pre
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/copy-file
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/copy-file/post
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/copy-file/pre
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/post
+ %{_sharedstatedir}/glusterd/hooks/1/delete/post/S57glusterfind-delete-post
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/pre
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/delete/pre/S10selinux-del-fcontext.sh
%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
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/reset
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/reset/post
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/reset/pre
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/set
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/set/post
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/set/post/S30samba-set.sh
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/set/post/S32gluster_enable_shared_storage.sh
%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/pre
-%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/glustershd
-%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/vols
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start/post
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start/post/S29CTDBsetup.sh
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start/post/S30samba-start.sh
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/start/pre
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/post
+ %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/pre
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/pre/S30samba-stop.sh
+ %attr(0755,-,-) %{_sharedstatedir}/glusterd/hooks/1/stop/pre/S29CTDB-teardown.sh
+%config(noreplace) %ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/options
%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/peers
-%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs
-%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/nfs-server.vol
-%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/nfs/run
-%ghost %attr(0600,-,-) %{_sharedstatedir}/glusterd/nfs/run/nfs.pid
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/quotad
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/scrub
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/snaps
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/ss_brick
+%ghost %dir %attr(0755,-,-) %{_sharedstatedir}/glusterd/vols
# Extra utility script
-%{_datadir}/glusterfs/scripts/stop-all-gluster-processes.sh
+%dir %{_libexecdir}/glusterfs
+%dir %{_datadir}/glusterfs/scripts
+ %{_datadir}/glusterfs/scripts/stop-all-gluster-processes.sh
+%if ( 0%{?_with_systemd:1} )
+ %{_libexecdir}/glusterfs/mount-shared-storage.sh
+ %{_datadir}/glusterfs/scripts/control-cpu-load.sh
+ %{_datadir}/glusterfs/scripts/control-mem.sh
+%endif
# Incrementalapi
-%{_libexecdir}/glusterfs/glusterfind
+ %{_libexecdir}/glusterfs/glusterfind
%{_bindir}/glusterfind
-%{_libexecdir}/glusterfs/peer_add_secret_pub
-%{_sharedstatedir}/glusterd/hooks/1/delete/post/S57glusterfind-delete-post.py
+ %{_libexecdir}/glusterfs/peer_add_secret_pub
%if ( 0%{?_with_firewalld:1} )
-/usr/lib/firewalld/services/glusterfs.xml
+%{_prefix}/lib/firewalld/services/glusterfs.xml
+%endif
+# end of server files
%endif
+# Events
+%if ( 0%{!?_without_events:1} )
+%files events
+%config(noreplace) %{_sysconfdir}/glusterfs/eventsconfig.json
+%dir %{_sharedstatedir}/glusterd
+%dir %{_sharedstatedir}/glusterd/events
+%dir %{_libexecdir}/glusterfs
+ %{_libexecdir}/glusterfs/gfevents
+ %{_libexecdir}/glusterfs/peer_eventsapi.py*
+%{_sbindir}/glustereventsd
+%{_sbindir}/gluster-eventsapi
+%{_datadir}/glusterfs/scripts/eventsdash.py*
+%if ( 0%{?_with_systemd:1} )
+%{_unitdir}/glustereventsd.service
+%else
+%{_sysconfdir}/init.d/glustereventsd
+%endif
+%endif
%changelog
+* Thu May 14 2020 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- refactor, common practice, Issue #1126
+
+* Mon May 11 2020 Sunny Kumar <sunkumar@redhat.com>
+- added requires policycoreutils-python-utils on rhel8 for geo-replication
+
+* Wed Oct 9 2019 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- remove leftover bd xlator cruft
+
+* Fri Aug 23 2019 Shwetha K Acharya <sacharya@redhat.com>
+- removed {name}-ufs from Obsoletes
+- added "< version" for obsoletes {name}-gnfs and {name}-rdma
+
+* Mon Jul 15 2019 Jiffin Tony Thottan <jthottan@redhat.com>
+- Adding ganesha ha bits back in gluster repository
+
+* Fri Jul 12 2019 Amar Tumballi <amarts@redhat.com>
+- Remove rdma package, and mark older rdma package as 'Obsoletes'
+
+* Fri Jun 14 2019 Niels de Vos <ndevos@redhat.com>
+- always build glusterfs-cli to allow monitoring/managing from clients
+
+* Wed Mar 6 2019 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- remove unneeded ldconfig in scriptlets
+- reported by Igor Gnatenko in Fedora
+- https://src.fedoraproject.org/rpms/glusterfs/pull-request/5
+
+* Mon Mar 4 2019 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- s390x has RDMA, since around Fedora 27 and in RHEL7 since June 2016.
+
+* Tue Feb 26 2019 Ashish Pandey <aspandey@redhat.com>
+- Add thin-arbiter package
+
+* Sun Feb 24 2019 Aravinda VK <avishwan@redhat.com>
+- Renamed events package to gfevents
+
+* Thu Feb 21 2019 Jiffin Tony Thottan <jthottan@redhat.com>
+- Obsoleting gluster-gnfs package
+
+* Wed Nov 28 2018 Krutika Dhananjay <kdhananj@redhat.com>
+- Install /var/lib/glusterd/groups/distributed-virt by default
+
+* Tue Nov 13 2018 Niels de Vos <ndevos@redhat.com>
+- Add an option to build with ThreadSanitizer (TSAN)
+
+* Fri Sep 7 2018 Niels de Vos <ndevos@redhat.com>
+- Add an option to build with address sanitizer (ASAN)
+
+* Sun Jul 29 2018 Niels de Vos <ndevos@redhat.com>
+- Disable building glusterfs-resource-agents on el6 (#1609551)
+
+* Thu Feb 22 2018 Kotresh HR <khiremat@redhat.com>
+- Added util-linux as dependency to georeplication rpm (#1544382)
+
+* Thu Feb 1 2018 Niels de Vos <ndevos@redhat.com>
+- Add '--without server' option to facilitate el6 builds (#1074947)
+
+* Wed Jan 24 2018 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- python-ctypes no long exists, now in python stdlib (#1538258)
+
+* Thu Jan 18 2018 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- Fedora 28 glibc has removed rpc headers and rpcgen, use libtirpc
+
+* Mon Dec 25 2017 Niels de Vos <ndevos@redhat.com>
+- Fedora 28 has renamed pyxattr
+
+* Wed Sep 27 2017 Mohit Agrawal <moagrawa@redhat.com>
+- Added control-cpu-load.sh and control-mem.sh scripts to glusterfs-server section(#1496335)
+
+* Tue Aug 22 2017 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- libibverbs-devel, librdmacm-devel -> rdma-core-devel #1483995
+
+* Thu Jul 20 2017 Aravinda VK <avishwan@redhat.com>
+- Added new tool/binary to set the gfid2path xattr on files
+
+* Thu Jul 13 2017 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- various directories not owned by any package
+
+* Fri Jun 16 2017 Jiffin Tony Thottan <jthottan@redhat.com>
+- Add glusterfssharedstorage.service systemd file
+
+* Fri Jun 9 2017 Poornima G <pgurusid@redhat.com>
+- Install /var/lib/glusterd/groups/nl-cache by default
+
+* Wed May 10 2017 Pranith Kumar K <pkarampu@redhat.com>
+- Install /var/lib/glusterd/groups/gluster-block by default
+
+* Thu Apr 27 2017 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- gnfs in an optional subpackage
+
+* Wed Apr 26 2017 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- /var/run/gluster owner gluster:gluster(0775) for qemu(gfapi)
+ statedumps (#1445569)
+
+* Mon Apr 24 2017 Jiffin Tony Thottan <jhottan@redhat.com>
+- Install SELinux hook scripts that manage contexts for bricks (#1047975)
+
+* Thu Apr 20 2017 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- firewalld-filesystem -> firewalld (#1443959)
+
+* Thu Apr 13 2017 Niels de Vos <ndevos@redhat.com>
+- the -regression-tests sub-package needs "bc" for some tests (#1442145)
+
+* Mon Mar 20 2017 Niels de Vos <ndevos@redhat.com>
+- Drop dependency on psmisc, pkill is used instead of killall (#1197308)
+
+* Thu Feb 16 2017 Niels de Vos <ndevos@redhat.com>
+- Obsolete and Provide python-gluster for upgrading from glusterfs < 3.10
+
+* Wed Feb 1 2017 Poornima G <pgurusid@redhat.com>
+- Install /var/lib/glusterd/groups/metadata-cache by default
+
+* Wed Jan 18 2017 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- python2 (versus python3) cleanup (#1414902)
+
+* Fri Jan 13 2017 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- switch to storhaug HA
+
+* Fri Jan 6 2017 Niels de Vos <ndevos@redhat.com>
+- use macro provided by firewalld-filesystem to reload firewalld
+
+* Thu Nov 24 2016 Jiffin Tony Thottan <jhottan@redhat.com>
+- remove S31ganesha-reset.sh from hooks (#1397795)
+
+* Thu Sep 22 2016 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- python-ctypes no long exists, now in python stdlib (#1378436)
+
+* Wed Sep 14 2016 Aravinda VK <avishwan@redhat.com>
+- Changed attribute of eventsconfig.json file as same as other configs (#1375532)
+
+* Thu Sep 08 2016 Aravinda VK <avishwan@redhat.com>
+- Added init script for glustereventsd (#1365395)
+
+* Wed Aug 31 2016 Avra Sengupta <asengupt@redhat.com>
+- Added conf.py for snap scheduler
+
+* Wed Aug 31 2016 Aravinda VK <avishwan@redhat.com>
+- Added new Geo-replication utility "gluster-georep-sshkey" (#1356508)
+
+* Thu Aug 25 2016 Aravinda VK <avishwan@redhat.com>
+- Added gluster-mountbroker utility for geo-rep mountbroker setup (#1343333)
+
+* Mon Aug 22 2016 Milind Changire <mchangir@redhat.com>
+- Add psmisc as dependency for glusterfs-fuse for killall command (#1367665)
+
+* Thu Aug 4 2016 Jiffin Tony Thottan <jthottan@redhat.com>
+- Remove ganesha.so from client xlators
+
+* Sun Jul 31 2016 Soumya Koduri <skoduri@redhat.com>
+- Add dependency on portblock resource agent for ganesha package (#1354439)
+
+* Mon Jul 18 2016 Aravinda VK <avishwan@redhat.com>
+- Added new subpackage events(glusterfs-events) (#1334044)
+
+* Fri Jul 15 2016 Aravinda VK <avishwan@redhat.com>
+- Removed ".py" extension from symlink(S57glusterfind-delete-post)(#1356868)
+
+* Thu Jul 14 2016 Aravinda VK <avishwan@redhat.com>
+- Removed extra packaging line of cliutils(python-gluster)(#1342356)
+
+* Mon Jul 11 2016 Aravinda VK <avishwan@redhat.com>
+- Added Python subpackage "cliutils" under gluster
+
+* Tue May 31 2016 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- broken brp-python-bytecompile in RHEL7 results in installed
+ but unpackaged files.
+
+* Fri May 6 2016 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- additional dirs and files in /var/lib/glusterd/... (#1326410)
+
+* Tue Apr 26 2016 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- %%postun libs w/o firewalld on RHEL6 (#1330583)
+
+* Tue Apr 12 2016 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- additional dirs and files in /var/lib/glusterd/... (#1326410)
+
+* Mon Mar 7 2016 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- %%pre, %%post etc. scriptlet cleanup, ... -p /sbin/ldconfig (#1315024)
+
+* Fri Jan 22 2016 Aravinda VK <avishwan@redhat.com>
+- Added schedule_georep.py script to the glusterfs-geo-replication (#1300956)
+
+* Sat Jan 16 2016 Niels de Vos <ndevos@redhat.com>
+- glusterfs-server depends on -api (#1296931)
+
+* Sun Jan 10 2016 Niels de Vos <ndevos@redhat.com>
+- build system got fixed so that special glupy build is not needed anymore
+
+* Mon Dec 28 2015 Niels de Vos <ndevos@redhat.com>
+- hook scripts in glusterfs-ganesha use dbus-send, add dependency (#1294446)
+
+* Tue Dec 22 2015 Niels de Vos <ndevos@redhat.com>
+- move hook scripts for nfs-ganesha to the -ganesha sub-package
+- use standard 'make' installation for the hook scripts (#1174765)
+
* Tue Sep 1 2015 Kaleb S. KEITHLEY <kkeithle@redhat.com>
- erroneous ghost of ../hooks/1/delete causes install failure (#1258975)
@@ -1300,7 +1851,6 @@ fi
* Mon May 18 2015 Milind Changire <mchangir@redhat.com>
- Move file peer_add_secret_pub to the server RPM to support glusterfind (#1221544)
-
* Sun May 17 2015 Niels de Vos <ndevos@redhat.com>
- Fix building on RHEL-5 based distributions (#1222317)
@@ -1313,9 +1863,6 @@ fi
* Sat Mar 28 2015 Mohammed Rafi KC <rkavunga@redhat.com>
- Add dependency for librdmacm version >= 1.0.15 (#1206744)
-* Thu Mar 26 2015 Kaleb S. KEITHLEY <kkeithle@redhat.com>
-- attr dependency (#1174627)
-
* Tue Mar 24 2015 Niels de Vos <ndevos@redhat.com>
- move libgfdb (with sqlite dependency) to -server subpackage (#1194753)
@@ -1404,6 +1951,9 @@ fi
* Wed Apr 02 2014 Arumugam Balamurugan <barumuga@redhat.com>
- add version/release dynamically (#1074919)
+* Thu Mar 27 2014 Kaleb S. KEITHLEY <kkeithle@redhat.com>
+- attr dependency (#1184626)
+
* Wed Mar 26 2014 Poornima G <pgurusid@redhat.com>
- Include the hook scripts of add-brick, volume start, stop and set
diff --git a/glusterfsd/src/Makefile.am b/glusterfsd/src/Makefile.am
index 0f83622bb37..a0a778158d8 100644
--- a/glusterfsd/src/Makefile.am
+++ b/glusterfsd/src/Makefile.am
@@ -1,19 +1,34 @@
sbin_PROGRAMS = glusterfsd
+if WITH_SERVER
+sbin_PROGRAMS += glusterfsd gf_attach
+endif
glusterfsd_SOURCES = glusterfsd.c glusterfsd-mgmt.c
glusterfsd_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
- $(top_builddir)/rpc/xdr/src/libgfxdr.la ${GF_LDADD}
-
+ $(top_builddir)/rpc/xdr/src/libgfxdr.la $(GF_LDADD) $(LIB_DL)
glusterfsd_LDFLAGS = $(GF_LDFLAGS)
+
+gf_attach_SOURCES = gf_attach.c
+gf_attach_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
+ $(top_builddir)/api/src/libgfapi.la \
+ $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
+ $(top_builddir)/rpc/xdr/src/libgfxdr.la
+gf_attach_LDFLAGS = $(GF_LDFLAGS)
+
noinst_HEADERS = glusterfsd.h glusterfsd-mem-types.h glusterfsd-messages.h
AM_CPPFLAGS = $(GF_CPPFLAGS) \
-I$(top_srcdir)/libglusterfs/src -DDATADIR=\"$(localstatedir)\" \
-DCONFDIR=\"$(sysconfdir)/glusterfs\" $(GF_GLUSTERFS_CFLAGS) \
-DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \
- -I$(top_srcdir)/rpc/rpc-lib/src -I$(top_srcdir)/rpc/xdr/src \
- -I$(top_srcdir)/xlators/nfs/server/src
+ -DLIBEXECDIR=\"$(GLUSTERFS_LIBEXECDIR)\"\
+ -I$(top_srcdir)/rpc/rpc-lib/src \
+ -I$(top_srcdir)/rpc/xdr/src \
+ -I$(top_builddir)/rpc/xdr/src \
+ -I$(top_srcdir)/xlators/nfs/server/src \
+ -I$(top_srcdir)/xlators/protocol/server/src \
+ -I$(top_srcdir)/api/src
AM_CFLAGS = -Wall $(GF_CFLAGS)
@@ -32,6 +47,8 @@ install-data-local:
$(INSTALL) -d -m 755 $(DESTDIR)$(localstatedir)/log/glusterfs
$(INSTALL) -d -m 755 $(DESTDIR)$(sbindir)
rm -f $(DESTDIR)$(sbindir)/glusterfs
- rm -f $(DESTDIR)$(sbindir)/glusterd
ln -s glusterfsd $(DESTDIR)$(sbindir)/glusterfs
+if WITH_SERVER
+ rm -f $(DESTDIR)$(sbindir)/glusterd
ln -s glusterfsd $(DESTDIR)$(sbindir)/glusterd
+endif
diff --git a/glusterfsd/src/gf_attach.c b/glusterfsd/src/gf_attach.c
new file mode 100644
index 00000000000..c553b0b1f61
--- /dev/null
+++ b/glusterfsd/src/gf_attach.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com>
+ * This file is part of GlusterFS.
+ *
+ * This file is licensed to you under your choice of the GNU Lesser
+ * General Public License, version 3 or any later version (LGPLv3 or
+ * later), or the GNU General Public License, version 2 (GPLv2), in all
+ * cases as published by the Free Software Foundation.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <glusterfs/glusterfs.h>
+#include "glfs-internal.h"
+#include "rpc-clnt.h"
+#include "protocol-common.h"
+#include "xdr-generic.h"
+#include "glusterd1-xdr.h"
+
+/* In seconds */
+#define CONNECT_TIMEOUT 60
+#define REPLY_TIMEOUT 120
+
+int done = 0;
+int rpc_status;
+
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+
+struct rpc_clnt_procedure gf_attach_actors[GLUSTERD_BRICK_MAXVALUE] = {
+ [GLUSTERD_BRICK_NULL] = {"NULL", NULL},
+ [GLUSTERD_BRICK_OP] = {"BRICK_OP", NULL},
+};
+
+struct rpc_clnt_program gf_attach_prog = {
+ .progname = "brick operations",
+ .prognum = GD_BRICK_PROGRAM,
+ .progver = GD_BRICK_VERSION,
+ .proctable = gf_attach_actors,
+ .numproc = GLUSTERD_BRICK_MAXVALUE,
+};
+
+int32_t
+my_callback(struct rpc_req *req, struct iovec *iov, int count, void *frame)
+{
+ pthread_mutex_lock(&mutex);
+ rpc_status = req->rpc_status;
+ done = 1;
+ /* Signal main thread which is the only waiter */
+ pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&mutex);
+ return 0;
+}
+
+/* copied from gd_syncop_submit_request */
+int
+send_brick_req(xlator_t *this, struct rpc_clnt *rpc, char *path, int op)
+{
+ int ret = -1;
+ struct timespec ts;
+ struct iobuf *iobuf = NULL;
+ struct iobref *iobref = NULL;
+ struct iovec iov = {
+ 0,
+ };
+ ssize_t req_size = 0;
+ call_frame_t *frame = NULL;
+ gd1_mgmt_brick_op_req brick_req;
+ void *req = &brick_req;
+
+ brick_req.op = op;
+ brick_req.name = path;
+ brick_req.input.input_val = NULL;
+ brick_req.input.input_len = 0;
+ brick_req.dict.dict_val = NULL;
+ brick_req.dict.dict_len = 0;
+
+ req_size = xdr_sizeof((xdrproc_t)xdr_gd1_mgmt_brick_op_req, req);
+ iobuf = iobuf_get2(rpc->ctx->iobuf_pool, req_size);
+ if (!iobuf)
+ goto out;
+
+ iobref = iobref_new();
+ if (!iobref)
+ goto out;
+
+ iobref_add(iobref, iobuf);
+
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = iobuf_pagesize(iobuf);
+
+ /* Create the xdr payload */
+ ret = xdr_serialize_generic(iov, req, (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret == -1)
+ goto out;
+
+ iov.iov_len = ret;
+
+ /* Wait for connection */
+ timespec_now_realtime(&ts);
+ ts.tv_sec += CONNECT_TIMEOUT;
+ pthread_mutex_lock(&rpc->conn.lock);
+ {
+ while (!rpc->conn.connected)
+ if (pthread_cond_timedwait(&rpc->conn.cond, &rpc->conn.lock, &ts) ==
+ ETIMEDOUT) {
+ fprintf(stderr, "timeout waiting for RPC connection\n");
+ pthread_mutex_unlock(&rpc->conn.lock);
+ return EXIT_FAILURE;
+ }
+ }
+ pthread_mutex_unlock(&rpc->conn.lock);
+
+ frame = create_frame(this, this->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ /* Send the msg */
+ ret = rpc_clnt_submit(rpc, &gf_attach_prog, op, my_callback, &iov, 1, NULL,
+ 0, iobref, frame, NULL, 0, NULL, 0, NULL);
+ if (!ret) {
+ /* OK, wait for callback */
+ timespec_now_realtime(&ts);
+ ts.tv_sec += REPLY_TIMEOUT;
+ pthread_mutex_lock(&mutex);
+ {
+ while (!done)
+ if (pthread_cond_timedwait(&cond, &mutex, &ts) == ETIMEDOUT) {
+ fprintf(stderr, "timeout waiting for RPC reply\n");
+ pthread_mutex_unlock(&mutex);
+ return EXIT_FAILURE;
+ }
+ }
+ pthread_mutex_unlock(&mutex);
+ }
+
+out:
+
+ iobref_unref(iobref);
+ iobuf_unref(iobuf);
+ if (frame)
+ STACK_DESTROY(frame->root);
+
+ if (rpc_status != 0) {
+ fprintf(stderr, "got error %d on RPC\n", rpc_status);
+ return EXIT_FAILURE;
+ }
+
+ printf("OK\n");
+ return EXIT_SUCCESS;
+}
+
+int
+usage(char *prog)
+{
+ fprintf(stderr, "Usage: %s uds_path volfile_path (to attach)\n", prog);
+ fprintf(stderr, " %s -d uds_path brick_path (to detach)\n", prog);
+
+ return EXIT_FAILURE;
+}
+
+int
+main(int argc, char *argv[])
+{
+ glfs_t *fs;
+ struct rpc_clnt *rpc;
+ dict_t *options;
+ int ret;
+ int op = GLUSTERD_BRICK_ATTACH;
+
+ for (;;) {
+ switch (getopt(argc, argv, "d")) {
+ case 'd':
+ op = GLUSTERD_BRICK_TERMINATE;
+ break;
+ case -1:
+ goto done_parsing;
+ default:
+ return usage(argv[0]);
+ }
+ }
+done_parsing:
+ if (optind != (argc - 2)) {
+ return usage(argv[0]);
+ }
+
+ fs = glfs_new("gf-attach");
+ if (!fs) {
+ fprintf(stderr, "glfs_new failed\n");
+ return EXIT_FAILURE;
+ }
+
+ (void)glfs_set_logging(fs, "/dev/stderr", 7);
+ /*
+ * This will actually fail because we haven't defined a volume, but
+ * it will do enough initialization to get us going.
+ */
+ (void)glfs_init(fs);
+
+ options = dict_new();
+ if (!options) {
+ return EXIT_FAILURE;
+ }
+ ret = dict_set_str(options, "transport-type", "socket");
+ if (ret != 0) {
+ fprintf(stderr, "failed to set transport type\n");
+ return EXIT_FAILURE;
+ }
+ ret = dict_set_str(options, "transport.address-family", "unix");
+ if (ret != 0) {
+ fprintf(stderr, "failed to set address family\n");
+ return EXIT_FAILURE;
+ }
+ ret = dict_set_str(options, "transport.socket.connect-path", argv[optind]);
+ if (ret != 0) {
+ fprintf(stderr, "failed to set connect path\n");
+ return EXIT_FAILURE;
+ }
+
+ rpc = rpc_clnt_new(options, fs->ctx->master, "gf-attach-rpc", 0);
+ if (!rpc) {
+ fprintf(stderr, "rpc_clnt_new failed\n");
+ return EXIT_FAILURE;
+ }
+
+ if (rpc_clnt_register_notify(rpc, NULL, NULL) != 0) {
+ fprintf(stderr, "rpc_clnt_register_notify failed\n");
+ return EXIT_FAILURE;
+ }
+
+ if (rpc_clnt_start(rpc) != 0) {
+ fprintf(stderr, "rpc_clnt_start failed\n");
+ return EXIT_FAILURE;
+ }
+
+ return send_brick_req(fs->ctx->master, rpc, argv[optind + 1], op);
+}
diff --git a/glusterfsd/src/glusterfsd-mem-types.h b/glusterfsd/src/glusterfsd-mem-types.h
index 7135c0ada9e..e59b558deb0 100644
--- a/glusterfsd/src/glusterfsd-mem-types.h
+++ b/glusterfsd/src/glusterfsd-mem-types.h
@@ -10,18 +10,18 @@
#ifndef __GLUSTERFSD_MEM_TYPES_H__
#define __GLUSTERFSD_MEM_TYPES_H__
-#include "mem-types.h"
+#include <glusterfs/mem-types.h>
#define GF_MEM_TYPE_START (gf_common_mt_end + 1)
enum gfd_mem_types_ {
- gfd_mt_xlator_list_t = GF_MEM_TYPE_START,
- gfd_mt_xlator_t,
- gfd_mt_server_cmdline_t,
- gfd_mt_xlator_cmdline_option_t,
- gfd_mt_char,
- gfd_mt_call_pool_t,
- gfd_mt_end
+ gfd_mt_xlator_list_t = GF_MEM_TYPE_START,
+ gfd_mt_xlator_t,
+ gfd_mt_server_cmdline_t,
+ gfd_mt_xlator_cmdline_option_t,
+ gfd_mt_char,
+ gfd_mt_call_pool_t,
+ gfd_mt_end
};
#endif
diff --git a/glusterfsd/src/glusterfsd-messages.h b/glusterfsd/src/glusterfsd-messages.h
index 9c6196c1d44..0cdbffa71ea 100644
--- a/glusterfsd/src/glusterfsd-messages.h
+++ b/glusterfsd/src/glusterfsd-messages.h
@@ -11,101 +11,83 @@
#ifndef _GLUSTERFSD_MESSAGES_H_
#define _GLUSTERFSD_MESSAGES_H_
-#include "glfs-message-id.h"
+#include <glusterfs/glfs-message-id.h>
-/* NOTE: Rules for message additions
- * 1) Each instance of a message is _better_ left with a unique message ID, even
- * if the message format is the same. Reasoning is that, if the message
- * format needs to change in one instance, the other instances are not
- * impacted or the new change does not change the ID of the instance being
- * modified.
- * 2) Addition of a message,
- * - Should increment the GLFS_NUM_MESSAGES
- * - Append to the list of messages defined, towards the end
- * - Retain macro naming as glfs_msg_X (for redability across developers)
- * NOTE: Rules for message format modifications
- * 3) Check acorss the code if the message ID macro in question is reused
- * anywhere. If reused then then the modifications should ensure correctness
- * everywhere, or needs a new message ID as (1) above was not adhered to. If
- * not used anywhere, proceed with the required modification.
- * NOTE: Rules for message deletion
- * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
- * anywhere, then can be deleted, but will leave a hole by design, as
- * addition rules specify modification to the end of the list and not filling
- * holes.
+/* To add new message IDs, append new identifiers at the end of the list.
+ *
+ * Never remove a message ID. If it's not used anymore, you can rename it or
+ * leave it as it is, but not delete it. This is to prevent reutilization of
+ * IDs by other messages.
+ *
+ * The component name must match one of the entries defined in
+ * glfs-message-id.h.
*/
-#define GLFS_COMP_BASE GLFS_MSGID_COMP_GLUSTERFSD
-#define GLFS_NUM_MESSAGES 34
-#define GLFS_MSGID_END (GLFS_COMP_BASE + GLFS_NUM_MESSAGES + 1)
-/* Messaged with message IDs */
-#define glfs_msg_start_x GLFS_COMP_BASE, "Invalid: Start of messages"
-/*------------*/
-#define glusterfsd_msg_1 (GLFS_COMP_BASE + 1), "Could not create absolute" \
- " mountpoint path"
-#define glusterfsd_msg_2 (GLFS_COMP_BASE + 2), "Could not get current " \
- "working directory"
-#define glusterfsd_msg_3 (GLFS_COMP_BASE + 3), "failed to set mount-point" \
- " to options dictionary"
-#define glusterfsd_msg_4 (GLFS_COMP_BASE + 4), "failed to set dict value" \
- " for key %s"
-#define glusterfsd_msg_5 (GLFS_COMP_BASE + 5), "failed to set 'disable'" \
- " for key %s"
-#define glusterfsd_msg_6 (GLFS_COMP_BASE + 6), "failed to set 'enable'" \
- " for key %s"
-#define glusterfsd_msg_7 (GLFS_COMP_BASE + 7), "Not a client process, not" \
- " performing mount operation"
-#define glusterfsd_msg_8 (GLFS_COMP_BASE + 8), "MOUNT-POINT %s" \
- " initialization failed"
-#define glusterfsd_msg_9 (GLFS_COMP_BASE + 9), "loading volume file %s" \
- " failed"
-#define glusterfsd_msg_10 (GLFS_COMP_BASE + 10), "xlator option %s is" \
- " invalid"
-#define glusterfsd_msg_11 (GLFS_COMP_BASE + 11), "Fetching the volume" \
- " file from server..."
-#define glusterfsd_msg_12 (GLFS_COMP_BASE + 12), "volume initialization" \
- " failed."
-#define glusterfsd_msg_13 (GLFS_COMP_BASE + 13), "ERROR: glusterfs uuid" \
- " generation failed"
-#define glusterfsd_msg_14 (GLFS_COMP_BASE + 14), "ERROR: glusterfs %s" \
- " pool creation failed"
-#define glusterfsd_msg_15 (GLFS_COMP_BASE + 15), "ERROR: '--volfile-id' is" \
- " mandatory if '-s' OR '--volfile-server'" \
- " option is given"
-#define glusterfsd_msg_16 (GLFS_COMP_BASE + 16), "ERROR: parsing the" \
- " volfile failed"
-#define glusterfsd_msg_17 (GLFS_COMP_BASE + 17), "pidfile %s open failed"
-#define glusterfsd_msg_18 (GLFS_COMP_BASE + 18), "pidfile %s lock failed"
-#define glusterfsd_msg_19 (GLFS_COMP_BASE + 19), "pidfile %s unlock failed"
-#define glusterfsd_msg_20 (GLFS_COMP_BASE + 20), "pidfile %s truncation" \
- " failed"
-#define glusterfsd_msg_21 (GLFS_COMP_BASE + 21), "pidfile %s write failed"
-#define glusterfsd_msg_22 (GLFS_COMP_BASE + 22), "failed to execute" \
- " pthread_sigmask"
-#define glusterfsd_msg_23 (GLFS_COMP_BASE + 23), "failed to create pthread"
-#define glusterfsd_msg_24 (GLFS_COMP_BASE + 24), "daemonization failed"
-#define glusterfsd_msg_25 (GLFS_COMP_BASE + 25), "mount failed"
-#define glusterfsd_msg_26 (GLFS_COMP_BASE + 26), "failed to construct" \
- " the graph"
-#define glusterfsd_msg_27 (GLFS_COMP_BASE + 27), "fuse xlator cannot be" \
- " specified in volume file"
-#define glusterfsd_msg_28 (GLFS_COMP_BASE + 28), "Cannot reach volume" \
- " specification file"
-#define glusterfsd_msg_29 (GLFS_COMP_BASE + 29), "ERROR: glusterfs context" \
- " not initialized"
-#define glusterfsd_msg_30 (GLFS_COMP_BASE + 30), "Started running %s" \
- " version %s (args: %s)"
-#define glusterfsd_msg_31 (GLFS_COMP_BASE + 31), "Could not create new" \
- " sync-environment"
-#define glusterfsd_msg_32 (GLFS_COMP_BASE + 32), "received signum (%d)," \
- " shutting down"
-#define glusterfsd_msg_33 (GLFS_COMP_BASE + 33), "obsolete option " \
- "'--volfile-max-fetch-attempts or fetch-attempts' " \
- "was provided"
-#define glusterfsd_msg_34 (GLFS_COMP_BASE + 34), "memory accounting init" \
- " failed."
-/*------------*/
-#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
+GLFS_MSGID(
+ GLUSTERFSD, glusterfsd_msg_1, glusterfsd_msg_2, glusterfsd_msg_3,
+ glusterfsd_msg_4, glusterfsd_msg_5, glusterfsd_msg_6, glusterfsd_msg_7,
+ glusterfsd_msg_8, glusterfsd_msg_9, glusterfsd_msg_10, glusterfsd_msg_11,
+ glusterfsd_msg_12, glusterfsd_msg_13, glusterfsd_msg_14, glusterfsd_msg_15,
+ glusterfsd_msg_16, glusterfsd_msg_17, glusterfsd_msg_18, glusterfsd_msg_19,
+ glusterfsd_msg_20, glusterfsd_msg_21, glusterfsd_msg_22, glusterfsd_msg_23,
+ glusterfsd_msg_24, glusterfsd_msg_25, glusterfsd_msg_26, glusterfsd_msg_27,
+ glusterfsd_msg_28, glusterfsd_msg_29, glusterfsd_msg_30, glusterfsd_msg_31,
+ glusterfsd_msg_32, glusterfsd_msg_33, glusterfsd_msg_34, glusterfsd_msg_35,
+ glusterfsd_msg_36, glusterfsd_msg_37, glusterfsd_msg_38, glusterfsd_msg_39,
+ glusterfsd_msg_40, glusterfsd_msg_41, glusterfsd_msg_42, glusterfsd_msg_43,
+ glusterfsd_msg_029, glusterfsd_msg_041, glusterfsd_msg_042);
+#define glusterfsd_msg_1_STR "Could not create absolute mountpoint path"
+#define glusterfsd_msg_2_STR "Could not get current working directory"
+#define glusterfsd_msg_4_STR "failed to set mount-point to options dictionary"
+#define glusterfsd_msg_3_STR "failed to set dict value for key"
+#define glusterfsd_msg_5_STR "failed to set disable for key"
+#define glusterfsd_msg_6_STR "failed to set enable for key"
+#define glusterfsd_msg_7_STR \
+ "Not a client process, not performing mount operation"
+#define glusterfsd_msg_8_STR "MOUNT_POINT initialization failed"
+#define glusterfsd_msg_9_STR "loading volume file failed"
+#define glusterfsd_msg_10_STR "xlator option is invalid"
+#define glusterfsd_msg_11_STR "Fetching the volume file from server..."
+#define glusterfsd_msg_12_STR "volume initialization failed"
+#define glusterfsd_msg_34_STR "memory init failed"
+#define glusterfsd_msg_13_STR "ERROR: glusterfs uuid generation failed"
+#define glusterfsd_msg_14_STR "ERROR: glusterfs pool creation failed"
+#define glusterfsd_msg_15_STR \
+ "ERROR: '--volfile-id' is mandatory if '-s' OR '--volfile-server' option " \
+ "is given"
+#define glusterfsd_msg_16_STR "ERROR: parsing the volfile failed"
+#define glusterfsd_msg_33_STR \
+ "obsolete option '--volfile-max-fecth-attempts or fetch-attempts' was " \
+ "provided"
+#define glusterfsd_msg_17_STR "pidfile open failed"
+#define glusterfsd_msg_18_STR "pidfile lock failed"
+#define glusterfsd_msg_20_STR "pidfile truncation failed"
+#define glusterfsd_msg_21_STR "pidfile write failed"
+#define glusterfsd_msg_22_STR "failed to exeute pthread_sigmask"
+#define glusterfsd_msg_23_STR "failed to create pthread"
+#define glusterfsd_msg_24_STR "daemonization failed"
+#define glusterfsd_msg_25_STR "mount failed"
+#define glusterfsd_msg_26_STR "failed to construct the graph"
+#define glusterfsd_msg_27_STR "fuse xlator cannot be specified in volume file"
+#define glusterfsd_msg_28_STR "Cannot reach volume specification file"
+#define glusterfsd_msg_29_STR "ERROR: glusterfsd context not initialized"
+#define glusterfsd_msg_43_STR \
+ "command line argument --brick-mux is valid only for brick process"
+#define glusterfsd_msg_029_STR "failed to create command line string"
+#define glusterfsd_msg_30_STR "Started running version"
+#define glusterfsd_msg_31_STR "Could not create new sync-environment"
+#define glusterfsd_msg_40_STR "No change in volfile, countinuing"
+#define glusterfsd_msg_39_STR "Unable to create/delete temporary file"
+#define glusterfsd_msg_38_STR \
+ "Not processing brick-op since volume graph is not yet active"
+#define glusterfsd_msg_35_STR "rpc req buffer unserialization failed"
+#define glusterfsd_msg_36_STR "problem in xlator loading"
+#define glusterfsd_msg_37_STR "failed to get dict value"
+#define glusterfsd_msg_41_STR "received attach request for volfile"
+#define glusterfsd_msg_42_STR "failed to unserialize xdata to dictionary"
+#define glusterfsd_msg_041_STR "can't detach. flie not found"
+#define glusterfsd_msg_042_STR \
+ "couldnot detach old graph. Aborting the reconfiguration operation"
#endif /* !_GLUSTERFSD_MESSAGES_H_ */
diff --git a/glusterfsd/src/glusterfsd-mgmt.c b/glusterfsd/src/glusterfsd-mgmt.c
index 459d79fea0e..eaf6796e4c3 100644
--- a/glusterfsd/src/glusterfsd-mgmt.c
+++ b/glusterfsd/src/glusterfsd-mgmt.c
@@ -13,14 +13,14 @@
#include <stdlib.h>
#include <signal.h>
-#include "glusterfs.h"
-#include "stack.h"
-#include "dict.h"
-#include "event.h"
-#include "defaults.h"
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/dict.h>
+#include <glusterfs/gf-event.h>
+#include <glusterfs/defaults.h>
#include "rpc-clnt.h"
#include "protocol-common.h"
+#include "glusterfsd-messages.h"
#include "glusterfs3.h"
#include "portmap-xdr.h"
#include "xdr-generic.h"
@@ -28,2239 +28,3028 @@
#include "glusterfsd.h"
#include "rpcsvc.h"
#include "cli1-xdr.h"
-#include "statedump.h"
-#include "syncop.h"
-#include "xlator.h"
+#include <glusterfs/statedump.h>
+#include <glusterfs/syncop.h>
+#include <glusterfs/xlator.h>
+#include <glusterfs/syscall.h>
+#include <glusterfs/monitoring.h>
+#include "server.h"
static gf_boolean_t is_mgmt_rpc_reconnect = _gf_false;
+int need_emancipate = 0;
-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 emancipate(glusterfs_ctx_t *ctx, int ret);
+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
+emancipate(glusterfs_ctx_t *ctx, int ret);
+int
+glusterfs_process_svc_attach_volfp(glusterfs_ctx_t *ctx, FILE *fp,
+ char *volfile_id, char *checksum,
+ dict_t *dict);
+int
+glusterfs_mux_volfile_reconfigure(FILE *newvolfile_fp, glusterfs_ctx_t *ctx,
+ gf_volfile_t *volfile_obj, char *checksum,
+ dict_t *dict);
+int
+glusterfs_process_svc_attach_volfp(glusterfs_ctx_t *ctx, FILE *fp,
+ char *volfile_id, char *checksum,
+ dict_t *dict);
+int
+glusterfs_process_svc_detach(glusterfs_ctx_t *ctx, gf_volfile_t *volfile_obj);
+
+gf_boolean_t
+mgmt_is_multiplexed_daemon(char *name);
+
+static int
+glusterfs_volume_top_perf(const char *brick_path, dict_t *dict,
+ gf_boolean_t write_test);
int
-mgmt_cbk_spec (struct rpc_clnt *rpc, void *mydata, void *data)
+mgmt_cbk_spec(struct rpc_clnt *rpc, void *mydata, void *data)
{
- glusterfs_ctx_t *ctx = NULL;
- xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
- this = mydata;
- ctx = glusterfsd_ctx;
- gf_log ("mgmt", GF_LOG_INFO, "Volume file changed");
+ ctx = glusterfsd_ctx;
+ gf_log("mgmt", GF_LOG_INFO, "Volume file changed");
- glusterfs_volfile_fetch (ctx);
- return 0;
+ glusterfs_volfile_fetch(ctx);
+ return 0;
}
-
int
-mgmt_cbk_event (struct rpc_clnt *rpc, void *mydata, void *data)
+mgmt_process_volfile(const char *volfile, ssize_t size, char *volfile_id,
+ dict_t *dict)
{
- return 0;
-}
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = 0;
+ FILE *tmpfp = NULL;
+ gf_volfile_t *volfile_obj = NULL;
+ gf_volfile_t *volfile_tmp = NULL;
+ char sha256_hash[SHA256_DIGEST_LENGTH] = {
+ 0,
+ };
+ int tmp_fd = -1;
+ char template[] = "/tmp/glfs.volfile.XXXXXX";
+
+ glusterfs_compute_sha256((const unsigned char *)volfile, size, sha256_hash);
+ ctx = THIS->ctx;
+ LOCK(&ctx->volfile_lock);
+ {
+ list_for_each_entry(volfile_obj, &ctx->volfile_list, volfile_list)
+ {
+ if (!strcmp(volfile_id, volfile_obj->vol_id)) {
+ if (!memcmp(sha256_hash, volfile_obj->volfile_checksum,
+ sizeof(volfile_obj->volfile_checksum))) {
+ UNLOCK(&ctx->volfile_lock);
+ gf_smsg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_40,
+ NULL);
+ goto out;
+ }
+ volfile_tmp = volfile_obj;
+ break;
+ }
+ }
-struct iobuf *
-glusterfs_serialize_reply (rpcsvc_request_t *req, void *arg,
- struct iovec *outmsg, xdrproc_t xdrproc)
-{
- struct iobuf *iob = NULL;
- ssize_t retlen = -1;
- ssize_t xdr_size = 0;
+ /* coverity[secure_temp] mkstemp uses 0600 as the mode */
+ tmp_fd = mkstemp(template);
+ if (-1 == tmp_fd) {
+ UNLOCK(&ctx->volfile_lock);
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, glusterfsd_msg_39,
+ "create template=%s", template, NULL);
+ ret = -1;
+ goto out;
+ }
- /* First, get the io buffer into which the reply in arg will
- * be serialized.
+ /* Calling unlink so that when the file is closed or program
+ * terminates the temporary file is deleted.
*/
- xdr_size = xdr_sizeof (xdrproc, arg);
- iob = iobuf_get2 (req->svc->ctx->iobuf_pool, xdr_size);
- if (!iob) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get iobuf");
- goto ret;
+ ret = sys_unlink(template);
+ if (ret < 0) {
+ gf_smsg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_39,
+ "delete template=%s", template, NULL);
+ ret = 0;
}
- iobuf_to_iovec (iob, outmsg);
- /* Use the given serializer to translate the give C structure in arg
- * to XDR format which will be written into the buffer in outmsg.
- */
- /* retlen is used to received the error since size_t is unsigned and we
- * need -1 for error notification during encoding.
- */
- retlen = xdr_serialize_generic (*outmsg, arg, xdrproc);
- if (retlen == -1) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to encode message");
- goto ret;
+ tmpfp = fdopen(tmp_fd, "w+b");
+ if (!tmpfp) {
+ ret = -1;
+ goto unlock;
}
- outmsg->iov_len = retlen;
-ret:
- if (retlen == -1) {
- iob = NULL;
+ fwrite(volfile, size, 1, tmpfp);
+ fflush(tmpfp);
+ if (ferror(tmpfp)) {
+ ret = -1;
+ goto unlock;
}
- return iob;
+ if (!volfile_tmp) {
+ /* There is no checksum in the list, which means simple attach
+ * the volfile
+ */
+ ret = glusterfs_process_svc_attach_volfp(ctx, tmpfp, volfile_id,
+ sha256_hash, dict);
+ goto unlock;
+ }
+ ret = glusterfs_mux_volfile_reconfigure(tmpfp, ctx, volfile_obj,
+ sha256_hash, dict);
+ if (ret < 0) {
+ gf_msg_debug("glusterfsd-mgmt", EINVAL, "Reconfigure failed !!");
+ }
+ }
+unlock:
+ UNLOCK(&ctx->volfile_lock);
+out:
+ if (tmpfp)
+ fclose(tmpfp);
+ else if (tmp_fd != -1)
+ sys_close(tmp_fd);
+ return ret;
}
int
-glusterfs_submit_reply (rpcsvc_request_t *req, void *arg,
- struct iovec *payload, int payloadcount,
- struct iobref *iobref, xdrproc_t xdrproc)
+mgmt_cbk_event(struct rpc_clnt *rpc, void *mydata, void *data)
{
- struct iobuf *iob = NULL;
- int ret = -1;
- struct iovec rsp = {0,};
- char new_iobref = 0;
+ return 0;
+}
- if (!req) {
- GF_ASSERT (req);
- goto out;
- }
+struct iobuf *
+glusterfs_serialize_reply(rpcsvc_request_t *req, void *arg,
+ 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.
+ */
+ xdr_size = xdr_sizeof(xdrproc, arg);
+ iob = iobuf_get2(req->svc->ctx->iobuf_pool, xdr_size);
+ if (!iob) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Failed to get iobuf");
+ goto ret;
+ }
+
+ iobuf_to_iovec(iob, outmsg);
+ /* Use the given serializer to translate the give C structure in arg
+ * to XDR format which will be written into the buffer in outmsg.
+ */
+ /* retlen is used to received the error since size_t is unsigned and we
+ * need -1 for error notification during encoding.
+ */
+ retlen = xdr_serialize_generic(*outmsg, arg, xdrproc);
+ if (retlen == -1) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Failed to encode message");
+ GF_FREE(iob);
+ goto ret;
+ }
+
+ outmsg->iov_len = retlen;
+ret:
+ if (retlen == -1) {
+ iob = NULL;
+ }
- if (!iobref) {
- iobref = iobref_new ();
- if (!iobref) {
- gf_log (THIS->name, GF_LOG_ERROR, "out of memory");
- goto out;
- }
+ return iob;
+}
- new_iobref = 1;
+int
+glusterfs_submit_reply(rpcsvc_request_t *req, void *arg, struct iovec *payload,
+ int payloadcount, struct iobref *iobref,
+ xdrproc_t xdrproc)
+{
+ struct iobuf *iob = NULL;
+ int ret = -1;
+ struct iovec rsp = {
+ 0,
+ };
+ char new_iobref = 0;
+
+ if (!req) {
+ GF_ASSERT(req);
+ goto out;
+ }
+
+ if (!iobref) {
+ iobref = iobref_new();
+ if (!iobref) {
+ gf_log(THIS->name, GF_LOG_ERROR, "out of memory");
+ goto out;
}
- iob = glusterfs_serialize_reply (req, arg, &rsp, xdrproc);
- if (!iob) {
- gf_log_callingfn (THIS->name, GF_LOG_ERROR, "Failed to serialize reply");
- } else {
- iobref_add (iobref, iob);
- }
+ new_iobref = 1;
+ }
- ret = rpcsvc_submit_generic (req, &rsp, 1, payload, payloadcount,
- iobref);
+ iob = glusterfs_serialize_reply(req, arg, &rsp, xdrproc);
+ if (!iob) {
+ gf_log_callingfn(THIS->name, GF_LOG_ERROR, "Failed to serialize reply");
+ } else {
+ iobref_add(iobref, iob);
+ }
- /* Now that we've done our job of handing the message to the RPC layer
- * we can safely unref the iob in the hope that RPC layer must have
- * ref'ed the iob on receiving into the txlist.
- */
- if (ret == -1) {
- gf_log (THIS->name, GF_LOG_ERROR, "Reply submission failed");
- goto out;
- }
+ ret = rpcsvc_submit_generic(req, &rsp, 1, payload, payloadcount, iobref);
- ret = 0;
+ /* Now that we've done our job of handing the message to the RPC layer
+ * we can safely unref the iob in the hope that RPC layer must have
+ * ref'ed the iob on receiving into the txlist.
+ */
+ if (ret == -1) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Reply submission failed");
+ goto out;
+ }
+
+ ret = 0;
out:
- if (iob)
- iobuf_unref (iob);
+ if (iob)
+ iobuf_unref(iob);
- if (new_iobref && iobref)
- iobref_unref (iobref);
+ if (new_iobref && iobref)
+ iobref_unref(iobref);
- return ret;
+ return ret;
}
int
-glusterfs_terminate_response_send (rpcsvc_request_t *req, int op_ret)
+glusterfs_terminate_response_send(rpcsvc_request_t *req, int op_ret)
{
- gd1_mgmt_brick_op_rsp rsp = {0,};
- dict_t *dict = NULL;
- int ret = 0;
-
- rsp.op_ret = op_ret;
- rsp.op_errno = 0;
- rsp.op_errstr = "";
- dict = dict_new ();
-
- if (dict)
- ret = dict_allocate_and_serialize (dict, &rsp.output.output_val,
- &rsp.output.output_len);
-
-
- if (ret == 0)
- ret = glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ gd1_mgmt_brick_op_rsp rsp = {
+ 0,
+ };
+ dict_t *dict = NULL;
+ int ret = 0;
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = 0;
+ rsp.op_errstr = "";
+ dict = dict_new();
+
+ if (dict)
+ ret = dict_allocate_and_serialize(dict, &rsp.output.output_val,
+ &rsp.output.output_len);
+
+ if (ret == 0)
+ ret = glusterfs_submit_reply(req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
- GF_FREE (rsp.output.output_val);
- if (dict)
- dict_unref (dict);
- return ret;
+ GF_FREE(rsp.output.output_val);
+ if (dict)
+ dict_unref(dict);
+ return ret;
}
int
-glusterfs_handle_terminate (rpcsvc_request_t *req)
+glusterfs_handle_terminate(rpcsvc_request_t *req)
{
-
- glusterfs_terminate_response_send (req, 0);
- cleanup_and_exit (SIGTERM);
- return 0;
+ gd1_mgmt_brick_op_req xlator_req = {
+ 0,
+ };
+ ssize_t ret;
+ glusterfs_ctx_t *ctx = NULL;
+ xlator_t *top = NULL;
+ xlator_t *victim = NULL;
+ xlator_t *tvictim = NULL;
+ xlator_list_t **trav_p = NULL;
+ gf_boolean_t lockflag = _gf_false;
+ gf_boolean_t still_bricks_attached = _gf_false;
+
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ req->rpc_err = GARBAGE_ARGS;
+ return -1;
+ }
+ ctx = glusterfsd_ctx;
+
+ LOCK(&ctx->volfile_lock);
+ {
+ /* Find the xlator_list_t that points to our victim. */
+ if (glusterfsd_ctx->active) {
+ top = glusterfsd_ctx->active->first;
+ for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) {
+ victim = (*trav_p)->xlator;
+ if (!victim->cleanup_starting &&
+ strcmp(victim->name, xlator_req.name) == 0) {
+ break;
+ }
+ }
+ }
+
+ if (!top)
+ goto err;
+ }
+ if (!*trav_p) {
+ gf_log(THIS->name, GF_LOG_ERROR, "can't terminate %s - not found",
+ xlator_req.name);
+ /*
+ * Used to be -ENOENT. However, the caller asked us to
+ * make sure it's down and if it's already down that's
+ * good enough.
+ */
+ glusterfs_terminate_response_send(req, 0);
+ goto err;
+ }
+
+ glusterfs_terminate_response_send(req, 0);
+ for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) {
+ tvictim = (*trav_p)->xlator;
+ if (!tvictim->cleanup_starting &&
+ !strcmp(tvictim->name, xlator_req.name)) {
+ continue;
+ }
+ if (!tvictim->cleanup_starting) {
+ still_bricks_attached = _gf_true;
+ break;
+ }
+ }
+ if (!still_bricks_attached) {
+ gf_log(THIS->name, GF_LOG_INFO,
+ "terminating after loss of last child %s", xlator_req.name);
+ rpc_clnt_mgmt_pmap_signout(glusterfsd_ctx, xlator_req.name);
+ kill(getpid(), SIGTERM);
+ } else {
+ /* TODO cleanup sequence needs to be done properly for
+ Quota and Changelog
+ */
+ if (victim->cleanup_starting)
+ goto err;
+
+ rpc_clnt_mgmt_pmap_signout(glusterfsd_ctx, xlator_req.name);
+ victim->cleanup_starting = 1;
+
+ UNLOCK(&ctx->volfile_lock);
+ lockflag = _gf_true;
+
+ gf_log(THIS->name, GF_LOG_INFO,
+ "detaching not-only"
+ " child %s",
+ xlator_req.name);
+ top->notify(top, GF_EVENT_CLEANUP, victim);
+ }
+err:
+ if (!lockflag)
+ UNLOCK(&ctx->volfile_lock);
+ if (xlator_req.input.input_val)
+ free(xlator_req.input.input_val);
+ if (xlator_req.dict.dict_val)
+ free(xlator_req.dict.dict_val);
+ free(xlator_req.name);
+ xlator_req.name = NULL;
+ return 0;
}
int
-glusterfs_translator_info_response_send (rpcsvc_request_t *req, int ret,
- char *msg, dict_t *output)
+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;
+ 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 = "";
- 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;
+ 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_xlator_op_response_send (rpcsvc_request_t *req, int op_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,};
- int ret = -1;
- gf_boolean_t free_ptr = _gf_false;
- GF_ASSERT (req);
-
- rsp.op_ret = op_ret;
- rsp.op_errno = 0;
- if (op_ret && msg && msg[0])
- rsp.op_errstr = msg;
- else
- rsp.op_errstr = "";
-
- if (output) {
- ret = dict_allocate_and_serialize (output,
- &rsp.output.output_val,
- &rsp.output.output_len);
- }
- if (!ret)
- free_ptr = _gf_true;
+ gd1_mgmt_brick_op_rsp rsp = {
+ 0,
+ };
+ int ret = -1;
+ gf_boolean_t free_ptr = _gf_false;
+ GF_ASSERT(req);
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = 0;
+ if (op_ret && msg && msg[0])
+ rsp.op_errstr = msg;
+ else
+ rsp.op_errstr = "";
- ret = glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ if (output) {
+ ret = dict_allocate_and_serialize(output, &rsp.output.output_val,
+ &rsp.output.output_len);
+ }
+ if (!ret)
+ free_ptr = _gf_true;
- if (free_ptr)
- GF_FREE (rsp.output.output_val);
+ ret = glusterfs_submit_reply(req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
- return ret;
+ if (free_ptr)
+ GF_FREE(rsp.output.output_val);
+
+ return ret;
}
int
-glusterfs_handle_translator_info_get (rpcsvc_request_t *req)
+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;
- double time = 0;
- double throughput = 0;
- 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;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ret = xdr_to_generic (req->msg[0], &xlator_req,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
+ 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;
+ 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;
+
+ GF_ASSERT(req);
+ this = THIS;
+ GF_ASSERT(this);
+
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ // 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;
+ }
+
+ ret = dict_get_int32(dict, "top-op", (int32_t *)&top_op);
+ if (ret)
+ goto cont;
+ if (GF_CLI_TOP_READ_PERF == top_op) {
+ ret = glusterfs_volume_top_perf(xlator_req.name, dict, _gf_false);
+ } else if (GF_CLI_TOP_WRITE_PERF == top_op) {
+ ret = glusterfs_volume_top_perf(xlator_req.name, dict, _gf_true);
+ }
- 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;
- }
-
- 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;
-
- if (GF_CLI_TOP_READ_PERF == top_op) {
- ret = glusterfs_volume_top_read_perf
- (blk_size, blk_count, xlator_req.name,
- &throughput, &time);
- } else if ( GF_CLI_TOP_WRITE_PERF == top_op) {
- ret = glusterfs_volume_top_write_perf
- (blk_size, blk_count, xlator_req.name,
- &throughput, &time);
- }
- ret = dict_set_double (dict, "time", time);
- if (ret)
- goto cont;
- ret = dict_set_double (dict, "throughput", throughput);
- if (ret)
- goto cont;
- }
cont:
- ctx = glusterfsd_ctx;
- GF_ASSERT (ctx);
- active = ctx->active;
- any = active->first;
+ ctx = glusterfsd_ctx;
+ GF_ASSERT(ctx);
+ active = ctx->active;
+ if (active == NULL) {
+ gf_log(THIS->name, GF_LOG_ERROR, "ctx->active returned NULL");
+ ret = -1;
+ goto out;
+ }
+ any = active->first;
- xlator = xlator_search_by_name (any, xlator_req.name);
+ xlator = get_xlator_by_name(any, xlator_req.name);
+ if (!xlator) {
+ ret = -1;
+ snprintf(msg, sizeof(msg), "xlator %s is not loaded", xlator_req.name);
+ goto out;
+ }
+
+ if (strcmp(xlator->type, "debug/io-stats")) {
+ xlator = get_xlator_by_type(xlator, "debug/io-stats");
if (!xlator) {
- snprintf (msg, sizeof (msg), "xlator %s is not loaded",
- xlator_req.name);
- goto out;
+ ret = -1;
+ snprintf(msg, sizeof(msg),
+ "xlator-type debug/io-stats is not loaded");
+ goto out;
}
+ }
- output = dict_new ();
- ret = xlator->notify (xlator, GF_EVENT_TRANSLATOR_INFO, dict, output);
+ output = dict_new();
+ ret = xlator->notify(xlator, GF_EVENT_TRANSLATOR_INFO, dict, output);
out:
- ret = glusterfs_translator_info_response_send (req, ret, msg, output);
-
- free (xlator_req.name);
- free (xlator_req.input.input_val);
- if (output)
- dict_unref (output);
- if (dict)
- dict_unref (dict);
- return ret;
+ ret = glusterfs_translator_info_response_send(req, ret, msg, output);
+
+ free(xlator_req.name);
+ free(xlator_req.input.input_val);
+ if (xlator_req.dict.dict_val)
+ free(xlator_req.dict.dict_val);
+ if (output)
+ dict_unref(output);
+ if (dict)
+ dict_unref(dict);
+ return ret;
}
-int
-glusterfs_volume_top_write_perf (uint32_t blk_size, uint32_t blk_count,
- char *brick_path, double *throughput,
- double *time)
+static int
+glusterfs_volume_top_perf(const char *brick_path, dict_t *dict,
+ gf_boolean_t write_test)
{
- int32_t fd = -1;
- int32_t input_fd = -1;
- char export_path[PATH_MAX] = {0,};
- char *buf = NULL;
- int32_t iter = 0;
- int32_t ret = -1;
- uint64_t total_blks = 0;
- struct timeval begin, end = {0,};
-
- GF_ASSERT (brick_path);
- GF_ASSERT (throughput);
- GF_ASSERT (time);
- if (!(blk_size > 0) || ! (blk_count > 0))
- goto out;
-
- snprintf (export_path, sizeof (export_path), "%s/%s",
- brick_path, ".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;
- }
+ int32_t fd = -1;
+ int32_t output_fd = -1;
+ char export_path[PATH_MAX] = {
+ 0,
+ };
+ char *buf = NULL;
+ int32_t iter = 0;
+ int32_t ret = -1;
+ uint64_t total_blks = 0;
+ uint32_t blk_size;
+ uint32_t blk_count;
+ double throughput = 0;
+ double time = 0;
+ struct timeval begin, end = {
+ 0,
+ };
+
+ GF_ASSERT(brick_path);
+
+ ret = dict_get_uint32(dict, "blk-size", &blk_size);
+ if (ret)
+ goto out;
+ ret = dict_get_uint32(dict, "blk-cnt", &blk_count);
+ if (ret)
+ goto out;
+
+ if (!(blk_size > 0) || !(blk_count > 0))
+ goto out;
+
+ buf = GF_CALLOC(1, blk_size * sizeof(*buf), gf_common_mt_char);
+ if (!buf) {
+ ret = -1;
+ gf_log("glusterd", GF_LOG_ERROR, "Could not allocate memory");
+ goto out;
+ }
+
+ snprintf(export_path, sizeof(export_path), "%s/%s", brick_path,
+ ".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;
+ }
+
+ gettimeofday(&begin, NULL);
+ for (iter = 0; iter < blk_count; iter++) {
+ ret = sys_write(fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ total_blks += ret;
+ }
+ gettimeofday(&end, NULL);
+ if (total_blks != ((uint64_t)blk_size * blk_count)) {
+ gf_log("glusterd", GF_LOG_WARNING, "Error in write");
+ ret = -1;
+ goto out;
+ }
+
+ time = gf_tvdiff(&begin, &end);
+ throughput = total_blks / time;
+ gf_log("glusterd", GF_LOG_INFO,
+ "Throughput %.2f Mbps time %.2f secs "
+ "bytes written %" PRId64,
+ throughput, time, total_blks);
+
+ /* if it's a write test, we are done. Otherwise, we continue to the read
+ * part */
+ if (write_test == _gf_true) {
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);
+ goto out;
+ }
+
+ ret = sys_fsync(fd);
+ if (ret) {
+ gf_log("glusterd", GF_LOG_ERROR, "could not flush cache");
+ goto out;
+ }
+ ret = sys_lseek(fd, 0L, 0);
+ if (ret != 0) {
+ gf_log("glusterd", GF_LOG_ERROR, "could not seek back to start");
+ ret = -1;
+ 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;
+ }
+
+ total_blks = 0;
+
+ gettimeofday(&begin, NULL);
+ for (iter = 0; iter < blk_count; iter++) {
+ ret = sys_read(fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ ret = sys_write(output_fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ total_blks += ret;
+ }
+ gettimeofday(&end, NULL);
+ if (total_blks != ((uint64_t)blk_size * blk_count)) {
+ ret = -1;
+ gf_log("glusterd", GF_LOG_WARNING, "Error in read");
+ goto out;
+ }
+
+ time = gf_tvdiff(&begin, &end);
+ throughput = total_blks / time;
+ gf_log("glusterd", GF_LOG_INFO,
+ "Throughput %.2f Mbps time %.2f secs "
+ "bytes read %" PRId64,
+ throughput, time, total_blks);
+ ret = 0;
out:
- if (fd >= 0)
- close (fd);
- if (input_fd >= 0)
- close (input_fd);
- GF_FREE (buf);
- unlink (export_path);
-
- return ret;
+ if (fd >= 0)
+ sys_close(fd);
+ if (output_fd >= 0)
+ sys_close(output_fd);
+ GF_FREE(buf);
+ sys_unlink(export_path);
+ if (ret == 0) {
+ ret = dict_set_double(dict, "time", time);
+ if (ret)
+ goto end;
+ ret = dict_set_double(dict, "throughput", throughput);
+ if (ret)
+ goto end;
+ }
+end:
+ return ret;
}
int
-glusterfs_volume_top_read_perf (uint32_t blk_size, uint32_t blk_count,
- char *brick_path, double *throughput,
- double *time)
+glusterfs_handle_translator_op(rpcsvc_request_t *req)
{
- int32_t fd = -1;
- int32_t input_fd = -1;
- int32_t output_fd = -1;
- char export_path[PATH_MAX] = {0,};
- char *buf = NULL;
- int32_t iter = 0;
- int32_t ret = -1;
- uint64_t total_blks = 0;
- struct timeval begin, end = {0,};
-
- GF_ASSERT (brick_path);
- GF_ASSERT (throughput);
- GF_ASSERT (time);
- if (!(blk_size > 0) || ! (blk_count > 0))
- goto out;
-
- snprintf (export_path, sizeof (export_path), "%s/%s",
- brick_path, ".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;
- }
- }
+ int32_t ret = -1;
+ int32_t op_ret = 0;
+ 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[32] = {0};
+ int len;
+ char *xname = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *this = NULL;
+ int i = 0;
+ int count = 0;
+
+ GF_ASSERT(req);
+ this = THIS;
+ GF_ASSERT(this);
+
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ // failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ ctx = glusterfsd_ctx;
+ active = ctx->active;
+ if (!active) {
+ ret = -1;
+ gf_smsg(this->name, GF_LOG_ERROR, EAGAIN, glusterfsd_msg_38,
+ "brick-op_no.=%d", xlator_req.op, NULL);
+ goto out;
+ }
+ 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;
+ }
- ret = fsync (fd);
+ for (i = 0; i < count; i++) {
+ len = snprintf(key, sizeof(key), "xl-%d", i);
+ ret = dict_get_strn(input, key, len, &xname);
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;
+ gf_log(this->name, GF_LOG_ERROR,
+ "Couldn't get "
+ "xlator %s ",
+ key);
+ 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);
-
+ 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++) {
+ len = snprintf(key, sizeof(key), "xl-%d", i);
+ ret = dict_get_strn(input, key, len, &xname);
+ xlator = xlator_search_by_name(any, xname);
+ XLATOR_NOTIFY(ret, xlator, GF_EVENT_TRANSLATOR_OP, input, output);
+ /* If notify fails for an xlator we need to capture it but
+ * continue with the loop. */
+ if (ret)
+ op_ret = -1;
+ }
+ ret = op_ret;
out:
- if (fd >= 0)
- close (fd);
- if (input_fd >= 0)
- close (input_fd);
- if (output_fd >= 0)
- close (output_fd);
- GF_FREE (buf);
- unlink (export_path);
-
- return ret;
+ glusterfs_xlator_op_response_send(req, ret, "", output);
+ if (input)
+ dict_unref(input);
+ if (output)
+ dict_unref(output);
+ free(xlator_req.name); // malloced by xdr
+
+ return 0;
}
int
-glusterfs_handle_translator_op (rpcsvc_request_t *req)
+glusterfs_handle_bitrot(rpcsvc_request_t *req)
{
- 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;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ret = xdr_to_generic (req->msg[0], &xlator_req,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- ctx = glusterfsd_ctx;
- 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;
- }
+ int32_t ret = -1;
+ gd1_mgmt_brick_op_req xlator_req = {
+ 0,
+ };
+ dict_t *input = NULL;
+ dict_t *output = NULL;
+ xlator_t *any = NULL;
+ xlator_t *this = NULL;
+ xlator_t *xlator = NULL;
+ char msg[2048] = {
+ 0,
+ };
+ char xname[1024] = {
+ 0,
+ };
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ char *scrub_opt = NULL;
+
+ GF_ASSERT(req);
+ this = THIS;
+ GF_ASSERT(this);
+
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+
+ if (ret < 0) {
+ /*failed to decode msg;*/
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ ctx = glusterfsd_ctx;
+ GF_ASSERT(ctx);
+
+ active = ctx->active;
+ if (!active) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ any = active->first;
+
+ input = dict_new();
+ if (!input)
+ goto out;
+
+ ret = dict_unserialize(xlator_req.input.input_val,
+ xlator_req.input.input_len, &input);
+
+ if (ret < 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, glusterfsd_msg_35, NULL);
+ goto out;
+ }
+
+ /* Send scrubber request to bitrot xlator */
+ snprintf(xname, sizeof(xname), "%s-bit-rot-0", xlator_req.name);
+ xlator = xlator_search_by_name(any, xname);
+ if (!xlator) {
+ snprintf(msg, sizeof(msg), "xlator %s is not loaded", xname);
+ gf_smsg(this->name, GF_LOG_ERROR, 0, glusterfsd_msg_36, NULL);
+ goto out;
+ }
+
+ 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;
- }
+ ret = dict_get_str(input, "scrub-value", &scrub_opt);
+ if (ret) {
+ snprintf(msg, sizeof(msg), "Failed to get scrub value");
+ gf_smsg(this->name, GF_LOG_ERROR, 0, glusterfsd_msg_37, NULL);
+ ret = -1;
+ goto out;
+ }
+
+ if (!strncmp(scrub_opt, "status", SLEN("status"))) {
+ ret = xlator->notify(xlator, GF_EVENT_SCRUB_STATUS, input, output);
+ } else if (!strncmp(scrub_opt, "ondemand", SLEN("ondemand"))) {
+ ret = xlator->notify(xlator, GF_EVENT_SCRUB_ONDEMAND, input, output);
+ if (ret == -2) {
+ snprintf(msg, sizeof(msg),
+ "Scrubber is in "
+ "Pause/Inactive/Running state");
+ ret = -1;
+ goto out;
+ }
+ }
out:
- glusterfs_xlator_op_response_send (req, ret, "", output);
- if (input)
- dict_unref (input);
- if (output)
- dict_unref (output);
- free (xlator_req.name); //malloced by xdr
-
- return 0;
+ glusterfs_translator_info_response_send(req, ret, msg, output);
+
+ if (input)
+ dict_unref(input);
+ free(xlator_req.input.input_val); /*malloced by xdr*/
+ if (xlator_req.dict.dict_val)
+ free(xlator_req.dict.dict_val);
+ if (output)
+ dict_unref(output);
+ free(xlator_req.name);
+
+ return 0;
}
-
int
-glusterfs_handle_defrag (rpcsvc_request_t *req)
+glusterfs_handle_attach(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;
- char msg[2048] = {0};
- glusterfs_ctx_t *ctx = NULL;
- glusterfs_graph_t *active = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ctx = glusterfsd_ctx;
- GF_ASSERT (ctx);
-
- active = ctx->active;
- if (!active) {
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- any = active->first;
- ret = xdr_to_generic (req->msg[0], &xlator_req,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
- if (ret < 0) {
- //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,
- &dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to "
- "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);
- goto out;
+ int32_t ret = -1;
+ gd1_mgmt_brick_op_req xlator_req = {
+ 0,
+ };
+ xlator_t *this = NULL;
+ xlator_t *nextchild = NULL;
+ glusterfs_graph_t *newgraph = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ xlator_t *srv_xl = NULL;
+ server_conf_t *srv_conf = NULL;
+
+ GF_ASSERT(req);
+ this = THIS;
+ GF_ASSERT(this);
+
+ ctx = this->ctx;
+ if (!ctx->cmd_args.volfile_id) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "No volfile-id provided, erroring out");
+ return -1;
+ }
+
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+
+ if (ret < 0) {
+ /*failed to decode msg;*/
+ req->rpc_err = GARBAGE_ARGS;
+ return -1;
+ }
+ ret = 0;
+
+ if (!this->ctx->active) {
+ gf_log(this->name, GF_LOG_WARNING,
+ "got attach for %s but no active graph", xlator_req.name);
+ goto post_unlock;
+ }
+
+ gf_log(this->name, GF_LOG_INFO, "got attach for %s", xlator_req.name);
+
+ LOCK(&ctx->volfile_lock);
+ {
+ ret = glusterfs_graph_attach(this->ctx->active, xlator_req.name,
+ &newgraph);
+ if (!ret && (newgraph && newgraph->first)) {
+ nextchild = newgraph->first;
+ ret = xlator_notify(nextchild, GF_EVENT_PARENT_UP, nextchild);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_EVENT_NOTIFY_FAILED,
+ "event=ParentUp", "name=%s", nextchild->name, NULL);
+ goto unlock;
+ }
+ /* we need a protocol/server xlator as
+ * nextchild
+ */
+ srv_xl = this->ctx->active->first;
+ srv_conf = (server_conf_t *)srv_xl->private;
+ rpcsvc_autoscale_threads(this->ctx, srv_conf->rpc, 1);
}
-
- output = dict_new ();
- if (!output) {
- ret = -1;
- goto out;
+ if (ret) {
+ ret = -1;
}
+ ret = glusterfs_translator_info_response_send(req, ret, NULL, NULL);
+ if (ret) {
+ /* Response sent back to glusterd, req is already destroyed. So
+ * resetting the ret to 0. Otherwise another response will be
+ * send from rpcsvc_check_and_reply_error. Which will lead to
+ * double resource leak.
+ */
+ ret = 0;
+ }
+ unlock:
+ UNLOCK(&ctx->volfile_lock);
+ }
+post_unlock:
+ if (xlator_req.dict.dict_val)
+ free(xlator_req.dict.dict_val);
+ free(xlator_req.input.input_val);
+ free(xlator_req.name);
+
+ return ret;
+}
- ret = xlator->notify (xlator, GF_EVENT_VOLUME_DEFRAG, dict, output);
-
- ret = glusterfs_translator_info_response_send (req, ret,
- msg, output);
+int
+glusterfs_handle_svc_attach(rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gd1_mgmt_brick_op_req xlator_req = {
+ 0,
+ };
+ xlator_t *this = NULL;
+ dict_t *dict = NULL;
+
+ GF_ASSERT(req);
+ this = THIS;
+ GF_ASSERT(this);
+
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+
+ if (ret < 0) {
+ /*failed to decode msg;*/
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ gf_smsg(THIS->name, GF_LOG_INFO, 0, glusterfsd_msg_41, "volfile-id=%s",
+ xlator_req.name, NULL);
+
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = dict_unserialize(xlator_req.dict.dict_val, xlator_req.dict.dict_len,
+ &dict);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_WARNING, EINVAL, glusterfsd_msg_42, NULL);
+ goto out;
+ }
+ dict->extra_stdfree = xlator_req.dict.dict_val;
+
+ ret = 0;
+
+ ret = mgmt_process_volfile(xlator_req.input.input_val,
+ xlator_req.input.input_len, xlator_req.name,
+ dict);
out:
- if (dict)
- dict_unref (dict);
- free (xlator_req.input.input_val); // malloced by xdr
- if (output)
- dict_unref (output);
- free (xlator_req.name); //malloced by xdr
-
- return ret;
-
+ if (dict)
+ dict_unref(dict);
+ if (xlator_req.input.input_val)
+ free(xlator_req.input.input_val);
+ if (xlator_req.name)
+ free(xlator_req.name);
+ glusterfs_translator_info_response_send(req, ret, NULL, NULL);
+ return 0;
}
+
int
-glusterfs_handle_brick_status (rpcsvc_request_t *req)
+glusterfs_handle_svc_detach(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);
-
- ret = xdr_to_generic (req->msg[0], &brick_req,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
- if (ret < 0) {
- 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);
+ gd1_mgmt_brick_op_req xlator_req = {
+ 0,
+ };
+ ssize_t ret;
+ gf_volfile_t *volfile_obj = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ gf_volfile_t *volfile_tmp = NULL;
+
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ req->rpc_err = GARBAGE_ARGS;
+ return -1;
+ }
+ ctx = glusterfsd_ctx;
+
+ LOCK(&ctx->volfile_lock);
+ {
+ list_for_each_entry(volfile_obj, &ctx->volfile_list, volfile_list)
+ {
+ if (!strcmp(xlator_req.name, volfile_obj->vol_id)) {
+ volfile_tmp = volfile_obj;
+ break;
+ }
+ }
+
+ if (!volfile_tmp) {
+ UNLOCK(&ctx->volfile_lock);
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, glusterfsd_msg_041, "name=%s",
+ xlator_req.name, NULL);
+ /*
+ * Used to be -ENOENT. However, the caller asked us to
+ * make sure it's down and if it's already down that's
+ * good enough.
+ */
+ ret = 0;
+ goto out;
+ }
+ /* coverity[ORDER_REVERSAL] */
+ ret = glusterfs_process_svc_detach(ctx, volfile_tmp);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Couldn't get volname");
- goto out;
+ UNLOCK(&ctx->volfile_lock);
+ gf_smsg("glusterfsd-mgmt", GF_LOG_ERROR, EINVAL, glusterfsd_msg_042,
+ NULL);
+ goto out;
}
+ }
+ UNLOCK(&ctx->volfile_lock);
+out:
+ glusterfs_terminate_response_send(req, ret);
+ free(xlator_req.name);
+ xlator_req.name = NULL;
- ctx = glusterfsd_ctx;
- 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;
+ return 0;
+}
- case GF_CLI_STATUS_INODE:
- ret = xlator->dumpops->inode_to_dict (xlator, output);
- break;
+int
+glusterfs_handle_dump_metrics(rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gd1_mgmt_brick_op_req xlator_req = {
+ 0,
+ };
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char *filepath = NULL;
+ int fd = -1;
+ struct stat statbuf = {
+ 0,
+ };
+ char *msg = NULL;
+
+ GF_ASSERT(req);
+ this = THIS;
+ GF_ASSERT(this);
+
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+
+ if (ret < 0) {
+ /*failed to decode msg;*/
+ req->rpc_err = GARBAGE_ARGS;
+ return -1;
+ }
+ ret = -1;
+ ctx = this->ctx;
+
+ /* Infra for monitoring */
+ filepath = gf_monitor_metrics(ctx);
+ if (!filepath)
+ goto out;
+
+ fd = sys_open(filepath, O_RDONLY, 0);
+ if (fd < 0)
+ goto out;
+
+ if (sys_fstat(fd, &statbuf) < 0)
+ goto out;
+
+ if (statbuf.st_size > GF_UNIT_MB) {
+ gf_smsg(this->name, GF_LOG_WARNING, ENOMEM, LG_MSG_NO_MEMORY,
+ "reconsider logic (%" PRId64 ")", statbuf.st_size, NULL);
+ }
+ msg = GF_CALLOC(1, (statbuf.st_size + 1), gf_common_mt_char);
+ if (!msg)
+ goto out;
+
+ ret = sys_read(fd, msg, statbuf.st_size);
+ if (ret < 0)
+ goto out;
+
+ /* Send all the data in errstr, instead of dictionary for now */
+ glusterfs_translator_info_response_send(req, 0, msg, NULL);
+
+ ret = 0;
+out:
+ if (fd >= 0)
+ sys_close(fd);
- case GF_CLI_STATUS_FD:
- ret = xlator->dumpops->fd_to_dict (xlator, output);
- break;
+ GF_FREE(msg);
+ GF_FREE(filepath);
+ if (xlator_req.input.input_val)
+ free(xlator_req.input.input_val);
+ if (xlator_req.dict.dict_val)
+ free(xlator_req.dict.dict_val);
- case GF_CLI_STATUS_CALLPOOL:
- ret = 0;
- gf_proc_dump_pending_frames_to_dict (ctx->pool, output);
- break;
+ return ret;
+}
- 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;
- }
+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;
+ char msg[2048] = {0};
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *this = NULL;
+
+ GF_ASSERT(req);
+ this = THIS;
+ GF_ASSERT(this);
+
+ ctx = glusterfsd_ctx;
+ GF_ASSERT(ctx);
+
+ active = ctx->active;
+ if (!active) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ any = active->first;
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ // 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, &dict);
+ if (ret < 0) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "failed to "
+ "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);
+ goto out;
+ }
+
+ output = dict_new();
+ if (!output) {
+ ret = -1;
+ goto out;
+ }
- glusterfs_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
- ret = 0;
+ ret = xlator->notify(xlator, GF_EVENT_VOLUME_DEFRAG, dict, output);
+ ret = glusterfs_translator_info_response_send(req, ret, msg, output);
out:
- if (dict)
- dict_unref (dict);
- if (output)
- dict_unref (output);
- free (brick_req.input.input_val);
- GF_FREE (xname);
- GF_FREE (msg);
- GF_FREE (rsp.output.output_val);
-
- return ret;
+ if (dict)
+ dict_unref(dict);
+ free(xlator_req.input.input_val); // malloced by xdr
+ if (xlator_req.dict.dict_val)
+ free(xlator_req.dict.dict_val);
+ if (output)
+ dict_unref(output);
+ free(xlator_req.name); // malloced by xdr
+
+ return ret;
}
-
-
int
-glusterfs_handle_node_status (rpcsvc_request_t *req)
+glusterfs_handle_brick_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);
-
- ret = xdr_to_generic (req->msg[0], &node_req,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
- if (ret < 0) {
- 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 = glusterfsd_ctx;
- 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 if ((cmd & GF_CLI_STATUS_QUOTAD) != 0)
- ret = gf_asprintf (&node_name, "%s", "quotad");
- else if ((cmd & GF_CLI_STATUS_BITD) != 0)
- ret = gf_asprintf (&node_name, "%s", "bitd");
- else if ((cmd & GF_CLI_STATUS_SCRUB) != 0)
- ret = gf_asprintf (&node_name, "%s", "scrubber");
-
- 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;
- }
+ 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 *server_xl = NULL;
+ xlator_t *brick_xl = NULL;
+ dict_t *dict = NULL;
+ dict_t *output = NULL;
+ uint32_t cmd = 0;
+ char *msg = NULL;
+ char *brickname = NULL;
+
+ GF_ASSERT(req);
+ this = THIS;
+ GF_ASSERT(this);
+
+ ret = xdr_to_generic(req->msg[0], &brick_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ 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, "brick-name", &brickname);
+ if (ret) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "Couldn't get brickname from"
+ " dict");
+ goto out;
+ }
+
+ ctx = glusterfsd_ctx;
+ if (ctx == NULL) {
+ gf_log(this->name, GF_LOG_ERROR, "ctx returned NULL");
+ ret = -1;
+ goto out;
+ }
+ if (ctx->active == NULL) {
+ gf_log(this->name, GF_LOG_ERROR, "ctx->active returned NULL");
+ ret = -1;
+ goto out;
+ }
+ active = ctx->active;
+ if (ctx->active->first == NULL) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "ctx->active->first "
+ "returned NULL");
+ ret = -1;
+ goto out;
+ }
+ server_xl = active->first;
- 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 if ((cmd & GF_CLI_STATUS_QUOTAD) != 0)
- ret = gf_asprintf (&subvol_name, "%s", volname);
- else if ((cmd & GF_CLI_STATUS_BITD) != 0)
- ret = gf_asprintf (&subvol_name, "%s", volname);
- else if ((cmd & GF_CLI_STATUS_SCRUB) != 0)
- ret = gf_asprintf (&subvol_name, "%s", volname);
- else {
- ret = -1;
- goto out;
- }
- if (ret == -1) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to set node xlator name");
- goto out;
- }
+ brick_xl = get_xlator_by_name(server_xl, brickname);
+ if (!brick_xl) {
+ gf_log(this->name, GF_LOG_ERROR, "xlator is not loaded");
+ 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:
+ case GF_CLI_STATUS_CLIENT_LIST:
+ ret = server_xl->dumpops->priv_to_dict(server_xl, output,
+ brickname);
+ break;
+
+ case GF_CLI_STATUS_INODE:
+ ret = server_xl->dumpops->inode_to_dict(brick_xl, output);
+ break;
+
+ case GF_CLI_STATUS_FD:
+ ret = server_xl->dumpops->fd_to_dict(brick_xl, output);
+ break;
+
+ case GF_CLI_STATUS_CALLPOOL:
+ ret = 0;
+ gf_proc_dump_pending_frames_to_dict(ctx->pool, output);
+ break;
- 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;
- }
+ 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 = "";
- 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;
- }
+ 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;
+ glusterfs_submit_reply(req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ ret = 0;
out:
- if (dict)
- dict_unref (dict);
- free (node_req.input.input_val);
- GF_FREE (msg);
- GF_FREE (rsp.output.output_val);
- GF_FREE (node_name);
- GF_FREE (subvol_name);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ if (dict)
+ dict_unref(dict);
+ if (output)
+ dict_unref(output);
+ free(brick_req.input.input_val);
+ if (brick_req.dict.dict_val)
+ free(brick_req.dict.dict_val);
+ free(brick_req.name);
+ GF_FREE(msg);
+ GF_FREE(rsp.output.output_val);
+
+ return ret;
}
int
-glusterfs_handle_nfs_profile (rpcsvc_request_t *req)
+glusterfs_handle_node_status(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);
-
- ret = xdr_to_generic (req->msg[0], &nfs_req,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
- if (ret < 0) {
- 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;
- }
+ 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);
+
+ ret = xdr_to_generic(req->msg[0], &node_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ 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 = glusterfsd_ctx;
+ GF_ASSERT(ctx);
+ active = ctx->active;
+ if (active == NULL) {
+ gf_log(THIS->name, GF_LOG_ERROR, "ctx->active returned NULL");
+ ret = -1;
+ goto out;
+ }
+ any = active->first;
+
+ if ((cmd & GF_CLI_STATUS_SHD) != 0)
+ ret = gf_asprintf(&node_name, "%s", "glustershd");
+#ifdef BUILD_GNFS
+ else if ((cmd & GF_CLI_STATUS_NFS) != 0)
+ ret = gf_asprintf(&node_name, "%s", "nfs-server");
+#endif
+ else if ((cmd & GF_CLI_STATUS_QUOTAD) != 0)
+ ret = gf_asprintf(&node_name, "%s", "quotad");
+ else if ((cmd & GF_CLI_STATUS_BITD) != 0)
+ ret = gf_asprintf(&node_name, "%s", "bitd");
+ else if ((cmd & GF_CLI_STATUS_SCRUB) != 0)
+ ret = gf_asprintf(&node_name, "%s", "scrubber");
+
+ 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 if ((cmd & GF_CLI_STATUS_QUOTAD) != 0)
+ ret = gf_asprintf(&subvol_name, "%s", volname);
+ else if ((cmd & GF_CLI_STATUS_BITD) != 0)
+ ret = gf_asprintf(&subvol_name, "%s", volname);
+ else if ((cmd & GF_CLI_STATUS_SCRUB) != 0)
+ ret = gf_asprintf(&subvol_name, "%s", 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 available for SHD
+ if ((cmd & GF_CLI_STATUS_SHD) != 0)
+ break;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get volname");
+ 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, NULL);
+ break;
- ctx = glusterfsd_ctx;
- GF_ASSERT (ctx);
+ case GF_CLI_STATUS_INODE:
+ ret = 0;
+ inode_table_dump_to_dict(subvol->itable, "conn0", output);
+ ret = dict_set_int32(output, "conncount", 1);
+ break;
- active = ctx->active;
- any = active->first;
+ case GF_CLI_STATUS_FD:
+ // cannot find fd-tables in nfs-server graph
+ // TODO: finish once found
+ break;
- // 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;
- }
+ case GF_CLI_STATUS_CALLPOOL:
+ ret = 0;
+ gf_proc_dump_pending_frames_to_dict(ctx->pool, output);
+ break;
- 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;
+ 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;
- }
+ 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;
+ glusterfs_submit_reply(req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ ret = 0;
out:
- free (nfs_req.input.input_val);
- if (dict)
- dict_unref (dict);
- if (output)
- dict_unref (output);
- GF_FREE (rsp.output.output_val);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ if (dict)
+ dict_unref(dict);
+ free(node_req.input.input_val);
+ if (node_req.dict.dict_val)
+ free(node_req.dict.dict_val);
+ GF_FREE(msg);
+ GF_FREE(rsp.output.output_val);
+ GF_FREE(node_name);
+ GF_FREE(subvol_name);
+
+ gf_log(THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
int
-glusterfs_handle_volume_barrier_op (rpcsvc_request_t *req)
+glusterfs_handle_nfs_profile(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;
- char msg[2048] = {0};
- glusterfs_ctx_t *ctx = NULL;
- glusterfs_graph_t *active = NULL;
- xlator_t *this = NULL;
-
- GF_ASSERT (req);
- this = THIS;
- GF_ASSERT (this);
-
- ctx = glusterfsd_ctx;
- GF_ASSERT (ctx);
-
- active = ctx->active;
- if (!active) {
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
+ 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);
+
+ ret = xdr_to_generic(req->msg[0], &nfs_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ 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 = glusterfsd_ctx;
+ GF_ASSERT(ctx);
+
+ active = ctx->active;
+ if (active == NULL) {
+ gf_log(THIS->name, GF_LOG_ERROR, "ctx->active returned NULL");
+ ret = -1;
+ goto out;
+ }
+ 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;
+ }
- any = active->first;
- ret = xdr_to_generic (req->msg[0], &xlator_req,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
- if (ret < 0) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
- dict = dict_new ();
- if (!dict)
- goto out;
+ output = dict_new();
+ ret = subvol->notify(subvol, GF_EVENT_TRANSLATOR_INFO, dict, output);
- 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;
- }
- xlator = xlator_search_by_name (any, xlator_req.name);
- if (!xlator) {
- snprintf (msg, sizeof (msg), "xlator %s is not loaded",
- xlator_req.name);
- goto out;
- }
+ rsp.op_ret = ret;
+ rsp.op_errno = 0;
+ rsp.op_errstr = "";
- output = dict_new ();
- if (!output) {
- ret = -1;
- goto out;
- }
+ 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;
+ }
- ret = xlator->notify (xlator, GF_EVENT_VOLUME_BARRIER_OP,
- dict, output);
+ glusterfs_submit_reply(req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ ret = 0;
- ret = glusterfs_translator_info_response_send (req, ret,
- msg, output);
out:
- if (dict)
- dict_unref (dict);
- free (xlator_req.input.input_val); // malloced by xdr
- if (output)
- dict_unref (output);
- free (xlator_req.name); //malloced by xdr
-
- return ret;
-
+ free(nfs_req.input.input_val);
+ if (nfs_req.dict.dict_val)
+ free(nfs_req.dict.dict_val);
+ if (dict)
+ dict_unref(dict);
+ if (output)
+ dict_unref(output);
+ GF_FREE(rsp.output.output_val);
+
+ gf_log(THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
int
-glusterfs_handle_barrier (rpcsvc_request_t *req)
+glusterfs_handle_volume_barrier_op(rpcsvc_request_t *req)
{
- int ret = -1;
- gd1_mgmt_brick_op_req brick_req = {0,};
- gd1_mgmt_brick_op_rsp brick_rsp = {0,};
- glusterfs_ctx_t *ctx = NULL;
- glusterfs_graph_t *active = NULL;
- xlator_t *any = NULL;
- xlator_t *xlator = NULL;
- xlator_t *old_THIS = NULL;
- dict_t *dict = NULL;
- char name[1024] = {0,};
- gf_boolean_t barrier = _gf_true;
- gf_boolean_t barrier_err = _gf_false;
-
- GF_ASSERT (req);
-
- ret = xdr_to_generic(req->msg[0], &brick_req,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
- if (ret < 0) {
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- ctx = glusterfsd_ctx;
- GF_ASSERT (ctx);
- active = ctx->active;
- any = active->first;
-
- dict = dict_new();
- if (!dict) {
- ret = -1;
- goto out;
- }
+ 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;
+ char msg[2048] = {0};
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *this = NULL;
+
+ GF_ASSERT(req);
+ this = THIS;
+ GF_ASSERT(this);
+
+ ctx = glusterfsd_ctx;
+ GF_ASSERT(ctx);
+
+ active = ctx->active;
+ if (!active) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ any = active->first;
+ ret = xdr_to_generic(req->msg[0], &xlator_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ // 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, &dict);
+ if (ret < 0) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "failed to "
+ "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);
+ goto out;
+ }
+
+ output = dict_new();
+ if (!output) {
+ ret = -1;
+ goto out;
+ }
- 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 "
- "request dictionary");
- goto out;
- }
+ ret = xlator->notify(xlator, GF_EVENT_VOLUME_BARRIER_OP, dict, output);
- brick_rsp.op_ret = 0;
- brick_rsp.op_errstr = ""; // initing to prevent serilaztion failures
- old_THIS = THIS;
+ ret = glusterfs_translator_info_response_send(req, ret, msg, output);
+out:
+ if (dict)
+ dict_unref(dict);
+ free(xlator_req.input.input_val); // malloced by xdr
+ if (xlator_req.dict.dict_val)
+ free(xlator_req.dict.dict_val);
+ if (output)
+ dict_unref(output);
+ free(xlator_req.name); // malloced by xdr
+
+ return ret;
+}
- /* Send barrier request to the barrier xlator */
- snprintf (name, sizeof (name), "%s-barrier", brick_req.name);
- xlator = xlator_search_by_name(any, name);
- if (!xlator) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR, "%s xlator is not loaded",
- name);
- goto out;
- }
+int
+glusterfs_handle_barrier(rpcsvc_request_t *req)
+{
+ int ret = -1;
+ gd1_mgmt_brick_op_req brick_req = {
+ 0,
+ };
+ gd1_mgmt_brick_op_rsp brick_rsp = {
+ 0,
+ };
+ glusterfs_ctx_t *ctx = NULL;
+ glusterfs_graph_t *active = NULL;
+ xlator_t *top = NULL;
+ xlator_t *xlator = NULL;
+ xlator_t *old_THIS = NULL;
+ dict_t *dict = NULL;
+ gf_boolean_t barrier = _gf_true;
+ xlator_list_t *trav;
+
+ GF_ASSERT(req);
+
+ ret = xdr_to_generic(req->msg[0], &brick_req,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ if (ret < 0) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ ctx = glusterfsd_ctx;
+ GF_ASSERT(ctx);
+ active = ctx->active;
+ if (active == NULL) {
+ gf_log(THIS->name, GF_LOG_ERROR, "ctx->active returned NULL");
+ ret = -1;
+ goto out;
+ }
+ top = active->first;
- THIS = xlator;
- // TODO: Extend this to accept return of errnos
- ret = xlator->notify (xlator, GF_EVENT_TRANSLATOR_OP, dict);
- if (ret) {
- brick_rsp.op_ret = ret;
- brick_rsp.op_errstr = gf_strdup ("Failed to reconfigure "
- "barrier.");
- /* This is to invoke changelog-barrier disable if barrier
- * disable fails and don't invoke if barrier enable fails.
- */
- barrier = dict_get_str_boolean (dict, "barrier", _gf_true);
- if (barrier)
- goto submit_reply;
- else
- barrier_err = _gf_true;
+ for (trav = top->children; trav; trav = trav->next) {
+ if (strcmp(trav->xlator->name, brick_req.name) == 0) {
+ break;
}
+ }
+ if (!trav) {
+ ret = -1;
+ goto out;
+ }
+ top = trav->xlator;
- /* Reset THIS so that we have it correct in case of an error below
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ 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 "
+ "request dictionary");
+ goto out;
+ }
+
+ brick_rsp.op_ret = 0;
+ brick_rsp.op_errstr = ""; // initing to prevent serilaztion failures
+ old_THIS = THIS;
+
+ /* Send barrier request to the barrier xlator */
+ xlator = get_xlator_by_type(top, "features/barrier");
+ if (!xlator) {
+ ret = -1;
+ gf_log(THIS->name, GF_LOG_ERROR, "%s xlator is not loaded",
+ "features/barrier");
+ goto out;
+ }
+
+ THIS = xlator;
+ // TODO: Extend this to accept return of errnos
+ ret = xlator->notify(xlator, GF_EVENT_TRANSLATOR_OP, dict);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "barrier notify failed");
+ brick_rsp.op_ret = ret;
+ brick_rsp.op_errstr = gf_strdup(
+ "Failed to reconfigure "
+ "barrier.");
+ /* This is to invoke changelog-barrier disable if barrier
+ * disable fails and don't invoke if barrier enable fails.
*/
- THIS = old_THIS;
-
- /* Send barrier request to changelog as well */
-
- memset (name, 0, sizeof (name));
- snprintf (name, sizeof (name), "%s-changelog", brick_req.name);
- xlator = xlator_search_by_name(any, name);
- if (!xlator) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR, "%s xlator is not loaded",
- name);
- goto out;
- }
-
- THIS = xlator;
- ret = xlator->notify (xlator, GF_EVENT_TRANSLATOR_OP, dict);
- if (ret) {
- brick_rsp.op_ret = ret;
- brick_rsp.op_errstr = gf_strdup ("changelog notify failed");
- goto submit_reply;
- }
-
- if (barrier_err)
- ret = -1;
+ barrier = dict_get_str_boolean(dict, "barrier", _gf_true);
+ if (barrier)
+ goto submit_reply;
+ }
+
+ /* Reset THIS so that we have it correct in case of an error below
+ */
+ THIS = old_THIS;
+
+ /* Send barrier request to changelog as well */
+ xlator = get_xlator_by_type(top, "features/changelog");
+ if (!xlator) {
+ ret = -1;
+ gf_log(THIS->name, GF_LOG_ERROR, "%s xlator is not loaded",
+ "features/changelog");
+ goto out;
+ }
+
+ THIS = xlator;
+ ret = xlator->notify(xlator, GF_EVENT_TRANSLATOR_OP, dict);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "changelog notify failed");
+ brick_rsp.op_ret = ret;
+ brick_rsp.op_errstr = gf_strdup("changelog notify failed");
+ goto submit_reply;
+ }
submit_reply:
- THIS = old_THIS;
+ THIS = old_THIS;
- ret = glusterfs_submit_reply (req, &brick_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ ret = glusterfs_submit_reply(req, &brick_rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
out:
- if (dict)
- dict_unref (dict);
- free (brick_req.input.input_val);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ if (dict)
+ dict_unref(dict);
+ free(brick_req.input.input_val);
+ if (brick_req.dict.dict_val)
+ free(brick_req.dict.dict_val);
+ gf_log(THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
int
-glusterfs_handle_rpc_msg (rpcsvc_request_t *req)
+glusterfs_handle_rpc_msg(rpcsvc_request_t *req)
{
- int ret = -1;
- /* for now, nothing */
- return ret;
+ int ret = -1;
+ /* for now, nothing */
+ return ret;
}
-rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = {
- [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec },
- [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY,
- mgmt_cbk_event},
+static rpcclnt_cb_actor_t mgmt_cbk_actors[GF_CBK_MAXVALUE] = {
+ [GF_CBK_FETCHSPEC] = {"FETCHSPEC", mgmt_cbk_spec, GF_CBK_FETCHSPEC},
+ [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", mgmt_cbk_event,
+ GF_CBK_EVENT_NOTIFY},
+ [GF_CBK_STATEDUMP] = {"STATEDUMP", mgmt_cbk_event, GF_CBK_STATEDUMP},
};
-
-struct rpcclnt_cb_program mgmt_cbk_prog = {
- .progname = "GlusterFS Callback",
- .prognum = GLUSTER_CBK_PROGRAM,
- .progver = GLUSTER_CBK_VERSION,
- .actors = mgmt_cbk_actors,
- .numactors = GF_CBK_MAXVALUE,
+static struct rpcclnt_cb_program mgmt_cbk_prog = {
+ .progname = "GlusterFS Callback",
+ .prognum = GLUSTER_CBK_PROGRAM,
+ .progver = GLUSTER_CBK_VERSION,
+ .actors = mgmt_cbk_actors,
+ .numactors = GF_CBK_MAXVALUE,
};
-char *clnt_pmap_procs[GF_PMAP_MAXVALUE] = {
- [GF_PMAP_NULL] = "NULL",
- [GF_PMAP_PORTBYBRICK] = "PORTBYBRICK",
- [GF_PMAP_BRICKBYPORT] = "BRICKBYPORT",
- [GF_PMAP_SIGNIN] = "SIGNIN",
- [GF_PMAP_SIGNOUT] = "SIGNOUT",
- [GF_PMAP_SIGNUP] = "SIGNUP",
+static char *clnt_pmap_procs[GF_PMAP_MAXVALUE] = {
+ [GF_PMAP_NULL] = "NULL",
+ [GF_PMAP_PORTBYBRICK] = "PORTBYBRICK",
+ [GF_PMAP_BRICKBYPORT] = "BRICKBYPORT",
+ [GF_PMAP_SIGNIN] = "SIGNIN",
+ [GF_PMAP_SIGNOUT] = "SIGNOUT",
+ [GF_PMAP_SIGNUP] = "SIGNUP", /* DEPRECATED - DON'T USE! */
};
-
-rpc_clnt_prog_t clnt_pmap_prog = {
- .progname = "Gluster Portmap",
- .prognum = GLUSTER_PMAP_PROGRAM,
- .progver = GLUSTER_PMAP_VERSION,
- .procnames = clnt_pmap_procs,
+static rpc_clnt_prog_t clnt_pmap_prog = {
+ .progname = "Gluster Portmap",
+ .prognum = GLUSTER_PMAP_PROGRAM,
+ .progver = GLUSTER_PMAP_VERSION,
+ .procnames = clnt_pmap_procs,
};
-char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
- [GF_HNDSK_NULL] = "NULL",
- [GF_HNDSK_SETVOLUME] = "SETVOLUME",
- [GF_HNDSK_GETSPEC] = "GETSPEC",
- [GF_HNDSK_PING] = "PING",
- [GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY",
+static char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
+ [GF_HNDSK_NULL] = "NULL",
+ [GF_HNDSK_SETVOLUME] = "SETVOLUME",
+ [GF_HNDSK_GETSPEC] = "GETSPEC",
+ [GF_HNDSK_PING] = "PING",
+ [GF_HNDSK_EVENT_NOTIFY] = "EVENTNOTIFY",
};
-rpc_clnt_prog_t clnt_handshake_prog = {
- .progname = "GlusterFS Handshake",
- .prognum = GLUSTER_HNDSK_PROGRAM,
- .progver = GLUSTER_HNDSK_VERSION,
- .procnames = clnt_handshake_procs,
+static rpc_clnt_prog_t clnt_handshake_prog = {
+ .progname = "GlusterFS Handshake",
+ .prognum = GLUSTER_HNDSK_PROGRAM,
+ .progver = GLUSTER_HNDSK_VERSION,
+ .procnames = clnt_handshake_procs,
};
-rpcsvc_actor_t glusterfs_actors[GLUSTERD_BRICK_MAXVALUE] = {
- [GLUSTERD_BRICK_NULL] = {"NULL", GLUSTERD_BRICK_NULL, glusterfs_handle_rpc_msg, NULL, 0, DRC_NA},
- [GLUSTERD_BRICK_TERMINATE] = {"TERMINATE", GLUSTERD_BRICK_TERMINATE, glusterfs_handle_terminate, NULL, 0, DRC_NA},
- [GLUSTERD_BRICK_XLATOR_INFO] = {"TRANSLATOR INFO", GLUSTERD_BRICK_XLATOR_INFO, glusterfs_handle_translator_info_get, NULL, 0, DRC_NA},
- [GLUSTERD_BRICK_XLATOR_OP] = {"TRANSLATOR OP", GLUSTERD_BRICK_XLATOR_OP, glusterfs_handle_translator_op, NULL, 0, DRC_NA},
- [GLUSTERD_BRICK_STATUS] = {"STATUS", GLUSTERD_BRICK_STATUS, glusterfs_handle_brick_status, NULL, 0, DRC_NA},
- [GLUSTERD_BRICK_XLATOR_DEFRAG] = {"TRANSLATOR DEFRAG", GLUSTERD_BRICK_XLATOR_DEFRAG, glusterfs_handle_defrag, NULL, 0, DRC_NA},
- [GLUSTERD_NODE_PROFILE] = {"NFS PROFILE", GLUSTERD_NODE_PROFILE, glusterfs_handle_nfs_profile, NULL, 0, DRC_NA},
- [GLUSTERD_NODE_STATUS] = {"NFS STATUS", GLUSTERD_NODE_STATUS, glusterfs_handle_node_status, NULL, 0, DRC_NA},
- [GLUSTERD_VOLUME_BARRIER_OP] = {"VOLUME BARRIER OP", GLUSTERD_VOLUME_BARRIER_OP, glusterfs_handle_volume_barrier_op, NULL, 0, DRC_NA},
- [GLUSTERD_BRICK_BARRIER] = {"BARRIER", GLUSTERD_BRICK_BARRIER, glusterfs_handle_barrier, NULL, 0, DRC_NA},
+static rpcsvc_actor_t glusterfs_actors[GLUSTERD_BRICK_MAXVALUE] = {
+ [GLUSTERD_BRICK_NULL] = {"NULL", glusterfs_handle_rpc_msg, NULL,
+ GLUSTERD_BRICK_NULL, DRC_NA, 0},
+ [GLUSTERD_BRICK_TERMINATE] = {"TERMINATE", glusterfs_handle_terminate, NULL,
+ GLUSTERD_BRICK_TERMINATE, DRC_NA, 0},
+ [GLUSTERD_BRICK_XLATOR_INFO] = {"TRANSLATOR INFO",
+ glusterfs_handle_translator_info_get, NULL,
+ GLUSTERD_BRICK_XLATOR_INFO, DRC_NA, 0},
+ [GLUSTERD_BRICK_XLATOR_OP] = {"TRANSLATOR OP",
+ glusterfs_handle_translator_op, NULL,
+ GLUSTERD_BRICK_XLATOR_OP, DRC_NA, 0},
+ [GLUSTERD_BRICK_STATUS] = {"STATUS", glusterfs_handle_brick_status, NULL,
+ GLUSTERD_BRICK_STATUS, DRC_NA, 0},
+ [GLUSTERD_BRICK_XLATOR_DEFRAG] = {"TRANSLATOR DEFRAG",
+ glusterfs_handle_defrag, NULL,
+ GLUSTERD_BRICK_XLATOR_DEFRAG, DRC_NA, 0},
+ [GLUSTERD_NODE_PROFILE] = {"NFS PROFILE", glusterfs_handle_nfs_profile,
+ NULL, GLUSTERD_NODE_PROFILE, DRC_NA, 0},
+ [GLUSTERD_NODE_STATUS] = {"NFS STATUS", glusterfs_handle_node_status, NULL,
+ GLUSTERD_NODE_STATUS, DRC_NA, 0},
+ [GLUSTERD_VOLUME_BARRIER_OP] = {"VOLUME BARRIER OP",
+ glusterfs_handle_volume_barrier_op, NULL,
+ GLUSTERD_VOLUME_BARRIER_OP, DRC_NA, 0},
+ [GLUSTERD_BRICK_BARRIER] = {"BARRIER", glusterfs_handle_barrier, NULL,
+ GLUSTERD_BRICK_BARRIER, DRC_NA, 0},
+ [GLUSTERD_NODE_BITROT] = {"BITROT", glusterfs_handle_bitrot, NULL,
+ GLUSTERD_NODE_BITROT, DRC_NA, 0},
+ [GLUSTERD_BRICK_ATTACH] = {"ATTACH", glusterfs_handle_attach, NULL,
+ GLUSTERD_BRICK_ATTACH, DRC_NA, 0},
+
+ [GLUSTERD_DUMP_METRICS] = {"DUMP METRICS", glusterfs_handle_dump_metrics,
+ NULL, GLUSTERD_DUMP_METRICS, DRC_NA, 0},
+
+ [GLUSTERD_SVC_ATTACH] = {"ATTACH CLIENT", glusterfs_handle_svc_attach, NULL,
+ GLUSTERD_SVC_ATTACH, DRC_NA, 0},
+
+ [GLUSTERD_SVC_DETACH] = {"DETACH CLIENT", glusterfs_handle_svc_detach, NULL,
+ GLUSTERD_SVC_DETACH, DRC_NA, 0},
+
};
-struct rpcsvc_program glusterfs_mop_prog = {
- .progname = "Gluster Brick operations",
- .prognum = GD_BRICK_PROGRAM,
- .progver = GD_BRICK_VERSION,
- .actors = glusterfs_actors,
- .numactors = GLUSTERD_BRICK_MAXVALUE,
- .synctask = _gf_true,
+static struct rpcsvc_program glusterfs_mop_prog = {
+ .progname = "Gluster Brick operations",
+ .prognum = GD_BRICK_PROGRAM,
+ .progver = GD_BRICK_VERSION,
+ .actors = glusterfs_actors,
+ .numactors = GLUSTERD_BRICK_MAXVALUE,
+ .synctask = _gf_true,
};
int
-mgmt_submit_request (void *req, call_frame_t *frame,
- glusterfs_ctx_t *ctx,
- rpc_clnt_prog_t *prog, int procnum,
- fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
+mgmt_submit_request(void *req, call_frame_t *frame, glusterfs_ctx_t *ctx,
+ rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn,
+ xdrproc_t xdrproc)
{
- int ret = -1;
- int count = 0;
- struct iovec iov = {0, };
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- ssize_t xdr_size = 0;
-
- iobref = iobref_new ();
- if (!iobref) {
- goto out;
- }
-
- if (req) {
- xdr_size = xdr_sizeof (xdrproc, req);
-
- iobuf = iobuf_get2 (ctx->iobuf_pool, xdr_size);
- if (!iobuf) {
- goto out;
- };
-
- iobref_add (iobref, iobuf);
-
- iov.iov_base = iobuf->ptr;
- iov.iov_len = iobuf_pagesize (iobuf);
-
- /* Create the xdr payload */
- ret = xdr_serialize_generic (iov, req, xdrproc);
- if (ret == -1) {
- gf_log (THIS->name, GF_LOG_WARNING, "failed to create XDR payload");
- goto out;
- }
- iov.iov_len = ret;
- count = 1;
+ int ret = -1;
+ int count = 0;
+ struct iovec iov = {
+ 0,
+ };
+ struct iobuf *iobuf = NULL;
+ struct iobref *iobref = NULL;
+ ssize_t xdr_size = 0;
+
+ iobref = iobref_new();
+ if (!iobref) {
+ goto out;
+ }
+
+ if (req) {
+ xdr_size = xdr_sizeof(xdrproc, req);
+
+ iobuf = iobuf_get2(ctx->iobuf_pool, xdr_size);
+ if (!iobuf) {
+ goto out;
+ };
+
+ iobref_add(iobref, iobuf);
+
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = iobuf_pagesize(iobuf);
+
+ /* Create the xdr payload */
+ ret = xdr_serialize_generic(iov, req, xdrproc);
+ if (ret == -1) {
+ gf_log(THIS->name, GF_LOG_WARNING, "failed to create XDR payload");
+ goto out;
}
+ iov.iov_len = ret;
+ count = 1;
+ }
- /* Send the msg */
- ret = rpc_clnt_submit (ctx->mgmt, prog, procnum, cbkfn,
- &iov, count,
- NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL);
+ /* Send the msg */
+ ret = rpc_clnt_submit(ctx->mgmt, prog, procnum, cbkfn, &iov, count, NULL, 0,
+ iobref, frame, NULL, 0, NULL, 0, NULL);
out:
- if (iobref)
- iobref_unref (iobref);
+ if (iobref)
+ iobref_unref(iobref);
- if (iobuf)
- iobuf_unref (iobuf);
- return ret;
+ if (iobuf)
+ iobuf_unref(iobuf);
+ return ret;
}
-
-/* XXX: move these into @ctx */
-static char *oldvolfile = NULL;
-static int oldvollen = 0;
-
-
-
int
-mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
+mgmt_getspec_cbk(struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
{
- gf_getspec_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- glusterfs_ctx_t *ctx = NULL;
- int ret = 0;
- ssize_t size = 0;
- FILE *tmpfp = NULL;
- char *volfilebuf = NULL;
-
- frame = myframe;
- ctx = frame->this->ctx;
-
- if (-1 == req->rpc_status) {
- ret = -1;
- goto out;
- }
+ gf_getspec_rsp rsp = {
+ 0,
+ };
+ call_frame_t *frame = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = 0, locked = 0;
+ ssize_t size = 0;
+ FILE *tmpfp = NULL;
+ char *volfile_id = NULL;
+ gf_volfile_t *volfile_obj = NULL;
+ gf_volfile_t *volfile_tmp = NULL;
+ char sha256_hash[SHA256_DIGEST_LENGTH] = {
+ 0,
+ };
+ dict_t *dict = NULL;
+ char *servers_list = NULL;
+ int tmp_fd = -1;
+ char template[] = "/tmp/glfs.volfile.XXXXXX";
+
+ 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_getspec_rsp);
- if (ret < 0) {
- gf_log (frame->this->name, GF_LOG_ERROR, "XDR decoding error");
- ret = -1;
- goto out;
+ ret = xdr_to_generic(*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
+ if (ret < 0) {
+ gf_log(frame->this->name, GF_LOG_ERROR, "XDR decoding error");
+ ret = -1;
+ goto out;
+ }
+
+ if (-1 == rsp.op_ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR,
+ "failed to get the 'volume file' from server");
+ ret = rsp.op_errno;
+ goto out;
+ }
+
+ if (!rsp.xdata.xdata_len) {
+ goto volfile;
+ }
+
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ ret = dict_unserialize(rsp.xdata.xdata_val, rsp.xdata.xdata_len, &dict);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR,
+ "failed to unserialize xdata to dictionary");
+ goto out;
+ }
+ dict->extra_stdfree = rsp.xdata.xdata_val;
+
+ ret = dict_get_str(dict, "servers-list", &servers_list);
+ if (ret) {
+ /* Server list is set by glusterd at the time of getspec */
+ ret = dict_get_str(dict, GLUSTERD_BRICK_SERVERS, &servers_list);
+ if (ret)
+ goto volfile;
+ }
+
+ gf_log(frame->this->name, GF_LOG_INFO,
+ "Received list of available volfile servers: %s", servers_list);
+
+ ret = gf_process_getspec_servers_list(&ctx->cmd_args, servers_list);
+ if (ret) {
+ gf_log(frame->this->name, GF_LOG_ERROR,
+ "Failed (%s) to process servers list: %s", strerror(errno),
+ servers_list);
+ }
+
+volfile:
+ size = rsp.op_ret;
+ volfile_id = frame->local;
+ if (mgmt_is_multiplexed_daemon(ctx->cmd_args.process_name)) {
+ ret = mgmt_process_volfile((const char *)rsp.spec, size, volfile_id,
+ dict);
+ goto post_graph_mgmt;
+ }
+
+ ret = 0;
+ glusterfs_compute_sha256((const unsigned char *)rsp.spec, size,
+ sha256_hash);
+
+ LOCK(&ctx->volfile_lock);
+ {
+ locked = 1;
+
+ list_for_each_entry(volfile_obj, &ctx->volfile_list, volfile_list)
+ {
+ if (!strcmp(volfile_id, volfile_obj->vol_id)) {
+ if (!memcmp(sha256_hash, volfile_obj->volfile_checksum,
+ sizeof(volfile_obj->volfile_checksum))) {
+ UNLOCK(&ctx->volfile_lock);
+ gf_log(frame->this->name, GF_LOG_INFO,
+ "No change in volfile,"
+ "continuing");
+ goto post_unlock;
+ }
+ volfile_tmp = volfile_obj;
+ break;
+ }
}
- if (-1 == rsp.op_ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "failed to get the 'volume file' from server");
- ret = rsp.op_errno;
- goto out;
+ /* coverity[secure_temp] mkstemp uses 0600 as the mode */
+ tmp_fd = mkstemp(template);
+ if (-1 == tmp_fd) {
+ UNLOCK(&ctx->volfile_lock);
+ gf_smsg(frame->this->name, GF_LOG_ERROR, 0, glusterfsd_msg_39,
+ "create template=%s", template, NULL);
+ ret = -1;
+ goto post_unlock;
}
- ret = 0;
- size = rsp.op_ret;
-
- if (size == oldvollen && (memcmp (oldvolfile, rsp.spec, size) == 0)) {
- gf_log (frame->this->name, GF_LOG_INFO,
- "No change in volfile, continuing");
- goto out;
+ /* Calling unlink so that when the file is closed or program
+ * terminates the temporary file is deleted.
+ */
+ ret = sys_unlink(template);
+ if (ret < 0) {
+ gf_smsg(frame->this->name, GF_LOG_INFO, 0, glusterfsd_msg_39,
+ "delete template=%s", template, NULL);
+ ret = 0;
}
- tmpfp = tmpfile ();
+ tmpfp = fdopen(tmp_fd, "w+b");
if (!tmpfp) {
- ret = -1;
- goto out;
+ ret = -1;
+ goto out;
}
- fwrite (rsp.spec, size, 1, tmpfp);
- fflush (tmpfp);
- if (ferror (tmpfp)) {
- ret = -1;
- goto out;
+ fwrite(rsp.spec, size, 1, tmpfp);
+ fflush(tmpfp);
+ if (ferror(tmpfp)) {
+ ret = -1;
+ goto out;
}
/* Check if only options have changed. No need to reload the
- * volfile if topology hasn't changed.
- * glusterfs_volfile_reconfigure returns 3 possible return states
- * return 0 =======> reconfiguration of options has succeeded
- * return 1 =======> the graph has to be reconstructed and all the xlators should be inited
- * return -1(or -ve) =======> Some Internal Error occurred during the operation
- */
+ * volfile if topology hasn't changed.
+ * glusterfs_volfile_reconfigure returns 3 possible return states
+ * return 0 =======> reconfiguration of options has succeeded
+ * return 1 =======> the graph has to be reconstructed and all
+ * the xlators should be inited return -1(or -ve) =======> Some Internal
+ * Error occurred during the operation
+ */
- ret = glusterfs_volfile_reconfigure (oldvollen, tmpfp, ctx, oldvolfile);
+ ret = glusterfs_volfile_reconfigure(tmpfp, ctx);
if (ret == 0) {
- gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG,
- "No need to re-load volfile, reconfigure done");
- if (oldvolfile)
- volfilebuf = GF_REALLOC (oldvolfile, size);
- else
- volfilebuf = GF_CALLOC (1, size, gf_common_mt_char);
- if (!volfilebuf) {
- ret = -1;
- goto out;
- }
- oldvolfile = volfilebuf;
- oldvollen = size;
- memcpy (oldvolfile, rsp.spec, size);
- goto out;
+ gf_log("glusterfsd-mgmt", GF_LOG_DEBUG,
+ "No need to re-load volfile, reconfigure done");
+ if (!volfile_tmp) {
+ ret = -1;
+ UNLOCK(&ctx->volfile_lock);
+ gf_log("mgmt", GF_LOG_ERROR,
+ "Graph reconfigure succeeded with out having "
+ "checksum.");
+ goto post_unlock;
+ }
+ memcpy(volfile_tmp->volfile_checksum, sha256_hash,
+ sizeof(volfile_tmp->volfile_checksum));
+ goto out;
}
if (ret < 0) {
- gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, "Reconfigure failed !!");
- goto out;
+ UNLOCK(&ctx->volfile_lock);
+ gf_log("glusterfsd-mgmt", GF_LOG_DEBUG, "Reconfigure failed !!");
+ goto post_unlock;
}
- ret = glusterfs_process_volfp (ctx, tmpfp);
+ ret = glusterfs_process_volfp(ctx, tmpfp);
/* tmpfp closed */
tmpfp = NULL;
+ tmp_fd = -1;
if (ret)
- goto out;
-
- if (oldvolfile)
- volfilebuf = GF_REALLOC (oldvolfile, size);
- else
- volfilebuf = GF_CALLOC (1, size, gf_common_mt_char);
+ goto out;
- if (!volfilebuf) {
+ if (!volfile_tmp) {
+ volfile_tmp = GF_CALLOC(1, sizeof(gf_volfile_t),
+ gf_common_volfile_t);
+ if (!volfile_tmp) {
ret = -1;
goto out;
- }
- oldvolfile = volfilebuf;
- oldvollen = size;
- memcpy (oldvolfile, rsp.spec, size);
- if (!is_mgmt_rpc_reconnect) {
- glusterfs_mgmt_pmap_signin (ctx);
- is_mgmt_rpc_reconnect = _gf_true;
- }
-
-out:
- STACK_DESTROY (frame->root);
-
- free (rsp.spec);
+ }
- if (ctx)
- emancipate (ctx, ret);
-
- // Stop if server is running at an unsupported op-version
- if (ENOTSUP == ret) {
- gf_log ("mgmt", GF_LOG_ERROR, "Server is operating at an "
- "op-version which is not supported");
- cleanup_and_exit (0);
+ INIT_LIST_HEAD(&volfile_tmp->volfile_list);
+ volfile_tmp->graph = ctx->active;
+ list_add(&volfile_tmp->volfile_list, &ctx->volfile_list);
+ snprintf(volfile_tmp->vol_id, sizeof(volfile_tmp->vol_id), "%s",
+ volfile_id);
}
+ memcpy(volfile_tmp->volfile_checksum, sha256_hash,
+ sizeof(volfile_tmp->volfile_checksum));
+ }
+ UNLOCK(&ctx->volfile_lock);
- if (ret && ctx && !ctx->active) {
- /* Do it only for the first time */
- /* Failed to get the volume file, something wrong,
- restart the process */
- gf_log ("mgmt", GF_LOG_ERROR,
- "failed to fetch volume file (key:%s)",
- ctx->cmd_args.volfile_id);
- cleanup_and_exit (0);
- }
+ locked = 0;
+post_graph_mgmt:
+ if (!is_mgmt_rpc_reconnect) {
+ need_emancipate = 1;
+ glusterfs_mgmt_pmap_signin(ctx);
+ is_mgmt_rpc_reconnect = _gf_true;
+ }
- if (tmpfp)
- fclose (tmpfp);
+out:
- return 0;
+ if (locked)
+ UNLOCK(&ctx->volfile_lock);
+post_unlock:
+ GF_FREE(frame->local);
+ frame->local = NULL;
+ STACK_DESTROY(frame->root);
+ free(rsp.spec);
+
+ if (dict)
+ dict_unref(dict);
+
+ // Stop if server is running at an unsupported op-version
+ if (ENOTSUP == ret) {
+ gf_log("mgmt", GF_LOG_ERROR,
+ "Server is operating at an "
+ "op-version which is not supported");
+ cleanup_and_exit(0);
+ }
+
+ if (ret && ctx && !ctx->active) {
+ /* Do it only for the first time */
+ /* Failed to get the volume file, something wrong,
+ restart the process */
+ gf_log("mgmt", GF_LOG_ERROR, "failed to fetch volume file (key:%s)",
+ ctx->cmd_args.volfile_id);
+ cleanup_and_exit(0);
+ }
+
+ if (tmpfp)
+ fclose(tmpfp);
+ else if (tmp_fd != -1)
+ sys_close(tmp_fd);
+
+ return 0;
}
-
-int
-glusterfs_volfile_fetch (glusterfs_ctx_t *ctx)
+static int
+glusterfs_volfile_fetch_one(glusterfs_ctx_t *ctx, char *volfile_id)
{
- cmd_args_t *cmd_args = NULL;
- gf_getspec_req req = {0, };
- int ret = 0;
- call_frame_t *frame = NULL;
- dict_t *dict = NULL;
-
- cmd_args = &ctx->cmd_args;
-
- frame = create_frame (THIS, ctx->pool);
-
- req.key = cmd_args->volfile_id;
- req.flags = 0;
-
- dict = dict_new ();
- if (!dict) {
- ret = -1;
- goto out;
- }
+ cmd_args_t *cmd_args = NULL;
+ gf_getspec_req req = {
+ 0,
+ };
+ int ret = 0;
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+
+ cmd_args = &ctx->cmd_args;
+ if (!volfile_id) {
+ volfile_id = ctx->cmd_args.volfile_id;
+ if (!volfile_id) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "No volfile-id provided, erroring out");
+ return -1;
+ }
+ }
+
+ frame = create_frame(THIS, ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ req.key = volfile_id;
+ req.flags = 0;
+ /*
+ * We are only storing one variable in local, hence using the same
+ * variable. If multiple local variable is required, create a struct.
+ */
+ frame->local = gf_strdup(volfile_id);
+ if (!frame->local) {
+ ret = -1;
+ goto out;
+ }
- // Set the supported min and max op-versions, so glusterd can make a
- // decision
- ret = dict_set_int32 (dict, "min-op-version", GD_OP_VERSION_MIN);
+ dict = dict_new();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ // Set the supported min and max op-versions, so glusterd can make a
+ // decision
+ ret = dict_set_int32(dict, "min-op-version", GD_OP_VERSION_MIN);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "Failed to set min-op-version"
+ " in request dict");
+ goto out;
+ }
+
+ ret = dict_set_int32(dict, "max-op-version", GD_OP_VERSION_MAX);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "Failed to set max-op-version"
+ " in request dict");
+ goto out;
+ }
+
+ /* Ask for a list of volfile (glusterd2 only) servers */
+ if (GF_CLIENT_PROCESS == ctx->process_mode) {
+ req.flags = req.flags | GF_GETSPEC_FLAG_SERVERS_LIST;
+ }
+
+ if (cmd_args->brick_name) {
+ ret = dict_set_dynstr_with_alloc(dict, "brick_name",
+ cmd_args->brick_name);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to set min-op-version"
- " in request dict");
- goto out;
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "Failed to set brick_name in request dict");
+ goto out;
}
+ }
- ret = dict_set_int32 (dict, "max-op-version", GD_OP_VERSION_MAX);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to set max-op-version"
- " in request dict");
- goto out;
- }
+ ret = dict_allocate_and_serialize(dict, &req.xdata.xdata_val,
+ &req.xdata.xdata_len);
+ if (ret < 0) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Failed to serialize dictionary");
+ goto out;
+ }
- if (cmd_args->brick_name) {
- ret = dict_set_dynstr_with_alloc (dict, "brick_name",
- cmd_args->brick_name);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to set brick_name in request dict");
- goto out;
- }
- }
+ ret = mgmt_submit_request(&req, frame, ctx, &clnt_handshake_prog,
+ GF_HNDSK_GETSPEC, mgmt_getspec_cbk,
+ (xdrproc_t)xdr_gf_getspec_req);
- ret = dict_allocate_and_serialize (dict, &req.xdata.xdata_val,
- &req.xdata.xdata_len);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to serialize dictionary");
- goto out;
- }
+out:
+ GF_FREE(req.xdata.xdata_val);
+ if (dict)
+ dict_unref(dict);
+ if (ret && frame) {
+ /* Free the frame->local fast, because we have not used memget
+ */
+ GF_FREE(frame->local);
+ frame->local = NULL;
+ STACK_DESTROY(frame->root);
+ }
- ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog,
- GF_HNDSK_GETSPEC, mgmt_getspec_cbk,
- (xdrproc_t)xdr_gf_getspec_req);
+ return ret;
+}
-out:
- GF_FREE (req.xdata.xdata_val);
- if (dict)
- dict_unref (dict);
+int
+glusterfs_volfile_fetch(glusterfs_ctx_t *ctx)
+{
+ xlator_t *server_xl = NULL;
+ xlator_list_t *trav;
+ gf_volfile_t *volfile_obj = NULL;
+ int ret = 0;
+
+ LOCK(&ctx->volfile_lock);
+ {
+ if (ctx->active &&
+ mgmt_is_multiplexed_daemon(ctx->cmd_args.process_name)) {
+ list_for_each_entry(volfile_obj, &ctx->volfile_list, volfile_list)
+ {
+ ret |= glusterfs_volfile_fetch_one(ctx, volfile_obj->vol_id);
+ }
+ UNLOCK(&ctx->volfile_lock);
+ return ret;
+ }
+
+ if (ctx->active) {
+ server_xl = ctx->active->first;
+ if (strcmp(server_xl->type, "protocol/server") != 0) {
+ server_xl = NULL;
+ }
+ }
+ if (!server_xl) {
+ /* Startup (ctx->active not set) or non-server. */
+ UNLOCK(&ctx->volfile_lock);
+ return glusterfs_volfile_fetch_one(ctx, ctx->cmd_args.volfile_id);
+ }
- return ret;
+ ret = 0;
+ for (trav = server_xl->children; trav; trav = trav->next) {
+ ret |= glusterfs_volfile_fetch_one(ctx, trav->xlator->volfile_id);
+ }
+ }
+ UNLOCK(&ctx->volfile_lock);
+ return ret;
}
int32_t
-mgmt_event_notify_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
+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;
+ gf_event_notify_rsp rsp = {
+ 0,
+ };
+ call_frame_t *frame = NULL;
+ int ret = 0;
- frame = myframe;
- ctx = frame->this->ctx;
+ frame = myframe;
- if (-1 == req->rpc_status) {
- ret = -1;
- goto out;
- }
+ 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;
- }
+ 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;
- }
+ 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:
- free (rsp.dict.dict_val); //malloced by xdr
- return ret;
-
+ 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)
+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;
+ gf_event_notify_rsp rsp = {
+ 0,
+ };
+ call_frame_t *frame = NULL;
+ int ret = 0;
- frame = myframe;
- ctx = frame->this->ctx;
+ frame = myframe;
- if (-1 == req->rpc_status) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "failed to get the rsp from server");
- ret = -1;
- goto out;
- }
+ 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;
- }
+ 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;
- }
+ 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:
- free (rsp.dict.dict_val); //malloced by xdr
- return ret;
+ free(rsp.dict.dict_val); // malloced by xdr
+ if (frame) {
+ STACK_DESTROY(frame->root);
+ }
+
+ return ret;
}
int32_t
-glusterfs_rebalance_event_notify (dict_t *dict)
+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 = glusterfsd_ctx;
- cmd_args = &ctx->cmd_args;
+ 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;
- frame = create_frame (THIS, ctx->pool);
+ ctx = glusterfsd_ctx;
+ cmd_args = &ctx->cmd_args;
- req.op = GF_EN_DEFRAG_STATUS;
+ frame = create_frame(THIS, ctx->pool);
- if (dict) {
- ret = dict_set_str (dict, "volname", cmd_args->volfile_id);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "failed to set volname");
+ req.op = GF_EN_DEFRAG_STATUS;
- ret = dict_allocate_and_serialize (dict, &req.dict.dict_val,
- &req.dict.dict_len);
+ 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);
+ if (ret) {
+ gf_log("", GF_LOG_ERROR, "failed to serialize dict");
+ }
+ }
- 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);
-
- GF_FREE (req.dict.dict_val);
+ 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 (frame) {
- STACK_DESTROY (frame->root);
- }
- return ret;
+ GF_FREE(req.dict.dict_val);
+ return ret;
}
static int
-mgmt_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
- void *data)
+mgmt_rpc_notify(struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
+ void *data)
{
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
- int ret = 0;
- server_cmdline_t *server = NULL;
- rpc_transport_t *rpc_trans = NULL;
- int need_term = 0;
- int emval = 0;
-
- this = mydata;
- rpc_trans = rpc->conn.trans;
- ctx = this->ctx;
-
- switch (event) {
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = 0;
+ server_cmdline_t *server = NULL;
+ rpc_transport_t *rpc_trans = NULL;
+ int need_term = 0;
+ int emval = 0;
+ static int log_ctr1;
+ static int log_ctr2;
+ struct dnscache6 *dnscache = NULL;
+
+ this = mydata;
+ rpc_trans = rpc->conn.trans;
+ ctx = this->ctx;
+
+ switch (event) {
case RPC_CLNT_DISCONNECT:
+ if (rpc_trans->connect_failed) {
+ GF_LOG_OCCASIONALLY(log_ctr1, "glusterfsd-mgmt", GF_LOG_ERROR,
+ "failed to connect to remote-"
+ "host: %s",
+ ctx->cmd_args.volfile_server);
+ } else {
+ GF_LOG_OCCASIONALLY(log_ctr1, "glusterfsd-mgmt", GF_LOG_INFO,
+ "disconnected from remote-"
+ "host: %s",
+ ctx->cmd_args.volfile_server);
+ }
+
+ if (!rpc->disabled) {
+ /*
+ * Check if dnscache is exhausted for current server
+ * and continue until cache is exhausted
+ */
+ dnscache = rpc_trans->dnscache;
+ if (dnscache && dnscache->next) {
+ break;
+ }
+ }
+ server = ctx->cmd_args.curr_server;
+ if (server->list.next == &ctx->cmd_args.volfile_servers) {
+ if (!ctx->active) {
+ need_term = 1;
+ }
+ emval = ENOTCONN;
+ GF_LOG_OCCASIONALLY(log_ctr2, "glusterfsd-mgmt", GF_LOG_INFO,
+ "Exhausted all volfile servers");
+ break;
+ }
+ server = list_entry(server->list.next, typeof(*server), list);
+ ctx->cmd_args.curr_server = server;
+ ctx->cmd_args.volfile_server = server->volfile_server;
+
+ ret = dict_set_str(rpc_trans->options, "remote-host",
+ server->volfile_server);
+ if (ret != 0) {
+ gf_log("glusterfsd-mgmt", GF_LOG_ERROR,
+ "failed to set remote-host: %s", server->volfile_server);
if (!ctx->active) {
- gf_log ("glusterfsd-mgmt", GF_LOG_ERROR,
- "failed to connect with remote-host: %s (%s)",
- ctx->cmd_args.volfile_server,
- strerror (errno));
- server = ctx->cmd_args.curr_server;
- if (server->list.next == &ctx->cmd_args.volfile_servers) {
- need_term = 1;
- emval = ENOTCONN;
- gf_log("glusterfsd-mgmt", GF_LOG_INFO,
- "Exhausted all volfile servers");
- break;
- }
- server = list_entry (server->list.next, typeof(*server),
- list);
- ctx->cmd_args.curr_server = server;
- ctx->cmd_args.volfile_server = server->volfile_server;
-
- ret = dict_set_str (rpc_trans->options,
- "remote-host",
- server->volfile_server);
- if (ret != 0) {
- gf_log ("glusterfsd-mgmt", GF_LOG_ERROR,
- "failed to set remote-host: %s",
- server->volfile_server);
- need_term = 1;
- emval = ENOTCONN;
- break;
- }
- gf_log ("glusterfsd-mgmt", GF_LOG_INFO,
- "connecting to next volfile server %s",
- server->volfile_server);
+ need_term = 1;
}
+ emval = ENOTCONN;
break;
+ }
+ gf_log("glusterfsd-mgmt", GF_LOG_INFO,
+ "connecting to next volfile server %s",
+ server->volfile_server);
+ break;
case RPC_CLNT_CONNECT:
- rpc_clnt_set_connected (&((struct rpc_clnt*)ctx->mgmt)->conn);
-
- ret = glusterfs_volfile_fetch (ctx);
- if (ret) {
- emval = ret;
- if (!ctx->active) {
- need_term = 1;
- gf_log ("glusterfsd-mgmt", GF_LOG_ERROR,
- "failed to fetch volume file (key:%s)",
- ctx->cmd_args.volfile_id);
- break;
-
- }
+ ret = glusterfs_volfile_fetch(ctx);
+ if (ret) {
+ emval = ret;
+ if (!ctx->active) {
+ need_term = 1;
+ gf_log("glusterfsd-mgmt", GF_LOG_ERROR,
+ "failed to fetch volume file (key:%s)",
+ ctx->cmd_args.volfile_id);
+ break;
}
+ }
- if (is_mgmt_rpc_reconnect)
- glusterfs_mgmt_pmap_signin (ctx);
+ if (is_mgmt_rpc_reconnect)
+ glusterfs_mgmt_pmap_signin(ctx);
- break;
+ break;
default:
- break;
- }
+ break;
+ }
- if (need_term) {
- emancipate (ctx, emval);
- cleanup_and_exit (1);
- }
+ if (need_term) {
+ emancipate(ctx, emval);
+ cleanup_and_exit(1);
+ }
- return 0;
+ return 0;
}
int
-glusterfs_rpcsvc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
- void *data)
+glusterfs_rpcsvc_notify(rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
+ void *data)
{
- if (!xl || !data) {
- goto out;
- }
+ if (!xl || !data) {
+ goto out;
+ }
- switch (event) {
- case RPCSVC_EVENT_ACCEPT:
- {
- break;
+ switch (event) {
+ case RPCSVC_EVENT_ACCEPT: {
+ break;
}
- case RPCSVC_EVENT_DISCONNECT:
- {
- break;
+ case RPCSVC_EVENT_DISCONNECT: {
+ break;
}
default:
- break;
- }
+ break;
+ }
out:
- return 0;
+ return 0;
}
int
-glusterfs_listener_init (glusterfs_ctx_t *ctx)
+glusterfs_listener_init(glusterfs_ctx_t *ctx)
{
- cmd_args_t *cmd_args = NULL;
- rpcsvc_t *rpc = NULL;
- dict_t *options = NULL;
- int ret = -1;
-
- cmd_args = &ctx->cmd_args;
-
- if (ctx->listener)
- return 0;
-
- if (!cmd_args->sock_file)
- return 0;
-
- ret = rpcsvc_transport_unix_options_build (&options,
- cmd_args->sock_file);
- if (ret)
- goto out;
+ cmd_args_t *cmd_args = NULL;
+ rpcsvc_t *rpc = NULL;
+ dict_t *options = NULL;
+ int ret = -1;
- rpc = rpcsvc_init (THIS, ctx, options, 8);
- if (rpc == NULL) {
- goto out;
- }
-
- ret = rpcsvc_register_notify (rpc, glusterfs_rpcsvc_notify, THIS);
- if (ret) {
- goto out;
- }
+ cmd_args = &ctx->cmd_args;
- ret = rpcsvc_create_listeners (rpc, options, "glusterfsd");
- if (ret < 1) {
- ret = -1;
- goto out;
- }
-
- ret = rpcsvc_program_register (rpc, &glusterfs_mop_prog);
- if (ret) {
- goto out;
- }
-
- ctx->listener = rpc;
-
-out:
- return ret;
-}
+ if (ctx->listener)
+ return 0;
-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;
+ if (!cmd_args->sock_file)
+ return 0;
- GF_ASSERT (ctx);
+ options = dict_new();
+ if (!options)
+ goto out;
- rpc = ctx->listener;
- ctx->listener = NULL;
+ ret = rpcsvc_transport_unix_options_build(options, cmd_args->sock_file);
+ if (ret)
+ goto out;
- (void) rpcsvc_program_unregister(rpc, &glusterfs_mop_prog);
+ rpc = rpcsvc_init(THIS, ctx, options, 8);
+ if (rpc == NULL) {
+ goto out;
+ }
- list_for_each_entry_safe (listener, next, &rpc->listeners, list) {
- rpcsvc_listener_destroy (listener);
- }
+ ret = rpcsvc_register_notify(rpc, glusterfs_rpcsvc_notify, THIS);
+ if (ret) {
+ goto out;
+ }
- (void) rpcsvc_unregister_notify (rpc, glusterfs_rpcsvc_notify, THIS);
+ ret = rpcsvc_create_listeners(rpc, options, "glusterfsd");
+ if (ret < 1) {
+ goto out;
+ }
- GF_FREE (rpc);
+ ret = rpcsvc_program_register(rpc, &glusterfs_mop_prog, _gf_false);
+ if (ret) {
+ goto out;
+ }
- cmd_args = &ctx->cmd_args;
- if (cmd_args->sock_file) {
- ret = unlink (cmd_args->sock_file);
- if (ret && (ENOENT == errno)) {
- ret = 0;
- }
- }
+ ctx->listener = rpc;
- if (ret) {
- this = THIS;
- gf_log (this->name, GF_LOG_ERROR, "Failed to unlink listener "
- "socket %s, error: %s", cmd_args->sock_file,
- strerror (errno));
- }
- return ret;
+out:
+ if (options)
+ dict_unref(options);
+ return ret;
}
int
-glusterfs_mgmt_notify (int32_t op, void *data, ...)
+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;
+ 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;
- }
+ default:
+ gf_log("", GF_LOG_ERROR, "Invalid op");
+ break;
+ }
- return ret;
+ return ret;
}
int
-glusterfs_mgmt_init (glusterfs_ctx_t *ctx)
+glusterfs_mgmt_init(glusterfs_ctx_t *ctx)
{
- cmd_args_t *cmd_args = NULL;
- struct rpc_clnt *rpc = NULL;
- dict_t *options = NULL;
- int ret = -1;
- int port = GF_DEFAULT_BASE_PORT;
- char *host = NULL;
-
- cmd_args = &ctx->cmd_args;
-
- if (ctx->mgmt)
- return 0;
+ cmd_args_t *cmd_args = NULL;
+ struct rpc_clnt *rpc = NULL;
+ dict_t *options = NULL;
+ int ret = -1;
+ int port = GF_DEFAULT_BASE_PORT;
+ char *host = NULL;
+ xlator_cmdline_option_t *opt = NULL;
+
+ cmd_args = &ctx->cmd_args;
+ GF_VALIDATE_OR_GOTO(THIS->name, cmd_args->volfile_server, out);
+
+ if (ctx->mgmt)
+ return 0;
- if (cmd_args->volfile_server_port)
- port = cmd_args->volfile_server_port;
+ options = dict_new();
+ if (!options)
+ goto out;
- host = "localhost";
- if (cmd_args->volfile_server)
- host = cmd_args->volfile_server;
+ LOCK_INIT(&ctx->volfile_lock);
- ret = rpc_transport_inet_options_build (&options, host, port);
- if (ret)
- goto out;
+ if (cmd_args->volfile_server_port)
+ port = cmd_args->volfile_server_port;
- rpc = rpc_clnt_new (options, THIS, THIS->name, 8);
- if (!rpc) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_WARNING, "failed to create rpc clnt");
- goto out;
- }
+ host = cmd_args->volfile_server;
- ret = rpc_clnt_register_notify (rpc, mgmt_rpc_notify, THIS);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to register notify function");
- goto out;
- }
+ if (cmd_args->volfile_server_transport &&
+ !strcmp(cmd_args->volfile_server_transport, "unix")) {
+ ret = rpc_transport_unix_options_build(options, host, 0);
+ } else {
+ opt = find_xlator_option_in_cmd_args_t("address-family", cmd_args);
+ ret = rpc_transport_inet_options_build(options, host, port,
+ (opt ? opt->value : NULL));
+ }
+ if (ret)
+ goto out;
- ret = rpcclnt_cbk_program_register (rpc, &mgmt_cbk_prog, THIS);
+ /* Explicitly turn on encrypted transport. */
+ if (ctx->secure_mgmt) {
+ ret = dict_set_dynstr_with_alloc(options,
+ "transport.socket.ssl-enabled", "yes");
if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to register callback function");
- goto out;
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "failed to set 'transport.socket.ssl-enabled' "
+ "in options dict");
+ 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;
+ ctx->ssl_cert_depth = glusterfs_read_secure_access_file();
+ }
- ret = rpc_clnt_start (rpc);
+ rpc = rpc_clnt_new(options, THIS, THIS->name, 8);
+ if (!rpc) {
+ ret = -1;
+ gf_log(THIS->name, GF_LOG_WARNING, "failed to create rpc clnt");
+ goto out;
+ }
+
+ ret = rpc_clnt_register_notify(rpc, mgmt_rpc_notify, THIS);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_WARNING,
+ "failed to register notify function");
+ goto out;
+ }
+
+ ret = rpcclnt_cbk_program_register(rpc, &mgmt_cbk_prog, THIS);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_WARNING,
+ "failed to register callback function");
+ goto out;
+ }
+
+ ctx->notify = glusterfs_mgmt_notify;
+
+ /* This value should be set before doing the 'rpc_clnt_start()' as
+ the notify function uses this variable */
+ ctx->mgmt = rpc;
+
+ ret = rpc_clnt_start(rpc);
out:
- return ret;
+ if (options)
+ dict_unref(options);
+ return ret;
}
static int
-mgmt_pmap_signin2_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
+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;
+ pmap_signin_rsp rsp = {
+ 0,
+ };
+ glusterfs_ctx_t *ctx = NULL;
+ call_frame_t *frame = NULL;
+ int ret = 0;
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
+ ctx = glusterfsd_ctx;
+ frame = myframe;
- 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 == req->rpc_status) {
+ ret = -1;
+ 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");
+ ret = -1;
+ goto out;
+ }
- if (-1 == rsp.op_ret) {
- gf_log (frame->this->name, GF_LOG_ERROR,
- "failed to register the port with glusterd");
- goto out;
- }
+ ret = 0;
out:
- STACK_DESTROY (frame->root);
- return 0;
+ if (need_emancipate)
+ emancipate(ctx, ret);
+ STACK_DESTROY(frame->root);
+ return 0;
}
static int
-mgmt_pmap_signin_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
+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;
-
- 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;
- }
-
- ctx = glusterfsd_ctx;
- cmd_args = &ctx->cmd_args;
+ pmap_signin_rsp rsp = {
+ 0,
+ };
+ call_frame_t *frame = NULL;
+ int ret = 0;
+ int emancipate_ret = -1;
+ 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;
+ ctx = glusterfsd_ctx;
+ cmd_args = &ctx->cmd_args;
+
+ if (-1 == req->rpc_status) {
+ ret = -1;
+ 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");
+ ret = -1;
+ goto out;
+ }
- if (!cmd_args->brick_port2) {
- /* We are done with signin process */
- goto out;
- }
+ if (!cmd_args->brick_port2) {
+ /* We are done with signin process */
+ emancipate_ret = 0;
+ 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;
+ 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;
+ 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;
+ return 0;
out:
+ if (need_emancipate && (ret < 0 || !cmd_args->brick_port2))
+ emancipate(ctx, emancipate_ret);
- STACK_DESTROY (frame->root);
- return 0;
+ STACK_DESTROY(frame->root);
+ return 0;
}
int
-glusterfs_mgmt_pmap_signin (glusterfs_ctx_t *ctx)
-{
- call_frame_t *frame = NULL;
- pmap_signin_req req = {0, };
- int ret = -1;
- cmd_args_t *cmd_args = NULL;
- char brick_name[PATH_MAX] = {0,};
-
- frame = create_frame (THIS, ctx->pool);
- cmd_args = &ctx->cmd_args;
-
- if (!cmd_args->brick_port || !cmd_args->brick_name) {
- gf_log ("fsd-mgmt", GF_LOG_DEBUG,
- "portmapper signin arguments not given");
- goto out;
- }
-
- if (cmd_args->volfile_server_transport &&
- !strcmp(cmd_args->volfile_server_transport, "rdma")) {
- snprintf (brick_name, sizeof(brick_name), "%s.rdma",
- cmd_args->brick_name);
- req.brick = brick_name;
- } else
- req.brick = cmd_args->brick_name;
-
- req.port = cmd_args->brick_port;
-
- ret = mgmt_submit_request (&req, frame, ctx, &clnt_pmap_prog,
- GF_PMAP_SIGNIN, mgmt_pmap_signin_cbk,
- (xdrproc_t)xdr_pmap_signin_req);
-
-out:
- return ret;
-}
-
-
-static int
-mgmt_pmap_signout_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
+glusterfs_mgmt_pmap_signin(glusterfs_ctx_t *ctx)
{
- pmap_signout_rsp rsp = {0,};
- int ret = 0;
- glusterfs_ctx_t *ctx = NULL;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- ctx = glusterfsd_ctx;
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_signout_rsp);
- if (ret < 0) {
- 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 (THIS->name, GF_LOG_ERROR,
- "failed to register the port with glusterd");
- goto out;
- }
-out:
- return 0;
-}
-
-
-int
-glusterfs_mgmt_pmap_signout (glusterfs_ctx_t *ctx)
-{
- int ret = 0;
- pmap_signout_req req = {0, };
- call_frame_t *frame = NULL;
- cmd_args_t *cmd_args = NULL;
- char brick_name[PATH_MAX] = {0,};
-
- frame = create_frame (THIS, ctx->pool);
- cmd_args = &ctx->cmd_args;
-
- if (!cmd_args->brick_port || !cmd_args->brick_name) {
- gf_log ("fsd-mgmt", GF_LOG_DEBUG,
- "portmapper signout arguments not given");
- goto out;
- }
+ call_frame_t *frame = NULL;
+ xlator_list_t **trav_p;
+ xlator_t *top;
+ pmap_signin_req req = {
+ 0,
+ };
+ int ret = -1;
+ int emancipate_ret = -1;
+ cmd_args_t *cmd_args = NULL;
+
+ cmd_args = &ctx->cmd_args;
+
+ if (!cmd_args->brick_port || !cmd_args->brick_name) {
+ gf_log("fsd-mgmt", GF_LOG_DEBUG,
+ "portmapper signin arguments not given");
+ emancipate_ret = 0;
+ goto out;
+ }
+
+ req.port = cmd_args->brick_port;
+ req.pid = (int)getpid(); /* only glusterd2 consumes this */
+
+ if (ctx->active) {
+ top = ctx->active->first;
+ for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) {
+ frame = create_frame(THIS, ctx->pool);
+ req.brick = (*trav_p)->xlator->name;
+ ret = mgmt_submit_request(&req, frame, ctx, &clnt_pmap_prog,
+ GF_PMAP_SIGNIN, mgmt_pmap_signin_cbk,
+ (xdrproc_t)xdr_pmap_signin_req);
+ if (ret < 0) {
+ gf_log(THIS->name, GF_LOG_WARNING,
+ "failed to send sign in request; brick = %s", req.brick);
+ }
+ }
+ }
+
+ /* unfortunately, the caller doesn't care about the returned value */
- if (cmd_args->volfile_server_transport &&
- !strcmp(cmd_args->volfile_server_transport, "rdma")) {
- snprintf (brick_name, sizeof(brick_name), "%s.rdma",
- cmd_args->brick_name);
- req.brick = brick_name;
- } else
- req.brick = cmd_args->brick_name;
-
- req.port = cmd_args->brick_port;
- req.rdma_port = cmd_args->brick_port2;
- ret = mgmt_submit_request (&req, frame, ctx, &clnt_pmap_prog,
- GF_PMAP_SIGNOUT, mgmt_pmap_signout_cbk,
- (xdrproc_t)xdr_pmap_signout_req);
out:
- return ret;
+ if (need_emancipate && ret < 0)
+ emancipate(ctx, emancipate_ret);
+ return ret;
}
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c
index 6ebcd6ce8c4..dae41f33fef 100644
--- a/glusterfsd/src/glusterfsd.c
+++ b/glusterfsd/src/glusterfsd.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006-2013 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2016 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
@@ -32,1215 +32,1430 @@
#include <errno.h>
#include <pwd.h>
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
+#ifdef GF_LINUX_HOST_OS
+#ifdef HAVE_LINUX_OOM_H
+#include <linux/oom.h>
+#else
+#define OOM_SCORE_ADJ_MIN (-1000)
+#define OOM_SCORE_ADJ_MAX 1000
+#define OOM_DISABLE (-17)
+#define OOM_ADJUST_MAX 15
#endif
-
-#ifdef HAVE_MALLOC_STATS
-#ifdef DEBUG
-#include <mcheck.h>
#endif
+
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
#endif
-#include "xlator.h"
-#include "glusterfs.h"
-#include "compat.h"
-#include "logging.h"
+#include <glusterfs/xlator.h>
+#include <glusterfs/glusterfs.h>
+#include <glusterfs/compat.h>
+#include <glusterfs/logging.h>
#include "glusterfsd-messages.h"
-#include "dict.h"
-#include "list.h"
-#include "timer.h"
+#include <glusterfs/dict.h>
+#include <glusterfs/list.h>
+#include <glusterfs/timer.h>
#include "glusterfsd.h"
-#include "stack.h"
-#include "revision.h"
-#include "common-utils.h"
-#include "event.h"
-#include "globals.h"
-#include "statedump.h"
-#include "latency.h"
+#include <glusterfs/revision.h>
+#include <glusterfs/common-utils.h>
+#include <glusterfs/gf-event.h>
+#include <glusterfs/statedump.h>
+#include <glusterfs/latency.h>
#include "glusterfsd-mem-types.h"
-#include "syscall.h"
-#include "call-stub.h"
+#include <glusterfs/syscall.h>
+#include <glusterfs/call-stub.h>
#include <fnmatch.h>
#include "rpc-clnt.h"
-#include "syncop.h"
-#include "client_t.h"
+#include <glusterfs/syncop.h>
+#include <glusterfs/client_t.h>
#include "netgroups.h"
#include "exports.h"
+#include <glusterfs/monitoring.h>
-#include "daemon.h"
-#include "tw.h"
-
-/* process mode definitions */
-#define GF_SERVER_PROCESS 0
-#define GF_CLIENT_PROCESS 1
-#define GF_GLUSTERD_PROCESS 2
+#include <glusterfs/daemon.h>
/* using argp for command line parsing */
static char gf_doc[] = "";
-static char argp_doc[] = "--volfile-server=SERVER [MOUNT-POINT]\n" \
- "--volfile=VOLFILE [MOUNT-POINT]";
-const char *argp_program_version = ""
- PACKAGE_NAME" "PACKAGE_VERSION" built on "__DATE__" "__TIME__
- "\nRepository revision: " GLUSTERFS_REPOSITORY_REVISION "\n"
- "Copyright (c) 2006-2013 Red Hat, Inc. <http://www.redhat.com/>\n"
- "GlusterFS comes with ABSOLUTELY NO WARRANTY.\n"
- "It is licensed to you under your choice of the GNU Lesser\n"
- "General Public License, version 3 or any later version (LGPLv3\n"
- "or later), or the GNU General Public License, version 2 (GPLv2),\n"
- "in all cases as published by the Free Software Foundation.";
+static char argp_doc[] =
+ "--volfile-server=SERVER [MOUNT-POINT]\n"
+ "--volfile=VOLFILE [MOUNT-POINT]";
+const char *argp_program_version =
+ "" PACKAGE_NAME " " PACKAGE_VERSION
+ "\nRepository revision: " GLUSTERFS_REPOSITORY_REVISION
+ "\n"
+ "Copyright (c) 2006-2016 Red Hat, Inc. "
+ "<https://www.gluster.org/>\n"
+ "GlusterFS comes with ABSOLUTELY NO WARRANTY.\n"
+ "It is licensed to you under your choice of the GNU Lesser\n"
+ "General Public License, version 3 or any later version (LGPLv3\n"
+ "or later), or the GNU General Public License, version 2 (GPLv2),\n"
+ "in all cases as published by the Free Software Foundation.";
const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
-static error_t parse_opts (int32_t key, char *arg, struct argp_state *_state);
+static error_t
+parse_opts(int32_t key, char *arg, struct argp_state *_state);
static struct argp_option gf_options[] = {
- {0, 0, 0, 0, "Basic options:"},
- {"volfile-server", ARGP_VOLFILE_SERVER_KEY, "SERVER", 0,
- "Server to get the volume file from. This option overrides "
- "--volfile option"},
- {"volfile", ARGP_VOLUME_FILE_KEY, "VOLFILE", 0,
- "File to use as VOLUME_FILE"},
- {"spec-file", ARGP_VOLUME_FILE_KEY, "VOLFILE", OPTION_HIDDEN,
- "File to use as VOLUME FILE"},
-
- {"log-level", ARGP_LOG_LEVEL_KEY, "LOGLEVEL", 0,
- "Logging severity. Valid options are DEBUG, INFO, WARNING, ERROR, "
- "CRITICAL, TRACE and NONE [default: INFO]"},
- {"log-file", ARGP_LOG_FILE_KEY, "LOGFILE", 0,
- "File to use for logging [default: "
- DEFAULT_LOG_FILE_DIRECTORY "/" PACKAGE_NAME ".log" "]"},
- {"logger", ARGP_LOGGER, "LOGGER", 0, "Set which logging sub-system to "
- "log to, valid options are: gluster-log and syslog, "
- "[default: \"gluster-log\"]"},
- {"log-format", ARGP_LOG_FORMAT, "LOG-FORMAT", 0, "Set log format, valid"
- " options are: no-msg-id and with-msg-id, [default: \"with-msg-id\"]"},
- {"log-buf-size", ARGP_LOG_BUF_SIZE, "LOG-BUF-SIZE", 0, "Set logging "
- "buffer size, [default: 5]"},
- {"log-flush-timeout", ARGP_LOG_FLUSH_TIMEOUT, "LOG-FLUSH-TIMEOUT", 0,
- "Set log flush timeout, [default: 2 minutes]"},
-
- {0, 0, 0, 0, "Advanced Options:"},
- {"volfile-server-port", ARGP_VOLFILE_SERVER_PORT_KEY, "PORT", 0,
- "Listening port number of volfile server"},
- {"volfile-server-transport", ARGP_VOLFILE_SERVER_TRANSPORT_KEY,
- "TRANSPORT", 0,
- "Transport type to get volfile from server [default: socket]"},
- {"volfile-id", ARGP_VOLFILE_ID_KEY, "KEY", 0,
- "'key' of the volfile to be fetched from server"},
- {"pid-file", ARGP_PID_FILE_KEY, "PIDFILE", 0,
- "File to use as pid file"},
- {"socket-file", ARGP_SOCK_FILE_KEY, "SOCKFILE", 0,
- "File to use as unix-socket"},
- {"no-daemon", ARGP_NO_DAEMON_KEY, 0, 0,
- "Run in foreground"},
- {"run-id", ARGP_RUN_ID_KEY, "RUN-ID", OPTION_HIDDEN,
- "Run ID for the process, used by scripts to keep track of process "
- "they started, defaults to none"},
- {"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, "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"},
-
- {"print-netgroups", ARGP_PRINT_NETGROUPS, "NETGROUP-FILE", 0,
- "Validate the netgroups file and print it out"},
- {"print-exports", ARGP_PRINT_EXPORTS, "EXPORTS-FILE", 0,
- "Validate the exports file and print it out"},
-
- {"volfile-max-fetch-attempts", ARGP_VOLFILE_MAX_FETCH_ATTEMPTS, "0",
- OPTION_HIDDEN, "Maximum number of attempts to fetch the volfile"},
- {"aux-gfid-mount", ARGP_AUX_GFID_MOUNT_KEY, 0, 0,
- "Enable access to filesystem through gfid directly"},
- {"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 "
+ {0, 0, 0, 0, "Basic options:"},
+ {"volfile-server", ARGP_VOLFILE_SERVER_KEY, "SERVER", 0,
+ "Server to get the volume file from. Unix domain socket path when "
+ "transport type 'unix'. This option overrides --volfile option"},
+ {"volfile", ARGP_VOLUME_FILE_KEY, "VOLFILE", 0,
+ "File to use as VOLUME_FILE"},
+ {"spec-file", ARGP_VOLUME_FILE_KEY, "VOLFILE", OPTION_HIDDEN,
+ "File to use as VOLUME FILE"},
+
+ {"log-level", ARGP_LOG_LEVEL_KEY, "LOGLEVEL", 0,
+ "Logging severity. Valid options are DEBUG, INFO, WARNING, ERROR, "
+ "CRITICAL, TRACE and NONE [default: INFO]"},
+ {"log-file", ARGP_LOG_FILE_KEY, "LOGFILE", 0,
+ "File to use for logging [default: " DEFAULT_LOG_FILE_DIRECTORY
+ "/" PACKAGE_NAME ".log"
+ "]"},
+ {"logger", ARGP_LOGGER, "LOGGER", 0,
+ "Set which logging sub-system to "
+ "log to, valid options are: gluster-log and syslog, "
+ "[default: \"gluster-log\"]"},
+ {"log-format", ARGP_LOG_FORMAT, "LOG-FORMAT", 0,
+ "Set log format, valid"
+ " options are: no-msg-id and with-msg-id, [default: \"with-msg-id\"]"},
+ {"log-buf-size", ARGP_LOG_BUF_SIZE, "LOG-BUF-SIZE", 0,
+ "Set logging "
+ "buffer size, [default: 5]"},
+ {"log-flush-timeout", ARGP_LOG_FLUSH_TIMEOUT, "LOG-FLUSH-TIMEOUT", 0,
+ "Set log flush timeout, [default: 2 minutes]"},
+
+ {0, 0, 0, 0, "Advanced Options:"},
+ {"volfile-server-port", ARGP_VOLFILE_SERVER_PORT_KEY, "PORT", 0,
+ "Listening port number of volfile server"},
+ {"volfile-server-transport", ARGP_VOLFILE_SERVER_TRANSPORT_KEY, "TRANSPORT",
+ 0, "Transport type to get volfile from server [default: socket]"},
+ {"volfile-id", ARGP_VOLFILE_ID_KEY, "KEY", 0,
+ "'key' of the volfile to be fetched from server"},
+ {"pid-file", ARGP_PID_FILE_KEY, "PIDFILE", 0, "File to use as pid file"},
+ {"socket-file", ARGP_SOCK_FILE_KEY, "SOCKFILE", 0,
+ "File to use as unix-socket"},
+ {"no-daemon", ARGP_NO_DAEMON_KEY, 0, 0, "Run in foreground"},
+ {"run-id", ARGP_RUN_ID_KEY, "RUN-ID", OPTION_HIDDEN,
+ "Run ID for the process, used by scripts to keep track of process "
+ "they started, defaults to none"},
+ {"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, "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 (extended attributes) support on inodes"},
+ {"capability", ARGP_CAPABILITY_KEY, 0, 0,
+ "Enable Capability (extended attributes) support on inodes"},
+ {"subdir-mount", ARGP_SUBDIR_MOUNT_KEY, "SUBDIR-PATH", 0,
+ "Mount subdirectory given [default: NULL]"},
+
+ {"print-netgroups", ARGP_PRINT_NETGROUPS, "NETGROUP-FILE", 0,
+ "Validate the netgroups file and print it out"},
+ {"print-exports", ARGP_PRINT_EXPORTS, "EXPORTS-FILE", 0,
+ "Validate the exports file and print it out"},
+ {"print-xlatordir", ARGP_PRINT_XLATORDIR_KEY, 0, OPTION_ARG_OPTIONAL,
+ "Print xlator directory path"},
+ {"print-statedumpdir", ARGP_PRINT_STATEDUMPDIR_KEY, 0, OPTION_ARG_OPTIONAL,
+ "Print directory path in which statedumps shall be generated"},
+ {"print-logdir", ARGP_PRINT_LOGDIR_KEY, 0, OPTION_ARG_OPTIONAL,
+ "Print path of default log directory"},
+ {"print-libexecdir", ARGP_PRINT_LIBEXECDIR_KEY, 0, OPTION_ARG_OPTIONAL,
+ "Print path of default libexec directory"},
+
+ {"volfile-max-fetch-attempts", ARGP_VOLFILE_MAX_FETCH_ATTEMPTS, "0",
+ OPTION_HIDDEN, "Maximum number of attempts to fetch the volfile"},
+ {"aux-gfid-mount", ARGP_AUX_GFID_MOUNT_KEY, 0, 0,
+ "Enable access to filesystem through gfid directly"},
+ {"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
- "[default: \"on\" on client side, else \"off\"]"
+ "[default: \"on\" on client side, else \"off\"]"
#else
- "[default: \"off\"]"
+ "[default: \"off\"]"
+#endif
+ },
+ {"brick-name", ARGP_BRICK_NAME_KEY, "BRICK-NAME", OPTION_HIDDEN,
+ "Brick name to be registered with Gluster portmapper"},
+ {"brick-port", ARGP_BRICK_PORT_KEY, "BRICK-PORT", OPTION_HIDDEN,
+ "Brick Port to be registered with Gluster portmapper"},
+ {"fopen-keep-cache", ARGP_FOPEN_KEEP_CACHE_KEY, "BOOL", OPTION_ARG_OPTIONAL,
+ "Do not purge the cache on file open [default: false]"},
+ {"global-timer-wheel", ARGP_GLOBAL_TIMER_WHEEL, "BOOL", OPTION_ARG_OPTIONAL,
+ "Instantiate process global timer-wheel"},
+ {"thin-client", ARGP_THIN_CLIENT_KEY, 0, 0,
+ "Enables thin mount and connects via gfproxyd daemon"},
+ {"global-threading", ARGP_GLOBAL_THREADING_KEY, "BOOL", OPTION_ARG_OPTIONAL,
+ "Use the global thread pool instead of io-threads"},
+ {0, 0, 0, 0, "Fuse options:"},
+ {"direct-io-mode", ARGP_DIRECT_IO_MODE_KEY, "BOOL|auto",
+ OPTION_ARG_OPTIONAL, "Specify direct I/O strategy [default: \"auto\"]"},
+ {"entry-timeout", ARGP_ENTRY_TIMEOUT_KEY, "SECONDS", 0,
+ "Set entry timeout to SECONDS in fuse kernel module [default: 1]"},
+ {"negative-timeout", ARGP_NEGATIVE_TIMEOUT_KEY, "SECONDS", 0,
+ "Set negative timeout to SECONDS in fuse kernel module [default: 0]"},
+ {"attribute-timeout", ARGP_ATTRIBUTE_TIMEOUT_KEY, "SECONDS", 0,
+ "Set attribute timeout to SECONDS for inodes in fuse kernel module "
+ "[default: 1]"},
+ {"gid-timeout", ARGP_GID_TIMEOUT_KEY, "SECONDS", 0,
+ "Set auxiliary group list timeout to SECONDS for fuse translator "
+ "[default: 300]"},
+ {"resolve-gids", ARGP_RESOLVE_GIDS_KEY, 0, 0,
+ "Resolve all auxiliary groups in fuse translator (max 32 otherwise)"},
+ {"lru-limit", ARGP_FUSE_LRU_LIMIT_KEY, "N", 0,
+ "Set fuse module's limit for number of inodes kept in LRU list to N "
+ "[default: 65536]"},
+ {"invalidate-limit", ARGP_FUSE_INVALIDATE_LIMIT_KEY, "N", 0,
+ "Suspend inode invalidations implied by 'lru-limit' if the number of "
+ "outstanding invalidations reaches N"},
+ {"background-qlen", ARGP_FUSE_BACKGROUND_QLEN_KEY, "N", 0,
+ "Set fuse module's background queue length to N "
+ "[default: 64]"},
+ {"congestion-threshold", ARGP_FUSE_CONGESTION_THRESHOLD_KEY, "N", 0,
+ "Set fuse module's congestion threshold to N "
+ "[default: 48]"},
+#ifdef GF_LINUX_HOST_OS
+ {"oom-score-adj", ARGP_OOM_SCORE_ADJ_KEY, "INTEGER", 0,
+ "Set oom_score_adj value for process"
+ "[default: 0]"},
#endif
- },
- {"brick-name", ARGP_BRICK_NAME_KEY, "BRICK-NAME", OPTION_HIDDEN,
- "Brick name to be registered with Gluster portmapper" },
- {"brick-port", ARGP_BRICK_PORT_KEY, "BRICK-PORT", OPTION_HIDDEN,
- "Brick Port to be registered with Gluster portmapper" },
- {"fopen-keep-cache", ARGP_FOPEN_KEEP_CACHE_KEY, "BOOL", OPTION_ARG_OPTIONAL,
- "Do not purge the cache on file open"},
- {"global-timer-wheel", ARGP_GLOBAL_TIMER_WHEEL, "BOOL",
- OPTION_ARG_OPTIONAL, "Instantiate process global timer-wheel"},
-
- {0, 0, 0, 0, "Fuse options:"},
- {"direct-io-mode", ARGP_DIRECT_IO_MODE_KEY, "BOOL", OPTION_ARG_OPTIONAL,
- "Use direct I/O mode in fuse kernel module"
- " [default: \"off\" if big writes are supported, else "
- "\"on\" for fds not opened with O_RDONLY]"},
- {"entry-timeout", ARGP_ENTRY_TIMEOUT_KEY, "SECONDS", 0,
- "Set entry timeout to SECONDS in fuse kernel module [default: 1]"},
- {"negative-timeout", ARGP_NEGATIVE_TIMEOUT_KEY, "SECONDS", 0,
- "Set negative timeout to SECONDS in fuse kernel module [default: 0]"},
- {"attribute-timeout", ARGP_ATTRIBUTE_TIMEOUT_KEY, "SECONDS", 0,
- "Set attribute timeout to SECONDS for inodes in fuse kernel module "
- "[default: 1]"},
- {"gid-timeout", ARGP_GID_TIMEOUT_KEY, "SECONDS", 0,
- "Set auxilary group list timeout to SECONDS for fuse translator "
- "[default: 300]"},
- {"resolve-gids", ARGP_RESOLVE_GIDS_KEY, 0, 0,
- "Resolve all auxilary groups in fuse translator (max 32 otherwise)"},
- {"background-qlen", ARGP_FUSE_BACKGROUND_QLEN_KEY, "N", 0,
- "Set fuse module's background queue length to N "
- "[default: 64]"},
- {"congestion-threshold", ARGP_FUSE_CONGESTION_THRESHOLD_KEY, "N", 0,
- "Set fuse module's congestion threshold to N "
- "[default: 48]"},
- {"client-pid", ARGP_CLIENT_PID_KEY, "PID", OPTION_HIDDEN,
- "client will authenticate itself with process id PID to server"},
- {"no-root-squash", ARGP_FUSE_NO_ROOT_SQUASH_KEY, "BOOL",
- OPTION_ARG_OPTIONAL, "disable/enable root squashing for the trusted "
- "client"},
- {"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"},
- {"no-mem-accounting", ARGP_MEM_ACCOUNTING_KEY, 0, OPTION_HIDDEN,
- "disable internal memory accounting"},
- {"fuse-mountopts", ARGP_FUSE_MOUNTOPTS_KEY, "OPTIONS", OPTION_HIDDEN,
- "Extra mount options to pass to FUSE"},
- {"use-readdirp", ARGP_FUSE_USE_READDIRP_KEY, "BOOL", OPTION_ARG_OPTIONAL,
- "Use readdirp mode in fuse kernel module"
- " [default: \"off\"]"},
- {"secure-mgmt", ARGP_SECURE_MGMT_KEY, "BOOL", OPTION_ARG_OPTIONAL,
- "Override default for secure (SSL) management connections"},
- {0, 0, 0, 0, "Miscellaneous Options:"},
- {0, }
-};
-
-
-static struct argp argp = { gf_options, parse_opts, argp_doc, gf_doc };
-
-
-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);
+ {"client-pid", ARGP_CLIENT_PID_KEY, "PID", OPTION_HIDDEN,
+ "client will authenticate itself with process id PID to server"},
+ {"no-root-squash", ARGP_FUSE_NO_ROOT_SQUASH_KEY, "BOOL",
+ OPTION_ARG_OPTIONAL,
+ "disable/enable root squashing for the trusted "
+ "client"},
+ {"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"},
+ {"no-mem-accounting", ARGP_MEM_ACCOUNTING_KEY, 0, OPTION_HIDDEN,
+ "disable internal memory accounting"},
+ {"fuse-mountopts", ARGP_FUSE_MOUNTOPTS_KEY, "OPTIONS", OPTION_HIDDEN,
+ "Extra mount options to pass to FUSE"},
+ {"use-readdirp", ARGP_FUSE_USE_READDIRP_KEY, "BOOL", OPTION_ARG_OPTIONAL,
+ "Use readdirp mode in fuse kernel module"
+ " [default: \"yes\"]"},
+ {"secure-mgmt", ARGP_SECURE_MGMT_KEY, "BOOL", OPTION_ARG_OPTIONAL,
+ "Override default for secure (SSL) management connections"},
+ {"localtime-logging", ARGP_LOCALTIME_LOGGING_KEY, 0, 0,
+ "Enable localtime logging"},
+ {"process-name", ARGP_PROCESS_NAME_KEY, "PROCESS-NAME", OPTION_HIDDEN,
+ "option to specify the process type"},
+ {"event-history", ARGP_FUSE_EVENT_HISTORY_KEY, "BOOL", OPTION_ARG_OPTIONAL,
+ "disable/enable fuse event-history"},
+ {"reader-thread-count", ARGP_READER_THREAD_COUNT_KEY, "INTEGER",
+ OPTION_ARG_OPTIONAL, "set fuse reader thread count"},
+ {"kernel-writeback-cache", ARGP_KERNEL_WRITEBACK_CACHE_KEY, "BOOL",
+ OPTION_ARG_OPTIONAL, "enable fuse in-kernel writeback cache"},
+ {"attr-times-granularity", ARGP_ATTR_TIMES_GRANULARITY_KEY, "NS",
+ OPTION_ARG_OPTIONAL,
+ "declare supported granularity of file attribute"
+ " times in nanoseconds"},
+ {"fuse-flush-handle-interrupt", ARGP_FUSE_FLUSH_HANDLE_INTERRUPT_KEY,
+ "BOOL", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
+ "handle interrupt in fuse FLUSH handler"},
+ {"auto-invalidation", ARGP_FUSE_AUTO_INVAL_KEY, "BOOL", OPTION_ARG_OPTIONAL,
+ "controls whether fuse-kernel can auto-invalidate "
+ "attribute, dentry and page-cache. "
+ "Disable this only if same files/directories are not accessed across "
+ "two different mounts concurrently [default: \"on\"]"},
+ {"fuse-dev-eperm-ratelimit-ns", ARGP_FUSE_DEV_EPERM_RATELIMIT_NS_KEY,
+ "OPTIONS", OPTION_HIDDEN,
+ "rate limit reading from fuse device upon EPERM failure"},
+ {"brick-mux", ARGP_BRICK_MUX_KEY, 0, 0, "Enable brick mux. "},
+ {0, 0, 0, 0, "Miscellaneous Options:"},
+ {
+ 0,
+ }};
+
+static struct argp argp = {gf_options, parse_opts, argp_doc, gf_doc};
+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);
+
+#define DICT_SET_VAL(method, dict, key, val, msgid) \
+ if (method(dict, key, val)) { \
+ gf_smsg("glusterfsd", GF_LOG_ERROR, 0, msgid, "key=%s", key); \
+ goto err; \
+ }
static int
-set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
+set_fuse_mount_options(glusterfs_ctx_t *ctx, dict_t *options)
{
- int ret = 0;
- cmd_args_t *cmd_args = NULL;
- char *mount_point = NULL;
- char cwd[PATH_MAX] = {0,};
-
- cmd_args = &ctx->cmd_args;
-
- /* 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_msg ("glusterfsd", GF_LOG_ERROR, errno,
- glusterfsd_msg_1);
- goto err;
- }
- } else {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno,
- glusterfsd_msg_2);
- goto err;
- }
- } else
- mount_point = gf_strdup (cmd_args->mount_point);
-
- ret = dict_set_dynstr (options, ZR_MOUNTPOINT_OPT, mount_point);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_3);
+ int ret = 0;
+ cmd_args_t *cmd_args = NULL;
+ char *mount_point = NULL;
+ char cwd[PATH_MAX] = {
+ 0,
+ };
+
+ cmd_args = &ctx->cmd_args;
+
+ /* Check if mount-point is absolute path,
+ * if not convert to absolute path by concatenating 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_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_1,
+ "gf_asprintf failed", NULL);
goto err;
- }
-
- if (cmd_args->fuse_attribute_timeout >= 0) {
- ret = dict_set_double (options, ZR_ATTR_TIMEOUT_OPT,
- cmd_args->fuse_attribute_timeout);
-
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno,
- glusterfsd_msg_4, ZR_ATTR_TIMEOUT_OPT);
- goto err;
- }
- }
-
- if (cmd_args->fuse_entry_timeout >= 0) {
- ret = dict_set_double (options, ZR_ENTRY_TIMEOUT_OPT,
- cmd_args->fuse_entry_timeout);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- ZR_ENTRY_TIMEOUT_OPT);
- goto err;
- }
- }
-
- if (cmd_args->fuse_negative_timeout >= 0) {
- ret = dict_set_double (options, ZR_NEGATIVE_TIMEOUT_OPT,
- cmd_args->fuse_negative_timeout);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- ZR_NEGATIVE_TIMEOUT_OPT);
- goto err;
- }
- }
-
- if (cmd_args->client_pid_set) {
- ret = dict_set_int32 (options, "client-pid",
- cmd_args->client_pid);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "client-pid");
- goto err;
- }
- }
-
- if (cmd_args->uid_map_root) {
- ret = dict_set_int32 (options, "uid-map-root",
- cmd_args->uid_map_root);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "uid-map-root");
- goto err;
- }
- }
-
- if (cmd_args->volfile_check) {
- ret = dict_set_int32 (options, ZR_STRICT_VOLFILE_CHECK,
- cmd_args->volfile_check);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- ZR_STRICT_VOLFILE_CHECK);
- goto err;
- }
- }
-
- if (cmd_args->dump_fuse) {
- ret = dict_set_static_ptr (options, ZR_DUMP_FUSE,
- cmd_args->dump_fuse);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- ZR_DUMP_FUSE);
- goto err;
- }
- }
-
- if (cmd_args->acl) {
- ret = dict_set_static_ptr (options, "acl", "on");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "acl");
- goto err;
- }
- }
-
- if (cmd_args->selinux) {
- ret = dict_set_static_ptr (options, "selinux", "on");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "selinux");
- goto err;
- }
- }
-
- if (cmd_args->aux_gfid_mount) {
- ret = dict_set_static_ptr (options, "virtual-gfid-access",
- "on");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "aux-gfid-mount");
- goto err;
- }
- }
-
- if (cmd_args->enable_ino32) {
- ret = dict_set_static_ptr (options, "enable-ino32", "on");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "enable-ino32");
- goto err;
- }
- }
-
- if (cmd_args->read_only) {
- ret = dict_set_static_ptr (options, "read-only", "on");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "read-only");
- goto err;
- }
- }
-
- switch (cmd_args->fopen_keep_cache) {
- case GF_OPTION_ENABLE:
- ret = dict_set_static_ptr(options, "fopen-keep-cache",
- "on");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "fopen-keep-cache");
- goto err;
- }
- break;
- case GF_OPTION_DISABLE:
- ret = dict_set_static_ptr(options, "fopen-keep-cache",
- "off");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "fopen-keep-cache");
- goto err;
- }
- break;
- case GF_OPTION_DEFERRED: /* default */
+ }
+ } else {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_2,
+ "getcwd failed", NULL);
+ goto err;
+ }
+
+ } else {
+ mount_point = gf_strdup(cmd_args->mount_point);
+ }
+ DICT_SET_VAL(dict_set_dynstr_sizen, options, ZR_MOUNTPOINT_OPT, mount_point,
+ glusterfsd_msg_3);
+
+ if (cmd_args->fuse_attribute_timeout >= 0) {
+ DICT_SET_VAL(dict_set_double, options, ZR_ATTR_TIMEOUT_OPT,
+ cmd_args->fuse_attribute_timeout, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->fuse_entry_timeout >= 0) {
+ DICT_SET_VAL(dict_set_double, options, ZR_ENTRY_TIMEOUT_OPT,
+ cmd_args->fuse_entry_timeout, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->fuse_negative_timeout >= 0) {
+ DICT_SET_VAL(dict_set_double, options, ZR_NEGATIVE_TIMEOUT_OPT,
+ cmd_args->fuse_negative_timeout, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->client_pid_set) {
+ DICT_SET_VAL(dict_set_int32_sizen, options, "client-pid",
+ cmd_args->client_pid, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->uid_map_root) {
+ DICT_SET_VAL(dict_set_int32_sizen, options, "uid-map-root",
+ cmd_args->uid_map_root, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->volfile_check) {
+ DICT_SET_VAL(dict_set_int32_sizen, options, ZR_STRICT_VOLFILE_CHECK,
+ cmd_args->volfile_check, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->dump_fuse) {
+ DICT_SET_VAL(dict_set_static_ptr, options, ZR_DUMP_FUSE,
+ cmd_args->dump_fuse, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->acl) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "acl", "on",
+ glusterfsd_msg_3);
+ }
+
+ if (cmd_args->selinux) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "selinux", "on",
+ glusterfsd_msg_3);
+ }
+
+ if (cmd_args->capability) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "capability", "on",
+ glusterfsd_msg_3);
+ }
+
+ if (cmd_args->aux_gfid_mount) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "virtual-gfid-access", "on",
+ glusterfsd_msg_3);
+ }
+
+ if (cmd_args->enable_ino32) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "enable-ino32", "on",
+ glusterfsd_msg_3);
+ }
+
+ if (cmd_args->read_only) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "read-only", "on",
+ glusterfsd_msg_3);
+ }
+
+ switch (cmd_args->fopen_keep_cache) {
+ case GF_OPTION_ENABLE:
+
+ DICT_SET_VAL(dict_set_static_ptr, options, "fopen-keep-cache", "on",
+ glusterfsd_msg_3);
+ break;
+ case GF_OPTION_DISABLE:
+ DICT_SET_VAL(dict_set_static_ptr, options, "fopen-keep-cache",
+ "off", glusterfsd_msg_3);
+ break;
default:
- gf_msg_debug ("glusterfsd", 0, "fopen-keep-cache mode %d",
- cmd_args->fopen_keep_cache);
- break;
- }
-
- if (cmd_args->gid_timeout_set) {
- ret = dict_set_int32(options, "gid-timeout",
- cmd_args->gid_timeout);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "gid-timeout");
- goto err;
- }
- }
-
- if (cmd_args->resolve_gids) {
- ret = dict_set_static_ptr (options, "resolve-gids", "on");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "resolve-gids");
- goto err;
- }
- }
-
- if (cmd_args->background_qlen) {
- ret = dict_set_int32 (options, "background-qlen",
- cmd_args->background_qlen);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "background-qlen");
- goto err;
- }
- }
- if (cmd_args->congestion_threshold) {
- ret = dict_set_int32 (options, "congestion-threshold",
- cmd_args->congestion_threshold);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "congestion-threshold");
- goto err;
- }
- }
-
- switch (cmd_args->fuse_direct_io_mode) {
+ gf_msg_debug("glusterfsd", 0, "fopen-keep-cache mode %d",
+ cmd_args->fopen_keep_cache);
+ break;
+ }
+
+ if (cmd_args->gid_timeout_set) {
+ DICT_SET_VAL(dict_set_int32_sizen, options, "gid-timeout",
+ cmd_args->gid_timeout, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->resolve_gids) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "resolve-gids", "on",
+ glusterfsd_msg_3);
+ }
+
+ if (cmd_args->lru_limit >= 0) {
+ DICT_SET_VAL(dict_set_int32_sizen, options, "lru-limit",
+ cmd_args->lru_limit, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->invalidate_limit >= 0) {
+ DICT_SET_VAL(dict_set_int32_sizen, options, "invalidate-limit",
+ cmd_args->invalidate_limit, glusterfsd_msg_3);
+ }
+
+ if (cmd_args->background_qlen) {
+ DICT_SET_VAL(dict_set_int32_sizen, options, "background-qlen",
+ cmd_args->background_qlen, glusterfsd_msg_3);
+ }
+ if (cmd_args->congestion_threshold) {
+ DICT_SET_VAL(dict_set_int32_sizen, options, "congestion-threshold",
+ cmd_args->congestion_threshold, glusterfsd_msg_3);
+ }
+
+ switch (cmd_args->fuse_direct_io_mode) {
case GF_OPTION_DISABLE: /* disable */
- ret = dict_set_static_ptr (options, ZR_DIRECT_IO_OPT,
- "disable");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_5,
- ZR_DIRECT_IO_OPT);
- goto err;
- }
- break;
+ DICT_SET_VAL(dict_set_static_ptr, options, ZR_DIRECT_IO_OPT,
+ "disable", glusterfsd_msg_3);
+ break;
case GF_OPTION_ENABLE: /* enable */
- ret = dict_set_static_ptr (options, ZR_DIRECT_IO_OPT,
- "enable");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_6,
- ZR_DIRECT_IO_OPT);
- goto err;
- }
- break;
- case GF_OPTION_DEFERRED: /* default */
+ DICT_SET_VAL(dict_set_static_ptr, options, ZR_DIRECT_IO_OPT,
+ "enable", glusterfsd_msg_3);
+ break;
default:
- gf_msg_debug ("glusterfsd", 0, "fuse direct io type %d",
- cmd_args->fuse_direct_io_mode);
- break;
- }
+ gf_msg_debug("glusterfsd", 0, "fuse direct io type %d",
+ cmd_args->fuse_direct_io_mode);
+ break;
+ }
- switch (cmd_args->no_root_squash) {
+ switch (cmd_args->no_root_squash) {
case GF_OPTION_ENABLE: /* enable */
- ret = dict_set_static_ptr (options, "no-root-squash",
- "enable");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_6,
- "no-root-squash");
- goto err;
- }
- break;
- case GF_OPTION_DISABLE: /* disable/default */
+ DICT_SET_VAL(dict_set_static_ptr, options, "no-root-squash",
+ "enable", glusterfsd_msg_3);
+ break;
default:
- ret = dict_set_static_ptr (options, "no-root-squash",
- "disable");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_5,
- "no-root-squash");
- goto err;
- }
- gf_msg_debug ("glusterfsd", 0, "fuse no-root-squash mode %d",
- cmd_args->no_root_squash);
- break;
- }
-
- if (!cmd_args->no_daemon_mode) {
- ret = dict_set_static_ptr (options, "sync-to-mount",
- "enable");
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "sync-mtab");
- goto err;
- }
- }
-
- if (cmd_args->use_readdirp) {
- ret = dict_set_str (options, "use-readdirp",
- cmd_args->use_readdirp);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- "use-readdirp");
- goto err;
- }
- }
- ret = 0;
+ DICT_SET_VAL(dict_set_static_ptr, options, "no-root-squash",
+ "disable", glusterfsd_msg_3);
+ gf_msg_debug("glusterfsd", 0, "fuse no-root-squash mode %d",
+ cmd_args->no_root_squash);
+ break;
+ }
+
+ if (!cmd_args->no_daemon_mode) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "sync-to-mount", "enable",
+ glusterfsd_msg_3);
+ }
+
+ if (cmd_args->use_readdirp) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "use-readdirp",
+ cmd_args->use_readdirp, glusterfsd_msg_3);
+ }
+ if (cmd_args->event_history) {
+ ret = dict_set_str(options, "event-history", cmd_args->event_history);
+ DICT_SET_VAL(dict_set_static_ptr, options, "event-history",
+ cmd_args->event_history, glusterfsd_msg_3);
+ }
+ if (cmd_args->thin_client) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "thin-client", "on",
+ glusterfsd_msg_3);
+ }
+ if (cmd_args->reader_thread_count) {
+ DICT_SET_VAL(dict_set_uint32, options, "reader-thread-count",
+ cmd_args->reader_thread_count, glusterfsd_msg_3);
+ }
+
+ DICT_SET_VAL(dict_set_uint32, options, "auto-invalidation",
+ cmd_args->fuse_auto_inval, glusterfsd_msg_3);
+
+ switch (cmd_args->kernel_writeback_cache) {
+ case GF_OPTION_ENABLE:
+ DICT_SET_VAL(dict_set_static_ptr, options, "kernel-writeback-cache",
+ "on", glusterfsd_msg_3);
+ break;
+ case GF_OPTION_DISABLE:
+ DICT_SET_VAL(dict_set_static_ptr, options, "kernel-writeback-cache",
+ "off", glusterfsd_msg_3);
+ break;
+ default:
+ gf_msg_debug("glusterfsd", 0, "kernel-writeback-cache mode %d",
+ cmd_args->kernel_writeback_cache);
+ break;
+ }
+ if (cmd_args->attr_times_granularity) {
+ DICT_SET_VAL(dict_set_uint32, options, "attr-times-granularity",
+ cmd_args->attr_times_granularity, glusterfsd_msg_3);
+ }
+ switch (cmd_args->fuse_flush_handle_interrupt) {
+ case GF_OPTION_ENABLE:
+ DICT_SET_VAL(dict_set_static_ptr, options, "flush-handle-interrupt",
+ "on", glusterfsd_msg_3);
+ break;
+ case GF_OPTION_DISABLE:
+ DICT_SET_VAL(dict_set_static_ptr, options, "flush-handle-interrupt",
+ "off", glusterfsd_msg_3);
+ break;
+ default:
+ gf_msg_debug("glusterfsd", 0, "fuse-flush-handle-interrupt mode %d",
+ cmd_args->fuse_flush_handle_interrupt);
+ break;
+ }
+ if (cmd_args->global_threading) {
+ DICT_SET_VAL(dict_set_static_ptr, options, "global-threading", "on",
+ glusterfsd_msg_3);
+ }
+ if (cmd_args->fuse_dev_eperm_ratelimit_ns) {
+ DICT_SET_VAL(dict_set_uint32, options, "fuse-dev-eperm-ratelimit-ns",
+ cmd_args->fuse_dev_eperm_ratelimit_ns, glusterfsd_msg_3);
+ }
+
+ ret = 0;
err:
- return ret;
+ return ret;
}
int
-create_fuse_mount (glusterfs_ctx_t *ctx)
+create_fuse_mount(glusterfs_ctx_t *ctx)
{
- int ret = 0;
- cmd_args_t *cmd_args = NULL;
- xlator_t *master = NULL;
-
- cmd_args = &ctx->cmd_args;
-
- if (!cmd_args->mount_point) {
- gf_msg_trace ("glusterfsd", 0,
- "mount point not found, not a client process");
- return 0;
- }
-
- if (ctx->process_mode != GF_CLIENT_PROCESS) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_7);
- return -1;
- }
-
- master = GF_CALLOC (1, sizeof (*master),
- gfd_mt_xlator_t);
- if (!master)
- goto err;
-
- master->name = gf_strdup ("fuse");
- if (!master->name)
- goto err;
-
- if (xlator_set_type (master, "mount/fuse") == -1) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_8,
- cmd_args->mount_point);
- goto err;
- }
-
- master->ctx = ctx;
- master->options = get_new_dict ();
- if (!master->options)
- goto err;
-
- ret = set_fuse_mount_options (ctx, master->options);
- if (ret)
- goto err;
-
- if (cmd_args->fuse_mountopts) {
- ret = dict_set_static_ptr (master->options, ZR_FUSE_MOUNTOPTS,
- cmd_args->fuse_mountopts);
- if (ret < 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
- ZR_FUSE_MOUNTOPTS);
- goto err;
- }
+ int ret = 0;
+ cmd_args_t *cmd_args = NULL;
+ xlator_t *master = NULL;
+
+ cmd_args = &ctx->cmd_args;
+ if (!cmd_args->mount_point) {
+ gf_msg_trace("glusterfsd", 0,
+ "mount point not found, not a client process");
+ return 0;
+ }
+
+ if (ctx->process_mode != GF_CLIENT_PROCESS) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_7, NULL);
+ return -1;
+ }
+
+ master = GF_CALLOC(1, sizeof(*master), gfd_mt_xlator_t);
+ if (!master)
+ goto err;
+
+ master->name = gf_strdup("fuse");
+ if (!master->name)
+ goto err;
+
+ if (xlator_set_type(master, "mount/fuse") == -1) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_8,
+ "MOUNT-POINT=%s", cmd_args->mount_point, NULL);
+ goto err;
+ }
+
+ master->ctx = ctx;
+ master->options = dict_new();
+ if (!master->options)
+ goto err;
+
+ ret = set_fuse_mount_options(ctx, master->options);
+ if (ret)
+ goto err;
+
+ if (cmd_args->fuse_mountopts) {
+ ret = dict_set_static_ptr(master->options, ZR_FUSE_MOUNTOPTS,
+ cmd_args->fuse_mountopts);
+ if (ret < 0) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_3,
+ ZR_FUSE_MOUNTOPTS, NULL);
+ goto err;
}
+ }
- ret = xlator_init (master);
- if (ret) {
- gf_msg_debug ("glusterfsd", 0,
- "failed to initialize fuse translator");
- goto err;
- }
+ ret = xlator_init(master);
+ if (ret) {
+ gf_msg_debug("glusterfsd", 0, "failed to initialize fuse translator");
+ goto err;
+ }
- ctx->master = master;
+ ctx->master = master;
- return 0;
+ return 0;
err:
- if (master) {
- xlator_destroy (master);
- }
+ if (master) {
+ xlator_destroy(master);
+ }
- return 1;
+ return 1;
}
-
static FILE *
-get_volfp (glusterfs_ctx_t *ctx)
+get_volfp(glusterfs_ctx_t *ctx)
{
- int ret = 0;
- cmd_args_t *cmd_args = NULL;
- FILE *specfp = NULL;
- struct stat statbuf;
+ cmd_args_t *cmd_args = NULL;
+ FILE *specfp = NULL;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- ret = sys_lstat (cmd_args->volfile, &statbuf);
- if (ret == -1) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_9,
- cmd_args->volfile);
- return NULL;
- }
-
- if ((specfp = fopen (cmd_args->volfile, "r")) == NULL) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_9,
- cmd_args->volfile);
- return NULL;
- }
+ if ((specfp = fopen(cmd_args->volfile, "r")) == NULL) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_9,
+ "volume_file=%s", cmd_args->volfile, NULL);
+ return NULL;
+ }
- gf_msg_debug ("glusterfsd", 0, "loading volume file %s",
- cmd_args->volfile);
+ gf_msg_debug("glusterfsd", 0, "loading volume file %s", cmd_args->volfile);
- return specfp;
+ return specfp;
}
static int
-gf_remember_backup_volfile_server (char *arg)
+gf_remember_backup_volfile_server(char *arg)
{
- glusterfs_ctx_t *ctx = NULL;
- cmd_args_t *cmd_args = NULL;
- int ret = -1;
- server_cmdline_t *server = NULL;
-
- ctx = glusterfsd_ctx;
- if (!ctx)
- goto out;
- cmd_args = &ctx->cmd_args;
-
- if(!cmd_args)
- goto out;
-
- server = GF_CALLOC (1, sizeof (server_cmdline_t),
- gfd_mt_server_cmdline_t);
- if (!server)
- goto out;
-
- INIT_LIST_HEAD(&server->list);
-
- server->volfile_server = gf_strdup(arg);
-
- if (!cmd_args->volfile_server) {
- cmd_args->volfile_server = server->volfile_server;
- cmd_args->curr_server = server;
- }
-
- if (!server->volfile_server) {
- gf_msg ("glusterfsd", GF_LOG_WARNING, 0, glusterfsd_msg_10,
- arg);
- goto out;
- }
-
- list_add_tail (&server->list, &cmd_args->volfile_servers);
-
- ret = 0;
+ glusterfs_ctx_t *ctx = NULL;
+ cmd_args_t *cmd_args = NULL;
+ int ret = -1;
+
+ ctx = glusterfsd_ctx;
+ if (!ctx)
+ goto out;
+ cmd_args = &ctx->cmd_args;
+
+ if (!cmd_args)
+ goto out;
+
+ ret = gf_set_volfile_server_common(
+ cmd_args, arg, GF_DEFAULT_VOLFILE_TRANSPORT, GF_DEFAULT_BASE_PORT);
+ if (ret) {
+ gf_log("glusterfs", GF_LOG_ERROR, "failed to set volfile server: %s",
+ strerror(errno));
+ }
out:
- if (ret == -1) {
- if (server) {
- GF_FREE (server->volfile_server);
- GF_FREE (server);
- }
- }
-
- return ret;
-
+ return ret;
}
static int
-gf_remember_xlator_option (char *arg)
+gf_remember_xlator_option(char *arg)
{
- glusterfs_ctx_t *ctx = NULL;
- cmd_args_t *cmd_args = NULL;
- xlator_cmdline_option_t *option = NULL;
- int ret = -1;
- char *dot = NULL;
- char *equals = NULL;
-
- ctx = glusterfsd_ctx;
- cmd_args = &ctx->cmd_args;
-
- option = GF_CALLOC (1, sizeof (xlator_cmdline_option_t),
- gfd_mt_xlator_cmdline_option_t);
- if (!option)
- goto out;
+ glusterfs_ctx_t *ctx = NULL;
+ cmd_args_t *cmd_args = NULL;
+ xlator_cmdline_option_t *option = NULL;
+ int ret = -1;
+ char *dot = NULL;
+ char *equals = NULL;
- INIT_LIST_HEAD (&option->cmd_args);
+ ctx = glusterfsd_ctx;
+ cmd_args = &ctx->cmd_args;
- dot = strchr (arg, '.');
- if (!dot) {
- gf_msg ("", GF_LOG_WARNING, 0, glusterfsd_msg_10, arg);
- goto out;
- }
+ option = GF_CALLOC(1, sizeof(xlator_cmdline_option_t),
+ gfd_mt_xlator_cmdline_option_t);
+ if (!option)
+ goto out;
- option->volume = GF_CALLOC ((dot - arg) + 1, sizeof (char),
- gfd_mt_char);
- if (!option->volume)
- goto out;
+ INIT_LIST_HEAD(&option->cmd_args);
- strncpy (option->volume, arg, (dot - arg));
+ dot = strchr(arg, '.');
+ if (!dot) {
+ gf_smsg("", GF_LOG_WARNING, 0, glusterfsd_msg_10, "arg=%s", arg, NULL);
+ goto out;
+ }
- equals = strchr (arg, '=');
- if (!equals) {
- gf_msg ("", GF_LOG_WARNING, 0, glusterfsd_msg_10, arg);
- goto out;
- }
+ option->volume = GF_MALLOC((dot - arg) + 1, gfd_mt_char);
+ if (!option->volume)
+ goto out;
- option->key = GF_CALLOC ((equals - dot) + 1, sizeof (char),
- gfd_mt_char);
- if (!option->key)
- goto out;
+ strncpy(option->volume, arg, (dot - arg));
+ option->volume[(dot - arg)] = '\0';
- strncpy (option->key, dot + 1, (equals - dot - 1));
+ equals = strchr(arg, '=');
+ if (!equals) {
+ gf_smsg("", GF_LOG_WARNING, 0, glusterfsd_msg_10, "arg=%s", arg, NULL);
+ goto out;
+ }
- if (!*(equals + 1)) {
- gf_msg ("", GF_LOG_WARNING, 0, glusterfsd_msg_10, arg);
- goto out;
- }
+ option->key = GF_MALLOC((equals - dot) + 1, gfd_mt_char);
+ if (!option->key)
+ goto out;
- option->value = gf_strdup (equals + 1);
+ strncpy(option->key, dot + 1, (equals - dot - 1));
+ option->key[(equals - dot - 1)] = '\0';
- list_add (&option->cmd_args, &cmd_args->xlator_options);
+ if (!*(equals + 1)) {
+ gf_smsg("", GF_LOG_WARNING, 0, glusterfsd_msg_10, "arg=%s", arg, NULL);
+ goto out;
+ }
- ret = 0;
+ option->value = gf_strdup(equals + 1);
+
+ list_add(&option->cmd_args, &cmd_args->xlator_options);
+
+ ret = 0;
out:
- if (ret == -1) {
- if (option) {
- GF_FREE (option->volume);
- GF_FREE (option->key);
- GF_FREE (option->value);
+ if (ret == -1) {
+ if (option) {
+ GF_FREE(option->volume);
+ GF_FREE(option->key);
+ GF_FREE(option->value);
- GF_FREE (option);
- }
+ GF_FREE(option);
}
+ }
- return ret;
+ return ret;
}
+#ifdef GF_LINUX_HOST_OS
+static struct oom_api_info {
+ char *oom_api_file;
+ int32_t oom_min;
+ int32_t oom_max;
+} oom_api_info[] = {
+ {"/proc/self/oom_score_adj", OOM_SCORE_ADJ_MIN, OOM_SCORE_ADJ_MAX},
+ {"/proc/self/oom_adj", OOM_DISABLE, OOM_ADJUST_MAX},
+ {NULL, 0, 0}};
+
+static struct oom_api_info *
+get_oom_api_info(void)
+{
+ struct oom_api_info *api = NULL;
+ for (api = oom_api_info; api->oom_api_file; api++) {
+ if (sys_access(api->oom_api_file, F_OK) != -1) {
+ return api;
+ }
+ }
+
+ return NULL;
+}
+#endif
static error_t
-parse_opts (int key, char *arg, struct argp_state *state)
+parse_opts(int key, char *arg, struct argp_state *state)
{
- 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;
- int ret = 0;
-
- cmd_args = state->input;
-
- switch (key) {
+ cmd_args_t *cmd_args = NULL;
+ uint32_t n = 0;
+#ifdef GF_LINUX_HOST_OS
+ int32_t k = 0;
+ struct oom_api_info *api = NULL;
+#endif
+ double d = 0.0;
+ gf_boolean_t b = _gf_false;
+ char *pwd = NULL;
+ char *tmp_str = NULL;
+ char *port_str = NULL;
+ struct passwd *pw = NULL;
+ int ret = 0;
+
+ cmd_args = state->input;
+
+ switch (key) {
case ARGP_VOLFILE_SERVER_KEY:
- gf_remember_backup_volfile_server (arg);
+ gf_remember_backup_volfile_server(arg);
- break;
+ break;
case ARGP_READ_ONLY_KEY:
- cmd_args->read_only = 1;
- break;
+ cmd_args->read_only = 1;
+ break;
case ARGP_ACL_KEY:
- cmd_args->acl = 1;
- gf_remember_xlator_option ("*-md-cache.cache-posix-acl=true");
- break;
+ cmd_args->acl = 1;
+ gf_remember_xlator_option("*-md-cache.cache-posix-acl=true");
+ break;
case ARGP_SELINUX_KEY:
- cmd_args->selinux = 1;
- gf_remember_xlator_option ("*-md-cache.cache-selinux=true");
- break;
+ cmd_args->selinux = 1;
+ gf_remember_xlator_option("*-md-cache.cache-selinux=true");
+ break;
+
+ case ARGP_CAPABILITY_KEY:
+ cmd_args->capability = 1;
+ break;
case ARGP_AUX_GFID_MOUNT_KEY:
- cmd_args->aux_gfid_mount = 1;
- break;
+ cmd_args->aux_gfid_mount = 1;
+ break;
case ARGP_INODE32_KEY:
- cmd_args->enable_ino32 = 1;
- break;
+ cmd_args->enable_ino32 = 1;
+ break;
case ARGP_WORM_KEY:
- cmd_args->worm = 1;
- break;
+ cmd_args->worm = 1;
+ break;
case ARGP_PRINT_NETGROUPS:
- cmd_args->print_netgroups = arg;
- break;
+ cmd_args->print_netgroups = arg;
+ break;
case ARGP_PRINT_EXPORTS:
- cmd_args->print_exports = arg;
- break;
+ cmd_args->print_exports = arg;
+ break;
- case ARGP_MAC_COMPAT_KEY:
- if (!arg)
- arg = "on";
+ case ARGP_PRINT_XLATORDIR_KEY:
+ cmd_args->print_xlatordir = _gf_true;
+ break;
- if (gf_string2boolean (arg, &b) == 0) {
- cmd_args->mac_compat = b;
+ case ARGP_PRINT_STATEDUMPDIR_KEY:
+ cmd_args->print_statedumpdir = _gf_true;
+ break;
- break;
- }
+ case ARGP_PRINT_LOGDIR_KEY:
+ cmd_args->print_logdir = _gf_true;
+ break;
+
+ case ARGP_PRINT_LIBEXECDIR_KEY:
+ cmd_args->print_libexecdir = _gf_true;
+ break;
+
+ case ARGP_MAC_COMPAT_KEY:
+ if (!arg)
+ arg = "on";
+
+ if (gf_string2boolean(arg, &b) == 0) {
+ cmd_args->mac_compat = b;
- argp_failure (state, -1, 0,
- "invalid value \"%s\" for mac-compat", arg);
break;
+ }
+
+ argp_failure(state, -1, 0, "invalid value \"%s\" for mac-compat",
+ arg);
+ break;
case ARGP_VOLUME_FILE_KEY:
- GF_FREE (cmd_args->volfile);
-
- if (arg[0] != '/') {
- pwd = getcwd (NULL, PATH_MAX);
- if (!pwd) {
- argp_failure (state, -1, errno,
- "getcwd failed with error no %d",
- errno);
- break;
- }
- snprintf (tmp_buf, 1024, "%s/%s", pwd, arg);
- cmd_args->volfile = gf_strdup (tmp_buf);
- free (pwd);
- } else {
- cmd_args->volfile = gf_strdup (arg);
+ GF_FREE(cmd_args->volfile);
+
+ if (arg[0] != '/') {
+ pwd = getcwd(NULL, PATH_MAX);
+ if (!pwd) {
+ argp_failure(state, -1, errno,
+ "getcwd failed with error no %d", errno);
+ break;
}
+ char tmp_buf[1024];
+ snprintf(tmp_buf, sizeof(tmp_buf), "%s/%s", pwd, arg);
+ cmd_args->volfile = gf_strdup(tmp_buf);
+ free(pwd);
+ } else {
+ cmd_args->volfile = gf_strdup(arg);
+ }
- break;
+ break;
case ARGP_LOG_LEVEL_KEY:
- if (strcasecmp (arg, ARGP_LOG_LEVEL_NONE_OPTION) == 0) {
- cmd_args->log_level = GF_LOG_NONE;
- break;
- }
- if (strcasecmp (arg, ARGP_LOG_LEVEL_CRITICAL_OPTION) == 0) {
- cmd_args->log_level = GF_LOG_CRITICAL;
- break;
- }
- if (strcasecmp (arg, ARGP_LOG_LEVEL_ERROR_OPTION) == 0) {
- cmd_args->log_level = GF_LOG_ERROR;
- break;
- }
- if (strcasecmp (arg, ARGP_LOG_LEVEL_WARNING_OPTION) == 0) {
- cmd_args->log_level = GF_LOG_WARNING;
- break;
- }
- if (strcasecmp (arg, ARGP_LOG_LEVEL_INFO_OPTION) == 0) {
- cmd_args->log_level = GF_LOG_INFO;
- break;
- }
- if (strcasecmp (arg, ARGP_LOG_LEVEL_DEBUG_OPTION) == 0) {
- cmd_args->log_level = GF_LOG_DEBUG;
- break;
- }
- if (strcasecmp (arg, ARGP_LOG_LEVEL_TRACE_OPTION) == 0) {
- cmd_args->log_level = GF_LOG_TRACE;
- break;
- }
-
- argp_failure (state, -1, 0, "unknown log level %s", arg);
+ if (strcasecmp(arg, ARGP_LOG_LEVEL_NONE_OPTION) == 0) {
+ cmd_args->log_level = GF_LOG_NONE;
+ break;
+ }
+ if (strcasecmp(arg, ARGP_LOG_LEVEL_CRITICAL_OPTION) == 0) {
+ cmd_args->log_level = GF_LOG_CRITICAL;
+ break;
+ }
+ if (strcasecmp(arg, ARGP_LOG_LEVEL_ERROR_OPTION) == 0) {
+ cmd_args->log_level = GF_LOG_ERROR;
+ break;
+ }
+ if (strcasecmp(arg, ARGP_LOG_LEVEL_WARNING_OPTION) == 0) {
+ cmd_args->log_level = GF_LOG_WARNING;
+ break;
+ }
+ if (strcasecmp(arg, ARGP_LOG_LEVEL_INFO_OPTION) == 0) {
+ cmd_args->log_level = GF_LOG_INFO;
+ break;
+ }
+ if (strcasecmp(arg, ARGP_LOG_LEVEL_DEBUG_OPTION) == 0) {
+ cmd_args->log_level = GF_LOG_DEBUG;
break;
+ }
+ if (strcasecmp(arg, ARGP_LOG_LEVEL_TRACE_OPTION) == 0) {
+ cmd_args->log_level = GF_LOG_TRACE;
+ break;
+ }
+
+ argp_failure(state, -1, 0, "unknown log level %s", arg);
+ break;
case ARGP_LOG_FILE_KEY:
- cmd_args->log_file = gf_strdup (arg);
- break;
+ cmd_args->log_file = gf_strdup(arg);
+ break;
case ARGP_VOLFILE_SERVER_PORT_KEY:
- n = 0;
-
- if (gf_string2uint_base10 (arg, &n) == 0) {
- cmd_args->volfile_server_port = n;
- break;
- }
+ n = 0;
- argp_failure (state, -1, 0,
- "unknown volfile server port %s", arg);
+ if (gf_string2uint_base10(arg, &n) == 0) {
+ cmd_args->volfile_server_port = n;
break;
+ }
+
+ argp_failure(state, -1, 0, "unknown volfile server port %s", arg);
+ break;
case ARGP_VOLFILE_SERVER_TRANSPORT_KEY:
- cmd_args->volfile_server_transport = gf_strdup (arg);
- break;
+ cmd_args->volfile_server_transport = gf_strdup(arg);
+ break;
case ARGP_VOLFILE_ID_KEY:
- cmd_args->volfile_id = gf_strdup (arg);
- break;
+ cmd_args->volfile_id = gf_strdup(arg);
+ break;
+
+ case ARGP_THIN_CLIENT_KEY:
+ cmd_args->thin_client = _gf_true;
+ break;
+
+ case ARGP_BRICK_MUX_KEY:
+ cmd_args->brick_mux = _gf_true;
+ break;
case ARGP_PID_FILE_KEY:
- cmd_args->pid_file = gf_strdup (arg);
- break;
+ cmd_args->pid_file = gf_strdup(arg);
+ break;
case ARGP_SOCK_FILE_KEY:
- cmd_args->sock_file = gf_strdup (arg);
- break;
+ cmd_args->sock_file = gf_strdup(arg);
+ break;
case ARGP_NO_DAEMON_KEY:
- cmd_args->no_daemon_mode = ENABLE_NO_DAEMON_MODE;
- break;
+ cmd_args->no_daemon_mode = ENABLE_NO_DAEMON_MODE;
+ break;
case ARGP_RUN_ID_KEY:
- cmd_args->run_id = gf_strdup (arg);
- break;
+ cmd_args->run_id = gf_strdup(arg);
+ break;
case ARGP_DEBUG_KEY:
- cmd_args->debug_mode = ENABLE_DEBUG_MODE;
- break;
+ cmd_args->debug_mode = ENABLE_DEBUG_MODE;
+ break;
case ARGP_VOLFILE_MAX_FETCH_ATTEMPTS:
- cmd_args->max_connect_attempts = 1;
- break;
+ cmd_args->max_connect_attempts = 1;
+ break;
case ARGP_DIRECT_IO_MODE_KEY:
- if (!arg)
- arg = "on";
+ if (!arg)
+ arg = "on";
- if (gf_string2boolean (arg, &b) == 0) {
- cmd_args->fuse_direct_io_mode = b;
+ if (gf_string2boolean(arg, &b) == 0) {
+ cmd_args->fuse_direct_io_mode = b;
- break;
- }
+ break;
+ }
- argp_failure (state, -1, 0,
- "unknown direct I/O mode setting \"%s\"", arg);
+ if (strcmp(arg, "auto") == 0)
break;
+ argp_failure(state, -1, 0, "unknown direct I/O mode setting \"%s\"",
+ arg);
+ break;
+
case ARGP_FUSE_NO_ROOT_SQUASH_KEY:
- cmd_args->no_root_squash = _gf_true;
- break;
+ cmd_args->no_root_squash = _gf_true;
+ break;
case ARGP_ENTRY_TIMEOUT_KEY:
- d = 0.0;
-
- gf_string2double (arg, &d);
- if (!(d < 0.0)) {
- cmd_args->fuse_entry_timeout = d;
- break;
- }
+ d = 0.0;
- argp_failure (state, -1, 0, "unknown entry timeout %s", arg);
+ gf_string2double(arg, &d);
+ if (!(d < 0.0)) {
+ cmd_args->fuse_entry_timeout = d;
break;
+ }
- case ARGP_NEGATIVE_TIMEOUT_KEY:
- d = 0.0;
+ argp_failure(state, -1, 0, "unknown entry timeout %s", arg);
+ break;
- ret = gf_string2double (arg, &d);
- if ((ret == 0) && !(d < 0.0)) {
- cmd_args->fuse_negative_timeout = d;
- break;
- }
+ case ARGP_NEGATIVE_TIMEOUT_KEY:
+ d = 0.0;
- argp_failure (state, -1, 0, "unknown negative timeout %s", arg);
+ ret = gf_string2double(arg, &d);
+ if ((ret == 0) && !(d < 0.0)) {
+ cmd_args->fuse_negative_timeout = d;
break;
+ }
- case ARGP_ATTRIBUTE_TIMEOUT_KEY:
- d = 0.0;
+ argp_failure(state, -1, 0, "unknown negative timeout %s", arg);
+ break;
- gf_string2double (arg, &d);
- if (!(d < 0.0)) {
- cmd_args->fuse_attribute_timeout = d;
- break;
- }
+ case ARGP_ATTRIBUTE_TIMEOUT_KEY:
+ d = 0.0;
- argp_failure (state, -1, 0,
- "unknown attribute timeout %s", arg);
+ gf_string2double(arg, &d);
+ if (!(d < 0.0)) {
+ cmd_args->fuse_attribute_timeout = d;
break;
+ }
- case ARGP_CLIENT_PID_KEY:
- if (gf_string2int (arg, &cmd_args->client_pid) == 0) {
- cmd_args->client_pid_set = 1;
- break;
- }
+ argp_failure(state, -1, 0, "unknown attribute timeout %s", arg);
+ break;
- argp_failure (state, -1, 0,
- "unknown client pid %s", arg);
+ case ARGP_CLIENT_PID_KEY:
+ if (gf_string2int(arg, &cmd_args->client_pid) == 0) {
+ cmd_args->client_pid_set = 1;
break;
+ }
+
+ argp_failure(state, -1, 0, "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;
+ 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;
+ cmd_args->volfile_check = 1;
+ break;
case ARGP_VOLUME_NAME_KEY:
- cmd_args->volume_name = gf_strdup (arg);
- break;
+ cmd_args->volume_name = gf_strdup(arg);
+ break;
case ARGP_XLATOR_OPTION_KEY:
- if (gf_remember_xlator_option (arg))
- argp_failure (state, -1, 0, "invalid xlator option %s",
- arg);
+ if (gf_remember_xlator_option(arg))
+ argp_failure(state, -1, 0, "invalid xlator option %s", arg);
- break;
+ break;
case ARGP_KEY_NO_ARGS:
- break;
+ break;
case ARGP_KEY_ARG:
- if (state->arg_num >= 1)
- argp_usage (state);
-
- cmd_args->mount_point = gf_strdup (arg);
- break;
+ if (state->arg_num >= 1)
+ argp_usage(state);
+ cmd_args->mount_point = gf_strdup(arg);
+ break;
case ARGP_DUMP_FUSE_KEY:
- cmd_args->dump_fuse = gf_strdup (arg);
- break;
+ cmd_args->dump_fuse = gf_strdup(arg);
+ break;
case ARGP_BRICK_NAME_KEY:
- cmd_args->brick_name = gf_strdup (arg);
- break;
+ cmd_args->brick_name = gf_strdup(arg);
+ break;
case ARGP_BRICK_PORT_KEY:
- 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);
+ n = 0;
+
+ if (arg != NULL) {
+ 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;
}
- 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;
+ 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 */
- //gf_mem_acct_enable_set (THIS->ctx);
- break;
+ /* TODO: it should have got handled much earlier */
+ // gf_mem_acct_enable_set (THIS->ctx);
+ break;
- case ARGP_FOPEN_KEEP_CACHE_KEY:
- if (!arg)
- arg = "on";
+ case ARGP_FOPEN_KEEP_CACHE_KEY:
+ if (!arg)
+ arg = "on";
- if (gf_string2boolean (arg, &b) == 0) {
- cmd_args->fopen_keep_cache = b;
+ if (gf_string2boolean(arg, &b) == 0) {
+ cmd_args->fopen_keep_cache = b;
- break;
- }
+ break;
+ }
- argp_failure (state, -1, 0,
- "unknown cache setting \"%s\"", arg);
+ argp_failure(state, -1, 0, "unknown cache setting \"%s\"", arg);
- break;
+ break;
case ARGP_GLOBAL_TIMER_WHEEL:
- cmd_args->global_timer_wheel = 1;
- break;
+ cmd_args->global_timer_wheel = 1;
+ break;
- case ARGP_GID_TIMEOUT_KEY:
- if (!gf_string2int(arg, &cmd_args->gid_timeout)) {
- cmd_args->gid_timeout_set = _gf_true;
- break;
- }
+ case ARGP_GID_TIMEOUT_KEY:
+ if (!gf_string2int(arg, &cmd_args->gid_timeout)) {
+ cmd_args->gid_timeout_set = _gf_true;
+ break;
+ }
- argp_failure(state, -1, 0, "unknown group list timeout %s", arg);
- break;
+ argp_failure(state, -1, 0, "unknown group list timeout %s", arg);
+ break;
case ARGP_RESOLVE_GIDS_KEY:
- cmd_args->resolve_gids = 1;
+ cmd_args->resolve_gids = 1;
+ break;
+
+ case ARGP_FUSE_LRU_LIMIT_KEY:
+ if (!gf_string2int32(arg, &cmd_args->lru_limit))
break;
- case ARGP_FUSE_BACKGROUND_QLEN_KEY:
- if (!gf_string2int (arg, &cmd_args->background_qlen))
- break;
+ argp_failure(state, -1, 0, "unknown LRU limit option %s", arg);
+ break;
+
+ case ARGP_FUSE_INVALIDATE_LIMIT_KEY:
+ if (!gf_string2int32(arg, &cmd_args->invalidate_limit))
+ break;
+
+ argp_failure(state, -1, 0, "unknown invalidate limit option %s",
+ arg);
+ break;
- argp_failure (state, -1, 0,
- "unknown background qlen option %s", arg);
+ case ARGP_FUSE_BACKGROUND_QLEN_KEY:
+ if (!gf_string2int(arg, &cmd_args->background_qlen))
break;
+
+ argp_failure(state, -1, 0, "unknown background qlen option %s",
+ arg);
+ break;
case ARGP_FUSE_CONGESTION_THRESHOLD_KEY:
- if (!gf_string2int (arg, &cmd_args->congestion_threshold))
- break;
+ if (!gf_string2int(arg, &cmd_args->congestion_threshold))
+ break;
+
+ argp_failure(state, -1, 0, "unknown congestion threshold option %s",
+ arg);
+ break;
+
+#ifdef GF_LINUX_HOST_OS
+ case ARGP_OOM_SCORE_ADJ_KEY:
+ k = 0;
- argp_failure (state, -1, 0,
- "unknown congestion threshold option %s", arg);
+ api = get_oom_api_info();
+ if (!api)
+ goto no_oom_api;
+
+ if (gf_string2int(arg, &k) == 0 && k >= api->oom_min &&
+ k <= api->oom_max) {
+ cmd_args->oom_score_adj = gf_strdup(arg);
break;
+ }
+
+ argp_failure(state, -1, 0, "unknown oom_score_adj value %s", arg);
+
+ no_oom_api:
+ break;
+#endif
case ARGP_FUSE_MOUNTOPTS_KEY:
- cmd_args->fuse_mountopts = gf_strdup (arg);
- break;
+ cmd_args->fuse_mountopts = gf_strdup(arg);
+ break;
case ARGP_FUSE_USE_READDIRP_KEY:
- if (!arg)
- arg = "yes";
-
- if (gf_string2boolean (arg, &b) == 0) {
- if (b) {
- cmd_args->use_readdirp = "yes";
- } else {
- cmd_args->use_readdirp = "no";
- }
+ if (!arg)
+ arg = "yes";
- break;
+ if (gf_string2boolean(arg, &b) == 0) {
+ if (b) {
+ cmd_args->use_readdirp = "yes";
+ } else {
+ cmd_args->use_readdirp = "no";
}
- argp_failure (state, -1, 0,
- "unknown use-readdirp setting \"%s\"", arg);
break;
+ }
+
+ argp_failure(state, -1, 0, "unknown use-readdirp setting \"%s\"",
+ arg);
+ break;
case ARGP_LOGGER:
- if (strcasecmp (arg, GF_LOGGER_GLUSTER_LOG) == 0)
- cmd_args->logger = gf_logger_glusterlog;
- else if (strcasecmp (arg, GF_LOGGER_SYSLOG) == 0)
- cmd_args->logger = gf_logger_syslog;
- else
- argp_failure (state, -1, 0, "unknown logger %s", arg);
+ if (strcasecmp(arg, GF_LOGGER_GLUSTER_LOG) == 0)
+ cmd_args->logger = gf_logger_glusterlog;
+ else if (strcasecmp(arg, GF_LOGGER_SYSLOG) == 0)
+ cmd_args->logger = gf_logger_syslog;
+ else
+ argp_failure(state, -1, 0, "unknown logger %s", arg);
- break;
+ break;
case ARGP_LOG_FORMAT:
- if (strcasecmp (arg, GF_LOG_FORMAT_NO_MSG_ID) == 0)
- cmd_args->log_format = gf_logformat_traditional;
- else if (strcasecmp (arg, GF_LOG_FORMAT_WITH_MSG_ID) == 0)
- cmd_args->log_format = gf_logformat_withmsgid;
- else
- argp_failure (state, -1, 0, "unknown log format %s",
- arg);
+ if (strcasecmp(arg, GF_LOG_FORMAT_NO_MSG_ID) == 0)
+ cmd_args->log_format = gf_logformat_traditional;
+ else if (strcasecmp(arg, GF_LOG_FORMAT_WITH_MSG_ID) == 0)
+ cmd_args->log_format = gf_logformat_withmsgid;
+ else
+ argp_failure(state, -1, 0, "unknown log format %s", arg);
- break;
+ break;
case ARGP_LOG_BUF_SIZE:
- if (gf_string2uint32 (arg, &cmd_args->log_buf_size)) {
- argp_failure (state, -1, 0,
- "unknown log buf size option %s", arg);
- } else if ((cmd_args->log_buf_size < GF_LOG_LRU_BUFSIZE_MIN) ||
- (cmd_args->log_buf_size > GF_LOG_LRU_BUFSIZE_MAX)) {
- argp_failure (state, -1, 0,
- "Invalid log buf size %s. "
- "Valid range: ["
- GF_LOG_LRU_BUFSIZE_MIN_STR","
- GF_LOG_LRU_BUFSIZE_MAX_STR"]", arg);
+ if (gf_string2uint32(arg, &cmd_args->log_buf_size)) {
+ argp_failure(state, -1, 0, "unknown log buf size option %s",
+ arg);
+ } else if (cmd_args->log_buf_size > GF_LOG_LRU_BUFSIZE_MAX) {
+ argp_failure(state, -1, 0,
+ "Invalid log buf size %s. "
+ "Valid range: [" GF_LOG_LRU_BUFSIZE_MIN_STR
+ "," GF_LOG_LRU_BUFSIZE_MAX_STR "]",
+ arg);
+ }
+
+ break;
+
+ case ARGP_LOG_FLUSH_TIMEOUT:
+ if (gf_string2uint32(arg, &cmd_args->log_flush_timeout)) {
+ argp_failure(state, -1, 0,
+ "unknown log flush timeout option %s", arg);
+ } else if ((cmd_args->log_flush_timeout <
+ GF_LOG_FLUSH_TIMEOUT_MIN) ||
+ (cmd_args->log_flush_timeout >
+ GF_LOG_FLUSH_TIMEOUT_MAX)) {
+ argp_failure(state, -1, 0,
+ "Invalid log flush timeout %s. "
+ "Valid range: [" GF_LOG_FLUSH_TIMEOUT_MIN_STR
+ "," GF_LOG_FLUSH_TIMEOUT_MAX_STR "]",
+ arg);
+ }
+
+ break;
+
+ case ARGP_SECURE_MGMT_KEY:
+ if (!arg)
+ arg = "yes";
+
+ if (gf_string2boolean(arg, &b) == 0) {
+ cmd_args->secure_mgmt = b ? 1 : 0;
+ break;
+ }
+
+ argp_failure(state, -1, 0, "unknown secure-mgmt setting \"%s\"",
+ arg);
+ break;
+
+ case ARGP_LOCALTIME_LOGGING_KEY:
+ cmd_args->localtime_logging = 1;
+ break;
+ case ARGP_PROCESS_NAME_KEY:
+ cmd_args->process_name = gf_strdup(arg);
+ break;
+ case ARGP_SUBDIR_MOUNT_KEY:
+ if (arg[0] != '/') {
+ argp_failure(state, -1, 0, "expect '/%s', provided just \"%s\"",
+ arg, arg);
+ break;
+ }
+ cmd_args->subdir_mount = gf_strdup(arg);
+ break;
+ case ARGP_FUSE_EVENT_HISTORY_KEY:
+ if (!arg)
+ arg = "no";
+
+ if (gf_string2boolean(arg, &b) == 0) {
+ if (b) {
+ cmd_args->event_history = "yes";
+ } else {
+ cmd_args->event_history = "no";
}
break;
+ }
+
+ argp_failure(state, -1, 0, "unknown event-history setting \"%s\"",
+ arg);
+ break;
+ case ARGP_READER_THREAD_COUNT_KEY:
+ if (gf_string2uint32(arg, &cmd_args->reader_thread_count)) {
+ argp_failure(state, -1, 0,
+ "unknown reader thread count option %s", arg);
+ } else if ((cmd_args->reader_thread_count < 1) ||
+ (cmd_args->reader_thread_count > 64)) {
+ argp_failure(state, -1, 0,
+ "Invalid reader thread count %s. "
+ "Valid range: [\"1, 64\"]",
+ arg);
+ }
+
+ break;
+
+ case ARGP_KERNEL_WRITEBACK_CACHE_KEY:
+ if (!arg)
+ arg = "yes";
+
+ if (gf_string2boolean(arg, &b) == 0) {
+ cmd_args->kernel_writeback_cache = b;
- case ARGP_LOG_FLUSH_TIMEOUT:
- if (gf_string2uint32 (arg, &cmd_args->log_flush_timeout)) {
- argp_failure (state, -1, 0,
- "unknown log flush timeout option %s", arg);
- } else if ((cmd_args->log_flush_timeout <
- GF_LOG_FLUSH_TIMEOUT_MIN) ||
- (cmd_args->log_flush_timeout >
- GF_LOG_FLUSH_TIMEOUT_MAX)) {
- argp_failure (state, -1, 0,
- "Invalid log flush timeout %s. "
- "Valid range: ["
- GF_LOG_FLUSH_TIMEOUT_MIN_STR","
- GF_LOG_FLUSH_TIMEOUT_MAX_STR"]", arg);
- }
+ break;
+ }
+
+ argp_failure(state, -1, 0,
+ "unknown kernel writeback cache setting \"%s\"", arg);
+ break;
+ case ARGP_ATTR_TIMES_GRANULARITY_KEY:
+ if (gf_string2uint32(arg, &cmd_args->attr_times_granularity)) {
+ argp_failure(state, -1, 0,
+ "unknown attribute times granularity option %s",
+ arg);
+ } else if (cmd_args->attr_times_granularity > 1000000000) {
+ argp_failure(state, -1, 0,
+ "Invalid attribute times granularity value %s. "
+ "Valid range: [\"0, 1000000000\"]",
+ arg);
+ }
+
+ break;
+
+ case ARGP_FUSE_FLUSH_HANDLE_INTERRUPT_KEY:
+ if (!arg)
+ arg = "yes";
+
+ if (gf_string2boolean(arg, &b) == 0) {
+ cmd_args->fuse_flush_handle_interrupt = b;
break;
+ }
- case ARGP_SECURE_MGMT_KEY:
- if (!arg)
- arg = "yes";
+ argp_failure(state, -1, 0,
+ "unknown fuse flush handle interrupt setting \"%s\"",
+ arg);
+ break;
- if (gf_string2boolean (arg, &b) == 0) {
- cmd_args->secure_mgmt = b ? 1 : 0;
- break;
- }
+ case ARGP_FUSE_AUTO_INVAL_KEY:
+ if (!arg)
+ arg = "yes";
- argp_failure (state, -1, 0,
- "unknown secure-mgmt setting \"%s\"", arg);
+ if (gf_string2boolean(arg, &b) == 0) {
+ cmd_args->fuse_auto_inval = b;
break;
- }
+ }
- return 0;
+ break;
+
+ case ARGP_GLOBAL_THREADING_KEY:
+ if (!arg || (*arg == 0)) {
+ arg = "yes";
+ }
+
+ if (gf_string2boolean(arg, &b) == 0) {
+ cmd_args->global_threading = b;
+ break;
+ }
+
+ argp_failure(state, -1, 0,
+ "Invalid value for global threading \"%s\"", arg);
+ break;
+
+ case ARGP_FUSE_DEV_EPERM_RATELIMIT_NS_KEY:
+ if (gf_string2uint32(arg, &cmd_args->fuse_dev_eperm_ratelimit_ns)) {
+ argp_failure(state, -1, 0,
+ "Non-numerical value for "
+ "'fuse-dev-eperm-ratelimit-ns' option %s",
+ arg);
+ } else if (cmd_args->fuse_dev_eperm_ratelimit_ns > 1000000000) {
+ argp_failure(state, -1, 0,
+ "Invalid 'fuse-dev-eperm-ratelimit-ns' value %s. "
+ "Valid range: [\"0, 1000000000\"]",
+ arg);
+ }
+
+ break;
+ }
+ return 0;
}
+gf_boolean_t
+should_call_fini(glusterfs_ctx_t *ctx, xlator_t *trav)
+{
+ /* There's nothing to call, so the other checks don't matter. */
+ if (!trav->fini) {
+ return _gf_false;
+ }
+
+ /* This preserves previous behavior in glusterd. */
+ if (ctx->process_mode == GF_GLUSTERD_PROCESS) {
+ return _gf_true;
+ }
+
+ return _gf_false;
+}
void
-cleanup_and_exit (int signum)
+cleanup_and_exit(int signum)
{
- glusterfs_ctx_t *ctx = NULL;
- xlator_t *trav = NULL;
-
- ctx = glusterfsd_ctx;
-
- if (!ctx)
- return;
-
- /* To take or not to take the mutex here and in the other
- * signal handler - gf_print_trace() - is the big question here.
- *
- * Taking mutex in signal handler would mean that if the process
- * receives a fatal signal while another thread is holding
- * ctx->log.log_buf_lock to perhaps log a message in _gf_msg_internal(),
- * the offending thread hangs on the mutex lock forever without letting
- * the process exit.
- *
- * On the other hand. not taking the mutex in signal handler would cause
- * it to modify the lru_list of buffered log messages in a racy manner,
- * corrupt the list and potentially give rise to an unending
- * cascade of SIGSEGVs and other re-entrancy issues.
- */
-
- gf_log_disable_suppression_before_exit (ctx);
+ glusterfs_ctx_t *ctx = NULL;
+ xlator_t *trav = NULL;
+ xlator_t *top;
+ xlator_t *victim;
+ xlator_list_t **trav_p;
- gf_msg_callingfn ("", GF_LOG_WARNING, 0, glusterfsd_msg_32, signum);
+ ctx = glusterfsd_ctx;
- if (ctx->cleanup_started)
- return;
+ if (!ctx)
+ return;
+ /* To take or not to take the mutex here and in the other
+ * signal handler - gf_print_trace() - is the big question here.
+ *
+ * Taking mutex in signal handler would mean that if the process
+ * receives a fatal signal while another thread is holding
+ * ctx->log.log_buf_lock to perhaps log a message in _gf_msg_internal(),
+ * the offending thread hangs on the mutex lock forever without letting
+ * the process exit.
+ *
+ * On the other hand. not taking the mutex in signal handler would cause
+ * it to modify the lru_list of buffered log messages in a racy manner,
+ * corrupt the list and potentially give rise to an unending
+ * cascade of SIGSEGVs and other re-entrancy issues.
+ */
+
+ gf_log_disable_suppression_before_exit(ctx);
+
+ gf_msg_callingfn("", GF_LOG_WARNING, 0, glusterfsd_msg_32,
+ "received signum (%d), shutting down", signum);
+
+ if (ctx->cleanup_started)
+ return;
+ pthread_mutex_lock(&ctx->cleanup_lock);
+ {
ctx->cleanup_started = 1;
- glusterfs_mgmt_pmap_signout (ctx);
+
+ /* signout should be sent to all the bricks in case brick mux is enabled
+ * and multiple brick instances are attached to this process
+ */
+ if (ctx->active) {
+ top = ctx->active->first;
+ for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) {
+ victim = (*trav_p)->xlator;
+ rpc_clnt_mgmt_pmap_signout(ctx, victim->name);
+ }
+ } else {
+ rpc_clnt_mgmt_pmap_signout(ctx, NULL);
+ }
/* below part is a racy code where the rpcsvc object is freed.
* But in another thread (epoll thread), upon poll error in the
* socket the transports are cleaned up where again rpcsvc object
* is accessed (which is already freed by the below function).
- * Since the process is about to be killed dont execute the function
+ * Since the process is about to be killed don't execute the function
* below.
*/
/* if (ctx->listener) { */
@@ -1252,11 +1467,11 @@ cleanup_and_exit (int signum)
* 'umount' of mount point is done properly */
trav = ctx->master;
if (trav && trav->fini) {
- THIS = trav;
- trav->fini (trav);
+ THIS = trav;
+ trav->fini(trav);
}
- glusterfs_pidfile_cleanup (ctx);
+ glusterfs_pidfile_cleanup(ctx);
#if 0
/* TODO: Properly do cleanup_and_exit(), with synchronization */
@@ -1267,299 +1482,308 @@ cleanup_and_exit (int signum)
}
#endif
- /* call fini() of each xlator */
-
- /*call fini for glusterd xlator */
- /* TODO : Invoke fini for rest of the xlators */
- if (ctx->process_mode == GF_GLUSTERD_PROCESS) {
+ trav = NULL;
- trav = NULL;
- if (ctx->active)
- trav = ctx->active->top;
- while (trav) {
- if (trav->fini) {
- THIS = trav;
- trav->fini (trav);
- }
- trav = trav->next;
- }
-
- }
- exit(0);
+ /* previously we were releasing the cleanup mutex lock before the
+ process exit. As we are releasing the cleanup mutex lock, before
+ the process can exit some other thread which is blocked on
+ cleanup mutex lock is acquiring the cleanup mutex lock and
+ trying to acquire some resources which are already freed as a
+ part of cleanup. To avoid this, we are exiting the process without
+ releasing the cleanup mutex lock. This will not cause any lock
+ related issues as the process which acquired the lock is going down
+ */
+ /* NOTE: Only the least significant 8 bits i.e (signum & 255)
+ will be available to parent process on calling exit() */
+ exit(abs(signum));
+ }
}
-
static void
-reincarnate (int signum)
+reincarnate(int signum)
{
- int ret = 0;
- glusterfs_ctx_t *ctx = NULL;
- cmd_args_t *cmd_args = NULL;
+ int ret = 0;
+ glusterfs_ctx_t *ctx = NULL;
+ cmd_args_t *cmd_args = NULL;
- ctx = glusterfsd_ctx;
- cmd_args = &ctx->cmd_args;
+ ctx = glusterfsd_ctx;
+ cmd_args = &ctx->cmd_args;
- if (cmd_args->volfile_server) {
- gf_msg ("glusterfsd", GF_LOG_INFO, 0, glusterfsd_msg_11);
- ret = glusterfs_volfile_fetch (ctx);
- } else {
- gf_msg_debug ("glusterfsd", 0,
- "Not reloading volume specification file"
- " on SIGHUP");
- }
+ gf_msg_trace("gluster", 0, "received reincarnate request (sig:HUP)");
- /* Also, SIGHUP should do logrotate */
- gf_log_logrotate (1);
+ if (cmd_args->volfile_server) {
+ gf_smsg("glusterfsd", GF_LOG_INFO, 0, glusterfsd_msg_11, NULL);
+ ret = glusterfs_volfile_fetch(ctx);
+ }
- if (ret < 0)
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_12);
+ /* Also, SIGHUP should do logrotate */
+ gf_log_logrotate(1);
- return;
+ if (ret < 0)
+ gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_12, NULL);
+
+ return;
}
void
-emancipate (glusterfs_ctx_t *ctx, int ret)
+emancipate(glusterfs_ctx_t *ctx, int ret)
{
- /* break free from the parent */
- if (ctx->daemon_pipe[1] != -1) {
- write (ctx->daemon_pipe[1], (void *) &ret, sizeof (ret));
- close (ctx->daemon_pipe[1]);
- ctx->daemon_pipe[1] = -1;
- }
+ /* break free from the parent */
+ if (ctx->daemon_pipe[1] != -1) {
+ sys_write(ctx->daemon_pipe[1], (void *)&ret, sizeof(ret));
+ sys_close(ctx->daemon_pipe[1]);
+ ctx->daemon_pipe[1] = -1;
+ }
}
static uint8_t
-gf_get_process_mode (char *exec_name)
+gf_get_process_mode(char *exec_name)
{
- char *dup_execname = NULL, *base = NULL;
- uint8_t ret = 0;
+ char *dup_execname = NULL, *base = NULL;
+ uint8_t ret = 0;
- dup_execname = gf_strdup (exec_name);
- base = basename (dup_execname);
+ dup_execname = gf_strdup(exec_name);
+ base = basename(dup_execname);
- if (!strncmp (base, "glusterfsd", 10)) {
- ret = GF_SERVER_PROCESS;
- } else if (!strncmp (base, "glusterd", 8)) {
- ret = GF_GLUSTERD_PROCESS;
- } else {
- ret = GF_CLIENT_PROCESS;
- }
+ if (!strncmp(base, "glusterfsd", 10)) {
+ ret = GF_SERVER_PROCESS;
+ } else if (!strncmp(base, "glusterd", 8)) {
+ ret = GF_GLUSTERD_PROCESS;
+ } else {
+ ret = GF_CLIENT_PROCESS;
+ }
- GF_FREE (dup_execname);
+ GF_FREE(dup_execname);
- return ret;
+ return ret;
}
-
static int
-glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
+glusterfs_ctx_defaults_init(glusterfs_ctx_t *ctx)
{
- cmd_args_t *cmd_args = NULL;
- struct rlimit lim = {0, };
- int ret = -1;
-
- ret = xlator_mem_acct_init (THIS, gfd_mt_end);
- if (ret != 0) {
- gf_msg(THIS->name, GF_LOG_CRITICAL, 0, glusterfsd_msg_34);
- return ret;
- }
-
- /* reset ret to -1 so that we don't need to explicitly
- * set it in all error paths before "goto err"
- */
- ret = -1;
-
- ctx->process_uuid = generate_glusterfs_ctx_id ();
- if (!ctx->process_uuid) {
- gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_13);
- goto out;
- }
-
- ctx->page_size = 128 * GF_UNIT_KB;
-
- ctx->iobuf_pool = iobuf_pool_new ();
- if (!ctx->iobuf_pool) {
- gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "iobuf");
- goto out;
- }
-
- ctx->event_pool = event_pool_new (DEFAULT_EVENT_POOL_SIZE,
- STARTING_EVENT_THREADS);
- if (!ctx->event_pool) {
- gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "event");
- goto out;
- }
-
- ctx->pool = GF_CALLOC (1, sizeof (call_pool_t), gfd_mt_call_pool_t);
- if (!ctx->pool) {
- gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "call");
- goto out;
- }
-
- INIT_LIST_HEAD (&ctx->pool->all_frames);
- LOCK_INIT (&ctx->pool->lock);
-
- /* frame_mem_pool size 112 * 4k */
- ctx->pool->frame_mem_pool = mem_pool_new (call_frame_t, 4096);
- if (!ctx->pool->frame_mem_pool) {
- gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "frame");
- goto out;
- }
- /* stack_mem_pool size 256 * 1024 */
- ctx->pool->stack_mem_pool = mem_pool_new (call_stack_t, 1024);
- if (!ctx->pool->stack_mem_pool) {
- gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "stack");
- goto out;
- }
-
- ctx->stub_mem_pool = mem_pool_new (call_stub_t, 1024);
- if (!ctx->stub_mem_pool) {
- gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "stub");
- goto out;
- }
-
- ctx->dict_pool = mem_pool_new (dict_t, GF_MEMPOOL_COUNT_OF_DICT_T);
- if (!ctx->dict_pool)
- goto out;
-
- ctx->dict_pair_pool = mem_pool_new (data_pair_t,
- GF_MEMPOOL_COUNT_OF_DATA_PAIR_T);
- if (!ctx->dict_pair_pool)
- goto out;
-
- ctx->dict_data_pool = mem_pool_new (data_t, GF_MEMPOOL_COUNT_OF_DATA_T);
- if (!ctx->dict_data_pool)
- goto out;
-
- ctx->logbuf_pool = mem_pool_new (log_buf_t,
- GF_MEMPOOL_COUNT_OF_LRU_BUF_T);
- if (!ctx->logbuf_pool)
- goto out;
+ cmd_args_t *cmd_args = NULL;
+ struct rlimit lim = {
+ 0,
+ };
+ int ret = -1;
- pthread_mutex_init (&(ctx->lock), NULL);
- pthread_mutex_init (&ctx->notify_lock, NULL);
- pthread_cond_init (&ctx->notify_cond, NULL);
-
- ctx->clienttable = gf_clienttable_alloc();
- if (!ctx->clienttable)
- goto out;
-
- cmd_args = &ctx->cmd_args;
-
- /* parsing command line arguments */
- cmd_args->log_level = DEFAULT_LOG_LEVEL;
- cmd_args->logger = gf_logger_glusterlog;
- cmd_args->log_format = gf_logformat_withmsgid;
- cmd_args->log_buf_size = GF_LOG_LRU_BUFSIZE_DEFAULT;
- cmd_args->log_flush_timeout = GF_LOG_FLUSH_TIMEOUT_DEFAULT;
+ if (!ctx)
+ return ret;
- cmd_args->mac_compat = GF_OPTION_DISABLE;
+ ret = xlator_mem_acct_init(THIS, gfd_mt_end);
+ if (ret != 0) {
+ gf_smsg(THIS->name, GF_LOG_CRITICAL, 0, glusterfsd_msg_34, NULL);
+ return ret;
+ }
+
+ /* reset ret to -1 so that we don't need to explicitly
+ * set it in all error paths before "goto err"
+ */
+ ret = -1;
+
+ /* monitoring should be enabled by default */
+ ctx->measure_latency = true;
+
+ ctx->process_uuid = generate_glusterfs_ctx_id();
+ if (!ctx->process_uuid) {
+ gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_13, NULL);
+ goto out;
+ }
+
+ ctx->page_size = 128 * GF_UNIT_KB;
+
+ ctx->iobuf_pool = iobuf_pool_new();
+ if (!ctx->iobuf_pool) {
+ gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "iobuf", NULL);
+ goto out;
+ }
+
+ ctx->event_pool = gf_event_pool_new(DEFAULT_EVENT_POOL_SIZE,
+ STARTING_EVENT_THREADS);
+ if (!ctx->event_pool) {
+ gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "event", NULL);
+ goto out;
+ }
+
+ ctx->pool = GF_CALLOC(1, sizeof(call_pool_t), gfd_mt_call_pool_t);
+ if (!ctx->pool) {
+ gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "call", NULL);
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&ctx->pool->all_frames);
+ LOCK_INIT(&ctx->pool->lock);
+
+ /* frame_mem_pool size 112 * 4k */
+ ctx->pool->frame_mem_pool = mem_pool_new(call_frame_t, 4096);
+ if (!ctx->pool->frame_mem_pool) {
+ gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "frame", NULL);
+ goto out;
+ }
+ /* stack_mem_pool size 256 * 1024 */
+ ctx->pool->stack_mem_pool = mem_pool_new(call_stack_t, 1024);
+ if (!ctx->pool->stack_mem_pool) {
+ gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "stack", NULL);
+ goto out;
+ }
+
+ ctx->stub_mem_pool = mem_pool_new(call_stub_t, 1024);
+ if (!ctx->stub_mem_pool) {
+ gf_smsg("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "stub", NULL);
+ goto out;
+ }
+
+ ctx->dict_pool = mem_pool_new(dict_t, GF_MEMPOOL_COUNT_OF_DICT_T);
+ if (!ctx->dict_pool)
+ goto out;
+
+ ctx->dict_pair_pool = mem_pool_new(data_pair_t,
+ GF_MEMPOOL_COUNT_OF_DATA_PAIR_T);
+ if (!ctx->dict_pair_pool)
+ goto out;
+
+ ctx->dict_data_pool = mem_pool_new(data_t, GF_MEMPOOL_COUNT_OF_DATA_T);
+ if (!ctx->dict_data_pool)
+ goto out;
+
+ ctx->logbuf_pool = mem_pool_new(log_buf_t, GF_MEMPOOL_COUNT_OF_LRU_BUF_T);
+ if (!ctx->logbuf_pool)
+ goto out;
+
+ pthread_mutex_init(&ctx->notify_lock, NULL);
+ pthread_mutex_init(&ctx->cleanup_lock, NULL);
+ pthread_cond_init(&ctx->notify_cond, NULL);
+
+ ctx->clienttable = gf_clienttable_alloc();
+ if (!ctx->clienttable)
+ goto out;
+
+ cmd_args = &ctx->cmd_args;
+
+ /* parsing command line arguments */
+ cmd_args->log_level = DEFAULT_LOG_LEVEL;
+ cmd_args->logger = gf_logger_glusterlog;
+ cmd_args->log_format = gf_logformat_withmsgid;
+ cmd_args->log_buf_size = GF_LOG_LRU_BUFSIZE_DEFAULT;
+ cmd_args->log_flush_timeout = GF_LOG_FLUSH_TIMEOUT_DEFAULT;
+
+ cmd_args->mac_compat = GF_OPTION_DISABLE;
#ifdef GF_DARWIN_HOST_OS
- /* On Darwin machines, O_APPEND is not handled,
- * which may corrupt the data
- */
- cmd_args->fuse_direct_io_mode = GF_OPTION_DISABLE;
+ /* 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->fuse_direct_io_mode = GF_OPTION_DEFERRED;
+ cmd_args->fuse_direct_io_mode = GF_OPTION_DEFERRED;
#endif
- cmd_args->fuse_attribute_timeout = -1;
- cmd_args->fuse_entry_timeout = -1;
- cmd_args->fopen_keep_cache = GF_OPTION_DEFERRED;
-
- if (ctx->mem_acct_enable)
- cmd_args->mem_acct = 1;
-
- INIT_LIST_HEAD (&cmd_args->xlator_options);
- INIT_LIST_HEAD (&cmd_args->volfile_servers);
-
- lim.rlim_cur = RLIM_INFINITY;
- lim.rlim_max = RLIM_INFINITY;
- setrlimit (RLIMIT_CORE, &lim);
-
- ret = 0;
+ cmd_args->fuse_attribute_timeout = -1;
+ cmd_args->fuse_entry_timeout = -1;
+ cmd_args->fopen_keep_cache = GF_OPTION_DEFERRED;
+ cmd_args->kernel_writeback_cache = GF_OPTION_DEFERRED;
+ cmd_args->fuse_flush_handle_interrupt = GF_OPTION_DEFERRED;
+
+ if (ctx->mem_acct_enable)
+ cmd_args->mem_acct = 1;
+
+ INIT_LIST_HEAD(&cmd_args->xlator_options);
+ INIT_LIST_HEAD(&cmd_args->volfile_servers);
+ ctx->pxl_count = 0;
+ pthread_mutex_init(&ctx->fd_lock, NULL);
+ pthread_cond_init(&ctx->fd_cond, NULL);
+ INIT_LIST_HEAD(&ctx->janitor_fds);
+
+ lim.rlim_cur = RLIM_INFINITY;
+ lim.rlim_max = RLIM_INFINITY;
+ setrlimit(RLIMIT_CORE, &lim);
+
+ ret = 0;
out:
- if (ret && ctx) {
- if (ctx->pool) {
- mem_pool_destroy (ctx->pool->frame_mem_pool);
- mem_pool_destroy (ctx->pool->stack_mem_pool);
- }
- GF_FREE (ctx->pool);
- mem_pool_destroy (ctx->stub_mem_pool);
- mem_pool_destroy (ctx->dict_pool);
- mem_pool_destroy (ctx->dict_data_pool);
- mem_pool_destroy (ctx->dict_pair_pool);
- mem_pool_destroy (ctx->logbuf_pool);
+ if (ret) {
+ if (ctx->pool) {
+ mem_pool_destroy(ctx->pool->frame_mem_pool);
+ mem_pool_destroy(ctx->pool->stack_mem_pool);
}
+ GF_FREE(ctx->pool);
+ mem_pool_destroy(ctx->stub_mem_pool);
+ mem_pool_destroy(ctx->dict_pool);
+ mem_pool_destroy(ctx->dict_data_pool);
+ mem_pool_destroy(ctx->dict_pair_pool);
+ mem_pool_destroy(ctx->logbuf_pool);
+ }
- return ret;
+ return ret;
}
static int
-logging_init (glusterfs_ctx_t *ctx, const char *progpath)
+logging_init(glusterfs_ctx_t *ctx, const char *progpath)
{
- cmd_args_t *cmd_args = NULL;
- int ret = 0;
+ cmd_args_t *cmd_args = NULL;
+ int ret = 0;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- if (cmd_args->log_file == NULL) {
- ret = gf_set_log_file_path (cmd_args);
- if (ret == -1) {
- fprintf (stderr, "ERROR: failed to set the log file "
- "path\n");
- return -1;
- }
+ if (cmd_args->log_file == NULL) {
+ ret = gf_set_log_file_path(cmd_args, ctx);
+ if (ret == -1) {
+ fprintf(stderr,
+ "ERROR: failed to set the log file "
+ "path\n");
+ return -1;
}
+ }
- if (cmd_args->log_ident == NULL) {
- ret = gf_set_log_ident (cmd_args);
- if (ret == -1) {
- fprintf (stderr, "ERROR: failed to set the log "
- "identity\n");
- return -1;
- }
+ if (cmd_args->log_ident == NULL) {
+ ret = gf_set_log_ident(cmd_args);
+ if (ret == -1) {
+ fprintf(stderr,
+ "ERROR: failed to set the log "
+ "identity\n");
+ return -1;
}
+ }
- /* finish log set parameters before init */
- gf_log_set_loglevel (cmd_args->log_level);
+ /* finish log set parameters before init */
+ gf_log_set_loglevel(ctx, cmd_args->log_level);
- gf_log_set_logger (cmd_args->logger);
+ gf_log_set_localtime(cmd_args->localtime_logging);
- gf_log_set_logformat (cmd_args->log_format);
+ gf_log_set_logger(cmd_args->logger);
- gf_log_set_log_buf_size (cmd_args->log_buf_size);
+ gf_log_set_logformat(cmd_args->log_format);
- gf_log_set_log_flush_timeout (cmd_args->log_flush_timeout);
+ gf_log_set_log_buf_size(cmd_args->log_buf_size);
- if (gf_log_init (ctx, cmd_args->log_file, cmd_args->log_ident) == -1) {
- fprintf (stderr, "ERROR: failed to open logfile %s\n",
- cmd_args->log_file);
- return -1;
- }
+ gf_log_set_log_flush_timeout(cmd_args->log_flush_timeout);
- /* At this point, all the logging related parameters are initialised
- * except for the log flush timer, which will be injected post fork(2)
- * in daemonize() . During this time, any log message that is logged
- * will be kept buffered. And if the list that holds these messages
- * overflows, then the same lru policy is used to drive out the least
- * recently used message and displace it with the message just logged.
- */
+ if (gf_log_init(ctx, cmd_args->log_file, cmd_args->log_ident) == -1) {
+ fprintf(stderr, "ERROR: failed to open logfile %s\n",
+ cmd_args->log_file);
+ return -1;
+ }
- return 0;
+ /* At this point, all the logging related parameters are initialised
+ * except for the log flush timer, which will be injected post fork(2)
+ * in daemonize() . During this time, any log message that is logged
+ * will be kept buffered. And if the list that holds these messages
+ * overflows, then the same lru policy is used to drive out the least
+ * recently used message and displace it with the message just logged.
+ */
+
+ return 0;
}
void
-gf_check_and_set_mem_acct (int argc, char *argv[])
+gf_check_and_set_mem_acct(int argc, char *argv[])
{
- int i = 0;
+ int i = 0;
- for (i = 0; i < argc; i++) {
- if (strcmp (argv[i], "--no-mem-accounting") == 0) {
- gf_global_mem_acct_enable_set (0);
- break;
- }
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "--no-mem-accounting") == 0) {
+ gf_global_mem_acct_enable_set(0);
+ break;
}
+ }
}
/**
@@ -1577,87 +1801,85 @@ gf_check_and_set_mem_acct (int argc, char *argv[])
* error messages. Hence there are different return values.
*/
int
-print_exports_file (const char *exports_file)
+print_exports_file(const char *exports_file)
{
- void *libhandle = NULL;
- char *libpathfull = NULL;
- struct exports_file *file = NULL;
- int ret = 0;
-
- int (*exp_file_parse)(const char *filepath,
- struct exports_file **expfile,
- struct mount3_state *ms) = NULL;
- void (*exp_file_print)(const struct exports_file *file) = NULL;
- void (*exp_file_deinit)(struct exports_file *ptr) = NULL;
-
- /* XLATORDIR passed through a -D flag to GCC */
- ret = gf_asprintf (&libpathfull, "%s/%s/server.so", XLATORDIR,
- "nfs");
- if (ret < 0) {
- gf_log ("glusterfs", GF_LOG_CRITICAL, "asprintf () failed.");
- ret = -1;
- goto out;
- }
-
- /* Load up the library */
- libhandle = dlopen (libpathfull, RTLD_NOW);
- if (!libhandle) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "Error loading NFS server library : "
- "%s\n", dlerror ());
- ret = -1;
- goto out;
- }
-
- /* Load up the function */
- exp_file_parse = dlsym (libhandle, "exp_file_parse");
- if (!exp_file_parse) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "Error finding function exp_file_parse "
- "in symbol.");
- ret = -1;
- goto out;
- }
-
- /* Parse the file */
- ret = exp_file_parse (exports_file, &file, NULL);
- if (ret < 0) {
- ret = 1; /* This means we failed to parse */
- goto out;
- }
-
- /* Load up the function */
- exp_file_print = dlsym (libhandle, "exp_file_print");
- if (!exp_file_print) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "Error finding function exp_file_print in symbol.");
- ret = -1;
- goto out;
- }
+ void *libhandle = NULL;
+ char *libpathfull = NULL;
+ struct exports_file *file = NULL;
+ int ret = 0;
+
+ int (*exp_file_parse)(const char *filepath, struct exports_file **expfile,
+ struct mount3_state *ms) = NULL;
+ void (*exp_file_print)(const struct exports_file *file) = NULL;
+ void (*exp_file_deinit)(struct exports_file * ptr) = NULL;
+
+ /* XLATORDIR passed through a -D flag to GCC */
+ ret = gf_asprintf(&libpathfull, "%s/%s/server.so", XLATORDIR, "nfs");
+ if (ret < 0) {
+ gf_log("glusterfs", GF_LOG_CRITICAL, "asprintf () failed.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Load up the library */
+ libhandle = dlopen(libpathfull, RTLD_NOW);
+ if (!libhandle) {
+ gf_log("glusterfs", GF_LOG_CRITICAL,
+ "Error loading NFS server library : "
+ "%s\n",
+ dlerror());
+ ret = -1;
+ goto out;
+ }
+
+ /* Load up the function */
+ exp_file_parse = dlsym(libhandle, "exp_file_parse");
+ if (!exp_file_parse) {
+ gf_log("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function exp_file_parse "
+ "in symbol.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Parse the file */
+ ret = exp_file_parse(exports_file, &file, NULL);
+ if (ret < 0) {
+ ret = 1; /* This means we failed to parse */
+ goto out;
+ }
+
+ /* Load up the function */
+ exp_file_print = dlsym(libhandle, "exp_file_print");
+ if (!exp_file_print) {
+ gf_log("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function exp_file_print in symbol.");
+ ret = -1;
+ goto out;
+ }
- /* Print it out to screen */
- exp_file_print (file);
+ /* Print it out to screen */
+ exp_file_print(file);
- /* Load up the function */
- exp_file_deinit = dlsym (libhandle, "exp_file_deinit");
- if (!exp_file_deinit) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "Error finding function exp_file_deinit in lib.");
- ret = -1;
- goto out;
- }
+ /* Load up the function */
+ exp_file_deinit = dlsym(libhandle, "exp_file_deinit");
+ if (!exp_file_deinit) {
+ gf_log("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function exp_file_deinit in lib.");
+ ret = -1;
+ goto out;
+ }
- /* Free the file */
- exp_file_deinit (file);
+ /* Free the file */
+ exp_file_deinit(file);
out:
- if (libhandle)
- dlclose(libhandle);
- GF_FREE (libpathfull);
- return ret;
+ if (libhandle)
+ dlclose(libhandle);
+ GF_FREE(libpathfull);
+ return ret;
}
-
/**
* print_netgroups_file - Print out & verify the syntax
* of the netgroups file specified
@@ -1675,676 +1897,842 @@ out:
* we want to print out a different error messages based on the ret value.
*/
int
-print_netgroups_file (const char *netgroups_file)
+print_netgroups_file(const char *netgroups_file)
{
- void *libhandle = NULL;
- char *libpathfull = NULL;
- struct netgroups_file *file = NULL;
- int ret = 0;
-
- struct netgroups_file *(*ng_file_parse)(const char *file_path) = NULL;
- void (*ng_file_print)(const struct netgroups_file *file) = NULL;
- void (*ng_file_deinit)(struct netgroups_file *ptr) = NULL;
-
- /* XLATORDIR passed through a -D flag to GCC */
- ret = gf_asprintf (&libpathfull, "%s/%s/server.so", XLATORDIR,
- "nfs");
- if (ret < 0) {
- gf_log ("glusterfs", GF_LOG_CRITICAL, "asprintf () failed.");
- ret = -1;
- goto out;
- }
- /* Load up the library */
- libhandle = dlopen (libpathfull, RTLD_NOW);
- if (!libhandle) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "Error loading NFS server library : %s\n", dlerror ());
- ret = -1;
- goto out;
- }
-
- /* Load up the function */
- ng_file_parse = dlsym (libhandle, "ng_file_parse");
- if (!ng_file_parse) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "Error finding function ng_file_parse in symbol.");
- ret = -1;
- goto out;
- }
-
- /* Parse the file */
- file = ng_file_parse (netgroups_file);
- if (!file) {
- ret = 1; /* This means we failed to parse */
- goto out;
- }
-
- /* Load up the function */
- ng_file_print = dlsym (libhandle, "ng_file_print");
- if (!ng_file_print) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "Error finding function ng_file_print in symbol.");
- ret = -1;
- goto out;
- }
+ void *libhandle = NULL;
+ char *libpathfull = NULL;
+ struct netgroups_file *file = NULL;
+ int ret = 0;
+
+ struct netgroups_file *(*ng_file_parse)(const char *file_path) = NULL;
+ void (*ng_file_print)(const struct netgroups_file *file) = NULL;
+ void (*ng_file_deinit)(struct netgroups_file * ptr) = NULL;
+
+ /* XLATORDIR passed through a -D flag to GCC */
+ ret = gf_asprintf(&libpathfull, "%s/%s/server.so", XLATORDIR, "nfs");
+ if (ret < 0) {
+ gf_log("glusterfs", GF_LOG_CRITICAL, "asprintf () failed.");
+ ret = -1;
+ goto out;
+ }
+ /* Load up the library */
+ libhandle = dlopen(libpathfull, RTLD_NOW);
+ if (!libhandle) {
+ gf_log("glusterfs", GF_LOG_CRITICAL,
+ "Error loading NFS server library : %s\n", dlerror());
+ ret = -1;
+ goto out;
+ }
+
+ /* Load up the function */
+ ng_file_parse = dlsym(libhandle, "ng_file_parse");
+ if (!ng_file_parse) {
+ gf_log("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function ng_file_parse in symbol.");
+ ret = -1;
+ goto out;
+ }
+
+ /* Parse the file */
+ file = ng_file_parse(netgroups_file);
+ if (!file) {
+ ret = 1; /* This means we failed to parse */
+ goto out;
+ }
+
+ /* Load up the function */
+ ng_file_print = dlsym(libhandle, "ng_file_print");
+ if (!ng_file_print) {
+ gf_log("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function ng_file_print in symbol.");
+ ret = -1;
+ goto out;
+ }
- /* Print it out to screen */
- ng_file_print (file);
+ /* Print it out to screen */
+ ng_file_print(file);
- /* Load up the function */
- ng_file_deinit = dlsym (libhandle, "ng_file_deinit");
- if (!ng_file_deinit) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "Error finding function ng_file_deinit in lib.");
- ret = -1;
- goto out;
- }
+ /* Load up the function */
+ ng_file_deinit = dlsym(libhandle, "ng_file_deinit");
+ if (!ng_file_deinit) {
+ gf_log("glusterfs", GF_LOG_CRITICAL,
+ "Error finding function ng_file_deinit in lib.");
+ ret = -1;
+ goto out;
+ }
- /* Free the file */
- ng_file_deinit (file);
+ /* Free the file */
+ ng_file_deinit(file);
out:
- if (libhandle)
- dlclose(libhandle);
- GF_FREE (libpathfull);
- return ret;
+ if (libhandle)
+ dlclose(libhandle);
+ GF_FREE(libpathfull);
+ return ret;
}
-
int
-parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
+parse_cmdline(int argc, char *argv[], glusterfs_ctx_t *ctx)
{
- 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;
-
- /* Do this before argp_parse so it can be overridden. */
- if (access(SECURE_ACCESS_FILE,F_OK) == 0) {
- cmd_args->secure_mgmt = 1;
- }
-
- argp_parse (&argp, argc, argv, ARGP_IN_ORDER, NULL, cmd_args);
- if (cmd_args->print_netgroups) {
- /* When this option is set we don't want to do anything else
- * except for printing & verifying the netgroups file.
- */
- ret = 0;
- goto out;
- }
-
- if (cmd_args->print_exports) {
- /* When this option is set we don't want to do anything else
- * except for printing & verifying the exports file.
- */
- ret = 0;
- goto out;
- }
-
-
- ctx->secure_mgmt = cmd_args->secure_mgmt;
-
- if (ENABLE_DEBUG_MODE == cmd_args->debug_mode) {
- cmd_args->log_level = GF_LOG_DEBUG;
- cmd_args->log_file = gf_strdup ("/dev/stderr");
- cmd_args->no_daemon_mode = ENABLE_NO_DAEMON_MODE;
- }
-
- process_mode = gf_get_process_mode (argv[0]);
- ctx->process_mode = process_mode;
+ int process_mode = 0;
+ int ret = 0;
+ struct stat stbuf = {
+ 0,
+ };
+ char timestr[GF_TIMESTR_SIZE];
+ char tmp_logfile[1024] = {0};
+ char *tmp_logfile_dyn = NULL;
+ char *tmp_logfilebase = NULL;
+ cmd_args_t *cmd_args = NULL;
+ int len = 0;
+ char *thin_volfileid = NULL;
+
+ cmd_args = &ctx->cmd_args;
+
+ /* Do this before argp_parse so it can be overridden. */
+ if (sys_access(SECURE_ACCESS_FILE, F_OK) == 0) {
+ cmd_args->secure_mgmt = 1;
+ ctx->ssl_cert_depth = glusterfs_read_secure_access_file();
+ }
+
+ /* Need to set lru_limit to below 0 to indicate there was nothing
+ specified. This is needed as 0 is a valid option, and may not be
+ default value. */
+ cmd_args->lru_limit = -1;
+
+ argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, cmd_args);
+
+ if (cmd_args->print_xlatordir || cmd_args->print_statedumpdir ||
+ cmd_args->print_logdir || cmd_args->print_libexecdir) {
+ /* Just print, nothing else to do */
+ goto out;
+ }
+
+ if (cmd_args->print_netgroups) {
+ /* When this option is set we don't want to do anything else
+ * except for printing & verifying the netgroups file.
+ */
+ ret = 0;
+ goto out;
+ }
- /* 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_msg ("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_15);
- ret = -1;
+ if (cmd_args->print_exports) {
+ /* When this option is set we don't want to do anything else
+ * except for printing & verifying the exports file.
+ */
+ ret = 0;
+ goto out;
+ }
+
+ ctx->secure_mgmt = cmd_args->secure_mgmt;
+
+ if (ENABLE_DEBUG_MODE == cmd_args->debug_mode) {
+ cmd_args->log_level = GF_LOG_DEBUG;
+ cmd_args->log_file = gf_strdup("/dev/stderr");
+ cmd_args->no_daemon_mode = ENABLE_NO_DAEMON_MODE;
+ }
+
+ process_mode = gf_get_process_mode(argv[0]);
+ ctx->process_mode = process_mode;
+
+ if (cmd_args->process_name) {
+ ctx->cmd_args.process_name = cmd_args->process_name;
+ }
+ /* 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_smsg("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_15, NULL);
+ ret = -1;
+ goto out;
+ }
+
+ if ((cmd_args->volfile_server == NULL) && (cmd_args->volfile == NULL)) {
+ if (process_mode == GF_SERVER_PROCESS)
+ cmd_args->volfile = gf_strdup(DEFAULT_SERVER_VOLFILE);
+ else if (process_mode == GF_GLUSTERD_PROCESS)
+ 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 = sys_stat(cmd_args->volfile, &stbuf);
+ if (ret) {
+ gf_smsg("glusterfs", GF_LOG_CRITICAL, errno, glusterfsd_msg_16,
+ NULL);
+ /* argp_usage (argp.) */
+ fprintf(stderr, "USAGE: %s [options] [mountpoint]\n", argv[0]);
+ goto out;
+ }
+ }
+
+ if (cmd_args->thin_client) {
+ len = strlen(cmd_args->volfile_id) + SLEN("gfproxy-client/");
+ thin_volfileid = GF_MALLOC(len + 1, gf_common_mt_char);
+ snprintf(thin_volfileid, len + 1, "gfproxy-client/%s",
+ cmd_args->volfile_id);
+ GF_FREE(cmd_args->volfile_id);
+ cmd_args->volfile_id = thin_volfileid;
+ }
+
+ if (cmd_args->run_id) {
+ ret = sys_lstat(cmd_args->log_file, &stbuf);
+ /* If its /dev/null, or /dev/stdout, /dev/stderr,
+ * let it use the same, no need to alter
+ */
+ if (((ret == 0) &&
+ (S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))) ||
+ (ret == -1)) {
+ /* Have separate logfile per run. */
+ gf_time_fmt(timestr, sizeof timestr, gf_time(), gf_timefmt_FT);
+ sprintf(tmp_logfile, "%s.%s.%d", cmd_args->log_file, timestr,
+ getpid());
+
+ /* Create symlink to actual log file */
+ sys_unlink(cmd_args->log_file);
+
+ tmp_logfile_dyn = gf_strdup(tmp_logfile);
+ tmp_logfilebase = basename(tmp_logfile_dyn);
+ ret = sys_symlink(tmp_logfilebase, cmd_args->log_file);
+ if (ret == -1) {
+ fprintf(stderr, "ERROR: symlink of logfile failed\n");
goto out;
- }
-
- if ((cmd_args->volfile_server == NULL)
- && (cmd_args->volfile == NULL)) {
- if (process_mode == GF_SERVER_PROCESS)
- cmd_args->volfile = gf_strdup (DEFAULT_SERVER_VOLFILE);
- else if (process_mode == GF_GLUSTERD_PROCESS)
- 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_msg ("glusterfs", GF_LOG_CRITICAL, errno,
- glusterfsd_msg_16);
- /* argp_usage (argp.) */
- fprintf (stderr, "USAGE: %s [options] [mountpoint]\n",
- argv[0]);
- goto out;
- }
- }
+ }
- if (cmd_args->run_id) {
- ret = sys_lstat (cmd_args->log_file, &stbuf);
- /* If its /dev/null, or /dev/stdout, /dev/stderr,
- * let it use the same, no need to alter
- */
- if (((ret == 0) &&
- (S_ISREG (stbuf.st_mode) || S_ISLNK (stbuf.st_mode))) ||
- (ret == -1)) {
- /* 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 ());
-
- /* Create symlink to actual log file */
- sys_unlink (cmd_args->log_file);
-
- tmp_logfile_dyn = gf_strdup (tmp_logfile);
- tmp_logfilebase = basename (tmp_logfile_dyn);
- ret = sys_symlink (tmp_logfilebase,
- cmd_args->log_file);
- if (ret == -1) {
- fprintf (stderr, "ERROR: symlink of logfile failed\n");
- goto out;
- }
-
- GF_FREE (cmd_args->log_file);
- cmd_args->log_file = gf_strdup (tmp_logfile);
+ GF_FREE(cmd_args->log_file);
+ cmd_args->log_file = gf_strdup(tmp_logfile);
- GF_FREE (tmp_logfile_dyn);
- }
+ GF_FREE(tmp_logfile_dyn);
}
+ }
- /*
- This option was made obsolete but parsing it for backward
- compatibility with third party applications
- */
- if (cmd_args->max_connect_attempts) {
- gf_msg ("glusterfs", GF_LOG_WARNING, 0, glusterfsd_msg_33);
- }
+ /*
+ This option was made obsolete but parsing it for backward
+ compatibility with third party applications
+ */
+ if (cmd_args->max_connect_attempts) {
+ gf_smsg("glusterfs", GF_LOG_WARNING, 0, glusterfsd_msg_33, NULL);
+ }
#ifdef GF_DARWIN_HOST_OS
- if (cmd_args->mount_point)
- cmd_args->mac_compat = GF_OPTION_DEFERRED;
+ if (cmd_args->mount_point)
+ cmd_args->mac_compat = GF_OPTION_DEFERRED;
#endif
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
int
-glusterfs_pidfile_setup (glusterfs_ctx_t *ctx)
+glusterfs_pidfile_setup(glusterfs_ctx_t *ctx)
{
- cmd_args_t *cmd_args = NULL;
- int ret = -1;
- FILE *pidfp = NULL;
+ cmd_args_t *cmd_args = NULL;
+ int ret = -1;
+ FILE *pidfp = NULL;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- if (!cmd_args->pid_file)
- return 0;
+ if (!cmd_args->pid_file)
+ return 0;
- pidfp = fopen (cmd_args->pid_file, "a+");
- if (!pidfp) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_17,
- cmd_args->pid_file);
- goto out;
- }
+ pidfp = fopen(cmd_args->pid_file, "a+");
+ if (!pidfp) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_17,
+ "pidfile=%s", cmd_args->pid_file, NULL);
+ goto out;
+ }
- ctx->pidfp = pidfp;
+ ctx->pidfp = pidfp;
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
int
-glusterfs_pidfile_cleanup (glusterfs_ctx_t *ctx)
+glusterfs_pidfile_cleanup(glusterfs_ctx_t *ctx)
{
- cmd_args_t *cmd_args = NULL;
+ cmd_args_t *cmd_args = NULL;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- if (!ctx->pidfp)
- return 0;
+ if (!ctx->pidfp)
+ return 0;
- gf_msg_trace ("glusterfsd", 0, "pidfile %s cleanup",
- cmd_args->pid_file);
+ gf_msg_trace("glusterfsd", 0, "pidfile %s cleanup", cmd_args->pid_file);
- if (ctx->cmd_args.pid_file) {
- unlink (ctx->cmd_args.pid_file);
- ctx->cmd_args.pid_file = NULL;
- }
+ if (ctx->cmd_args.pid_file) {
+ GF_FREE(ctx->cmd_args.pid_file);
+ ctx->cmd_args.pid_file = NULL;
+ }
- lockf (fileno (ctx->pidfp), F_ULOCK, 0);
- fclose (ctx->pidfp);
- ctx->pidfp = NULL;
+ lockf(fileno(ctx->pidfp), F_ULOCK, 0);
+ fclose(ctx->pidfp);
+ ctx->pidfp = NULL;
- return 0;
+ return 0;
}
int
-glusterfs_pidfile_update (glusterfs_ctx_t *ctx)
+glusterfs_pidfile_update(glusterfs_ctx_t *ctx, pid_t pid)
{
- cmd_args_t *cmd_args = NULL;
- int ret = 0;
- FILE *pidfp = NULL;
+ cmd_args_t *cmd_args = NULL;
+ int ret = 0;
+ FILE *pidfp = NULL;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- pidfp = ctx->pidfp;
- if (!pidfp)
- return 0;
+ pidfp = ctx->pidfp;
+ if (!pidfp)
+ return 0;
- ret = lockf (fileno (pidfp), F_TLOCK, 0);
- if (ret) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_18,
- cmd_args->pid_file);
- return ret;
- }
+ ret = lockf(fileno(pidfp), F_TLOCK, 0);
+ if (ret) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_18,
+ "pidfile=%s", cmd_args->pid_file, NULL);
+ return ret;
+ }
- ret = ftruncate (fileno (pidfp), 0);
- if (ret) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_20,
- cmd_args->pid_file);
- return ret;
- }
+ ret = sys_ftruncate(fileno(pidfp), 0);
+ if (ret) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_20,
+ "pidfile=%s", cmd_args->pid_file, NULL);
+ return ret;
+ }
- ret = fprintf (pidfp, "%d\n", getpid ());
- if (ret <= 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21,
- cmd_args->pid_file);
- return ret;
- }
+ ret = fprintf(pidfp, "%d\n", pid);
+ if (ret <= 0) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21,
+ "pidfile=%s", cmd_args->pid_file, NULL);
+ return ret;
+ }
- ret = fflush (pidfp);
- if (ret) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21,
- cmd_args->pid_file);
- return ret;
- }
+ ret = fflush(pidfp);
+ if (ret) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21,
+ "pidfile=%s", cmd_args->pid_file, NULL);
+ return ret;
+ }
- gf_msg_debug ("glusterfsd", 0, "pidfile %s updated with pid %d",
- cmd_args->pid_file, getpid ());
+ gf_msg_debug("glusterfsd", 0, "pidfile %s updated with pid %d",
+ cmd_args->pid_file, pid);
- return 0;
+ return 0;
}
-
void *
-glusterfs_sigwaiter (void *arg)
+glusterfs_sigwaiter(void *arg)
{
- sigset_t set;
- int ret = 0;
- int sig = 0;
+ sigset_t set;
+ int ret = 0;
+ int sig = 0;
+ char *file = NULL;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGINT); /* cleanup_and_exit */
+ sigaddset(&set, SIGTERM); /* cleanup_and_exit */
+ sigaddset(&set, SIGHUP); /* reincarnate */
+ sigaddset(&set, SIGUSR1); /* gf_proc_dump_info */
+ sigaddset(&set, SIGUSR2);
+
+ for (;;) {
+ ret = sigwait(&set, &sig);
+ if (ret)
+ continue;
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ cleanup_and_exit(sig);
+ break;
+ case SIGHUP:
+ reincarnate(sig);
+ break;
+ case SIGUSR1:
+ gf_proc_dump_info(sig, glusterfsd_ctx);
+ break;
+ case SIGUSR2:
+ file = gf_monitor_metrics(glusterfsd_ctx);
- sigemptyset (&set);
- sigaddset (&set, SIGINT); /* cleanup_and_exit */
- sigaddset (&set, SIGTERM); /* cleanup_and_exit */
- sigaddset (&set, SIGHUP); /* reincarnate */
- sigaddset (&set, SIGUSR1); /* gf_proc_dump_info */
- sigaddset (&set, SIGUSR2); /* gf_latency_toggle */
+ /* Nothing needed to be done here */
+ GF_FREE(file);
- for (;;) {
- ret = sigwait (&set, &sig);
- if (ret)
- continue;
-
-
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- cleanup_and_exit (sig);
- break;
- case SIGHUP:
- reincarnate (sig);
- break;
- case SIGUSR1:
- gf_proc_dump_info (sig, glusterfsd_ctx);
- break;
- case SIGUSR2:
- gf_latency_toggle (sig, glusterfsd_ctx);
- break;
- default:
-
- break;
- }
+ break;
+ default:
+
+ break;
}
+ }
- return NULL;
+ return NULL;
}
-
void
-glusterfsd_print_trace (int signum)
+glusterfsd_print_trace(int signum)
{
- gf_print_trace (signum, glusterfsd_ctx);
+ gf_print_trace(signum, glusterfsd_ctx);
}
-
int
-glusterfs_signals_setup (glusterfs_ctx_t *ctx)
+glusterfs_signals_setup(glusterfs_ctx_t *ctx)
{
- sigset_t set;
- int ret = 0;
-
- sigemptyset (&set);
-
- /* common setting for all threads */
- signal (SIGSEGV, glusterfsd_print_trace);
- signal (SIGABRT, glusterfsd_print_trace);
- signal (SIGILL, glusterfsd_print_trace);
- signal (SIGTRAP, glusterfsd_print_trace);
- signal (SIGFPE, glusterfsd_print_trace);
- signal (SIGBUS, glusterfsd_print_trace);
- signal (SIGINT, cleanup_and_exit);
- signal (SIGPIPE, SIG_IGN);
-
- /* block these signals from non-sigwaiter threads */
- sigaddset (&set, SIGTERM); /* cleanup_and_exit */
- sigaddset (&set, SIGHUP); /* reincarnate */
- sigaddset (&set, SIGUSR1); /* gf_proc_dump_info */
- sigaddset (&set, SIGUSR2); /* gf_latency_toggle */
-
- ret = pthread_sigmask (SIG_BLOCK, &set, NULL);
- if (ret) {
- gf_msg ("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_22);
- return ret;
- }
-
- ret = pthread_create (&ctx->sigwaiter, NULL, glusterfs_sigwaiter,
- (void *) &set);
- if (ret) {
- /*
- TODO:
- fallback to signals getting handled by other threads.
- setup the signal handlers
- */
- gf_msg ("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_23);
- return ret;
- }
+ sigset_t set;
+ int ret = 0;
+
+ sigemptyset(&set);
+
+ /* common setting for all threads */
+ signal(SIGSEGV, glusterfsd_print_trace);
+ signal(SIGABRT, glusterfsd_print_trace);
+ signal(SIGILL, glusterfsd_print_trace);
+ signal(SIGTRAP, glusterfsd_print_trace);
+ signal(SIGFPE, glusterfsd_print_trace);
+ signal(SIGBUS, glusterfsd_print_trace);
+ signal(SIGINT, cleanup_and_exit);
+ signal(SIGPIPE, SIG_IGN);
+
+ /* block these signals from non-sigwaiter threads */
+ sigaddset(&set, SIGTERM); /* cleanup_and_exit */
+ sigaddset(&set, SIGHUP); /* reincarnate */
+ sigaddset(&set, SIGUSR1); /* gf_proc_dump_info */
+ sigaddset(&set, SIGUSR2);
+
+ /* Signals needed for asynchronous framework. */
+ sigaddset(&set, GF_ASYNC_SIGQUEUE);
+ sigaddset(&set, GF_ASYNC_SIGCTRL);
+
+ ret = pthread_sigmask(SIG_BLOCK, &set, NULL);
+ if (ret) {
+ gf_smsg("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_22, NULL);
+ return ret;
+ }
+ ret = gf_thread_create(&ctx->sigwaiter, NULL, glusterfs_sigwaiter,
+ (void *)&set, "sigwait");
+ if (ret) {
+ /*
+ TODO:
+ fallback to signals getting handled by other threads.
+ setup the signal handlers
+ */
+ gf_smsg("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_23, NULL);
return ret;
-}
+ }
+ return ret;
+}
int
-daemonize (glusterfs_ctx_t *ctx)
+daemonize(glusterfs_ctx_t *ctx)
{
- int ret = -1;
- cmd_args_t *cmd_args = NULL;
- int cstatus = 0;
- int err = 0;
+ int ret = -1;
+ cmd_args_t *cmd_args = NULL;
+ int cstatus = 0;
+ int err = 1;
+ int child_pid = 0;
+
+ cmd_args = &ctx->cmd_args;
+
+ ret = glusterfs_pidfile_setup(ctx);
+ if (ret)
+ goto out;
+
+ if (cmd_args->no_daemon_mode) {
+ goto postfork;
+ }
+
+ if (cmd_args->debug_mode)
+ goto postfork;
+
+ ret = pipe(ctx->daemon_pipe);
+ if (ret) {
+ /* If pipe() fails, retain daemon_pipe[] = {-1, -1}
+ and parent will just not wait for child status
+ */
+ ctx->daemon_pipe[0] = -1;
+ ctx->daemon_pipe[1] = -1;
+ }
+
+ ret = os_daemon_return(0, 0);
+ switch (ret) {
+ case -1:
+ if (ctx->daemon_pipe[0] != -1) {
+ sys_close(ctx->daemon_pipe[0]);
+ sys_close(ctx->daemon_pipe[1]);
+ }
- cmd_args = &ctx->cmd_args;
+ gf_smsg("daemonize", GF_LOG_ERROR, errno, glusterfsd_msg_24, NULL);
+ goto out;
+ case 0:
+ /* child */
+ /* close read */
+ sys_close(ctx->daemon_pipe[0]);
+ break;
+ default:
+ /* parent */
+ /* close write */
+ child_pid = ret;
+ sys_close(ctx->daemon_pipe[1]);
+
+ if (ctx->mnt_pid > 0) {
+ ret = waitpid(ctx->mnt_pid, &cstatus, 0);
+ if (!(ret == ctx->mnt_pid)) {
+ if (WIFEXITED(cstatus)) {
+ err = WEXITSTATUS(cstatus);
+ } else {
+ err = cstatus;
+ }
+ gf_smsg("daemonize", GF_LOG_ERROR, 0, glusterfsd_msg_25,
+ NULL);
+ exit(err);
+ }
+ }
+ sys_read(ctx->daemon_pipe[0], (void *)&err, sizeof(err));
+ /* NOTE: Only the least significant 8 bits i.e (err & 255)
+ will be available to parent process on calling exit() */
+ if (err)
+ _exit(abs(err));
+
+ /* Update pid in parent only for glusterd process */
+ if (ctx->process_mode == GF_GLUSTERD_PROCESS) {
+ ret = glusterfs_pidfile_update(ctx, child_pid);
+ if (ret)
+ exit(1);
+ }
+ _exit(0);
+ }
- ret = glusterfs_pidfile_setup (ctx);
+postfork:
+ /* Update pid in child either process_mode is not belong to glusterd
+ or process is spawned in no daemon mode
+ */
+ if ((ctx->process_mode != GF_GLUSTERD_PROCESS) ||
+ (cmd_args->no_daemon_mode)) {
+ ret = glusterfs_pidfile_update(ctx, getpid());
if (ret)
- goto out;
+ goto out;
+ }
+ gf_log("glusterfs", GF_LOG_INFO, "Pid of current running process is %d",
+ getpid());
+ ret = gf_log_inject_timer_event(ctx);
- if (cmd_args->no_daemon_mode)
- goto postfork;
+ glusterfs_signals_setup(ctx);
+out:
+ return ret;
+}
- if (cmd_args->debug_mode)
- goto postfork;
+#ifdef GF_LINUX_HOST_OS
+static int
+set_oom_score_adj(glusterfs_ctx_t *ctx)
+{
+ int ret = -1;
+ cmd_args_t *cmd_args = NULL;
+ int fd = -1;
+ size_t oom_score_len = 0;
+ struct oom_api_info *api = NULL;
- ret = pipe (ctx->daemon_pipe);
- if (ret) {
- /* If pipe() fails, retain daemon_pipe[] = {-1, -1}
- and parent will just not wait for child status
- */
- ctx->daemon_pipe[0] = -1;
- ctx->daemon_pipe[1] = -1;
- }
+ cmd_args = &ctx->cmd_args;
- ret = os_daemon_return (0, 0);
- switch (ret) {
- case -1:
- if (ctx->daemon_pipe[0] != -1) {
- close (ctx->daemon_pipe[0]);
- close (ctx->daemon_pipe[1]);
- }
+ if (!cmd_args->oom_score_adj)
+ goto success;
- gf_msg ("daemonize", GF_LOG_ERROR, errno, glusterfsd_msg_24);
- goto out;
- case 0:
- /* child */
- /* close read */
- close (ctx->daemon_pipe[0]);
- break;
- default:
- /* parent */
- /* close write */
- close (ctx->daemon_pipe[1]);
-
- if (ctx->mnt_pid > 0) {
- ret = waitpid (ctx->mnt_pid, &cstatus, 0);
- if (!(ret == ctx->mnt_pid && cstatus == 0)) {
- gf_msg ("daemonize", GF_LOG_ERROR, 0,
- glusterfsd_msg_25);
- exit (1);
- }
- }
+ api = get_oom_api_info();
+ if (!api)
+ goto out;
- err = 1;
- read (ctx->daemon_pipe[0], (void *)&err, sizeof (err));
- _exit (err);
- }
+ fd = open(api->oom_api_file, O_WRONLY);
+ if (fd < 0)
+ goto out;
-postfork:
- ret = glusterfs_pidfile_update (ctx);
- if (ret)
- goto out;
+ oom_score_len = strlen(cmd_args->oom_score_adj);
+ if (sys_write(fd, cmd_args->oom_score_adj, oom_score_len) !=
+ oom_score_len) {
+ sys_close(fd);
+ goto out;
+ }
+
+ if (sys_close(fd) < 0)
+ goto out;
- ret = gf_log_inject_timer_event (ctx);
+success:
+ ret = 0;
- glusterfs_signals_setup (ctx);
out:
- return ret;
+ return ret;
}
-
+#endif
int
-glusterfs_process_volfp (glusterfs_ctx_t *ctx, FILE *fp)
+glusterfs_process_volfp(glusterfs_ctx_t *ctx, FILE *fp)
{
- glusterfs_graph_t *graph = NULL;
- int ret = -1;
- xlator_t *trav = NULL;
+ glusterfs_graph_t *graph = NULL;
+ int ret = -1;
+ xlator_t *trav = NULL;
- graph = glusterfs_graph_construct (fp);
- if (!graph) {
- gf_msg ("", GF_LOG_ERROR, 0, glusterfsd_msg_26);
- goto out;
- }
+ if (!ctx)
+ return -1;
- for (trav = graph->first; trav; trav = trav->next) {
- if (strcmp (trav->type, "mount/fuse") == 0) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0,
- glusterfsd_msg_27);
- goto out;
- }
- }
+ graph = glusterfs_graph_construct(fp);
+ if (!graph) {
+ gf_smsg("", GF_LOG_ERROR, 0, glusterfsd_msg_26, NULL);
+ goto out;
+ }
- ret = glusterfs_graph_prepare (graph, ctx);
- if (ret) {
- glusterfs_graph_destroy (graph);
- goto out;
+ for (trav = graph->first; trav; trav = trav->next) {
+ if (strcmp(trav->type, "mount/fuse") == 0) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_27, NULL);
+ goto out;
}
+ }
- ret = glusterfs_graph_activate (graph, ctx);
+ xlator_t *xl = graph->first;
+ if (xl && (strcmp(xl->type, "protocol/server") == 0)) {
+ (void)copy_opts_to_child(xl, FIRST_CHILD(xl), "*auth*");
+ }
- if (ret) {
- glusterfs_graph_destroy (graph);
- goto out;
- }
+ ret = glusterfs_graph_prepare(graph, ctx, ctx->cmd_args.volume_name);
+ if (ret) {
+ goto out;
+ }
- gf_log_dump_graph (fp, graph);
+ ret = glusterfs_graph_activate(graph, ctx);
- ret = 0;
+ if (ret) {
+ goto out;
+ }
+
+ gf_log_dump_graph(fp, graph);
+
+ ret = 0;
out:
- if (fp)
- fclose (fp);
+ if (fp)
+ fclose(fp);
+
+ if (ret) {
+ /* TODO This code makes to generic for all graphs
+ client as well as servers.For now it destroys
+ graph only for server-side xlators not for client-side
+ xlators, before destroying a graph call xlator fini for
+ xlators those call xlator_init to avoid leak
+ */
+ if (graph) {
+ xl = graph->first;
+ if ((ctx->active != graph) &&
+ (xl && !strcmp(xl->type, "protocol/server"))) {
+ /* Take dict ref for every graph xlator to avoid dict leak
+ at the time of graph destroying
+ */
+ glusterfs_graph_fini(graph);
+ glusterfs_graph_destroy(graph);
+ }
+ }
- if (ret && !ctx->active) {
- /* there is some error in setting up the first graph itself */
- cleanup_and_exit (0);
+ /* there is some error in setting up the first graph itself */
+ if (!ctx->active) {
+ emancipate(ctx, ret);
+ cleanup_and_exit(ret);
}
+ }
- return ret;
+ return ret;
}
-
int
-glusterfs_volumes_init (glusterfs_ctx_t *ctx)
+glusterfs_volumes_init(glusterfs_ctx_t *ctx)
{
- FILE *fp = NULL;
- cmd_args_t *cmd_args = NULL;
- int ret = 0;
+ FILE *fp = NULL;
+ cmd_args_t *cmd_args = NULL;
+ int ret = 0;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- if (cmd_args->sock_file) {
- ret = glusterfs_listener_init (ctx);
- if (ret)
- goto out;
- }
+ if (cmd_args->sock_file) {
+ ret = glusterfs_listener_init(ctx);
+ if (ret)
+ goto out;
+ }
- if (cmd_args->volfile_server) {
- ret = glusterfs_mgmt_init (ctx);
- /* return, do not emancipate() yet */
- return ret;
- }
+ if (cmd_args->volfile_server) {
+ ret = glusterfs_mgmt_init(ctx);
+ /* return, do not emancipate() yet */
+ return ret;
+ }
- fp = get_volfp (ctx);
+ fp = get_volfp(ctx);
- if (!fp) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_28);
- ret = -1;
- goto out;
- }
+ if (!fp) {
+ gf_smsg("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_28, NULL);
+ ret = -1;
+ goto out;
+ }
- ret = glusterfs_process_volfp (ctx, fp);
- if (ret)
- goto out;
+ ret = glusterfs_process_volfp(ctx, fp);
+ if (ret)
+ goto out;
out:
- emancipate (ctx, ret);
- return ret;
+ emancipate(ctx, ret);
+ return ret;
}
/* This is the only legal global pointer */
glusterfs_ctx_t *glusterfsd_ctx;
int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
{
- glusterfs_ctx_t *ctx = NULL;
- int ret = -1;
- char cmdlinestr[PATH_MAX] = {0,};
- cmd_args_t *cmd = NULL;
-
- gf_check_and_set_mem_acct (argc, argv);
-
- ctx = glusterfs_ctx_new ();
- if (!ctx) {
- gf_msg ("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_29);
- return ENOMEM;
- }
- glusterfsd_ctx = ctx;
+ glusterfs_ctx_t *ctx = NULL;
+ int ret = -1;
+ char cmdlinestr[PATH_MAX] = {
+ 0,
+ };
+ cmd_args_t *cmd = NULL;
+
+ gf_check_and_set_mem_acct(argc, argv);
+
+ ctx = glusterfs_ctx_new();
+ if (!ctx) {
+ gf_smsg("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_29, NULL);
+ return ENOMEM;
+ }
+ glusterfsd_ctx = ctx;
+
+ ret = glusterfs_globals_init(ctx);
+ if (ret)
+ return ret;
- ret = glusterfs_globals_init (ctx);
- if (ret)
- return ret;
+ THIS->ctx = ctx;
- THIS->ctx = ctx;
+ ret = glusterfs_ctx_defaults_init(ctx);
+ if (ret)
+ goto out;
- ret = glusterfs_ctx_defaults_init (ctx);
- if (ret)
- goto out;
+ ret = parse_cmdline(argc, argv, ctx);
+ if (ret)
+ goto out;
+ cmd = &ctx->cmd_args;
- ret = parse_cmdline (argc, argv, ctx);
- if (ret)
- goto out;
- cmd = &ctx->cmd_args;
- if (cmd->print_netgroups) {
- /* If this option is set we want to print & verify the file,
- * set the return value (exit code in this case) and exit.
- */
- ret = print_netgroups_file (cmd->print_netgroups);
- goto out;
- }
-
- if (cmd->print_exports) {
- /* If this option is set we want to print & verify the file,
- * set the return value (exit code in this case)
- * and exit.
- */
- ret = print_exports_file (cmd->print_exports);
+ if (cmd->print_xlatordir) {
+ /* XLATORDIR passed through a -D flag to GCC */
+ printf("%s\n", XLATORDIR);
+ goto out;
+ }
+
+ if (cmd->print_statedumpdir) {
+ printf("%s\n", DEFAULT_VAR_RUN_DIRECTORY);
+ goto out;
+ }
+
+ if (cmd->print_logdir) {
+ printf("%s\n", DEFAULT_LOG_FILE_DIRECTORY);
+ goto out;
+ }
+
+ if (cmd->print_libexecdir) {
+ printf("%s\n", LIBEXECDIR);
+ goto out;
+ }
+
+ if (cmd->print_netgroups) {
+ /* If this option is set we want to print & verify the file,
+ * set the return value (exit code in this case) and exit.
+ */
+ ret = print_netgroups_file(cmd->print_netgroups);
+ goto out;
+ }
+
+ if (cmd->print_exports) {
+ /* If this option is set we want to print & verify the file,
+ * set the return value (exit code in this case)
+ * and exit.
+ */
+ ret = print_exports_file(cmd->print_exports);
+ goto out;
+ }
+
+ ret = logging_init(ctx, argv[0]);
+ if (ret)
+ goto out;
+
+ /* set brick_mux mode only for server process */
+ if ((ctx->process_mode != GF_SERVER_PROCESS) && cmd->brick_mux) {
+ gf_smsg("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_43, NULL);
+ goto out;
+ }
+
+ /* log the version of glusterfs running here along with the actual
+ command line options. */
+ {
+ int i = 0;
+ int pos = 0;
+ int len = snprintf(cmdlinestr, sizeof(cmdlinestr), "%s", argv[0]);
+ for (i = 1; (i < argc) && (len > 0); i++) {
+ pos += len;
+ len = snprintf(cmdlinestr + pos, sizeof(cmdlinestr) - pos, " %s",
+ argv[i]);
+ if ((len <= 0) || (len >= (sizeof(cmdlinestr) - pos))) {
+ gf_smsg("glusterfs", GF_LOG_ERROR, 0, glusterfsd_msg_029, NULL);
+ ret = -1;
goto out;
+ }
}
+ gf_smsg(argv[0], GF_LOG_INFO, 0, glusterfsd_msg_30, "arg=%s", argv[0],
+ "version=%s", PACKAGE_VERSION, "cmdlinestr=%s", cmdlinestr,
+ NULL);
- ret = logging_init (ctx, argv[0]);
- if (ret)
- goto out;
+ ctx->cmdlinestr = gf_strdup(cmdlinestr);
+ }
+ gf_proc_dump_init();
- /* log the version of glusterfs running here along with the actual
- command line options. */
- {
- int i = 0;
- strcpy (cmdlinestr, argv[0]);
- for (i = 1; i < argc; i++) {
- strcat (cmdlinestr, " ");
- strcat (cmdlinestr, argv[i]);
- }
- gf_msg (argv[0], GF_LOG_INFO, 0, glusterfsd_msg_30,
- argv[0], PACKAGE_VERSION, cmdlinestr);
+ ret = create_fuse_mount(ctx);
+ if (ret)
+ goto out;
- ctx->cmdlinestr = gf_strdup (cmdlinestr);
- }
+ ret = daemonize(ctx);
+ if (ret)
+ goto out;
- gf_proc_dump_init();
+ /*
+ * If we do this before daemonize, the pool-sweeper thread dies with
+ * the parent, but we want to do it as soon as possible after that in
+ * case something else depends on pool allocations.
+ */
+ mem_pools_init();
- ret = create_fuse_mount (ctx);
- if (ret)
- goto out;
+ ret = gf_async_init(ctx);
+ if (ret < 0) {
+ goto out;
+ }
- ret = daemonize (ctx);
- if (ret)
- goto out;
+#ifdef GF_LINUX_HOST_OS
+ ret = set_oom_score_adj(ctx);
+ if (ret)
+ goto out;
+#endif
- ctx->env = syncenv_new (0, 0, 0);
- if (!ctx->env) {
- gf_msg ("", GF_LOG_ERROR, 0, glusterfsd_msg_31);
- goto out;
- }
+ ctx->env = syncenv_new(0, 0, 0);
+ if (!ctx->env) {
+ gf_smsg("", GF_LOG_ERROR, 0, glusterfsd_msg_31, NULL);
+ goto out;
+ }
- /* do this _after_ deamonize() */
- if (cmd->global_timer_wheel) {
- ret = glusterfs_global_timer_wheel_init (ctx);
- if (ret)
- goto out;
- }
+ /* do this _after_ daemonize() */
+ if (!glusterfs_ctx_tw_get(ctx)) {
+ ret = -1;
+ goto out;
+ }
- ret = glusterfs_volumes_init (ctx);
- if (ret)
- goto out;
+ ret = glusterfs_volumes_init(ctx);
+ if (ret)
+ goto out;
- ret = event_dispatch (ctx->event_pool);
+ ret = gf_event_dispatch(ctx->event_pool);
out:
-// glusterfs_ctx_destroy (ctx);
- return ret;
+ // glusterfs_ctx_destroy (ctx);
+ gf_async_fini();
+ return ret;
}
diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h
index 8247469e6e1..4e1413caa70 100644
--- a/glusterfsd/src/glusterfsd.h
+++ b/glusterfsd/src/glusterfsd.h
@@ -13,109 +13,130 @@
#include "rpcsvc.h"
#include "glusterd1-xdr.h"
-#define DEFAULT_GLUSTERD_VOLFILE CONFDIR "/glusterd.vol"
-#define DEFAULT_CLIENT_VOLFILE CONFDIR "/glusterfs.vol"
-#define DEFAULT_SERVER_VOLFILE CONFDIR "/glusterfsd.vol"
+#define DEFAULT_GLUSTERD_VOLFILE CONFDIR "/glusterd.vol"
+#define DEFAULT_CLIENT_VOLFILE CONFDIR "/glusterfs.vol"
+#define DEFAULT_SERVER_VOLFILE CONFDIR "/glusterfsd.vol"
-#define DEFAULT_EVENT_POOL_SIZE 16384
+#define DEFAULT_EVENT_POOL_SIZE 16384
-#define ARGP_LOG_LEVEL_NONE_OPTION "NONE"
-#define ARGP_LOG_LEVEL_TRACE_OPTION "TRACE"
-#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_DEBUG_OPTION "DEBUG"
+#define ARGP_LOG_LEVEL_NONE_OPTION "NONE"
+#define ARGP_LOG_LEVEL_TRACE_OPTION "TRACE"
+#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_DEBUG_OPTION "DEBUG"
-#define ENABLE_NO_DAEMON_MODE 1
-#define ENABLE_DEBUG_MODE 1
+#define ENABLE_NO_DAEMON_MODE 1
+#define ENABLE_DEBUG_MODE 1
-#define GF_MEMPOOL_COUNT_OF_DICT_T 4096
+#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)
+#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)
-#define GF_MEMPOOL_COUNT_OF_LRU_BUF_T 256
+#define GF_MEMPOOL_COUNT_OF_LRU_BUF_T 256
enum argp_option_keys {
- ARGP_VOLFILE_SERVER_KEY = 's',
- ARGP_VOLUME_FILE_KEY = 'f',
- ARGP_LOG_LEVEL_KEY = 'L',
- ARGP_LOG_FILE_KEY = 'l',
- ARGP_VOLFILE_SERVER_PORT_KEY = 131,
- ARGP_VOLFILE_SERVER_TRANSPORT_KEY = 132,
- ARGP_PID_FILE_KEY = 'p',
- ARGP_SOCK_FILE_KEY = 'S',
- ARGP_NO_DAEMON_KEY = 'N',
- ARGP_RUN_ID_KEY = 'r',
- ARGP_PRINT_NETGROUPS = 'n',
- ARGP_PRINT_EXPORTS = 'e',
- ARGP_DEBUG_KEY = 133,
- ARGP_NEGATIVE_TIMEOUT_KEY = 134,
- ARGP_ENTRY_TIMEOUT_KEY = 135,
- ARGP_ATTRIBUTE_TIMEOUT_KEY = 136,
- ARGP_VOLUME_NAME_KEY = 137,
- ARGP_XLATOR_OPTION_KEY = 138,
- ARGP_DIRECT_IO_MODE_KEY = 139,
+ ARGP_VOLFILE_SERVER_KEY = 's',
+ ARGP_VOLUME_FILE_KEY = 'f',
+ ARGP_LOG_LEVEL_KEY = 'L',
+ ARGP_LOG_FILE_KEY = 'l',
+ ARGP_VOLFILE_SERVER_PORT_KEY = 131,
+ ARGP_VOLFILE_SERVER_TRANSPORT_KEY = 132,
+ ARGP_PID_FILE_KEY = 'p',
+ ARGP_SOCK_FILE_KEY = 'S',
+ ARGP_NO_DAEMON_KEY = 'N',
+ ARGP_RUN_ID_KEY = 'r',
+ ARGP_PRINT_NETGROUPS = 'n',
+ ARGP_PRINT_EXPORTS = 'e',
+ ARGP_DEBUG_KEY = 133,
+ ARGP_NEGATIVE_TIMEOUT_KEY = 134,
+ ARGP_ENTRY_TIMEOUT_KEY = 135,
+ ARGP_ATTRIBUTE_TIMEOUT_KEY = 136,
+ ARGP_VOLUME_NAME_KEY = 137,
+ ARGP_XLATOR_OPTION_KEY = 138,
+ ARGP_DIRECT_IO_MODE_KEY = 139,
#ifdef GF_DARWIN_HOST_OS
- ARGP_NON_LOCAL_KEY = 140,
+ ARGP_NON_LOCAL_KEY = 140,
#endif /* DARWIN */
- ARGP_VOLFILE_ID_KEY = 143,
- ARGP_VOLFILE_CHECK_KEY = 144,
- ARGP_VOLFILE_MAX_FETCH_ATTEMPTS = 145,
- ARGP_LOG_SERVER_KEY = 146,
- ARGP_LOG_SERVER_PORT_KEY = 147,
- ARGP_READ_ONLY_KEY = 148,
- ARGP_MAC_COMPAT_KEY = 149,
- ARGP_DUMP_FUSE_KEY = 150,
- 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_FOPEN_KEEP_CACHE_KEY = 159,
- ARGP_GID_TIMEOUT_KEY = 160,
- ARGP_FUSE_BACKGROUND_QLEN_KEY = 161,
- ARGP_FUSE_CONGESTION_THRESHOLD_KEY = 162,
- ARGP_INODE32_KEY = 163,
- ARGP_FUSE_MOUNTOPTS_KEY = 164,
- ARGP_FUSE_USE_READDIRP_KEY = 165,
- ARGP_AUX_GFID_MOUNT_KEY = 166,
- ARGP_FUSE_NO_ROOT_SQUASH_KEY = 167,
- ARGP_LOGGER = 168,
- ARGP_LOG_FORMAT = 169,
- ARGP_LOG_BUF_SIZE = 170,
- ARGP_LOG_FLUSH_TIMEOUT = 171,
- ARGP_SECURE_MGMT_KEY = 172,
- ARGP_GLOBAL_TIMER_WHEEL = 173,
- ARGP_RESOLVE_GIDS_KEY = 174,
+ ARGP_VOLFILE_ID_KEY = 143,
+ ARGP_VOLFILE_CHECK_KEY = 144,
+ ARGP_VOLFILE_MAX_FETCH_ATTEMPTS = 145,
+ ARGP_LOG_SERVER_KEY = 146,
+ ARGP_LOG_SERVER_PORT_KEY = 147,
+ ARGP_READ_ONLY_KEY = 148,
+ ARGP_MAC_COMPAT_KEY = 149,
+ ARGP_DUMP_FUSE_KEY = 150,
+ 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_FOPEN_KEEP_CACHE_KEY = 159,
+ ARGP_GID_TIMEOUT_KEY = 160,
+ ARGP_FUSE_BACKGROUND_QLEN_KEY = 161,
+ ARGP_FUSE_CONGESTION_THRESHOLD_KEY = 162,
+ ARGP_INODE32_KEY = 163,
+ ARGP_FUSE_MOUNTOPTS_KEY = 164,
+ ARGP_FUSE_USE_READDIRP_KEY = 165,
+ ARGP_AUX_GFID_MOUNT_KEY = 166,
+ ARGP_FUSE_NO_ROOT_SQUASH_KEY = 167,
+ ARGP_LOGGER = 168,
+ ARGP_LOG_FORMAT = 169,
+ ARGP_LOG_BUF_SIZE = 170,
+ ARGP_LOG_FLUSH_TIMEOUT = 171,
+ ARGP_SECURE_MGMT_KEY = 172,
+ ARGP_GLOBAL_TIMER_WHEEL = 173,
+ ARGP_RESOLVE_GIDS_KEY = 174,
+ ARGP_CAPABILITY_KEY = 175,
+#ifdef GF_LINUX_HOST_OS
+ ARGP_OOM_SCORE_ADJ_KEY = 176,
+#endif
+ ARGP_LOCALTIME_LOGGING_KEY = 177,
+ ARGP_SUBDIR_MOUNT_KEY = 178,
+ ARGP_PROCESS_NAME_KEY = 179,
+ ARGP_FUSE_EVENT_HISTORY_KEY = 180,
+ ARGP_THIN_CLIENT_KEY = 181,
+ ARGP_READER_THREAD_COUNT_KEY = 182,
+ ARGP_PRINT_XLATORDIR_KEY = 183,
+ ARGP_PRINT_STATEDUMPDIR_KEY = 184,
+ ARGP_PRINT_LOGDIR_KEY = 185,
+ ARGP_KERNEL_WRITEBACK_CACHE_KEY = 186,
+ ARGP_ATTR_TIMES_GRANULARITY_KEY = 187,
+ ARGP_PRINT_LIBEXECDIR_KEY = 188,
+ ARGP_FUSE_FLUSH_HANDLE_INTERRUPT_KEY = 189,
+ ARGP_FUSE_LRU_LIMIT_KEY = 190,
+ ARGP_FUSE_AUTO_INVAL_KEY = 191,
+ ARGP_GLOBAL_THREADING_KEY = 192,
+ ARGP_BRICK_MUX_KEY = 193,
+ ARGP_FUSE_DEV_EPERM_RATELIMIT_NS_KEY = 194,
+ ARGP_FUSE_INVALIDATE_LIMIT_KEY = 195,
};
-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;
+struct _gfd_vol_top_priv {
+ 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;
+typedef struct _gfd_vol_top_priv 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);
+int
+glusterfs_mgmt_pmap_signin(glusterfs_ctx_t *ctx);
+int
+glusterfs_volfile_fetch(glusterfs_ctx_t *ctx);
+void
+cleanup_and_exit(int signum);
-int glusterfs_volume_top_write_perf (uint32_t blk_size, uint32_t blk_count,
- char *brick_path, double *throughput,
- double *time);
-int glusterfs_volume_top_read_perf (uint32_t blk_size, uint32_t blk_count,
- char *brick_path, double *throughput,
- double *time);
+void
+xlator_mem_cleanup(xlator_t *this);
extern glusterfs_ctx_t *glusterfsd_ctx;
#endif /* __GLUSTERFSD_H__ */
diff --git a/heal/src/Makefile.am b/heal/src/Makefile.am
index 512e9e64fde..aa18d3eff88 100644
--- a/heal/src/Makefile.am
+++ b/heal/src/Makefile.am
@@ -1,4 +1,7 @@
-sbin_PROGRAMS = glfsheal
+if WITH_SERVER
+scriptdir = $(GLUSTERFS_LIBEXECDIR)
+script_PROGRAMS = glfsheal
+endif
glfsheal_SOURCES = glfs-heal.c
@@ -14,13 +17,11 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) \
-I$(top_srcdir)/xlators/lib/src\
-I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/rpc-lib/src\
-I$(top_srcdir)/rpc/xdr/src\
+ -I$(top_builddir)/rpc/xdr/src\
-I$(top_srcdir)/api/src\
- -I$(top_srcdir)/contrib/argp-standalone\
- -DDATADIR=\"$(localstatedir)\" \
- -DSBIN_DIR=\"$(sbindir)\" \
- $(XML_CPPFLAGS)
+ -DDATADIR=\"$(localstatedir)\"
-AM_CFLAGS = -Wall $(GF_CFLAGS)
+AM_CFLAGS = -Wall $(GF_CFLAGS) $(XML_CFLAGS)
CLEANFILES =
diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c
index 3b3003ece67..bf4b47f8760 100644
--- a/heal/src/glfs-heal.c
+++ b/heal/src/glfs-heal.c
@@ -12,702 +12,1473 @@
#include <stdlib.h>
#include <errno.h>
#include "glfs.h"
-#include "glfs-handles.h"
#include "glfs-internal.h"
#include "protocol-common.h"
-#include "syncop.h"
-#include "syncop-utils.h"
+#include <glusterfs/syscall.h>
+#include <glusterfs/syncop.h>
+#include <glusterfs/syncop-utils.h>
#include <string.h>
-#include <time.h>
+#include <glusterfs/glusterfs.h>
+#include <libgen.h>
+
+#if (HAVE_LIB_XML)
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+
+xmlTextWriterPtr glfsh_writer;
+xmlDocPtr glfsh_doc = NULL;
+#endif
+
+#define XML_RET_CHECK_AND_GOTO(ret, label) \
+ do { \
+ if (ret < 0) { \
+ ret = -1; \
+ goto label; \
+ } else \
+ ret = 0; \
+ } while (0)
+
+#define MODE_XML (1 << 0)
+#define MODE_NO_LOG (1 << 1)
+
+typedef struct num_entries {
+ uint64_t num_entries;
+ uint64_t pending_entries;
+ uint64_t spb_entries;
+ uint64_t possibly_healing_entries;
+} num_entries_t;
+
+typedef int (*print_status)(dict_t *, char *, uuid_t, num_entries_t *,
+ gf_boolean_t flag);
+
+int
+glfsh_heal_splitbrain_file(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
+ char *file, dict_t *xattr_req);
+
+typedef struct glfs_info {
+ int (*init)(void);
+ int (*print_brick_from_xl)(xlator_t *xl, loc_t *rootloc);
+ int (*print_heal_op_status)(int ret, uint64_t num_entries, char *fmt_str);
+ int (*print_heal_op_summary)(int ret, num_entries_t *num_entries);
+ int (*print_heal_status)(char *path, uuid_t gfid, char *status);
+ int (*print_spb_status)(char *path, uuid_t gfid, char *status);
+ int (*end)(int op_ret, char *op_errstr);
+} glfsh_info_t;
+
+glfsh_info_t *glfsh_output = NULL;
+int32_t is_xml;
#define DEFAULT_HEAL_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
-#define USAGE_STR "Usage: %s <VOLNAME> [bigger-file <FILE> | "\
- "source-brick <HOSTNAME:BRICKNAME> [<FILE>] | "\
- "split-brain-info]\n"
+#define USAGE_STR \
+ "Usage: %s <VOLNAME> [bigger-file <FILE> | " \
+ "latest-mtime <FILE> | " \
+ "source-brick <HOSTNAME:BRICKNAME> [<FILE>] | " \
+ "split-brain-info | info-summary] [glusterd-sock <FILE>" \
+ "]\n"
+
+typedef enum {
+ GLFSH_MODE_CONTINUE_ON_ERROR = 1,
+ GLFSH_MODE_EXIT_ON_FIRST_FAILURE,
+} glfsh_fail_mode_t;
-typedef void (*print_status) (dict_t *, char *, uuid_t, uint64_t *);
+int
+glfsh_init()
+{
+ return 0;
+}
-int glfsh_heal_splitbrain_file (glfs_t *fs, xlator_t *top_subvol,
- loc_t *rootloc, char *file, dict_t *xattr_req);
+int
+glfsh_end_op_granular_entry_heal(int op_ret, char *op_errstr)
+{
+ /* If error string is available, give it higher precedence.*/
+
+ if (op_errstr) {
+ printf("%s\n", op_errstr);
+ } else if (op_ret < 0) {
+ if (op_ret == -EAGAIN)
+ printf(
+ "One or more entries need heal. Please execute "
+ "the command again after there are no entries "
+ "to be healed\n");
+ else if (op_ret == -ENOTCONN)
+ printf(
+ "One or more bricks could be down. Please "
+ "execute the command again after bringing all "
+ "bricks online and finishing any pending "
+ "heals\n");
+ else
+ printf(
+ "Command failed - %s. Please check the logs for"
+ " more details\n",
+ strerror(-op_ret));
+ }
+ return 0;
+}
int
-glfsh_link_inode_update_loc (loc_t *loc, struct iatt *iattr)
+glfsh_end(int op_ret, char *op_errstr)
{
- inode_t *link_inode = NULL;
- int ret = -1;
+ if (op_errstr)
+ printf("%s\n", op_errstr);
+ return 0;
+}
- link_inode = inode_link (loc->inode, NULL, NULL, iattr);
- if (link_inode == NULL)
- goto out;
+int
+glfsh_print_hr_spb_status(char *path, uuid_t gfid, char *status)
+{
+ printf("%s\n", path);
+ fflush(stdout);
+ return 0;
+}
- inode_unref (loc->inode);
- loc->inode = link_inode;
- ret = 0;
-out:
- return ret;
+int
+glfsh_no_print_hr_status(char *path, uuid_t gfid, char *status)
+{
+ return 0;
}
+int
+glfsh_print_hr_heal_status(char *path, uuid_t gfid, char *status)
+{
+ printf("%s%s\n", path, status);
+ fflush(stdout);
+ return 0;
+}
+
+#if (HAVE_LIB_XML)
int
-glfsh_get_index_dir_loc (loc_t *rootloc, xlator_t *xl, loc_t *dirloc,
- int32_t *op_errno)
+glfsh_xml_init()
{
- void *index_gfid = NULL;
- int ret = 0;
- dict_t *xattr = NULL;
- struct iatt iattr = {0};
- struct iatt parent = {0};
+ int ret = -1;
+ glfsh_writer = xmlNewTextWriterDoc(&glfsh_doc, 0);
+ if (glfsh_writer == NULL) {
+ return -1;
+ }
+
+ ret = xmlTextWriterStartDocument(glfsh_writer, "1.0", "UTF-8", "yes");
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+
+ /* <cliOutput> */
+ ret = xmlTextWriterStartElement(glfsh_writer, (xmlChar *)"cliOutput");
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+
+ /* <healInfo> */
+ ret = xmlTextWriterStartElement(glfsh_writer, (xmlChar *)"healInfo");
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+ /* <bricks> */
+ ret = xmlTextWriterStartElement(glfsh_writer, (xmlChar *)"bricks");
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+ xmlTextWriterFlush(glfsh_writer);
+xml_out:
+ return ret;
+}
- ret = syncop_getxattr (xl, rootloc, &xattr, GF_XATTROP_INDEX_GFID,
- NULL, NULL);
- if (ret < 0) {
- *op_errno = -ret;
- goto out;
+int
+glfsh_xml_end(int op_ret, char *op_errstr)
+{
+ int ret = -1;
+ int op_errno = 0;
+ gf_boolean_t alloc = _gf_false;
+
+ if (op_ret < 0) {
+ op_errno = -op_ret;
+ op_ret = -1;
+ if (op_errstr == NULL) {
+ op_errstr = gf_strdup(strerror(op_errno));
+ alloc = _gf_true;
}
+ } else {
+ op_errstr = NULL;
+ }
+
+ /* </bricks> */
+ ret = xmlTextWriterEndElement(glfsh_writer);
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+
+ /* </healInfo> */
+ ret = xmlTextWriterEndElement(glfsh_writer);
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+
+ ret = xmlTextWriterWriteFormatElement(glfsh_writer, (xmlChar *)"opRet",
+ "%d", op_ret);
+
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+
+ ret = xmlTextWriterWriteFormatElement(glfsh_writer, (xmlChar *)"opErrno",
+ "%d", op_errno);
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+
+ if (op_errstr)
+ ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"opErrstr", "%s", op_errstr);
+ else
+ ret = xmlTextWriterWriteFormatElement(glfsh_writer,
+ (xmlChar *)"opErrstr", "%s", "");
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+ ret = xmlTextWriterEndDocument(glfsh_writer);
+ XML_RET_CHECK_AND_GOTO(ret, xml_out);
+
+ /* Dump xml document to stdout and pretty format it */
+ xmlSaveFormatFileEnc("-", glfsh_doc, "UTF-8", 1);
+
+ xmlFreeTextWriter(glfsh_writer);
+ xmlFreeDoc(glfsh_doc);
+xml_out:
+ if (alloc)
+ GF_FREE(op_errstr);
+ return ret;
+}
- ret = dict_get_ptr (xattr, GF_XATTROP_INDEX_GFID, &index_gfid);
- if (ret < 0) {
- *op_errno = EINVAL;
- goto out;
+int
+glfsh_print_xml_heal_op_status(int ret, uint64_t num_entries, char *fmt_str)
+{
+ int x_ret = 0;
+ if (ret < 0 && num_entries == 0) {
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"status", "%s", strerror(-ret));
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ if (fmt_str) {
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"numberOfEntries", "-");
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
}
-
- gf_uuid_copy (dirloc->gfid, index_gfid);
- dirloc->path = "";
- dirloc->inode = inode_new (rootloc->inode->table);
- ret = syncop_lookup (xl, dirloc, &iattr, &parent, NULL, NULL);
- dirloc->path = NULL;
- if (ret < 0) {
- *op_errno = -ret;
- goto out;
+ goto out;
+ } else if (ret == 0) {
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"status", "%s", "Connected");
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ }
+
+ if (ret < 0) {
+ if (fmt_str) {
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"status",
+ "Failed to process entries completely. "
+ "(%s)%s %" PRIu64 "",
+ strerror(-ret), fmt_str, num_entries);
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
}
- ret = glfsh_link_inode_update_loc (dirloc, &iattr);
- if (ret)
- goto out;
- glfs_loc_touchup (dirloc);
+ } else {
+ if (fmt_str) {
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"numberOfEntries", "%" PRIu64 "",
+ num_entries);
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ }
+ }
+out:
+ if (x_ret >= 0) {
+ x_ret = xmlTextWriterEndElement(glfsh_writer);
+ if (x_ret >= 0) {
+ xmlTextWriterFlush(glfsh_writer);
+ x_ret = 0;
+ } else {
+ x_ret = -1;
+ }
+ }
+ return x_ret;
+}
- ret = 0;
+int
+glfsh_print_xml_heal_op_summary(int ret, num_entries_t *num_entries)
+{
+ int x_ret = 0;
+
+ if (ret < 0 && num_entries == 0) {
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"status", "%s", strerror(-ret));
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"totalNumberOfEntries", "-");
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"numberOfEntriesInHealPending", "-");
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"numberOfEntriesInSplitBrain", "-");
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"numberOfEntriesPossiblyHealing", "-");
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ goto out;
+ } else if (ret == 0) {
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"status", "%s", "Connected");
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ }
+
+ if (ret < 0) {
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"status",
+ "Failed to process entries"
+ " completely. "
+ "(%s)totalNumberOfEntries%" PRIu64 "",
+ strerror(-ret), num_entries->num_entries);
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ } else {
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"totalNumberOfEntries", "%" PRIu64 "",
+ num_entries->num_entries);
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"numberOfEntriesInHealPending",
+ "%" PRIu64 "", num_entries->pending_entries);
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"numberOfEntriesInSplitBrain",
+ "%" PRIu64 "", num_entries->spb_entries);
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"numberOfEntriesPossiblyHealing",
+ "%" PRIu64 "", num_entries->possibly_healing_entries);
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ }
out:
- if (xattr)
- dict_unref (xattr);
- return ret;
+ if (x_ret >= 0) {
+ x_ret = xmlTextWriterEndElement(glfsh_writer);
+ }
+ return x_ret;
}
-static xlator_t*
-_get_ancestor (xlator_t *xl, gf_xl_afr_op_t heal_op)
+int
+glfsh_print_xml_file_status(char *path, uuid_t gfid, char *status)
{
- static char *replica_xl[] = {"cluster/replicate", NULL};
- static char *heal_xls[] = {"cluster/replicate", "cluster/disperse",
- NULL};
- char **ancestors = NULL;
+ int x_ret = 0;
+
+ x_ret = xmlTextWriterStartElement(glfsh_writer, (xmlChar *)"file");
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterWriteFormatAttribute(glfsh_writer, (xmlChar *)"gfid",
+ "%s", uuid_utoa(gfid));
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterWriteFormatString(glfsh_writer, "%s", path);
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ x_ret = xmlTextWriterEndElement(glfsh_writer);
+ XML_RET_CHECK_AND_GOTO(x_ret, out);
+ xmlTextWriterFlush(glfsh_writer);
+out:
+ return x_ret;
+}
- if (heal_op == GF_SHD_OP_INDEX_SUMMARY)
- ancestors = heal_xls;
- else
- ancestors = replica_xl;
+int
+glfsh_print_xml_brick_from_xl(xlator_t *xl, loc_t *rootloc)
+{
+ char *remote_host = NULL;
+ char *remote_subvol = NULL;
+ char *uuid = NULL;
+ int ret = 0;
+ int x_ret = 0;
+
+ ret = dict_get_str(xl->options, "remote-host", &remote_host);
+ if (ret < 0)
+ goto print;
+
+ ret = dict_get_str(xl->options, "remote-subvolume", &remote_subvol);
+ if (ret < 0)
+ goto print;
+ ret = syncop_getxattr(xl, rootloc, &xl->options, GF_XATTR_NODE_UUID_KEY,
+ NULL, NULL);
+ if (ret < 0)
+ goto print;
+
+ ret = dict_get_str(xl->options, GF_XATTR_NODE_UUID_KEY, &uuid);
+ if (ret < 0)
+ goto print;
+print:
+
+ x_ret = xmlTextWriterStartElement(glfsh_writer, (xmlChar *)"brick");
+ XML_RET_CHECK_AND_GOTO(x_ret, xml_out);
+ x_ret = xmlTextWriterWriteFormatAttribute(
+ glfsh_writer, (xmlChar *)"hostUuid", "%s", uuid ? uuid : "-");
+ XML_RET_CHECK_AND_GOTO(x_ret, xml_out);
+
+ x_ret = xmlTextWriterWriteFormatElement(
+ glfsh_writer, (xmlChar *)"name", "%s:%s",
+ remote_host ? remote_host : "-", remote_subvol ? remote_subvol : "-");
+ XML_RET_CHECK_AND_GOTO(x_ret, xml_out);
+ xmlTextWriterFlush(glfsh_writer);
+xml_out:
+ return ret;
+}
+#endif
- if (!xl || !xl->parents)
- return NULL;
+int
+glfsh_link_inode_update_loc(loc_t *loc, struct iatt *iattr)
+{
+ inode_t *link_inode = NULL;
+ int ret = -1;
- while (xl->parents) {
- xl = xl->parents->xlator;
- if (!xl)
- break;
- if (gf_get_index_by_elem (ancestors, xl->type) != -1)
- return xl;
- }
+ link_inode = inode_link(loc->inode, NULL, NULL, iattr);
+ if (link_inode == NULL)
+ goto out;
- return NULL;
+ inode_unref(loc->inode);
+ loc->inode = link_inode;
+ ret = 0;
+out:
+ return ret;
}
int
-glfsh_index_purge (xlator_t *subvol, inode_t *inode, char *name)
+glfsh_no_print_hr_heal_op_status(int ret, uint64_t num_entries, char *fmt_str)
{
- loc_t loc = {0, };
- int ret = 0;
+ return 0;
+}
- loc.parent = inode_ref (inode);
- loc.name = name;
+int
+glfsh_print_hr_heal_op_summary(int ret, num_entries_t *num_entries)
+{
+ if (ret < 0 && num_entries->num_entries == 0) {
+ printf("Status: %s\n", strerror(-ret));
+ printf("Total Number of entries: -\n");
+ printf("Number of entries in heal pending: -\n");
+ printf("Number of entries in split-brain: -\n");
+ printf("Number of entries possibly healing: -\n");
+ goto out;
+ } else if (ret == 0) {
+ printf("Status: Connected\n");
+ }
+
+ if (ret < 0) {
+ printf(
+ "Status: Failed to process entries completely. "
+ "(%s)\nTotal Number of entries: %" PRIu64 "\n",
+ strerror(-ret), num_entries->num_entries);
+ } else {
+ printf("Total Number of entries: %" PRIu64 "\n",
+ num_entries->num_entries);
+ printf("Number of entries in heal pending: %" PRIu64 "\n",
+ num_entries->pending_entries);
+ printf("Number of entries in split-brain: %" PRIu64 "\n",
+ num_entries->spb_entries);
+ printf("Number of entries possibly healing: %" PRIu64 "\n",
+ num_entries->possibly_healing_entries);
+ }
+out:
+ printf("\n");
+ fflush(stdout);
+ return 0;
+}
- ret = syncop_unlink (subvol, &loc, NULL, NULL);
+int
+glfsh_print_hr_heal_op_status(int ret, uint64_t num_entries, char *fmt_str)
+{
+ if (ret < 0 && num_entries == 0) {
+ printf("Status: %s\n", strerror(-ret));
+ if (fmt_str)
+ printf("%s -\n", fmt_str);
+ goto out;
+ } else if (ret == 0) {
+ printf("Status: Connected\n");
+ }
+
+ if (ret < 0) {
+ if (fmt_str)
+ printf(
+ "Status: Failed to process entries completely. "
+ "(%s)\n%s %" PRIu64 "\n",
+ strerror(-ret), fmt_str, num_entries);
+ } else {
+ if (fmt_str)
+ printf("%s %" PRIu64 "\n", fmt_str, num_entries);
+ }
+out:
+ printf("\n");
+ return 0;
+}
- loc_wipe (&loc);
- return ret;
+int
+glfsh_print_info_summary(int ret, num_entries_t *num_entries)
+{
+ return glfsh_output->print_heal_op_summary(ret, num_entries);
}
-void
-glfsh_print_spb_status (dict_t *dict, char *path, uuid_t gfid,
- uint64_t *num_entries)
+int
+glfsh_print_heal_op_status(int ret, uint64_t num_entries,
+ gf_xl_afr_op_t heal_op)
{
- char *value = NULL;
- int ret = 0;
+ char *fmt_str = NULL;
- ret = dict_get_str (dict, "heal-info", &value);
- if (ret)
- return;
+ if (heal_op == GF_SHD_OP_INDEX_SUMMARY)
+ fmt_str = "Number of entries:";
+ else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES)
+ fmt_str = "Number of entries in split-brain:";
+ else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK)
+ fmt_str = "Number of healed entries:";
- if (!strcmp (value, "split-brain")) {
- (*num_entries)++;
- printf ("%s\n",
- path ? path : uuid_utoa (gfid));
- }
- return;
+ return glfsh_output->print_heal_op_status(ret, num_entries, fmt_str);
}
-void
-glfsh_print_heal_status (dict_t *dict, char *path, uuid_t gfid,
- uint64_t *num_entries)
+int
+glfsh_get_index_dir_loc(loc_t *rootloc, xlator_t *xl, loc_t *dirloc,
+ int32_t *op_errno, char *vgfid)
{
- char *value = NULL;
- int ret = 0;
- char *status = NULL;
+ void *index_gfid = NULL;
+ int ret = 0;
+ dict_t *xattr = NULL;
+ struct iatt iattr = {0};
+ struct iatt parent = {0};
+
+ ret = syncop_getxattr(xl, rootloc, &xattr, vgfid, NULL, NULL);
+ if (ret < 0) {
+ *op_errno = -ret;
+ goto out;
+ }
+
+ ret = dict_get_ptr(xattr, vgfid, &index_gfid);
+ if (ret < 0) {
+ *op_errno = EINVAL;
+ goto out;
+ }
+
+ gf_uuid_copy(dirloc->gfid, index_gfid);
+ dirloc->path = "";
+ dirloc->inode = inode_new(rootloc->inode->table);
+ ret = syncop_lookup(xl, dirloc, &iattr, &parent, NULL, NULL);
+ dirloc->path = NULL;
+ if (ret < 0) {
+ *op_errno = -ret;
+ goto out;
+ }
+ ret = glfsh_link_inode_update_loc(dirloc, &iattr);
+ if (ret)
+ goto out;
+
+ ret = glfs_loc_touchup(dirloc);
+ if (ret < 0) {
+ *op_errno = errno;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (xattr)
+ dict_unref(xattr);
+ return ret;
+}
- ret = dict_get_str (dict, "heal-info", &value);
- if (ret || (!strcmp (value, "no-heal")))
- return;
+static xlator_t *
+_get_ancestor(xlator_t *xl, gf_xl_afr_op_t heal_op)
+{
+ static char *replica_xl[] = {"cluster/replicate", NULL};
+ static char *heal_xls[] = {"cluster/replicate", "cluster/disperse", NULL};
+ char **ancestors = NULL;
- (*num_entries)++;
- if (!strcmp (value, "heal")) {
- ret = gf_asprintf (&status, " ");
- } else if (!strcmp (value, "possibly-healing")) {
- ret = gf_asprintf (&status, " - Possibly undergoing heal\n");
- } else if (!strcmp (value, "split-brain")) {
- ret = gf_asprintf (&status, " - Is in split-brain\n");
- }
- if (ret == -1)
- status = NULL;
+ if (heal_op == GF_SHD_OP_INDEX_SUMMARY || heal_op == GF_SHD_OP_HEAL_SUMMARY)
+ ancestors = heal_xls;
+ else
+ ancestors = replica_xl;
- printf ("%s%s\n",
- path ? path : uuid_utoa (gfid),
- status);
+ if (!xl || !xl->parents)
+ return NULL;
+
+ while (xl->parents) {
+ xl = xl->parents->xlator;
+ if (!xl)
+ break;
+ if (gf_get_index_by_elem(ancestors, xl->type) != -1)
+ return xl;
+ }
- if (status)
- GF_FREE (status);
- return;
+ return NULL;
}
-static int
-glfsh_heal_entries (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
- gf_dirent_t *entries, uint64_t *offset,
- uint64_t *num_entries, dict_t *xattr_req) {
-
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
- int ret = 0;
- char file[64] = {0};
-
- list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- *offset = entry->d_off;
- if ((strcmp (entry->d_name, ".") == 0) ||
- (strcmp (entry->d_name, "..") == 0))
- continue;
- memset (file, 0, sizeof(file));
- snprintf (file, sizeof(file), "gfid:%s", entry->d_name);
- ret = glfsh_heal_splitbrain_file (fs, top_subvol, rootloc, file,
- xattr_req);
- if (ret)
- continue;
- (*num_entries)++;
- }
+int
+glfsh_index_purge(xlator_t *subvol, inode_t *inode, char *name)
+{
+ loc_t loc = {
+ 0,
+ };
+ int ret = 0;
- return ret;
+ loc.parent = inode_ref(inode);
+ loc.name = name;
+
+ ret = syncop_unlink(subvol, &loc, NULL, NULL);
+
+ loc_wipe(&loc);
+ return ret;
}
-static int
-glfsh_process_entries (xlator_t *xl, fd_t *fd, gf_dirent_t *entries,
- uint64_t *offset, uint64_t *num_entries,
- print_status glfsh_print_status)
-{
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
- int ret = 0;
- char *path = NULL;
- uuid_t gfid = {0};
- xlator_t *this = NULL;
- dict_t *dict = NULL;
- loc_t loc = {0,};
- this = THIS;
-
- list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- *offset = entry->d_off;
- if ((strcmp (entry->d_name, ".") == 0) ||
- (strcmp (entry->d_name, "..") == 0))
- continue;
-
- if (dict) {
- dict_unref (dict);
- dict = NULL;
- }
- gf_uuid_clear (gfid);
- GF_FREE (path);
- path = NULL;
-
- gf_uuid_parse (entry->d_name, gfid);
- gf_uuid_copy (loc.gfid, gfid);
- ret = syncop_getxattr (this, &loc, &dict, GF_HEAL_INFO, NULL,
- NULL);
- if (ret)
- continue;
-
- ret = syncop_gfid_to_path (this->itable, xl, gfid, &path);
-
- if (ret == -ENOENT || ret == -ESTALE) {
- glfsh_index_purge (xl, fd->inode, entry->d_name);
- ret = 0;
- continue;
- }
- if (dict)
- glfsh_print_status (dict, path, gfid,
- num_entries);
- }
- ret = 0;
- GF_FREE (path);
- if (dict) {
- dict_unref (dict);
- dict = NULL;
- }
- return ret;
+int
+glfsh_print_summary_status(dict_t *dict, char *path, uuid_t gfid,
+ num_entries_t *num_entries, gf_boolean_t flag)
+{
+ int ret = 0;
+ char *value = NULL;
+
+ ret = dict_get_str(dict, "heal-info", &value);
+ if (ret)
+ goto out;
+
+ if ((!strcmp(value, "heal")) || (!strcmp(value, "heal-pending"))) {
+ (num_entries->pending_entries)++;
+ } else if ((!strcmp(value, "split-brain")) ||
+ (!strcmp(value, "split-brain-pending"))) {
+ (num_entries->spb_entries)++;
+ } else if ((!strcmp(value, "possibly-healing-pending")) ||
+ (!strcmp(value, "possibly-healing"))) {
+ (num_entries->possibly_healing_entries)++;
+ } else {
+ goto out;
+ }
+ (num_entries->num_entries)++;
+out:
+ return ret;
}
-static int
-glfsh_crawl_directory (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
- xlator_t *readdir_xl, fd_t *fd, loc_t *loc,
- dict_t *xattr_req)
-{
- uint64_t offset = 0;
- gf_dirent_t entries;
- int ret = 0;
- gf_boolean_t free_entries = _gf_false;
- uint64_t num_entries = 0;
- int heal_op = -1;
-
- INIT_LIST_HEAD (&entries.list);
- ret = dict_get_int32 (xattr_req, "heal-op", &heal_op);
- if (ret)
- return ret;
+int
+glfsh_print_spb_status(dict_t *dict, char *path, uuid_t gfid,
+ num_entries_t *num_entries, gf_boolean_t flag)
+{
+ int ret = 0;
+ gf_boolean_t pending = _gf_false;
+ gf_boolean_t split_b = _gf_false;
+ char *value = NULL;
+ char gfid_str[64] = {0};
+
+ ret = dict_get_str(dict, "heal-info", &value);
+ if (ret)
+ return 0;
- while (1) {
- ret = syncop_readdir (readdir_xl, fd, 131072, offset, &entries,
- NULL, NULL);
- if (ret <= 0)
- break;
- ret = 0;
- free_entries = _gf_true;
-
- if (list_empty (&entries.list))
- goto out;
-
- if (heal_op == GF_SHD_OP_INDEX_SUMMARY) {
- ret = glfsh_process_entries (readdir_xl, fd,
- &entries, &offset,
- &num_entries,
- glfsh_print_heal_status);
- if (ret < 0)
- goto out;
- } else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) {
- ret = glfsh_process_entries (readdir_xl, fd,
- &entries, &offset,
- &num_entries,
- glfsh_print_spb_status);
- if (ret < 0)
- goto out;
- } else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) {
- ret = glfsh_heal_entries (fs, top_subvol, rootloc,
- &entries, &offset,
- &num_entries, xattr_req);
- }
- gf_dirent_free (&entries);
- free_entries = _gf_false;
- }
- ret = 0;
-out:
- if (free_entries)
- gf_dirent_free (&entries);
- if (ret < 0) {
- printf ("Failed to complete gathering info. "
- "Number of entries so far: %"PRIu64"\n", num_entries);
- } else {
- if (heal_op == GF_SHD_OP_INDEX_SUMMARY)
- printf ("Number of entries: %"PRIu64"\n", num_entries);
- else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES)
- printf ("Number of entries in split-brain: %"PRIu64"\n"
- , num_entries);
- else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK)
- printf ("Number of healed entries: %"PRIu64"\n",
- num_entries);
+ if (!strcmp(value, "split-brain")) {
+ split_b = _gf_true;
+ } else if (!strcmp(value, "split-brain-pending")) {
+ split_b = _gf_true;
+ pending = _gf_true;
+ }
+ /* Consider the entry only iff :
+ * 1) The dir being processed is not indices/dirty, indicated by
+ * flag == _gf_false
+ * 2) The dir being processed is indices/dirty but the entry also
+ * exists in indices/xattrop dir and has already been processed.
+ */
+ if (split_b) {
+ if (!flag || (flag && !pending)) {
+ (num_entries->num_entries)++;
+ glfsh_output->print_spb_status(
+ path ? path : uuid_utoa_r(gfid, gfid_str), gfid, NULL);
}
- return ret;
+ }
+ return 0;
}
-static int
-glfsh_print_brick (xlator_t *xl, loc_t *rootloc)
+int
+glfsh_print_heal_status(dict_t *dict, char *path, uuid_t gfid,
+ num_entries_t *num_entries, gf_boolean_t ignore_dirty)
{
- int ret = 0;
- dict_t *xattr = NULL;
- char *pathinfo = NULL;
- char *brick_start = NULL;
- char *brick_end = NULL;
+ int ret = 0;
+ gf_boolean_t pending = _gf_false;
+ char *status = NULL;
+ char *value = NULL;
+ char gfid_str[64] = {0};
+
+ ret = dict_get_str(dict, "heal-info", &value);
+ if (ret || (!strcmp(value, "no-heal")))
+ return 0;
- ret = syncop_getxattr (xl, rootloc, &xattr, GF_XATTR_PATHINFO_KEY,
- NULL, NULL);
+ if (!strcmp(value, "heal")) {
+ ret = gf_asprintf(&status, " ");
if (ret < 0)
- goto out;
-
- ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &pathinfo);
+ goto out;
+ } else if (!strcmp(value, "possibly-healing")) {
+ ret = gf_asprintf(&status, " - Possibly undergoing heal");
if (ret < 0)
- goto out;
+ goto out;
+ } else if (!strcmp(value, "split-brain")) {
+ ret = gf_asprintf(&status, " - Is in split-brain");
+ if (ret < 0)
+ goto out;
+ } else if (!strcmp(value, "heal-pending")) {
+ pending = _gf_true;
+ ret = gf_asprintf(&status, " ");
+ if (ret < 0)
+ goto out;
+ } else if (!strcmp(value, "split-brain-pending")) {
+ pending = _gf_true;
+ ret = gf_asprintf(&status, " - Is in split-brain");
+ if (ret < 0)
+ goto out;
+ } else if (!strcmp(value, "possibly-healing-pending")) {
+ pending = _gf_true;
+ ret = gf_asprintf(&status, " - Possibly undergoing heal");
+ if (ret < 0)
+ goto out;
+ }
+out:
+ /* If ignore_dirty is set, it means indices/dirty directory is
+ * being processed. Ignore the entry if it also exists in
+ * indices/xattrop.
+ * Boolean pending is set to true if the entry also exists in
+ * indices/xattrop directory.
+ */
+ if (ignore_dirty) {
+ if (pending) {
+ GF_FREE(status);
+ status = NULL;
+ return 0;
+ }
+ }
+ if (ret == -1)
+ status = NULL;
- brick_start = strchr (pathinfo, ':') + 1;
- brick_end = pathinfo + strlen (pathinfo) - 1;
- *brick_end = 0;
- printf ("Brick %s\n", brick_start);
+ (num_entries->num_entries)++;
+ glfsh_output->print_heal_status(path ? path : uuid_utoa_r(gfid, gfid_str),
+ gfid, status ? status : "");
-out:
- if (xattr)
- dict_unref (xattr);
- return ret;
+ GF_FREE(status);
+ return 0;
}
-void
-glfsh_print_brick_from_xl (xlator_t *xl)
+int
+glfsh_heal_status_boolean(dict_t *dict, char *path, uuid_t gfid,
+ num_entries_t *num_entries, gf_boolean_t ignore_dirty)
{
- char *remote_host = NULL;
- char *remote_subvol = NULL;
- int ret = 0;
+ int ret = 0;
+ char *value = NULL;
- ret = dict_get_str (xl->options, "remote-host", &remote_host);
- if (ret < 0)
- goto out;
+ ret = dict_get_str(dict, "heal-info", &value);
+ if ((!ret) && (!strcmp(value, "no-heal")))
+ return 0;
+ else
+ return -1;
+}
- ret = dict_get_str (xl->options, "remote-subvolume", &remote_subvol);
- if (ret < 0)
- goto out;
-out:
- if (ret < 0)
- printf ("Brick - Not able to get brick information\n");
- else
- printf ("Brick %s:%s\n", remote_host, remote_subvol);
+static void
+glfsh_heal_entries(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
+ gf_dirent_t *entries, uint64_t *offset,
+ num_entries_t *num_entries, dict_t *xattr_req)
+{
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+ int ret = 0;
+ char file[64] = {0};
+
+ list_for_each_entry_safe(entry, tmp, &entries->list, list)
+ {
+ *offset = entry->d_off;
+ if ((strcmp(entry->d_name, ".") == 0) ||
+ (strcmp(entry->d_name, "..") == 0))
+ continue;
+ snprintf(file, sizeof(file), "gfid:%s", entry->d_name);
+ ret = glfsh_heal_splitbrain_file(fs, top_subvol, rootloc, file,
+ xattr_req);
+ if (ret)
+ continue;
+ (num_entries->num_entries)++;
+ }
}
-void
-glfsh_print_pending_heals (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
- xlator_t *xl, gf_xl_afr_op_t heal_op)
+static int
+glfsh_process_entries(xlator_t *xl, fd_t *fd, gf_dirent_t *entries,
+ uint64_t *offset, num_entries_t *num_entries,
+ print_status glfsh_print_status,
+ gf_boolean_t ignore_dirty, glfsh_fail_mode_t mode)
{
- int ret = 0;
- loc_t dirloc = {0};
- fd_t *fd = NULL;
- int32_t op_errno = 0;
- dict_t *xattr_req = NULL;
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+ int ret = 0;
+ int print_status = 0;
+ char *path = NULL;
+ uuid_t gfid = {0};
+ xlator_t *this = NULL;
+ dict_t *dict = NULL;
+ loc_t loc = {
+ 0,
+ };
+ this = THIS;
+
+ list_for_each_entry_safe(entry, tmp, &entries->list, list)
+ {
+ *offset = entry->d_off;
+ if ((strcmp(entry->d_name, ".") == 0) ||
+ (strcmp(entry->d_name, "..") == 0))
+ continue;
- xattr_req = dict_new();
- if (!xattr_req)
- goto out;
+ if (dict) {
+ dict_unref(dict);
+ dict = NULL;
+ }
+ gf_uuid_clear(gfid);
+ GF_FREE(path);
+ path = NULL;
- ret = dict_set_int32 (xattr_req, "heal-op", heal_op);
- if (ret)
- goto out;
- ret = glfsh_print_brick (xl, rootloc);
- if (ret < 0) {
- glfsh_print_brick_from_xl (xl);
- printf ("Status: %s\n", strerror (-ret));
+ gf_uuid_parse(entry->d_name, gfid);
+ gf_uuid_copy(loc.gfid, gfid);
+ ret = syncop_getxattr(this, &loc, &dict, GF_HEAL_INFO, NULL, NULL);
+ if (ret) {
+ if ((mode != GLFSH_MODE_CONTINUE_ON_ERROR) && (ret == -ENOTCONN))
goto out;
+ else
+ continue;
}
- ret = glfsh_get_index_dir_loc (rootloc, xl, &dirloc, &op_errno);
- if (ret < 0) {
- if (op_errno == ESTALE || op_errno == ENOENT)
- printf ("Number of entries: 0\n");
- else
- printf ("Status: %s\n", strerror (op_errno));
+ ret = syncop_gfid_to_path(this->itable, xl, gfid, &path);
+
+ if (ret == -ENOENT || ret == -ESTALE) {
+ glfsh_index_purge(xl, fd->inode, entry->d_name);
+ ret = 0;
+ continue;
+ }
+ if (dict) {
+ print_status = glfsh_print_status(dict, path, gfid, num_entries,
+ ignore_dirty);
+ if ((print_status) && (mode != GLFSH_MODE_CONTINUE_ON_ERROR)) {
+ ret = -EAGAIN;
goto out;
+ }
}
+ }
+ ret = 0;
+out:
+ GF_FREE(path);
+ if (dict) {
+ dict_unref(dict);
+ dict = NULL;
+ }
+ return ret;
+}
- ret = syncop_dirfd (xl, &dirloc, &fd, GF_CLIENT_PID_GLFS_HEAL);
- if (ret)
- goto out;
+static int
+glfsh_crawl_directory(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
+ xlator_t *readdir_xl, fd_t *fd, loc_t *loc,
+ dict_t *xattr_req, num_entries_t *num_entries,
+ gf_boolean_t ignore)
+{
+ int ret = 0;
+ int heal_op = -1;
+ uint64_t offset = 0;
+ gf_dirent_t entries;
+ gf_boolean_t free_entries = _gf_false;
+ glfsh_fail_mode_t mode = GLFSH_MODE_CONTINUE_ON_ERROR;
+
+ INIT_LIST_HEAD(&entries.list);
+ ret = dict_get_int32(xattr_req, "heal-op", &heal_op);
+ if (ret)
+ return ret;
+
+ if (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE)
+ mode = GLFSH_MODE_EXIT_ON_FIRST_FAILURE;
- ret = glfsh_crawl_directory (fs, top_subvol, rootloc, xl, fd, &dirloc,
- xattr_req);
- if (fd)
- fd_unref (fd);
- if (xattr_req)
- dict_unref (xattr_req);
- if (ret < 0) {
- if (heal_op == GF_SHD_OP_INDEX_SUMMARY)
- printf ("Failed to find entries with pending"
- " self-heal\n");
- if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES)
- printf ("Failed to find entries in split-brain\n");
+ while (1) {
+ ret = syncop_readdir(readdir_xl, fd, 131072, offset, &entries, NULL,
+ NULL);
+ if (ret <= 0)
+ break;
+ ret = 0;
+ free_entries = _gf_true;
+
+ if (list_empty(&entries.list))
+ goto out;
+
+ if (heal_op == GF_SHD_OP_INDEX_SUMMARY) {
+ ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset,
+ num_entries, glfsh_print_heal_status,
+ ignore, mode);
+ if (ret < 0)
+ goto out;
+ } else if (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) {
+ ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset,
+ num_entries, glfsh_print_spb_status,
+ ignore, mode);
+ if (ret < 0)
+ goto out;
+ } else if (heal_op == GF_SHD_OP_HEAL_SUMMARY) {
+ ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset,
+ num_entries, glfsh_print_summary_status,
+ ignore, mode);
+ if (ret < 0)
+ goto out;
+ } else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) {
+ glfsh_heal_entries(fs, top_subvol, rootloc, &entries, &offset,
+ num_entries, xattr_req);
+ } else if (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) {
+ ret = glfsh_process_entries(readdir_xl, fd, &entries, &offset,
+ num_entries, glfsh_heal_status_boolean,
+ ignore, mode);
+ if (ret < 0)
+ goto out;
}
+ gf_dirent_free(&entries);
+ free_entries = _gf_false;
+ }
+ ret = 0;
out:
- loc_wipe (&dirloc);
- return;
+ if (free_entries)
+ gf_dirent_free(&entries);
+ return ret;
}
static int
-glfsh_validate_volume (xlator_t *xl, gf_xl_afr_op_t heal_op)
+glfsh_no_print_brick_from_xl(xlator_t *xl, loc_t *rootloc)
{
- xlator_t *heal_xl = NULL;
- int ret = -1;
+ return 0;
+}
- while (xl->next)
- xl = xl->next;
+static int
+glfsh_print_brick_from_xl(xlator_t *xl, loc_t *rootloc)
+{
+ char *remote_host = NULL;
+ char *remote_subvol = NULL;
+ int ret = 0;
- while (xl) {
- if (strcmp (xl->type, "protocol/client") == 0) {
- heal_xl = _get_ancestor (xl, heal_op);
- if (heal_xl) {
- ret = 0;
- break;
- }
- }
+ ret = dict_get_str(xl->options, "remote-host", &remote_host);
+ if (ret < 0)
+ goto out;
- xl = xl->prev;
- }
+ ret = dict_get_str(xl->options, "remote-subvolume", &remote_subvol);
+ if (ret < 0)
+ goto out;
+out:
+ if (ret < 0)
+ printf("Brick - Not able to get brick information\n");
+ else
+ printf("Brick %s:%s\n", remote_host, remote_subvol);
+ return ret;
+}
- return ret;
+int
+glfsh_print_pending_heals_type(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
+ xlator_t *xl, gf_xl_afr_op_t heal_op,
+ dict_t *xattr_req, char *vgfid,
+ num_entries_t *num_entries)
+{
+ int ret = 0;
+ loc_t dirloc = {0};
+ fd_t *fd = NULL;
+ int32_t op_errno = 0;
+ gf_boolean_t ignore = _gf_false;
+
+ if (!strcmp(vgfid, GF_XATTROP_DIRTY_GFID))
+ ignore = _gf_true;
+
+ ret = glfsh_get_index_dir_loc(rootloc, xl, &dirloc, &op_errno, vgfid);
+ if (ret < 0) {
+ if (op_errno == ESTALE || op_errno == ENOENT || op_errno == ENOTSUP)
+ ret = 0;
+ else
+ ret = -op_errno;
+ goto out;
+ }
+
+ ret = syncop_dirfd(xl, &dirloc, &fd, GF_CLIENT_PID_GLFS_HEAL);
+ if (ret)
+ goto out;
+
+ ret = glfsh_crawl_directory(fs, top_subvol, rootloc, xl, fd, &dirloc,
+ xattr_req, num_entries, ignore);
+ if (fd)
+ fd_unref(fd);
+out:
+ loc_wipe(&dirloc);
+ return ret;
+}
+
+int
+glfsh_print_pending_heals(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
+ xlator_t *xl, gf_xl_afr_op_t heal_op,
+ gf_boolean_t is_parent_replicate)
+{
+ int ret = 0;
+ num_entries_t num_entries = {
+ 0,
+ };
+ num_entries_t total = {
+ 0,
+ };
+
+ dict_t *xattr_req = NULL;
+
+ xattr_req = dict_new();
+ if (!xattr_req)
+ goto out;
+ ret = dict_set_int32(xattr_req, "heal-op", heal_op);
+ if (ret)
+ goto out;
+
+ if ((!is_parent_replicate) &&
+ ((heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE) ||
+ (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_DISABLE))) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = glfsh_output->print_brick_from_xl(xl, rootloc);
+ if (ret < 0)
+ goto out;
+
+ ret = glfsh_print_pending_heals_type(fs, top_subvol, rootloc, xl, heal_op,
+ xattr_req, GF_XATTROP_INDEX_GFID,
+ &num_entries);
+
+ if (ret < 0 && heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE)
+ goto out;
+
+ total.num_entries += num_entries.num_entries;
+ total.pending_entries += num_entries.pending_entries;
+ total.spb_entries += num_entries.spb_entries;
+ total.possibly_healing_entries += num_entries.possibly_healing_entries;
+ num_entries.num_entries = 0;
+ num_entries.pending_entries = 0;
+ num_entries.spb_entries = 0;
+ num_entries.possibly_healing_entries = 0;
+ if (ret == -ENOTCONN)
+ goto out;
+
+ if (is_parent_replicate) {
+ ret = glfsh_print_pending_heals_type(
+ fs, top_subvol, rootloc, xl, heal_op, xattr_req,
+ GF_XATTROP_DIRTY_GFID, &num_entries);
+ total.num_entries += num_entries.num_entries;
+ total.pending_entries += num_entries.pending_entries;
+ total.spb_entries += num_entries.spb_entries;
+ total.possibly_healing_entries += num_entries.possibly_healing_entries;
+ }
+out:
+ if (xattr_req)
+ dict_unref(xattr_req);
+ if (heal_op == GF_SHD_OP_HEAL_SUMMARY) {
+ glfsh_print_info_summary(ret, &total);
+ } else {
+ glfsh_print_heal_op_status(ret, total.num_entries, heal_op);
+ }
+ return ret;
}
-static xlator_t*
-_brick_path_to_client_xlator (xlator_t *top_subvol, char *hostname,
- char *brickpath)
+static int
+glfsh_set_heal_options(glfs_t *fs, gf_xl_afr_op_t heal_op)
{
- int ret = 0;
- xlator_t *xl = NULL;
- char *remote_host = NULL;
- char *remote_subvol = NULL;
+ int ret = 0;
- xl = top_subvol;
+ ret = glfs_set_xlator_option(fs, "*-replicate-*",
+ "background-self-heal-count", "0");
+ if (ret)
+ goto out;
- while (xl->next)
- xl = xl->next;
+ ret = glfs_set_xlator_option(fs, "*-replicate-*", "halo-enabled", "off");
+ if (ret)
+ goto out;
- while (xl) {
- if (!strcmp (xl->type, "protocol/client")) {
- ret = dict_get_str (xl->options, "remote-host",
- &remote_host);
- if (ret < 0)
- goto out;
- ret = dict_get_str (xl->options,
- "remote-subvolume", &remote_subvol);
- if (ret < 0)
- goto out;
- if (!strcmp (hostname, remote_host) &&
- !strcmp (brickpath, remote_subvol))
- return xl;
- }
- xl = xl->prev;
- }
+ if ((heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE) &&
+ (heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) &&
+ (heal_op != GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME))
+ return 0;
+ ret = glfs_set_xlator_option(fs, "*-replicate-*", "data-self-heal", "on");
+ if (ret)
+ goto out;
+
+ ret = glfs_set_xlator_option(fs, "*-replicate-*", "metadata-self-heal",
+ "on");
+ if (ret)
+ goto out;
+
+ ret = glfs_set_xlator_option(fs, "*-replicate-*", "entry-self-heal", "on");
out:
- return NULL;
+ return ret;
}
+static int
+glfsh_validate_volume(xlator_t *xl, gf_xl_afr_op_t heal_op)
+{
+ xlator_t *heal_xl = NULL;
+ int ret = -1;
-int
-glfsh_gather_heal_info (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
- gf_xl_afr_op_t heal_op)
+ while (xl->next)
+ xl = xl->next;
+
+ while (xl) {
+ if (strcmp(xl->type, "protocol/client") == 0) {
+ heal_xl = _get_ancestor(xl, heal_op);
+ if (heal_xl) {
+ ret = 0;
+ break;
+ }
+ }
+
+ xl = xl->prev;
+ }
+
+ return ret;
+}
+
+static xlator_t *
+_brick_path_to_client_xlator(xlator_t *top_subvol, char *hostname,
+ char *brickpath)
{
- xlator_t *xl = NULL;
- xlator_t *heal_xl = NULL;
- xlator_t *old_THIS = NULL;
+ int ret = 0;
+ xlator_t *xl = NULL;
+ char *remote_host = NULL;
+ char *remote_subvol = NULL;
- xl = top_subvol;
- while (xl->next)
- xl = xl->next;
- while (xl) {
- if (strcmp (xl->type, "protocol/client") == 0) {
- heal_xl = _get_ancestor (xl, heal_op);
- if (heal_xl) {
- old_THIS = THIS;
- THIS = heal_xl;
- glfsh_print_pending_heals (fs, top_subvol,
- rootloc, xl,
- heal_op);
- THIS = old_THIS;
- printf ("\n");
- }
- }
+ xl = top_subvol;
- xl = xl->prev;
+ while (xl->next)
+ xl = xl->next;
+
+ while (xl) {
+ if (!strcmp(xl->type, "protocol/client")) {
+ ret = dict_get_str(xl->options, "remote-host", &remote_host);
+ if (ret < 0)
+ goto out;
+ ret = dict_get_str(xl->options, "remote-subvolume", &remote_subvol);
+ if (ret < 0)
+ goto out;
+ if (!strcmp(hostname, remote_host) &&
+ !strcmp(brickpath, remote_subvol))
+ return xl;
}
+ xl = xl->prev;
+ }
- return 0;
+out:
+ return NULL;
}
int
-_validate_directory (dict_t *xattr_req, char *file)
+glfsh_gather_heal_info(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
+ gf_xl_afr_op_t heal_op)
{
- int heal_op = -1;
- int ret = 0;
+ int ret = 0;
+ xlator_t *xl = NULL;
+ xlator_t *heal_xl = NULL;
+ xlator_t *old_THIS = NULL;
+
+ xl = top_subvol;
+ while (xl->next)
+ xl = xl->next;
+ while (xl) {
+ if (strcmp(xl->type, "protocol/client") == 0 &&
+ !strstr(xl->name, "-ta-")) {
+ heal_xl = _get_ancestor(xl, heal_op);
+ if (heal_xl) {
+ old_THIS = THIS;
+ THIS = heal_xl;
+ ret = glfsh_print_pending_heals(
+ fs, top_subvol, rootloc, xl, heal_op,
+ !strcmp(heal_xl->type, "cluster/replicate"));
+ THIS = old_THIS;
+
+ if ((ret < 0) &&
+ (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE))
+ goto out;
+ }
+ }
- ret = dict_get_int32 (xattr_req, "heal-op", &heal_op);
- if (ret)
- return ret;
+ xl = xl->prev;
+ }
- if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE) {
- printf ("'bigger-file' not a valid option for directories.\n");
- ret = -1;
- } else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) {
- printf ("'source-brick' option used on a directory (%s). "
- "Performing conservative merge.\n", file);
- }
+out:
+ if (heal_op != GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE)
+ ret = 0;
+ return ret;
+}
+
+int
+_validate_directory(dict_t *xattr_req, char *file)
+{
+ int heal_op = -1;
+ int ret = 0;
+
+ ret = dict_get_int32(xattr_req, "heal-op", &heal_op);
+ if (ret)
return ret;
+
+ if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE) {
+ printf("'bigger-file' not a valid option for directories.\n");
+ ret = -1;
+ } else if (heal_op == GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK) {
+ printf(
+ "'source-brick' option used on a directory (%s). "
+ "Performing conservative merge.\n",
+ file);
+ }
+
+ return ret;
}
int
-glfsh_heal_splitbrain_file (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
+glfsh_heal_splitbrain_file(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
char *file, dict_t *xattr_req)
{
- int ret = -1;
- int reval = 0;
- loc_t loc = {0, };
- char *path = NULL;
- char *filename = NULL;
- struct iatt iatt = {0, };
- xlator_t *xl = top_subvol;
- dict_t *xattr_rsp = NULL;
- char *sh_fail_msg = NULL;
- int32_t op_errno = 0;
-
- if (!strncmp (file, "gfid:", 5)) {
- filename = gf_strdup(file);
- path = strtok (filename, ":");
- path = strtok (NULL, ";");
- gf_uuid_parse (path, loc.gfid);
- loc.path = gf_strdup (uuid_utoa (loc.gfid));
- loc.inode = inode_new (rootloc->inode->table);
- ret = syncop_lookup (xl, &loc, &iatt, 0, xattr_req, &xattr_rsp);
- if (ret) {
- op_errno = -ret;
- printf ("Lookup failed on %s:%s.\n", file,
- strerror(op_errno));
- goto out;
- }
- } else {
- if (file[0] != '/') {
- printf ("<FILE> must be absolute path w.r.t. the "
- "volume, starting with '/'\n");
- ret = -1;
- goto out;
- }
-retry:
- ret = glfs_resolve (fs, xl, file, &loc, &iatt, reval);
- ESTALE_RETRY (ret, errno, reval, &loc, retry);
- if (ret) {
- printf("Lookup failed on %s:%s\n",
- file, strerror (errno));
- goto out;
- }
- }
-
- if (iatt.ia_type == IA_IFDIR) {
- ret = _validate_directory (xattr_req, file);
- if (ret)
- goto out;
- }
- ret = syncop_getxattr (xl, &loc, &xattr_rsp, GF_AFR_HEAL_SBRAIN,
- xattr_req, NULL);
+ int ret = -1;
+ int reval = 0;
+ loc_t loc = {
+ 0,
+ };
+ char *path = NULL;
+ char *path1 = NULL;
+ char *path2 = NULL;
+ char *filename = NULL;
+ char *filename1 = NULL;
+ struct iatt iatt = {
+ 0,
+ };
+ xlator_t *xl = top_subvol;
+ dict_t *xattr_rsp = NULL;
+ char *sh_fail_msg = NULL;
+ char *gfid_heal_msg = NULL;
+ int32_t op_errno = 0;
+ gf_boolean_t flag = _gf_false;
+
+ if (!strncmp(file, "gfid:", 5)) {
+ filename = gf_strdup(file);
+ if (!filename) {
+ printf("Error allocating memory to filename\n");
+ goto out;
+ }
+ path = strtok(filename, ":");
+ path = strtok(NULL, ";");
+ gf_uuid_parse(path, loc.gfid);
+ loc.path = gf_strdup(uuid_utoa(loc.gfid));
+ if (!loc.path) {
+ printf("Error allocating memory to path\n");
+ goto out;
+ }
+ loc.inode = inode_new(rootloc->inode->table);
+ if (!loc.inode) {
+ printf("Error getting inode\n");
+ goto out;
+ }
+ ret = syncop_lookup(xl, &loc, &iatt, 0, xattr_req, &xattr_rsp);
if (ret) {
- op_errno = -ret;
- printf ("Healing %s failed:%s.\n", file, strerror(op_errno));
- goto out;
+ op_errno = -ret;
+ printf("Lookup failed on %s:%s.\n", file, strerror(op_errno));
+ goto out;
+ }
+ } else {
+ if (file[0] != '/') {
+ printf(
+ "<FILE> must be absolute path w.r.t. the "
+ "volume, starting with '/'\n");
+ ret = -1;
+ goto out;
+ }
+ path1 = gf_strdup(file);
+ if (!path1) {
+ printf("Error allocating memory to path\n");
+ ret = -1;
+ goto out;
+ }
+ path2 = gf_strdup(file);
+ if (!path2) {
+ printf("Error allocating memory to path\n");
+ ret = -1;
+ goto out;
+ }
+ path = dirname(path1);
+ filename1 = basename(path2);
+ retry1:
+ ret = glfs_resolve(fs, xl, path, &loc, &iatt, reval);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry1);
+ if (ret) {
+ printf("Lookup failed on %s:%s\n", path, strerror(errno));
+ goto out;
+ }
+ GF_FREE((char *)loc.path);
+ loc.path = gf_strdup(file);
+ if (!loc.path) {
+ printf("Error allocating memory for path\n");
+ ret = -1;
+ goto out;
+ }
+ loc.parent = inode_unref(loc.parent);
+ loc.parent = inode_ref(loc.inode);
+ loc.inode = inode_unref(loc.inode);
+ loc.inode = inode_new(rootloc->inode->table);
+ if (!loc.inode) {
+ printf("Error getting inode\n");
+ ret = -1;
+ goto out;
+ }
+ loc.name = filename1;
+ gf_uuid_copy(loc.pargfid, loc.gfid);
+ gf_uuid_clear(loc.gfid);
+
+ ret = syncop_lookup(xl, &loc, &iatt, 0, xattr_req, &xattr_rsp);
+ if (ret) {
+ op_errno = -ret;
+ printf("Lookup failed on %s:%s.\n", file, strerror(op_errno));
+ flag = _gf_true;
}
- ret = dict_get_str (xattr_rsp, "sh-fail-msg", &sh_fail_msg);
+
+ ret = dict_get_str(xattr_rsp, "gfid-heal-msg", &gfid_heal_msg);
if (!ret) {
- printf ("Healing %s failed: %s.\n", file, sh_fail_msg);
- ret = -1;
- goto out;
+ printf("%s for file %s\n", gfid_heal_msg, file);
+ loc_wipe(&loc);
+ goto out;
}
- printf ("Healed %s.\n", file);
- ret = 0;
+ if (flag)
+ goto out;
+
+ reval = 0;
+ loc_wipe(&loc);
+ memset(&iatt, 0, sizeof(iatt));
+
+ retry2:
+ ret = glfs_resolve(fs, xl, file, &loc, &iatt, reval);
+ ESTALE_RETRY(ret, errno, reval, &loc, retry2);
+ if (ret) {
+ printf("Lookup failed on %s:%s\n", file, strerror(errno));
+ goto out;
+ }
+ }
+
+ if (iatt.ia_type == IA_IFDIR) {
+ ret = _validate_directory(xattr_req, file);
+ if (ret)
+ goto out;
+ }
+ ret = syncop_getxattr(xl, &loc, &xattr_rsp, GF_AFR_HEAL_SBRAIN, xattr_req,
+ NULL);
+ if (ret) {
+ op_errno = -ret;
+ printf("Healing %s failed:%s.\n", file, strerror(op_errno));
+ goto out;
+ }
+ ret = dict_get_str(xattr_rsp, "sh-fail-msg", &sh_fail_msg);
+ if (!ret) {
+ printf("Healing %s failed: %s.\n", file, sh_fail_msg);
+ ret = -1;
+ goto out;
+ }
+ printf("Healed %s.\n", file);
+ ret = 0;
out:
- if (xattr_rsp)
- dict_unref (xattr_rsp);
- return ret;
+ if (xattr_rsp)
+ dict_unref(xattr_rsp);
+ if (path1)
+ GF_FREE(path1);
+ if (path2)
+ GF_FREE(path2);
+ if (filename)
+ GF_FREE(filename);
+ loc_wipe(&loc);
+ return ret;
}
int
-glfsh_heal_from_brick (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
- char *hostname, char *brickpath, char *file)
+glfsh_heal_from_brick_type(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
+ char *hostname, char *brickpath, xlator_t *client,
+ dict_t *xattr_req, char *vgfid,
+ num_entries_t *num_entries)
{
- int ret = -1;
- dict_t *xattr_req = NULL;
- xlator_t *client = NULL;
- fd_t *fd = NULL;
- loc_t dirloc = {0};
- int32_t op_errno = 0;
-
- xattr_req = dict_new();
- if (!xattr_req)
- goto out;
- ret = dict_set_int32 (xattr_req, "heal-op",
- GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
- if (ret)
- goto out;
- client = _brick_path_to_client_xlator (top_subvol, hostname, brickpath);
- if (!client) {
- printf("\"%s:%s\"- No such brick available in the volume.\n",
- hostname, brickpath);
- ret = -1;
- goto out;
- }
- ret = dict_set_str (xattr_req, "child-name", client->name);
- if (ret)
- goto out;
- if (file)
- ret = glfsh_heal_splitbrain_file (fs, top_subvol, rootloc, file,
- xattr_req);
- else {
- ret = glfsh_get_index_dir_loc (rootloc, client, &dirloc,
- &op_errno);
- ret = syncop_dirfd (client, &dirloc, &fd,
- GF_CLIENT_PID_GLFS_HEAL);
- if (ret)
- goto out;
- ret = glfsh_crawl_directory (fs, top_subvol, rootloc, client,
- fd, &dirloc, xattr_req);
- if (fd)
- fd_unref (fd);
- }
+ fd_t *fd = NULL;
+ loc_t dirloc = {0};
+ int32_t op_errno = 0;
+ int ret = -1;
+
+ ret = glfsh_get_index_dir_loc(rootloc, client, &dirloc, &op_errno, vgfid);
+ if (ret < 0) {
+ if (op_errno == ESTALE || op_errno == ENOENT)
+ ret = 0;
+ else
+ ret = -op_errno;
+ goto out;
+ }
+
+ ret = syncop_dirfd(client, &dirloc, &fd, GF_CLIENT_PID_GLFS_HEAL);
+ if (ret)
+ goto out;
+ ret = glfsh_crawl_directory(fs, top_subvol, rootloc, client, fd, &dirloc,
+ xattr_req, num_entries, _gf_false);
+ if (fd)
+ fd_unref(fd);
out:
- if (xattr_req)
- dict_unref (xattr_req);
- loc_wipe (&dirloc);
- return ret;
+ loc_wipe(&dirloc);
+ return ret;
}
int
-glfsh_heal_from_bigger_file (glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
- char *file)
+glfsh_heal_from_brick(glfs_t *fs, xlator_t *top_subvol, loc_t *rootloc,
+ char *hostname, char *brickpath, char *file)
{
+ int ret = -1;
+ dict_t *xattr_req = NULL;
+ xlator_t *client = NULL;
+ num_entries_t num_entries = {
+ 0,
+ };
+ num_entries_t total = {
+ 0,
+ };
+
+ xattr_req = dict_new();
+ if (!xattr_req)
+ goto out;
+ ret = dict_set_int32(xattr_req, "heal-op",
+ GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
+ if (ret)
+ goto out;
+ client = _brick_path_to_client_xlator(top_subvol, hostname, brickpath);
+ if (!client) {
+ printf("\"%s:%s\"- No such brick available in the volume.\n", hostname,
+ brickpath);
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_str(xattr_req, "child-name", client->name);
+ if (ret)
+ goto out;
+ if (file)
+ ret = glfsh_heal_splitbrain_file(fs, top_subvol, rootloc, file,
+ xattr_req);
+ else {
+ ret = glfsh_heal_from_brick_type(fs, top_subvol, rootloc, hostname,
+ brickpath, client, xattr_req,
+ GF_XATTROP_INDEX_GFID, &num_entries);
+ total.num_entries += num_entries.num_entries;
+ num_entries.num_entries = 0;
+ if (ret == -ENOTCONN)
+ goto out;
+
+ ret = glfsh_heal_from_brick_type(fs, top_subvol, rootloc, hostname,
+ brickpath, client, xattr_req,
+ GF_XATTROP_DIRTY_GFID, &num_entries);
+ total.num_entries += num_entries.num_entries;
+ if (ret < 0)
+ goto out;
+ }
+out:
+ if (xattr_req)
+ dict_unref(xattr_req);
+ if (!file)
+ glfsh_print_heal_op_status(ret, total.num_entries,
+ GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
- int ret = -1;
- dict_t *xattr_req = NULL;
+ return ret;
+}
- xattr_req = dict_new();
- if (!xattr_req)
- goto out;
- ret = dict_set_int32 (xattr_req, "heal-op",
- GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE);
- if (ret)
- goto out;
- ret = glfsh_heal_splitbrain_file (fs, top_subvol, rootloc, file,
- xattr_req);
+int
+glfsh_heal_from_bigger_file_or_mtime(glfs_t *fs, xlator_t *top_subvol,
+ loc_t *rootloc, char *file,
+ gf_xl_afr_op_t heal_op)
+{
+ int ret = -1;
+ dict_t *xattr_req = NULL;
+
+ xattr_req = dict_new();
+ if (!xattr_req)
+ goto out;
+ ret = dict_set_int32(xattr_req, "heal-op", heal_op);
+ if (ret)
+ goto out;
+ ret = glfsh_heal_splitbrain_file(fs, top_subvol, rootloc, file, xattr_req);
out:
- if (xattr_req)
- dict_unref (xattr_req);
- return ret;
+ if (xattr_req)
+ dict_unref(xattr_req);
+ return ret;
}
static void
-cleanup (glfs_t *fs)
+cleanup(glfs_t *fs)
{
- if (!fs)
- return;
+ if (!fs)
+ return;
#if 0
/* glfs fini path is still racy and crashing the program. Since
- * this program any way has to die, we are not gonna call fini
+ * this program any way has to die, we are not going to call fini
* in the released versions. i.e. final builds. For all
* internal testing lets enable this so that glfs_fini code
* path becomes stable. */
@@ -715,158 +1486,308 @@ cleanup (glfs_t *fs)
#endif
}
-int
-main (int argc, char **argv)
+glfsh_info_t glfsh_human_readable = {
+ .init = glfsh_init,
+ .print_brick_from_xl = glfsh_print_brick_from_xl,
+ .print_heal_op_status = glfsh_print_hr_heal_op_status,
+ .print_heal_op_summary = glfsh_print_hr_heal_op_summary,
+ .print_heal_status = glfsh_print_hr_heal_status,
+ .print_spb_status = glfsh_print_hr_spb_status,
+ .end = glfsh_end};
+
+glfsh_info_t glfsh_no_print = {
+ .init = glfsh_init,
+ .print_brick_from_xl = glfsh_no_print_brick_from_xl,
+ .print_heal_op_status = glfsh_no_print_hr_heal_op_status,
+ .print_heal_status = glfsh_no_print_hr_status,
+ .print_spb_status = glfsh_no_print_hr_status,
+ .end = glfsh_end_op_granular_entry_heal};
+
+#if (HAVE_LIB_XML)
+glfsh_info_t glfsh_xml_output = {
+ .init = glfsh_xml_init,
+ .print_brick_from_xl = glfsh_print_xml_brick_from_xl,
+ .print_heal_op_status = glfsh_print_xml_heal_op_status,
+ .print_heal_op_summary = glfsh_print_xml_heal_op_summary,
+ .print_heal_status = glfsh_print_xml_file_status,
+ .print_spb_status = glfsh_print_xml_file_status,
+ .end = glfsh_xml_end};
+#endif
+
+static void
+parse_flags(int *argc, char **argv, int *flags)
{
- glfs_t *fs = NULL;
- int ret = 0;
- char *volname = NULL;
- xlator_t *top_subvol = NULL;
- loc_t rootloc = {0};
- char logfilepath[PATH_MAX] = {0};
- char *hostname = NULL;
- char *path = NULL;
- char *file = NULL;
- gf_xl_afr_op_t heal_op = -1;
+ int i = 0;
+ char *opt = NULL;
+ int count = 0;
+
+ for (i = 0; i < *argc; i++) {
+ opt = strtail(argv[i], "--");
+ if (!opt)
+ continue;
+ if (strcmp(opt, "nolog") == 0) {
+ *flags |= MODE_NO_LOG;
+ count++;
+ } else if (strcmp(opt, "xml") == 0) {
+ *flags |= MODE_XML;
+ count++;
+ }
+ }
+ *argc = *argc - count;
+}
- if (argc < 2) {
- printf (USAGE_STR, argv[0]);
- ret = -1;
- goto out;
+int
+main(int argc, char **argv)
+{
+ glfs_t *fs = NULL;
+ int ret = 0;
+ char *volname = NULL;
+ xlator_t *top_subvol = NULL;
+ loc_t rootloc = {0};
+ char logfilepath[PATH_MAX] = {0};
+ char *hostname = NULL;
+ char *path = NULL;
+ char *file = NULL;
+ char *op_errstr = NULL;
+ char *socket_filepath = NULL;
+ gf_xl_afr_op_t heal_op = -1;
+ gf_loglevel_t log_level = GF_LOG_INFO;
+ int flags = 0;
+
+ if (argc < 2) {
+ printf(USAGE_STR, argv[0]);
+ ret = -1;
+ goto out;
+ } else if (argc >= 4) {
+ if (!strcmp(argv[argc - 2], "glusterd-sock")) {
+ socket_filepath = argv[argc - 1];
+ argc = argc - 2;
}
- volname = argv[1];
- switch (argc) {
+ }
+ volname = argv[1];
+
+ parse_flags(&argc, argv, &flags);
+ if (flags & MODE_NO_LOG)
+ log_level = GF_LOG_NONE;
+ if (flags & MODE_XML)
+ is_xml = 1;
+
+ switch (argc) {
case 2:
- heal_op = GF_SHD_OP_INDEX_SUMMARY;
- break;
+ heal_op = GF_SHD_OP_INDEX_SUMMARY;
+ break;
case 3:
- if (!strcmp (argv[2], "split-brain-info")) {
- heal_op = GF_SHD_OP_SPLIT_BRAIN_FILES;
- } else {
- printf (USAGE_STR, argv[0]);
- ret = -1;
- goto out;
- }
- break;
- case 4:
- if (!strcmp (argv[2], "bigger-file")) {
- heal_op = GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE;
- file = argv[3];
- } else if (!strcmp (argv[2], "source-brick")) {
- heal_op = GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK;
- hostname = strtok (argv[3], ":");
- path = strtok (NULL, ":");
- } else {
- printf (USAGE_STR, argv[0]);
- ret = -1;
- goto out;
- }
- break;
- case 5:
- if (!strcmp (argv[2], "source-brick")) {
- heal_op = GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK;
- hostname = strtok (argv[3], ":");
- path = strtok (NULL, ":");
- file = argv[4];
- } else {
- printf (USAGE_STR, argv[0]);
- ret = -1;
- goto out;
- }
- break;
- default:
- printf (USAGE_STR, argv[0]);
+ if (!strcmp(argv[2], "split-brain-info")) {
+ heal_op = GF_SHD_OP_SPLIT_BRAIN_FILES;
+ } else if (!strcmp(argv[2], "granular-entry-heal-op")) {
+ heal_op = GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE;
+ } else if (!strcmp(argv[2], "info-summary")) {
+ heal_op = GF_SHD_OP_HEAL_SUMMARY;
+ } else {
+ printf(USAGE_STR, argv[0]);
ret = -1;
goto out;
- }
-
- fs = glfs_new (volname);
- if (!fs) {
+ }
+ break;
+ case 4:
+ if (!strcmp(argv[2], "bigger-file")) {
+ heal_op = GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE;
+ file = argv[3];
+ } else if (!strcmp(argv[2], "latest-mtime")) {
+ heal_op = GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME;
+ file = argv[3];
+ } else if (!strcmp(argv[2], "source-brick")) {
+ heal_op = GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK;
+ hostname = strtok(argv[3], ":");
+ path = strtok(NULL, ":");
+ } else {
+ printf(USAGE_STR, argv[0]);
ret = -1;
- printf ("Not able to initialize volume '%s'\n", volname);
goto out;
- }
-
- ret = glfs_set_volfile_server (fs, "tcp", "localhost", 24007);
- if (ret) {
- printf("Setting the volfile server failed, %s\n", strerror (errno));
- goto out;
- }
- snprintf (logfilepath, sizeof (logfilepath),
- DEFAULT_HEAL_LOG_FILE_DIRECTORY"/glfsheal-%s.log", volname);
- ret = glfs_set_logging(fs, logfilepath, GF_LOG_INFO);
- if (ret < 0) {
- printf ("Failed to set the log file path, %s\n", strerror (errno));
- goto out;
- }
-
- ret = glfs_init (fs);
- if (ret < 0) {
+ }
+ break;
+ case 5:
+ if (!strcmp(argv[2], "source-brick")) {
+ heal_op = GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK;
+ hostname = strtok(argv[3], ":");
+ path = strtok(NULL, ":");
+ file = argv[4];
+ } else {
+ printf(USAGE_STR, argv[0]);
ret = -1;
- if (errno == ENOENT) {
- printf ("Volume %s does not exist\n", volname);
- }
- else {
- printf ("%s: Not able to fetch volfile from "
- "glusterd\n", volname);
- }
goto out;
+ }
+ break;
+ default:
+ printf(USAGE_STR, argv[0]);
+ ret = -1;
+ goto out;
+ }
+
+ glfsh_output = &glfsh_human_readable;
+ if (is_xml) {
+#if (HAVE_LIB_XML)
+ if ((heal_op == GF_SHD_OP_INDEX_SUMMARY) ||
+ (heal_op == GF_SHD_OP_SPLIT_BRAIN_FILES) ||
+ (heal_op == GF_SHD_OP_HEAL_SUMMARY)) {
+ glfsh_output = &glfsh_xml_output;
+ } else {
+ printf(USAGE_STR, argv[0]);
+ ret = -1;
+ goto out;
}
-
- sleep (2);
- top_subvol = glfs_active_subvol (fs);
- if (!top_subvol) {
- ret = -1;
- if (errno == ENOTCONN) {
- printf ("Volume %s is not started (Or) All the bricks "
- "are not running.\n", volname);
- }
- else {
- printf ("%s: Not able to mount the volume, %s\n",
- volname, strerror (errno));
- }
- goto out;
+#else
+ /*No point doing anything, just fail the command*/
+ exit(EXIT_FAILURE);
+#endif
+ }
+
+ if (heal_op == GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE)
+ glfsh_output = &glfsh_no_print;
+
+ ret = glfsh_output->init();
+ if (ret)
+ exit(EXIT_FAILURE);
+
+ fs = glfs_new(volname);
+ if (!fs) {
+ ret = -errno;
+ gf_asprintf(&op_errstr, "Not able to initialize volume '%s'", volname);
+ goto out;
+ }
+
+ if (sys_access(SECURE_ACCESS_FILE, F_OK) == 0) {
+ fs->ctx->secure_mgmt = 1;
+ fs->ctx->ssl_cert_depth = glusterfs_read_secure_access_file();
+ }
+ if (socket_filepath != NULL) {
+ ret = glfs_set_volfile_server(fs, "unix", socket_filepath, 0);
+ } else {
+ ret = glfs_set_volfile_server(fs, "unix", DEFAULT_GLUSTERD_SOCKFILE, 0);
+ }
+ if (ret) {
+ ret = -errno;
+ gf_asprintf(&op_errstr,
+ "Setting the volfile server failed, "
+ "%s",
+ strerror(errno));
+ goto out;
+ }
+
+ ret = glfsh_set_heal_options(fs, heal_op);
+ if (ret) {
+ printf("Setting xlator heal options failed, %s\n", strerror(errno));
+ goto out;
+ }
+ snprintf(logfilepath, sizeof(logfilepath),
+ DEFAULT_HEAL_LOG_FILE_DIRECTORY "/glfsheal-%s.log", volname);
+ ret = glfs_set_logging(fs, logfilepath, log_level);
+ if (ret < 0) {
+ ret = -errno;
+ gf_asprintf(&op_errstr,
+ "Failed to set the log file path, "
+ "%s",
+ strerror(errno));
+ goto out;
+ }
+
+ ret = glfs_setfspid(fs, GF_CLIENT_PID_GLFS_HEAL);
+ if (ret) {
+ printf("Setting client pid failed, %s\n", strerror(errno));
+ goto out;
+ }
+
+ ret = glfs_init(fs);
+ if (ret < 0) {
+ ret = -errno;
+ if (errno == ENOENT) {
+ gf_asprintf(&op_errstr, "Volume %s does not exist", volname);
+ } else {
+ gf_asprintf(&op_errstr,
+ "%s: Not able to fetch "
+ "volfile from glusterd",
+ volname);
}
-
- ret = glfsh_validate_volume (top_subvol, heal_op);
- if (ret < 0) {
- printf ("Volume %s is not of type %s\n", volname,
- (heal_op == GF_SHD_OP_INDEX_SUMMARY) ?
- "replicate/disperse":"replicate");
- goto out;
+ goto out;
+ }
+
+ top_subvol = glfs_active_subvol(fs);
+ if (!top_subvol) {
+ ret = -errno;
+ if (errno == ENOTCONN) {
+ gf_asprintf(&op_errstr,
+ "Volume %s is not started "
+ "(Or) All the bricks are not "
+ "running.",
+ volname);
+ } else {
+ gf_asprintf(&op_errstr,
+ "%s: Not able to mount the "
+ "volume, %s",
+ volname, strerror(errno));
}
- rootloc.inode = inode_ref (top_subvol->itable->root);
- glfs_loc_touchup (&rootloc);
-
- switch (heal_op) {
+ goto out;
+ }
+
+ char *var_str = (heal_op == GF_SHD_OP_INDEX_SUMMARY ||
+ heal_op == GF_SHD_OP_HEAL_SUMMARY)
+ ? "replicate/disperse"
+ : "replicate";
+
+ ret = glfsh_validate_volume(top_subvol, heal_op);
+ if (ret < 0) {
+ ret = -EINVAL;
+ gf_asprintf(&op_errstr,
+ "This command is supported "
+ "for only volumes of %s type. Volume %s "
+ "is not of type %s",
+ var_str, volname, var_str);
+ goto out;
+ }
+ rootloc.inode = inode_ref(top_subvol->itable->root);
+ ret = glfs_loc_touchup(&rootloc);
+ if (ret < 0) {
+ ret = -errno;
+ goto out;
+ }
+
+ switch (heal_op) {
case GF_SHD_OP_INDEX_SUMMARY:
case GF_SHD_OP_SPLIT_BRAIN_FILES:
- ret = glfsh_gather_heal_info (fs, top_subvol, &rootloc,
- heal_op);
- break;
+ case GF_SHD_OP_GRANULAR_ENTRY_HEAL_ENABLE:
+ case GF_SHD_OP_HEAL_SUMMARY:
+ ret = glfsh_gather_heal_info(fs, top_subvol, &rootloc, heal_op);
+ break;
case GF_SHD_OP_SBRAIN_HEAL_FROM_BIGGER_FILE:
- ret = glfsh_heal_from_bigger_file (fs, top_subvol,
- &rootloc, file);
- break;
+ case GF_SHD_OP_SBRAIN_HEAL_FROM_LATEST_MTIME:
+ ret = glfsh_heal_from_bigger_file_or_mtime(fs, top_subvol, &rootloc,
+ file, heal_op);
+ break;
case GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK:
- ret = glfsh_heal_from_brick (fs, top_subvol, &rootloc,
- hostname, path, file);
- break;
+ ret = glfsh_heal_from_brick(fs, top_subvol, &rootloc, hostname,
+ path, file);
+ break;
default:
- ret = -1;
- break;
- }
-
- loc_wipe (&rootloc);
- glfs_subvol_done (fs, top_subvol);
- cleanup (fs);
-
- return ret;
+ ret = -EINVAL;
+ break;
+ }
+
+ glfsh_output->end(ret, NULL);
+ if (ret < 0)
+ ret = -ret;
+ loc_wipe(&rootloc);
+ glfs_subvol_done(fs, top_subvol);
+ cleanup(fs);
+
+ return ret;
out:
- if (fs && top_subvol)
- glfs_subvol_done (fs, top_subvol);
- loc_wipe (&rootloc);
- cleanup (fs);
-
- return ret;
+ if (fs && top_subvol)
+ glfs_subvol_done(fs, top_subvol);
+ loc_wipe(&rootloc);
+ cleanup(fs);
+ if (glfsh_output)
+ glfsh_output->end(ret, op_errstr);
+ if (op_errstr)
+ GF_FREE(op_errstr);
+ return ret;
}
diff --git a/libgfchangelog.pc.in b/libgfchangelog.pc.in
index 91c85e6f1f8..79eac2ad2d3 100644
--- a/libgfchangelog.pc.in
+++ b/libgfchangelog.pc.in
@@ -9,4 +9,4 @@ Description: GlusterFS Changelog Consumer Library
Version: @LIBGFCHANGELOG_VERSION@
Requires: @PKGCONFIG_UUID@
Libs: -L${libdir} -lgfchangelog -lglusterfs
-Cflags: -I${includedir}/glusterfs/gfchangelog -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64
+Cflags: -I${includedir} -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D__USE_LARGEFILE64
diff --git a/libgfdb.pc.in b/libgfdb.pc.in
deleted file mode 100644
index 945685cde98..00000000000
--- a/libgfdb.pc.in
+++ /dev/null
@@ -1,12 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-
-Name: libgfdb
-Description: GlusterFS Database Library
-Version: @LIBGFDB_VERSION@
-Libs: -L${libdir} -lgfchangedb -lglusterfs
-Cflags: -I${includedir}/glusterfs/gfdb
-Requires: sqlite3 @PKGCONFIG_UUID@
diff --git a/xlators/features/changetimerecorder/Makefile.am b/libglusterd/Makefile.am
index a985f42a877..a985f42a877 100644
--- a/xlators/features/changetimerecorder/Makefile.am
+++ b/libglusterd/Makefile.am
diff --git a/libglusterd/src/Makefile.am b/libglusterd/src/Makefile.am
new file mode 100644
index 00000000000..684d2bac96b
--- /dev/null
+++ b/libglusterd/src/Makefile.am
@@ -0,0 +1,31 @@
+libglusterd_la_CFLAGS = $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \
+ -DDATADIR=\"$(localstatedir)\"
+
+libglusterd_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \
+ -DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \
+ -DXLATORPARENTDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)\" \
+ -DXXH_NAMESPACE=GF_ -D__USE_LARGEFILE64 \
+ -I$(CONTRIBDIR)/rbtree \
+ -I$(CONTRIBDIR)/libexecinfo ${ARGP_STANDALONE_CPPFLAGS} \
+ -DSBIN_DIR=\"$(sbindir)\" -I$(CONTRIBDIR)/timer-wheel \
+ -I$(CONTRIBDIR)/xxhash \
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_builddir)/rpc/xdr/src \
+ -I$(top_srcdir)/rpc/rpc-lib/src/
+
+libglusterd_la_LIBADD = $(ZLIB_LIBS) $(MATH_LIB) $(UUID_LIBS)
+libglusterd_la_LDFLAGS = -version-info $(LIBGLUSTERFS_LT_VERSION) $(GF_LDFLAGS) \
+ -export-symbols $(top_srcdir)/libglusterd/src/libglusterd.sym
+
+lib_LTLIBRARIES = libglusterd.la
+
+libglusterd_la_SOURCES = gd-common-utils.c
+
+libglusterd_la_HEADERS = gd-common-utils.h
+
+libglusterd_ladir = $(includedir)/glusterfs
+
+noinst_HEADERS = gd-common-utils.h
+
+EXTRA_DIST = libglusterd.sym
+
+CLEANFILES =
diff --git a/libglusterd/src/gd-common-utils.c b/libglusterd/src/gd-common-utils.c
new file mode 100644
index 00000000000..243fab215e6
--- /dev/null
+++ b/libglusterd/src/gd-common-utils.c
@@ -0,0 +1,78 @@
+/*
+ Copyright (c) 2019 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 "gd-common-utils.h"
+#include "cli1-xdr.h"
+
+int
+get_vol_type(int type, int dist_count, int brick_count)
+{
+ if ((type != GF_CLUSTER_TYPE_TIER) && (type > 0) &&
+ (dist_count < brick_count))
+ type = type + GF_CLUSTER_TYPE_MAX - 1;
+
+ return type;
+}
+
+char *
+get_struct_variable(int mem_num, gf_gsync_status_t *sts_val)
+{
+ switch (mem_num) {
+ case 0:
+ return (sts_val->node);
+ case 1:
+ return (sts_val->master);
+ case 2:
+ return (sts_val->brick);
+ case 3:
+ return (sts_val->slave_user);
+ case 4:
+ return (sts_val->slave);
+ case 5:
+ return (sts_val->slave_node);
+ case 6:
+ return (sts_val->worker_status);
+ case 7:
+ return (sts_val->crawl_status);
+ case 8:
+ return (sts_val->last_synced);
+ case 9:
+ return (sts_val->entry);
+ case 10:
+ return (sts_val->data);
+ case 11:
+ return (sts_val->meta);
+ case 12:
+ return (sts_val->failures);
+ case 13:
+ return (sts_val->checkpoint_time);
+ case 14:
+ return (sts_val->checkpoint_completed);
+ case 15:
+ return (sts_val->checkpoint_completion_time);
+ case 16:
+ return (sts_val->brick_host_uuid);
+ case 17:
+ return (sts_val->last_synced_utc);
+ case 18:
+ return (sts_val->checkpoint_time_utc);
+ case 19:
+ return (sts_val->checkpoint_completion_time_utc);
+ case 20:
+ return (sts_val->slavekey);
+ case 21:
+ return (sts_val->session_slave);
+ default:
+ goto out;
+ }
+
+out:
+ return NULL;
+}
diff --git a/libglusterd/src/gd-common-utils.h b/libglusterd/src/gd-common-utils.h
new file mode 100644
index 00000000000..b9bb4f956fe
--- /dev/null
+++ b/libglusterd/src/gd-common-utils.h
@@ -0,0 +1,28 @@
+/*
+ Copyright (c) 2019 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 _GD_COMMON_UTILS_H
+#define _GD_COMMON_UTILS_H
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stddef.h>
+
+#include "protocol-common.h"
+#include "rpcsvc.h"
+
+int
+get_vol_type(int type, int dist_count, int brick_count);
+
+char *
+get_struct_variable(int mem_num, gf_gsync_status_t *sts_val);
+
+#endif /* _GD_COMMON_UTILS_H */
diff --git a/libglusterd/src/libglusterd.sym b/libglusterd/src/libglusterd.sym
new file mode 100644
index 00000000000..45969a87c12
--- /dev/null
+++ b/libglusterd/src/libglusterd.sym
@@ -0,0 +1,2 @@
+get_vol_type
+get_struct_variable
diff --git a/libglusterfs/Makefile.am b/libglusterfs/Makefile.am
index 8e5a4a0ccbf..d471a3f9243 100644
--- a/libglusterfs/Makefile.am
+++ b/libglusterfs/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = src src/gfdb
+SUBDIRS = src
CLEANFILES =
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index fd6d275e8fa..385e8ef4600 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -1,14 +1,21 @@
+noinst_PYTHON = generator.py gen-defaults.py $(top_srcdir)/events/eventskeygen.py
+
libglusterfs_la_CFLAGS = $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \
-DDATADIR=\"$(localstatedir)\"
libglusterfs_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \
-DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \
- -I$(top_srcdir)/rpc/rpc-lib/src/ -I$(CONTRIBDIR)/rbtree \
+ -DXLATORPARENTDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)\" \
+ -DXXH_NAMESPACE=GF_ -D__USE_LARGEFILE64 \
+ -I$(CONTRIBDIR)/rbtree \
-I$(CONTRIBDIR)/libexecinfo ${ARGP_STANDALONE_CPPFLAGS} \
- -DSBIN_DIR=\"$(sbindir)\" -I$(CONTRIBDIR)/timer-wheel
+ -DSBIN_DIR=\"$(sbindir)\" -I$(CONTRIBDIR)/timer-wheel \
+ -I$(CONTRIBDIR)/xxhash
-libglusterfs_la_LIBADD = @LEXLIB@ $(ZLIB_LIBS) $(MATH_LIB) $(UUID_LIBS)
-libglusterfs_la_LDFLAGS = -version-info $(LIBGLUSTERFS_LT_VERSION)
+libglusterfs_la_LIBADD = $(ZLIB_LIBS) $(MATH_LIB) $(UUID_LIBS) $(LIB_DL) \
+ $(URCU_LIBS) $(URCU_CDS_LIBS)
+libglusterfs_la_LDFLAGS = -version-info $(LIBGLUSTERFS_LT_VERSION) $(GF_LDFLAGS) \
+ -export-symbols $(top_srcdir)/libglusterfs/src/libglusterfs.sym
lib_LTLIBRARIES = libglusterfs.la
libgfchangelogdir = $(includedir)/glusterfs/gfchangelog
@@ -16,7 +23,7 @@ libgfchangelogdir = $(includedir)/glusterfs/gfchangelog
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 \
+ hashfn.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 timespec.c \
$(CONTRIBDIR)/rbtree/rb.c rbthash.c store.c latency.c \
@@ -24,46 +31,66 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \
circ-buff.c event-history.c gidcache.c ctx.c client_t.c event-poll.c \
event-epoll.c syncop-utils.c cluster-syncop.c refcount.c \
$(CONTRIBDIR)/libgen/basename_r.c \
- $(CONTRIBDIR)/libgen/dirname_r.c $(CONTRIBDIR)/stdlib/gf_mkostemp.c \
+ $(CONTRIBDIR)/libgen/dirname_r.c \
strfd.c parse-utils.c $(CONTRIBDIR)/mount/mntent.c \
$(CONTRIBDIR)/libexecinfo/execinfo.c quota-common-utils.c rot-buffs.c \
$(CONTRIBDIR)/timer-wheel/timer-wheel.c \
- $(CONTRIBDIR)/timer-wheel/find_last_bit.c tw.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 timespec.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 store.h\
- rbthash.h iatt.h latency.h mem-types.h syncop.h cluster-syncop.h \
- graph-utils.h trie.h refcount.h \
- run.h options.h lkowner.h fd-lk.h circ-buff.h event-history.h \
- gidcache.h client_t.h glusterfs-acl.h glfs-message-id.h \
- template-component-messages.h strfd.h syncop-utils.h parse-utils.h \
- libglusterfs-messages.h ctr-messages.h \
- $(CONTRIBDIR)/mount/mntent_compat.h lvm-defaults.h \
+ $(CONTRIBDIR)/timer-wheel/find_last_bit.c default-args.c locking.c \
+ $(CONTRIBDIR)/xxhash/xxhash.c \
+ throttle-tbf.c monitoring.c async.c
+
+nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c defaults.c
+nodist_libglusterfs_la_HEADERS = y.tab.h
+
+BUILT_SOURCES = graph.lex.c defaults.c eventtypes.h
+
+libglusterfs_la_HEADERS = glusterfs/common-utils.h glusterfs/defaults.h \
+ glusterfs/default-args.h glusterfs/dict.h glusterfs/glusterfs.h \
+ glusterfs/hashfn.h glusterfs/timespec.h glusterfs/logging.h \
+ glusterfs/xlator.h glusterfs/stack.h glusterfs/timer.h glusterfs/list.h \
+ glusterfs/inode.h glusterfs/call-stub.h glusterfs/compat.h glusterfs/fd.h \
+ glusterfs/revision.h glusterfs/compat-errno.h glusterfs/gf-event.h \
+ glusterfs/mem-pool.h glusterfs/byte-order.h glusterfs/gf-dirent.h \
+ glusterfs/locking.h glusterfs/syscall.h glusterfs/iobuf.h \
+ glusterfs/globals.h glusterfs/statedump.h glusterfs/checksum.h \
+ glusterfs/daemon.h glusterfs/store.h glusterfs/rbthash.h glusterfs/iatt.h \
+ glusterfs/latency.h glusterfs/mem-types.h glusterfs/syncop.h \
+ glusterfs/cluster-syncop.h glusterfs/graph-utils.h glusterfs/trie.h \
+ glusterfs/refcount.h glusterfs/run.h glusterfs/options.h \
+ glusterfs/lkowner.h glusterfs/fd-lk.h glusterfs/circ-buff.h \
+ glusterfs/event-history.h glusterfs/gidcache.h glusterfs/client_t.h \
+ glusterfs/glusterfs-acl.h glusterfs/glfs-message-id.h \
+ glusterfs/template-component-messages.h glusterfs/strfd.h \
+ glusterfs/syncop-utils.h glusterfs/parse-utils.h \
+ glusterfs/libglusterfs-messages.h glusterfs/lvm-defaults.h \
+ glusterfs/quota-common-utils.h glusterfs/rot-buffs.h \
+ glusterfs/compat-uuid.h glusterfs/upcall-utils.h glusterfs/throttle-tbf.h \
+ glusterfs/events.h glusterfs/atomic.h glusterfs/monitoring.h \
+ glusterfs/async.h glusterfs/glusterfs-fops.h
+
+libglusterfs_ladir = $(includedir)/glusterfs
+
+noinst_HEADERS = unittest/unittest.h \
+ $(CONTRIBDIR)/rbtree/rb.h \
+ $(CONTRIBDIR)/mount/mntent_compat.h \
$(CONTRIBDIR)/libexecinfo/execinfo_compat.h \
- unittest/unittest.h quota-common-utils.h rot-buffs.h \
- $(CONTRIBDIR)/timer-wheel/timer-wheel.h compat-uuid.h \
- tw.h upcall-utils.h
-
-if !HAVE_LIBUUID
-# FIXME: unbundle libuuid, see compat-uuid.h.
-libglusterfs_la_SOURCES += $(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
+ $(CONTRIBDIR)/timer-wheel/timer-wheel.h \
+ $(CONTRIBDIR)/xxhash/xxhash.h \
+ $(CONTRIBDIR)/userspace-rcu/wfcqueue.h \
+ $(CONTRIBDIR)/userspace-rcu/wfstack.h \
+ $(CONTRIBDIR)/userspace-rcu/static-wfcqueue.h \
+ $(CONTRIBDIR)/userspace-rcu/static-wfstack.h
+
+eventtypes.h: $(top_srcdir)/events/eventskeygen.py
+ $(PYTHON) $(top_srcdir)/events/eventskeygen.py C_HEADER
+
+if BUILD_EVENTS
+libglusterfs_la_SOURCES += events.c
endif
libgfchangelog_HEADERS = changelog.h
-EXTRA_DIST = graph.l graph.y
+EXTRA_DIST = graph.l graph.y defaults-tmpl.c libglusterfs.sym
graph.lex.c: graph.l y.tab.h
$(LEX) -Pgraphyy -t $(srcdir)/graph.l > $@
@@ -72,10 +99,18 @@ y.tab.c: y.tab.h
y.tab.h: graph.y
$(YACC) -p graphyy -d $(srcdir)/graph.y
-CLEANFILES = graph.lex.c y.tab.c y.tab.h
+defaults.c: defaults-tmpl.c generator.py gen-defaults.py
+ $(PYTHON) $(srcdir)/gen-defaults.py $(srcdir)/defaults-tmpl.c > $@
+
+CLEANFILES = $(nodist_libglusterfs_la_SOURCES) \
+ $(nodist_libglusterfs_la_HEADERS) *.pyc
if UNITTEST
CLEANFILES += *.gcda *.gcno *_xunit.xml
noinst_PROGRAMS =
TESTS =
endif
+
+if BUILD_EVENTS
+CLEANFILES += eventtypes.h
+endif
diff --git a/libglusterfs/src/async.c b/libglusterfs/src/async.c
new file mode 100644
index 00000000000..1d6cfa374b6
--- /dev/null
+++ b/libglusterfs/src/async.c
@@ -0,0 +1,720 @@
+/*
+ Copyright (c) 2019 Red Hat, Inc <https://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.
+*/
+
+/* To implement an efficient thread pool with minimum contention we have used
+ * the following ideas:
+ *
+ * - The queue of jobs has been implemented using a Wait-Free queue provided
+ * by the userspace-rcu library. This queue requires a mutex when multiple
+ * consumers can be extracting items from it concurrently, but the locked
+ * region is very small, which minimizes the chances of contention. To
+ * further minimize contention, the number of active worker threads that
+ * are accessing the queue is dynamically adjusted so that we always have
+ * the minimum required amount of workers contending for the queue. Adding
+ * new items can be done with a single atomic operation, without locks.
+ *
+ * - All queue management operations, like creating more threads, enabling
+ * sleeping ones, etc. are done by a single thread. This makes it possible
+ * to manage all scaling related information and workers lists without
+ * locks. This functionality is implemented as a role that can be assigned
+ * to any of the worker threads, which avoids that some lengthy operations
+ * could interfere with this task.
+ *
+ * - Management is based on signals. We used signals for management tasks to
+ * avoid multiple system calls for each request (with signals we can wait
+ * for multiple events and get some additional data for each request in a
+ * single call, instead of first polling and then reading).
+ *
+ * TODO: There are some other changes that can take advantage of this new
+ * thread pool.
+ *
+ * - Use this thread pool as the core threading model for synctasks. I
+ * think this would improve synctask performance because I think we
+ * currently have some contention there for some workloads.
+ *
+ * - Implement a per thread timer that will allow adding and removing
+ * timers without using mutexes.
+ *
+ * - Integrate with userspace-rcu library in QSBR mode, allowing
+ * other portions of code to be implemented using RCU-based
+ * structures with a extremely fast read side without contention.
+ *
+ * - Integrate I/O into the thread pool so that the thread pool is
+ * able to efficiently manage all loads and scale dynamically. This
+ * could make it possible to minimize context switching when serving
+ * requests from fuse or network.
+ *
+ * - Dynamically scale the number of workers based on system load.
+ * This will make it possible to reduce contention when system is
+ * heavily loaded, improving performance under these circumstances
+ * (or minimizing performance loss). This will also make it possible
+ * that gluster can coexist with other processes that also consume
+ * CPU, with minimal interference from each other.
+ */
+
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "glusterfs/list.h"
+#include "glusterfs/mem-types.h"
+#include "glusterfs/async.h"
+
+/* These macros wrap a simple system/library call to check the returned error
+ * and log a message in case of failure. */
+#define GF_ASYNC_CHECK(_func, _args...) \
+ ({ \
+ int32_t __async_error = -_func(_args); \
+ if (caa_unlikely(__async_error != 0)) { \
+ gf_async_error(__async_error, #_func "() failed."); \
+ } \
+ __async_error; \
+ })
+
+#define GF_ASYNC_CHECK_ERRNO(_func, _args...) \
+ ({ \
+ int32_t __async_error = _func(_args); \
+ if (caa_unlikely(__async_error < 0)) { \
+ __async_error = -errno; \
+ gf_async_error(__async_error, #_func "() failed."); \
+ } \
+ __async_error; \
+ })
+
+/* These macros are used when, based on POSIX documentation, the function
+ * should never fail under the conditions we are using it. So any unexpected
+ * error will be handled as a fatal event. It probably means a critical bug
+ * or memory corruption. In both cases we consider that stopping the process
+ * is safer (otherwise it could cause more corruption with unknown effects
+ * that could be worse). */
+#define GF_ASYNC_CANTFAIL(_func, _args...) \
+ do { \
+ int32_t __async_error = -_func(_args); \
+ if (caa_unlikely(__async_error != 0)) { \
+ gf_async_fatal(__async_error, #_func "() failed"); \
+ } \
+ } while (0)
+
+#define GF_ASYNC_CANTFAIL_ERRNO(_func, _args...) \
+ ({ \
+ int32_t __async_error = _func(_args); \
+ if (caa_unlikely(__async_error < 0)) { \
+ __async_error = -errno; \
+ gf_async_fatal(__async_error, #_func "() failed"); \
+ } \
+ __async_error; \
+ })
+
+/* TODO: for now we allocate a static array of workers. There's an issue if we
+ * try to use dynamic memory since these workers are initialized very
+ * early in the process startup and it seems that sometimes not all is
+ * ready to use dynamic memory. */
+static gf_async_worker_t gf_async_workers[GF_ASYNC_MAX_THREADS];
+
+/* This is the only global variable needed to manage the entire framework. */
+gf_async_control_t gf_async_ctrl = {};
+
+static __thread gf_async_worker_t *gf_async_current_worker = NULL;
+
+/* The main function of the worker threads. */
+static void *
+gf_async_worker(void *arg);
+
+static void
+gf_async_sync_init(void)
+{
+ GF_ASYNC_CANTFAIL(pthread_barrier_init, &gf_async_ctrl.sync, NULL, 2);
+}
+
+static void
+gf_async_sync_now(void)
+{
+ int32_t ret;
+
+ ret = pthread_barrier_wait(&gf_async_ctrl.sync);
+ if (ret == PTHREAD_BARRIER_SERIAL_THREAD) {
+ GF_ASYNC_CANTFAIL(pthread_barrier_destroy, &gf_async_ctrl.sync);
+ ret = 0;
+ }
+ if (caa_unlikely(ret != 0)) {
+ gf_async_fatal(-ret, "pthread_barrier_wait() failed");
+ }
+}
+
+static void
+gf_async_sigmask_empty(sigset_t *mask)
+{
+ GF_ASYNC_CANTFAIL_ERRNO(sigemptyset, mask);
+}
+
+static void
+gf_async_sigmask_add(sigset_t *mask, int32_t signal)
+{
+ GF_ASYNC_CANTFAIL_ERRNO(sigaddset, mask, signal);
+}
+
+static void
+gf_async_sigmask_set(int32_t mode, sigset_t *mask, sigset_t *old)
+{
+ GF_ASYNC_CANTFAIL(pthread_sigmask, mode, mask, old);
+}
+
+static void
+gf_async_sigaction(int32_t signum, const struct sigaction *action,
+ struct sigaction *old)
+{
+ GF_ASYNC_CANTFAIL_ERRNO(sigaction, signum, action, old);
+}
+
+static int32_t
+gf_async_sigwait(sigset_t *set)
+{
+ int32_t ret, signum;
+
+ do {
+ ret = sigwait(set, &signum);
+ } while (caa_unlikely((ret < 0) && (errno == EINTR)));
+
+ if (caa_unlikely(ret < 0)) {
+ ret = -errno;
+ gf_async_fatal(ret, "sigwait() failed");
+ }
+
+ return signum;
+}
+
+static int32_t
+gf_async_sigtimedwait(sigset_t *set, struct timespec *timeout)
+{
+ int32_t ret;
+
+ do {
+ ret = sigtimedwait(set, NULL, timeout);
+ } while (caa_unlikely((ret < 0) && (errno == EINTR)));
+ if (caa_unlikely(ret < 0)) {
+ ret = -errno;
+ /* EAGAIN means that the timeout has expired, so we allow this error.
+ * Any other error shouldn't happen. */
+ if (caa_unlikely(ret != -EAGAIN)) {
+ gf_async_fatal(ret, "sigtimedwait() failed");
+ }
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static void
+gf_async_sigbroadcast(int32_t signum)
+{
+ GF_ASYNC_CANTFAIL_ERRNO(kill, gf_async_ctrl.pid, signum);
+}
+
+static void
+gf_async_signal_handler(int32_t signum)
+{
+ /* We should never handle a signal in this function. */
+ gf_async_fatal(-EBUSY,
+ "Unexpected processing of signal %d through a handler.",
+ signum);
+}
+
+static void
+gf_async_signal_setup(void)
+{
+ struct sigaction action;
+
+ /* We configure all related signals so that we can detect threads using an
+ * invalid signal mask that doesn't block our critical signal. */
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = gf_async_signal_handler;
+
+ gf_async_sigaction(GF_ASYNC_SIGCTRL, &action, &gf_async_ctrl.handler_ctrl);
+
+ gf_async_sigaction(GF_ASYNC_SIGQUEUE, &action,
+ &gf_async_ctrl.handler_queue);
+}
+
+static void
+gf_async_signal_restore(void)
+{
+ /* Handlers we have previously changed are restored back to their original
+ * value. */
+
+ if (gf_async_ctrl.handler_ctrl.sa_handler != gf_async_signal_handler) {
+ gf_async_sigaction(GF_ASYNC_SIGCTRL, &gf_async_ctrl.handler_ctrl, NULL);
+ }
+
+ if (gf_async_ctrl.handler_queue.sa_handler != gf_async_signal_handler) {
+ gf_async_sigaction(GF_ASYNC_SIGQUEUE, &gf_async_ctrl.handler_queue,
+ NULL);
+ }
+}
+
+static void
+gf_async_signal_flush(void)
+{
+ struct timespec delay;
+
+ delay.tv_sec = 0;
+ delay.tv_nsec = 0;
+
+ /* We read all pending signals so that they don't trigger once the signal
+ * mask of some thread is changed. */
+ while (gf_async_sigtimedwait(&gf_async_ctrl.sigmask_ctrl, &delay) > 0) {
+ }
+ while (gf_async_sigtimedwait(&gf_async_ctrl.sigmask_queue, &delay) > 0) {
+ }
+}
+
+static int32_t
+gf_async_thread_create(pthread_t *thread, int32_t id, void *data)
+{
+ int32_t ret;
+
+ ret = gf_thread_create(thread, NULL, gf_async_worker, data,
+ GF_ASYNC_THREAD_NAME "%u", id);
+ if (caa_unlikely(ret < 0)) {
+ /* TODO: gf_thread_create() should return a more specific error
+ * code. */
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void
+gf_async_thread_wait(pthread_t thread)
+{
+ /* TODO: this is a blocking call executed inside one of the workers of the
+ * thread pool. This is bad, but this is only executed once we have
+ * received a notification from the thread that it's terminating, so
+ * this should return almost immediately. However, to be more robust
+ * it would be better to use pthread_timedjoin_np() (or even a call
+ * to pthread_tryjoin_np() followed by a delayed recheck if it
+ * fails), but they are not portable. We should see how to do this
+ * in other platforms. */
+ GF_ASYNC_CANTFAIL(pthread_join, thread, NULL);
+}
+
+static int32_t
+gf_async_worker_create(void)
+{
+ struct cds_wfs_node *node;
+ gf_async_worker_t *worker;
+ uint32_t counts, running, max;
+ int32_t ret;
+
+ node = __cds_wfs_pop_blocking(&gf_async_ctrl.available);
+ if (caa_unlikely(node == NULL)) {
+ /* There are no more available workers. We have all threads running. */
+ return 1;
+ }
+ cds_wfs_node_init(node);
+
+ ret = 1;
+
+ counts = uatomic_read(&gf_async_ctrl.counts);
+ max = uatomic_read(&gf_async_ctrl.max_threads);
+ running = GF_ASYNC_COUNT_RUNNING(counts);
+ if (running < max) {
+ uatomic_add(&gf_async_ctrl.counts, GF_ASYNC_COUNTS(1, 0));
+
+ worker = caa_container_of(node, gf_async_worker_t, stack);
+
+ ret = gf_async_thread_create(&worker->thread, worker->id, worker);
+ if (caa_likely(ret >= 0)) {
+ return 0;
+ }
+
+ uatomic_add(&gf_async_ctrl.counts, GF_ASYNC_COUNTS(-1, 0));
+ }
+
+ cds_wfs_push(&gf_async_ctrl.available, node);
+
+ return ret;
+}
+
+static void
+gf_async_worker_enable(void)
+{
+ /* This will wake one of the spare workers. If all workers are busy now,
+ * the signal will be queued so that the first one that completes its
+ * work will become the leader. */
+ gf_async_sigbroadcast(GF_ASYNC_SIGCTRL);
+
+ /* We have consumed a spare worker. We create another one for future
+ * needs. */
+ gf_async_worker_create();
+}
+
+static void
+gf_async_worker_wait(void)
+{
+ int32_t signum;
+
+ signum = gf_async_sigwait(&gf_async_ctrl.sigmask_ctrl);
+ if (caa_unlikely(signum != GF_ASYNC_SIGCTRL)) {
+ gf_async_fatal(-EINVAL, "Worker received an unexpected signal (%d)",
+ signum);
+ }
+}
+
+static void
+gf_async_leader_wait(void)
+{
+ int32_t signum;
+
+ signum = gf_async_sigwait(&gf_async_ctrl.sigmask_queue);
+ if (caa_unlikely(signum != GF_ASYNC_SIGQUEUE)) {
+ gf_async_fatal(-EINVAL, "Leader received an unexpected signal (%d)",
+ signum);
+ }
+}
+
+static void
+gf_async_run(struct cds_wfcq_node *node)
+{
+ gf_async_t *async;
+
+ /* We've just got work from the queue. Process it. */
+ async = caa_container_of(node, gf_async_t, queue);
+ /* TODO: remove dependency from THIS and xl. */
+ THIS = async->xl;
+ async->cbk(async->xl, async);
+}
+
+static void
+gf_async_worker_run(void)
+{
+ struct cds_wfcq_node *node;
+
+ do {
+ /* We keep executing jobs from the queue while it's not empty. Note
+ * that while we do this, we are ignoring any stop request. That's
+ * fine, since we need to process our own 'join' messages to fully
+ * terminate all threads. Note that normal jobs should have already
+ * completed once a stop request is received. */
+ node = cds_wfcq_dequeue_blocking(&gf_async_ctrl.queue.head,
+ &gf_async_ctrl.queue.tail);
+ if (node != NULL) {
+ gf_async_run(node);
+ }
+ } while (node != NULL);
+
+ /* TODO: I've tried to keep the worker looking at the queue for some small
+ * amount of time in a busy loop to see if more jobs come soon. With
+ * this I attempted to avoid the overhead of signal management if
+ * jobs come fast enough. However experimental results seem to
+ * indicate that doing this, CPU utilization grows and performance
+ * is actually reduced. We need to see if that's because I used bad
+ * parameters or it's really better to do it as it's done now. */
+}
+
+static void
+gf_async_leader_run(void)
+{
+ struct cds_wfcq_node *node;
+
+ node = cds_wfcq_dequeue_blocking(&gf_async_ctrl.queue.head,
+ &gf_async_ctrl.queue.tail);
+ while (caa_unlikely(node == NULL)) {
+ gf_async_leader_wait();
+
+ node = cds_wfcq_dequeue_blocking(&gf_async_ctrl.queue.head,
+ &gf_async_ctrl.queue.tail);
+ }
+
+ /* Activate the next available worker thread. It will become the new
+ * leader. */
+ gf_async_worker_enable();
+
+ gf_async_run(node);
+}
+
+static uint32_t
+gf_async_stop_check(gf_async_worker_t *worker)
+{
+ uint32_t counts, old, running, max;
+
+ /* First we check if we should stop without doing any costly atomic
+ * operation. */
+ old = uatomic_read(&gf_async_ctrl.counts);
+ max = uatomic_read(&gf_async_ctrl.max_threads);
+ running = GF_ASYNC_COUNT_RUNNING(old);
+ while (running > max) {
+ /* There are too many threads. We try to stop the current worker. */
+ counts = uatomic_cmpxchg(&gf_async_ctrl.counts, old,
+ old + GF_ASYNC_COUNTS(-1, 1));
+ if (old != counts) {
+ /* Another thread has just updated the counts. We need to retry. */
+ old = counts;
+ running = GF_ASYNC_COUNT_RUNNING(old);
+
+ continue;
+ }
+
+ running--;
+ worker->running = false;
+ }
+
+ return running;
+}
+
+static void
+gf_async_stop_all(xlator_t *xl, gf_async_t *async)
+{
+ if (gf_async_stop_check(gf_async_current_worker) > 0) {
+ /* There are more workers running. We propagate the stop request to
+ * them. */
+ gf_async(async, xl, gf_async_stop_all);
+ }
+}
+
+static void
+gf_async_join(xlator_t *xl, gf_async_t *async)
+{
+ gf_async_worker_t *worker;
+
+ worker = caa_container_of(async, gf_async_worker_t, async);
+
+ gf_async_thread_wait(worker->thread);
+
+ cds_wfs_push(&gf_async_ctrl.available, &worker->stack);
+}
+
+static void
+gf_async_terminate(gf_async_worker_t *worker)
+{
+ uint32_t counts;
+
+ counts = uatomic_add_return(&gf_async_ctrl.counts, GF_ASYNC_COUNTS(0, -1));
+ if (counts == 0) {
+ /* This is the termination of the last worker thread. We need to
+ * synchronize the main thread that is waiting for all workers to
+ * finish. */
+ gf_async_ctrl.sync_thread = worker->thread;
+
+ gf_async_sync_now();
+ } else {
+ /* Force someone else to join this thread to release resources. */
+ gf_async(&worker->async, THIS, gf_async_join);
+ }
+}
+
+static void *
+gf_async_worker(void *arg)
+{
+ gf_async_worker_t *worker;
+
+ worker = (gf_async_worker_t *)arg;
+ gf_async_current_worker = worker;
+
+ worker->running = true;
+ do {
+ /* This thread does nothing until someone enables it to become a
+ * leader. */
+ gf_async_worker_wait();
+
+ /* This thread is now a leader. It will process jobs from the queue
+ * and, if necessary, enable another worker and transfer leadership
+ * to it. */
+ gf_async_leader_run();
+
+ /* This thread is not a leader anymore. It will continue processing
+ * queued jobs until it becomes empty. */
+ gf_async_worker_run();
+
+ /* Stop the current thread if there are too many threads running. */
+ gf_async_stop_check(worker);
+ } while (worker->running);
+
+ gf_async_terminate(worker);
+
+ return NULL;
+}
+
+static void
+gf_async_cleanup(void)
+{
+ /* We do some basic initialization of the global variable 'gf_async_ctrl'
+ * so that it's put into a relatively consistent state. */
+
+ gf_async_ctrl.enabled = false;
+
+ gf_async_ctrl.pid = 0;
+ gf_async_sigmask_empty(&gf_async_ctrl.sigmask_ctrl);
+ gf_async_sigmask_empty(&gf_async_ctrl.sigmask_queue);
+
+ /* This is used to later detect if the handler of these signals have been
+ * changed or not. */
+ gf_async_ctrl.handler_ctrl.sa_handler = gf_async_signal_handler;
+ gf_async_ctrl.handler_queue.sa_handler = gf_async_signal_handler;
+
+ gf_async_ctrl.table = NULL;
+ gf_async_ctrl.max_threads = 0;
+ gf_async_ctrl.counts = 0;
+}
+
+void
+gf_async_fini(void)
+{
+ gf_async_t async;
+
+ if (uatomic_read(&gf_async_ctrl.counts) != 0) {
+ /* We ensure that all threads will quit on the next check. */
+ gf_async_ctrl.max_threads = 0;
+
+ /* Send the stop request to the thread pool. This will cause the
+ * execution of gf_async_stop_all() by one of the worker threads which,
+ * eventually, will terminate all worker threads. */
+ gf_async(&async, THIS, gf_async_stop_all);
+
+ /* We synchronize here with the last thread. */
+ gf_async_sync_now();
+
+ /* We have just synchronized with the latest thread. Now just wait for
+ * it to terminate. */
+ gf_async_thread_wait(gf_async_ctrl.sync_thread);
+
+ gf_async_signal_flush();
+ }
+
+ gf_async_signal_restore();
+
+ gf_async_cleanup();
+}
+
+void
+gf_async_adjust_threads(int32_t threads)
+{
+ if (threads == 0) {
+ /* By default we allow a maximum of 2 * #cores worker threads. This
+ * value is to try to accommodate threads that will do some I/O. Having
+ * more threads than cores we can keep CPU busy even if some threads
+ * are blocked for I/O. In the most efficient case, we can have #cores
+ * computing threads and #cores blocked threads on I/O. However this is
+ * hard to achieve because we can end with more than #cores computing
+ * threads, which won't provide a real benefit and will increase
+ * contention.
+ *
+ * TODO: implement a more intelligent dynamic maximum based on CPU
+ * usage and/or system load. */
+ threads = sysconf(_SC_NPROCESSORS_ONLN) * 2;
+ if (threads < 0) {
+ /* If we can't get the current number of processors, we pick a
+ * random number. */
+ threads = 16;
+ }
+ }
+ if (threads > GF_ASYNC_MAX_THREADS) {
+ threads = GF_ASYNC_MAX_THREADS;
+ }
+ uatomic_set(&gf_async_ctrl.max_threads, threads);
+}
+
+int32_t
+gf_async_init(glusterfs_ctx_t *ctx)
+{
+ sigset_t set;
+ gf_async_worker_t *worker;
+ uint32_t i;
+ int32_t ret;
+ bool running;
+
+ gf_async_cleanup();
+
+ if (!ctx->cmd_args.global_threading ||
+ (ctx->process_mode == GF_GLUSTERD_PROCESS)) {
+ return 0;
+ }
+
+ /* At the init time, the maximum number of threads has not yet been
+ * configured. We use a small starting value that will be layer dynamically
+ * adjusted when ctx->config.max_threads is updated. */
+ gf_async_adjust_threads(GF_ASYNC_SPARE_THREADS + 1);
+
+ gf_async_ctrl.pid = getpid();
+
+ __cds_wfs_init(&gf_async_ctrl.available);
+ cds_wfcq_init(&gf_async_ctrl.queue.head, &gf_async_ctrl.queue.tail);
+
+ gf_async_sync_init();
+
+ /* TODO: it would be cleaner to use dynamic memory, but at this point some
+ * memory management resources are not yet initialized. */
+ gf_async_ctrl.table = gf_async_workers;
+
+ /* We keep all workers in a stack. It will be used when a new thread needs
+ * to be created. */
+ for (i = GF_ASYNC_MAX_THREADS; i > 0; i--) {
+ worker = &gf_async_ctrl.table[i - 1];
+
+ worker->id = i - 1;
+ cds_wfs_node_init(&worker->stack);
+ cds_wfs_push(&gf_async_ctrl.available, &worker->stack);
+ }
+
+ /* Prepare the signal mask for regular workers and the leader. */
+ gf_async_sigmask_add(&gf_async_ctrl.sigmask_ctrl, GF_ASYNC_SIGCTRL);
+ gf_async_sigmask_add(&gf_async_ctrl.sigmask_queue, GF_ASYNC_SIGQUEUE);
+
+ /* TODO: this is needed to block our special signals in the current thread
+ * and all children that it starts. It would be cleaner to do it when
+ * signals are initialized, but there doesn't seem to be a unique
+ * place to do that, so for now we do it here. */
+ gf_async_sigmask_empty(&set);
+ gf_async_sigmask_add(&set, GF_ASYNC_SIGCTRL);
+ gf_async_sigmask_add(&set, GF_ASYNC_SIGQUEUE);
+ gf_async_sigmask_set(SIG_BLOCK, &set, NULL);
+
+ /* Configure the signal handlers. This is mostly for safety, not really
+ * needed, but it doesn't hurt. Note that the caller must ensure that the
+ * signals we need to run are already blocked in any thread already
+ * started. Otherwise this won't work. */
+ gf_async_signal_setup();
+
+ running = false;
+
+ /* We start the spare workers + 1 for the leader. */
+ for (i = 0; i < GF_ASYNC_SPARE_THREADS; i++) {
+ ret = gf_async_worker_create();
+ if (caa_unlikely(ret < 0)) {
+ /* This is the initial start up so we enforce that the spare
+ * threads are created. If this fails at the beginning, it's very
+ * unlikely that the async workers could do its job, so we abort
+ * the initialization. */
+ goto out;
+ }
+
+ /* Once the first thread is started, we can enable it to become the
+ * initial leader. */
+ if ((ret == 0) && !running) {
+ running = true;
+ gf_async_worker_enable();
+ }
+ }
+
+ if (caa_unlikely(!running)) {
+ gf_async_fatal(-ENOMEM, "No worker thread has started");
+ }
+
+ gf_async_ctrl.enabled = true;
+
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ gf_async_error(ret, "Unable to initialize the thread pool.");
+ gf_async_fini();
+ }
+
+ return ret;
+}
diff --git a/libglusterfs/src/byte-order.h b/libglusterfs/src/byte-order.h
deleted file mode 100644
index 4101db2c71d..00000000000
--- a/libglusterfs/src/byte-order.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- 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
-#define _BYTE_ORDER_H
-
-#include <inttypes.h>
-
-#define LS1 0x00ffU
-#define MS1 0xff00U
-#define LS2 0x0000ffffU
-#define MS2 0xffff0000U
-#define LS4 0x00000000ffffffffULL
-#define MS4 0xffffffff00000000ULL
-
-
-static uint16_t (*hton16) (uint16_t);
-static uint32_t (*hton32) (uint32_t);
-static uint64_t (*hton64) (uint64_t);
-
-#define ntoh16 hton16
-#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)))
-
-
-static inline uint16_t
-__swap16 (uint16_t x)
-{
- return do_swap2(x);
-}
-
-
-static inline uint32_t
-__swap32 (uint32_t x)
-{
- return do_swap4(x);
-}
-
-
-static inline uint64_t
-__swap64 (uint64_t x)
-{
- return do_swap8(x);
-}
-
-
-static inline uint16_t
-__noswap16 (uint16_t x)
-{
- return x;
-}
-
-
-static inline uint32_t
-__noswap32 (uint32_t x)
-{
- return x;
-}
-
-
-static inline uint64_t
-__noswap64 (uint64_t x)
-{
- return x;
-}
-
-
-static inline uint16_t
-__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;
- }
-
- return hton16 (i);
-}
-
-
-static inline uint32_t
-__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;
- }
-
- return hton32 (i);
-}
-
-
-static inline uint64_t
-__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;
- }
-
- return hton64 (i);
-}
-
-
-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 610277820d6..ee84f08acd4 100644
--- a/libglusterfs/src/call-stub.c
+++ b/libglusterfs/src/call-stub.c
@@ -11,2593 +11,2457 @@
#include <openssl/md5.h>
#include <inttypes.h>
-#include "call-stub.h"
-#include "mem-types.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/call-stub.h"
+#include "glusterfs/mem-types.h"
+#include "glusterfs/libglusterfs-messages.h"
static call_stub_t *
-stub_new (call_frame_t *frame,
- char wind,
- glusterfs_fop_t fop)
+stub_new(call_frame_t *frame, const char wind, const glusterfs_fop_t fop)
{
- call_stub_t *new = NULL;
+ call_stub_t *new = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", frame, out);
- new = mem_get0 (frame->this->ctx->stub_mem_pool);
- GF_VALIDATE_OR_GOTO ("call-stub", new, out);
+ new = mem_get0(frame->this->ctx->stub_mem_pool);
+ GF_VALIDATE_OR_GOTO("call-stub", new, out);
- new->frame = frame;
- new->wind = wind;
- new->fop = fop;
- new->stub_mem_pool = frame->this->ctx->stub_mem_pool;
- INIT_LIST_HEAD (&new->list);
+ new->frame = frame;
+ new->wind = wind;
+ new->fop = fop;
+ new->stub_mem_pool = frame->this->ctx->stub_mem_pool;
+ INIT_LIST_HEAD(&new->list);
- INIT_LIST_HEAD (&new->args_cbk.entries);
+ INIT_LIST_HEAD(&new->args_cbk.entries);
out:
- return new;
+ return new;
}
-
call_stub_t *
-fop_lookup_stub (call_frame_t *frame, fop_lookup_t fn, loc_t *loc,
- dict_t *xdata)
+fop_lookup_stub(call_frame_t *frame, fop_lookup_t fn, loc_t *loc, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_LOOKUP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub->fn.lookup = fn;
-
- loc_copy (&stub->args.loc, loc);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub = stub_new(frame, 1, GF_FOP_LOOKUP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn.lookup = fn;
+ args_lookup_store(&stub->args, loc, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_lookup_cbk_stub (call_frame_t *frame, fop_lookup_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- dict_t *xdata, struct iatt *postparent)
+fop_lookup_cbk_stub(call_frame_t *frame, fop_lookup_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata, struct iatt *postparent)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_LOOKUP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_LOOKUP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.lookup = fn;
- args_lookup_cbk_store (&stub->args_cbk, op_ret, op_errno, inode,
- buf, xdata, postparent);
+ stub->fn_cbk.lookup = fn;
+ args_lookup_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf, xdata,
+ postparent);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_stat_stub (call_frame_t *frame, fop_stat_t fn,
- loc_t *loc, dict_t *xdata)
+fop_stat_stub(call_frame_t *frame, fop_stat_t fn, loc_t *loc, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_STAT);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_STAT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.stat = fn;
- loc_copy (&stub->args.loc, loc);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.stat = fn;
+ args_stat_store(&stub->args, loc, xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+fop_stat_cbk_stub(call_frame_t *frame, fop_stat_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_STAT);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_STAT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.stat = fn;
- args_stat_cbk_store (&stub->args_cbk, op_ret, op_errno, buf,
- xdata);
+ stub->fn_cbk.stat = fn;
+ args_stat_cbk_store(&stub->args_cbk, op_ret, op_errno, buf, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fstat_stub (call_frame_t *frame, fop_fstat_t fn,
- fd_t *fd, dict_t *xdata)
+fop_fstat_stub(call_frame_t *frame, fop_fstat_t fn, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 1, GF_FOP_FSTAT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_FSTAT);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.fstat = fn;
+ args_fstat_store(&stub->args, fd, xdata);
+out:
+ return stub;
+}
- stub->fn.fstat = fn;
+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, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ stub = stub_new(frame, 0, GF_FOP_FSTAT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (fd)
- stub->args.fd = fd_ref (fd);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.fstat = fn;
+ args_fstat_cbk_store(&stub->args_cbk, op_ret, op_errno, buf, xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+fop_truncate_stub(call_frame_t *frame, fop_truncate_t fn, loc_t *loc, off_t off,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 0, GF_FOP_FSTAT);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_TRUNCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.fstat = fn;
- args_fstat_cbk_store (&stub->args_cbk, op_ret, op_errno, buf,
- xdata);
+ stub->fn.truncate = fn;
+ args_truncate_store(&stub->args, loc, off, xdata);
out:
- return stub;
+ return stub;
}
+call_stub_t *
+fop_truncate_cbk_stub(call_frame_t *frame, fop_truncate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ stub = stub_new(frame, 0, GF_FOP_TRUNCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ stub->fn_cbk.truncate = fn;
+ args_truncate_cbk_store(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
+out:
+ return stub;
+}
call_stub_t *
-fop_truncate_stub (call_frame_t *frame, fop_truncate_t fn,
- loc_t *loc, off_t off, dict_t *xdata)
+fop_ftruncate_stub(call_frame_t *frame, fop_ftruncate_t fn, fd_t *fd, off_t off,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ stub = stub_new(frame, 1, GF_FOP_FTRUNCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_TRUNCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.ftruncate = fn;
+ args_ftruncate_store(&stub->args, fd, off, xdata);
- stub->fn.truncate = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.offset = off;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_truncate_cbk_stub (call_frame_t *frame, fop_truncate_cbk_t fn,
+fop_ftruncate_cbk_stub(call_frame_t *frame, fop_ftruncate_cbk_t fn,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_FTRUNCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_TRUNCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.ftruncate = fn;
+ args_ftruncate_cbk_store(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
- stub->fn_cbk.truncate = fn;
- args_truncate_cbk_store (&stub->args_cbk, op_ret, op_errno,
- prebuf, postbuf, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_ftruncate_stub (call_frame_t *frame, fop_ftruncate_t fn,
- fd_t *fd, off_t off, dict_t *xdata)
+fop_access_stub(call_frame_t *frame, fop_access_t fn, loc_t *loc, int32_t mask,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FTRUNCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub->fn.ftruncate = fn;
- if (fd)
- stub->args.fd = fd_ref (fd);
+ stub = stub_new(frame, 1, GF_FOP_ACCESS);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.offset = off;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.access = fn;
+ args_access_store(&stub->args, loc, mask, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_ftruncate_cbk_stub (call_frame_t *frame, fop_ftruncate_cbk_t fn,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+fop_access_cbk_stub(call_frame_t *frame, fop_access_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_FTRUNCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- stub->fn_cbk.ftruncate = fn;
- args_ftruncate_cbk_store (&stub->args_cbk, op_ret, op_errno,
- prebuf, postbuf, xdata);
+ stub = stub_new(frame, 0, GF_FOP_ACCESS);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+ stub->fn_cbk.access = fn;
+ args_access_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_access_stub (call_frame_t *frame, fop_access_t fn,
- loc_t *loc, int32_t mask, dict_t *xdata)
+fop_readlink_stub(call_frame_t *frame, fop_readlink_t fn, loc_t *loc,
+ size_t size, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_ACCESS);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_READLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.access = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.mask = mask;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.readlink = fn;
+ args_readlink_store(&stub->args, loc, size, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_access_cbk_stub (call_frame_t *frame, fop_access_cbk_t fn,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+fop_readlink_cbk_stub(call_frame_t *frame, fop_readlink_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, const char *path,
+ struct iatt *stbuf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_READLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_ACCESS);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn_cbk.access = fn;
- args_access_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn_cbk.readlink = fn;
+ args_readlink_cbk_store(&stub->args_cbk, op_ret, op_errno, path, stbuf,
+ xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readlink_stub (call_frame_t *frame, fop_readlink_t fn,
- loc_t *loc, size_t size, dict_t *xdata)
+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;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_READLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_MKNOD);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.readlink = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.size = size;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.mknod = fn;
+ args_mknod_store(&stub->args, loc, mode, rdev, umask, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readlink_cbk_stub (call_frame_t *frame, fop_readlink_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- const char *path, struct iatt *stbuf, dict_t *xdata)
+fop_mknod_cbk_stub(call_frame_t *frame, fop_mknod_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_MKNOD);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_READLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn_cbk.readlink = fn;
- args_readlink_cbk_store (&stub->args_cbk, op_ret, op_errno, path,
- stbuf, xdata);
+ stub->fn_cbk.mknod = fn;
+ args_mknod_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
out:
- return stub;
+ 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, mode_t umask, dict_t *xdata)
+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 *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_MKNOD);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_MKDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.mknod = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.mode = mode;
- stub->args.rdev = rdev;
- stub->args.umask = umask;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.mkdir = fn;
+ args_mkdir_store(&stub->args, loc, mode, umask, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_mknod_cbk_stub (call_frame_t *frame, fop_mknod_cbk_t fn, int32_t op_ret,
- int32_t op_errno, inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+fop_mkdir_cbk_stub(call_frame_t *frame, fop_mkdir_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_MKDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_MKNOD);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn_cbk.mknod = fn;
- args_mknod_cbk_store (&stub->args_cbk, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ stub->fn_cbk.mkdir = fn;
+ args_mkdir_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_mkdir_stub (call_frame_t *frame, fop_mkdir_t fn,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
+fop_unlink_stub(call_frame_t *frame, fop_unlink_t fn, loc_t *loc, int xflag,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_MKDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_UNLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.mkdir = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.mode = mode;
- stub->args.umask = umask;
+ stub->fn.unlink = fn;
+ args_unlink_store(&stub->args, loc, xflag, xdata);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_mkdir_cbk_stub (call_frame_t *frame, fop_mkdir_cbk_t fn,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
+fop_unlink_cbk_stub(call_frame_t *frame, fop_unlink_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
struct iatt *postparent, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_MKDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_UNLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.mkdir = fn;
- args_mkdir_cbk_store (&stub->args_cbk, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
+ stub->fn_cbk.unlink = fn;
+ args_unlink_cbk_store(&stub->args_cbk, op_ret, op_errno, preparent,
+ postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_unlink_stub (call_frame_t *frame, fop_unlink_t fn,
- loc_t *loc, int xflag, dict_t *xdata)
+fop_rmdir_stub(call_frame_t *frame, fop_rmdir_t fn, loc_t *loc, int flags,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ stub = stub_new(frame, 1, GF_FOP_RMDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_UNLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.rmdir = fn;
+ args_rmdir_store(&stub->args, loc, flags, xdata);
- stub->fn.unlink = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.xflag = xflag;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
out:
- return stub;
+ return stub;
}
+call_stub_t *
+fop_rmdir_cbk_stub(call_frame_t *frame, fop_rmdir_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ stub = stub_new(frame, 0, GF_FOP_RMDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ stub->fn_cbk.rmdir = fn;
+ args_rmdir_cbk_store(&stub->args_cbk, op_ret, op_errno, preparent,
+ postparent, xdata);
+out:
+ return stub;
+}
call_stub_t *
-fop_unlink_cbk_stub (call_frame_t *frame, fop_unlink_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+fop_symlink_stub(call_frame_t *frame, fop_symlink_t fn, const char *linkname,
+ loc_t *loc, mode_t umask, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", linkname, out);
- stub = stub_new (frame, 0, GF_FOP_UNLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_SYMLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.unlink = fn;
- args_unlink_cbk_store (&stub->args_cbk, op_ret, op_errno, preparent,
- postparent, xdata);
+ stub->fn.symlink = fn;
+ args_symlink_store(&stub->args, linkname, loc, umask, xdata);
out:
- return stub;
+ return stub;
}
+call_stub_t *
+fop_symlink_cbk_stub(call_frame_t *frame, fop_symlink_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+ stub = stub_new(frame, 0, GF_FOP_SYMLINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ stub->fn_cbk.symlink = fn;
+ args_symlink_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
+out:
+ return stub;
+}
call_stub_t *
-fop_rmdir_stub (call_frame_t *frame, fop_rmdir_t fn,
- loc_t *loc, int flags, dict_t *xdata)
+fop_rename_stub(call_frame_t *frame, fop_rename_t fn, loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", oldloc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", newloc, out);
- stub = stub_new (frame, 1, GF_FOP_RMDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_RENAME);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.rmdir = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.flags = flags;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.rename = fn;
+ args_rename_store(&stub->args, oldloc, newloc, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_rmdir_cbk_stub (call_frame_t *frame, fop_rmdir_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+fop_rename_cbk_stub(call_frame_t *frame, fop_rename_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_RMDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_RENAME);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.rmdir = fn;
- args_rmdir_cbk_store (&stub->args_cbk, op_ret, op_errno, preparent,
- postparent, xdata);
+ stub->fn_cbk.rename = fn;
+ args_rename_cbk_store(&stub->args_cbk, op_ret, op_errno, buf, preoldparent,
+ postoldparent, prenewparent, postnewparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_symlink_stub (call_frame_t *frame, fop_symlink_t fn,
- const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata)
+fop_link_stub(call_frame_t *frame, fop_link_t fn, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", linkname, out);
+ GF_VALIDATE_OR_GOTO("call-stub", oldloc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", newloc, out);
- stub = stub_new (frame, 1, GF_FOP_SYMLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_LINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.symlink = fn;
- stub->args.linkname = gf_strdup (linkname);
- stub->args.umask = umask;
- loc_copy (&stub->args.loc, loc);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.link = fn;
+ args_link_store(&stub->args, oldloc, newloc, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_symlink_cbk_stub (call_frame_t *frame, fop_symlink_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+fop_link_cbk_stub(call_frame_t *frame, fop_link_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_SYMLINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_LINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.symlink = fn;
- args_symlink_cbk_store (&stub->args_cbk, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ stub->fn_cbk.link = fn;
+ args_link_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ preparent, postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_rename_stub (call_frame_t *frame, fop_rename_t fn,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+fop_create_stub(call_frame_t *frame, fop_create_t fn, loc_t *loc, int32_t flags,
+ mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", oldloc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", newloc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_RENAME);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_CREATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.rename = fn;
- loc_copy (&stub->args.loc, oldloc);
- loc_copy (&stub->args.loc2, newloc);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.create = fn;
+ args_create_store(&stub->args, loc, flags, mode, umask, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_rename_cbk_stub (call_frame_t *frame, fop_rename_cbk_t fn,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+fop_create_cbk_stub(call_frame_t *frame, fop_create_cbk_t fn, 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)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_CREATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_RENAME);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn_cbk.rename = fn;
- args_rename_cbk_store (&stub->args_cbk, op_ret, op_errno, buf,
- preoldparent, postoldparent, prenewparent,
- postnewparent, xdata);
+ stub->fn_cbk.create = fn;
+ args_create_cbk_store(&stub->args_cbk, op_ret, op_errno, fd, inode, buf,
+ preparent, postparent, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_link_stub (call_frame_t *frame, fop_link_t fn,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+fop_open_stub(call_frame_t *frame, fop_open_t fn, loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", oldloc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", newloc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 1, GF_FOP_LINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_OPEN);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.link = fn;
- loc_copy (&stub->args.loc, oldloc);
- loc_copy (&stub->args.loc2, newloc);
-
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.open = fn;
+ args_open_store(&stub->args, loc, flags, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_link_cbk_stub (call_frame_t *frame, fop_link_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+fop_open_cbk_stub(call_frame_t *frame, fop_open_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_OPEN);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_LINK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn_cbk.link = fn;
- args_link_cbk_store (&stub->args_cbk, op_ret, op_errno,
- inode, buf, preparent, postparent, xdata);
+ stub->fn_cbk.open = fn;
+ args_open_cbk_store(&stub->args_cbk, op_ret, op_errno, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_create_stub (call_frame_t *frame, fop_create_t fn,
- loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *xdata)
+fop_readv_stub(call_frame_t *frame, fop_readv_t fn, fd_t *fd, size_t size,
+ off_t off, uint32_t flags, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ stub = stub_new(frame, 1, GF_FOP_READ);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_CREATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn.create = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.flags = flags;
- stub->args.mode = mode;
- stub->args.umask = umask;
- if (fd)
- stub->args.fd = fd_ref (fd);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.readv = fn;
+ args_readv_store(&stub->args, fd, size, off, flags, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_create_cbk_stub (call_frame_t *frame, fop_create_cbk_t fn,
- 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)
+fop_readv_cbk_stub(call_frame_t *frame, fop_readv_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iovec *vector, int32_t count,
+ struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_READ);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_CREATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn_cbk.create = fn;
- args_create_cbk_store (&stub->args_cbk, op_ret, op_errno, fd, inode,
- buf, preparent, postparent, xdata);
+ stub->fn_cbk.readv = fn;
+ args_readv_cbk_store(&stub->args_cbk, op_ret, op_errno, vector, count,
+ stbuf, iobref, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_open_stub (call_frame_t *frame, fop_open_t fn,
- loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata)
+fop_writev_stub(call_frame_t *frame, fop_writev_t fn, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", vector, out);
- stub = stub_new (frame, 1, GF_FOP_OPEN);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_WRITE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.open = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.flags = flags;
- if (fd)
- stub->args.fd = fd_ref (fd);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.writev = fn;
+ args_writev_store(&stub->args, fd, vector, count, off, flags, iobref,
+ xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+fop_writev_cbk_stub(call_frame_t *frame, fop_writev_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_OPEN);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_WRITE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.open = fn;
- args_open_cbk_store (&stub->args_cbk, op_ret, op_errno, fd, xdata);
+ stub->fn_cbk.writev = fn;
+ args_writev_cbk_store(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readv_stub (call_frame_t *frame, fop_readv_t fn,
- fd_t *fd, size_t size, off_t off, uint32_t flags,
- dict_t *xdata)
+fop_flush_stub(call_frame_t *frame, fop_flush_t fn, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 1, GF_FOP_FLUSH);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_READ);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.flush = fn;
+ args_flush_store(&stub->args, fd, xdata);
+out:
+ return stub;
+}
- stub->fn.readv = fn;
- if (fd)
- stub->args.fd = fd_ref (fd);
- stub->args.size = size;
- stub->args.offset = off;
- stub->args.flags = flags;
+call_stub_t *
+fop_flush_cbk_stub(call_frame_t *frame, fop_flush_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub = stub_new(frame, 0, GF_FOP_FLUSH);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ stub->fn_cbk.flush = fn;
+ args_flush_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readv_cbk_stub (call_frame_t *frame, fop_readv_cbk_t fn,
- int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata)
+fop_fsync_stub(call_frame_t *frame, fop_fsync_t fn, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 1, GF_FOP_FSYNC);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_READ);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn_cbk.readv = fn;
- args_readv_cbk_store (&stub->args_cbk, op_ret, op_errno, vector,
- count, stbuf, iobref, xdata);
+ stub->fn.fsync = fn;
+ args_fsync_store(&stub->args, fd, datasync, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_writev_stub (call_frame_t *frame, fop_writev_t fn,
- fd_t *fd, struct iovec *vector, int32_t count, off_t off,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+fop_fsync_cbk_stub(call_frame_t *frame, fop_fsync_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", vector, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_WRITE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FSYNC);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.writev = fn;
- if (fd)
- stub->args.fd = fd_ref (fd);
- stub->args.vector = iov_dup (vector, count);
- stub->args.count = count;
- stub->args.offset = off;
- stub->args.flags = flags;
- stub->args.iobref = iobref_ref (iobref);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.fsync = fn;
+ args_fsync_cbk_store(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_writev_cbk_stub (call_frame_t *frame, fop_writev_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+fop_opendir_stub(call_frame_t *frame, fop_opendir_t fn, loc_t *loc, fd_t *fd,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 0, GF_FOP_WRITE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_OPENDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.writev = fn;
- args_writev_cbk_store (&stub->args_cbk, op_ret, op_errno,
- prebuf, postbuf, xdata);
+ stub->fn.opendir = fn;
+ args_opendir_store(&stub->args, loc, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_flush_stub (call_frame_t *frame, fop_flush_t fn,
- fd_t *fd, dict_t *xdata)
+fop_opendir_cbk_stub(call_frame_t *frame, fop_opendir_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, fd_t *fd, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FLUSH);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_OPENDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.flush = fn;
- if (fd)
- stub->args.fd = fd_ref (fd);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.opendir = fn;
+ args_opendir_cbk_store(&stub->args_cbk, op_ret, op_errno, fd, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_flush_cbk_stub (call_frame_t *frame, fop_flush_cbk_t fn,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+fop_fsyncdir_stub(call_frame_t *frame, fop_fsyncdir_t fn, fd_t *fd,
+ int32_t datasync, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_FLUSH);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FSYNCDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.flush = fn;
- args_flush_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn.fsyncdir = fn;
+ args_fsyncdir_store(&stub->args, fd, datasync, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsync_stub (call_frame_t *frame, fop_fsync_t fn,
- fd_t *fd, int32_t datasync, dict_t *xdata)
+fop_fsyncdir_cbk_stub(call_frame_t *frame, fop_fsyncdir_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);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FSYNC);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FSYNCDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.fsync = fn;
- if (fd)
- stub->args.fd = fd_ref (fd);
- stub->args.datasync = datasync;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.fsyncdir = fn;
+ args_fsyncdir_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsync_cbk_stub (call_frame_t *frame, fop_fsync_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+fop_statfs_stub(call_frame_t *frame, fop_statfs_t fn, loc_t *loc, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 0, GF_FOP_FSYNC);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_STATFS);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.fsync = fn;
- args_fsync_cbk_store (&stub->args_cbk, op_ret, op_errno,
- prebuf, postbuf, xdata);
+ stub->fn.statfs = fn;
+ args_statfs_store(&stub->args, loc, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_opendir_stub (call_frame_t *frame, fop_opendir_t fn,
- loc_t *loc, fd_t *fd, dict_t *xdata)
+fop_statfs_cbk_stub(call_frame_t *frame, fop_statfs_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct statvfs *buf, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ stub = stub_new(frame, 0, GF_FOP_STATFS);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_OPENDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn.opendir = fn;
- loc_copy (&stub->args.loc, loc);
- if (fd)
- stub->args.fd = fd_ref (fd);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.statfs = fn;
+ args_statfs_cbk_store(&stub->args_cbk, op_ret, op_errno, buf, xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+fop_setxattr_stub(call_frame_t *frame, fop_setxattr_t fn, loc_t *loc,
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 0, GF_FOP_OPENDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_SETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.opendir = fn;
- args_opendir_cbk_store (&stub->args_cbk, op_ret, op_errno, fd, xdata);
+ stub->fn.setxattr = fn;
+ args_setxattr_store(&stub->args, loc, dict, flags, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsyncdir_stub (call_frame_t *frame, fop_fsyncdir_t fn,
- fd_t *fd, int32_t datasync, dict_t *xdata)
+fop_setxattr_cbk_stub(call_frame_t *frame, fop_setxattr_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_SETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_FSYNCDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn.fsyncdir = fn;
- if (fd)
- stub->args.fd = fd_ref (fd);
- stub->args.datasync = datasync;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.setxattr = fn;
+ args_setxattr_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsyncdir_cbk_stub (call_frame_t *frame, fop_fsyncdir_cbk_t fn,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+fop_getxattr_stub(call_frame_t *frame, fop_getxattr_t fn, loc_t *loc,
+ const char *name, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
- stub = stub_new (frame, 0, GF_FOP_FSYNCDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_GETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.fsyncdir = fn;
- args_fsyncdir_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn.getxattr = fn;
+ args_getxattr_store(&stub->args, loc, name, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_statfs_stub (call_frame_t *frame, fop_statfs_t fn,
- loc_t *loc, dict_t *xdata)
+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 *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_STATFS);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_GETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.statfs = fn;
- loc_copy (&stub->args.loc, loc);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.getxattr = fn;
+ args_getxattr_cbk_store(&stub->args_cbk, op_ret, op_errno, dict, xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+fop_fsetxattr_stub(call_frame_t *frame, fop_fsetxattr_t fn, fd_t *fd,
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fd, out);
- stub = stub_new (frame, 0, GF_FOP_STATFS);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FSETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.statfs = fn;
- args_statfs_cbk_store (&stub->args_cbk, op_ret, op_errno, buf, xdata);
+ stub->fn.fsetxattr = fn;
+ args_fsetxattr_store(&stub->args, fd, dict, flags, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_setxattr_stub (call_frame_t *frame, fop_setxattr_t fn,
- loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
+fop_fsetxattr_cbk_stub(call_frame_t *frame, fop_fsetxattr_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);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_SETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FSETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.setxattr = fn;
- loc_copy (&stub->args.loc, loc);
- /* TODO */
- if (dict)
- stub->args.xattr = dict_ref (dict);
- stub->args.flags = flags;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.fsetxattr = fn;
+ args_fsetxattr_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_setxattr_cbk_stub (call_frame_t *frame,
- fop_setxattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+fop_fgetxattr_stub(call_frame_t *frame, fop_fgetxattr_t fn, fd_t *fd,
+ const char *name, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fd, out);
- stub = stub_new (frame, 0, GF_FOP_SETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FGETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.setxattr = fn;
- args_setxattr_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn.fgetxattr = fn;
+ args_fgetxattr_store(&stub->args, fd, name, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_getxattr_stub (call_frame_t *frame, fop_getxattr_t fn,
- loc_t *loc, const char *name, dict_t *xdata)
+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 *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_GETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_GETXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.getxattr = fn;
- loc_copy (&stub->args.loc, loc);
-
- if (name)
- stub->args.name = gf_strdup (name);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.fgetxattr = fn;
+ args_fgetxattr_cbk_store(&stub->args_cbk, op_ret, op_errno, dict, xdata);
out:
- return stub;
+ return stub;
}
-
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 *dict, dict_t *xdata)
+fop_removexattr_stub(call_frame_t *frame, fop_removexattr_t fn, loc_t *loc,
+ const char *name, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", loc, out);
+ GF_VALIDATE_OR_GOTO("call-stub", name, out);
- stub = stub_new (frame, 0, GF_FOP_GETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_REMOVEXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.getxattr = fn;
- args_getxattr_cbk_store (&stub->args_cbk, op_ret, op_errno, dict,
- xdata);
+ stub->fn.removexattr = fn;
+ args_removexattr_store(&stub->args, loc, name, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsetxattr_stub (call_frame_t *frame, fop_fsetxattr_t fn,
- fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata)
+fop_removexattr_cbk_stub(call_frame_t *frame, fop_removexattr_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);
- GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FSETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_REMOVEXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.fsetxattr = fn;
- stub->args.fd = fd_ref (fd);
-
- if (dict)
- stub->args.xattr = dict_ref (dict);
- stub->args.flags = flags;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.removexattr = fn;
+ args_removexattr_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsetxattr_cbk_stub (call_frame_t *frame, fop_fsetxattr_cbk_t fn,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+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;
+ 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, 0, GF_FOP_FSETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FREMOVEXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.fsetxattr = fn;
- args_fsetxattr_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn.fremovexattr = fn;
+ args_fremovexattr_store(&stub->args, fd, name, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fgetxattr_stub (call_frame_t *frame, fop_fgetxattr_t fn,
- fd_t *fd, const char *name, dict_t *xdata)
+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);
- GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FGETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FREMOVEXATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.fgetxattr = fn;
- stub->args.fd = fd_ref (fd);
-
- if (name)
- stub->args.name = gf_strdup (name);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.fremovexattr = fn;
+ args_fremovexattr_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
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 *dict, dict_t *xdata)
+fop_lk_stub(call_frame_t *frame, fop_lk_t fn, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", lock, out);
- stub = stub_new (frame, 0, GF_FOP_GETXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_LK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.fgetxattr = fn;
- args_fgetxattr_cbk_store (&stub->args_cbk, op_ret, op_errno, dict,
- xdata);
+ stub->fn.lk = fn;
+ args_lk_store(&stub->args, fd, cmd, lock, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_removexattr_stub (call_frame_t *frame, fop_removexattr_t fn,
- loc_t *loc, const char *name, dict_t *xdata)
+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, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", loc, out);
- GF_VALIDATE_OR_GOTO ("call-stub", name, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_REMOVEXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_LK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.removexattr = fn;
- loc_copy (&stub->args.loc, loc);
- stub->args.name = gf_strdup (name);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.lk = fn;
+ args_lk_cbk_store(&stub->args_cbk, op_ret, op_errno, lock, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_removexattr_cbk_stub (call_frame_t *frame, fop_removexattr_cbk_t fn,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+fop_inodelk_stub(call_frame_t *frame, fop_inodelk_t fn, const char *volume,
+ loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", lock, out);
- stub = stub_new (frame, 0, GF_FOP_REMOVEXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_INODELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.removexattr = fn;
- args_removexattr_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn.inodelk = fn;
+ args_inodelk_store(&stub->args, volume, loc, cmd, lock, xdata);
out:
- return stub;
+ 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)
+fop_inodelk_cbk_stub(call_frame_t *frame, fop_inodelk_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);
- GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
- GF_VALIDATE_OR_GOTO ("call-stub", name, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_FREMOVEXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_INODELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.fremovexattr = fn;
- stub->args.fd = fd_ref (fd);
- stub->args.name = gf_strdup (name);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.inodelk = fn;
+ args_inodelk_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ 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)
+fop_finodelk_stub(call_frame_t *frame, fop_finodelk_t fn, const char *volume,
+ fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", lock, out);
- stub = stub_new (frame, 0, GF_FOP_FREMOVEXATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FINODELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ stub->fn.finodelk = fn;
+ args_finodelk_store(&stub->args, volume, fd, cmd, lock, xdata);
- stub->fn_cbk.fremovexattr = fn;
- args_fremovexattr_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ 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, dict_t *xdata)
+fop_finodelk_cbk_stub(call_frame_t *frame, fop_inodelk_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", lock, out);
+ stub = stub_new(frame, 0, GF_FOP_FINODELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_LK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn.lk = fn;
- if (fd)
- stub->args.fd = fd_ref (fd);
- stub->args.cmd = cmd;
- stub->args.lock = *lock;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.finodelk = fn;
+ args_finodelk_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+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, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 1, GF_FOP_ENTRYLK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_LK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.entrylk = fn;
+ args_entrylk_store(&stub->args, volume, loc, name, cmd, type, xdata);
- stub->fn_cbk.lk = fn;
- args_lk_cbk_store (&stub->args_cbk, op_ret, op_errno, lock, xdata);
out:
- return stub;
+ 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, dict_t *xdata)
+fop_entrylk_cbk_stub(call_frame_t *frame, fop_entrylk_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", lock, out);
+ stub = stub_new(frame, 0, GF_FOP_ENTRYLK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_INODELK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.entrylk = fn;
+ args_entrylk_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
+out:
+ return stub;
+}
- stub->fn.inodelk = fn;
+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, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (volume)
- stub->args.volume = gf_strdup (volume);
+ stub = stub_new(frame, 1, GF_FOP_FENTRYLK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- loc_copy (&stub->args.loc, loc);
- stub->args.cmd = cmd;
- stub->args.lock = *lock;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.fentrylk = fn;
+ args_fentrylk_store(&stub->args, volume, fd, name, cmd, type, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_inodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
+fop_fentrylk_cbk_stub(call_frame_t *frame, fop_fentrylk_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);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_INODELK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FENTRYLK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.inodelk = fn;
- args_inodelk_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn_cbk.fentrylk = fn;
+ args_fentrylk_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+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,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", lock, out);
+ stub = stub_new(frame, 0, GF_FOP_READDIRP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_FINODELK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.readdirp = fn;
+ args_readdirp_cbk_store(&stub->args_cbk, op_ret, op_errno, entries, xdata);
+out:
+ return stub;
+}
- stub->fn.finodelk = fn;
+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, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (fd)
- stub->args.fd = fd_ref (fd);
+ stub = stub_new(frame, 0, GF_FOP_READDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (volume)
- stub->args.volume = gf_strdup (volume);
+ stub->fn_cbk.readdir = fn;
+ args_readdir_cbk_store(&stub->args_cbk, op_ret, op_errno, entries, xdata);
+out:
+ return stub;
+}
+
+call_stub_t *
+fop_readdir_stub(call_frame_t *frame, fop_readdir_t fn, fd_t *fd, size_t size,
+ off_t off, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- stub->args.cmd = cmd;
- stub->args.lock = *lock;
+ stub = stub_new(frame, 1, GF_FOP_READDIR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.readdir = fn;
+ args_readdir_store(&stub->args, fd, size, off, xdata);
out:
- return stub;
+ return stub;
}
+call_stub_t *
+fop_readdirp_stub(call_frame_t *frame, fop_readdirp_t fn, fd_t *fd, size_t size,
+ off_t off, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ stub = stub_new(frame, 1, GF_FOP_READDIRP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ stub->fn.readdirp = fn;
+ args_readdirp_store(&stub->args, fd, size, off, xdata);
+out:
+ return stub;
+}
call_stub_t *
-fop_finodelk_cbk_stub (call_frame_t *frame, fop_inodelk_cbk_t fn,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+fop_rchecksum_stub(call_frame_t *frame, fop_rchecksum_t fn, fd_t *fd,
+ off_t offset, int32_t len, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fd, out);
- stub = stub_new (frame, 0, GF_FOP_FINODELK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_RCHECKSUM);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.finodelk = fn;
- args_finodelk_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn.rchecksum = fn;
+ args_rchecksum_store(&stub->args, fd, offset, len, xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+fop_rchecksum_cbk_stub(call_frame_t *frame, fop_rchecksum_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, uint32_t weak_checksum,
+ uint8_t *strong_checksum, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_RCHECKSUM);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_ENTRYLK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.rchecksum = fn;
+ args_rchecksum_cbk_store(&stub->args_cbk, op_ret, op_errno, weak_checksum,
+ strong_checksum, xdata);
+out:
+ return stub;
+}
- stub->fn.entrylk = fn;
+call_stub_t *
+fop_xattrop_cbk_stub(call_frame_t *frame, fop_xattrop_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xattr, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (volume)
- stub->args.volume = gf_strdup (volume);
+ stub = stub_new(frame, 0, GF_FOP_XATTROP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- loc_copy (&stub->args.loc, loc);
+ stub->fn_cbk.xattrop = fn;
+ args_xattrop_cbk_store(&stub->args_cbk, op_ret, op_errno, xattr, xdata);
+out:
+ return stub;
+}
- stub->args.entrylkcmd = cmd;
- stub->args.entrylktype = type;
+call_stub_t *
+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 *xdata)
+{
+ call_stub_t *stub = NULL;
- if (name)
- stub->args.name = gf_strdup (name);
+ stub = stub_new(frame, 0, GF_FOP_FXATTROP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.fxattrop = fn;
+ args_xattrop_cbk_store(&stub->args_cbk, op_ret, op_errno, xattr, xdata);
out:
- return stub;
+ 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, dict_t *xdata)
+fop_xattrop_stub(call_frame_t *frame, fop_xattrop_t fn, loc_t *loc,
+ gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", xattr, out);
- stub = stub_new (frame, 0, GF_FOP_ENTRYLK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_XATTROP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.entrylk = fn;
- args_entrylk_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn.xattrop = fn;
+ args_xattrop_store(&stub->args, loc, optype, xattr, xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+fop_fxattrop_stub(call_frame_t *frame, fop_fxattrop_t fn, fd_t *fd,
+ gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", xattr, out);
- stub = stub_new (frame, 1, GF_FOP_FENTRYLK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FXATTROP);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.fentrylk = fn;
+ stub->fn.fxattrop = fn;
+ args_fxattrop_store(&stub->args, fd, optype, xattr, xdata);
+out:
+ return stub;
+}
- if (volume)
- stub->args.volume = gf_strdup (volume);
+call_stub_t *
+fop_setattr_cbk_stub(call_frame_t *frame, fop_setattr_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (fd)
- stub->args.fd = fd_ref (fd);
- stub->args.entrylkcmd = cmd;
- stub->args.entrylktype = type;
- if (name)
- stub->args.name = gf_strdup (name);
+ stub = stub_new(frame, 0, GF_FOP_SETATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.setattr = fn;
+ args_setattr_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre, statpost,
+ xdata);
out:
- return stub;
+ 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, dict_t *xdata)
+fop_fsetattr_cbk_stub(call_frame_t *frame, fop_setattr_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_FENTRYLK);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FSETATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.fentrylk = fn;
- args_fentrylk_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
+ stub->fn_cbk.fsetattr = fn;
+ args_fsetattr_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre,
+ statpost, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-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, dict_t *xdata)
+fop_setattr_stub(call_frame_t *frame, fop_setattr_t fn, loc_t *loc,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 0, GF_FOP_READDIRP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_SETATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.readdirp = fn;
- args_readdirp_cbk_store (&stub->args_cbk, op_ret, op_errno, entries,
- xdata);
+ stub->fn.setattr = fn;
+ args_setattr_store(&stub->args, loc, stbuf, valid, xdata);
out:
- return stub;
+ return stub;
}
-
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, dict_t *xdata)
+fop_fsetattr_stub(call_frame_t *frame, fop_fsetattr_t fn, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 0, GF_FOP_READDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FSETATTR);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.readdir = fn;
- args_readdir_cbk_store (&stub->args_cbk, op_ret, op_errno, entries,
- xdata);
+ stub->fn.fsetattr = fn;
+ args_fsetattr_store(&stub->args, fd, stbuf, valid, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readdir_stub (call_frame_t *frame, fop_readdir_t fn,
- fd_t *fd, size_t size,
- off_t off, dict_t *xdata)
+fop_fallocate_cbk_stub(call_frame_t *frame, fop_fallocate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 1, GF_FOP_READDIR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_FALLOCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.readdir = fn;
- stub->args.fd = fd_ref (fd);
- stub->args.size = size;
- stub->args.offset = off;
+ stub->fn_cbk.fallocate = fn;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ args_fallocate_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre,
+ statpost, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_readdirp_stub (call_frame_t *frame, fop_readdirp_t fn,
- fd_t *fd, size_t size, off_t off, dict_t *xdata)
+fop_fallocate_stub(call_frame_t *frame, fop_fallocate_t fn, fd_t *fd,
+ int32_t mode, off_t offset, size_t len, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 1, GF_FOP_READDIRP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_FALLOCATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.readdirp = fn;
- stub->args.fd = fd_ref (fd);
- stub->args.size = size;
- stub->args.offset = off;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn.fallocate = fn;
+ args_fallocate_store(&stub->args, fd, mode, offset, len, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_rchecksum_stub (call_frame_t *frame, fop_rchecksum_t fn,
- fd_t *fd, off_t offset, int32_t len, dict_t *xdata)
+fop_discard_cbk_stub(call_frame_t *frame, fop_discard_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fd, out);
+ stub = stub_new(frame, 0, GF_FOP_DISCARD);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_RCHECKSUM);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.discard = fn;
- stub->fn.rchecksum = fn;
- stub->args.fd = fd_ref (fd);
- stub->args.offset = offset;
- stub->args.size = len;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ args_discard_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre, statpost,
+ xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_rchecksum_cbk_stub (call_frame_t *frame, fop_rchecksum_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- uint32_t weak_checksum, uint8_t *strong_checksum,
- dict_t *xdata)
+fop_discard_stub(call_frame_t *frame, fop_discard_t fn, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 0, GF_FOP_RCHECKSUM);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_DISCARD);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.rchecksum = fn;
- args_rchecksum_cbk_store (&stub->args_cbk, op_ret, op_errno,
- weak_checksum, strong_checksum, xdata);
+ stub->fn.discard = fn;
+ args_discard_store(&stub->args, fd, offset, len, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_xattrop_cbk_stub (call_frame_t *frame, fop_xattrop_cbk_t fn, int32_t op_ret,
- int32_t op_errno, dict_t *xattr, dict_t *xdata)
+fop_zerofill_cbk_stub(call_frame_t *frame, fop_zerofill_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_XATTROP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.zerofill = fn;
- stub->fn_cbk.xattrop = fn;
- args_xattrop_cbk_store (&stub->args_cbk, op_ret, op_errno, xattr,
- xdata);
+ args_zerofill_cbk_store(&stub->args_cbk, op_ret, op_errno, statpre,
+ statpost, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-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 *xdata)
+fop_zerofill_stub(call_frame_t *frame, fop_zerofill_t fn, fd_t *fd,
+ off_t offset, off_t len, dict_t *xdata)
{
- call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_FXATTROP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub->fn_cbk.fxattrop = fn;
- args_xattrop_cbk_store (&stub->args_cbk, op_ret, op_errno, xattr,
- xdata);
+ stub = stub_new(frame, 1, GF_FOP_ZEROFILL);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ stub->fn.zerofill = fn;
+ args_zerofill_store(&stub->args, fd, offset, len, xdata);
out:
- return stub;
+ return stub;
}
-
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 *xdata)
+fop_ipc_cbk_stub(call_frame_t *frame, fop_ipc_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);
- GF_VALIDATE_OR_GOTO ("call-stub", xattr, out);
-
- stub = stub_new (frame, 1, GF_FOP_XATTROP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
-
- stub->fn.xattrop = fn;
+ call_stub_t *stub = NULL;
- loc_copy (&stub->args.loc, loc);
+ stub = stub_new(frame, 0, GF_FOP_IPC);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.optype = optype;
- stub->args.xattr = dict_ref (xattr);
+ stub->fn_cbk.ipc = fn;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ args_ipc_cbk_store(&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
-
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 *xdata)
+fop_ipc_stub(call_frame_t *frame, fop_ipc_t fn, int32_t op, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", xattr, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 1, GF_FOP_FXATTROP);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_IPC);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.fxattrop = fn;
+ stub->fn.ipc = fn;
+ args_ipc_store(&stub->args, op, xdata);
+out:
+ return stub;
+}
- stub->args.fd = fd_ref (fd);
+call_stub_t *
+fop_lease_cbk_stub(call_frame_t *frame, fop_lease_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct gf_lease *lease, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- stub->args.optype = optype;
- stub->args.xattr = dict_ref (xattr);
+ stub = stub_new(frame, 0, GF_FOP_LEASE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ stub->fn_cbk.lease = fn;
+ args_lease_cbk_store(&stub->args_cbk, op_ret, op_errno, lease, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_setattr_cbk_stub (call_frame_t *frame, fop_setattr_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
+fop_lease_stub(call_frame_t *frame, fop_lease_t fn, loc_t *loc,
+ struct gf_lease *lease, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
+ GF_VALIDATE_OR_GOTO("call-stub", lease, out);
- stub = stub_new (frame, 0, GF_FOP_SETATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_LEASE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.setattr = fn;
- args_setattr_cbk_store (&stub->args_cbk, op_ret, op_errno, statpre,
- statpost, xdata);
+ stub->fn.lease = fn;
+ args_lease_store(&stub->args, loc, lease, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsetattr_cbk_stub (call_frame_t *frame, fop_setattr_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
+fop_seek_cbk_stub(call_frame_t *frame, fop_seek_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, off_t offset, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_SEEK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_FSETATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.seek = fn;
- stub->fn_cbk.fsetattr = fn;
- args_fsetattr_cbk_store (&stub->args_cbk, op_ret, op_errno, statpre,
- statpost, xdata);
+ args_seek_cbk_store(&stub->args_cbk, op_ret, op_errno, offset, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_setattr_stub (call_frame_t *frame, fop_setattr_t fn,
- loc_t *loc, struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
+fop_seek_stub(call_frame_t *frame, fop_seek_t fn, fd_t *fd, off_t offset,
+ gf_seek_what_t what, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 1, GF_FOP_SETATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_SEEK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.setattr = fn;
+ stub->fn.seek = fn;
+ args_seek_store(&stub->args, fd, offset, what, xdata);
+out:
+ return stub;
+}
- loc_copy (&stub->args.loc, loc);
+call_stub_t *
+fop_getactivelk_cbk_stub(call_frame_t *frame, fop_getactivelk_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ lock_migration_info_t *lmi, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (stbuf)
- stub->args.stat = *stbuf;
+ stub = stub_new(frame, 0, GF_FOP_GETACTIVELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.valid = valid;
+ stub->fn_cbk.getactivelk = fn;
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ args_getactivelk_cbk_store(&stub->args_cbk, op_ret, op_errno, lmi, xdata);
out:
- return stub;
+ return stub;
}
-
call_stub_t *
-fop_fsetattr_stub (call_frame_t *frame, fop_fsetattr_t fn,
- fd_t *fd, struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
+fop_getactivelk_stub(call_frame_t *frame, fop_getactivelk_t fn, loc_t *loc,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
-
- stub = stub_new (frame, 1, GF_FOP_FSETATTR);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- stub->fn.fsetattr = fn;
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- if (fd)
- stub->args.fd = fd_ref (fd);
+ stub = stub_new(frame, 1, GF_FOP_GETACTIVELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (stbuf)
- stub->args.stat = *stbuf;
+ stub->fn.getactivelk = fn;
- stub->args.valid = valid;
+ loc_copy(&stub->args.loc, loc);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
+ if (xdata)
+ stub->args.xdata = dict_ref(xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_fallocate_cbk_stub(call_frame_t *frame, fop_fallocate_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
+fop_setactivelk_cbk_stub(call_frame_t *frame, fop_setactivelk_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 0, GF_FOP_SETACTIVELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_FALLOCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.setactivelk = fn;
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
- stub->fn_cbk.fallocate = fn;
+ if (xdata)
+ stub->args.xdata = dict_ref(xdata);
- args_fallocate_cbk_store (&stub->args_cbk, op_ret, op_errno, statpre,
- statpost, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_fallocate_stub(call_frame_t *frame, fop_fallocate_t fn, fd_t *fd,
- int32_t mode, off_t offset, size_t len, dict_t *xdata)
+fop_setactivelk_stub(call_frame_t *frame, fop_setactivelk_t fn, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 1, GF_FOP_FALLOCATE);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_SETACTIVELK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.fallocate = fn;
+ stub->fn.setactivelk = fn;
- if (fd)
- stub->args.fd = fd_ref (fd);
+ args_setactivelk_store(&stub->args, loc, locklist, xdata);
- stub->args.flags = mode;
- stub->args.offset = offset;
- stub->args.size = len;
-
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
out:
- return stub;
-
+ return stub;
}
call_stub_t *
-fop_discard_cbk_stub(call_frame_t *frame, fop_discard_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
+fop_copy_file_range_stub(call_frame_t *frame, fop_copy_file_range_t fn,
+ fd_t *fd_in, off64_t off_in, fd_t *fd_out,
+ off64_t off_out, size_t len, uint32_t flags,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ stub = stub_new(frame, 1, GF_FOP_COPY_FILE_RANGE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 0, GF_FOP_DISCARD);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn.copy_file_range = fn;
- stub->fn_cbk.discard = fn;
+ args_copy_file_range_store(&stub->args, fd_in, off_in, fd_out, off_out, len,
+ flags, xdata);
- args_discard_cbk_store (&stub->args_cbk, op_ret, op_errno, statpre,
- statpost, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_discard_stub(call_frame_t *frame, fop_discard_t fn, fd_t *fd,
- off_t offset, size_t len, dict_t *xdata)
+fop_copy_file_range_cbk_stub(call_frame_t *frame, fop_copy_file_range_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *stbuf, struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
-
- stub = stub_new (frame, 1, GF_FOP_DISCARD);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ call_stub_t *stub = NULL;
- stub->fn.discard = fn;
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- if (fd)
- stub->args.fd = fd_ref (fd);
+ stub = stub_new(frame, 0, GF_FOP_COPY_FILE_RANGE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->args.offset = offset;
- stub->args.size = len;
+ stub->fn_cbk.copy_file_range = fn;
+ args_copy_file_range_cbk_store(&stub->args_cbk, op_ret, op_errno, stbuf,
+ prebuf_dst, postbuf_dst, xdata);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
out:
- return stub;
-
+ return stub;
}
call_stub_t *
-fop_zerofill_cbk_stub(call_frame_t *frame, fop_zerofill_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
+fop_put_stub(call_frame_t *frame, fop_put_t fn, loc_t *loc, mode_t mode,
+ mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,
+ off_t offset, struct iobref *iobref, dict_t *xattr, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO("call-stub", vector, out);
- stub = stub_new (frame, 0, GF_FOP_ZEROFILL);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_PUT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.zerofill = fn;
-
- args_zerofill_cbk_store (&stub->args_cbk, op_ret, op_errno, statpre,
- statpost, xdata);
+ stub->fn.put = fn;
+ args_put_store(&stub->args, loc, mode, umask, flags, vector, count, offset,
+ iobref, xattr, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_zerofill_stub(call_frame_t *frame, fop_zerofill_t fn, fd_t *fd,
- off_t offset, off_t len, dict_t *xdata)
+fop_put_cbk_stub(call_frame_t *frame, fop_put_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+ stub = stub_new(frame, 0, GF_FOP_PUT);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub = stub_new (frame, 1, GF_FOP_ZEROFILL);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub->fn_cbk.put = fn;
+ args_put_cbk_store(&stub->args_cbk, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+out:
+ return stub;
+}
- stub->fn.zerofill = fn;
+call_stub_t *
+fop_icreate_stub(call_frame_t *frame, fop_icreate_t fn, loc_t *loc, mode_t mode,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
- if (fd)
- stub->args.fd = fd_ref (fd);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub->args.offset = offset;
- stub->args.size = len;
+ stub = stub_new(frame, 1, GF_FOP_ICREATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
-out:
- return stub;
+ stub->fn.icreate = fn;
+
+ stub->args.mode = mode;
+ if (loc)
+ loc_copy(&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref(xdata);
+out:
+ return stub;
}
+static void
+args_icreate_store_cbk(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+}
call_stub_t *
-fop_ipc_cbk_stub (call_frame_t *frame, fop_ipc_cbk_t fn,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+fop_icreate_cbk_stub(call_frame_t *frame, fop_icreate_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
-
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ call_stub_t *stub = NULL;
- stub = stub_new (frame, 0, GF_FOP_IPC);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 0, GF_FOP_ICREATE);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn_cbk.ipc = fn;
+ stub->fn_cbk.icreate = fn;
+ args_icreate_store_cbk(&stub->args_cbk, op_ret, op_errno, inode, buf,
+ xdata);
- args_ipc_cbk_store (&stub->args_cbk, op_ret, op_errno, xdata);
out:
- return stub;
+ return stub;
}
call_stub_t *
-fop_ipc_stub (call_frame_t *frame, fop_ipc_t fn,
- int32_t op, dict_t *xdata)
+fop_namelink_stub(call_frame_t *frame, fop_namelink_t fn, loc_t *loc,
+ dict_t *xdata)
{
- call_stub_t *stub = NULL;
+ call_stub_t *stub = NULL;
- GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
- GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+ GF_VALIDATE_OR_GOTO("call-stub", fn, out);
- stub = stub_new (frame, 1, GF_FOP_IPC);
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ stub = stub_new(frame, 1, GF_FOP_NAMELINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- stub->fn.ipc = fn;
+ stub->fn.namelink = fn;
- stub->args.cmd = op;
+ if (loc)
+ loc_copy(&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref(xdata);
- if (xdata)
- stub->args.xdata = dict_ref (xdata);
out:
- return stub;
+ return stub;
+}
+static void
+args_namelink_store_cbk(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (postbuf)
+ args->poststat = *postbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
}
+call_stub_t *
+fop_namelink_cbk_stub(call_frame_t *frame, fop_namelink_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ stub = stub_new(frame, 0, GF_FOP_NAMELINK);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
+
+ stub->fn_cbk.namelink = fn;
+ args_namelink_store_cbk(&stub->args_cbk, op_ret, op_errno, prebuf, postbuf,
+ xdata);
+
+out:
+ return stub;
+}
void
-call_resume_wind (call_stub_t *stub)
+call_resume_wind(call_stub_t *stub)
{
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- switch (stub->fop) {
+ switch (stub->fop) {
case GF_FOP_OPEN:
- stub->fn.open (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.flags,
- stub->args.fd, stub->args.xdata);
- break;
+ stub->fn.open(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.flags, stub->args.fd, stub->args.xdata);
+ break;
case GF_FOP_CREATE:
- stub->fn.create (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.flags,
- stub->args.mode, stub->args.umask,
- stub->args.fd, stub->args.xdata);
- break;
+ stub->fn.create(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.flags, stub->args.mode, stub->args.umask,
+ stub->args.fd, stub->args.xdata);
+ break;
case GF_FOP_STAT:
- stub->fn.stat (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.xdata);
- break;
+ stub->fn.stat(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xdata);
+ break;
case GF_FOP_READLINK:
- stub->fn.readlink (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.size,
- stub->args.xdata);
- break;
+ stub->fn.readlink(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.size, stub->args.xdata);
+ break;
case GF_FOP_MKNOD:
- stub->fn.mknod (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.mode,
- stub->args.rdev, stub->args.umask,
- stub->args.xdata);
- break;
+ stub->fn.mknod(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.mode, stub->args.rdev, stub->args.umask,
+ stub->args.xdata);
+ break;
case GF_FOP_MKDIR:
- stub->fn.mkdir (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.mode,
- stub->args.umask, stub->args.xdata);
- break;
+ stub->fn.mkdir(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.mode, stub->args.umask, stub->args.xdata);
+ break;
case GF_FOP_UNLINK:
- stub->fn.unlink (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.xflag,
- stub->args.xdata);
- break;
+ stub->fn.unlink(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xflag, stub->args.xdata);
+ break;
case GF_FOP_RMDIR:
- stub->fn.rmdir (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.flags,
- stub->args.xdata);
- break;
+ stub->fn.rmdir(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.flags, stub->args.xdata);
+ break;
case GF_FOP_SYMLINK:
- stub->fn.symlink (stub->frame, stub->frame->this,
- stub->args.linkname, &stub->args.loc,
- stub->args.umask, stub->args.xdata);
- break;
+ stub->fn.symlink(stub->frame, stub->frame->this,
+ stub->args.linkname, &stub->args.loc,
+ stub->args.umask, stub->args.xdata);
+ break;
case GF_FOP_RENAME:
- stub->fn.rename (stub->frame, stub->frame->this,
- &stub->args.loc, &stub->args.loc2,
- stub->args.xdata);
- break;
+ stub->fn.rename(stub->frame, stub->frame->this, &stub->args.loc,
+ &stub->args.loc2, stub->args.xdata);
+ break;
case GF_FOP_LINK:
- stub->fn.link (stub->frame, stub->frame->this,
- &stub->args.loc, &stub->args.loc2,
- stub->args.xdata);
- break;
+ stub->fn.link(stub->frame, stub->frame->this, &stub->args.loc,
+ &stub->args.loc2, stub->args.xdata);
+ break;
case GF_FOP_TRUNCATE:
- stub->fn.truncate (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.offset,
- stub->args.xdata);
- break;
+ stub->fn.truncate(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.offset, stub->args.xdata);
+ break;
case GF_FOP_READ:
- stub->fn.readv (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.size,
- stub->args.offset, stub->args.flags,
- stub->args.xdata);
- break;
+ stub->fn.readv(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.size, stub->args.offset, stub->args.flags,
+ stub->args.xdata);
+ break;
case GF_FOP_WRITE:
- stub->fn.writev (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.vector,
- stub->args.count, stub->args.offset,
- stub->args.flags, stub->args.iobref,
- stub->args.xdata);
- break;
+ stub->fn.writev(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.vector, stub->args.count,
+ stub->args.offset, stub->args.flags,
+ stub->args.iobref, stub->args.xdata);
+ break;
case GF_FOP_STATFS:
- stub->fn.statfs (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.xdata);
- break;
+ stub->fn.statfs(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xdata);
+ break;
case GF_FOP_FLUSH:
- stub->fn.flush (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.xdata);
- break;
+ stub->fn.flush(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.xdata);
+ break;
case GF_FOP_FSYNC:
- stub->fn.fsync (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.datasync,
- stub->args.xdata);
- break;
+ stub->fn.fsync(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.datasync, stub->args.xdata);
+ break;
case GF_FOP_SETXATTR:
- stub->fn.setxattr (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.xattr,
- stub->args.flags, stub->args.xdata);
- break;
+ stub->fn.setxattr(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xattr, stub->args.flags,
+ stub->args.xdata);
+ break;
case GF_FOP_GETXATTR:
- stub->fn.getxattr (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.name,
- stub->args.xdata);
- break;
+ stub->fn.getxattr(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.name, stub->args.xdata);
+ break;
case GF_FOP_FSETXATTR:
- stub->fn.fsetxattr (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.xattr,
- stub->args.flags, stub->args.xdata);
- break;
+ stub->fn.fsetxattr(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.xattr, stub->args.flags,
+ stub->args.xdata);
+ break;
case GF_FOP_FGETXATTR:
- stub->fn.fgetxattr (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.name,
- stub->args.xdata);
- break;
+ stub->fn.fgetxattr(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.name, stub->args.xdata);
+ break;
case GF_FOP_REMOVEXATTR:
- stub->fn.removexattr (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.name,
- stub->args.xdata);
- break;
+ stub->fn.removexattr(stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.name,
+ stub->args.xdata);
+ break;
case GF_FOP_FREMOVEXATTR:
- stub->fn.fremovexattr (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.name,
- stub->args.xdata);
- break;
+ stub->fn.fremovexattr(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.name, stub->args.xdata);
+ break;
case GF_FOP_OPENDIR:
- stub->fn.opendir (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.fd,
- stub->args.xdata);
- break;
+ stub->fn.opendir(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.fd, stub->args.xdata);
+ break;
case GF_FOP_FSYNCDIR:
- stub->fn.fsyncdir (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.datasync,
- stub->args.xdata);
- break;
+ stub->fn.fsyncdir(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.datasync, stub->args.xdata);
+ break;
case GF_FOP_ACCESS:
- stub->fn.access (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.mask,
- stub->args.xdata);
- break;
+ stub->fn.access(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.mask, stub->args.xdata);
+ break;
case GF_FOP_FTRUNCATE:
- stub->fn.ftruncate (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.offset,
- stub->args.xdata);
- break;
+ stub->fn.ftruncate(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.xdata);
+ break;
case GF_FOP_FSTAT:
- stub->fn.fstat (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.xdata);
- break;
+ stub->fn.fstat(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.xdata);
+ break;
case GF_FOP_LK:
- stub->fn.lk (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.cmd,
- &stub->args.lock, stub->args.xdata);
- break;
+ stub->fn.lk(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.cmd, &stub->args.lock, stub->args.xdata);
+ break;
case GF_FOP_INODELK:
- stub->fn.inodelk (stub->frame, stub->frame->this,
- stub->args.volume, &stub->args.loc,
- stub->args.cmd, &stub->args.lock,
- stub->args.xdata);
- break;
+ stub->fn.inodelk(stub->frame, stub->frame->this, stub->args.volume,
+ &stub->args.loc, stub->args.cmd, &stub->args.lock,
+ stub->args.xdata);
+ break;
case GF_FOP_FINODELK:
- stub->fn.finodelk (stub->frame, stub->frame->this,
- stub->args.volume, stub->args.fd,
- stub->args.cmd, &stub->args.lock,
- stub->args.xdata);
- break;
+ stub->fn.finodelk(stub->frame, stub->frame->this, stub->args.volume,
+ stub->args.fd, stub->args.cmd, &stub->args.lock,
+ stub->args.xdata);
+ break;
case GF_FOP_ENTRYLK:
- stub->fn.entrylk (stub->frame, stub->frame->this,
- stub->args.volume, &stub->args.loc,
- stub->args.name, stub->args.entrylkcmd,
- stub->args.entrylktype, stub->args.xdata);
- break;
+ stub->fn.entrylk(stub->frame, stub->frame->this, stub->args.volume,
+ &stub->args.loc, stub->args.name,
+ stub->args.entrylkcmd, stub->args.entrylktype,
+ stub->args.xdata);
+ break;
case GF_FOP_FENTRYLK:
- stub->fn.fentrylk (stub->frame, stub->frame->this,
- stub->args.volume, stub->args.fd,
- stub->args.name, stub->args.entrylkcmd,
- stub->args.entrylktype, stub->args.xdata);
- break;
+ stub->fn.fentrylk(stub->frame, stub->frame->this, stub->args.volume,
+ stub->args.fd, stub->args.name,
+ stub->args.entrylkcmd, stub->args.entrylktype,
+ stub->args.xdata);
+ break;
case GF_FOP_LOOKUP:
- stub->fn.lookup (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.xdata);
- break;
+ stub->fn.lookup(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.xdata);
+ break;
case GF_FOP_RCHECKSUM:
- stub->fn.rchecksum (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.offset,
- stub->args.size, stub->args.xdata);
- break;
+ stub->fn.rchecksum(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.size,
+ stub->args.xdata);
+ break;
case GF_FOP_READDIR:
- stub->fn.readdir (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.size,
- stub->args.offset, stub->args.xdata);
- break;
+ stub->fn.readdir(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.size, stub->args.offset,
+ stub->args.xdata);
+ break;
case GF_FOP_READDIRP:
- stub->fn.readdirp (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.size,
- stub->args.offset, stub->args.xdata);
- break;
+ stub->fn.readdirp(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.size, stub->args.offset,
+ stub->args.xdata);
+ break;
case GF_FOP_XATTROP:
- stub->fn.xattrop (stub->frame, stub->frame->this,
- &stub->args.loc, stub->args.optype,
- stub->args.xattr, stub->args.xdata);
- break;
+ stub->fn.xattrop(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.optype, stub->args.xattr,
+ stub->args.xdata);
+ break;
case GF_FOP_FXATTROP:
- stub->fn.fxattrop (stub->frame, stub->frame->this,
- stub->args.fd, stub->args.optype,
- stub->args.xattr, stub->args.xdata);
- break;
+ stub->fn.fxattrop(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.optype, stub->args.xattr,
+ stub->args.xdata);
+ break;
case GF_FOP_SETATTR:
- stub->fn.setattr (stub->frame, stub->frame->this,
- &stub->args.loc, &stub->args.stat,
- stub->args.valid, stub->args.xdata);
- break;
+ stub->fn.setattr(stub->frame, stub->frame->this, &stub->args.loc,
+ &stub->args.stat, stub->args.valid,
+ stub->args.xdata);
+ break;
case GF_FOP_FSETATTR:
- stub->fn.fsetattr (stub->frame, stub->frame->this,
- stub->args.fd, &stub->args.stat,
- stub->args.valid, stub->args.xdata);
- break;
- case GF_FOP_FALLOCATE:
- stub->fn.fallocate(stub->frame, stub->frame->this,
- stub->args.fd, stub->args.flags,
- stub->args.offset, stub->args.size,
- stub->args.xdata);
- break;
- case GF_FOP_DISCARD:
- stub->fn.discard(stub->frame, stub->frame->this,
- stub->args.fd, stub->args.offset,
- stub->args.size, stub->args.xdata);
- break;
+ stub->fn.fsetattr(stub->frame, stub->frame->this, stub->args.fd,
+ &stub->args.stat, stub->args.valid,
+ stub->args.xdata);
+ break;
+ case GF_FOP_FALLOCATE:
+ stub->fn.fallocate(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.flags, stub->args.offset,
+ stub->args.size, stub->args.xdata);
+ break;
+ case GF_FOP_DISCARD:
+ stub->fn.discard(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.size,
+ stub->args.xdata);
+ break;
case GF_FOP_ZEROFILL:
- stub->fn.zerofill(stub->frame, stub->frame->this,
- stub->args.fd, stub->args.offset,
- stub->args.size, stub->args.xdata);
- break;
+ stub->fn.zerofill(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.size,
+ stub->args.xdata);
+ break;
case GF_FOP_IPC:
- stub->fn.ipc (stub->frame, stub->frame->this,
- stub->args.cmd, stub->args.xdata);
- break;
+ stub->fn.ipc(stub->frame, stub->frame->this, stub->args.cmd,
+ stub->args.xdata);
+ break;
+ case GF_FOP_SEEK:
+ stub->fn.seek(stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.offset, stub->args.what, stub->args.xdata);
+ break;
+ case GF_FOP_LEASE:
+ stub->fn.lease(stub->frame, stub->frame->this, &stub->args.loc,
+ &stub->args.lease, stub->args.xdata);
+ break;
+
+ case GF_FOP_GETACTIVELK:
+ stub->fn.getactivelk(stub->frame, stub->frame->this,
+ &stub->args.loc, stub->args.xdata);
+ break;
+
+ case GF_FOP_SETACTIVELK:
+ stub->fn.setactivelk(stub->frame, stub->frame->this,
+ &stub->args.loc, &stub->args.locklist,
+ stub->args.xdata);
+ break;
+
+ case GF_FOP_PUT:
+ stub->fn.put(stub->frame, stub->frame->this, &stub->args.loc,
+ stub->args.mode, stub->args.umask, stub->args.flags,
+ stub->args.vector, stub->args.count, stub->args.offset,
+ stub->args.iobref, stub->args.xattr, stub->args.xdata);
+ break;
+
+ case GF_FOP_COPY_FILE_RANGE:
+ stub->fn.copy_file_range(
+ stub->frame, stub->frame->this, stub->args.fd,
+ stub->args.off_in, stub->args.fd_dst, stub->args.off_out,
+ stub->args.size, stub->args.flags, stub->args.xdata);
+ break;
default:
- gf_msg_callingfn ("call-stub", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ENTRY, "Invalid value of FOP"
- " (%d)", stub->fop);
- break;
- }
-out:
- return;
-}
-
-
-#define STUB_UNWIND(stb, fop, args ...) do { \
- if (stb->fn_cbk.fop) \
- stb->fn_cbk.fop (stb->frame, stb->frame->cookie, \
- stb->frame->this, stb->args_cbk.op_ret, \
- stb->args_cbk.op_errno, args); \
- else \
- STACK_UNWIND_STRICT (fop, stb->frame, stb->args_cbk.op_ret, \
- stb->args_cbk.op_errno, args); \
- } while (0)
-
+ gf_msg_callingfn("call-stub", GF_LOG_ERROR, EINVAL,
+ LG_MSG_INVALID_ENTRY,
+ "Invalid value of FOP"
+ " (%d)",
+ stub->fop);
+ break;
+ }
+out:
+ return;
+}
+
+#define STUB_UNWIND(stb, fop, args...) \
+ do { \
+ if (stb->fn_cbk.fop) \
+ stb->fn_cbk.fop(stb->frame, stb->frame->cookie, stb->frame->this, \
+ stb->args_cbk.op_ret, stb->args_cbk.op_errno, \
+ args); \
+ else \
+ STACK_UNWIND_STRICT(fop, stb->frame, stb->args_cbk.op_ret, \
+ stb->args_cbk.op_errno, args); \
+ } while (0)
static void
-call_resume_unwind (call_stub_t *stub)
+call_resume_unwind(call_stub_t *stub)
{
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- switch (stub->fop) {
+ switch (stub->fop) {
case GF_FOP_OPEN:
- STUB_UNWIND (stub, open, stub->args_cbk.fd,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, open, stub->args_cbk.fd, stub->args_cbk.xdata);
+ break;
case GF_FOP_CREATE:
- STUB_UNWIND (stub, create, stub->args_cbk.fd,
- stub->args_cbk.inode, &stub->args_cbk.stat,
- &stub->args_cbk.preparent,
- &stub->args_cbk.postparent,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, create, stub->args_cbk.fd, stub->args_cbk.inode,
+ &stub->args_cbk.stat, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_STAT:
- STUB_UNWIND (stub, stat, &stub->args_cbk.stat,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, stat, &stub->args_cbk.stat, stub->args_cbk.xdata);
+ break;
case GF_FOP_READLINK:
- STUB_UNWIND (stub, readlink, stub->args_cbk.buf,
- &stub->args_cbk.stat, stub->args.xdata);
- break;
+ STUB_UNWIND(stub, readlink, stub->args_cbk.buf,
+ &stub->args_cbk.stat, stub->args.xdata);
+ break;
case GF_FOP_MKNOD:
- STUB_UNWIND (stub, mknod, stub->args_cbk.inode,
- &stub->args_cbk.stat, &stub->args_cbk.preparent,
- &stub->args_cbk.postparent, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, mknod, stub->args_cbk.inode, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_MKDIR:
- STUB_UNWIND (stub, mkdir, stub->args_cbk.inode,
- &stub->args_cbk.stat, &stub->args_cbk.preparent,
- &stub->args_cbk.postparent, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, mkdir, stub->args_cbk.inode, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_UNLINK:
- STUB_UNWIND (stub, unlink, &stub->args_cbk.preparent,
- &stub->args_cbk.postparent, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, unlink, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_RMDIR:
- STUB_UNWIND (stub, rmdir, &stub->args_cbk.preparent,
- &stub->args_cbk.postparent, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, rmdir, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_SYMLINK:
- STUB_UNWIND (stub, symlink, stub->args_cbk.inode,
- &stub->args_cbk.stat, &stub->args_cbk.preparent,
- &stub->args_cbk.postparent, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, symlink, stub->args_cbk.inode,
+ &stub->args_cbk.stat, &stub->args_cbk.preparent,
+ &stub->args_cbk.postparent, stub->args_cbk.xdata);
+ break;
case GF_FOP_RENAME:
- STUB_UNWIND (stub, rename, &stub->args_cbk.stat,
- &stub->args_cbk.preparent,
- &stub->args_cbk.postparent,
- &stub->args_cbk.preparent2,
- &stub->args_cbk.postparent2,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, rename, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ &stub->args_cbk.preparent2, &stub->args_cbk.postparent2,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_LINK:
- STUB_UNWIND (stub, link, stub->args_cbk.inode,
- &stub->args_cbk.stat, &stub->args_cbk.preparent,
- &stub->args_cbk.postparent, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, link, stub->args_cbk.inode, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_TRUNCATE:
- STUB_UNWIND (stub, truncate, &stub->args_cbk.prestat,
- &stub->args_cbk.poststat, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, truncate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_READ:
- STUB_UNWIND (stub, readv, stub->args_cbk.vector,
- stub->args_cbk.count, &stub->args_cbk.stat,
- stub->args_cbk.iobref, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, readv, stub->args_cbk.vector,
+ stub->args_cbk.count, &stub->args_cbk.stat,
+ stub->args_cbk.iobref, stub->args_cbk.xdata);
+ break;
case GF_FOP_WRITE:
- STUB_UNWIND (stub, writev, &stub->args_cbk.prestat,
- &stub->args_cbk.poststat, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, writev, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_STATFS:
- STUB_UNWIND (stub, statfs, &stub->args_cbk.statvfs,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, statfs, &stub->args_cbk.statvfs,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FLUSH:
- STUB_UNWIND (stub, flush, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, flush, stub->args_cbk.xdata);
+ break;
case GF_FOP_FSYNC:
- STUB_UNWIND (stub, fsync, &stub->args_cbk.prestat,
- &stub->args_cbk.poststat, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, fsync, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_SETXATTR:
- STUB_UNWIND (stub, setxattr, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, setxattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_GETXATTR:
- STUB_UNWIND (stub, getxattr, stub->args_cbk.xattr,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, getxattr, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FSETXATTR:
- STUB_UNWIND (stub, fsetxattr, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, fsetxattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_FGETXATTR:
- STUB_UNWIND (stub, fgetxattr, stub->args_cbk.xattr,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, fgetxattr, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_REMOVEXATTR:
- STUB_UNWIND (stub, removexattr, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, removexattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_FREMOVEXATTR:
- STUB_UNWIND (stub, fremovexattr, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, fremovexattr, stub->args_cbk.xdata);
+ break;
case GF_FOP_OPENDIR:
- STUB_UNWIND (stub, opendir, stub->args_cbk.fd,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, opendir, stub->args_cbk.fd, stub->args_cbk.xdata);
+ break;
case GF_FOP_FSYNCDIR:
- STUB_UNWIND (stub, fsyncdir, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, fsyncdir, stub->args_cbk.xdata);
+ break;
case GF_FOP_ACCESS:
- STUB_UNWIND (stub, access, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, access, stub->args_cbk.xdata);
+ break;
case GF_FOP_FTRUNCATE:
- STUB_UNWIND (stub, ftruncate, &stub->args_cbk.prestat,
- &stub->args_cbk.poststat, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, ftruncate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_FSTAT:
- STUB_UNWIND (stub, fstat, &stub->args_cbk.stat,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, fstat, &stub->args_cbk.stat,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_LK:
- STUB_UNWIND (stub, lk, &stub->args_cbk.lock,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, lk, &stub->args_cbk.lock, stub->args_cbk.xdata);
+ break;
case GF_FOP_INODELK:
- STUB_UNWIND (stub, inodelk, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, inodelk, stub->args_cbk.xdata);
+ break;
case GF_FOP_FINODELK:
- STUB_UNWIND (stub, finodelk, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, finodelk, stub->args_cbk.xdata);
+ break;
case GF_FOP_ENTRYLK:
- STUB_UNWIND (stub, entrylk, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, entrylk, stub->args_cbk.xdata);
+ break;
case GF_FOP_FENTRYLK:
- STUB_UNWIND (stub, fentrylk, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, fentrylk, stub->args_cbk.xdata);
+ break;
case GF_FOP_LOOKUP:
- STUB_UNWIND (stub, lookup, stub->args_cbk.inode,
- &stub->args_cbk.stat, stub->args_cbk.xdata,
- &stub->args_cbk.postparent);
- break;
+ STUB_UNWIND(stub, lookup, stub->args_cbk.inode,
+ &stub->args_cbk.stat, stub->args_cbk.xdata,
+ &stub->args_cbk.postparent);
+ break;
case GF_FOP_RCHECKSUM:
- STUB_UNWIND (stub, rchecksum, stub->args_cbk.weak_checksum,
- stub->args_cbk.strong_checksum, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, rchecksum, stub->args_cbk.weak_checksum,
+ stub->args_cbk.strong_checksum, stub->args_cbk.xdata);
+ break;
case GF_FOP_READDIR:
- STUB_UNWIND (stub, readdir, &stub->args_cbk.entries,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, readdir, &stub->args_cbk.entries,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_READDIRP:
- STUB_UNWIND (stub, readdir, &stub->args_cbk.entries,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, readdir, &stub->args_cbk.entries,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_XATTROP:
- STUB_UNWIND (stub, xattrop, stub->args_cbk.xattr,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, xattrop, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_FXATTROP:
- STUB_UNWIND (stub, fxattrop, stub->args_cbk.xattr,
- stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, fxattrop, stub->args_cbk.xattr,
+ stub->args_cbk.xdata);
+ break;
case GF_FOP_SETATTR:
- STUB_UNWIND (stub, setattr, &stub->args_cbk.prestat,
- &stub->args_cbk.poststat, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, setattr, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_FSETATTR:
- STUB_UNWIND (stub, fsetattr, &stub->args_cbk.prestat,
- &stub->args_cbk.poststat, stub->args_cbk.xdata);
- break;
- case GF_FOP_FALLOCATE:
- STUB_UNWIND(stub, fallocate, &stub->args_cbk.prestat,
- &stub->args_cbk.poststat, stub->args_cbk.xdata);
- break;
- case GF_FOP_DISCARD:
- STUB_UNWIND(stub, discard, &stub->args_cbk.prestat,
- &stub->args_cbk.poststat, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, fsetattr, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_FALLOCATE:
+ STUB_UNWIND(stub, fallocate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_DISCARD:
+ STUB_UNWIND(stub, discard, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_ZEROFILL:
- STUB_UNWIND(stub, zerofill, &stub->args_cbk.prestat,
- &stub->args_cbk.poststat, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, zerofill, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
case GF_FOP_IPC:
- STUB_UNWIND (stub, ipc, stub->args_cbk.xdata);
- break;
+ STUB_UNWIND(stub, ipc, stub->args_cbk.xdata);
+ break;
+ case GF_FOP_SEEK:
+ STUB_UNWIND(stub, seek, stub->args_cbk.offset,
+ stub->args_cbk.xdata);
+ break;
+ case GF_FOP_LEASE:
+ STUB_UNWIND(stub, lease, &stub->args_cbk.lease,
+ stub->args_cbk.xdata);
+ break;
+
+ case GF_FOP_GETACTIVELK:
+ STUB_UNWIND(stub, getactivelk, &stub->args_cbk.locklist,
+ stub->args_cbk.xdata);
+ break;
+
+ case GF_FOP_SETACTIVELK:
+ STUB_UNWIND(stub, setactivelk, stub->args_cbk.xdata);
+ break;
+
+ case GF_FOP_PUT:
+ STUB_UNWIND(stub, put, stub->args_cbk.inode, &stub->args_cbk.stat,
+ &stub->args_cbk.preparent, &stub->args_cbk.postparent,
+ stub->args_cbk.xdata);
+ break;
+
+ case GF_FOP_COPY_FILE_RANGE:
+ STUB_UNWIND(stub, copy_file_range, &stub->args_cbk.stat,
+ &stub->args_cbk.prestat, &stub->args_cbk.poststat,
+ stub->args_cbk.xdata);
+ break;
default:
- gf_msg_callingfn ("call-stub", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ENTRY, "Invalid value of FOP"
- " (%d)", stub->fop);
- break;
- }
+ gf_msg_callingfn("call-stub", GF_LOG_ERROR, EINVAL,
+ LG_MSG_INVALID_ENTRY,
+ "Invalid value of FOP"
+ " (%d)",
+ stub->fop);
+ break;
+ }
out:
- return;
+ return;
}
-
static void
-call_stub_wipe_args (call_stub_t *stub)
+call_stub_wipe_args(call_stub_t *stub)
{
- loc_wipe (&stub->args.loc);
-
- loc_wipe (&stub->args.loc2);
+ args_wipe(&stub->args);
+}
- if (stub->args.fd)
- fd_unref (stub->args.fd);
+static void
+call_stub_wipe_args_cbk(call_stub_t *stub)
+{
+ args_cbk_wipe(&stub->args_cbk);
+}
- GF_FREE ((char *)stub->args.linkname);
+void
+call_stub_destroy(call_stub_t *stub)
+{
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- GF_FREE (stub->args.vector);
+ if (stub->wind)
+ call_stub_wipe_args(stub);
+ else
+ call_stub_wipe_args_cbk(stub);
- if (stub->args.iobref)
- iobref_unref (stub->args.iobref);
+ stub->stub_mem_pool = NULL;
- if (stub->args.xattr)
- dict_unref (stub->args.xattr);
+ mem_put(stub);
+out:
+ return;
+}
- GF_FREE ((char *)stub->args.name);
+void
+call_resume(call_stub_t *stub)
+{
+ xlator_t *old_THIS = NULL;
- GF_FREE ((char *)stub->args.volume);
+ errno = EINVAL;
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- if (stub->args.xdata)
- dict_unref (stub->args.xdata);
-}
+ list_del_init(&stub->list);
+ old_THIS = THIS;
+ THIS = stub->frame->this;
+ {
+ if (stub->wind)
+ call_resume_wind(stub);
+ else
+ call_resume_unwind(stub);
+ }
+ THIS = old_THIS;
-static void
-call_stub_wipe_args_cbk (call_stub_t *stub)
-{
- args_cbk_wipe (&stub->args_cbk);
+ call_stub_destroy(stub);
+out:
+ return;
}
-
void
-call_stub_destroy (call_stub_t *stub)
+call_unwind_error(call_stub_t *stub, int op_ret, int op_errno)
{
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ xlator_t *old_THIS = NULL;
- if (stub->wind)
- call_stub_wipe_args (stub);
- else
- call_stub_wipe_args_cbk (stub);
+ list_del_init(&stub->list);
- stub->stub_mem_pool = NULL;
+ old_THIS = THIS;
+ THIS = stub->frame->this;
+ {
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ call_resume_unwind(stub);
+ }
+ THIS = old_THIS;
- mem_put (stub);
-out:
- return;
-}
+ call_stub_destroy(stub);
+ return;
+}
void
-call_resume (call_stub_t *stub)
+call_unwind_error_keep_stub(call_stub_t *stub, int op_ret, int op_errno)
{
- xlator_t *old_THIS = NULL;
+ xlator_t *old_THIS = NULL;
- errno = EINVAL;
- GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+ list_del_init(&stub->list);
- list_del_init (&stub->list);
+ old_THIS = THIS;
+ THIS = stub->frame->this;
+ {
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+ call_resume_unwind(stub);
+ }
- old_THIS = THIS;
- THIS = stub->frame->this;
- {
- if (stub->wind)
- call_resume_wind (stub);
- else
- call_resume_unwind (stub);
- }
- THIS = old_THIS;
+ THIS = old_THIS;
- call_stub_destroy (stub);
-out:
- return;
+ return;
}
-
void
-call_unwind_error (call_stub_t *stub, int op_ret, int op_errno)
+call_resume_keep_stub(call_stub_t *stub)
{
- xlator_t *old_THIS = NULL;
+ xlator_t *old_THIS = NULL;
- list_del_init (&stub->list);
+ errno = EINVAL;
+ GF_VALIDATE_OR_GOTO("call-stub", stub, out);
- old_THIS = THIS;
- THIS = stub->frame->this;
- {
- stub->args_cbk.op_ret = op_ret;
- stub->args_cbk.op_errno = op_errno;
- call_resume_unwind (stub);
- }
- THIS = old_THIS;
+ list_del_init(&stub->list);
- call_stub_destroy (stub);
+ old_THIS = THIS;
+ THIS = stub->frame->this;
+ {
+ if (stub->wind)
+ call_resume_wind(stub);
+ else
+ call_resume_unwind(stub);
+ }
- return;
+ THIS = old_THIS;
+out:
+ return;
}
diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h
deleted file mode 100644
index af4a2f55aff..00000000000
--- a/libglusterfs/src/call-stub.h
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- 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 _CALL_STUB_H_
-#define _CALL_STUB_H_
-
-#include "xlator.h"
-#include "defaults.h"
-#include "stack.h"
-#include "list.h"
-
-typedef struct {
- struct list_head list;
- char wind;
- call_frame_t *frame;
- glusterfs_fop_t fop;
- struct mem_pool *stub_mem_pool; /* pointer to stub mempool in ctx_t */
-
- union {
- fop_lookup_t lookup;
- fop_stat_t stat;
- fop_fstat_t fstat;
- fop_truncate_t truncate;
- fop_ftruncate_t ftruncate;
- fop_access_t access;
- fop_readlink_t readlink;
- fop_mknod_t mknod;
- fop_mkdir_t mkdir;
- fop_unlink_t unlink;
- fop_rmdir_t rmdir;
- fop_symlink_t symlink;
- fop_rename_t rename;
- fop_link_t link;
- fop_create_t create;
- fop_open_t open;
- fop_readv_t readv;
- fop_writev_t writev;
- fop_flush_t flush;
- fop_fsync_t fsync;
- fop_opendir_t opendir;
- fop_fsyncdir_t fsyncdir;
- fop_statfs_t statfs;
- fop_setxattr_t setxattr;
- fop_getxattr_t getxattr;
- fop_fgetxattr_t fgetxattr;
- fop_fsetxattr_t fsetxattr;
- fop_removexattr_t removexattr;
- fop_fremovexattr_t fremovexattr;
- fop_lk_t lk;
- fop_inodelk_t inodelk;
- fop_finodelk_t finodelk;
- fop_entrylk_t entrylk;
- fop_fentrylk_t fentrylk;
- fop_readdir_t readdir;
- fop_readdirp_t readdirp;
- fop_rchecksum_t rchecksum;
- fop_xattrop_t xattrop;
- fop_fxattrop_t fxattrop;
- fop_setattr_t setattr;
- fop_fsetattr_t fsetattr;
- fop_fallocate_t fallocate;
- fop_discard_t discard;
- fop_zerofill_t zerofill;
- fop_ipc_t ipc;
- } fn;
-
- union {
- fop_lookup_cbk_t lookup;
- fop_stat_cbk_t stat;
- fop_fstat_cbk_t fstat;
- fop_truncate_cbk_t truncate;
- fop_ftruncate_cbk_t ftruncate;
- fop_access_cbk_t access;
- fop_readlink_cbk_t readlink;
- fop_mknod_cbk_t mknod;
- fop_mkdir_cbk_t mkdir;
- fop_unlink_cbk_t unlink;
- fop_rmdir_cbk_t rmdir;
- fop_symlink_cbk_t symlink;
- fop_rename_cbk_t rename;
- fop_link_cbk_t link;
- fop_create_cbk_t create;
- fop_open_cbk_t open;
- fop_readv_cbk_t readv;
- fop_writev_cbk_t writev;
- fop_flush_cbk_t flush;
- fop_fsync_cbk_t fsync;
- fop_opendir_cbk_t opendir;
- fop_fsyncdir_cbk_t fsyncdir;
- fop_statfs_cbk_t statfs;
- fop_setxattr_cbk_t setxattr;
- fop_getxattr_cbk_t getxattr;
- fop_fgetxattr_cbk_t fgetxattr;
- fop_fsetxattr_cbk_t fsetxattr;
- fop_removexattr_cbk_t removexattr;
- fop_fremovexattr_cbk_t fremovexattr;
- fop_lk_cbk_t lk;
- fop_inodelk_cbk_t inodelk;
- fop_finodelk_cbk_t finodelk;
- fop_entrylk_cbk_t entrylk;
- fop_fentrylk_cbk_t fentrylk;
- fop_readdir_cbk_t readdir;
- fop_readdirp_cbk_t readdirp;
- fop_rchecksum_cbk_t rchecksum;
- fop_xattrop_cbk_t xattrop;
- fop_fxattrop_cbk_t fxattrop;
- fop_setattr_cbk_t setattr;
- fop_fsetattr_cbk_t fsetattr;
- fop_fallocate_cbk_t fallocate;
- fop_discard_cbk_t discard;
- fop_zerofill_cbk_t zerofill;
- fop_ipc_cbk_t ipc;
- } fn_cbk;
-
- struct {
- loc_t loc; // @old in rename(), link()
- loc_t loc2; // @new in rename(), link()
- fd_t *fd;
- off_t offset;
- int mask;
- size_t size;
- mode_t mode;
- dev_t rdev;
- mode_t umask;
- int xflag;
- int flags;
- const char *linkname;
- struct iovec *vector;
- int count;
- struct iobref *iobref;
- int datasync;
- dict_t *xattr;
- const char *name;
- int cmd;
- struct gf_flock lock;
- const char *volume;
- entrylk_cmd entrylkcmd;
- entrylk_type entrylktype;
- gf_xattrop_flags_t optype;
- int valid;
- struct iatt stat;
- dict_t *xdata;
- } args;
-
- default_args_cbk_t args_cbk;
-} call_stub_t;
-
-
-call_stub_t *
-fop_lookup_stub (call_frame_t *frame,
- fop_lookup_t fn,
- loc_t *loc,
- dict_t *xdata);
-
-call_stub_t *
-fop_lookup_cbk_stub (call_frame_t *frame,
- fop_lookup_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- dict_t *xdata,
- struct iatt *postparent);
-call_stub_t *
-fop_stat_stub (call_frame_t *frame,
- fop_stat_t fn,
- 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, dict_t *xdata);
-call_stub_t *
-fop_fstat_stub (call_frame_t *frame,
- fop_fstat_t fn,
- 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, dict_t *xdata);
-
-call_stub_t *
-fop_truncate_stub (call_frame_t *frame,
- fop_truncate_t fn,
- loc_t *loc,
- off_t off, dict_t *xdata);
-
-call_stub_t *
-fop_truncate_cbk_stub (call_frame_t *frame,
- fop_truncate_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- 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, dict_t *xdata);
-
-call_stub_t *
-fop_ftruncate_cbk_stub (call_frame_t *frame,
- fop_ftruncate_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- 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, 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, dict_t *xdata);
-
-call_stub_t *
-fop_readlink_stub (call_frame_t *frame,
- fop_readlink_t fn,
- loc_t *loc,
- size_t size, dict_t *xdata);
-
-call_stub_t *
-fop_readlink_cbk_stub (call_frame_t *frame,
- fop_readlink_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- const char *path,
- 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, mode_t umask, dict_t *xdata);
-
-call_stub_t *
-fop_mknod_cbk_stub (call_frame_t *frame,
- fop_mknod_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- 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,
- mode_t umask, dict_t *xdata);
-
-call_stub_t *
-fop_mkdir_cbk_stub (call_frame_t *frame,
- fop_mkdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata);
-
-call_stub_t *
-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,
- fop_unlink_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *preparent,
- 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, dict_t *xdata);
-
-call_stub_t *
-fop_rmdir_cbk_stub (call_frame_t *frame,
- fop_rmdir_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *preparent,
- 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, mode_t umask, dict_t *xdata);
-
-call_stub_t *
-fop_symlink_cbk_stub (call_frame_t *frame,
- fop_symlink_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- 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, dict_t *xdata);
-
-call_stub_t *
-fop_rename_cbk_stub (call_frame_t *frame,
- fop_rename_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *buf,
- struct iatt *preoldparent,
- struct iatt *postoldparent,
- struct iatt *prenewparent,
- 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, dict_t *xdata);
-
-call_stub_t *
-fop_link_cbk_stub (call_frame_t *frame,
- fop_link_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- struct iatt *preparent,
- 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,
- mode_t umask, fd_t *fd, dict_t *xdata);
-
-call_stub_t *
-fop_create_cbk_stub (call_frame_t *frame,
- fop_create_cbk_t fn,
- 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);
-
-call_stub_t *
-fop_open_stub (call_frame_t *frame,
- fop_open_t fn,
- loc_t *loc,
- int32_t flags,
- fd_t *fd,
- 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, 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, uint32_t flags, dict_t *xdata);
-
-call_stub_t *
-fop_readv_cbk_stub (call_frame_t *frame,
- fop_readv_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iovec *vector,
- int32_t count,
- struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata);
-
-call_stub_t *
-fop_writev_stub (call_frame_t *frame,
- fop_writev_t fn,
- fd_t *fd,
- struct iovec *vector,
- int32_t count,
- off_t off, uint32_t flags,
- struct iobref *iobref, dict_t *xdata);
-
-call_stub_t *
-fop_writev_cbk_stub (call_frame_t *frame,
- fop_writev_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata);
-
-call_stub_t *
-fop_flush_stub (call_frame_t *frame,
- fop_flush_t fn,
- 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, dict_t *xdata);
-
-call_stub_t *
-fop_fsync_stub (call_frame_t *frame,
- fop_fsync_t fn,
- fd_t *fd,
- int32_t datasync, dict_t *xdata);
-
-call_stub_t *
-fop_fsync_cbk_stub (call_frame_t *frame,
- fop_fsync_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *prebuf,
- 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, 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, dict_t *xdata);
-
-call_stub_t *
-fop_fsyncdir_stub (call_frame_t *frame,
- fop_fsyncdir_t fn,
- fd_t *fd,
- 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, dict_t *xdata);
-
-call_stub_t *
-fop_statfs_stub (call_frame_t *frame,
- fop_statfs_t fn,
- 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, 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, 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, dict_t *xdata);
-
-call_stub_t *
-fop_getxattr_stub (call_frame_t *frame,
- fop_getxattr_t fn,
- loc_t *loc,
- 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 *xdata);
-
-call_stub_t *
-fop_fsetxattr_stub (call_frame_t *frame,
- fop_fsetxattr_t fn,
- fd_t *fd,
- dict_t *dict,
- 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, dict_t *xdata);
-
-call_stub_t *
-fop_fgetxattr_stub (call_frame_t *frame,
- fop_fgetxattr_t fn,
- fd_t *fd,
- 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 *xdata);
-
-call_stub_t *
-fop_removexattr_stub (call_frame_t *frame,
- fop_removexattr_t fn,
- loc_t *loc,
- 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, dict_t *xdata);
-
-call_stub_t *
-fop_readdirp_stub (call_frame_t *frame,
- fop_readdirp_t fn,
- fd_t *fd,
- size_t size,
- 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, 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, 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, dict_t *xdata);
-
-call_stub_t *
-fop_rchecksum_cbk_stub (call_frame_t *frame,
- fop_rchecksum_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- uint32_t weak_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 *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, 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 *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, 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, dict_t *xdata);
-
-call_stub_t *
-fop_setattr_cbk_stub (call_frame_t *frame,
- fop_setattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *statpre,
- 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, dict_t *xdata);
-
-call_stub_t *
-fop_fsetattr_cbk_stub (call_frame_t *frame,
- fop_setattr_cbk_t fn,
- int32_t op_ret,
- int32_t op_errno,
- struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata);
-
-call_stub_t *
-fop_fallocate_stub(call_frame_t *frame,
- fop_fallocate_t fn,
- fd_t *fd,
- int32_t mode, off_t offset,
- size_t len, dict_t *xdata);
-
-call_stub_t *
-fop_fallocate_cbk_stub(call_frame_t *frame,
- fop_fallocate_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata);
-
-call_stub_t *
-fop_discard_stub(call_frame_t *frame,
- fop_discard_t fn,
- fd_t *fd,
- off_t offset,
- size_t len, dict_t *xdata);
-
-call_stub_t *
-fop_discard_cbk_stub(call_frame_t *frame,
- fop_discard_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata);
-
-call_stub_t *
-fop_zerofill_stub(call_frame_t *frame,
- fop_zerofill_t fn,
- fd_t *fd,
- off_t offset,
- off_t len, dict_t *xdata);
-
-call_stub_t *
-fop_zerofill_cbk_stub(call_frame_t *frame,
- fop_zerofill_cbk_t fn,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata);
-
-call_stub_t *
-fop_ipc_stub (call_frame_t *frame, fop_ipc_t fn, int32_t op, dict_t *xdata);
-
-call_stub_t *
-fop_ipc_cbk_stub (call_frame_t *frame, fop_ipc_cbk_t fn,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-
-void call_resume (call_stub_t *stub);
-void call_stub_destroy (call_stub_t *stub);
-void call_unwind_error (call_stub_t *stub, int op_ret, int op_errno);
-#endif
diff --git a/libglusterfs/src/changelog.h b/libglusterfs/src/changelog.h
index 6f86e5a54cd..a09d9f25287 100644
--- a/libglusterfs/src/changelog.h
+++ b/libglusterfs/src/changelog.h
@@ -16,101 +16,100 @@ struct gf_brick_spec;
/**
* Max bit shiter for event selection
*/
-#define CHANGELOG_EV_SELECTION_RANGE 5
-
-#define CHANGELOG_OP_TYPE_JOURNAL (1<<0)
-#define CHANGELOG_OP_TYPE_OPEN (1<<1)
-#define CHANGELOG_OP_TYPE_CREATE (1<<2)
-#define CHANGELOG_OP_TYPE_RELEASE (1<<3)
-#define CHANGELOG_OP_TYPE_BR_RELEASE (1<<4) /* logical release (last close()),
- sent by bitrot stub */
-#define CHANGELOG_OP_TYPE_MAX (1<<CHANGELOG_EV_SELECTION_RANGE)
+#define CHANGELOG_EV_SELECTION_RANGE 5
+#define CHANGELOG_OP_TYPE_JOURNAL (1 << 0)
+#define CHANGELOG_OP_TYPE_OPEN (1 << 1)
+#define CHANGELOG_OP_TYPE_CREATE (1 << 2)
+#define CHANGELOG_OP_TYPE_RELEASE (1 << 3)
+#define CHANGELOG_OP_TYPE_BR_RELEASE \
+ (1 << 4) /* logical release (last close()), \
+ sent by bitrot stub */
+#define CHANGELOG_OP_TYPE_MAX (1 << CHANGELOG_EV_SELECTION_RANGE)
struct ev_open {
- unsigned char gfid[16];
- int32_t flags;
+ unsigned char gfid[16];
+ int32_t flags;
};
struct ev_creat {
- unsigned char gfid[16];
- int32_t flags;
+ unsigned char gfid[16];
+ int32_t flags;
};
struct ev_release {
- unsigned char gfid[16];
+ unsigned char gfid[16];
};
struct ev_release_br {
- unsigned long version;
- unsigned char gfid[16];
- int32_t sign_info;
+ unsigned long version;
+ unsigned char gfid[16];
+ int32_t sign_info;
};
struct ev_changelog {
- char path[PATH_MAX];
+ char path[PATH_MAX];
};
typedef struct changelog_event {
- unsigned int ev_type;
-
- union {
- struct ev_open open;
- struct ev_creat create;
- struct ev_release release;
- struct ev_changelog journal;
- struct ev_release_br releasebr;
- } u;
+ unsigned int ev_type;
+
+ union {
+ struct ev_open open;
+ struct ev_creat create;
+ struct ev_release release;
+ struct ev_changelog journal;
+ struct ev_release_br releasebr;
+ } u;
} changelog_event_t;
-#define CHANGELOG_EV_SIZE (sizeof (changelog_event_t))
+#define CHANGELOG_EV_SIZE (sizeof(changelog_event_t))
/**
* event callback, connected & disconnection defs
*/
-typedef void (CALLBACK) (void *, char *,
- void *, changelog_event_t *);
-typedef void *(INIT) (void *, struct gf_brick_spec *);
-typedef void (FINI) (void *, char *, void *);
-typedef void (CONNECT) (void *, char *, void *);
-typedef void (DISCONNECT) (void *, char *, void *);
+typedef void(CALLBACK)(void *, char *, void *, changelog_event_t *);
+typedef void *(INIT)(void *, struct gf_brick_spec *);
+typedef void(FINI)(void *, char *, void *);
+typedef void(CONNECT)(void *, char *, void *);
+typedef void(DISCONNECT)(void *, char *, void *);
struct gf_brick_spec {
- char *brick_path;
- unsigned int filter;
+ char *brick_path;
+ unsigned int filter;
- INIT *init;
- FINI *fini;
- CALLBACK *callback;
- CONNECT *connected;
- DISCONNECT *disconnected;
+ INIT *init;
+ FINI *fini;
+ CALLBACK *callback;
+ CONNECT *connected;
+ DISCONNECT *disconnected;
- void *ptr;
+ void *ptr;
};
/* API set */
int
-gf_changelog_register (char *brick_path, char *scratch_dir,
- char *log_file, int log_levl, int max_reconnects);
+gf_changelog_register(char *brick_path, char *scratch_dir, char *log_file,
+ int log_levl, int max_reconnects);
ssize_t
-gf_changelog_scan ();
+gf_changelog_scan();
int
-gf_changelog_start_fresh ();
+gf_changelog_start_fresh();
ssize_t
-gf_changelog_next_change (char *bufptr, size_t maxlen);
+gf_changelog_next_change(char *bufptr, size_t maxlen);
int
-gf_changelog_done (char *file);
+gf_changelog_done(char *file);
/* newer flexible API */
int
-gf_changelog_init (void *xl);
+gf_changelog_init(void *xl);
int
-gf_changelog_register_generic (struct gf_brick_spec *bricks, int count,
- int ordered, char *logfile, int lvl, void *xl);
+gf_changelog_register_generic(struct gf_brick_spec *bricks, int count,
+ int ordered, char *logfile, int lvl, void *xl);
#endif
diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c
index 5fac1330094..acdaed04ae2 100644
--- a/libglusterfs/src/checksum.c
+++ b/libglusterfs/src/checksum.c
@@ -9,8 +9,10 @@
*/
#include <openssl/md5.h>
+#include <openssl/sha.h>
#include <zlib.h>
#include <stdint.h>
+#include <string.h>
/*
* The "weak" checksum required for the rsync algorithm.
@@ -20,17 +22,23 @@
* data. Thus int32_t and uint32_t are sufficient
*/
uint32_t
-gf_rsync_weak_checksum (unsigned char *buf, size_t len)
+gf_rsync_weak_checksum(unsigned char *buf, size_t len)
{
- return adler32 (0, buf, len);
+ return adler32(0, buf, len);
}
-
/*
* The "strong" checksum required for the rsync algorithm.
*/
void
-gf_rsync_strong_checksum (unsigned char *data, size_t len, unsigned char *md5)
+gf_rsync_strong_checksum(unsigned char *data, size_t len,
+ unsigned char *sha256_md)
+{
+ SHA256((const unsigned char *)data, len, sha256_md);
+}
+
+void
+gf_rsync_md5_checksum(unsigned char *data, size_t len, unsigned char *md5)
{
- MD5 (data, len, md5);
+ MD5(data, len, md5);
}
diff --git a/libglusterfs/src/circ-buff.c b/libglusterfs/src/circ-buff.c
index 6259282a917..913115c7be1 100644
--- a/libglusterfs/src/circ-buff.c
+++ b/libglusterfs/src/circ-buff.c
@@ -8,194 +8,186 @@
cases as published by the Free Software Foundation.
*/
-#include "circ-buff.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/circ-buff.h"
+#include "glusterfs/libglusterfs-messages.h"
void
-cb_destroy_data (circular_buffer_t *cb,
- void (*destroy_buffer_data) (void *data))
+cb_destroy_data(circular_buffer_t *cb, void (*destroy_buffer_data)(void *data))
{
- if (destroy_buffer_data)
- destroy_buffer_data (cb->data);
- GF_FREE (cb->data);
- return;
+ if (destroy_buffer_data)
+ destroy_buffer_data(cb->data);
+ GF_FREE(cb->data);
+ return;
}
-
/* hold lock while calling this function */
int
-__cb_add_entry_buffer (buffer_t *buffer, void *item)
+__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_msg ("circ-buff", GF_LOG_WARNING, 0, LG_MSG_BUFFER_ERROR,
- "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) {
- cb_destroy_data (ptr,
- buffer->destroy_buffer_data);
- ptr->data = NULL;
- GF_FREE (ptr);
- }
- buffer->cb[buffer->w_index] = NULL;
- ptr = NULL;
- }
+ 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_msg("circ-buff", GF_LOG_WARNING, 0, LG_MSG_BUFFER_ERROR,
+ "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) {
+ cb_destroy_data(ptr, buffer->destroy_buffer_data);
+ ptr->data = NULL;
+ GF_FREE(ptr);
}
-
- 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_msg_callingfn ("circ-buff", GF_LOG_WARNING, 0,
- LG_MSG_GETTIMEOFDAY_FAILED,
- "getting time of the day failed");
- buffer->w_index++;
- buffer->w_index %= buffer->size_buffer;
- //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;
+ 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_msg_callingfn("circ-buff", GF_LOG_WARNING, 0,
+ LG_MSG_GETTIMEOFDAY_FAILED,
+ "getting time of the day failed");
+ buffer->w_index++;
+ buffer->w_index %= buffer->size_buffer;
+ // 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)
+cb_add_entry_buffer(buffer_t *buffer, void *item)
{
- int write_index = -1;
+ int write_index = -1;
- pthread_mutex_lock (&buffer->lock);
- {
- write_index = __cb_add_entry_buffer (buffer, item);
- }
- pthread_mutex_unlock (&buffer->lock);
+ pthread_mutex_lock(&buffer->lock);
+ {
+ write_index = __cb_add_entry_buffer(buffer, item);
+ }
+ pthread_mutex_unlock(&buffer->lock);
- return write_index;
+ return write_index;
}
void
-cb_buffer_show (buffer_t *buffer)
+cb_buffer_show(buffer_t *buffer)
{
- pthread_mutex_lock (&buffer->lock);
- {
- gf_msg_debug ("circ-buff", 0, "w_index: %d, size: %"
- GF_PRI_SIZET" used_buffer: %d", buffer->w_index,
- buffer->size_buffer, buffer->used_len);
- }
- pthread_mutex_unlock (&buffer->lock);
+ pthread_mutex_lock(&buffer->lock);
+ {
+ gf_msg_debug("circ-buff", 0,
+ "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))
+cb_buffer_dump(buffer_t *buffer, void *data,
+ int(fn)(circular_buffer_t *buffer, void *data))
{
- int index = 0;
- circular_buffer_t *entry = NULL;
- int entries = 0;
- int ul = 0;
- int w_ind = 0;
- int size_buff = 0;
- int i = 0;
-
- ul = buffer->used_len;
- w_ind = buffer->w_index;
- size_buff = buffer->size_buffer;
-
- pthread_mutex_lock (&buffer->lock);
- {
- if (buffer->use_once == _gf_false) {
- index = (size_buff + (w_ind - ul))%size_buff;
- for (entries = 0; entries < buffer->used_len;
- entries++) {
- entry = buffer->cb[index];
- if (entry)
- fn (entry, data);
- else
- gf_msg_callingfn ("circ-buff",
- GF_LOG_WARNING, 0,
- LG_MSG_NULL_PTR,
- "Null entry in "
- "circular buffer at "
- "index %d.", index);
-
- index++;
- index %= buffer->size_buffer;
- }
- } else {
- for (i = 0; i < buffer->used_len ; i++) {
- entry = buffer->cb[i];
- fn (entry, data);
- }
- }
+ int index = 0;
+ circular_buffer_t *entry = NULL;
+ int entries = 0;
+ int ul = 0;
+ int w_ind = 0;
+ int size_buff = 0;
+ int i = 0;
+
+ ul = buffer->used_len;
+ w_ind = buffer->w_index;
+ size_buff = buffer->size_buffer;
+
+ pthread_mutex_lock(&buffer->lock);
+ {
+ if (buffer->use_once == _gf_false) {
+ index = (size_buff + (w_ind - ul)) % size_buff;
+ for (entries = 0; entries < buffer->used_len; entries++) {
+ entry = buffer->cb[index];
+ if (entry)
+ fn(entry, data);
+ else
+ gf_msg_callingfn("circ-buff", GF_LOG_WARNING, 0,
+ LG_MSG_NULL_PTR,
+ "Null entry in "
+ "circular buffer at "
+ "index %d.",
+ index);
+
+ index++;
+ index %= buffer->size_buffer;
+ }
+ } else {
+ for (i = 0; i < buffer->used_len; i++) {
+ entry = buffer->cb[i];
+ fn(entry, data);
+ }
}
- pthread_mutex_unlock (&buffer->lock);
+ }
+ pthread_mutex_unlock(&buffer->lock);
}
buffer_t *
-cb_buffer_new (size_t buffer_size, gf_boolean_t use_once,
- void (*destroy_buffer_data) (void *data))
+cb_buffer_new(size_t buffer_size, gf_boolean_t use_once,
+ void (*destroy_buffer_data)(void *data))
{
- buffer_t *buffer = NULL;
-
- buffer = GF_CALLOC (1, sizeof (*buffer), gf_common_mt_buffer_t);
- if (!buffer) {
- goto out;
- }
-
- buffer->cb = GF_CALLOC (buffer_size,
- sizeof (circular_buffer_t *),
- gf_common_mt_circular_buffer_t);
- if (!buffer->cb) {
- 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;
- buffer->destroy_buffer_data = destroy_buffer_data;
- pthread_mutex_init (&buffer->lock, NULL);
+ buffer_t *buffer = NULL;
+
+ buffer = GF_CALLOC(1, sizeof(*buffer), gf_common_mt_buffer_t);
+ if (!buffer) {
+ goto out;
+ }
+
+ buffer->cb = GF_CALLOC(buffer_size, sizeof(circular_buffer_t *),
+ gf_common_mt_circular_buffer_t);
+ if (!buffer->cb) {
+ 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;
+ buffer->destroy_buffer_data = destroy_buffer_data;
+ pthread_mutex_init(&buffer->lock, NULL);
out:
- return buffer;
+ return buffer;
}
void
-cb_buffer_destroy (buffer_t *buffer)
+cb_buffer_destroy(buffer_t *buffer)
{
- int i = 0;
- circular_buffer_t *ptr = NULL;
- if (buffer) {
- if (buffer->cb) {
- for (i = 0; i < buffer->used_len ; i++) {
- ptr = buffer->cb[i];
- if (ptr->data) {
- cb_destroy_data (ptr,
- buffer->destroy_buffer_data);
- ptr->data = NULL;
- GF_FREE (ptr);
- }
- }
- GF_FREE (buffer->cb);
+ int i = 0;
+ circular_buffer_t *ptr = NULL;
+ if (buffer) {
+ if (buffer->cb) {
+ for (i = 0; i < buffer->used_len; i++) {
+ ptr = buffer->cb[i];
+ if (ptr->data) {
+ cb_destroy_data(ptr, buffer->destroy_buffer_data);
+ ptr->data = NULL;
+ GF_FREE(ptr);
}
- pthread_mutex_destroy (&buffer->lock);
- GF_FREE (buffer);
+ }
+ 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
deleted file mode 100644
index e3459f5e3d0..00000000000
--- a/libglusterfs/src/circ-buff.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- 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;
- void (*destroy_buffer_data) (void *data);
- 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 (*destroy_data) (void *data));
-
-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/client_t.c b/libglusterfs/src/client_t.c
index 1c291518564..9d377c3c2e1 100644
--- a/libglusterfs/src/client_t.c
+++ b/libglusterfs/src/client_t.c
@@ -8,620 +8,541 @@
cases as published by the Free Software Foundation.
*/
-#include "glusterfs.h"
-#include "dict.h"
-#include "statedump.h"
-#include "client_t.h"
-#include "list.h"
-#include "rpcsvc.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/dict.h"
+#include "glusterfs/statedump.h"
+#include "glusterfs/client_t.h"
+#include "glusterfs/list.h"
+#include "glusterfs/libglusterfs-messages.h"
static int
-gf_client_chain_client_entries (cliententry_t *entries, uint32_t startidx,
- uint32_t endcount)
+gf_client_chain_client_entries(cliententry_t *entries, uint32_t startidx,
+ uint32_t endcount)
{
- uint32_t i = 0;
+ uint32_t i = 0;
- if (!entries) {
- gf_msg_callingfn ("client_t", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!entries");
- return -1;
- }
+ if (!entries) {
+ gf_msg_callingfn("client_t", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!entries");
+ return -1;
+ }
- /* Chain only till the second to last entry because we want to
- * ensure that the last entry has GF_CLIENTTABLE_END.
- */
- for (i = startidx; i < (endcount - 1); i++)
- entries[i].next_free = i + 1;
+ /* Chain only till the second to last entry because we want to
+ * ensure that the last entry has GF_CLIENTTABLE_END.
+ */
+ for (i = startidx; i < (endcount - 1); i++)
+ entries[i].next_free = i + 1;
- /* i has already been incremented up to the last entry. */
- entries[i].next_free = GF_CLIENTTABLE_END;
+ /* i has already been incremented up to the last entry. */
+ entries[i].next_free = GF_CLIENTTABLE_END;
- return 0;
+ return 0;
}
-
static int
-gf_client_clienttable_expand (clienttable_t *clienttable, uint32_t nr)
+gf_client_clienttable_expand(clienttable_t *clienttable, uint32_t nr)
{
- cliententry_t *oldclients = NULL;
- uint32_t oldmax_clients = -1;
- int ret = -1;
-
- if (clienttable == NULL || nr <= clienttable->max_clients) {
- gf_msg_callingfn ("client_t", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- ret = EINVAL;
- goto out;
- }
-
- oldclients = clienttable->cliententries;
- oldmax_clients = clienttable->max_clients;
-
- clienttable->cliententries = GF_CALLOC (nr, sizeof (cliententry_t),
- gf_common_mt_cliententry_t);
- if (!clienttable->cliententries) {
- clienttable->cliententries = oldclients;
- ret = 0;
- goto out;
- }
- clienttable->max_clients = nr;
-
- if (oldclients) {
- uint32_t cpy = oldmax_clients * sizeof (cliententry_t);
- memcpy (clienttable->cliententries, oldclients, cpy);
- }
-
- gf_client_chain_client_entries (clienttable->cliententries,
- oldmax_clients,
- clienttable->max_clients);
-
- /* Now that expansion is done, we must update the client list
- * head pointer so that the client allocation functions can continue
- * using the expanded table.
- */
- clienttable->first_free = oldmax_clients;
- GF_FREE (oldclients);
+ cliententry_t *oldclients = NULL;
+ uint32_t oldmax_clients = -1;
+ int ret = -1;
+
+ if (clienttable == NULL || nr <= clienttable->max_clients) {
+ gf_msg_callingfn("client_t", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ ret = EINVAL;
+ goto out;
+ }
+
+ oldclients = clienttable->cliententries;
+ oldmax_clients = clienttable->max_clients;
+
+ clienttable->cliententries = GF_CALLOC(nr, sizeof(cliententry_t),
+ gf_common_mt_cliententry_t);
+ if (!clienttable->cliententries) {
+ clienttable->cliententries = oldclients;
ret = 0;
+ goto out;
+ }
+ clienttable->max_clients = nr;
+
+ if (oldclients) {
+ uint32_t cpy = oldmax_clients * sizeof(cliententry_t);
+ memcpy(clienttable->cliententries, oldclients, cpy);
+ }
+
+ gf_client_chain_client_entries(clienttable->cliententries, oldmax_clients,
+ clienttable->max_clients);
+
+ /* Now that expansion is done, we must update the client list
+ * head pointer so that the client allocation functions can continue
+ * using the expanded table.
+ */
+ clienttable->first_free = oldmax_clients;
+ GF_FREE(oldclients);
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
clienttable_t *
-gf_clienttable_alloc (void)
-{
- clienttable_t *clienttable = NULL;
- int result = 0;
-
- clienttable =
- GF_CALLOC (1, sizeof (clienttable_t), gf_common_mt_clienttable_t);
- if (!clienttable)
- return NULL;
-
- LOCK_INIT (&clienttable->lock);
-
- result = gf_client_clienttable_expand (clienttable,
- GF_CLIENTTABLE_INITIAL_SIZE);
- if (result != 0) {
- gf_msg ("client_t", GF_LOG_ERROR, 0,
- LG_MSG_EXPAND_CLIENT_TABLE_FAILED,
- "gf_client_clienttable_expand failed");
- GF_FREE (clienttable);
- return NULL;
- }
-
- return clienttable;
-}
-
-
-void
-gf_client_clienttable_destroy (clienttable_t *clienttable)
+gf_clienttable_alloc(void)
{
- client_t *client = NULL;
- cliententry_t *cliententries = NULL;
- uint32_t client_count = 0;
- int32_t i = 0;
-
- if (!clienttable) {
- gf_msg_callingfn ("client_t", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!clienttable");
- return;
- }
-
- LOCK (&clienttable->lock);
- {
- client_count = clienttable->max_clients;
- clienttable->max_clients = 0;
- cliententries = clienttable->cliententries;
- clienttable->cliententries = NULL;
- }
- UNLOCK (&clienttable->lock);
-
- if (cliententries != NULL) {
- for (i = 0; i < client_count; i++) {
- client = cliententries[i].client;
- if (client != NULL) {
- gf_client_unref (client);
- }
- }
-
- GF_FREE (cliententries);
- LOCK_DESTROY (&clienttable->lock);
- GF_FREE (clienttable);
- }
+ clienttable_t *clienttable = NULL;
+ int result = 0;
+
+ clienttable = GF_CALLOC(1, sizeof(clienttable_t),
+ gf_common_mt_clienttable_t);
+ if (!clienttable)
+ return NULL;
+
+ LOCK_INIT(&clienttable->lock);
+
+ result = gf_client_clienttable_expand(clienttable,
+ GF_CLIENTTABLE_INITIAL_SIZE);
+ if (result != 0) {
+ gf_msg("client_t", GF_LOG_ERROR, 0, LG_MSG_EXPAND_CLIENT_TABLE_FAILED,
+ "gf_client_clienttable_expand failed");
+ GF_FREE(clienttable);
+ return NULL;
+ }
+
+ return clienttable;
}
-
/*
* Increments ref.bind if the client is already present or creates a new
* client with ref.bind = 1,ref.count = 1 it signifies that
* as long as ref.bind is > 0 client should be alive.
*/
client_t *
-gf_client_get (xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid)
+gf_client_get(xlator_t *this, client_auth_data_t *cred, char *client_uid,
+ char *subdir_mount)
{
- client_t *client = NULL;
- cliententry_t *cliententry = NULL;
- clienttable_t *clienttable = NULL;
- unsigned int i = 0;
-
- if (this == NULL || client_uid == NULL) {
- gf_msg_callingfn ("client_t", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- errno = EINVAL;
- return NULL;
- }
-
- clienttable = this->ctx->clienttable;
-
- LOCK (&clienttable->lock);
- {
- for (; i < clienttable->max_clients; i++) {
- client = clienttable->cliententries[i].client;
- if (client == NULL)
- continue;
- /*
- * look for matching client_uid, _and_
- * if auth was used, matching auth flavour and data
- */
- if (strcmp (client_uid, client->client_uid) == 0 &&
- (cred->flavour != AUTH_NONE &&
- (cred->flavour == client->auth.flavour &&
- (size_t) cred->datalen == client->auth.len &&
- memcmp (cred->authdata,
- client->auth.data,
- client->auth.len) == 0))) {
- INCREMENT_ATOMIC (client->ref.lock,
- client->ref.bind);
- goto unlock;
- }
- }
-
- client = GF_CALLOC (1, sizeof(client_t), gf_common_mt_client_t);
- if (client == NULL) {
- errno = ENOMEM;
- goto unlock;
- }
-
- client->this = this;
-
- LOCK_INIT (&client->scratch_ctx.lock);
- LOCK_INIT (&client->ref.lock);
-
- client->client_uid = gf_strdup (client_uid);
- if (client->client_uid == NULL) {
- GF_FREE (client);
- client = NULL;
- errno = ENOMEM;
- goto unlock;
- }
- client->scratch_ctx.count = GF_CLIENTCTX_INITIAL_SIZE;
- client->scratch_ctx.ctx =
- GF_CALLOC (GF_CLIENTCTX_INITIAL_SIZE,
- sizeof (struct client_ctx),
- gf_common_mt_client_ctx);
- if (client->scratch_ctx.ctx == NULL) {
- GF_FREE (client->client_uid);
- GF_FREE (client);
- client = NULL;
- errno = ENOMEM;
- goto unlock;
- }
-
- /* no need to do these atomically here */
- client->ref.bind = client->ref.count = 1;
-
- client->auth.flavour = cred->flavour;
- if (cred->flavour != AUTH_NONE) {
- client->auth.data =
- GF_CALLOC (1, cred->datalen,
- gf_common_mt_client_t);
- if (client->auth.data == NULL) {
- GF_FREE (client->scratch_ctx.ctx);
- GF_FREE (client->client_uid);
- GF_FREE (client);
- client = NULL;
- errno = ENOMEM;
- goto unlock;
- }
- memcpy (client->auth.data, cred->authdata,
- cred->datalen);
- client->auth.len = cred->datalen;
- }
-
- client->tbl_index = clienttable->first_free;
- cliententry = &clienttable->cliententries[clienttable->first_free];
- if (cliententry->next_free == GF_CLIENTTABLE_END) {
- int result =
- gf_client_clienttable_expand (clienttable,
- clienttable->max_clients +
- GF_CLIENTTABLE_INITIAL_SIZE);
- if (result != 0) {
- GF_FREE (client->scratch_ctx.ctx);
- GF_FREE (client->client_uid);
- GF_FREE (client);
- client = NULL;
- errno = result;
- goto unlock;
- }
- cliententry->next_free = clienttable->first_free;
- }
- cliententry->client = client;
- clienttable->first_free = cliententry->next_free;
- cliententry->next_free = GF_CLIENTENTRY_ALLOCATED;
- }
+ client_t *client = NULL;
+ cliententry_t *cliententry = NULL;
+ clienttable_t *clienttable = NULL;
+ unsigned int i = 0;
+
+ if (this == NULL || client_uid == NULL) {
+ gf_msg_callingfn("client_t", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ clienttable = this->ctx->clienttable;
+
+ LOCK(&clienttable->lock);
+ {
+ for (; i < clienttable->max_clients; i++) {
+ client = clienttable->cliententries[i].client;
+ if (client == NULL)
+ continue;
+ /*
+ * look for matching client_uid, _and_
+ * if auth was used, matching auth flavour and data
+ */
+ if (strcmp(client_uid, client->client_uid) == 0 &&
+ (cred->flavour && (cred->flavour == client->auth.flavour &&
+ (size_t)cred->datalen == client->auth.len &&
+ memcmp(cred->authdata, client->auth.data,
+ client->auth.len) == 0))) {
+ GF_ATOMIC_INC(client->bind);
+ goto unlock;
+ }
+ }
+
+ client = GF_CALLOC(1, sizeof(client_t), gf_common_mt_client_t);
+ if (client == NULL) {
+ errno = ENOMEM;
+ goto unlock;
+ }
+
+ client->this = this;
+ if (subdir_mount != NULL)
+ client->subdir_mount = gf_strdup(subdir_mount);
+
+ LOCK_INIT(&client->scratch_ctx.lock);
+
+ client->client_uid = gf_strdup(client_uid);
+ if (client->client_uid == NULL) {
+ GF_FREE(client);
+ client = NULL;
+ errno = ENOMEM;
+ goto unlock;
+ }
+ client->scratch_ctx.count = GF_CLIENTCTX_INITIAL_SIZE;
+ client->scratch_ctx.ctx = GF_CALLOC(GF_CLIENTCTX_INITIAL_SIZE,
+ sizeof(struct client_ctx),
+ gf_common_mt_client_ctx);
+ if (client->scratch_ctx.ctx == NULL) {
+ GF_FREE(client->client_uid);
+ GF_FREE(client);
+ client = NULL;
+ errno = ENOMEM;
+ goto unlock;
+ }
+
+ GF_ATOMIC_INIT(client->bind, 1);
+ GF_ATOMIC_INIT(client->count, 1);
+ GF_ATOMIC_INIT(client->fd_cnt, 0);
+
+ client->auth.flavour = cred->flavour;
+ if (cred->flavour) {
+ client->auth.data = GF_MALLOC(cred->datalen, gf_common_mt_client_t);
+ if (client->auth.data == NULL) {
+ GF_FREE(client->scratch_ctx.ctx);
+ GF_FREE(client->client_uid);
+ GF_FREE(client);
+ client = NULL;
+ errno = ENOMEM;
+ goto unlock;
+ }
+ memcpy(client->auth.data, cred->authdata, cred->datalen);
+ client->auth.len = cred->datalen;
+ }
+
+ client->tbl_index = clienttable->first_free;
+ cliententry = &clienttable->cliententries[clienttable->first_free];
+ if (cliententry->next_free == GF_CLIENTTABLE_END) {
+ int result = gf_client_clienttable_expand(
+ clienttable,
+ clienttable->max_clients + GF_CLIENTTABLE_INITIAL_SIZE);
+ if (result != 0) {
+ GF_FREE(client->scratch_ctx.ctx);
+ GF_FREE(client->client_uid);
+ GF_FREE(client);
+ client = NULL;
+ errno = result;
+ goto unlock;
+ }
+ cliententry = &clienttable->cliententries[client->tbl_index];
+ cliententry->next_free = clienttable->first_free;
+ }
+ cliententry->client = client;
+ clienttable->first_free = cliententry->next_free;
+ cliententry->next_free = GF_CLIENTENTRY_ALLOCATED;
+ }
unlock:
- UNLOCK (&clienttable->lock);
-
- if (client)
- gf_msg_callingfn ("client_t", GF_LOG_DEBUG, 0, LG_MSG_BIND_REF,
- "%s: bind_ref: %d, ref: %d",
- client->client_uid, client->ref.bind,
- client->ref.count);
- return client;
+ UNLOCK(&clienttable->lock);
+
+ if (client)
+ gf_msg_callingfn("client_t", GF_LOG_DEBUG, 0, LG_MSG_BIND_REF,
+ "%s: bind_ref: %" GF_PRI_ATOMIC
+ ", ref: "
+ "%" GF_PRI_ATOMIC,
+ client->client_uid, GF_ATOMIC_GET(client->bind),
+ GF_ATOMIC_GET(client->count));
+ return client;
}
void
-gf_client_put (client_t *client, gf_boolean_t *detached)
+gf_client_put(client_t *client, gf_boolean_t *detached)
{
- gf_boolean_t unref = _gf_false;
- int bind_ref;
-
- if (client == NULL)
- goto out;
-
+ gf_boolean_t unref = _gf_false;
+ int bind_ref;
+
+ if (client == NULL)
+ goto out;
+
+ if (detached)
+ *detached = _gf_false;
+
+ bind_ref = GF_ATOMIC_DEC(client->bind);
+ if (bind_ref == 0)
+ unref = _gf_true;
+
+ gf_msg_callingfn("client_t", GF_LOG_DEBUG, 0, LG_MSG_BIND_REF,
+ "%s: "
+ "bind_ref: %" GF_PRI_ATOMIC ", ref: %" GF_PRI_ATOMIC
+ ", "
+ "unref: %d",
+ client->client_uid, GF_ATOMIC_GET(client->bind),
+ GF_ATOMIC_GET(client->count), unref);
+ if (unref) {
if (detached)
- *detached = _gf_false;
-
- bind_ref = DECREMENT_ATOMIC (client->ref.lock, client->ref.bind);
- if (bind_ref == 0)
- unref = _gf_true;
-
- gf_msg_callingfn ("client_t", GF_LOG_DEBUG, 0, LG_MSG_BIND_REF, "%s: "
- "bind_ref: %d, ref: %d, unref: %d",
- client->client_uid, client->ref.bind,
- client->ref.count, unref);
- if (unref) {
- if (detached)
- *detached = _gf_true;
- gf_client_unref (client);
- }
+ *detached = _gf_true;
+ gf_client_unref(client);
+ }
out:
- return;
+ return;
}
client_t *
-gf_client_ref (client_t *client)
+gf_client_ref(client_t *client)
{
- if (!client) {
- gf_msg_callingfn ("client_t", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "null client");
- return NULL;
- }
-
- INCREMENT_ATOMIC (client->ref.lock, client->ref.count);
- gf_msg_callingfn ("client_t", GF_LOG_DEBUG, 0, LG_MSG_REF_COUNT, "%s: "
- "ref-count %d", client->client_uid,
- client->ref.count);
- return client;
+ if (!client) {
+ gf_msg_callingfn("client_t", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "null client");
+ return NULL;
+ }
+
+ GF_ATOMIC_INC(client->count);
+ gf_msg_callingfn("client_t", GF_LOG_DEBUG, 0, LG_MSG_REF_COUNT,
+ "%s: "
+ "ref-count %" GF_PRI_ATOMIC,
+ client->client_uid, GF_ATOMIC_GET(client->count));
+ return client;
}
-
static void
-client_destroy (client_t *client)
+gf_client_destroy_recursive(xlator_t *xl, client_t *client)
{
- clienttable_t *clienttable = NULL;
- glusterfs_graph_t *gtrav = NULL;
- xlator_t *xtrav = NULL;
+ xlator_list_t *trav;
- if (client == NULL){
- gf_msg_callingfn ("xlator", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- goto out;
- }
+ if (!xl->call_cleanup && xl->cbks->client_destroy) {
+ xl->cbks->client_destroy(xl, client);
+ }
- clienttable = client->this->ctx->clienttable;
-
- LOCK_DESTROY (&client->scratch_ctx.lock);
- LOCK_DESTROY (&client->ref.lock);
+ for (trav = xl->children; trav; trav = trav->next) {
+ gf_client_destroy_recursive(trav->xlator, client);
+ }
+}
- LOCK (&clienttable->lock);
- {
- clienttable->cliententries[client->tbl_index].client = NULL;
- clienttable->cliententries[client->tbl_index].next_free =
- clienttable->first_free;
- clienttable->first_free = client->tbl_index;
- }
- UNLOCK (&clienttable->lock);
-
- list_for_each_entry (gtrav, &client->this->ctx->graphs, list) {
- xtrav = gtrav->top;
- while (xtrav != NULL) {
- if (xtrav->cbks->client_destroy != NULL)
- xtrav->cbks->client_destroy (xtrav, client);
- xtrav = xtrav->next;
- }
- }
- GF_FREE (client->auth.data);
- GF_FREE (client->scratch_ctx.ctx);
- GF_FREE (client->client_uid);
- GF_FREE (client);
+static void
+client_destroy(client_t *client)
+{
+ clienttable_t *clienttable = NULL;
+ glusterfs_graph_t *gtrav = NULL;
+
+ if (client == NULL) {
+ gf_msg_callingfn("xlator", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ goto out;
+ }
+
+ clienttable = client->this->ctx->clienttable;
+
+ LOCK(&clienttable->lock);
+ {
+ clienttable->cliententries[client->tbl_index].client = NULL;
+ clienttable->cliententries[client->tbl_index]
+ .next_free = clienttable->first_free;
+ clienttable->first_free = client->tbl_index;
+ }
+ UNLOCK(&clienttable->lock);
+
+ list_for_each_entry(gtrav, &client->this->ctx->graphs, list)
+ {
+ gf_client_destroy_recursive(gtrav->top, client);
+ }
+
+ if (client->subdir_inode)
+ inode_unref(client->subdir_inode);
+
+ LOCK_DESTROY(&client->scratch_ctx.lock);
+
+ GF_FREE(client->auth.data);
+ GF_FREE(client->auth.username);
+ GF_FREE(client->auth.passwd);
+ GF_FREE(client->scratch_ctx.ctx);
+ GF_FREE(client->client_uid);
+ GF_FREE(client->subdir_mount);
+ GF_FREE(client->client_name);
+ GF_FREE(client);
out:
- return;
+ return;
}
+static int
+gf_client_disconnect_recursive(xlator_t *xl, client_t *client)
+{
+ int ret = 0;
+ xlator_list_t *trav;
+
+ if (!xl->call_cleanup && xl->cbks->client_disconnect) {
+ ret = xl->cbks->client_disconnect(xl, client);
+ }
+
+ for (trav = xl->children; trav; trav = trav->next) {
+ ret |= gf_client_disconnect_recursive(trav->xlator, client);
+ }
+
+ return ret;
+}
int
-gf_client_disconnect (client_t *client)
+gf_client_disconnect(client_t *client)
{
- int ret = 0;
- glusterfs_graph_t *gtrav = NULL;
- xlator_t *xtrav = NULL;
-
- list_for_each_entry (gtrav, &client->this->ctx->graphs, list) {
- xtrav = gtrav->top;
- while (xtrav != NULL) {
- if (xtrav->cbks->client_disconnect != NULL)
- if (xtrav->cbks->client_disconnect (xtrav, client) != 0)
- ret = -1;
- xtrav = xtrav->next;
- }
- }
+ int ret = 0;
+ glusterfs_graph_t *gtrav = NULL;
- return ret;
-}
+ list_for_each_entry(gtrav, &client->this->ctx->graphs, list)
+ {
+ ret |= gf_client_disconnect_recursive(gtrav->top, client);
+ }
+ return ret;
+}
void
-gf_client_unref (client_t *client)
+gf_client_unref(client_t *client)
{
- int refcount;
-
- if (!client) {
- gf_msg_callingfn ("client_t", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "client is NULL");
- return;
- }
+ uint64_t refcount;
- refcount = DECREMENT_ATOMIC (client->ref.lock, client->ref.count);
- gf_msg_callingfn ("client_t", GF_LOG_DEBUG, 0, LG_MSG_REF_COUNT, "%s: "
- "ref-count %d", client->client_uid,
- (int)client->ref.count);
- if (refcount == 0) {
- gf_msg (THIS->name, GF_LOG_INFO, 0, LG_MSG_DISCONNECT_CLIENT,
- "Shutting down connection %s", client->client_uid);
- client_destroy (client);
- }
+ if (!client) {
+ gf_msg_callingfn("client_t", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "client is NULL");
+ return;
+ }
+
+ refcount = GF_ATOMIC_DEC(client->count);
+ gf_msg_callingfn("client_t", GF_LOG_DEBUG, 0, LG_MSG_REF_COUNT,
+ "%s: "
+ "ref-count %" GF_PRI_ATOMIC,
+ client->client_uid, refcount);
+ if (refcount == 0) {
+ gf_msg(THIS->name, GF_LOG_INFO, 0, LG_MSG_DISCONNECT_CLIENT,
+ "Shutting down connection %s", client->client_uid);
+ client_destroy(client);
+ }
}
-
static int
-client_ctx_set_int (client_t *client, void *key, void *value)
+__client_ctx_get_int(client_t *client, void *key, void **value)
{
- int index = 0;
- int ret = 0;
- int set_idx = -1;
-
- for (index = 0; index < client->scratch_ctx.count; index++) {
- if (!client->scratch_ctx.ctx[index].ctx_key) {
- if (set_idx == -1)
- set_idx = index;
- /* dont break, to check if key already exists
- further on */
- }
- if (client->scratch_ctx.ctx[index].ctx_key == key) {
- set_idx = index;
- break;
- }
- }
+ int index = 0;
+ int ret = 0;
- if (set_idx == -1) {
- ret = -1;
- goto out;
- }
+ for (index = 0; index < client->scratch_ctx.count; index++) {
+ if (client->scratch_ctx.ctx[index].ctx_key == key)
+ break;
+ }
+
+ if (index == client->scratch_ctx.count) {
+ ret = -1;
+ goto out;
+ }
- client->scratch_ctx.ctx[set_idx].ctx_key = key;
- client->scratch_ctx.ctx[set_idx].ctx_value = value;
+ if (value)
+ *value = client->scratch_ctx.ctx[index].ctx_value;
out:
- return ret;
+ return ret;
}
-
-int
-client_ctx_set (client_t *client, void *key, void *value)
+static int
+__client_ctx_set_int(client_t *client, void *key, void *value)
{
- int ret = 0;
-
- if (!client || !key)
- return -1;
+ int index = 0;
+ int ret = 0;
+ int set_idx = -1;
- LOCK (&client->scratch_ctx.lock);
- {
- ret = client_ctx_set_int (client, key, value);
+ for (index = 0; index < client->scratch_ctx.count; index++) {
+ if (!client->scratch_ctx.ctx[index].ctx_key) {
+ if (set_idx == -1)
+ set_idx = index;
+ /* don't break, to check if key already exists
+ further on */
+ }
+ if (client->scratch_ctx.ctx[index].ctx_key == key) {
+ set_idx = index;
+ break;
}
- UNLOCK (&client->scratch_ctx.lock);
+ }
- return ret;
-}
+ if (set_idx == -1) {
+ ret = -1;
+ goto out;
+ }
+ client->scratch_ctx.ctx[set_idx].ctx_key = key;
+ client->scratch_ctx.ctx[set_idx].ctx_value = value;
-static int
-client_ctx_get_int (client_t *client, void *key, void **value)
+out:
+ return ret;
+}
+
+/*will return success with old value if exist*/
+void *
+client_ctx_set(client_t *client, void *key, void *value)
{
- int index = 0;
- int ret = 0;
+ int ret = 0;
+ void *ret_value = NULL;
- for (index = 0; index < client->scratch_ctx.count; index++) {
- if (client->scratch_ctx.ctx[index].ctx_key == key)
- break;
- }
+ if (!client || !key || !value)
+ return NULL;
- if (index == client->scratch_ctx.count) {
- ret = -1;
- goto out;
+ LOCK(&client->scratch_ctx.lock);
+ {
+ ret = __client_ctx_get_int(client, key, &ret_value);
+ if (!ret && ret_value) {
+ UNLOCK(&client->scratch_ctx.lock);
+ return ret_value;
}
- if (value)
- *value = client->scratch_ctx.ctx[index].ctx_value;
+ ret = __client_ctx_set_int(client, key, value);
+ }
+ UNLOCK(&client->scratch_ctx.lock);
-out:
- return ret;
+ if (ret)
+ return NULL;
+ return value;
}
-
int
-client_ctx_get (client_t *client, void *key, void **value)
+client_ctx_get(client_t *client, void *key, void **value)
{
- int ret = 0;
+ int ret = 0;
- if (!client || !key)
- return -1;
+ if (!client || !key)
+ return -1;
- LOCK (&client->scratch_ctx.lock);
- {
- ret = client_ctx_get_int (client, key, value);
- }
- UNLOCK (&client->scratch_ctx.lock);
+ LOCK(&client->scratch_ctx.lock);
+ {
+ ret = __client_ctx_get_int(client, key, value);
+ }
+ UNLOCK(&client->scratch_ctx.lock);
- return ret;
+ return ret;
}
-
static int
-client_ctx_del_int (client_t *client, void *key, void **value)
+__client_ctx_del_int(client_t *client, void *key, void **value)
{
- int index = 0;
- int ret = 0;
+ int index = 0;
+ int ret = 0;
- for (index = 0; index < client->scratch_ctx.count; index++) {
- if (client->scratch_ctx.ctx[index].ctx_key == key)
- break;
- }
+ for (index = 0; index < client->scratch_ctx.count; index++) {
+ if (client->scratch_ctx.ctx[index].ctx_key == key)
+ break;
+ }
- if (index == client->scratch_ctx.count) {
- ret = -1;
- goto out;
- }
+ if (index == client->scratch_ctx.count) {
+ ret = -1;
+ goto out;
+ }
- if (value)
- *value = client->scratch_ctx.ctx[index].ctx_value;
+ if (value)
+ *value = client->scratch_ctx.ctx[index].ctx_value;
- client->scratch_ctx.ctx[index].ctx_key = 0;
- client->scratch_ctx.ctx[index].ctx_value = 0;
+ client->scratch_ctx.ctx[index].ctx_key = 0;
+ client->scratch_ctx.ctx[index].ctx_value = 0;
out:
- return ret;
+ return ret;
}
-
int
-client_ctx_del (client_t *client, void *key, void **value)
+client_ctx_del(client_t *client, void *key, void **value)
{
- int ret = 0;
+ int ret = 0;
- if (!client || !key)
- return -1;
+ if (!client || !key)
+ return -1;
- LOCK (&client->scratch_ctx.lock);
- {
- ret = client_ctx_del_int (client, key, value);
- }
- UNLOCK (&client->scratch_ctx.lock);
+ LOCK(&client->scratch_ctx.lock);
+ {
+ ret = __client_ctx_del_int(client, key, value);
+ }
+ UNLOCK(&client->scratch_ctx.lock);
- return ret;
+ return ret;
}
-
void
-client_dump (client_t *client, char *prefix)
-{
- char key[GF_DUMP_MAX_BUF_LEN];
-
- if (!client)
- return;
-
- memset(key, 0, sizeof key);
- gf_proc_dump_write("refcount", "%d", client->ref.count);
-}
-
-
-void
-cliententry_dump (cliententry_t *cliententry, char *prefix)
-{
- if (!cliententry)
- return;
-
- if (GF_CLIENTENTRY_ALLOCATED != cliententry->next_free)
- return;
-
- if (cliententry->client)
- client_dump(cliententry->client, prefix);
-}
-
-
-void
-clienttable_dump (clienttable_t *clienttable, char *prefix)
-{
- int i = 0;
- int ret = -1;
- char key[GF_DUMP_MAX_BUF_LEN] = {0};
-
- if (!clienttable)
- return;
-
- ret = TRY_LOCK (&clienttable->lock);
- {
- if (ret) {
- gf_msg ("client_t", GF_LOG_WARNING, 0,
- LG_MSG_LOCK_FAILED,
- "Unable to acquire lock");
- return;
- }
- memset(key, 0, sizeof key);
- gf_proc_dump_build_key(key, prefix, "maxclients");
- gf_proc_dump_write(key, "%d", clienttable->max_clients);
- gf_proc_dump_build_key(key, prefix, "first_free");
- gf_proc_dump_write(key, "%d", clienttable->first_free);
- for ( i = 0 ; i < clienttable->max_clients; i++) {
- if (GF_CLIENTENTRY_ALLOCATED ==
- clienttable->cliententries[i].next_free) {
- gf_proc_dump_build_key(key, prefix,
- "cliententry[%d]", i);
- gf_proc_dump_add_section(key);
- cliententry_dump(&clienttable->cliententries[i],
- key);
- }
- }
- }
- UNLOCK(&clienttable->lock);
-}
-
-
-void
-client_ctx_dump (client_t *client, char *prefix)
+client_ctx_dump(client_t *client, char *prefix)
{
#if 0 /* TBD, FIXME */
struct client_ctx *client_ctx = NULL;
@@ -664,243 +585,241 @@ out:
#endif
}
-
/*
* the following functions are here to preserve legacy behavior of the
* protocol/server xlator dump, but perhaps they should just be folded
* into the client dump instead?
*/
int
-gf_client_dump_fdtables_to_dict (xlator_t *this, dict_t *dict)
+gf_client_dump_fdtables_to_dict(xlator_t *this, dict_t *dict)
{
- clienttable_t *clienttable = NULL;
- int count = 0;
- int ret = -1;
+ clienttable_t *clienttable = NULL;
+ int count = 0;
+ int ret = -1;
#ifdef NOTYET
- client_t *client = NULL;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ client_t *client = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
#endif
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, this, out);
+ GF_VALIDATE_OR_GOTO(this->name, dict, out);
- clienttable = this->ctx->clienttable;
+ clienttable = this->ctx->clienttable;
- if (!clienttable)
- return -1;
+ if (!clienttable)
+ return -1;
#ifdef NOTYET
- ret = TRY_LOCK (&clienttable->lock);
- {
- if (ret) {
- gf_msg ("client_t", GF_LOG_WARNING, 0,
- LG_MSG_LOCK_FAILED,
- "Unable to acquire lock");
- return -1;
- }
- for ( ; count < clienttable->max_clients; count++) {
- if (GF_CLIENTENTRY_ALLOCATED !=
- clienttable->cliententries[count].next_free)
- continue;
- client = clienttable->cliententries[count].client;
- memset(key, 0, sizeof key);
- snprintf (key, sizeof key, "conn%d", count++);
- fdtable_dump_to_dict (client->server_ctx.fdtable,
- key, dict);
- }
- }
- UNLOCK(&clienttable->lock);
+ ret = TRY_LOCK(&clienttable->lock);
+ {
+ if (ret) {
+ gf_msg("client_t", GF_LOG_WARNING, 0, LG_MSG_LOCK_FAILED,
+ "Unable to acquire lock");
+ return -1;
+ }
+ for (; count < clienttable->max_clients; count++) {
+ if (GF_CLIENTENTRY_ALLOCATED !=
+ clienttable->cliententries[count].next_free)
+ continue;
+ client = clienttable->cliententries[count].client;
+ if (client->bound_xl &&
+ !strcmp(client->bound_xl->name, this->name)) {
+ snprintf(key, sizeof(key), "conn%d", count++);
+ fdtable_dump_to_dict(client->server_ctx.fdtable, key, dict);
+ }
+ }
+ }
+ UNLOCK(&clienttable->lock);
#endif
- ret = dict_set_int32 (dict, "conncount", count);
+ ret = dict_set_int32(dict, "conncount", count);
out:
- return ret;
+ return ret;
}
int
-gf_client_dump_fdtables (xlator_t *this)
+gf_client_dump_fdtables(xlator_t *this)
{
- client_t *client = NULL;
- clienttable_t *clienttable = NULL;
- int count = 1;
- int ret = -1;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
-
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
-
- clienttable = this->ctx->clienttable;
-
- if (!clienttable)
- return -1;
-
- ret = TRY_LOCK (&clienttable->lock);
- {
- if (ret) {
- gf_msg ("client_t", GF_LOG_WARNING, 0,
- LG_MSG_LOCK_FAILED,
- "Unable to acquire lock");
- return -1;
- }
-
-
- for ( ; count < clienttable->max_clients; count++) {
- if (GF_CLIENTENTRY_ALLOCATED !=
- clienttable->cliententries[count].next_free)
- continue;
- client = clienttable->cliententries[count].client;
- memset(key, 0, sizeof key);
- if (client->client_uid) {
- gf_proc_dump_build_key (key, "conn",
- "%d.id", count);
- gf_proc_dump_write (key, "%s",
- client->client_uid);
- }
-
- gf_proc_dump_build_key (key, "conn", "%d.ref",
- count);
- gf_proc_dump_write (key, "%d", client->ref.count);
- if (client->bound_xl) {
- gf_proc_dump_build_key (key, "conn",
- "%d.bound_xl", count);
- gf_proc_dump_write (key, "%s",
- client->bound_xl->name);
- }
+ client_t *client = NULL;
+ clienttable_t *clienttable = NULL;
+ int count = 1;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO(THIS->name, this, out);
+
+ clienttable = this->ctx->clienttable;
+
+ if (!clienttable)
+ return -1;
+
+ ret = TRY_LOCK(&clienttable->lock);
+ {
+ if (ret) {
+ gf_msg("client_t", GF_LOG_WARNING, 0, LG_MSG_LOCK_FAILED,
+ "Unable to acquire lock");
+ return -1;
+ }
+
+ for (; count < clienttable->max_clients; count++) {
+ if (GF_CLIENTENTRY_ALLOCATED !=
+ clienttable->cliententries[count].next_free)
+ continue;
+ client = clienttable->cliententries[count].client;
+ if (client->client_uid) {
+ gf_proc_dump_build_key(key, "conn", "%d.id", count);
+ gf_proc_dump_write(key, "%s", client->client_uid);
+ }
+
+ if (client->subdir_mount) {
+ gf_proc_dump_build_key(key, "conn", "%d.subdir", count);
+ gf_proc_dump_write(key, "%s", client->subdir_mount);
+ }
+ gf_proc_dump_build_key(key, "conn", "%d.ref", count);
+ gf_proc_dump_write(key, "%" GF_PRI_ATOMIC,
+ GF_ATOMIC_GET(client->count));
+ if (client->bound_xl) {
+ gf_proc_dump_build_key(key, "conn", "%d.bound_xl", count);
+ gf_proc_dump_write(key, "%s", client->bound_xl->name);
+ }
#ifdef NOTYET
- gf_proc_dump_build_key (key, "conn","%d.id", count);
- fdtable_dump (client->server_ctx.fdtable, key);
+ gf_proc_dump_build_key(key, "conn", "%d.id", count);
+ fdtable_dump(client->server_ctx.fdtable, key);
#endif
- }
}
+ }
- UNLOCK(&clienttable->lock);
+ UNLOCK(&clienttable->lock);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
int
-gf_client_dump_inodes_to_dict (xlator_t *this, dict_t *dict)
+gf_client_dump_inodes_to_dict(xlator_t *this, dict_t *dict)
{
- client_t *client = NULL;
- clienttable_t *clienttable = NULL;
- xlator_t *prev_bound_xl = NULL;
- char key[32] = {0,};
- int count = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
- clienttable = this->ctx->clienttable;
-
- if (!clienttable)
- return -1;
-
- ret = TRY_LOCK (&clienttable->lock);
- {
- if (ret) {
- gf_msg ("client_t", GF_LOG_WARNING, 0,
- LG_MSG_LOCK_FAILED,
- "Unable to acquire lock");
- return -1;
- }
- for ( ; count < clienttable->max_clients; count++) {
- if (GF_CLIENTENTRY_ALLOCATED !=
- clienttable->cliententries[count].next_free)
- continue;
- client = clienttable->cliententries[count].client;
- memset(key, 0, sizeof key);
- if (client->bound_xl && client->bound_xl->itable) {
- /* Presently every brick contains only
- * one bound_xl for all connections.
- * This will lead to duplicating of
- * the inode lists, if listing is
- * done for every connection. This
- * simple check prevents duplication
- * in the present case. If need arises
- * the check can be improved.
- */
- if (client->bound_xl == prev_bound_xl)
- continue;
- prev_bound_xl = client->bound_xl;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "conn%d", count);
- inode_table_dump_to_dict (client->bound_xl->itable,
- key, dict);
- }
+ client_t *client = NULL;
+ clienttable_t *clienttable = NULL;
+ xlator_t *prev_bound_xl = NULL;
+ char key[32] = {
+ 0,
+ };
+ int count = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO(THIS->name, this, out);
+ GF_VALIDATE_OR_GOTO(this->name, dict, out);
+
+ clienttable = this->ctx->clienttable;
+
+ if (!clienttable)
+ return -1;
+
+ ret = LOCK(&clienttable->lock);
+ {
+ if (ret) {
+ gf_msg("client_t", GF_LOG_WARNING, 0, LG_MSG_LOCK_FAILED,
+ "Unable to acquire lock");
+ return -1;
+ }
+ for (; count < clienttable->max_clients; count++) {
+ if (GF_CLIENTENTRY_ALLOCATED !=
+ clienttable->cliententries[count].next_free)
+ continue;
+ client = clienttable->cliententries[count].client;
+ if (!strcmp(client->bound_xl->name, this->name)) {
+ if (client->bound_xl && client->bound_xl->itable) {
+ /* Presently every brick contains only
+ * one bound_xl for all connections.
+ * This will lead to duplicating of
+ * the inode lists, if listing is
+ * done for every connection. This
+ * simple check prevents duplication
+ * in the present case. If need arises
+ * the check can be improved.
+ */
+ if (client->bound_xl == prev_bound_xl)
+ continue;
+ prev_bound_xl = client->bound_xl;
+
+ snprintf(key, sizeof(key), "conn%d", count);
+ inode_table_dump_to_dict(client->bound_xl->itable, key,
+ dict);
}
+ }
}
- UNLOCK(&clienttable->lock);
+ }
+ UNLOCK(&clienttable->lock);
- ret = dict_set_int32 (dict, "conncount", count);
+ ret = dict_set_int32(dict, "conncount", count);
out:
- if (prev_bound_xl)
- prev_bound_xl = NULL;
- return ret;
+ if (prev_bound_xl)
+ prev_bound_xl = NULL;
+ return ret;
}
int
-gf_client_dump_inodes (xlator_t *this)
+gf_client_dump_inodes(xlator_t *this)
{
- client_t *client = NULL;
- clienttable_t *clienttable = NULL;
- xlator_t *prev_bound_xl = NULL;
- int count = 1;
- int ret = -1;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
-
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
-
- clienttable = this->ctx->clienttable;
-
- if (!clienttable)
- goto out;
-
- ret = TRY_LOCK (&clienttable->lock);
- {
- if (ret) {
- gf_msg ("client_t", GF_LOG_WARNING, 0,
- LG_MSG_LOCK_FAILED,
- "Unable to acquire lock");
- goto out;
- }
-
- for ( ; count < clienttable->max_clients; count++) {
- if (GF_CLIENTENTRY_ALLOCATED !=
- clienttable->cliententries[count].next_free)
- continue;
- client = clienttable->cliententries[count].client;
- memset(key, 0, sizeof key);
- if (client->bound_xl && client->bound_xl->itable) {
- /* Presently every brick contains only
- * one bound_xl for all connections.
- * This will lead to duplicating of
- * the inode lists, if listing is
- * done for every connection. This
- * simple check prevents duplication
- * in the present case. If need arises
- * the check can be improved.
- */
- if (client->bound_xl == prev_bound_xl)
- continue;
- prev_bound_xl = client->bound_xl;
-
- gf_proc_dump_build_key(key, "conn",
- "%d.bound_xl.%s", count,
- client->bound_xl->name);
- inode_table_dump(client->bound_xl->itable,key);
- }
- }
- }
- UNLOCK(&clienttable->lock);
-
- ret = 0;
+ client_t *client = NULL;
+ clienttable_t *clienttable = NULL;
+ xlator_t *prev_bound_xl = NULL;
+ int count = 0;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO(THIS->name, this, out);
+
+ clienttable = this->ctx->clienttable;
+
+ if (!clienttable)
+ goto out;
+
+ ret = TRY_LOCK(&clienttable->lock);
+ {
+ if (ret) {
+ gf_msg("client_t", GF_LOG_WARNING, 0, LG_MSG_LOCK_FAILED,
+ "Unable to acquire lock");
+ goto out;
+ }
+
+ for (; count < clienttable->max_clients; count++) {
+ if (GF_CLIENTENTRY_ALLOCATED !=
+ clienttable->cliententries[count].next_free)
+ continue;
+ client = clienttable->cliententries[count].client;
+ if (client->bound_xl && client->bound_xl->itable) {
+ /* Presently every brick contains only
+ * one bound_xl for all connections.
+ * This will lead to duplicating of
+ * the inode lists, if listing is
+ * done for every connection. This
+ * simple check prevents duplication
+ * in the present case. If need arises
+ * the check can be improved.
+ */
+ if (client->bound_xl == prev_bound_xl)
+ continue;
+ prev_bound_xl = client->bound_xl;
+
+ gf_proc_dump_build_key(key, "conn", "%d.bound_xl.%s", count,
+ client->bound_xl->name);
+ inode_table_dump(client->bound_xl->itable, key);
+ }
+ }
+ }
+ UNLOCK(&clienttable->lock);
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
diff --git a/libglusterfs/src/client_t.h b/libglusterfs/src/client_t.h
deleted file mode 100644
index bfea62061bd..00000000000
--- a/libglusterfs/src/client_t.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- 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 _CLIENT_T_H
-#define _CLIENT_T_H
-
-#include "glusterfs.h"
-#include "locking.h" /* for gf_lock_t, not included by glusterfs.h */
-
-struct client_ctx {
- void *ctx_key;
- void *ctx_value;
-};
-
-typedef struct _client_t {
- struct {
- /* e.g. protocol/server stashes its ctx here */
- gf_lock_t lock;
- unsigned short count;
- struct client_ctx *ctx;
- } scratch_ctx;
- struct {
- gf_lock_t lock;
- volatile int bind;
- volatile int count;
- } ref;
- xlator_t *bound_xl;
- xlator_t *this;
- int tbl_index;
- char *client_uid;
- struct {
- int flavour;
- size_t len;
- char *data;
- char *username;
- char *passwd;
- } auth;
-} client_t;
-
-#define GF_CLIENTCTX_INITIAL_SIZE 8
-
-struct client_table_entry {
- client_t *client;
- int next_free;
-};
-typedef struct client_table_entry cliententry_t;
-
-struct clienttable {
- unsigned int max_clients;
- gf_lock_t lock;
- cliententry_t *cliententries;
- int first_free;
- client_t *local;
-};
-typedef struct clienttable clienttable_t;
-
-#define GF_CLIENTTABLE_INITIAL_SIZE 128
-
-/* Signifies no more entries in the client table. */
-#define GF_CLIENTTABLE_END -1
-
-/* This is used to invalidate
- * the next_free value in an cliententry that has been allocated
- */
-#define GF_CLIENTENTRY_ALLOCATED -2
-
-struct rpcsvc_auth_data;
-
-/*
- * a more comprehensive feature test is shown at
- * http://lists.iptel.org/pipermail/semsdev/2010-October/005075.html
- * this is sufficient for RHEL5 i386 builds
- */
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && !defined(__i386__)
-# define INCREMENT_ATOMIC(lk,op) __sync_add_and_fetch(&op, 1)
-# define DECREMENT_ATOMIC(lk,op) __sync_sub_and_fetch(&op, 1)
-#else
-/* These are only here for old gcc, e.g. on RHEL5 i386.
- * We're not ever going to use this in an if stmt,
- * but let's be pedantically correct for style points */
-# define INCREMENT_ATOMIC(lk,op) do { LOCK (&lk); ++op; UNLOCK (&lk); } while (0)
-/* this is a gcc 'statement expression', it works with llvm/clang too */
-# define DECREMENT_ATOMIC(lk,op) ({ LOCK (&lk); --op; UNLOCK (&lk); op; })
-#endif
-
-client_t *
-gf_client_get (xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid);
-
-void
-gf_client_put (client_t *client, gf_boolean_t *detached);
-
-clienttable_t *
-gf_clienttable_alloc (void);
-
-void
-gf_client_clienttable_destroy (clienttable_t *clienttable);
-
-client_t *
-gf_client_ref (client_t *client);
-
-void
-gf_client_unref (client_t *client);
-
-int
-gf_client_dump_fdtable_to_dict (xlator_t *this, dict_t *dict);
-
-int
-gf_client_dump_fdtable (xlator_t *this);
-
-int
-gf_client_dump_inodes_to_dict (xlator_t *this, dict_t *dict);
-
-int
-gf_client_dump_inodes (xlator_t *this);
-
-int
-client_ctx_set (client_t *client, void *key, void *value);
-
-int
-client_ctx_get (client_t *client, void *key, void **value);
-
-int
-client_ctx_del (client_t *client, void *key, void **value);
-
-void
-client_ctx_dump (client_t *client, char *prefix);
-
-int
-gf_client_dump_fdtables_to_dict (xlator_t *this, dict_t *dict);
-
-int
-gf_client_dump_fdtables (xlator_t *this);
-
-int
-gf_client_dump_inodes_to_dict (xlator_t *this, dict_t *dict);
-
-int
-gf_client_dump_inodes (xlator_t *this);
-
-int
-gf_client_disconnect (client_t *client);
-
-#endif /* _CLIENT_T_H */
diff --git a/libglusterfs/src/cluster-syncop.c b/libglusterfs/src/cluster-syncop.c
index 10993e6088d..6ee89ddfdcf 100644
--- a/libglusterfs/src/cluster-syncop.c
+++ b/libglusterfs/src/cluster-syncop.c
@@ -14,523 +14,499 @@
/* NOTE: Cluster-syncop, like syncop blocks the executing thread until the
* responses are gathered if it is not executed as part of synctask. So it
* shouldn't be invoked in epoll worker thread */
-#include "cluster-syncop.h"
-#include "defaults.h"
-
-#define FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fop, args ...) do {\
- int __i = 0; \
- int __count = 0; \
- cluster_local_t __local = {0,}; \
- void *__old_local = frame->local; \
- \
- __local.replies = replies; \
- memset (output, 0, numsubvols); \
- cluster_replies_wipe (replies, numsubvols); \
- for (__i = 0; __i < numsubvols; __i++) \
- INIT_LIST_HEAD (&replies[__i].entries.list); \
- if (syncbarrier_init (&__local.barrier)) \
- break; \
- frame->local = &__local; \
- for (__i = 0; __i < numsubvols; __i++) { \
- if (!on[__i]) \
- continue; \
- STACK_WIND_COOKIE (frame, cluster_##fop##_cbk, \
- (void *)(long) __i, subvols[__i], \
- subvols[__i]->fops->fop, args); \
- __count++; \
- } \
- syncbarrier_wait (&__local.barrier, __count); \
- syncbarrier_destroy (&__local.barrier); \
- frame->local = __old_local; \
- STACK_RESET (frame->root); \
- } while (0)
-
-#define FOP_SEQ(subvols, on, numsubvols, replies, output, frame, fop, args ...) do {\
- int __i = 0; \
- \
- cluster_local_t __local = {0,}; \
- void *__old_local = frame->local; \
- __local.replies = replies; \
- memset (output, 0, numsubvols); \
- cluster_replies_wipe (replies, numsubvols); \
- for (__i = 0; __i < numsubvols; __i++) \
- INIT_LIST_HEAD (&replies[__i].entries.list); \
- if (syncbarrier_init (&__local.barrier)) \
- break; \
- frame->local = &__local; \
- for (__i = 0; __i < numsubvols; __i++) { \
- if (!on[__i]) \
- continue; \
- STACK_WIND_COOKIE (frame, cluster_##fop##_cbk, \
- (void *)(long) __i, subvols[__i], \
- subvols[__i]->fops->fop, args); \
- syncbarrier_wait (&__local.barrier, 1); \
- } \
- syncbarrier_destroy (&__local.barrier); \
- frame->local = __old_local; \
- STACK_RESET (frame->root); \
- } while (0)
-
-#define FOP_CBK(fop, frame, cookie, args ...) do {\
- cluster_local_t *__local = frame->local; \
- int __i = (long)cookie; \
- args_##fop##_cbk_store (&__local->replies[__i], args); \
- __local->replies[__i].valid = 1; \
- syncbarrier_wake (&__local->barrier); \
- } while (0)
-
-static int
-fop_success_fill (default_args_cbk_t *replies, int numsubvols,
- unsigned char *success)
-{
- int i = 0;
- int count = 0;
-
- for (i = 0; i < numsubvols; i++) {
- if (replies[i].valid && replies[i].op_ret >= 0) {
- success[i] = 1;
- count++;
- } else {
- success[i] = 0;
- }
+#include "glusterfs/cluster-syncop.h"
+#include "glusterfs/defaults.h"
+
+#define FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fop, \
+ args...) \
+ do { \
+ int __i = 0; \
+ int __count = 0; \
+ cluster_local_t __local = { \
+ 0, \
+ }; \
+ void *__old_local = frame->local; \
+ \
+ __local.replies = replies; \
+ memset(output, 0, numsubvols); \
+ cluster_replies_wipe(replies, numsubvols); \
+ for (__i = 0; __i < numsubvols; __i++) \
+ INIT_LIST_HEAD(&replies[__i].entries.list); \
+ if (syncbarrier_init(&__local.barrier)) \
+ break; \
+ frame->local = &__local; \
+ for (__i = 0; __i < numsubvols; __i++) { \
+ if (on[__i]) { \
+ __count++; \
+ } \
+ } \
+ __local.barrier.waitfor = __count; \
+ for (__i = 0; __i < numsubvols; __i++) { \
+ if (!on[__i]) \
+ continue; \
+ STACK_WIND_COOKIE(frame, cluster_##fop##_cbk, (void *)(long)__i, \
+ subvols[__i], subvols[__i]->fops->fop, args); \
+ } \
+ syncbarrier_wait(&__local.barrier, __count); \
+ syncbarrier_destroy(&__local.barrier); \
+ frame->local = __old_local; \
+ STACK_RESET(frame->root); \
+ } while (0)
+
+#define FOP_SEQ(subvols, on, numsubvols, replies, output, frame, fop, args...) \
+ do { \
+ int __i = 0; \
+ \
+ cluster_local_t __local = { \
+ 0, \
+ }; \
+ void *__old_local = frame->local; \
+ __local.replies = replies; \
+ memset(output, 0, numsubvols); \
+ cluster_replies_wipe(replies, numsubvols); \
+ for (__i = 0; __i < numsubvols; __i++) \
+ INIT_LIST_HEAD(&replies[__i].entries.list); \
+ if (syncbarrier_init(&__local.barrier)) \
+ break; \
+ frame->local = &__local; \
+ for (__i = 0; __i < numsubvols; __i++) { \
+ if (!on[__i]) \
+ continue; \
+ STACK_WIND_COOKIE(frame, cluster_##fop##_cbk, (void *)(long)__i, \
+ subvols[__i], subvols[__i]->fops->fop, args); \
+ syncbarrier_wait(&__local.barrier, 1); \
+ } \
+ syncbarrier_destroy(&__local.barrier); \
+ frame->local = __old_local; \
+ STACK_RESET(frame->root); \
+ } while (0)
+
+#define FOP_CBK(fop, frame, cookie, args...) \
+ do { \
+ cluster_local_t *__local = frame->local; \
+ int __i = (long)cookie; \
+ args_##fop##_cbk_store(&__local->replies[__i], args); \
+ __local->replies[__i].valid = 1; \
+ syncbarrier_wake(&__local->barrier); \
+ } while (0)
+
+int32_t
+cluster_fop_success_fill(default_args_cbk_t *replies, int numsubvols,
+ unsigned char *success)
+{
+ int i = 0;
+ int count = 0;
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].valid && replies[i].op_ret >= 0) {
+ success[i] = 1;
+ count++;
+ } else {
+ success[i] = 0;
}
+ }
- return count;
+ return count;
}
void
-cluster_replies_wipe (default_args_cbk_t *replies, int numsubvols)
+cluster_replies_wipe(default_args_cbk_t *replies, int numsubvols)
{
- int i = 0;
- for (i = 0; i < numsubvols; i++)
- args_cbk_wipe (&replies[i]);
- memset (replies, 0, numsubvols * sizeof (*replies));
+ int i = 0;
+
+ if (!replies)
+ return;
+
+ for (i = 0; i < numsubvols; i++)
+ args_cbk_wipe(&replies[i]);
+ memset(replies, 0, numsubvols * sizeof(*replies));
}
int32_t
-cluster_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 *xdata, struct iatt *postparent)
+cluster_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 *xdata, struct iatt *postparent)
{
- FOP_CBK (lookup, frame, cookie, op_ret, op_errno, inode, buf,
- xdata, postparent);
- return 0;
+ FOP_CBK(lookup, frame, cookie, op_ret, op_errno, inode, buf, xdata,
+ postparent);
+ return 0;
}
int32_t
-cluster_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+cluster_stat_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
{
- FOP_CBK (stat, frame, cookie, op_ret, op_errno, buf, xdata);
- return 0;
+ FOP_CBK(stat, frame, cookie, op_ret, op_errno, buf, xdata);
+ return 0;
}
+int32_t
+cluster_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, dict_t *xdata)
+{
+ FOP_CBK(truncate, frame, cookie, op_ret, op_errno, prebuf, postbuf, xdata);
+ return 0;
+}
int32_t
-cluster_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+cluster_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,
- dict_t *xdata)
+ struct iatt *postbuf, dict_t *xdata)
{
- FOP_CBK (truncate, frame, cookie, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
+ FOP_CBK(ftruncate, frame, cookie, op_ret, op_errno, prebuf, postbuf, xdata);
+ return 0;
}
int32_t
-cluster_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,
- dict_t *xdata)
+cluster_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (ftruncate, frame, cookie, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
+ FOP_CBK(access, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
int32_t
-cluster_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_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, dict_t *xdata)
{
- FOP_CBK (access, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(readlink, frame, cookie, op_ret, op_errno, path, buf, xdata);
+ return 0;
}
int32_t
-cluster_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, dict_t *xdata)
+cluster_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)
{
- FOP_CBK (readlink, frame, cookie, op_ret, op_errno, path, buf,
- xdata);
- return 0;
+ FOP_CBK(mknod, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
}
+int32_t
+cluster_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, dict_t *xdata)
+{
+ FOP_CBK(mkdir, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
+}
int32_t
-cluster_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,
+cluster_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, dict_t *xdata)
{
- FOP_CBK (mknod, frame, cookie, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
- return 0;
+ FOP_CBK(unlink, frame, cookie, op_ret, op_errno, preparent, postparent,
+ xdata);
+ return 0;
}
int32_t
-cluster_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, dict_t *xdata)
+cluster_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, dict_t *xdata)
{
- FOP_CBK (mkdir, frame, cookie, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
- return 0;
+ FOP_CBK(rmdir, frame, cookie, op_ret, op_errno, preparent, postparent,
+ xdata);
+ return 0;
}
int32_t
-cluster_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+cluster_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)
{
- FOP_CBK (unlink, frame, cookie, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
+ FOP_CBK(symlink, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
}
int32_t
-cluster_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,
+cluster_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,
dict_t *xdata)
{
- FOP_CBK (rmdir, frame, cookie, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
+ FOP_CBK(rename, frame, cookie, op_ret, op_errno, buf, preoldparent,
+ postoldparent, prenewparent, postnewparent, xdata);
+ return 0;
}
-
int32_t
-cluster_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)
+cluster_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)
{
- FOP_CBK (symlink, frame, cookie, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
+ FOP_CBK(link, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
}
-
int32_t
-cluster_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,
- dict_t *xdata)
+cluster_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)
{
- FOP_CBK (rename, frame, cookie, op_ret, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent, xdata);
- return 0;
+ FOP_CBK(create, frame, cookie, op_ret, op_errno, fd, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
}
-
int32_t
-cluster_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)
+cluster_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)
{
- FOP_CBK (link, frame, cookie, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
+ FOP_CBK(open, frame, cookie, op_ret, op_errno, fd, xdata);
+ return 0;
}
-
int32_t
-cluster_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)
+cluster_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)
{
- FOP_CBK (create, frame, cookie, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
- return 0;
+ FOP_CBK(readv, frame, cookie, op_ret, op_errno, vector, count, stbuf,
+ iobref, xdata);
+ return 0;
}
int32_t
-cluster_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)
+cluster_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, dict_t *xdata)
{
- FOP_CBK (open, frame, cookie, op_ret, op_errno, fd, xdata);
- return 0;
+ FOP_CBK(writev, frame, cookie, op_ret, op_errno, prebuf, postbuf, xdata);
+ return 0;
}
int32_t
-cluster_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)
+cluster_put_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)
{
- FOP_CBK (readv, frame, cookie, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
- return 0;
+ FOP_CBK(put, frame, cookie, op_ret, op_errno, inode, buf, preparent,
+ postparent, xdata);
+ return 0;
}
-
int32_t
-cluster_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,
- dict_t *xdata)
+cluster_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (writev, frame, cookie, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
+ FOP_CBK(flush, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
-
int32_t
-cluster_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_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)
{
- FOP_CBK (flush, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(fsync, frame, cookie, op_ret, op_errno, prebuf, postbuf, xdata);
+ return 0;
}
-
-
int32_t
-cluster_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)
+cluster_fstat_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata)
{
- FOP_CBK (fsync, frame, cookie, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
+ FOP_CBK(fstat, frame, cookie, op_ret, op_errno, buf, xdata);
+ return 0;
}
int32_t
-cluster_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+cluster_opendir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
{
- FOP_CBK (fstat, frame, cookie, op_ret, op_errno, buf, xdata);
- return 0;
+ FOP_CBK(opendir, frame, cookie, op_ret, op_errno, fd, xdata);
+ return 0;
}
int32_t
-cluster_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd,
- dict_t *xdata)
+cluster_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (opendir, frame, cookie, op_ret, op_errno, fd, xdata);
- return 0;
+ FOP_CBK(fsyncdir, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
int32_t
-cluster_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf,
+ dict_t *xdata)
{
- FOP_CBK (fsyncdir, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(statfs, frame, cookie, op_ret, op_errno, buf, xdata);
+ return 0;
}
int32_t
-cluster_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf,
- dict_t *xdata)
+cluster_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (statfs, frame, cookie, op_ret, op_errno, buf, xdata);
- return 0;
+ FOP_CBK(setxattr, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
-
int32_t
-cluster_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (setxattr, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(fsetxattr, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
-
int32_t
-cluster_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- FOP_CBK (fsetxattr, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(fgetxattr, frame, cookie, op_ret, op_errno, dict, xdata);
+ return 0;
}
-
-
int32_t
-cluster_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+cluster_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- FOP_CBK (fgetxattr, frame, cookie, op_ret, op_errno, dict, xdata);
- return 0;
+ FOP_CBK(getxattr, frame, cookie, op_ret, op_errno, dict, xdata);
+ return 0;
}
-
int32_t
-cluster_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+cluster_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- FOP_CBK (getxattr, frame, cookie, op_ret, op_errno, dict, xdata);
- return 0;
+ FOP_CBK(xattrop, frame, cookie, op_ret, op_errno, dict, xdata);
+ return 0;
}
int32_t
-cluster_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+cluster_fxattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, dict_t *dict,
dict_t *xdata)
{
- FOP_CBK (xattrop, frame, cookie, op_ret, op_errno, dict, xdata);
- return 0;
+ FOP_CBK(fxattrop, frame, cookie, op_ret, op_errno, dict, xdata);
+ return 0;
}
int32_t
-cluster_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+cluster_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (fxattrop, frame, cookie, op_ret, op_errno, dict, xdata);
- return 0;
+ FOP_CBK(removexattr, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
-
int32_t
-cluster_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_fremovexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (removexattr, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(fremovexattr, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
-
int32_t
-cluster_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata)
{
- FOP_CBK (fremovexattr, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(lk, frame, cookie, op_ret, op_errno, lock, xdata);
+ return 0;
}
int32_t
-cluster_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
- dict_t *xdata)
+cluster_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (lk, frame, cookie, op_ret, op_errno, lock, xdata);
- return 0;
+ FOP_CBK(inodelk, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
int32_t
-cluster_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_finodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (inodelk, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(finodelk, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
-
int32_t
-cluster_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (finodelk, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(entrylk, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
int32_t
-cluster_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_fentrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (entrylk, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(fentrylk, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
int32_t
-cluster_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+cluster_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, dict_t *xdata)
{
- FOP_CBK (fentrylk, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(rchecksum, frame, cookie, op_ret, op_errno, weak_checksum,
+ strong_checksum, xdata);
+ return 0;
}
-
int32_t
-cluster_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,
- dict_t *xdata)
+cluster_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)
{
- FOP_CBK (rchecksum, frame, cookie, op_ret, op_errno, weak_checksum,
- strong_checksum, xdata);
- return 0;
+ FOP_CBK(readdir, frame, cookie, op_ret, op_errno, entries, xdata);
+ return 0;
}
-
int32_t
-cluster_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+cluster_readdirp_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)
{
- FOP_CBK (readdir, frame, cookie, op_ret, op_errno, entries, xdata);
- return 0;
+ FOP_CBK(readdirp, frame, cookie, op_ret, op_errno, entries, xdata);
+ return 0;
}
-
int32_t
-cluster_readdirp_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)
+cluster_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, dict_t *xdata)
{
- FOP_CBK (readdirp, frame, cookie, op_ret, op_errno, entries, xdata);
- return 0;
+ FOP_CBK(setattr, frame, cookie, op_ret, op_errno, statpre, statpost, xdata);
+ return 0;
}
int32_t
-cluster_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+cluster_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,
- dict_t *xdata)
+ struct iatt *statpost, dict_t *xdata)
{
- FOP_CBK (setattr, frame, cookie, op_ret, op_errno, statpre,
- statpost, xdata);
- return 0;
-}
-
-int32_t
-cluster_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,
- dict_t *xdata)
-{
- FOP_CBK (fsetattr, frame, cookie, op_ret, op_errno, statpre,
- statpost, xdata);
- return 0;
+ FOP_CBK(fsetattr, frame, cookie, op_ret, op_errno, statpre, statpost,
+ xdata);
+ return 0;
}
int32_t
@@ -538,8 +514,8 @@ cluster_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *pre,
struct iatt *post, dict_t *xdata)
{
- FOP_CBK (fallocate, frame, cookie, op_ret, op_errno, pre, post, xdata);
- return 0;
+ FOP_CBK(fallocate, frame, cookie, op_ret, op_errno, pre, post, xdata);
+ return 0;
}
int32_t
@@ -547,638 +523,739 @@ cluster_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *pre,
struct iatt *post, dict_t *xdata)
{
- FOP_CBK (discard, frame, cookie, op_ret, op_errno, pre, post, xdata);
- return 0;
+ FOP_CBK(discard, frame, cookie, op_ret, op_errno, pre, post, xdata);
+ return 0;
}
int32_t
cluster_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata)
{
- FOP_CBK (zerofill, frame, cookie, op_ret, op_errno, pre,
- post, xdata);
- return 0;
+ FOP_CBK(zerofill, frame, cookie, op_ret, op_errno, pre, post, xdata);
+ return 0;
}
-
int32_t
-cluster_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+cluster_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- FOP_CBK (ipc, frame, cookie, op_ret, op_errno, xdata);
- return 0;
+ FOP_CBK(ipc, frame, cookie, op_ret, op_errno, xdata);
+ return 0;
}
int32_t
-cluster_fgetxattr (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, fgetxattr, fd,
- name, xdata);
- return fop_success_fill (replies, numsubvols, output);
-}
-
-int32_t
-cluster_fsetxattr (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
+cluster_fgetxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, fsetxattr, fd,
- dict, flags, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fgetxattr, fd,
+ name, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_setxattr (xlator_t **subvols, unsigned char *on, int numsubvols,
+cluster_fsetxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
int32_t flags, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, setxattr, loc,
- dict, flags, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fsetxattr, fd,
+ dict, flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_statfs (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+cluster_setxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, statfs, loc,
- xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, setxattr, loc,
+ dict, flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_fsyncdir (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
- dict_t *xdata)
+cluster_statfs(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, fsyncdir, fd,
- flags, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, statfs, loc,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_opendir (xlator_t **subvols, unsigned char *on, int numsubvols,
+cluster_fsyncdir(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, opendir, loc,
- fd, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fsyncdir, fd,
+ flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_fstat (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+cluster_opendir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
+ dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, fstat, fd,
- xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, opendir, loc,
+ fd, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_fsync (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
- dict_t *xdata)
+cluster_fstat(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, fsync, fd,
- flags, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fstat, fd,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_flush (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+cluster_fsync(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
+ dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, flush, fd,
- xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fsync, fd,
+ flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_writev (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iovec *vector, int32_t count, off_t off, uint32_t flags,
- struct iobref *iobref, dict_t *xdata)
+cluster_flush(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, writev, fd,
- vector, count, off, flags, iobref, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, flush, fd,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_readv (xlator_t **subvols, unsigned char *on, int numsubvols,
+cluster_writev(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, readv, fd, size,
- offset, flags, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, writev, fd,
+ vector, count, off, flags, iobref, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
+int32_t
+cluster_put(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,
+ off_t offset, struct iobref *iobref, dict_t *xattr, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, put, loc, mode,
+ umask, flags, vector, count, offset, iobref, xattr, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
int32_t
-cluster_open (xlator_t **subvols, unsigned char *on, int numsubvols,
+cluster_readv(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+ call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, open, loc,
- flags, fd, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, readv, fd, size,
+ offset, flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_create (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+cluster_open(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, create, loc,
- flags, mode, umask, fd, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, open, loc,
+ flags, fd, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_link (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+cluster_create(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, link, oldloc,
- newloc, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, create, loc,
+ flags, mode, umask, fd, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_rename (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+cluster_link(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, rename, oldloc,
- newloc, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, link, oldloc,
+ newloc, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
+int32_t
+cluster_rename(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, rename, oldloc,
+ newloc, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
int
-cluster_symlink (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+cluster_symlink(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc, mode_t umask, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, symlink,
- linkpath, loc, umask, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, symlink,
+ linkpath, loc, umask, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_rmdir (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
+cluster_rmdir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, rmdir, loc,
- flags, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, rmdir, loc,
+ flags, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_unlink (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
+cluster_unlink(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
+ dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, unlink, loc,
- xflag, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, unlink, loc,
+ xflag, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int
-cluster_mkdir (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+cluster_mkdir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, mkdir, loc,
- mode, umask, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, mkdir, loc,
+ mode, umask, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
-
int
-cluster_mknod (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
+cluster_mknod(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, mode_t umask, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, mknod, loc,
- mode, rdev, umask, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, mknod, loc,
+ mode, rdev, umask, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_readlink (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
- dict_t *xdata)
+cluster_readlink(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
+ dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, readlink, loc,
- size, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, readlink, loc,
+ size, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
-
int32_t
-cluster_access (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
- dict_t *xdata)
+cluster_access(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
+ dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, access, loc,
- mask, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, access, loc,
+ mask, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_ftruncate (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+cluster_ftruncate(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, ftruncate, fd,
- offset, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, ftruncate, fd,
+ offset, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_getxattr (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+cluster_getxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, getxattr, loc,
- name, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, getxattr, loc,
+ name, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
+int32_t
+cluster_xattrop(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+{
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, xattrop, loc,
+ flags, dict, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
int32_t
-cluster_xattrop (xlator_t **subvols, unsigned char *on, int numsubvols,
+cluster_fxattrop(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, xattrop, loc,
- flags, dict, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fxattrop, fd,
+ flags, dict, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_fxattrop (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+cluster_removexattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, fxattrop, fd,
- flags, dict, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, removexattr,
+ loc, name, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_removexattr (xlator_t **subvols, unsigned char *on, int numsubvols,
+cluster_fremovexattr(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
const char *name, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, removexattr,
- loc, name, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fremovexattr,
+ fd, name, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_fremovexattr (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+cluster_lk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, fremovexattr,
- fd, name, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, lk, fd, cmd,
+ lock, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_lk (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+cluster_rchecksum(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ int32_t len, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, lk, fd, cmd,
- lock, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, rchecksum, fd,
+ offset, len, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
-
int32_t
-cluster_rchecksum (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- int32_t len, dict_t *xdata)
+cluster_readdir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t off, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, rchecksum, fd,
- offset, len, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, readdir, fd,
+ size, off, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
-
int32_t
-cluster_readdir (xlator_t **subvols, unsigned char *on, int numsubvols,
+cluster_readdirp(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off, dict_t *xdata)
+ call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t off, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, readdir, fd,
- size, off, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, readdirp, fd,
+ size, off, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
-
int32_t
-cluster_readdirp (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off, dict_t *xdata)
+cluster_setattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, readdirp, fd,
- size, off, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, setattr, loc,
+ stbuf, valid, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_setattr (xlator_t **subvols, unsigned char *on, int numsubvols,
+cluster_truncate(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
+ dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, setattr, loc,
- stbuf, valid, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, truncate, loc,
+ offset, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_truncate (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+cluster_stat(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, truncate, loc,
- offset, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, stat, loc,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_stat (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+cluster_lookup(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, stat, loc,
- xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, lookup, loc,
+ xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_lookup (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+cluster_fsetattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, lookup, loc,
- xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fsetattr, fd,
+ stbuf, valid, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_fsetattr (xlator_t **subvols, unsigned char *on, int numsubvols,
+cluster_fallocate(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, fsetattr, fd,
- stbuf, valid, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fallocate, fd,
+ keep_size, offset, len, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
-cluster_fallocate (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
-{
- FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, fallocate, fd,
- keep_size, offset, len, xdata);
- return fop_success_fill (replies, numsubvols, output);
-}
-
-int32_t
-cluster_discard (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, size_t len, dict_t *xdata)
+cluster_discard(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata)
{
- FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, discard, fd,
- offset, len, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, discard, fd,
+ offset, len, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int32_t
cluster_zerofill(xlator_t **subvols, unsigned char *on, int numsubvols,
default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, off_t len, dict_t *xdata)
+ call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ off_t len, dict_t *xdata)
{
- FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, zerofill, fd,
- offset, len, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, zerofill, fd,
+ offset, len, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
-
int32_t
-cluster_ipc (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)
+cluster_ipc(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)
{
- FOP_ONLIST (subvols, on, numsubvols, replies, output, frame, ipc, op, xdata);
- return fop_success_fill (replies, numsubvols, output);
+ FOP_ONLIST(subvols, on, numsubvols, replies, output, frame, ipc, op, xdata);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int
-cluster_uninodelk (xlator_t **subvols, unsigned char *locked_on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, off_t off, size_t size)
+cluster_uninodelk(xlator_t **subvols, unsigned char *locked_on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, off_t off, size_t size)
{
- loc_t loc = {0,};
- struct gf_flock flock = {0, };
+ loc_t loc = {
+ 0,
+ };
+ struct gf_flock flock = {
+ 0,
+ };
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
- loc.inode = inode_ref (inode);
- gf_uuid_copy (loc.gfid, inode->gfid);
+ flock.l_type = F_UNLCK;
+ flock.l_start = off;
+ flock.l_len = size;
- flock.l_type = F_UNLCK;
- flock.l_start = off;
- flock.l_len = size;
+ FOP_ONLIST(subvols, locked_on, numsubvols, replies, output, frame, inodelk,
+ dom, &loc, F_SETLK, &flock, NULL);
- FOP_ONLIST (subvols, locked_on, numsubvols, replies, output, frame, inodelk,
- dom, &loc, F_SETLK, &flock, NULL);
+ loc_wipe(&loc);
- loc_wipe (&loc);
-
- return fop_success_fill (replies, numsubvols, output);
+ return cluster_fop_success_fill(replies, numsubvols, output);
}
int
-cluster_tryinodelk (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *locked_on,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, off_t off, size_t size)
+cluster_tryinodelk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, off_t off, size_t size)
{
- struct gf_flock flock = {0, };
- loc_t loc = {0};
+ struct gf_flock flock = {
+ 0,
+ };
+ loc_t loc = {0};
- flock.l_type = F_WRLCK;
- flock.l_start = off;
- flock.l_len = size;
+ flock.l_type = F_WRLCK;
+ flock.l_start = off;
+ flock.l_len = size;
- loc.inode = inode_ref (inode);
- gf_uuid_copy (loc.gfid, inode->gfid);
- FOP_ONLIST (subvols, on, numsubvols, replies, locked_on, frame, inodelk, dom,
- &loc, F_SETLK, &flock, NULL);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, inodelk, dom,
+ &loc, F_SETLK, &flock, NULL);
- loc_wipe (&loc);
- return fop_success_fill (replies, numsubvols, locked_on);
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
}
int
-cluster_inodelk (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *locked_on,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, off_t off, size_t size)
-{
- struct gf_flock flock = {0, };
- int i = 0;
- loc_t loc = {0};
- unsigned char *output = NULL;
-
- flock.l_type = F_WRLCK;
- flock.l_start = off;
- flock.l_len = size;
-
- output = alloca(numsubvols);
- loc.inode = inode_ref (inode);
- gf_uuid_copy (loc.gfid, inode->gfid);
- FOP_ONLIST (subvols, on, numsubvols, replies, locked_on, frame,
- inodelk, dom, &loc, F_SETLK, &flock, NULL);
-
- for (i = 0; i < numsubvols; i++) {
- if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
- fop_success_fill (replies, numsubvols, locked_on);
- cluster_uninodelk (subvols, locked_on, numsubvols,
- replies, output, frame, this, dom, inode, off, size);
-
- FOP_SEQ (subvols, on, numsubvols, replies, locked_on,
- frame, inodelk, dom, &loc, F_SETLKW, &flock,
- NULL);
- break;
- }
+cluster_inodelk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom, inode_t *inode,
+ off_t off, size_t size)
+{
+ struct gf_flock flock = {
+ 0,
+ };
+ int i = 0;
+ loc_t loc = {0};
+ unsigned char *output = NULL;
+
+ flock.l_type = F_WRLCK;
+ flock.l_start = off;
+ flock.l_len = size;
+
+ output = alloca(numsubvols);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, inodelk, dom,
+ &loc, F_SETLK, &flock, NULL);
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
+ cluster_fop_success_fill(replies, numsubvols, locked_on);
+ cluster_uninodelk(subvols, locked_on, numsubvols, replies, output,
+ frame, this, dom, inode, off, size);
+
+ FOP_SEQ(subvols, on, numsubvols, replies, locked_on, frame, inodelk,
+ dom, &loc, F_SETLKW, &flock, NULL);
+ break;
}
+ }
- loc_wipe (&loc);
- return fop_success_fill (replies, numsubvols, locked_on);
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
}
+int
+cluster_unentrylk(xlator_t **subvols, unsigned char *locked_on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, const char *name)
+{
+ loc_t loc = {
+ 0,
+ };
+
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+
+ FOP_ONLIST(subvols, locked_on, numsubvols, replies, output, frame, entrylk,
+ dom, &loc, name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL);
+
+ loc_wipe(&loc);
+
+ return cluster_fop_success_fill(replies, numsubvols, output);
+}
int
-cluster_unentrylk (xlator_t **subvols, unsigned char *locked_on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
+cluster_tryentrylk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
call_frame_t *frame, xlator_t *this, char *dom,
inode_t *inode, const char *name)
{
- loc_t loc = {0,};
-
+ loc_t loc = {0};
- loc.inode = inode_ref (inode);
- gf_uuid_copy (loc.gfid, inode->gfid);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, entrylk, dom,
+ &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL);
- FOP_ONLIST (subvols, locked_on, numsubvols, replies, output, frame,
- entrylk, dom, &loc, name, ENTRYLK_UNLOCK, ENTRYLK_WRLCK,
- NULL);
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
+}
- loc_wipe (&loc);
+int
+cluster_entrylk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom, inode_t *inode,
+ const char *name)
+{
+ int i = 0;
+ loc_t loc = {0};
+ unsigned char *output = NULL;
+
+ output = alloca(numsubvols);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, entrylk, dom,
+ &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL);
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
+ cluster_fop_success_fill(replies, numsubvols, locked_on);
+ cluster_unentrylk(subvols, locked_on, numsubvols, replies, output,
+ frame, this, dom, inode, name);
+ FOP_SEQ(subvols, on, numsubvols, replies, locked_on, frame, entrylk,
+ dom, &loc, name, ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
+ break;
+ }
+ }
- return fop_success_fill (replies, numsubvols, output);
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
}
int
-cluster_tryentrylk (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *locked_on,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, const char *name)
-{
- loc_t loc = {0};
+cluster_tiebreaker_inodelk(xlator_t **subvols, unsigned char *on,
+ int numsubvols, default_args_cbk_t *replies,
+ unsigned char *locked_on, call_frame_t *frame,
+ xlator_t *this, char *dom, inode_t *inode, off_t off,
+ size_t size)
+{
+ struct gf_flock flock = {
+ 0,
+ };
+ int i = 0;
+ int num_success = 0;
+ loc_t loc = {0};
+ unsigned char *output = NULL;
+
+ flock.l_type = F_WRLCK;
+ flock.l_start = off;
+ flock.l_len = size;
+
+ output = alloca(numsubvols);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, inodelk, dom,
+ &loc, F_SETLK, &flock, NULL);
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].valid && replies[i].op_ret == 0) {
+ num_success++;
+ continue;
+ }
- loc.inode = inode_ref (inode);
- gf_uuid_copy (loc.gfid, inode->gfid);
- FOP_ONLIST (subvols, on, numsubvols, replies, locked_on, frame,
- entrylk, dom, &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK,
- NULL);
+ /* TODO: If earlier subvols fail with an error other
+ * than EAGAIN, we could still have 2 clients competing
+ * for the lock*/
+ if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
+ cluster_fop_success_fill(replies, numsubvols, locked_on);
+ cluster_uninodelk(subvols, locked_on, numsubvols, replies, output,
+ frame, this, dom, inode, off, size);
+
+ if (num_success) {
+ FOP_SEQ(subvols, on, numsubvols, replies, locked_on, frame,
+ inodelk, dom, &loc, F_SETLKW, &flock, NULL);
+ } else {
+ loc_wipe(&loc);
+ memset(locked_on, 0, numsubvols);
+ return 0;
+ }
+ break;
+ }
+ }
- loc_wipe (&loc);
- return fop_success_fill (replies, numsubvols, locked_on);
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
}
int
-cluster_entrylk (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *locked_on,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, const char *name)
-{
- int i = 0;
- loc_t loc = {0};
- unsigned char *output = NULL;
-
- output = alloca(numsubvols);
- loc.inode = inode_ref (inode);
- gf_uuid_copy (loc.gfid, inode->gfid);
- FOP_ONLIST (subvols, on, numsubvols, replies, locked_on, frame,
- entrylk, dom, &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK,
- NULL);
-
- for (i = 0; i < numsubvols; i++) {
- if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
- fop_success_fill (replies, numsubvols, locked_on);
- cluster_unentrylk (subvols, locked_on, numsubvols,
- replies, output, frame, this, dom,
- inode, name);
- FOP_SEQ (subvols, on, numsubvols, replies,
- locked_on, frame, entrylk, dom, &loc, name,
- ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
- break;
- }
+cluster_tiebreaker_entrylk(xlator_t **subvols, unsigned char *on,
+ int numsubvols, default_args_cbk_t *replies,
+ unsigned char *locked_on, call_frame_t *frame,
+ xlator_t *this, char *dom, inode_t *inode,
+ const char *name)
+{
+ int i = 0;
+ loc_t loc = {0};
+ unsigned char *output = NULL;
+ int num_success = 0;
+
+ output = alloca(numsubvols);
+ loc.inode = inode_ref(inode);
+ gf_uuid_copy(loc.gfid, inode->gfid);
+ FOP_ONLIST(subvols, on, numsubvols, replies, locked_on, frame, entrylk, dom,
+ &loc, name, ENTRYLK_LOCK_NB, ENTRYLK_WRLCK, NULL);
+
+ for (i = 0; i < numsubvols; i++) {
+ if (replies[i].valid && replies[i].op_ret == 0) {
+ num_success++;
+ continue;
+ }
+ if (replies[i].op_ret == -1 && replies[i].op_errno == EAGAIN) {
+ cluster_fop_success_fill(replies, numsubvols, locked_on);
+ cluster_unentrylk(subvols, locked_on, numsubvols, replies, output,
+ frame, this, dom, inode, name);
+ if (num_success) {
+ FOP_SEQ(subvols, on, numsubvols, replies, locked_on, frame,
+ entrylk, dom, &loc, name, ENTRYLK_LOCK, ENTRYLK_WRLCK,
+ NULL);
+ } else {
+ loc_wipe(&loc);
+ memset(locked_on, 0, numsubvols);
+ return 0;
+ }
+ break;
}
+ }
- loc_wipe (&loc);
- return fop_success_fill (replies, numsubvols, locked_on);
+ loc_wipe(&loc);
+ return cluster_fop_success_fill(replies, numsubvols, locked_on);
}
diff --git a/libglusterfs/src/cluster-syncop.h b/libglusterfs/src/cluster-syncop.h
deleted file mode 100644
index 3712259c65b..00000000000
--- a/libglusterfs/src/cluster-syncop.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- Copyright (c) 2015 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 _CLUSTER_SYNCOP_H
-#define _CLUSTER_SYNCOP_H
-
-#include "xlator.h"
-#include <sys/time.h>
-#include <pthread.h>
-#include <ucontext.h>
-#include "defaults.h"
-#include "syncop.h"
-
-typedef struct cluster_local_ {
- default_args_cbk_t *replies;
- syncbarrier_t barrier;
-} cluster_local_t;
-
-int32_t
-cluster_lookup (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata);
-int32_t
-cluster_setattr (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata);
-int32_t
-cluster_getxattr (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata);
-int32_t
-cluster_setxattr (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata);
-
-int
-cluster_inodelk (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *locked_on,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, off_t off, size_t size);
-
-int
-cluster_uninodelk (xlator_t **subvols, unsigned char *locked_on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, off_t off, size_t size);
-
-int
-cluster_entrylk (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *locked_on,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, const char *name);
-
-int32_t
-cluster_rmdir (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata);
-
-int32_t
-cluster_unlink (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata);
-
-int
-cluster_mkdir (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata);
-
-int32_t
-cluster_readlink (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
- dict_t *xdata);
-
-int
-cluster_symlink (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata);
-
-int32_t
-cluster_link (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata);
-
-int
-cluster_mknod (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata);
-
-int
-cluster_unentrylk (xlator_t **subvols, unsigned char *locked_on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, const char *name);
-
-int
-cluster_tryentrylk (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *locked_on,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, const char *name);
-
-int32_t
-cluster_fxattrop (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata);
-
-int32_t
-cluster_fstat (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata);
-
-int32_t
-cluster_ftruncate (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata);
-
-int32_t
-cluster_open (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata);
-
-int
-cluster_tryinodelk (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *locked_on,
- call_frame_t *frame, xlator_t *this, char *dom,
- inode_t *inode, off_t off, size_t size);
-
-int32_t
-cluster_fsetattr (xlator_t **subvols, unsigned char *on, int numsubvols,
- default_args_cbk_t *replies, unsigned char *output,
- call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata);
-
-void
-cluster_replies_wipe (default_args_cbk_t *replies, int num_subvols);
-#endif /* !_CLUSTER_SYNCOP_H */
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 303ee665440..682cbf28055 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -24,152 +24,377 @@
#include <time.h>
#include <locale.h>
#include <sys/socket.h>
-#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <assert.h>
#include <libgen.h> /* for dirname() */
+#include <grp.h>
#if defined(GF_BSD_HOST_OS) || defined(GF_DARWIN_HOST_OS)
#include <sys/sysctl.h>
#endif
+#ifndef GF_LINUX_HOST_OS
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_SYNCFS_SYS
+#include <sys/syscall.h>
+#endif
-#include "compat-errno.h"
-#include "logging.h"
-#include "common-utils.h"
-#include "revision.h"
-#include "glusterfs.h"
-#include "stack.h"
-#include "globals.h"
-#include "lkowner.h"
-#include "syscall.h"
+#include "glusterfs/compat-errno.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/revision.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/stack.h"
+#include "glusterfs/lkowner.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/globals.h"
+#define XXH_INLINE_ALL
+#include "xxhash.h"
#include <ifaddrs.h>
-#include "libglusterfs-messages.h"
+#include "glusterfs/libglusterfs-messages.h"
+#include "glusterfs/glusterfs-acl.h"
+#ifdef __FreeBSD__
+#include <pthread_np.h>
+#undef BIT_SET
+#endif
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0
#endif /* AI_ADDRCONFIG */
+char *vol_type_str[] = {
+ "Distribute",
+ "Stripe [NOT SUPPORTED from v6.0]",
+ "Replicate",
+ "Striped-Replicate [NOT SUPPORTED from v6.0]",
+ "Disperse",
+ "Tier [NOT SUPPORTED from v6.0]",
+ "Distributed-Stripe [NOT SUPPORTED from v6.0]",
+ "Distributed-Replicate",
+ "Distributed-Striped-Replicate [NOT SUPPORTED from v6.0]",
+ "Distributed-Disperse",
+};
+
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);
-struct dnscache6 {
- struct addrinfo *first;
- struct addrinfo *next;
-};
+char *xattrs_to_heal[] = {"user.",
+ POSIX_ACL_ACCESS_XATTR,
+ POSIX_ACL_DEFAULT_XATTR,
+ QUOTA_LIMIT_KEY,
+ QUOTA_LIMIT_OBJECTS_KEY,
+ GF_SELINUX_XATTR_KEY,
+ GF_XATTR_MDATA_KEY,
+ NULL};
void
-md5_wrapper(const unsigned char *data, size_t len, char *md5)
+gf_xxh64_wrapper(const unsigned char *data, size_t const len,
+ unsigned long long const seed, char *xxh64)
{
- unsigned short i = 0;
- unsigned short lim = MD5_DIGEST_LENGTH*2+1;
- unsigned char scratch[MD5_DIGEST_LENGTH] = {0,};
- MD5(data, len, scratch);
- for (; i < MD5_DIGEST_LENGTH; i++)
- snprintf(md5 + i * 2, lim-i*2, "%02x", scratch[i]);
+ unsigned short i = 0;
+ const unsigned short lim = GF_XXH64_DIGEST_LENGTH * 2 + 1;
+ XXH64_hash_t hash = 0;
+ XXH64_canonical_t c_hash = {
+ {
+ 0,
+ },
+ };
+ const uint8_t *p = (const uint8_t *)&c_hash;
+
+ hash = XXH64(data, len, seed);
+ XXH64_canonicalFromHash(&c_hash, hash);
+
+ for (i = 0; i < GF_XXH64_DIGEST_LENGTH; i++)
+ snprintf(xxh64 + i * 2, lim - i * 2, "%02x", p[i]);
+}
+
+/**
+ * This function takes following arguments
+ * @this: xlator
+ * @gfid: The gfid which has to be filled
+ * @hash: the 8 byte hash which has to be filled inside the gfid
+ * @index: the array element of the uuid_t structure (which is
+ * a array of unsigned char) from where the 8 bytes of
+ * the hash has to be filled. Since uuid_t contains 16
+ * char elements in the array, each byte of the hash has
+ * to be filled in one array element.
+ *
+ * This function is called twice for 2 hashes (of 8 byte each) to
+ * be filled in the gfid.
+ *
+ * The for loop in this function actually is doing these 2 things
+ * for each hash
+ *
+ * 1) One of the hashes
+ * tmp[0] = (hash_2 >> 56) & 0xff;
+ * tmp[1] = (hash_2 >> 48) & 0xff;
+ * tmp[2] = (hash_2 >> 40) & 0xff;
+ * tmp[3] = (hash_2 >> 32) & 0xff;
+ * tmp[4] = (hash_2 >> 24) & 0xff;
+ * tmp[5] = (hash_2 >> 16) & 0xff;
+ * tmp[6] = (hash_2 >> 8) & 0xff;
+ * tmp[7] = (hash_2) & 0xff;
+ *
+ * 2) The other hash:
+ * tmp[8] = (hash_1 >> 56) & 0xff;
+ * tmp[9] = (hash_1 >> 48) & 0xff;
+ * tmp[10] = (hash_1 >> 40) & 0xff;
+ * tmp[11] = (hash_1 >> 32) & 0xff;
+ * tmp[12] = (hash_1 >> 24) & 0xff;
+ * tmp[13] = (hash_1 >> 16) & 0xff;
+ * tmp[14] = (hash_1 >> 8) & 0xff;
+ * tmp[15] = (hash_1) & 0xff;
+ **/
+static int
+gf_gfid_from_xxh64(xlator_t *this, uuid_t gfid, XXH64_hash_t hash,
+ unsigned short index)
+{
+ int ret = -1;
+ int i = -1;
+
+ if ((index != 0) && (index != 8)) {
+ gf_msg_callingfn("gfid-from-xxh64", GF_LOG_WARNING, 0,
+ LG_MSG_INDEX_NOT_FOUND,
+ "index can only be either 0 or 8, as this"
+ "function's purpose is to encode a 8 byte "
+ "hash inside the gfid (index: %d)",
+ index);
+ goto out;
+ }
+
+ for (i = 0; i < sizeof(hash); i++) {
+ /*
+ * As of now the below statement is equivalent of this.
+ * gfid[index+i] = (hash >> (64 - (8 * (i+1)))) & 0xff;
+ */
+ gfid[index + i] = (hash >> ((sizeof(hash) * 8) - (8 * (i + 1)))) &
+ (0xff);
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+/**
+ * This function does the same thing as gf_xxh64_wrapper. But gf_xxh64_wrapper
+ * does not return anything and in this xlator there is a need for both the
+ * actual hash and the canonicalized form of the hash.
+ *
+ * To summarize:
+ * - XXH64_hash_t is needed as return because, those bytes which contain the
+ * hash can be used for different purposes as needed. One example is
+ * to have those bytes copied into the uuid_t structure to be used as gfid
+ * - xxh64 string is needed because, it can be used as the key for generating
+ * the next hash (and any other purpose which might require canonical form
+ * of the hash).
+ **/
+XXH64_hash_t
+gf_xxh64_hash_wrapper(const unsigned char *data, size_t const len,
+ unsigned long long const seed, char *xxh64)
+{
+ unsigned short i = 0;
+ const unsigned short lim = GF_XXH64_DIGEST_LENGTH * 2 + 1;
+ XXH64_hash_t hash = 0;
+ XXH64_canonical_t c_hash = {
+ {
+ 0,
+ },
+ };
+ const uint8_t *p = (const uint8_t *)&c_hash;
+
+ hash = XXH64(data, len, seed);
+ XXH64_canonicalFromHash(&c_hash, hash);
+
+ for (i = 0; i < GF_XXH64_DIGEST_LENGTH; i++)
+ snprintf(xxh64 + i * 2, lim - i * 2, "%02x", p[i]);
+
+ return hash;
+}
+
+/**
+ * This is the algorithm followed for generating new gfid
+ * 1) generate xxh64 hash using snapname and original gfid of the object
+ * 2) Using the canonicalized form of above hash as the key, generate
+ * another hash
+ * 3) Combine both of the 8 byte hashes to generate a 16 byte uuid_t type
+ * 4) Use the above uuid as the gfid
+ *
+ * Each byte of the hash is stored separately in different elements of the
+ * character array represented by uuid_t
+ * Ex: tmp[0] = (hash_2 >> 56) & 0xFF
+ * This saves the most significant byte of hash_2 in tmp[0]
+ * tmp[1] = (hash_2 >> 48) & 0xFF
+ * This saves next most significant byte of hash_2 in tmp[1]
+ * .
+ * .
+ * So on.
+ * tmp[0] - tmp[7] holds the contents of hash_2
+ * tmp[8] - tmp[15] hold the conents of hash_1
+ *
+ * The hash generated (i.e. of type XXH64_hash_t) is 8 bytes long. And for
+ * gfid 16 byte uuid is needed. Hecne the 2 hashes are combined to form
+ * one 16 byte entity.
+ **/
+int
+gf_gfid_generate_from_xxh64(uuid_t gfid, char *key)
+{
+ char xxh64_1[GF_XXH64_DIGEST_LENGTH * 2 + 1] = {
+ 0,
+ };
+ char xxh64_2[GF_XXH64_DIGEST_LENGTH * 2 + 1] = {
+ 0,
+ };
+ XXH64_hash_t hash_1 = 0;
+ XXH64_hash_t hash_2 = 0;
+ int ret = -1;
+ xlator_t *this = THIS;
+
+ hash_1 = gf_xxh64_hash_wrapper((unsigned char *)key, strlen(key),
+ GF_XXHSUM64_DEFAULT_SEED, xxh64_1);
+
+ hash_2 = gf_xxh64_hash_wrapper((unsigned char *)xxh64_1, strlen(xxh64_1),
+ GF_XXHSUM64_DEFAULT_SEED, xxh64_2);
+
+ /* hash_2 is saved in 1st 8 elements of uuid_t char array */
+ if (gf_gfid_from_xxh64(this, gfid, hash_2, 0)) {
+ gf_msg_callingfn(this->name, GF_LOG_WARNING, 0,
+ LG_MSG_XXH64_TO_GFID_FAILED,
+ "failed to encode the hash %llx into the 1st"
+ "half of gfid",
+ hash_2);
+ goto out;
+ }
+
+ /* hash_1 is saved in the remaining 8 elements of uuid_t */
+ if (gf_gfid_from_xxh64(this, gfid, hash_1, 8)) {
+ gf_msg_callingfn(this->name, GF_LOG_WARNING, 0,
+ LG_MSG_XXH64_TO_GFID_FAILED,
+ "failed to encode the hash %llx into the 2nd"
+ "half of gfid",
+ hash_1);
+ goto out;
+ }
+
+ gf_msg_debug(this->name, 0,
+ "gfid generated is %s (hash1: %llx) "
+ "hash2: %llx, xxh64_1: %s xxh64_2: %s",
+ uuid_utoa(gfid), hash_1, hash_2, xxh64_1, xxh64_2);
+
+ ret = 0;
+
+out:
+ return ret;
}
/* works similar to mkdir(1) -p.
*/
int
-mkdir_p (char *path, mode_t mode, gf_boolean_t allow_symlinks)
-{
- int i = 0;
- int ret = -1;
- char dir[PATH_MAX] = {0,};
- struct stat stbuf = {0,};
-
- strncpy (dir, path, (PATH_MAX - 1));
- dir[PATH_MAX - 1] = '\0';
-
- i = (dir[0] == '/')? 1: 0;
- do {
- if (path[i] != '/' && path[i] != '\0')
- continue;
-
- dir[i] = '\0';
- ret = mkdir (dir, mode);
- if (ret && errno != EEXIST) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
- "Failed due to reason");
- goto out;
- }
-
- if (ret && errno == EEXIST && !allow_symlinks) {
- ret = lstat (dir, &stbuf);
- if (ret)
- goto out;
-
- if (S_ISLNK (stbuf.st_mode)) {
- ret = -1;
- gf_msg ("", GF_LOG_ERROR, 0,
- LG_MSG_DIR_IS_SYMLINK, "%s is a "
- "symlink", dir);
- goto out;
- }
- }
- dir[i] = '/';
-
- } while (path[i++] != '\0');
-
- ret = stat (dir, &stbuf);
- if (ret || !S_ISDIR (stbuf.st_mode)) {
- if (ret == 0)
- errno = 0;
+mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks)
+{
+ int i = 0;
+ int ret = -1;
+ char dir[PATH_MAX] = {
+ 0,
+ };
+ struct stat stbuf = {
+ 0,
+ };
+
+ const int path_len = min(strlen(path), PATH_MAX - 1);
+
+ snprintf(dir, path_len + 1, "%s", path);
+
+ i = (dir[0] == '/') ? 1 : 0;
+ do {
+ if (path[i] != '/' && path[i] != '\0')
+ continue;
+
+ dir[i] = '\0';
+ ret = sys_mkdir(dir, mode);
+ if (ret && errno != EEXIST) {
+ gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, NULL);
+ goto out;
+ }
+
+ if (ret && errno == EEXIST && !allow_symlinks) {
+ ret = sys_lstat(dir, &stbuf);
+ if (ret)
+ goto out;
+
+ if (S_ISLNK(stbuf.st_mode)) {
ret = -1;
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, "Failed"
- " to create directory, possibly some of the components"
- " were not directories");
+ gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_DIR_IS_SYMLINK, "dir=%s",
+ dir, NULL);
goto out;
+ }
}
+ dir[i] = '/';
- ret = 0;
+ } while (path[i++] != '\0');
+
+ ret = sys_stat(dir, &stbuf);
+ if (ret || !S_ISDIR(stbuf.st_mode)) {
+ if (ret == 0)
+ errno = 0;
+ ret = -1;
+ gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
+ "possibly some of the components"
+ " were not directories",
+ NULL);
+ goto out;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
-gf_lstat_dir (const char *path, struct stat *stbuf_in)
+gf_lstat_dir(const char *path, struct stat *stbuf_in)
{
- int ret = -1;
- struct stat stbuf = {0,};
+ int ret = -1;
+ struct stat stbuf = {
+ 0,
+ };
- if (path == NULL) {
- errno = EINVAL;
- goto out;
- }
+ if (path == NULL) {
+ errno = EINVAL;
+ goto out;
+ }
- ret = sys_lstat (path, &stbuf);
- if (ret)
- goto out;
+ ret = sys_lstat(path, &stbuf);
+ if (ret)
+ goto out;
- if (!S_ISDIR (stbuf.st_mode)) {
- errno = ENOTDIR;
- ret = -1;
- goto out;
- }
- ret = 0;
+ if (!S_ISDIR(stbuf.st_mode)) {
+ errno = ENOTDIR;
+ ret = -1;
+ goto out;
+ }
+ ret = 0;
out:
- if (!ret && stbuf_in)
- *stbuf_in = stbuf;
+ if (!ret && stbuf_in)
+ *stbuf_in = stbuf;
- return ret;
+ return ret;
}
int
-log_base2 (unsigned long x)
+log_base2(unsigned long x)
{
- int val = 0;
+ int val = 0;
- while (x > 1) {
- x /= 2;
- val++;
- }
+ while (x > 1) {
+ x /= 2;
+ val++;
+ }
- return val;
+ return val;
}
/**
@@ -181,1632 +406,1725 @@ log_base2 (unsigned long x)
* failure: NULL
*/
char *
-gf_rev_dns_lookup (const char *ip)
+gf_rev_dns_lookup(const char *ip)
{
- char *fqdn = NULL;
- int ret = 0;
- struct sockaddr_in sa = {0};
- char host_addr[256] = {0, };
+ char *fqdn = NULL;
+ int ret = 0;
- GF_VALIDATE_OR_GOTO ("resolver", ip, out);
-
- sa.sin_family = AF_INET;
- inet_pton (AF_INET, ip, &sa.sin_addr);
- ret = getnameinfo ((struct sockaddr *)&sa, sizeof (sa), host_addr,
- sizeof (host_addr), NULL, 0, 0);
-
- if (ret != 0) {
- gf_msg ("resolver", GF_LOG_INFO, errno,
- LG_MSG_RESOLVE_HOSTNAME_FAILED, "could not resolve "
- "hostname for %s", ip);
- goto out;
- }
-
- /* Get the FQDN */
- fqdn = gf_strdup (host_addr);
+ GF_VALIDATE_OR_GOTO("resolver", ip, out);
+ /* Get the FQDN */
+ ret = gf_get_hostname_from_ip((char *)ip, &fqdn);
+ if (ret != 0) {
+ gf_smsg("resolver", GF_LOG_INFO, errno, LG_MSG_RESOLVE_HOSTNAME_FAILED,
+ "hostname=%s", ip, NULL);
+ }
out:
- return fqdn;
+ return fqdn;
}
/**
- * gf_resolve_parent_path -- Given a path, returns an allocated string
+ * gf_resolve_path_parent -- Given a path, returns an allocated string
* containing the parent's path.
* @path: Path to parse
* @return: The parent path if found, NULL otherwise
*/
char *
-gf_resolve_path_parent (const char *path)
+gf_resolve_path_parent(const char *path)
{
- char *parent = NULL;
- char *tmp = NULL;
- char *pathc = NULL;
+ char *parent = NULL;
+ char *tmp = NULL;
+ char *pathc = NULL;
- GF_VALIDATE_OR_GOTO (THIS->name, path, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, path, out);
- if (strlen (path) <= 0) {
- gf_msg_callingfn (THIS->name, GF_LOG_DEBUG, 0,
- LG_MSG_INVALID_STRING,
- "invalid string for 'path'");
- goto out;
- }
+ if (0 == strlen(path)) {
+ gf_msg_callingfn(THIS->name, GF_LOG_DEBUG, 0, LG_MSG_INVALID_STRING,
+ "invalid string for 'path'");
+ goto out;
+ }
- /* dup the parameter, we don't want to modify it */
- pathc = strdupa (path);
- if (!pathc) {
- goto out;
- }
+ /* dup the parameter, we don't want to modify it */
+ pathc = strdupa(path);
+ if (!pathc) {
+ goto out;
+ }
- /* Get the parent directory */
- tmp = dirname (pathc);
- if (strcmp (tmp, "/") == 0)
- goto out;
+ /* Get the parent directory */
+ tmp = dirname(pathc);
+ if (strcmp(tmp, "/") == 0)
+ goto out;
- parent = gf_strdup (tmp);
+ parent = gf_strdup(tmp);
out:
- return parent;
+ return parent;
}
int32_t
-gf_resolve_ip6 (const char *hostname,
- uint16_t port,
- int family,
- void **dnscache,
- struct addrinfo **addr_info)
-{
- int32_t ret = 0;
- struct addrinfo hints;
- struct dnscache6 *cache = NULL;
- char service[NI_MAXSERV], host[NI_MAXHOST];
-
- if (!hostname) {
- gf_msg_callingfn ("resolver", GF_LOG_WARNING, 0,
- LG_MSG_HOSTNAME_NULL, "hostname is NULL");
- return -1;
- }
+gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache,
+ struct addrinfo **addr_info)
+{
+ int32_t ret = 0;
+ struct addrinfo hints;
+ struct dnscache6 *cache = NULL;
+ char service[NI_MAXSERV], host[NI_MAXHOST];
- if (!*dnscache) {
- *dnscache = GF_CALLOC (1, sizeof (struct dnscache6),
- gf_common_mt_dnscache6);
- if (!*dnscache)
- return -1;
+ if (!hostname) {
+ gf_msg_callingfn("resolver", GF_LOG_WARNING, 0, LG_MSG_HOSTNAME_NULL,
+ "hostname is NULL");
+ return -1;
+ }
+
+ if (!*dnscache) {
+ *dnscache = GF_CALLOC(1, sizeof(struct dnscache6),
+ gf_common_mt_dnscache6);
+ if (!*dnscache)
+ return -1;
+ }
+
+ cache = *dnscache;
+ if (cache->first && !cache->next) {
+ freeaddrinfo(cache->first);
+ cache->first = cache->next = NULL;
+ gf_msg_trace("resolver", 0, "flushing DNS cache");
+ }
+
+ if (!cache->first) {
+ char *port_str = NULL;
+ gf_msg_trace("resolver", 0,
+ "DNS cache not present, freshly "
+ "probing hostname: %s",
+ hostname);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+
+ ret = gf_asprintf(&port_str, "%d", port);
+ if (-1 == ret) {
+ return -1;
+ }
+ if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) !=
+ 0) {
+ gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED,
+ "family=%d", family, "ret=%s", gai_strerror(ret), NULL);
+
+ GF_FREE(*dnscache);
+ *dnscache = NULL;
+ GF_FREE(port_str);
+ return -1;
+ }
+ GF_FREE(port_str);
+
+ cache->next = cache->first;
+ }
+
+ if (cache->next) {
+ ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
+ cache->next->ai_addrlen, host, sizeof(host), service,
+ sizeof(service), NI_NUMERICHOST);
+ if (ret != 0) {
+ gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED,
+ "ret=%s", gai_strerror(ret), NULL);
+ goto err;
}
- cache = *dnscache;
- if (cache->first && !cache->next) {
- freeaddrinfo(cache->first);
- cache->first = cache->next = NULL;
- gf_msg_trace ("resolver", 0, "flushing DNS cache");
+ gf_msg_debug("resolver", 0,
+ "returning ip-%s (port-%s) for "
+ "hostname: %s and port: %d",
+ host, service, hostname, port);
+
+ *addr_info = cache->next;
+ }
+
+ if (cache->next)
+ cache->next = cache->next->ai_next;
+ if (cache->next) {
+ ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
+ cache->next->ai_addrlen, host, sizeof(host), service,
+ sizeof(service), NI_NUMERICHOST);
+ if (ret != 0) {
+ gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED,
+ "ret=%s", gai_strerror(ret), NULL);
+ goto err;
}
- if (!cache->first) {
- char *port_str = NULL;
- gf_msg_trace ("resolver", 0, "DNS cache not present, freshly "
- "probing hostname: %s", hostname);
+ gf_msg_debug("resolver", 0,
+ "next DNS query will return: "
+ "ip-%s port-%s",
+ host, service);
+ }
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = family;
- hints.ai_socktype = SOCK_STREAM;
-#ifndef __NetBSD__
- hints.ai_flags = AI_ADDRCONFIG;
-#endif
+ return 0;
- ret = gf_asprintf (&port_str, "%d", port);
- if (-1 == ret) {
- return -1;
- }
- if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) != 0) {
- gf_msg ("resolver", GF_LOG_ERROR, 0,
- LG_MSG_GETADDRINFO_FAILED, "getaddrinfo failed"
- " (%s)", gai_strerror (ret));
-
- GF_FREE (*dnscache);
- *dnscache = NULL;
- GF_FREE (port_str);
- return -1;
- }
- GF_FREE (port_str);
-
- cache->next = cache->first;
- }
+err:
+ freeaddrinfo(cache->first);
+ cache->first = cache->next = NULL;
+ GF_FREE(cache);
+ *dnscache = NULL;
+ return -1;
+}
- if (cache->next) {
- ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
- cache->next->ai_addrlen,
- host, sizeof (host),
- service, sizeof (service),
- NI_NUMERICHOST);
- if (ret != 0) {
- gf_msg ("resolver", GF_LOG_ERROR, 0,
- LG_MSG_GETNAMEINFO_FAILED, "getnameinfo failed"
- " (%s)", gai_strerror (ret));
- goto err;
- }
-
- gf_msg_debug ("resolver", 0, "returning ip-%s (port-%s) for "
- "hostname: %s and port: %d", host, service,
- hostname, port);
-
- *addr_info = cache->next;
- }
+/**
+ * gf_dnscache_init -- Initializes a dnscache struct and sets the ttl
+ * to the specified value in the parameter.
+ *
+ * @ttl: the TTL in seconds
+ * @return: SUCCESS: Pointer to an allocated dnscache struct
+ * FAILURE: NULL
+ */
+struct dnscache *
+gf_dnscache_init(time_t ttl)
+{
+ struct dnscache *cache = GF_MALLOC(sizeof(*cache), gf_common_mt_dnscache);
+ if (!cache)
+ return NULL;
- if (cache->next)
- cache->next = cache->next->ai_next;
- if (cache->next) {
- ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
- cache->next->ai_addrlen,
- host, sizeof (host),
- service, sizeof (service),
- NI_NUMERICHOST);
- if (ret != 0) {
- gf_msg ("resolver", GF_LOG_ERROR, 0,
- LG_MSG_GETNAMEINFO_FAILED, "getnameinfo failed"
- " (%s)", gai_strerror (ret));
- goto err;
- }
-
- gf_msg_debug ("resolver", 0, "next DNS query will return: "
- "ip-%s port-%s", host, service);
- }
+ cache->cache_dict = dict_new();
+ if (!cache->cache_dict) {
+ GF_FREE(cache);
+ cache = NULL;
+ } else {
+ cache->ttl = ttl;
+ }
- return 0;
+ return cache;
+}
-err:
- freeaddrinfo (cache->first);
- cache->first = cache->next = NULL;
- GF_FREE (cache);
- *dnscache = NULL;
- return -1;
+/**
+ * gf_dnscache_deinit -- cleanup resources used by struct dnscache
+ */
+void
+gf_dnscache_deinit(struct dnscache *cache)
+{
+ if (!cache) {
+ gf_msg_plain(GF_LOG_WARNING, "dnscache is NULL");
+ return;
+ }
+ dict_unref(cache->cache_dict);
+ GF_FREE(cache);
+}
+
+/**
+ * gf_dnscache_entry_init -- Initialize a dnscache entry
+ *
+ * @return: SUCCESS: Pointer to an allocated dnscache entry struct
+ * FAILURE: NULL
+ */
+struct dnscache_entry *
+gf_dnscache_entry_init()
+{
+ struct dnscache_entry *entry = GF_CALLOC(1, sizeof(*entry),
+ gf_common_mt_dnscache_entry);
+ return entry;
}
+/**
+ * gf_dnscache_entry_deinit -- Free memory used by a dnscache entry
+ *
+ * @entry: Pointer to deallocate
+ */
+void
+gf_dnscache_entry_deinit(struct dnscache_entry *entry)
+{
+ GF_FREE(entry->ip);
+ GF_FREE(entry->fqdn);
+ GF_FREE(entry);
+}
+
+/**
+ * gf_rev_dns_lookup -- Perform a reverse DNS lookup on the IP address.
+ *
+ * @ip: The IP address to perform a reverse lookup on
+ *
+ * @return: success: Allocated string containing the hostname
+ * failure: NULL
+ */
+char *
+gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache)
+{
+ char *fqdn = NULL;
+ int ret = 0;
+ dict_t *cache = NULL;
+ data_t *entrydata = NULL;
+ struct dnscache_entry *dnsentry = NULL;
+ gf_boolean_t from_cache = _gf_false;
+
+ if (!dnscache)
+ goto out;
+
+ cache = dnscache->cache_dict;
+
+ /* Quick cache lookup to see if we already hold it */
+ entrydata = dict_get(cache, (char *)ip);
+ if (entrydata) {
+ dnsentry = (struct dnscache_entry *)entrydata->data;
+ /* First check the TTL & timestamp */
+ if (gf_time() - dnsentry->timestamp > dnscache->ttl) {
+ gf_dnscache_entry_deinit(dnsentry);
+ entrydata->data = NULL; /* Mark this as 'null' so
+ * dict_del () doesn't try free
+ * this after we've already
+ * freed it.
+ */
+
+ dict_del(cache, (char *)ip); /* Remove this entry */
+ } else {
+ /* Cache entry is valid, get the FQDN and return */
+ fqdn = dnsentry->fqdn;
+ from_cache = _gf_true; /* Mark this as from cache */
+ goto out;
+ }
+ }
+
+ /* Get the FQDN */
+ ret = gf_get_hostname_from_ip((char *)ip, &fqdn);
+ if (ret != 0)
+ goto out;
+
+ if (!fqdn) {
+ gf_log_callingfn("resolver", GF_LOG_CRITICAL,
+ "Allocation failed for the host address");
+ goto out;
+ }
+
+ from_cache = _gf_false;
+out:
+ /* Insert into the cache */
+ if (fqdn && !from_cache && ip) {
+ struct dnscache_entry *entry = gf_dnscache_entry_init();
+
+ if (entry) {
+ entry->fqdn = fqdn;
+ entry->ip = gf_strdup(ip);
+ entry->timestamp = gf_time();
+ entrydata = bin_to_data(entry, sizeof(*entry));
+ dict_set(cache, (char *)ip, entrydata);
+ }
+ }
+ return fqdn;
+}
struct xldump {
- int lineno;
+ int lineno;
};
/* to catch any format discrepencies that may arise in code */
-static int nprintf (struct xldump *dump, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
static int
-nprintf (struct xldump *dump, const char *fmt, ...)
+nprintf(struct xldump *dump, const char *fmt, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
+static int
+nprintf(struct xldump *dump, const char *fmt, ...)
{
- va_list ap;
- char *msg = NULL;
- char header[32];
- int ret = 0;
+ va_list ap;
+ char *msg = NULL;
+ char header[32];
+ int ret = 0;
- ret = snprintf (header, 32, "%3d:", ++dump->lineno);
- if (ret < 0)
- goto out;
+ ret = snprintf(header, 32, "%3d:", ++dump->lineno);
+ if (ret < 0)
+ goto out;
- va_start (ap, fmt);
- ret = vasprintf (&msg, fmt, ap);
- va_end (ap);
- if (-1 == ret)
- goto out;
+ va_start(ap, fmt);
+ ret = vasprintf(&msg, fmt, ap);
+ va_end(ap);
+ if (-1 == ret)
+ goto out;
- /* NOTE: No ret value from gf_msg_plain, so unable to compute printed
- * characters. The return value from nprintf is not used, so for now
- * living with it */
- gf_msg_plain (GF_LOG_WARNING, "%s %s", header, msg);
+ /* NOTE: No ret value from gf_msg_plain, so unable to compute printed
+ * characters. The return value from nprintf is not used, so for now
+ * living with it */
+ gf_msg_plain(GF_LOG_WARNING, "%s %s", header, msg);
out:
- FREE (msg);
- return 0;
+ FREE(msg);
+ return 0;
}
-
static int
-xldump_options (dict_t *this, char *key, data_t *value, void *d)
+xldump_options(dict_t *this, char *key, data_t *value, void *d)
{
- nprintf (d, " option %s %s", key, value->data);
- return 0;
+ nprintf(d, " option %s %s", key, value->data);
+ return 0;
}
-
static void
-xldump_subvolumes (xlator_t *this, void *d)
+xldump_subvolumes(xlator_t *this, void *d)
{
- xlator_list_t *subv = NULL;
- int len = 0;
- char *subvstr = NULL;
+ xlator_list_t *subv = NULL;
+ int len = 0;
+ char *subvstr = NULL;
- subv = this->children;
- if (!this->children)
- return;
+ if (!this->children)
+ return;
- for (subv = this->children; subv; subv = subv->next)
- len += (strlen (subv->xlator->name) + 1);
+ for (subv = this->children; subv; subv = subv->next)
+ len += (strlen(subv->xlator->name) + 1);
- subvstr = GF_CALLOC (1, len, gf_common_mt_strdup);
+ subvstr = GF_MALLOC(len, gf_common_mt_strdup);
- len = 0;
- for (subv = this->children; subv; subv= subv->next)
- len += sprintf (subvstr + len, "%s%s", subv->xlator->name,
- subv->next ? " " : "");
+ len = 0;
+ for (subv = this->children; subv; subv = subv->next)
+ len += sprintf(subvstr + len, "%s%s", subv->xlator->name,
+ subv->next ? " " : "");
- nprintf (d, " subvolumes %s", subvstr);
+ nprintf(d, " subvolumes %s", subvstr);
- GF_FREE (subvstr);
+ GF_FREE(subvstr);
}
-
static void
-xldump (xlator_t *each, void *d)
+xldump(xlator_t *each, void *d)
{
- nprintf (d, "volume %s", each->name);
- nprintf (d, " type %s", each->type);
- dict_foreach (each->options, xldump_options, d);
+ nprintf(d, "volume %s", each->name);
+ nprintf(d, " type %s", each->type);
+ dict_foreach(each->options, xldump_options, d);
- xldump_subvolumes (each, d);
+ xldump_subvolumes(each, d);
- nprintf (d, "end-volume");
- nprintf (d, " ");
+ nprintf(d, "end-volume");
+ nprintf(d, " ");
}
-
void
-gf_log_dump_graph (FILE *specfp, glusterfs_graph_t *graph)
+gf_log_dump_graph(FILE *specfp, glusterfs_graph_t *graph)
{
- struct xldump xld = {0, };
+ struct xldump xld = {
+ 0,
+ };
- gf_msg_plain (GF_LOG_WARNING, "Final graph:");
- gf_msg_plain (GF_LOG_WARNING,
- "+---------------------------------------"
- "---------------------------------------+");
+ gf_msg_plain(GF_LOG_WARNING, "Final graph:");
+ gf_msg_plain(GF_LOG_WARNING,
+ "+---------------------------------------"
+ "---------------------------------------+");
- xlator_foreach_depth_first (graph->top, xldump, &xld);
+ xlator_foreach_depth_first(graph->top, xldump, &xld);
- gf_msg_plain (GF_LOG_WARNING,
- "+---------------------------------------"
- "---------------------------------------+");
+ gf_msg_plain(GF_LOG_WARNING,
+ "+---------------------------------------"
+ "---------------------------------------+");
}
static void
-gf_dump_config_flags ()
+gf_dump_config_flags()
{
- gf_msg_plain_nomem (GF_LOG_ALERT, "configuration details:");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "configuration details:");
/* have argp */
#ifdef HAVE_ARGP
- gf_msg_plain_nomem (GF_LOG_ALERT, "argp 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "argp 1");
#endif
/* ifdef if found backtrace */
#ifdef HAVE_BACKTRACE
- gf_msg_plain_nomem (GF_LOG_ALERT, "backtrace 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "backtrace 1");
#endif
/* Berkeley-DB version has cursor->get() */
#ifdef HAVE_BDB_CURSOR_GET
- gf_msg_plain_nomem (GF_LOG_ALERT, "bdb->cursor->get 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "bdb->cursor->get 1");
#endif
/* Define to 1 if you have the <db.h> header file. */
#ifdef HAVE_DB_H
- gf_msg_plain_nomem (GF_LOG_ALERT, "db.h 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "db.h 1");
#endif
/* Define to 1 if you have the <dlfcn.h> header file. */
#ifdef HAVE_DLFCN_H
- gf_msg_plain_nomem (GF_LOG_ALERT, "dlfcn 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "dlfcn 1");
#endif
/* define if fdatasync exists */
#ifdef HAVE_FDATASYNC
- gf_msg_plain_nomem (GF_LOG_ALERT, "fdatasync 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "fdatasync 1");
#endif
/* Define to 1 if you have the `pthread' library (-lpthread). */
#ifdef HAVE_LIBPTHREAD
- gf_msg_plain_nomem (GF_LOG_ALERT, "libpthread 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "libpthread 1");
#endif
/* define if llistxattr exists */
#ifdef HAVE_LLISTXATTR
- gf_msg_plain_nomem (GF_LOG_ALERT, "llistxattr 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "llistxattr 1");
#endif
/* define if found setfsuid setfsgid */
#ifdef HAVE_SET_FSID
- gf_msg_plain_nomem (GF_LOG_ALERT, "setfsid 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "setfsid 1");
#endif
/* define if found spinlock */
#ifdef HAVE_SPINLOCK
- gf_msg_plain_nomem (GF_LOG_ALERT, "spinlock 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "spinlock 1");
#endif
/* Define to 1 if you have the <sys/epoll.h> header file. */
#ifdef HAVE_SYS_EPOLL_H
- gf_msg_plain_nomem (GF_LOG_ALERT, "epoll.h 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "epoll.h 1");
#endif
/* Define to 1 if you have the <sys/extattr.h> header file. */
#ifdef HAVE_SYS_EXTATTR_H
- gf_msg_plain_nomem (GF_LOG_ALERT, "extattr.h 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "extattr.h 1");
#endif
/* Define to 1 if you have the <sys/xattr.h> header file. */
#ifdef HAVE_SYS_XATTR_H
- gf_msg_plain_nomem (GF_LOG_ALERT, "xattr.h 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "xattr.h 1");
#endif
/* define if found st_atim.tv_nsec */
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
- gf_msg_plain_nomem (GF_LOG_ALERT, "st_atim.tv_nsec 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "st_atim.tv_nsec 1");
#endif
/* define if found st_atimespec.tv_nsec */
#ifdef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
- gf_msg_plain_nomem (GF_LOG_ALERT, "st_atimespec.tv_nsec 1");
+ gf_msg_plain_nomem(GF_LOG_ALERT, "st_atimespec.tv_nsec 1");
#endif
/* Define to the full name and version of this package. */
#ifdef PACKAGE_STRING
- {
- char msg[128];
- sprintf (msg, "package-string: %s", PACKAGE_STRING);
- gf_msg_plain_nomem (GF_LOG_ALERT, msg);
+ {
+ char *msg = NULL;
+ int ret = -1;
+
+ ret = gf_asprintf(&msg, "package-string: %s", PACKAGE_STRING);
+ if (ret >= 0) {
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
+ GF_FREE(msg);
}
+ }
#endif
- return;
+ return;
}
/* Obtain a backtrace and print it to the log */
void
-gf_print_trace (int32_t signum, glusterfs_ctx_t *ctx)
-{
- char msg[1024] = {0,};
- char timestr[64] = {0,};
- call_stack_t *stack = NULL;
-
- /* Now every gf_log call will just write to a buffer and when the
- * buffer becomes full, its written to the log-file. Suppose the process
- * crashes and prints the backtrace in the log-file, then the previous
- * log information will still be in the buffer itself. So flush the
- * contents of the buffer to the log file before printing the backtrace
- * which helps in debugging.
- */
- gf_log_flush();
-
- gf_log_disable_suppression_before_exit (ctx);
-
- /* Pending frames, (if any), list them in order */
- gf_msg_plain_nomem (GF_LOG_ALERT, "pending frames:");
+gf_print_trace(int32_t signum, glusterfs_ctx_t *ctx)
+{
+ char msg[1024] = {
+ 0,
+ };
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ call_stack_t *stack = NULL;
+
+ /* Now every gf_log call will just write to a buffer and when the
+ * buffer becomes full, its written to the log-file. Suppose the process
+ * crashes and prints the backtrace in the log-file, then the previous
+ * log information will still be in the buffer itself. So flush the
+ * contents of the buffer to the log file before printing the backtrace
+ * which helps in debugging.
+ */
+ gf_log_flush();
+
+ gf_log_disable_suppression_before_exit(ctx);
+
+ /* Pending frames, (if any), list them in order */
+ gf_msg_plain_nomem(GF_LOG_ALERT, "pending frames:");
+ {
+ /* FIXME: traversing stacks outside pool->lock */
+ list_for_each_entry(stack, &ctx->pool->all_frames, all_frames)
{
- /* FIXME: traversing stacks outside pool->lock */
- list_for_each_entry (stack, &ctx->pool->all_frames,
- all_frames) {
- if (stack->type == GF_OP_TYPE_FOP)
- sprintf (msg,"frame : type(%d) op(%s)",
- stack->type,
- gf_fop_list[stack->op]);
- else
- sprintf (msg,"frame : type(%d) op(%d)",
- stack->type,
- stack->op);
-
- gf_msg_plain_nomem (GF_LOG_ALERT, msg);
- }
+ if (stack->type == GF_OP_TYPE_FOP)
+ sprintf(msg, "frame : type(%d) op(%s)", stack->type,
+ gf_fop_list[stack->op]);
+ else
+ sprintf(msg, "frame : type(%d) op(%d)", stack->type, stack->op);
+
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
}
+ }
- sprintf (msg, "patchset: %s", GLUSTERFS_REPOSITORY_REVISION);
- gf_msg_plain_nomem (GF_LOG_ALERT, msg);
+ sprintf(msg, "patchset: %s", GLUSTERFS_REPOSITORY_REVISION);
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
- sprintf (msg, "signal received: %d", signum);
- gf_msg_plain_nomem (GF_LOG_ALERT, msg);
- {
- /* Dump the timestamp of the crash too, so the previous logs
- can be related */
- gf_time_fmt (timestr, sizeof timestr, time (NULL),
- gf_timefmt_FT);
- gf_msg_plain_nomem (GF_LOG_ALERT, "time of crash: ");
- gf_msg_plain_nomem (GF_LOG_ALERT, timestr);
- }
+ sprintf(msg, "signal received: %d", signum);
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
+ {
+ /* Dump the timestamp of the crash too, so the previous logs
+ can be related */
+ gf_time_fmt(timestr, sizeof timestr, gf_time(), gf_timefmt_FT);
+ gf_msg_plain_nomem(GF_LOG_ALERT, "time of crash: ");
+ gf_msg_plain_nomem(GF_LOG_ALERT, timestr);
+ }
- gf_dump_config_flags ();
- gf_msg_backtrace_nomem (GF_LOG_ALERT, 200);
- sprintf (msg, "---------");
- gf_msg_plain_nomem (GF_LOG_ALERT, msg);
+ gf_dump_config_flags();
+ gf_msg_backtrace_nomem(GF_LOG_ALERT, 200);
+ sprintf(msg, "---------");
+ gf_msg_plain_nomem(GF_LOG_ALERT, msg);
- /* Send a signal to terminate the process */
- signal (signum, SIG_DFL);
- raise (signum);
+ /* Send a signal to terminate the process */
+ signal(signum, SIG_DFL);
+ raise(signum);
}
void
-trap (void)
+trap(void)
{
-
}
char *
-gf_trim (char *string)
+gf_trim(char *string)
{
- register char *s, *t;
-
- if (string == NULL) {
- return NULL;
- }
-
- for (s = string; isspace (*s); s++)
- ;
+ register char *s, *t;
- if (*s == 0)
- return s;
+ if (string == NULL) {
+ return NULL;
+ }
- t = s + strlen (s) - 1;
- while (t > s && isspace (*t))
- t--;
- *++t = '\0';
+ for (s = string; isspace(*s); s++)
+ ;
+ if (*s == 0)
return s;
-}
-
-int
-gf_strsplit (const char *str, const char *delim,
- char ***tokens, int *token_count)
-{
- char *_running = NULL;
- char *running = NULL;
- char *token = NULL;
- char **token_list = NULL;
- int count = 0;
- int i = 0;
- int j = 0;
-
- if (str == NULL || delim == NULL || tokens == NULL || token_count == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- return -1;
- }
-
- _running = gf_strdup (str);
- if (_running == NULL)
- return -1;
-
- running = _running;
-
- while ((token = strsep (&running, delim)) != NULL) {
- if (token[0] != '\0')
- count++;
- }
- GF_FREE (_running);
-
- _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_FREE (_running);
- return -1;
- }
- while ((token = strsep (&running, delim)) != NULL) {
- if (token[0] == '\0')
- continue;
+ t = s + strlen(s) - 1;
+ while (t > s && isspace(*t))
+ t--;
+ *++t = '\0';
- token_list[i] = gf_strdup (token);
- if (token_list[i] == NULL)
- goto free_exit;
- i++;
- }
-
- GF_FREE (_running);
-
- *tokens = token_list;
- *token_count = count;
- return 0;
-
-free_exit:
- GF_FREE (_running);
- for (j = 0; j < i; j++)
- GF_FREE (token_list[j]);
-
- GF_FREE (token_list);
- return -1;
+ return s;
}
int
-gf_strstr (const char *str, const char *delim, const char *match)
+gf_strstr(const char *str, const char *delim, const char *match)
{
- char *tmp = NULL;
- char *save_ptr = NULL;
- char *tmp_str = NULL;
+ char *tmp = NULL;
+ char *save_ptr = NULL;
+ char *tmp_str = NULL;
- int ret = 0;
+ int ret = 0;
- tmp_str = strdup (str);
-
- if (str == NULL || delim == NULL || match == NULL || tmp_str == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- ret = -1;
- goto out;
- }
+ tmp_str = strdup(str);
+ if (str == NULL || delim == NULL || match == NULL || tmp_str == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ ret = -1;
+ goto out;
+ }
- tmp = strtok_r (tmp_str, delim, &save_ptr);
+ tmp = strtok_r(tmp_str, delim, &save_ptr);
- while (tmp) {
- ret = strcmp (tmp, match);
+ while (tmp) {
+ ret = strcmp(tmp, match);
- if (ret == 0)
- break;
+ if (ret == 0)
+ break;
- tmp = strtok_r (NULL, delim, &save_ptr);
- }
+ tmp = strtok_r(NULL, delim, &save_ptr);
+ }
out:
- free (tmp_str);
-
- return ret;
+ free(tmp_str);
+ return ret;
}
int
-gf_volume_name_validate (const char *volume_name)
+gf_volume_name_validate(const char *volume_name)
{
- const char *vname = NULL;
+ const char *vname = NULL;
- if (volume_name == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- return -1;
- }
+ if (volume_name == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return -1;
+ }
- if (!isalpha (volume_name[0]))
- return 1;
+ if (!isalpha(volume_name[0]))
+ return 1;
- for (vname = &volume_name[1]; *vname != '\0'; vname++) {
- if (!(isalnum (*vname) || *vname == '_'))
- return 1;
- }
+ for (vname = &volume_name[1]; *vname != '\0'; vname++) {
+ if (!(isalnum(*vname) || *vname == '_'))
+ return 1;
+ }
- return 0;
+ return 0;
}
-
int
-gf_string2time (const char *str, uint32_t *n)
+gf_string2time(const char *str, uint32_t *n)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "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 = strtol (str, &tail, 0);
- if (str == tail)
- errno = EINVAL;
-
- 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'))))
- goto out;
-
- else if (((tail[0] == 'm') && (tail[1] == '\0')) ||
- ((tail[0] == 'm') && (tail[1] == 'i') &&
- (tail[2] == 'n') && (tail[3] == '\0'))) {
- value = value * GF_MINUTE_IN_SECONDS;
- goto out;
- }
-
- else if (((tail[0] == 'h') && (tail[1] == '\0')) ||
- ((tail[0] == 'h') && (tail[1] == 'r') &&
- (tail[2] == '\0'))) {
- value = value * GF_HOUR_IN_SECONDS;
- goto out;
- }
-
- else if (((tail[0] == 'd') && (tail[1] == '\0')) ||
- ((tail[0] == 'd') && (tail[1] == 'a') &&
- (tail[2] == 'y') && (tail[3] == 's') &&
- (tail[4] == '\0'))) {
- value = value * GF_DAY_IN_SECONDS;
- goto out;
- }
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "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 = strtol(str, &tail, 0);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- else if (((tail[0] == 'w') && (tail[1] == '\0')) ||
- ((tail[0] == 'w') && (tail[1] == 'k') &&
- (tail[2] == '\0'))) {
- value = value * GF_WEEK_IN_SECONDS;
- goto out;
- } else {
- 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'))))
+ goto out;
+
+ else if (((tail[0] == 'm') && (tail[1] == '\0')) ||
+ ((tail[0] == 'm') && (tail[1] == 'i') && (tail[2] == 'n') &&
+ (tail[3] == '\0'))) {
+ value = value * GF_MINUTE_IN_SECONDS;
+ goto out;
+ }
+
+ else if (((tail[0] == 'h') && (tail[1] == '\0')) ||
+ ((tail[0] == 'h') && (tail[1] == 'r') && (tail[2] == '\0'))) {
+ value = value * GF_HOUR_IN_SECONDS;
+ goto out;
+ }
+
+ else if (((tail[0] == 'd') && (tail[1] == '\0')) ||
+ ((tail[0] == 'd') && (tail[1] == 'a') && (tail[2] == 'y') &&
+ (tail[3] == 's') && (tail[4] == '\0'))) {
+ value = value * GF_DAY_IN_SECONDS;
+ goto out;
+ }
+
+ else if (((tail[0] == 'w') && (tail[1] == '\0')) ||
+ ((tail[0] == 'w') && (tail[1] == 'k') && (tail[2] == '\0'))) {
+ value = value * GF_WEEK_IN_SECONDS;
+ goto out;
+ } else {
+ return -1;
+ }
out:
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
int
-gf_string2percent (const char *str, double *n)
+gf_string2percent(const char *str, double *n)
{
- double value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
-
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- errno = EINVAL;
- return -1;
- }
+ double value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
- for (s = str; *s != '\0'; s++) {
- if (isspace (*s))
- continue;
- if (*s == '-')
- return -1;
- break;
- }
-
- old_errno = errno;
- errno = 0;
- value = strtod (str, &tail);
- if (str == tail)
- errno = EINVAL;
-
- if (errno == ERANGE || errno == EINVAL)
- return -1;
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "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 = strtod(str, &tail);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- errno = old_errno;
+ if (errno == 0)
+ errno = old_errno;
- if (!((tail[0] == '\0') ||
- ((tail[0] == '%') && (tail[1] == '\0'))))
- return -1;
+ if (!((tail[0] == '\0') || ((tail[0] == '%') && (tail[1] == '\0'))))
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
-
static int
-_gf_string2long (const char *str, long *n, int base)
+_gf_string2long(const char *str, long *n, int base)
{
- long value = 0;
- char *tail = NULL;
- int old_errno = 0;
+ long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- errno = EINVAL;
- return -1;
- }
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtol (str, &tail, base);
- if (str == tail)
- errno = EINVAL;
+ old_errno = errno;
+ errno = 0;
+ value = strtol(str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- return -1;
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- errno = old_errno;
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- return -1;
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
-_gf_string2ulong (const char *str, unsigned long *n, int base)
-{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
-
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "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 = strtoul (str, &tail, base);
- if (str == tail)
- errno = EINVAL;
+_gf_string2ulong(const char *str, unsigned long *n, int base)
+{
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
- if (errno == ERANGE || errno == EINVAL)
- return -1;
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "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 = strtoul(str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- errno = old_errno;
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- return -1;
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
-_gf_string2uint (const char *str, unsigned int *n, int base)
-{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
-
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "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 = strtoul (str, &tail, base);
- if (str == tail)
- errno = EINVAL;
+_gf_string2uint(const char *str, unsigned int *n, int base)
+{
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
- if (errno == ERANGE || errno == EINVAL)
- return -1;
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "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 = strtoul(str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- errno = old_errno;
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- return -1;
+ if (tail[0] != '\0')
+ return -1;
- *n = (unsigned int)value;
+ *n = (unsigned int)value;
- return 0;
+ return 0;
}
static int
-_gf_string2double (const char *str, double *n)
+_gf_string2double(const char *str, double *n)
{
- double value = 0.0;
- char *tail = NULL;
- int old_errno = 0;
+ double value = 0.0;
+ char *tail = NULL;
+ int old_errno = 0;
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- errno = EINVAL;
- return -1;
- }
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtod (str, &tail);
- if (str == tail)
- errno = EINVAL;
+ old_errno = errno;
+ errno = 0;
+ value = strtod(str, &tail);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- return -1;
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- errno = old_errno;
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- return -1;
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
-_gf_string2longlong (const char *str, long long *n, int base)
+_gf_string2longlong(const char *str, long long *n, int base)
{
- long long value = 0;
- char *tail = NULL;
- int old_errno = 0;
+ long long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- errno = EINVAL;
- return -1;
- }
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtoll (str, &tail, base);
- if (str == tail)
- errno = EINVAL;
+ old_errno = errno;
+ errno = 0;
+ value = strtoll(str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- return -1;
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- errno = old_errno;
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- return -1;
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
-_gf_string2ulonglong (const char *str, unsigned long long *n, int base)
-{
- unsigned long long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
-
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "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, base);
- if (str == tail)
- errno = EINVAL;
+_gf_string2ulonglong(const char *str, unsigned long long *n, int base)
+{
+ unsigned long long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
- if (errno == ERANGE || errno == EINVAL)
- return -1;
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "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, base);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- errno = old_errno;
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- return -1;
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
int
-gf_string2long (const char *str, long *n)
+gf_string2long(const char *str, long *n)
{
- return _gf_string2long (str, n, 0);
+ return _gf_string2long(str, n, 0);
}
int
-gf_string2ulong (const char *str, unsigned long *n)
+gf_string2ulong(const char *str, unsigned long *n)
{
- return _gf_string2ulong (str, n, 0);
+ return _gf_string2ulong(str, n, 0);
}
int
-gf_string2int (const char *str, int *n)
+gf_string2int(const char *str, int *n)
{
- long l = 0;
- int ret = 0;
+ long l = 0;
+ int ret = 0;
- ret = _gf_string2long (str, &l, 0);
+ ret = _gf_string2long(str, &l, 0);
- *n = l;
- return ret;
+ *n = l;
+ return ret;
}
int
-gf_string2uint (const char *str, unsigned int *n)
+gf_string2uint(const char *str, unsigned int *n)
{
- return _gf_string2uint (str, n, 0);
+ return _gf_string2uint(str, n, 0);
}
int
-gf_string2double (const char *str, double *n)
+gf_string2double(const char *str, double *n)
{
- return _gf_string2double (str, n);
+ return _gf_string2double(str, n);
}
int
-gf_string2longlong (const char *str, long long *n)
+gf_string2longlong(const char *str, long long *n)
{
- return _gf_string2longlong (str, n, 0);
+ return _gf_string2longlong(str, n, 0);
}
int
-gf_string2ulonglong (const char *str, unsigned long long *n)
+gf_string2ulonglong(const char *str, unsigned long long *n)
{
- return _gf_string2ulonglong (str, n, 0);
+ return _gf_string2ulonglong(str, n, 0);
}
int
-gf_string2int8 (const char *str, int8_t *n)
+gf_string2int8(const char *str, int8_t *n)
{
- long l = 0L;
- int rv = 0;
+ long l = 0L;
+ int rv = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2long(str, &l, 0);
+ if (rv != 0)
+ return rv;
- if ((l >= INT8_MIN) && (l <= INT8_MAX)) {
- *n = (int8_t) l;
- return 0;
- }
+ if ((l >= INT8_MIN) && (l <= INT8_MAX)) {
+ *n = (int8_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2int16 (const char *str, int16_t *n)
+gf_string2int16(const char *str, int16_t *n)
{
- long l = 0L;
- int rv = 0;
+ long l = 0L;
+ int rv = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2long(str, &l, 0);
+ if (rv != 0)
+ return rv;
- if ((l >= INT16_MIN) && (l <= INT16_MAX)) {
- *n = (int16_t) l;
- return 0;
- }
+ if ((l >= INT16_MIN) && (l <= INT16_MAX)) {
+ *n = (int16_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2int32 (const char *str, int32_t *n)
+gf_string2int32(const char *str, int32_t *n)
{
- long l = 0L;
- int rv = 0;
+ long l = 0L;
+ int rv = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2long(str, &l, 0);
+ if (rv != 0)
+ return rv;
- if ((l >= INT32_MIN) && (l <= INT32_MAX)) {
- *n = (int32_t) l;
- return 0;
- }
+ if ((l >= INT32_MIN) && (l <= INT32_MAX)) {
+ *n = (int32_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2int64 (const char *str, int64_t *n)
+gf_string2int64(const char *str, int64_t *n)
{
- long long l = 0LL;
- int rv = 0;
+ long long l = 0LL;
+ int rv = 0;
- rv = _gf_string2longlong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2longlong(str, &l, 0);
+ if (rv != 0)
+ return rv;
- if ((l >= INT64_MIN) && (l <= INT64_MAX)) {
- *n = (int64_t) l;
- return 0;
- }
-
- errno = ERANGE;
- return -1;
+ *n = (int64_t)l;
+ return 0;
}
int
-gf_string2uint8 (const char *str, uint8_t *n)
+gf_string2uint8(const char *str, uint8_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong(str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l <= UINT8_MAX) {
- *n = (uint8_t) l;
- return 0;
- }
+ if (l <= UINT8_MAX) {
+ *n = (uint8_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2uint16 (const char *str, uint16_t *n)
+gf_string2uint16(const char *str, uint16_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong(str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l <= UINT16_MAX) {
- *n = (uint16_t) l;
- return 0;
- }
+ if (l <= UINT16_MAX) {
+ *n = (uint16_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2uint32 (const char *str, uint32_t *n)
+gf_string2uint32(const char *str, uint32_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong(str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l <= UINT32_MAX) {
- *n = (uint32_t) l;
- return 0;
- }
+ if (l <= UINT32_MAX) {
+ *n = (uint32_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2uint64 (const char *str, uint64_t *n)
+gf_string2uint64(const char *str, uint64_t *n)
{
- unsigned long long l = 0ULL;
- int rv = 0;
+ unsigned long long l = 0ULL;
+ int rv = 0;
- rv = _gf_string2ulonglong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulonglong(str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l <= UINT64_MAX) {
- *n = (uint64_t) l;
- return 0;
- }
+ if (l <= UINT64_MAX) {
+ *n = (uint64_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2ulong_base10 (const char *str, unsigned long *n)
+gf_string2ulong_base10(const char *str, unsigned long *n)
{
- return _gf_string2ulong (str, n, 10);
+ return _gf_string2ulong(str, n, 10);
}
int
-gf_string2uint_base10 (const char *str, unsigned int *n)
+gf_string2uint_base10(const char *str, unsigned int *n)
{
- return _gf_string2uint (str, n, 10);
+ return _gf_string2uint(str, n, 10);
}
int
-gf_string2uint8_base10 (const char *str, uint8_t *n)
+gf_string2uint8_base10(const char *str, uint8_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong(str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l <= UINT8_MAX) {
- *n = (uint8_t) l;
- return 0;
- }
+ if (l <= UINT8_MAX) {
+ *n = (uint8_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2uint16_base10 (const char *str, uint16_t *n)
+gf_string2uint16_base10(const char *str, uint16_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong(str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l <= UINT16_MAX) {
- *n = (uint16_t) l;
- return 0;
- }
+ if (l <= UINT16_MAX) {
+ *n = (uint16_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2uint32_base10 (const char *str, uint32_t *n)
+gf_string2uint32_base10(const char *str, uint32_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong(str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l <= UINT32_MAX) {
- *n = (uint32_t) l;
- return 0;
- }
+ if (l <= UINT32_MAX) {
+ *n = (uint32_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
-gf_string2uint64_base10 (const char *str, uint64_t *n)
+gf_string2uint64_base10(const char *str, uint64_t *n)
{
- unsigned long long l = 0ULL;
- int rv = 0;
+ unsigned long long l = 0ULL;
+ int rv = 0;
- rv = _gf_string2ulonglong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulonglong(str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l <= UINT64_MAX) {
- *n = (uint64_t) l;
- return 0;
- }
+ if (l <= UINT64_MAX) {
+ *n = (uint64_t)l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ 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;
+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, "%" PRIu64 "Bytes", n);
+ if (ret < 0)
+ goto err;
+ }
+ return str;
err:
- return NULL;
+ return NULL;
}
int
-gf_string2bytesize_range (const char *str, uint64_t *n, uint64_t max)
-{
- double value = 0.0;
- uint64_t int_value = 0;
- uint64_t unit = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
- gf_boolean_t fraction = _gf_false;
+gf_string2bytesize_range(const char *str, uint64_t *n, uint64_t umax)
+{
+ double value = 0.0;
+ int64_t int_value = 0;
+ uint64_t unit = 0;
+ int64_t max = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+ gf_boolean_t fraction = _gf_false;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- errno = EINVAL;
- return -1;
- }
+ max = umax & 0x7fffffffffffffffLL;
- for (s = str; *s != '\0'; s++) {
- if (isspace (*s))
- continue;
- if (*s == '-')
- return -1;
- break;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace(*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- if (strrchr (str, '.'))
- fraction = _gf_true;
+ if (strrchr(str, '.'))
+ fraction = _gf_true;
- old_errno = errno;
- errno = 0;
- if (fraction)
- value = strtod (str, &tail);
- else
- int_value = strtoll (str, &tail, 10);
+ old_errno = errno;
+ errno = 0;
+ if (fraction)
+ value = strtod(str, &tail);
+ else
+ int_value = strtoll(str, &tail, 10);
+
+ if (str == tail)
+ errno = EINVAL;
- if (str == tail)
- errno = EINVAL;
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == ERANGE || errno == EINVAL)
- return -1;
+ if (errno == 0)
+ errno = old_errno;
- if (errno == 0)
- errno = old_errno;
+ if (tail[0] != '\0') {
+ if (strcasecmp(tail, GF_UNIT_KB_STRING) == 0)
+ unit = GF_UNIT_KB;
+ else if (strcasecmp(tail, GF_UNIT_MB_STRING) == 0)
+ unit = GF_UNIT_MB;
+ else if (strcasecmp(tail, GF_UNIT_GB_STRING) == 0)
+ unit = GF_UNIT_GB;
+ else if (strcasecmp(tail, GF_UNIT_TB_STRING) == 0)
+ unit = GF_UNIT_TB;
+ else if (strcasecmp(tail, GF_UNIT_PB_STRING) == 0)
+ unit = GF_UNIT_PB;
+ else if (strcasecmp(tail, GF_UNIT_B_STRING) != 0)
+ return -1;
- if (tail[0] != '\0')
- {
- if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0)
- unit = GF_UNIT_KB;
- else if (strcasecmp (tail, GF_UNIT_MB_STRING) == 0)
- unit = GF_UNIT_MB;
- else if (strcasecmp (tail, GF_UNIT_GB_STRING) == 0)
- unit = GF_UNIT_GB;
- else if (strcasecmp (tail, GF_UNIT_TB_STRING) == 0)
- unit = GF_UNIT_TB;
- else if (strcasecmp (tail, GF_UNIT_PB_STRING) == 0)
- unit = GF_UNIT_PB;
- else if (strcasecmp (tail, GF_UNIT_B_STRING) != 0)
- return -1;
-
- if (unit > 0) {
- if (fraction)
- value *= unit;
- else
- int_value *= unit;
- }
+ if (unit > 0) {
+ if (fraction)
+ value *= unit;
+ else
+ int_value *= unit;
}
+ }
- if (fraction) {
- if ((max - value) < 0) {
- errno = ERANGE;
- return -1;
- }
- *n = (uint64_t) value;
- } else {
- if ((max - int_value) < 0) {
- errno = ERANGE;
- return -1;
- }
- *n = int_value;
+ if (fraction) {
+ if ((max - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
+ *n = (uint64_t)value;
+ } else {
+ if ((max - int_value) < 0) {
+ errno = ERANGE;
+ return -1;
}
+ *n = int_value;
+ }
- return 0;
+ return 0;
}
int
-gf_string2bytesize_size (const char *str, size_t *n)
+gf_string2bytesize_uint64(const char *str, uint64_t *n)
{
- uint64_t u64;
- size_t max = (size_t) - 1;
- int val = gf_string2bytesize_range (str, &u64, max);
- *n = (size_t) u64;
- return val;
+ return gf_string2bytesize_range(str, n, UINT64_MAX);
}
int
-gf_string2bytesize (const char *str, uint64_t *n)
+gf_string2bytesize_int64(const char *str, int64_t *n)
{
- return gf_string2bytesize_range(str, n, UINT64_MAX);
-}
+ uint64_t u64 = 0;
+ int ret = 0;
-int
-gf_string2bytesize_uint64 (const char *str, uint64_t *n)
-{
- return gf_string2bytesize_range(str, n, UINT64_MAX);
+ ret = gf_string2bytesize_range(str, &u64, INT64_MAX);
+ *n = (int64_t)u64;
+ return ret;
}
int
-gf_string2bytesize_int64 (const char *str, int64_t *n)
-{
- uint64_t u64 = 0;
- int ret = 0;
+gf_string2percent_or_bytesize(const char *str, double *n,
+ gf_boolean_t *is_percent)
+{
+ double value = 0ULL;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "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 = strtod(str, &tail);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- ret = gf_string2bytesize_range(str, &u64, INT64_MAX);
- *n = (int64_t) u64;
- return ret;
+ if (errno == 0)
+ errno = old_errno;
+
+ /*Maximum accepted value for 64 bit OS will be (2^14 -1)PB*/
+ 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;
+ }
+
+ /* Error out if we cannot store the value in uint64 */
+ if ((UINT64_MAX - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ *n = value;
+
+ return 0;
}
-int
-gf_string2percent_or_bytesize (const char *str, double *n,
- gf_boolean_t *is_percent)
+int64_t
+gf_str_to_long_long(const char *number)
{
- double value = 0ULL;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ int64_t unit = 1;
+ int64_t ret = 0;
+ char *endptr = NULL;
+ if (!number)
+ return 0;
- if (str == NULL || n == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- errno = EINVAL;
- return -1;
- }
+ ret = strtoll(number, &endptr, 0);
- for (s = str; *s != '\0'; s++) {
- if (isspace (*s))
- continue;
- if (*s == '-')
- return -1;
+ if (endptr) {
+ switch (*endptr) {
+ case 'G':
+ case 'g':
+ if ((*(endptr + 1) == 'B') || (*(endptr + 1) == 'b'))
+ unit = 1024 * 1024 * 1024;
+ break;
+ case 'M':
+ case 'm':
+ if ((*(endptr + 1) == 'B') || (*(endptr + 1) == 'b'))
+ unit = 1024 * 1024;
+ break;
+ case 'K':
+ case 'k':
+ if ((*(endptr + 1) == 'B') || (*(endptr + 1) == 'b'))
+ unit = 1024;
+ break;
+ case '%':
+ unit = 1;
+ break;
+ default:
+ unit = 1;
break;
}
+ }
+ return ret * unit;
+}
- old_errno = errno;
- errno = 0;
- value = strtod (str, &tail);
- if (str == tail)
- errno = EINVAL;
-
- if (errno == ERANGE || errno == EINVAL)
- return -1;
-
- if (errno == 0)
- errno = old_errno;
-
- /*Maximum accepted value for 64 bit OS will be (2^14 -1)PB*/
- 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;
- }
-
- /* Error out if we cannot store the value in uint64 */
- if ((UINT64_MAX - value) < 0) {
- errno = ERANGE;
- return -1;
- }
-
- *n = value;
+int
+gf_string2boolean(const char *str, gf_boolean_t *b)
+{
+ if (str == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return -1;
+ }
+ if ((strcasecmp(str, "1") == 0) || (strcasecmp(str, "on") == 0) ||
+ (strcasecmp(str, "yes") == 0) || (strcasecmp(str, "true") == 0) ||
+ (strcasecmp(str, "enable") == 0)) {
+ *b = _gf_true;
return 0;
-}
+ }
-int64_t
-gf_str_to_long_long (const char *number)
-{
- int64_t unit = 1;
- int64_t ret = 0;
- char *endptr = NULL ;
- if (!number)
- return 0;
+ if ((strcasecmp(str, "0") == 0) || (strcasecmp(str, "off") == 0) ||
+ (strcasecmp(str, "no") == 0) || (strcasecmp(str, "false") == 0) ||
+ (strcasecmp(str, "disable") == 0)) {
+ *b = _gf_false;
+ return 0;
+ }
- ret = strtoll (number, &endptr, 0);
-
- if (endptr) {
- switch (*endptr) {
- case 'G':
- case 'g':
- if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
- unit = 1024 * 1024 * 1024;
- break;
- case 'M':
- case 'm':
- if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
- unit = 1024 * 1024;
- break;
- case 'K':
- case 'k':
- if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
- unit = 1024;
- break;
- case '%':
- unit = 1;
- break;
- default:
- unit = 1;
- break;
- }
- }
- return ret * unit;
+ return -1;
}
int
-gf_string2boolean (const char *str, gf_boolean_t *b)
+gf_strn2boolean(const char *str, const int len, gf_boolean_t *b)
{
- if (str == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- return -1;
- }
+ if (str == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return -1;
+ }
- if ((strcasecmp (str, "1") == 0) ||
- (strcasecmp (str, "on") == 0) ||
- (strcasecmp (str, "yes") == 0) ||
- (strcasecmp (str, "true") == 0) ||
- (strcasecmp (str, "enable") == 0)) {
+ switch (len) {
+ case 1:
+ if (strcasecmp(str, "1") == 0) {
*b = _gf_true;
return 0;
- }
-
- if ((strcasecmp (str, "0") == 0) ||
- (strcasecmp (str, "off") == 0) ||
- (strcasecmp (str, "no") == 0) ||
- (strcasecmp (str, "false") == 0) ||
- (strcasecmp (str, "disable") == 0)) {
+ } else if (strcasecmp(str, "0") == 0) {
*b = _gf_false;
return 0;
- }
-
- return -1;
+ }
+ break;
+ case 2:
+ if (strcasecmp(str, "on") == 0) {
+ *b = _gf_true;
+ return 0;
+ } else if (strcasecmp(str, "no") == 0) {
+ *b = _gf_false;
+ return 0;
+ }
+ break;
+ case 3:
+ if (strcasecmp(str, "yes") == 0) {
+ *b = _gf_true;
+ return 0;
+ } else if (strcasecmp(str, "off") == 0) {
+ *b = _gf_false;
+ return 0;
+ }
+ break;
+ case 4:
+ if (strcasecmp(str, "true") == 0) {
+ *b = _gf_true;
+ return 0;
+ }
+ break;
+ case 5:
+ if (strcasecmp(str, "false") == 0) {
+ *b = _gf_false;
+ return 0;
+ }
+ break;
+ case 6:
+ if (strcasecmp(str, "enable") == 0) {
+ *b = _gf_true;
+ return 0;
+ }
+ break;
+ case 7:
+ if (strcasecmp(str, "disable") == 0) {
+ *b = _gf_false;
+ return 0;
+ }
+ break;
+ default:
+ return -1;
+ break;
+ }
+ return -1;
}
-
int
-gf_lockfd (int fd)
+gf_lockfd(int fd)
{
- struct gf_flock fl;
+ struct gf_flock fl;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
- return fcntl (fd, F_SETLK, &fl);
+ return fcntl(fd, F_SETLK, &fl);
}
-
int
-gf_unlockfd (int fd)
+gf_unlockfd(int fd)
{
- struct gf_flock fl;
+ struct gf_flock fl;
- fl.l_type = F_UNLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
- return fcntl (fd, F_SETLK, &fl);
+ return fcntl(fd, F_SETLK, &fl);
}
static void
-compute_checksum (char *buf, size_t size, uint32_t *checksum)
+compute_checksum(char *buf, const ssize_t size, uint32_t *checksum)
{
- int ret = -1;
- char *checksum_buf = NULL;
+ int ret = -1;
+ char *checksum_buf = NULL;
- checksum_buf = (char *)(checksum);
+ checksum_buf = (char *)(checksum);
- if (!(*checksum)) {
- checksum_buf [0] = 0xba;
- checksum_buf [1] = 0xbe;
- checksum_buf [2] = 0xb0;
- checksum_buf [3] = 0x0b;
- }
+ if (!(*checksum)) {
+ checksum_buf[0] = 0xba;
+ checksum_buf[1] = 0xbe;
+ checksum_buf[2] = 0xb0;
+ checksum_buf[3] = 0x0b;
+ }
- for (ret = 0; ret < (size - 4); ret += 4) {
- checksum_buf[0] ^= (buf[ret]);
- checksum_buf[1] ^= (buf[ret + 1] << 1) ;
- checksum_buf[2] ^= (buf[ret + 2] << 2);
- checksum_buf[3] ^= (buf[ret + 3] << 3);
- }
+ for (ret = 0; ret < (size - 4); ret += 4) {
+ checksum_buf[0] ^= (buf[ret]);
+ checksum_buf[1] ^= (buf[ret + 1] << 1);
+ checksum_buf[2] ^= (buf[ret + 2] << 2);
+ checksum_buf[3] ^= (buf[ret + 3] << 3);
+ }
- for (ret = 0; ret <= (size % 4); ret++) {
- checksum_buf[ret] ^= (buf[(size - 4) + ret] << ret);
- }
+ for (ret = 0; ret <= (size % 4); ret++) {
+ checksum_buf[ret] ^= (buf[(size - 4) + ret] << ret);
+ }
- return;
+ return;
}
#define GF_CHECKSUM_BUF_SIZE 1024
int
-get_checksum_for_file (int fd, uint32_t *checksum)
+get_checksum_for_file(int fd, uint32_t *checksum, int op_version)
{
- int ret = -1;
- char buf[GF_CHECKSUM_BUF_SIZE] = {0,};
+ int ret = -1;
+ char buf[GF_CHECKSUM_BUF_SIZE] = {
+ 0,
+ };
- /* goto first place */
- lseek (fd, 0L, SEEK_SET);
- do {
- ret = read (fd, &buf, GF_CHECKSUM_BUF_SIZE);
- if (ret > 0)
- compute_checksum (buf, GF_CHECKSUM_BUF_SIZE,
- checksum);
- } while (ret > 0);
+ /* goto first place */
+ sys_lseek(fd, 0L, SEEK_SET);
+ do {
+ ret = sys_read(fd, &buf, GF_CHECKSUM_BUF_SIZE);
+ if (ret > 0) {
+ if (op_version < GD_OP_VERSION_5_4)
+ compute_checksum(buf, GF_CHECKSUM_BUF_SIZE, checksum);
+ else
+ compute_checksum(buf, ret, checksum);
+ }
+ } while (ret > 0);
- /* set it back */
- lseek (fd, 0L, SEEK_SET);
+ /* set it back */
+ sys_lseek(fd, 0L, SEEK_SET);
- return ret;
+ return ret;
}
-
int
-get_checksum_for_path (char *path, uint32_t *checksum)
+get_checksum_for_path(char *path, uint32_t *checksum, int op_version)
{
- int ret = -1;
- int fd = -1;
+ int ret = -1;
+ int fd = -1;
- GF_ASSERT (path);
- GF_ASSERT (checksum);
+ GF_ASSERT(path);
+ GF_ASSERT(checksum);
- fd = open (path, O_RDWR);
+ fd = open(path, O_RDWR);
- if (fd == -1) {
- gf_msg (THIS->name, GF_LOG_ERROR, errno, LG_MSG_PATH_ERROR,
- "Unable to open %s", path);
- goto out;
- }
+ if (fd == -1) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_PATH_OPEN_FAILED,
+ "path=%s", path, NULL);
+ goto out;
+ }
- ret = get_checksum_for_file (fd, checksum);
+ ret = get_checksum_for_file(fd, checksum, op_version);
out:
- if (fd != -1)
- close (fd);
+ if (fd != -1)
+ sys_close(fd);
- return ret;
+ return ret;
}
/**
@@ -1819,26 +2137,25 @@ out:
* errors : Errors returned by the stat () call
*/
int
-get_file_mtime (const char *path, time_t *stamp)
+get_file_mtime(const char *path, time_t *stamp)
{
- struct stat f_stat = {0};
- int ret = -EINVAL;
+ struct stat f_stat = {0};
+ int ret = -EINVAL;
- GF_VALIDATE_OR_GOTO (THIS->name, path, out);
- GF_VALIDATE_OR_GOTO (THIS->name, stamp, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, path, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, stamp, out);
- ret = stat (path, &f_stat);
- if (ret < 0) {
- gf_msg (THIS->name, GF_LOG_ERROR, errno,
- LG_MSG_FILE_STAT_FAILED, "failed to stat %s",
- path);
- goto out;
- }
+ ret = sys_stat(path, &f_stat);
+ if (ret < 0) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED,
+ "path=%s", path, NULL);
+ goto out;
+ }
- /* Set the mtime */
- *stamp = f_stat.st_mtime;
+ /* Set the mtime */
+ *stamp = f_stat.st_mtime;
out:
- return ret;
+ return ret;
}
/**
@@ -1850,268 +2167,402 @@ out:
* @ip_str : The IP to check
* @network: The network to check the IP against.
*
- * @return: success: 0
+ * @return: success: _gf_true
* failure: -EINVAL for bad args, retval of inet_pton otherwise
*/
gf_boolean_t
-gf_is_ip_in_net (const char *network, const char *ip_str)
-{
- unsigned long ip_buf = 0;
- unsigned long net_ip_buf = 0;
- unsigned long subnet_mask = 0;
- int ret = -EINVAL;
- char *slash = NULL;
- char *net_ip = NULL;
- char *subnet = NULL;
- char *net_str = NULL;
- int family = AF_INET;
- gf_boolean_t result = _gf_false;
-
- GF_ASSERT (network);
- GF_ASSERT (ip_str);
-
- if (strchr (network, ':'))
- family = AF_INET6;
- else if (strchr (network, '.'))
- family = AF_INET;
- else {
- family = -1;
- goto out;
- }
-
- net_str = strdupa (network);
- slash = strchr (net_str, '/');
- if (!slash)
- goto out;
- *slash = '\0';
-
- subnet = slash + 1;
- net_ip = net_str;
-
- /* Convert IP address to a long */
- ret = inet_pton (family, ip_str, &ip_buf);
- if (ret < 0)
- gf_msg ("common-utils", GF_LOG_ERROR, errno,
- LG_MSG_INET_PTON_FAILED, "inet_pton() failed");
-
- /* Convert network IP address to a long */
- ret = inet_pton (family, net_ip, &net_ip_buf);
- if (ret < 0) {
- gf_msg ("common-utils", GF_LOG_ERROR, errno,
- LG_MSG_INET_PTON_FAILED, "inet_pton() failed");
- goto out;
- }
-
- /* Converts /x into a mask */
- subnet_mask = (1 << atoi (subnet)) - 1;
-
- result = ((ip_buf & subnet_mask) == (net_ip_buf & subnet_mask));
+gf_is_ip_in_net(const char *network, const char *ip_str)
+{
+ unsigned long ip_buf = 0;
+ unsigned long net_ip_buf = 0;
+ unsigned long subnet_mask = 0;
+ int ret = -EINVAL;
+ char *slash = NULL;
+ char *net_ip = NULL;
+ char *subnet = NULL;
+ char *net_str = NULL;
+ int family = AF_INET;
+ gf_boolean_t result = _gf_false;
+
+ GF_ASSERT(network);
+ GF_ASSERT(ip_str);
+
+ if (strchr(network, ':'))
+ family = AF_INET6;
+ else if (strchr(network, '.'))
+ family = AF_INET;
+ else {
+ goto out;
+ }
+
+ net_str = strdupa(network);
+ slash = strchr(net_str, '/');
+ if (!slash)
+ goto out;
+ *slash = '\0';
+
+ subnet = slash + 1;
+ net_ip = net_str;
+
+ /* Convert IP address to a long */
+ ret = inet_pton(family, ip_str, &ip_buf);
+ if (ret < 0)
+ gf_smsg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED,
+ NULL);
+
+ /* Convert network IP address to a long */
+ ret = inet_pton(family, net_ip, &net_ip_buf);
+ if (ret < 0) {
+ gf_smsg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED,
+ NULL);
+ goto out;
+ }
+
+ /* Converts /x into a mask */
+ subnet_mask = (1 << atoi(subnet)) - 1;
+
+ result = ((ip_buf & subnet_mask) == (net_ip_buf & subnet_mask));
out:
- return result;
+ return result;
}
char *
-strtail (char *str, const char *pattern)
+strtail(char *str, const char *pattern)
{
- int i = 0;
+ int i = 0;
- for (i = 0; str[i] == pattern[i] && str[i]; i++);
+ for (i = 0; str[i] == pattern[i] && str[i]; i++)
+ ;
- if (pattern[i] == '\0')
- return str + i;
+ if (pattern[i] == '\0')
+ return str + i;
- return NULL;
+ return NULL;
}
void
-skipwhite (char **s)
+skipwhite(char **s)
{
- while (isspace (**s))
- (*s)++;
+ while (isspace(**s))
+ (*s)++;
}
-char *
-nwstrtail (char *str, char *pattern)
+void
+gf_strTrim(char **s)
{
- for (;;) {
- skipwhite (&str);
- skipwhite (&pattern);
+ char *end = NULL;
- if (*str != *pattern || !*str)
- break;
+ end = *s + strlen(*s) - 1;
+ while (end > *s && isspace((unsigned char)*end))
+ end--;
- str++;
- pattern++;
- }
+ *(end + 1) = '\0';
+
+ while (isspace(**s))
+ (*s)++;
- return *pattern ? NULL : str;
+ return;
}
-void
-skipword (char **s)
+char *
+nwstrtail(char *str, char *pattern)
{
- if (!*s)
- return;
+ for (;;) {
+ skipwhite(&str);
+ skipwhite(&pattern);
- skipwhite (s);
+ if (*str != *pattern || !*str)
+ break;
- while (!isspace(**s))
- (*s)++;
+ str++;
+ pattern++;
+ }
+
+ return *pattern ? NULL : str;
}
+/**
+ * token_iter_init -- initialize tokenization
+ *
+ * @str: string to be tokenized
+ * @sep: token separator character
+ * @tit: pointer to iteration state
+ *
+ * @return: token string
+ *
+ * The returned token string and tit are
+ * not to be used directly, but through
+ * next_token().
+ */
char *
-get_nth_word (const char *str, int n)
+token_iter_init(char *str, char sep, token_iter_t *tit)
{
- char buf[4096] = {0};
- char *start = NULL;
- char *word = NULL;
- int i = 0;
- int word_len = 0;
- const char *end = NULL;
+ tit->end = str + strlen(str);
+ tit->sep = sep;
- if (!str)
- goto out;
+ return str;
+}
- snprintf (buf, sizeof (buf), "%s", str);
- start = buf;
+/**
+ * next_token -- fetch next token in tokenization
+ * inited by token_iter_init().
+ *
+ * @tokenp: pointer to token
+ * @tit: pointer to iteration state
+ *
+ * @return: true if iteration ends, else false
+ *
+ * The token pointed by @tokenp can be used
+ * after a call to next_token(). When next_token()
+ * returns true the iteration is to be stopped
+ * and the string with which the tokenization
+ * was inited (see token_iter_init() is restored,
+ * apart from dropped tokens (see drop_token()).
+ */
+gf_boolean_t
+next_token(char **tokenp, token_iter_t *tit)
+{
+ char *cursor = NULL;
+ gf_boolean_t is_last = _gf_false;
- for (i = 0; i < n-1; i++)
- skipword (&start);
+ for (cursor = *tokenp; *cursor; cursor++)
+ ;
+ if (cursor < tit->end) {
+ /*
+ * We detect that in between current token and end a zero
+ * marker has already been inserted. This means that the
+ * token has already been returned. We restore the
+ * separator and move ahead.
+ */
+ *cursor = tit->sep;
+ *tokenp = cursor + 1;
+ }
- skipwhite (&start);
- end = strpbrk ((const char *)start, " \t\n\0");
+ for (cursor = *tokenp; *cursor && *cursor != tit->sep; cursor++)
+ ;
+ /* If the cursor ended up on a zero byte, then it's the last token. */
+ is_last = !*cursor;
+ /* Zero-terminate the token. */
+ *cursor = 0;
- if (!end)
- goto out;
+ return is_last;
+}
- word_len = abs (end - start);
+/*
+ * drop_token -- drop a token during iterated calls of next_token().
+ *
+ * Sample program that uses these functions to tokenize
+ * a comma-separated first argument while dropping the
+ * rest of the arguments if they occur as token:
+ *
+ * #include <stdio.h>
+ * #include <stdlib.h>
+ * #include <string.h>
+ * #include "glusterfs/common-utils.h"
+ *
+ * int
+ * main (int argc, char **argv)
+ * {
+ * char *buf;
+ * char *token;
+ * token_iter_t tit;
+ * int i;
+ * gf_boolean_t iter_end;
+ *
+ * if (argc <= 1)
+ * abort();
+ *
+ * buf = strdup (argv[1]);
+ * if (!buf)
+ * abort();
+ *
+ * for (token = token_iter_init (buf, ',', &tit) ;;) {
+ * iter_end = next_token (&token, &tit);
+ * printf("found token: '%s'\n", token);
+ * for (i = 2; i < argc; i++) {
+ * if (strcmp (argv[i], token) == 0) {
+ * printf ("%s\n", "dropping token!");
+ * drop_token (token, &tit);
+ * break;
+ * }
+ * }
+ * if (iter_end)
+ * break;
+ * }
+ *
+ * printf ("finally: '%s'\n", buf);
+ *
+ * return 0;
+ * }
+ */
+void
+drop_token(char *token, token_iter_t *tit)
+{
+ char *cursor = NULL;
- word = GF_CALLOC (1, word_len + 1, gf_common_mt_strdup);
- if (!word)
- goto out;
+ for (cursor = token; *cursor; cursor++)
+ ;
+ if (cursor < tit->end) {
+ /*
+ * We detect a zero inserted by next_token().
+ * Step the cursor and copy what comes after
+ * to token.
+ */
+ for (cursor++; cursor < tit->end; *token++ = *cursor++)
+ ;
+ }
- strncpy (word, start, word_len);
- *(word + word_len) = '\0';
- out:
- return word;
+ /*
+ * Zero out the remainder of the buffer.
+ * It would be enough to insert just a single zero,
+ * but we continue 'till the end to have cleaner
+ * memory content.
+ */
+ for (cursor = token; cursor < tit->end; *cursor++ = 0)
+ ;
+
+ /* Adjust the end to point to the new terminating zero. */
+ tit->end = token;
}
/* Syntax formed according to RFC 1912 (RFC 1123 & 952 are more restrictive) *
<hname> ::= <gen-name>*["."<gen-name>] *
<gen-name> ::= <let-or-digit> <[*[<let-or-digit-or-hyphen>]<let-or-digit>] */
char
-valid_host_name (char *address, int length)
+valid_host_name(char *address, int length)
{
- int i = 0;
- int str_len = 0;
- char ret = 1;
- char *dup_addr = NULL;
- char *temp_str = NULL;
- char *save_ptr = NULL;
+ 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 > _POSIX_HOST_NAME_MAX) || (length < 1)) {
+ ret = 0;
+ goto out;
+ }
- dup_addr = gf_strdup (address);
- if (!dup_addr) {
- ret = 0;
- goto out;
- }
+ dup_addr = gf_strdup(address);
+ if (!dup_addr) {
+ ret = 0;
+ goto out;
+ }
+
+ if (!isalnum(dup_addr[length - 1]) && (dup_addr[length - 1] != '*')) {
+ ret = 0;
+ goto out;
+ }
+
+ /* Check for consecutive dots, which is invalid in a hostname and is
+ * ignored by strtok()
+ */
+ if (strstr(dup_addr, "..")) {
+ ret = 0;
+ goto out;
+ }
- if (!isalnum (dup_addr[length - 1]) && (dup_addr[length - 1] != '*')) {
+ /* gen-name */
+ temp_str = strtok_r(dup_addr, ".", &save_ptr);
+ do {
+ str_len = strlen(temp_str);
+
+ if (!isalnum(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;
+ }
}
+ } while ((temp_str = strtok_r(NULL, ".", &save_ptr)));
- /* Check for consecutive dots, which is invalid in a hostname and is
- * ignored by strtok()
- */
- if (strstr (dup_addr, "..")) {
+out:
+ GF_FREE(dup_addr);
+ return ret;
+}
+
+/* Matches all ipv4 address, if wildcard_acc is true '*' wildcard pattern for*
+ subnets is considered as valid strings as well */
+char
+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 '.' and which have
+ * consecutive dots like ".." as strtok ignore consecutive
+ * delimiters.
+ */
+ if (length <= 0 || (strstr(address, "..")) ||
+ (!isdigit(tmp[length - 1]) && (tmp[length - 1] != '*'))) {
+ ret = 0;
+ goto out;
+ }
+
+ prev = strtok_r(tmp, ".", &ptr);
+
+ while (prev != NULL) {
+ octets++;
+ 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);
+ }
- /* gen-name */
- temp_str = strtok_r (dup_addr, ".", &save_ptr);
- do {
- str_len = strlen (temp_str);
-
- if (!isalnum (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;
- }
- }
- } while ((temp_str = strtok_r (NULL, ".", &save_ptr)));
+ if ((octets > 4) || (octets < 4 && !is_wildcard)) {
+ ret = 0;
+ }
out:
- GF_FREE (dup_addr);
- return ret;
+ GF_FREE(tmp);
+ return ret;
}
-/* Matches all ipv4 address, if wildcard_acc is true '*' wildcard pattern for*
- subnets is considered as valid strings as well */
char
-valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc)
+valid_cidr_address(char *cidr_address, 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;
+ unsigned int net_mask = 0, len = 0;
+ char *temp = NULL, *cidr_str = NULL, ret = 1;
- tmp = gf_strdup (address);
+ cidr_str = strdupa(cidr_address);
+ temp = strstr(cidr_str, "/");
+ if (temp == NULL)
+ return 0; /* Since Invalid cidr ip address we return 0 */
- /*
- * To prevent cases where last character is '.' and which have
- * consecutive dots like ".." as strtok ignore consecutive
- * delimeters.
- */
- if (length <= 0 ||
- (strstr (address, "..")) ||
- (!isdigit (tmp[length - 1]) && (tmp[length - 1] != '*'))) {
- ret = 0;
- goto out;
- }
+ *temp = '\0';
+ temp++;
+ net_mask = (unsigned int)atoi(temp);
- prev = tmp;
- prev = strtok_r (tmp, ".", &ptr);
-
- while (prev != NULL) {
- octets++;
- 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 (net_mask > 32 || net_mask < 1)
+ return 0; /* Since Invalid cidr ip address we return 0*/
- if ((octets > 4) || (octets < 4 && !is_wildcard)) {
- ret = 0;
- }
+ len = strlen(cidr_str);
-out:
- GF_FREE (tmp);
- return ret;
+ ret = valid_ipv4_address(cidr_str, len, wildcard_acc);
+
+ return ret;
}
/**
* valid_ipv4_subnetwork() takes the pattern and checks if it contains
* a valid ipv4 subnetwork pattern i.e. xx.xx.xx.xx/n. IPv4 address
- * part (xx.xx.xx.xx) and mask bits lengh part (n). The mask bits lengh
+ * part (xx.xx.xx.xx) and mask bits length part (n). The mask bits length
* must be in 0-32 range (ipv4 addr is 32 bit). The pattern must be
* in this format.
*
@@ -2119,141 +2570,158 @@ out:
* _gf_false otherwise.
*/
gf_boolean_t
-valid_ipv4_subnetwork (const char *address)
+valid_ipv4_subnetwork(const char *address)
{
- char *slash = NULL;
- char *paddr = NULL;
- char *endptr = NULL;
- long prefixlen = -1;
- gf_boolean_t retv = _gf_true;
-
- if (address == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- return _gf_false;
- }
-
- paddr = gf_strdup (address);
- if (paddr == NULL) /* ENOMEM */
- return _gf_false;
-
- /*
- * INVALID: If '/' is not present OR
- * Nothing specified after '/'
- */
- slash = strchr(paddr, '/');
- if ((slash == NULL) || (slash[1] == '\0')) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INVALID_IPV4_FORMAT, "Invalid IPv4 "
- "subnetwork format");
- retv = _gf_false;
- goto out;
- }
+ char *slash = NULL;
+ char *paddr = NULL;
+ char *endptr = NULL;
+ long prefixlen = -1;
+ gf_boolean_t retv = _gf_true;
- *slash = '\0';
- retv = valid_ipv4_address (paddr, strlen(paddr), _gf_false);
- if (retv == _gf_false) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INVALID_IPV4_FORMAT,
- "Invalid IPv4 subnetwork address");
- goto out;
- }
+ if (address == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return _gf_false;
+ }
- prefixlen = strtol (slash + 1, &endptr, 10);
- if ((errno != 0) || (*endptr != '\0') ||
- (prefixlen < 0) || (prefixlen > IPv4_ADDR_SIZE)) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INVALID_IPV4_FORMAT,
- "Invalid IPv4 subnetwork mask");
- retv = _gf_false;
- goto out;
- }
+ paddr = gf_strdup(address);
+ if (paddr == NULL) /* ENOMEM */
+ return _gf_false;
- retv = _gf_true;
+ /*
+ * INVALID: If '/' is not present OR
+ * Nothing specified after '/'
+ */
+ slash = strchr(paddr, '/');
+ if ((slash == NULL) || (slash[1] == '\0')) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_INVALID_IPV4_FORMAT,
+ "Invalid IPv4 "
+ "subnetwork format");
+ retv = _gf_false;
+ goto out;
+ }
+
+ *slash = '\0';
+ retv = valid_ipv4_address(paddr, strlen(paddr), _gf_false);
+ if (retv == _gf_false) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_INVALID_IPV4_FORMAT,
+ "Invalid IPv4 subnetwork address");
+ goto out;
+ }
+ /*
+ * Reset errno before checking it
+ */
+ errno = 0;
+ prefixlen = strtol(slash + 1, &endptr, 10);
+ if ((errno != 0) || (*endptr != '\0') || (prefixlen < 0) ||
+ (prefixlen > IPv4_ADDR_SIZE)) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_INVALID_IPV4_FORMAT,
+ "Invalid IPv4 subnetwork mask");
+ retv = _gf_false;
+ goto out;
+ }
+
+ retv = _gf_true;
out:
- GF_FREE (paddr);
- return retv;
+ GF_FREE(paddr);
+ return retv;
}
char
-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 (length <= 0 || tmp[length - 1] == ':') {
+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 '%' for link local addresses */
+ endptr = strchr(tmp, '%');
+ if (endptr) {
+ *endptr = '\0';
+ length = strlen(tmp);
+ endptr = NULL;
+ }
+
+ /* Check for compressed form */
+ if (length <= 0 || 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;
+ }
}
- 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) {
- hex_numbers++;
- 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);
- }
+ prev = strtok_r(tmp, ":", &ptr);
- if ((hex_numbers > 8) || (hex_numbers < 8 && !is_wildcard
- && !is_compressed)) {
+ while (prev != NULL) {
+ hex_numbers++;
+ 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) ||
+ (hex_numbers < 8 && !is_wildcard && !is_compressed)) {
+ ret = 0;
+ }
out:
- GF_FREE (tmp);
- return ret;
+ GF_FREE(tmp);
+ return ret;
}
char
-valid_internet_address (char *address, gf_boolean_t wildcard_acc)
+valid_internet_address(char *address, gf_boolean_t wildcard_acc,
+ gf_boolean_t cidr)
{
- char ret = 0;
- int length = 0;
+ char ret = 0;
+ int length = 0;
- if (address == NULL) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- goto out;
- }
+ if (address == NULL) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ goto out;
+ }
- length = strlen (address);
- if (length == 0)
- goto out;
+ length = strlen(address);
+ if (length == 0)
+ goto out;
- if (valid_ipv4_address (address, length, wildcard_acc)
- || valid_ipv6_address (address, length, wildcard_acc)
- || valid_host_name (address, length))
- ret = 1;
+ if (cidr && valid_cidr_address(address, wildcard_acc)) {
+ ret = 1;
+ }
+
+ 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;
+ return ret;
}
/**
@@ -2263,56 +2731,56 @@ out:
*
* @return _gf_true if "address" is "*" (anonymous) 'OR'
* if "address" is valid FQDN or valid IPv4/6 address 'OR'
- * if "address" contains wildcard chars e.g. "'*' or '?' or '['"
- * if "address" is valid ipv4 subnet pattern (xx.xx.xx.xx/n)
- * _gf_false otherwise
+ * if "address" contains wildcard chars e.g. "'*' or '?' or
+ * '['" if "address" is valid ipv4 subnet pattern (xx.xx.xx.xx/n) _gf_false
+ * otherwise
*
*
* NB: If the user/admin set for wildcard pattern, then it does not have
* to be validated. Make it similar to the way exportfs (kNFS) works.
*/
gf_boolean_t
-valid_mount_auth_address (char *address)
+valid_mount_auth_address(char *address)
{
- int length = 0;
- char *cp = NULL;
+ int length = 0;
+ char *cp = NULL;
- /* 1. Check for "NULL and empty string */
- if ((address == NULL) || (address[0] == '\0')){
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "argument invalid");
- return _gf_false;
- }
+ /* 1. Check for "NULL and empty string */
+ if ((address == NULL) || (address[0] == '\0')) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "argument invalid");
+ return _gf_false;
+ }
- /* 2. Check for Anonymous */
- if (strcmp(address, "*") == 0)
- return _gf_true;
+ /* 2. Check for Anonymous */
+ if (strcmp(address, "*") == 0)
+ return _gf_true;
- for (cp = address; *cp; cp++) {
- /* 3. Check for wildcard pattern */
- if (*cp == '*' || *cp == '?' || *cp == '[') {
- return _gf_true;
- }
-
- /*
- * 4. check for IPv4 subnetwork i.e. xx.xx.xx.xx/n
- * TODO: check for IPv6 subnetwork
- * NB: Wildcard must not be mixed with subnetwork.
- */
- if (*cp == '/') {
- return valid_ipv4_subnetwork (address);
- }
+ for (cp = address; *cp; cp++) {
+ /* 3. Check for wildcard pattern */
+ if (*cp == '*' || *cp == '?' || *cp == '[') {
+ return _gf_true;
}
- /* 5. Check for v4/v6 IP addr and FQDN/hostname */
- length = strlen (address);
- if ((valid_ipv4_address (address, length, _gf_false)) ||
- (valid_ipv6_address (address, length, _gf_false)) ||
- (valid_host_name (address, length))) {
- return _gf_true;
+ /*
+ * 4. check for IPv4 subnetwork i.e. xx.xx.xx.xx/n
+ * TODO: check for IPv6 subnetwork
+ * NB: Wildcard must not be mixed with subnetwork.
+ */
+ if (*cp == '/') {
+ return valid_ipv4_subnetwork(address);
}
+ }
- return _gf_false;
+ /* 5. Check for v4/v6 IP addr and FQDN/hostname */
+ length = strlen(address);
+ if ((valid_ipv4_address(address, length, _gf_false)) ||
+ (valid_ipv6_address(address, length, _gf_false)) ||
+ (valid_host_name(address, length))) {
+ return _gf_true;
+ }
+
+ return _gf_false;
}
/**
@@ -2323,40 +2791,39 @@ valid_mount_auth_address (char *address)
* @return _gf_true if a and b have same ipv{4,6} addr, _gf_false otherwise
*/
gf_boolean_t
-gf_sock_union_equal_addr (union gf_sock_union *a,
- union gf_sock_union *b)
+gf_sock_union_equal_addr(union gf_sock_union *a, union gf_sock_union *b)
{
- if (!a || !b) {
- gf_msg ("common-utils", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
- "Invalid arguments to gf_sock_union_equal_addr");
- return _gf_false;
- }
+ if (!a || !b) {
+ gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
+ "gf_sock_union_equal_addr", NULL);
+ return _gf_false;
+ }
- if (a->storage.ss_family != b->storage.ss_family)
- return _gf_false;
+ if (a->storage.ss_family != b->storage.ss_family)
+ return _gf_false;
- switch (a->storage.ss_family) {
+ switch (a->storage.ss_family) {
case AF_INET:
- if (a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr)
- return _gf_true;
- else
- return _gf_false;
+ if (a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr)
+ return _gf_true;
+ else
+ return _gf_false;
case AF_INET6:
- if (memcmp ((void *)(&a->sin6.sin6_addr),
- (void *)(&b->sin6.sin6_addr),
- sizeof (a->sin6.sin6_addr)))
- return _gf_false;
- else
- return _gf_true;
+ if (memcmp((void *)(&a->sin6.sin6_addr),
+ (void *)(&b->sin6.sin6_addr), sizeof(a->sin6.sin6_addr)))
+ return _gf_false;
+ else
+ return _gf_true;
default:
- gf_msg_debug ("common-utils", 0, "Unsupported/invalid address "
- "family");
- break;
- }
+ gf_msg_debug("common-utils", 0,
+ "Unsupported/invalid address "
+ "family");
+ break;
+ }
- return _gf_false;
+ return _gf_false;
}
/*
@@ -2372,113 +2839,178 @@ gf_sock_union_equal_addr (union gf_sock_union *a,
gf_boolean_t
mask_match(const uint32_t a, const uint32_t b, const uint32_t m)
{
- return (((a ^ b) & m) == 0);
+ return (((a ^ b) & m) == 0);
}
-
/*Thread safe conversion function*/
char *
-uuid_utoa (uuid_t uuid)
+uuid_utoa(uuid_t uuid)
{
- char *uuid_buffer = glusterfs_uuid_buf_get ();
- gf_uuid_unparse (uuid, uuid_buffer);
- return uuid_buffer;
+ char *uuid_buffer = glusterfs_uuid_buf_get();
+ gf_uuid_unparse(uuid, uuid_buffer);
+ return uuid_buffer;
}
/*Re-entrant conversion function*/
char *
-uuid_utoa_r (uuid_t uuid, char *dst)
+uuid_utoa_r(uuid_t uuid, char *dst)
{
- if(!dst)
- return NULL;
- gf_uuid_unparse (uuid, dst);
- return dst;
+ if (!dst)
+ return NULL;
+ gf_uuid_unparse(uuid, dst);
+ return dst;
}
/*Thread safe conversion function*/
char *
-lkowner_utoa (gf_lkowner_t *lkowner)
+lkowner_utoa(gf_lkowner_t *lkowner)
{
- char *lkowner_buffer = glusterfs_lkowner_buf_get ();
- lkowner_unparse (lkowner, lkowner_buffer, GF_LKOWNER_BUF_SIZE);
- return lkowner_buffer;
+ 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)
+lkowner_utoa_r(gf_lkowner_t *lkowner, char *dst, int len)
+{
+ if (!dst)
+ return NULL;
+ lkowner_unparse(lkowner, dst, len);
+ return dst;
+}
+
+gf_boolean_t
+is_valid_lease_id(const char *lease_id)
+{
+ int i = 0;
+ gf_boolean_t valid = _gf_false;
+
+ for (i = 0; i < LEASE_ID_SIZE; i++) {
+ if (lease_id[i] != 0) {
+ valid = _gf_true;
+ goto out;
+ }
+ }
+out:
+ return valid;
+}
+
+/* Lease_id can be a either in printable or non printable binary
+ * format. This function can be used to print any lease_id.
+ *
+ * This function returns a pointer to a buf, containing the ascii
+ * representation of the value in lease_id, in the following format:
+ * 4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum
+ *
+ * Eg: If lease_id = "lid1-clnt1" the printable string would be:
+ * 6c69-6431-2d63-6c6e-7431-0000-0000-0000
+ *
+ * Note: The pointer returned should not be stored for further use, as any
+ * subsequent call to this function will override the same buffer.
+ */
+char *
+leaseid_utoa(const char *lease_id)
+{
+ char *buf = NULL;
+ int i = 0;
+ int j = 0;
+
+ buf = glusterfs_leaseid_buf_get();
+ if (!buf)
+ goto out;
+
+ for (i = 0; i < LEASE_ID_SIZE; i++) {
+ if (i && !(i % 2)) {
+ buf[j] = '-';
+ j++;
+ }
+ sprintf(&buf[j], "%02hhx", lease_id[i]);
+ j += 2;
+ if (j == GF_LEASE_ID_BUF_SIZE)
+ break;
+ }
+ buf[GF_LEASE_ID_BUF_SIZE - 1] = '\0';
+out:
+ return buf;
+}
+
+char *
+gf_leaseid_get()
{
- if(!dst)
- return NULL;
- lkowner_unparse (lkowner, dst, len);
- return dst;
+ return glusterfs_leaseid_buf_get();
}
-void* gf_array_elem (void *a, int index, size_t elem_size)
+char *
+gf_existing_leaseid()
+{
+ return glusterfs_leaseid_exist();
+}
+
+void *
+gf_array_elem(void *a, int index, size_t elem_size)
{
- uint8_t* ptr = a;
- return (void*)(ptr + index * elem_size);
+ uint8_t *ptr = a;
+ return (void *)(ptr + index * elem_size);
}
void
-gf_elem_swap (void *x, void *y, size_t l) {
- uint8_t *a = x, *b = y, c;
- while(l--) {
- c = *a;
- *a++ = *b;
- *b++ = c;
- }
+gf_elem_swap(void *x, void *y, size_t l)
+{
+ uint8_t *a = x, *b = y, c;
+ while (l--) {
+ c = *a;
+ *a++ = *b;
+ *b++ = c;
+ }
}
void
-gf_array_insertionsort (void *A, int l, int r, size_t elem_size,
- gf_cmp cmp)
-{
- int i = l;
- int N = r+1;
- void *Temp = NULL;
- int j = 0;
-
- 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) {
- gf_elem_swap (Temp, gf_array_elem (A, j, elem_size),
- elem_size);
- Temp = gf_array_elem (A, j, elem_size);
- j = j-1;
- }
+gf_array_insertionsort(void *A, int l, int r, size_t elem_size, gf_cmp cmp)
+{
+ int i = l;
+ int N = r + 1;
+ void *Temp = NULL;
+ int j = 0;
+
+ for (i = l; i < N; i++) {
+ Temp = gf_array_elem(A, i, elem_size);
+ j = i - 1;
+ while (j >= 0 && (cmp(Temp, gf_array_elem(A, j, elem_size)) < 0)) {
+ gf_elem_swap(Temp, gf_array_elem(A, j, elem_size), elem_size);
+ Temp = gf_array_elem(A, j, elem_size);
+ j = j - 1;
}
+ }
}
int
-gf_is_str_int (const char *value)
+gf_is_str_int(const char *value)
{
- int flag = 0;
- char *str = NULL;
- char *fptr = NULL;
+ int flag = 0;
+ char *str = NULL;
+ char *fptr = NULL;
- GF_VALIDATE_OR_GOTO (THIS->name, value, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, value, out);
- str = gf_strdup (value);
- if (!str)
- goto out;
+ str = gf_strdup(value);
+ if (!str)
+ goto out;
- fptr = str;
+ fptr = str;
- while (*str) {
- if (!isdigit(*str)) {
- flag = 1;
- goto out;
- }
- str++;
+ while (*str) {
+ if (!isdigit(*str)) {
+ flag = 1;
+ goto out;
}
+ str++;
+ }
out:
- GF_FREE (fptr);
+ GF_FREE(fptr);
- return flag;
+ return flag;
}
/*
* rounds up nr to power of two. If nr is already a power of two, just returns
@@ -2486,22 +3018,22 @@ out:
*/
int32_t
-gf_roundup_power_of_two (int32_t nr)
+gf_roundup_power_of_two(int32_t nr)
{
- int32_t result = 1;
+ int32_t result = 1;
- if (nr < 0) {
- gf_msg ("common-utils", GF_LOG_WARNING, 0,
- LG_MSG_NEGATIVE_NUM_PASSED, "negative number passed");
- result = -1;
- goto out;
- }
+ if (nr < 0) {
+ gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED,
+ NULL);
+ result = -1;
+ goto out;
+ }
- while (result < nr)
- result *= 2;
+ while (result < nr)
+ result *= 2;
out:
- return result;
+ return result;
}
/*
@@ -2510,383 +3042,365 @@ out:
*/
int32_t
-gf_roundup_next_power_of_two (int32_t nr)
+gf_roundup_next_power_of_two(int32_t nr)
{
- int32_t result = 1;
+ int32_t result = 1;
- if (nr < 0) {
- gf_msg ("common-utils", GF_LOG_WARNING, 0,
- LG_MSG_NEGATIVE_NUM_PASSED, "negative number passed");
- result = -1;
- goto out;
- }
+ if (nr < 0) {
+ gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED,
+ NULL);
+ result = -1;
+ goto out;
+ }
- while (result <= nr)
- result *= 2;
+ while (result <= nr)
+ result *= 2;
out:
- return result;
+ return result;
}
int
-validate_brick_name (char *brick)
+validate_brick_name(char *brick)
{
- char *delimiter = NULL;
- int ret = 0;
- delimiter = strrchr (brick, ':');
- if (!delimiter || delimiter == brick
- || *(delimiter+1) != '/')
- ret = -1;
+ char *delimiter = NULL;
+ int ret = 0;
+ delimiter = strrchr(brick, ':');
+ if (!delimiter || delimiter == brick || *(delimiter + 1) != '/')
+ ret = -1;
- return ret;
+ return ret;
}
char *
-get_host_name (char *word, char **host)
+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 *delimiter = NULL;
+ delimiter = strrchr(word, ':');
+ if (delimiter)
+ *delimiter = '\0';
+ else
+ return NULL;
+ *host = word;
+ return *host;
}
-
char *
-get_path_name (char *word, char **path)
+get_path_name(char *word, char **path)
{
- char *delimiter = NULL;
- delimiter = strchr (word, '/');
- if (!delimiter)
- return NULL;
- *path = delimiter;
- return *path;
+ char *delimiter = NULL;
+ delimiter = strchr(word, '/');
+ if (!delimiter)
+ return NULL;
+ *path = delimiter;
+ return *path;
}
void
-gf_path_strip_trailing_slashes (char *path)
+gf_path_strip_trailing_slashes(char *path)
{
- int i = 0;
- int len = 0;
+ int i = 0;
+ int len = 0;
- if (!path)
- return;
+ if (!path)
+ return;
- len = strlen (path);
- for (i = len - 1; i > 0; i--) {
- if (path[i] != '/')
- break;
- }
+ len = strlen(path);
+ for (i = len - 1; i > 0; i--) {
+ if (path[i] != '/')
+ break;
+ }
- if (i < (len -1))
- path [i+1] = '\0';
+ if (i < (len - 1))
+ path[i + 1] = '\0';
- return;
+ return;
}
uint64_t
-get_mem_size ()
+get_mem_size()
{
- uint64_t memsize = -1;
+ 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;
+ 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_DARWIN_HOST_OS || defined __FreeBSD__
- page_size = sysconf (_SC_PAGESIZE);
- num_pages = sysconf (_SC_PHYS_PAGES);
+ size_t len = sizeof(memsize);
+ int name[] = {CTL_HW, HW_PHYSMEM};
- memsize = page_size * num_pages;
+ sysctl(name, 2, &memsize, &len, NULL, 0);
#endif
-#if defined GF_BSD_HOST_OS || defined GF_DARWIN_HOST_OS
+#if defined __NetBSD__
- size_t len = sizeof(memsize);
- int name [] = { CTL_HW, HW_PHYSMEM };
+ size_t len = sizeof(memsize);
+ int name64[] = {CTL_HW, HW_PHYSMEM64};
- sysctl (name, 2, &memsize, &len, NULL, 0);
+ sysctl(name64, 2, &memsize, &len, NULL, 0);
+ if (memsize == -1)
+ sysctl(name64, 2, &memsize, &len, NULL, 0);
#endif
- return memsize;
+ 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)
+gf_strip_whitespace(char *str, int len)
{
- int i = 0;
- int new_len = 0;
- char *new_str = NULL;
+ int i = 0;
+ int new_len = 0;
+ char *new_str = NULL;
- GF_ASSERT (str);
+ GF_ASSERT(str);
- new_str = GF_CALLOC (1, len + 1, gf_common_mt_char);
- if (new_str == NULL)
- return -1;
+ new_str = GF_MALLOC(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';
+ 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);
- }
+ if (new_len != len) {
+ snprintf(str, new_len + 1, "%s", new_str);
+ }
- GF_FREE (new_str);
- return new_len;
+ GF_FREE(new_str);
+ return new_len;
}
int
-gf_canonicalize_path (char *path)
+gf_canonicalize_path(char *path)
{
- int ret = -1;
- int path_len = 0;
- int dir_path_len = 0;
- char *tmppath = NULL;
- char *dir = NULL;
- char *tmpstr = NULL;
+ int ret = -1;
+ int path_len = 0;
+ int dir_path_len = 0;
+ char *tmppath = NULL;
+ char *dir = NULL;
+ char *tmpstr = NULL;
- if (!path || *path != '/')
- goto out;
+ if (!path || *path != '/')
+ goto out;
- if (!strcmp (path, "/"))
- return 0;
+ if (!strcmp(path, "/"))
+ return 0;
- tmppath = gf_strdup (path);
- if (!tmppath)
- goto out;
+ tmppath = gf_strdup(path);
+ if (!tmppath)
+ goto out;
- /* Strip the extra slashes and return */
- bzero (path, strlen(path));
- path[0] = '/';
- dir = strtok_r(tmppath, "/", &tmpstr);
-
- while (dir) {
- dir_path_len = strlen(dir);
- strncpy ((path + path_len + 1), dir, dir_path_len);
- path_len += dir_path_len + 1;
- dir = strtok_r (NULL, "/", &tmpstr);
- if (dir)
- strncpy ((path + path_len), "/", 1);
+ /* Strip the extra slashes and return */
+ bzero(path, strlen(path));
+ path[0] = '/';
+ dir = strtok_r(tmppath, "/", &tmpstr);
+
+ while (dir) {
+ dir_path_len = strlen(dir);
+ memcpy((path + path_len + 1), dir, dir_path_len);
+ path_len += dir_path_len + 1;
+ dir = strtok_r(NULL, "/", &tmpstr);
+ if (dir) {
+ path[path_len] = '/';
}
- path[path_len] = '\0';
- ret = 0;
+ }
+ path[path_len] = '\0';
+ ret = 0;
- out:
- if (ret)
- gf_msg ("common-utils", GF_LOG_ERROR, 0, LG_MSG_PATH_ERROR,
- "Path manipulation failed");
+out:
+ if (ret)
+ gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_PATH_ERROR, NULL);
- GF_FREE(tmppath);
+ GF_FREE(tmppath);
- return ret;
+ return ret;
}
static const char *__gf_timefmts[] = {
- "%F %T",
- "%Y/%m/%d-%T",
- "%b %d %T",
- "%F %H%M%S",
- "%Y-%m-%d-%T",
- "%s",
+ "%F %T", "%Y/%m/%d-%T", "%b %d %T", "%F %H%M%S", "%Y-%m-%d-%T", "%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",
- "0000-00-00-00:00:00",
- "0",
+ "0000-00-00 00:00:00", "0000/00/00-00:00:00", "xxx 00 00:00:00",
+ "0000-00-00 000000", "0000-00-00-00:00:00", "0",
};
void
-_gf_timestuff (gf_timefmts *fmt, const char ***fmts, const char ***zeros)
+_gf_timestuff(const char ***fmts, const char ***zeros)
{
- *fmt = gf_timefmt_last;
- *fmts = __gf_timefmts;
- *zeros = __gf_zerotimes;
+ *fmts = __gf_timefmts;
+ *zeros = __gf_zerotimes;
}
-
char *
-generate_glusterfs_ctx_id (void)
+generate_glusterfs_ctx_id(void)
{
- char tmp_str[1024] = {0,};
- char hostname[256] = {0,};
- struct timeval tv = {0,};
- char now_str[32];
-
- if (gettimeofday (&tv, NULL) == -1) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno,
- LG_MSG_GETTIMEOFDAY_FAILED, "gettimeofday: "
- "failed");
- }
-
- if (gethostname (hostname, 256) == -1) {
- gf_msg ("glusterfsd", GF_LOG_ERROR, errno,
- LG_MSG_GETHOSTNAME_FAILED, "gethostname: failed");
- }
+ uuid_t ctxid;
+ char *tmp = NULL;
- 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
- "ld",
-#endif
- hostname, getpid(), now_str, tv.tv_usec);
+ gf_uuid_generate(ctxid);
+ tmp = uuid_utoa(ctxid);
- return gf_strdup (tmp_str);
+ return gf_strdup(tmp);
}
char *
-gf_get_reserved_ports ()
+gf_get_reserved_ports()
{
- char *ports_info = NULL;
+ char *ports_info = NULL;
#if defined GF_LINUX_HOST_OS
- int proc_fd = -1;
- char *proc_file = "/proc/sys/net/ipv4/ip_local_reserved_ports";
- char buffer[4096] = {0,};
- int32_t ret = -1;
-
- proc_fd = open (proc_file, O_RDONLY);
- if (proc_fd == -1) {
- /* What should be done in this case? error out from here
- * and thus stop the glusterfs process from starting or
- * continue with older method of using any of the available
- * port? For now 2nd option is considered.
- */
- gf_msg ("glusterfs", GF_LOG_WARNING, errno,
- LG_MSG_FILE_OP_FAILED, "could not open the file "
- "/proc/sys/net/ipv4/ip_local_reserved_ports for "
- "getting reserved ports info");
- goto out;
- }
+ int proc_fd = -1;
+ char *proc_file = "/proc/sys/net/ipv4/ip_local_reserved_ports";
+ char buffer[4096] = {
+ 0,
+ };
+ int32_t ret = -1;
+
+ proc_fd = open(proc_file, O_RDONLY);
+ if (proc_fd == -1) {
+ /* What should be done in this case? error out from here
+ * and thus stop the glusterfs process from starting or
+ * continue with older method of using any of the available
+ * port? For now 2nd option is considered.
+ */
+ gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ " /proc/sys/net/ipv4/ip_local_reserved_ports", NULL);
+ goto out;
+ }
- ret = read (proc_fd, buffer, sizeof (buffer));
- if (ret < 0) {
- gf_msg ("glusterfs", GF_LOG_WARNING, errno,
- LG_MSG_FILE_OP_FAILED, "could not read the file %s for"
- " getting reserved ports info", proc_file);
- goto out;
- }
- ports_info = gf_strdup (buffer);
+ ret = sys_read(proc_fd, buffer, sizeof(buffer) - 1);
+ if (ret < 0) {
+ gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "file=%s", proc_file, NULL);
+ goto out;
+ }
+
+ buffer[ret] = '\0';
+ ports_info = gf_strdup(buffer);
out:
- if (proc_fd != -1)
- close (proc_fd);
+ if (proc_fd != -1)
+ sys_close(proc_fd);
#endif /* GF_LINUX_HOST_OS */
- return ports_info;
+ return ports_info;
}
int
-gf_process_reserved_ports (gf_boolean_t *ports, uint32_t ceiling)
+gf_process_reserved_ports(unsigned char *ports, uint32_t ceiling)
{
- int ret = -1;
+ int ret = -1;
+
+ memset(ports, 0, GF_PORT_ARRAY_SIZE);
+
#if defined GF_LINUX_HOST_OS
- char *ports_info = NULL;
- char *tmp = NULL;
- char *blocked_port = NULL;
-
- ports_info = gf_get_reserved_ports ();
- if (!ports_info) {
- gf_msg ("glusterfs", GF_LOG_WARNING, 0,
- LG_MSG_RESERVED_PORTS_ERROR, "Not able to get reserved"
- " ports, hence there is a possibility that glusterfs "
- "may consume reserved port");
- goto out;
- }
+ char *ports_info = NULL;
+ char *tmp = NULL;
+ char *blocked_port = NULL;
- blocked_port = strtok_r (ports_info, ",\n",&tmp);
+ ports_info = gf_get_reserved_ports();
+ if (!ports_info) {
+ gf_smsg("glusterfs", GF_LOG_WARNING, 0, LG_MSG_RESERVED_PORTS_ERROR,
+ NULL);
+ goto out;
+ }
- while (blocked_port) {
- gf_ports_reserved (blocked_port, ports, ceiling);
- blocked_port = strtok_r (NULL, ",\n", &tmp);
- }
+ blocked_port = strtok_r(ports_info, ",\n", &tmp);
- ret = 0;
+ while (blocked_port) {
+ gf_ports_reserved(blocked_port, ports, ceiling);
+ blocked_port = strtok_r(NULL, ",\n", &tmp);
+ }
+
+ ret = 0;
out:
- GF_FREE (ports_info);
+ GF_FREE(ports_info);
+
+#else /* FIXME: Non Linux Host */
+ ret = 0;
#endif /* GF_LINUX_HOST_OS */
- return ret;
+
+ return ret;
}
gf_boolean_t
-gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling)
-{
- gf_boolean_t result = _gf_false;
- char *range_port = NULL;
- int16_t tmp_port1 = -1;
- int16_t tmp_port2 = -1;
-
- if (strstr (blocked_port, "-") == NULL) {
- /* get rid of the new line character*/
- if (blocked_port[strlen(blocked_port) -1] == '\n')
- blocked_port[strlen(blocked_port) -1] = '\0';
- if (gf_string2int16 (blocked_port, &tmp_port1) == 0) {
- if (tmp_port1 > ceiling
- || tmp_port1 < 0) {
- gf_msg ("glusterfs-socket", GF_LOG_WARNING, 0,
- LG_MSG_INVALID_PORT, "invalid port %d",
- tmp_port1);
- result = _gf_true;
- goto out;
- } else {
- gf_msg_debug ("glusterfs", 0, "blocking port "
- "%d", tmp_port1);
- ports[tmp_port1] = _gf_true;
- }
- } else {
- gf_msg ("glusterfs-socket", GF_LOG_WARNING, 0,
- LG_MSG_INVALID_PORT, "%s is not a valid port "
- "identifier", blocked_port);
- result = _gf_true;
- goto out;
- }
+gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling)
+{
+ gf_boolean_t result = _gf_false;
+ char *range_port = NULL;
+ int32_t tmp_port1 = -1;
+ int32_t tmp_port2 = -1;
+
+ if (strstr(blocked_port, "-") == NULL) {
+ /* get rid of the new line character*/
+ if (blocked_port[strlen(blocked_port) - 1] == '\n')
+ blocked_port[strlen(blocked_port) - 1] = '\0';
+ if (gf_string2int32(blocked_port, &tmp_port1) == 0) {
+ if (tmp_port1 > GF_PORT_MAX || tmp_port1 < 0) {
+ gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0,
+ LG_MSG_INVALID_PORT, "port=%d", tmp_port1, NULL);
+ result = _gf_true;
+ goto out;
+ } else {
+ gf_msg_debug("glusterfs", 0,
+ "blocking port "
+ "%d",
+ tmp_port1);
+ BIT_SET(ports, tmp_port1);
+ }
} else {
- range_port = strtok (blocked_port, "-");
- if (!range_port){
- result = _gf_true;
- goto out;
- }
- if (gf_string2int16 (range_port, &tmp_port1) == 0) {
- if (tmp_port1 > ceiling)
- tmp_port1 = ceiling;
- if (tmp_port1 < 0)
- tmp_port1 = 0;
- }
- range_port = strtok (NULL, "-");
- if (!range_port) {
- result = _gf_true;
- goto out;
- }
- /* get rid of the new line character*/
- if (range_port[strlen(range_port) -1] == '\n')
- range_port[strlen(range_port) - 1] = '\0';
- if (gf_string2int16 (range_port, &tmp_port2) == 0) {
- if (tmp_port2 > ceiling)
- tmp_port2 = ceiling;
- if (tmp_port2 < 0)
- tmp_port2 = 0;
- }
- gf_msg_debug ("glusterfs", 0, "lower: %d, higher: %d",
- tmp_port1, tmp_port2);
- for (; tmp_port1 <= tmp_port2; tmp_port1++)
- ports[tmp_port1] = _gf_true;
- }
+ gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0, LG_MSG_INVALID_PORT,
+ "port=%s", blocked_port, NULL);
+ result = _gf_true;
+ goto out;
+ }
+ } else {
+ range_port = strtok(blocked_port, "-");
+ if (!range_port) {
+ result = _gf_true;
+ goto out;
+ }
+ if (gf_string2int32(range_port, &tmp_port1) == 0) {
+ if (tmp_port1 > ceiling)
+ tmp_port1 = ceiling;
+ if (tmp_port1 < 0)
+ tmp_port1 = 0;
+ }
+ range_port = strtok(NULL, "-");
+ if (!range_port) {
+ result = _gf_true;
+ goto out;
+ }
+ /* get rid of the new line character*/
+ if (range_port[strlen(range_port) - 1] == '\n')
+ range_port[strlen(range_port) - 1] = '\0';
+ if (gf_string2int32(range_port, &tmp_port2) == 0) {
+ if (tmp_port2 > ceiling)
+ tmp_port2 = ceiling;
+ if (tmp_port2 < 0)
+ tmp_port2 = 0;
+ }
+ gf_msg_debug("glusterfs", 0, "lower: %d, higher: %d", tmp_port1,
+ tmp_port2);
+ for (; tmp_port1 <= tmp_port2; tmp_port1++)
+ BIT_SET(ports, tmp_port1);
+ }
out:
- return result;
+ return result;
}
/* Takes in client ip{v4,v6} and returns associated hostname, if any
@@ -2894,566 +3408,890 @@ out:
* Returns: 0 for success, -1 for failure
*/
int
-gf_get_hostname_from_ip (char *client_ip, char **hostname)
-{
- int ret = -1;
- struct sockaddr *client_sockaddr = NULL;
- struct sockaddr_in client_sock_in = {0};
- struct sockaddr_in6 client_sock_in6 = {0};
- char client_hostname[NI_MAXHOST] = {0};
- char *client_ip_copy = NULL;
- char *tmp = NULL;
- char *ip = NULL;
+gf_get_hostname_from_ip(char *client_ip, char **hostname)
+{
+ int ret = -1;
+ struct sockaddr *client_sockaddr = NULL;
+ struct sockaddr_in client_sock_in = {0};
+ struct sockaddr_in6 client_sock_in6 = {0};
+ char client_hostname[NI_MAXHOST] = {0};
+ char *client_ip_copy = NULL;
+ char *tmp = NULL;
+ char *ip = NULL;
+ size_t addr_sz = 0;
+
+ /* if ipv4, reverse lookup the hostname to
+ * allow FQDN based rpc authentication
+ */
+ if (!valid_ipv6_address(client_ip, strlen(client_ip), 0) &&
+ !valid_ipv4_address(client_ip, strlen(client_ip), 0)) {
+ /* most times, we get a.b.c.d:port form, so check that */
+ client_ip_copy = gf_strdup(client_ip);
+ if (!client_ip_copy)
+ goto out;
+
+ ip = strtok_r(client_ip_copy, ":", &tmp);
+ } else {
+ ip = client_ip;
+ }
+
+ if (valid_ipv4_address(ip, strlen(ip), 0) == _gf_true) {
+ client_sockaddr = (struct sockaddr *)&client_sock_in;
+ addr_sz = sizeof(client_sock_in);
+ client_sock_in.sin_family = AF_INET;
+ ret = inet_pton(AF_INET, ip, (void *)&client_sock_in.sin_addr.s_addr);
+
+ } else if (valid_ipv6_address(ip, strlen(ip), 0) == _gf_true) {
+ client_sockaddr = (struct sockaddr *)&client_sock_in6;
+ addr_sz = sizeof(client_sock_in6);
+
+ client_sock_in6.sin6_family = AF_INET6;
+ ret = inet_pton(AF_INET6, ip, (void *)&client_sock_in6.sin6_addr);
+ } else {
+ goto out;
+ }
+
+ if (ret != 1) {
+ ret = -1;
+ goto out;
+ }
+
+ /* You cannot just use sizeof (*client_sockaddr), as per the man page
+ * the (getnameinfo) size must be the size of the underlying sockaddr
+ * struct e.g. sockaddr_in6 or sockaddr_in. Failure to do so will
+ * break IPv6 hostname resolution (IPv4 will work only because
+ * the sockaddr_in struct happens to be of the correct size).
+ */
+ ret = getnameinfo(client_sockaddr, addr_sz, client_hostname,
+ sizeof(client_hostname), NULL, 0, 0);
+ if (ret) {
+ gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED,
+ "ip=%s", client_ip, "ret=%s", gai_strerror(ret), NULL);
+ ret = -1;
+ goto out;
+ }
+
+ *hostname = gf_strdup((char *)client_hostname);
+out:
+ if (client_ip_copy)
+ GF_FREE(client_ip_copy);
- /* if ipv4, reverse lookup the hostname to
- * allow FQDN based rpc authentication
- */
- if (valid_ipv4_address (client_ip, strlen (client_ip), 0) == _gf_false) {
- /* most times, we get a.b.c.d:port form, so check that */
- client_ip_copy = gf_strdup (client_ip);
- if (!client_ip_copy)
- goto out;
+ return ret;
+}
- ip = strtok_r (client_ip_copy, ":", &tmp);
- } else {
- ip = client_ip;
- }
+gf_boolean_t
+gf_interface_search(char *ip)
+{
+ int32_t ret = -1;
+ gf_boolean_t found = _gf_false;
+ struct ifaddrs *ifaddr, *ifa;
+ int family;
+ char host[NI_MAXHOST];
+ xlator_t *this = NULL;
+ char *pct = NULL;
- if (valid_ipv4_address (ip, strlen (ip), 0) == _gf_true) {
- client_sockaddr = (struct sockaddr *)&client_sock_in;
- client_sock_in.sin_family = AF_INET;
- ret = inet_pton (AF_INET, ip,
- (void *)&client_sock_in.sin_addr.s_addr);
+ this = THIS;
- } else if (valid_ipv6_address (ip, strlen (ip), 0) == _gf_true) {
- client_sockaddr = (struct sockaddr *) &client_sock_in6;
+ ret = getifaddrs(&ifaddr);
- client_sock_in6.sin6_family = AF_INET6;
- ret = inet_pton (AF_INET6, ip,
- (void *)&client_sock_in6.sin6_addr);
- } else {
- goto out;
- }
+ if (ret != 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETIFADDRS_FAILED, "ret=%s",
+ gai_strerror(ret), NULL);
+ goto out;
+ }
- if (ret != 1) {
- ret = -1;
- goto out;
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_addr) {
+ /*
+ * This seemingly happens if an interface hasn't
+ * been bound to a particular protocol (seen with
+ * TUN devices).
+ */
+ continue;
}
+ family = ifa->ifa_addr->sa_family;
- ret = getnameinfo (client_sockaddr,
- sizeof (*client_sockaddr),
- client_hostname, sizeof (client_hostname),
- NULL, 0, 0);
- if (ret) {
- gf_msg ("common-utils", GF_LOG_ERROR, 0,
- LG_MSG_GETNAMEINFO_FAILED, "Could not lookup hostname "
- "of %s : %s", client_ip, gai_strerror (ret));
- ret = -1;
- goto out;
- }
+ if (family != AF_INET && family != AF_INET6)
+ continue;
- *hostname = gf_strdup ((char *)client_hostname);
- out:
- if (client_ip_copy)
- GF_FREE (client_ip_copy);
-
- return ret;
-}
-
-gf_boolean_t
-gf_interface_search (char *ip)
-{
- int32_t ret = -1;
- gf_boolean_t found = _gf_false;
- struct ifaddrs *ifaddr, *ifa;
- int family;
- char host[NI_MAXHOST];
- xlator_t *this = NULL;
- char *pct = NULL;
-
- this = THIS;
-
- ret = getifaddrs (&ifaddr);
+ ret = getnameinfo(ifa->ifa_addr,
+ (family == AF_INET) ? sizeof(struct sockaddr_in)
+ : sizeof(struct sockaddr_in6),
+ host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (ret != 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0, LG_MSG_GETIFADDRS_FAILED,
- "getifaddrs() failed: %s\n", gai_strerror(ret));
- goto out;
+ gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED,
+ "ret=%s", gai_strerror(ret), NULL);
+ goto out;
+ }
+
+ /*
+ * Sometimes the address comes back as addr%eth0 or
+ * similar. Since % is an invalid character, we can
+ * strip it out with confidence that doing so won't
+ * harm anything.
+ */
+ pct = index(host, '%');
+ if (pct) {
+ *pct = '\0';
}
- for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
- if (!ifa->ifa_addr) {
- /*
- * This seemingly happens if an interface hasn't
- * been bound to a particular protocol (seen with
- * TUN devices).
- */
- continue;
- }
- family = ifa->ifa_addr->sa_family;
-
- if (family != AF_INET && family != AF_INET6)
- continue;
-
- ret = getnameinfo (ifa->ifa_addr,
- (family == AF_INET) ? sizeof(struct sockaddr_in) :
- sizeof(struct sockaddr_in6),
- host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
-
- if (ret != 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0,
- LG_MSG_GETNAMEINFO_FAILED, "getnameinfo() "
- "failed: %s\n", gai_strerror(ret));
- goto out;
- }
-
- /*
- * Sometimes the address comes back as addr%eth0 or
- * similar. Since % is an invalid character, we can
- * strip it out with confidence that doing so won't
- * harm anything.
- */
- pct = index(host,'%');
- if (pct) {
- *pct = '\0';
- }
-
- if (strncmp (ip, host, NI_MAXHOST) == 0) {
- gf_msg_debug (this->name, 0, "%s is local address at "
- "interface %s", ip, ifa->ifa_name);
- found = _gf_true;
- goto out;
- }
+ if (strncmp(ip, host, NI_MAXHOST) == 0) {
+ gf_msg_debug(this->name, 0,
+ "%s is local address at "
+ "interface %s",
+ ip, ifa->ifa_name);
+ found = _gf_true;
+ goto out;
}
+ }
out:
- if(ifaddr)
- freeifaddrs (ifaddr);
- return found;
+ if (ifaddr)
+ freeifaddrs(ifaddr);
+ return found;
}
char *
-get_ip_from_addrinfo (struct addrinfo *addr, char **ip)
+get_ip_from_addrinfo(struct addrinfo *addr, char **ip)
{
- char buf[64];
- void *in_addr = NULL;
- struct sockaddr_in *s4 = NULL;
- struct sockaddr_in6 *s6 = NULL;
+ char buf[64];
+ void *in_addr = NULL;
+ struct sockaddr_in *s4 = NULL;
+ struct sockaddr_in6 *s6 = NULL;
- switch (addr->ai_family)
- {
- case AF_INET:
- s4 = (struct sockaddr_in *)addr->ai_addr;
- in_addr = &s4->sin_addr;
- break;
-
- case AF_INET6:
- s6 = (struct sockaddr_in6 *)addr->ai_addr;
- in_addr = &s6->sin6_addr;
- break;
-
- default:
- gf_msg ("glusterd", GF_LOG_ERROR, 0,
- LG_MSG_INVALID_FAMILY, "Invalid family");
- return NULL;
- }
+ switch (addr->ai_family) {
+ case AF_INET:
+ s4 = (struct sockaddr_in *)addr->ai_addr;
+ in_addr = &s4->sin_addr;
+ break;
- if (!inet_ntop(addr->ai_family, in_addr, buf, sizeof(buf))) {
- gf_msg ("glusterd", GF_LOG_ERROR, 0, LG_MSG_CONVERSION_FAILED,
- "String conversion failed");
- return NULL;
- }
+ case AF_INET6:
+ s6 = (struct sockaddr_in6 *)addr->ai_addr;
+ in_addr = &s6->sin6_addr;
+ break;
- *ip = gf_strdup (buf);
- return *ip;
-}
+ default:
+ gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, NULL);
+ return NULL;
+ }
-gf_boolean_t
-gf_is_loopback_localhost (const struct sockaddr *sa, char *hostname)
-{
- GF_ASSERT (sa);
-
- gf_boolean_t is_local = _gf_false;
- const struct in_addr *addr4 = NULL;
- const struct in6_addr *addr6 = NULL;
- uint8_t *ap = NULL;
- struct in6_addr loopbackaddr6 = IN6ADDR_LOOPBACK_INIT;
-
- switch (sa->sa_family) {
- case AF_INET:
- addr4 = &(((struct sockaddr_in *)sa)->sin_addr);
- ap = (uint8_t*)&addr4->s_addr;
- if (ap[0] == 127)
- is_local = _gf_true;
- break;
-
- case AF_INET6:
- addr6 = &(((struct sockaddr_in6 *)sa)->sin6_addr);
- if (memcmp (addr6, &loopbackaddr6,
- sizeof (loopbackaddr6)) == 0)
- is_local = _gf_true;
- break;
-
- default:
- if (hostname)
- gf_msg ("glusterd", GF_LOG_ERROR, 0,
- LG_MSG_INVALID_FAMILY, "unknown "
- "address family %d for %s",
- sa->sa_family, hostname);
- break;
- }
+ if (!inet_ntop(addr->ai_family, in_addr, buf, sizeof(buf))) {
+ gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_CONVERSION_FAILED, NULL);
+ return NULL;
+ }
- return is_local;
+ *ip = gf_strdup(buf);
+ return *ip;
}
gf_boolean_t
-gf_is_local_addr (char *hostname)
+gf_is_loopback_localhost(const struct sockaddr *sa, char *hostname)
{
- int32_t ret = -1;
- struct addrinfo *result = NULL;
- struct addrinfo *res = NULL;
- gf_boolean_t found = _gf_false;
- char *ip = NULL;
- xlator_t *this = NULL;
+ GF_ASSERT(sa);
- this = THIS;
- ret = getaddrinfo (hostname, NULL, NULL, &result);
+ gf_boolean_t is_local = _gf_false;
+ const struct in_addr *addr4 = NULL;
+ const struct in6_addr *addr6 = NULL;
+ uint8_t *ap = NULL;
+ struct in6_addr loopbackaddr6 = IN6ADDR_LOOPBACK_INIT;
- if (ret != 0) {
- gf_msg (this->name, GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED,
- "error in getaddrinfo: %s\n", gai_strerror(ret));
- goto out;
- }
+ switch (sa->sa_family) {
+ case AF_INET:
+ addr4 = &(((struct sockaddr_in *)sa)->sin_addr);
+ ap = (uint8_t *)&addr4->s_addr;
+ if (ap[0] == 127)
+ is_local = _gf_true;
+ break;
- for (res = result; res != NULL; res = res->ai_next) {
- gf_msg_debug (this->name, 0, "%s ",
- get_ip_from_addrinfo (res, &ip));
-
- found = gf_is_loopback_localhost (res->ai_addr, hostname)
- || gf_interface_search (ip);
- if (found) {
- GF_FREE (ip);
- goto out;
- }
- GF_FREE (ip);
- }
+ case AF_INET6:
+ addr6 = &(((struct sockaddr_in6 *)sa)->sin6_addr);
+ if (memcmp(addr6, &loopbackaddr6, sizeof(loopbackaddr6)) == 0)
+ is_local = _gf_true;
+ break;
+
+ default:
+ if (hostname)
+ gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY,
+ "family=%d", sa->sa_family, "hostname=%s", hostname,
+ NULL);
+ break;
+ }
+
+ return is_local;
+}
+
+gf_boolean_t
+gf_is_local_addr(char *hostname)
+{
+ int32_t ret = -1;
+ struct addrinfo *result = NULL;
+ struct addrinfo *res = NULL;
+ gf_boolean_t found = _gf_false;
+ char *ip = NULL;
+ xlator_t *this = NULL;
+ struct addrinfo hints;
+
+ this = THIS;
+
+ memset(&hints, 0, sizeof(hints));
+ /*
+ * Removing AI_ADDRCONFIG from default_hints
+ * for being able to use link local ipv6 addresses
+ */
+ hints.ai_family = AF_UNSPEC;
+
+ ret = getaddrinfo(hostname, NULL, &hints, &result);
+
+ if (ret != 0) {
+ gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED,
+ "ret=%s", gai_strerror(ret), NULL);
+ goto out;
+ }
+
+ for (res = result; res != NULL; res = res->ai_next) {
+ get_ip_from_addrinfo(res, &ip);
+ gf_msg_debug(this->name, 0, "%s ", ip);
+
+ if (ip) {
+ found = (gf_is_loopback_localhost(res->ai_addr, hostname) ||
+ gf_interface_search(ip));
+ }
+ if (found) {
+ GF_FREE(ip);
+ goto out;
+ }
+ GF_FREE(ip);
+ /* the above free will not set ip to NULL, and hence, there is
+ double free possible as the loop continues. set ip to NULL. */
+ ip = NULL;
+ }
out:
- if (result)
- freeaddrinfo (result);
+ if (result)
+ freeaddrinfo(result);
- if (!found)
- gf_msg_debug (this->name, 0, "%s is not local", hostname);
+ if (!found)
+ gf_msg_debug(this->name, 0, "%s is not local", hostname);
- return found;
+ return found;
}
gf_boolean_t
-gf_is_same_address (char *name1, char *name2)
-{
- struct addrinfo *addr1 = NULL;
- struct addrinfo *addr2 = NULL;
- struct addrinfo *p = NULL;
- struct addrinfo *q = NULL;
- gf_boolean_t ret = _gf_false;
- int gai_err = 0;
-
- gai_err = getaddrinfo(name1,NULL,NULL,&addr1);
- if (gai_err != 0) {
- gf_msg (name1, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED,
- "error in getaddrinfo: %s\n", gai_strerror(gai_err));
- goto out;
- }
+gf_is_same_address(char *name1, char *name2)
+{
+ struct addrinfo *addr1 = NULL;
+ struct addrinfo *addr2 = NULL;
+ struct addrinfo *p = NULL;
+ struct addrinfo *q = NULL;
+ gf_boolean_t ret = _gf_false;
+ int gai_err = 0;
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+
+ gai_err = getaddrinfo(name1, NULL, &hints, &addr1);
+ if (gai_err != 0) {
+ gf_smsg(name1, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, "error=%s",
+ gai_strerror(gai_err), NULL);
+ goto out;
+ }
+
+ gai_err = getaddrinfo(name2, NULL, &hints, &addr2);
+ if (gai_err != 0) {
+ gf_smsg(name2, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, "error=%s",
+ gai_strerror(gai_err), NULL);
+ goto out;
+ }
+
+ for (p = addr1; p; p = p->ai_next) {
+ for (q = addr2; q; q = q->ai_next) {
+ if (p->ai_addrlen != q->ai_addrlen) {
+ continue;
+ }
+ if (memcmp(p->ai_addr, q->ai_addr, p->ai_addrlen)) {
+ continue;
+ }
+ ret = _gf_true;
+ goto out;
+ }
+ }
- gai_err = getaddrinfo(name2,NULL,NULL,&addr2);
- if (gai_err != 0) {
- gf_msg (name2, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED,
- "error in getaddrinfo: %s\n", gai_strerror(gai_err));
- goto out;
- }
+out:
+ if (addr1) {
+ freeaddrinfo(addr1);
+ }
+ if (addr2) {
+ freeaddrinfo(addr2);
+ }
+ return ret;
+}
- for (p = addr1; p; p = p->ai_next) {
- for (q = addr2; q; q = q->ai_next) {
- if (p->ai_addrlen != q->ai_addrlen) {
- continue;
- }
- if (memcmp(p->ai_addr,q->ai_addr,p->ai_addrlen)) {
- continue;
- }
- ret = _gf_true;
- goto out;
- }
- }
+/*
+ * Processes list of volfile servers.
+ * Format: <host1>:<port1> <host2>:<port2>...
+ */
+int
+gf_process_getspec_servers_list(cmd_args_t *cmd_args, const char *servers_list)
+{
+ char *tmp = NULL;
+ char *address = NULL;
+ char *host = NULL;
+ char *last_colon = NULL;
+ char *save_ptr = NULL;
+ int port = 0;
+ int ret = -1;
+
+ tmp = gf_strdup(servers_list);
+ if (!tmp) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ address = strtok_r(tmp, " ", &save_ptr);
+ if (!address) {
+ errno = EINVAL;
+ goto out;
+ }
+
+ while (1) {
+ last_colon = strrchr(address, ':');
+ if (!last_colon) {
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+ *last_colon = '\0';
+ host = address;
+ port = atoi(last_colon + 1);
+ if (port <= 0) {
+ errno = EINVAL;
+ ret = -1;
+ break;
+ }
+ ret = gf_set_volfile_server_common(cmd_args, host,
+ GF_DEFAULT_VOLFILE_TRANSPORT, port);
+ if (ret && errno != EEXIST) {
+ break;
+ }
+ address = strtok_r(NULL, " ", &save_ptr);
+ if (!address) {
+ errno = 0;
+ ret = 0;
+ break;
+ }
+ }
out:
- if (addr1) {
- freeaddrinfo(addr1);
- }
- if (addr2) {
- freeaddrinfo(addr2);
+ if (tmp) {
+ GF_FREE(tmp);
+ }
+
+ return ret;
+}
+
+int
+gf_set_volfile_server_common(cmd_args_t *cmd_args, const char *host,
+ const char *transport, int port)
+{
+ server_cmdline_t *server = NULL;
+ server_cmdline_t *tmp = NULL;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO(THIS->name, cmd_args, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, host, out);
+ GF_VALIDATE_OR_GOTO(THIS->name, transport, out);
+
+ server = GF_CALLOC(1, sizeof(server_cmdline_t),
+ gf_common_mt_server_cmdline_t);
+ if (!server) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&server->list);
+
+ server->volfile_server = gf_strdup(host);
+ if (!server->volfile_server) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ server->transport = gf_strdup(transport);
+ if (!server->transport) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ server->port = port;
+
+ if (!cmd_args->volfile_server) {
+ cmd_args->volfile_server = server->volfile_server;
+ cmd_args->volfile_server_transport = server->transport;
+ cmd_args->volfile_server_port = server->port;
+ cmd_args->curr_server = server;
+ }
+
+ list_for_each_entry(tmp, &cmd_args->volfile_servers, list)
+ {
+ if ((!strcmp(tmp->volfile_server, server->volfile_server) &&
+ !strcmp(tmp->transport, server->transport) &&
+ (tmp->port == server->port))) {
+ /* Duplicate option given, log and ignore */
+ gf_smsg("gluster", GF_LOG_INFO, EEXIST, LG_MSG_DUPLICATE_ENTRY,
+ NULL);
+ ret = 0;
+ goto out;
+ }
+ }
+
+ list_add_tail(&server->list, &cmd_args->volfile_servers);
+
+ ret = 0;
+out:
+ if (-1 == ret) {
+ if (server) {
+ GF_FREE(server->volfile_server);
+ GF_FREE(server->transport);
+ GF_FREE(server);
}
- return ret;
+ }
+ return ret;
}
/* Sets log file path from user provided arguments */
int
-gf_set_log_file_path (cmd_args_t *cmd_args)
-{
- int i = 0;
- int j = 0;
- int ret = 0;
- char tmp_str[1024] = {0,};
-
- if (!cmd_args)
- goto done;
-
- if (cmd_args->mount_point) {
- j = 0;
- i = 0;
- if (cmd_args->mount_point[0] == '/')
- i = 1;
- for (; i < strlen (cmd_args->mount_point); i++,j++) {
- tmp_str[j] = cmd_args->mount_point[i];
- if (cmd_args->mount_point[i] == '/')
- tmp_str[j] = '-';
- }
-
- ret = gf_asprintf (&cmd_args->log_file,
- DEFAULT_LOG_FILE_DIRECTORY "/%s.log",
- tmp_str);
- if (ret > 0)
- ret = 0;
- goto done;
- }
+gf_set_log_file_path(cmd_args_t *cmd_args, glusterfs_ctx_t *ctx)
+{
+ int i = 0;
+ int j = 0;
+ int ret = 0;
+ int tmp_len = 0;
+ char tmp_str[1024] = {
+ 0,
+ };
+
+ if (!cmd_args)
+ goto done;
- if (cmd_args->volfile) {
- j = 0;
- i = 0;
- if (cmd_args->volfile[0] == '/')
- i = 1;
- for (; i < strlen (cmd_args->volfile); i++,j++) {
- tmp_str[j] = cmd_args->volfile[i];
- if (cmd_args->volfile[i] == '/')
- tmp_str[j] = '-';
- }
- ret = gf_asprintf (&cmd_args->log_file,
- DEFAULT_LOG_FILE_DIRECTORY "/%s.log",
- tmp_str);
- if (ret > 0)
- ret = 0;
- goto done;
+ if (cmd_args->mount_point) {
+ j = 0;
+ i = 0;
+ if (cmd_args->mount_point[0] == '/')
+ i = 1;
+ for (; i < strlen(cmd_args->mount_point); i++, j++) {
+ tmp_str[j] = cmd_args->mount_point[i];
+ if (cmd_args->mount_point[i] == '/')
+ tmp_str[j] = '-';
}
- if (cmd_args->volfile_server) {
+ ret = gf_asprintf(&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log", tmp_str);
+ if (ret > 0)
+ ret = 0;
+ goto done;
+ }
- ret = gf_asprintf (&cmd_args->log_file,
- DEFAULT_LOG_FILE_DIRECTORY "/%s-%s-%d.log",
- cmd_args->volfile_server,
- cmd_args->volfile_id, getpid());
- if (ret > 0)
- ret = 0;
+ if (ctx && GF_GLUSTERD_PROCESS == ctx->process_mode) {
+ ret = gf_asprintf(&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log", GLUSTERD_NAME);
+ if (ret > 0)
+ ret = 0;
+
+ goto done;
+ }
+
+ if (cmd_args->volfile) {
+ j = 0;
+ i = 0;
+ if (cmd_args->volfile[0] == '/')
+ i = 1;
+ for (; i < strlen(cmd_args->volfile); i++, j++) {
+ tmp_str[j] = cmd_args->volfile[i];
+ if (cmd_args->volfile[i] == '/')
+ tmp_str[j] = '-';
+ }
+ ret = gf_asprintf(&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log", tmp_str);
+ if (ret > 0)
+ ret = 0;
+ goto done;
+ }
+
+ if (cmd_args->volfile_server) {
+ if (strncmp(cmd_args->volfile_server_transport, "unix", 4) == 0) {
+ if (cmd_args->volfile_server[0] == '/')
+ i = 1;
+ tmp_len = strlen(cmd_args->volfile_server);
+ for (j = 0; i < tmp_len; i++, j++) {
+ tmp_str[j] = cmd_args->volfile_server[i];
+ if (cmd_args->volfile_server[i] == '/')
+ tmp_str[j] = '-';
+ }
+ ret = gf_asprintf(&cmd_args->log_file, "%s/%s-%s-%d.log",
+ DEFAULT_LOG_FILE_DIRECTORY, tmp_str,
+ cmd_args->volfile_id, getpid());
+ } else {
+ ret = gf_asprintf(&cmd_args->log_file, "%s/%s-%s-%d.log",
+ DEFAULT_LOG_FILE_DIRECTORY,
+ cmd_args->volfile_server, cmd_args->volfile_id,
+ getpid());
}
+ if (ret > 0)
+ ret = 0;
+ }
done:
- return ret;
+ return ret;
}
int
-gf_set_log_ident (cmd_args_t *cmd_args)
+gf_set_log_ident(cmd_args_t *cmd_args)
{
- int ret = 0;
- char *ptr = NULL;
+ int ret = 0;
+ char *ptr = NULL;
- if (cmd_args->log_file == NULL) {
- /* no ident source */
- return 0;
- }
+ if (cmd_args->log_file == NULL) {
+ /* no ident source */
+ return 0;
+ }
+
+ /* TODO: Some idents would look like, etc-glusterfs-glusterd.vol, which
+ * seems ugly and can be bettered? */
+ /* just get the filename as the ident */
+ if (NULL != (ptr = strrchr(cmd_args->log_file, '/'))) {
+ ret = gf_asprintf(&cmd_args->log_ident, "%s", ptr + 1);
+ } else {
+ ret = gf_asprintf(&cmd_args->log_ident, "%s", cmd_args->log_file);
+ }
+
+ if (ret > 0)
+ ret = 0;
+ else
+ return ret;
- /* TODO: Some idents would look like, etc-glusterfs-glusterd.vol, which
- * seems ugly and can be bettered? */
- /* just get the filename as the ident */
- if (NULL != (ptr = strrchr (cmd_args->log_file, '/'))) {
- ret = gf_asprintf (&cmd_args->log_ident, "%s", ptr + 1);
- } else {
- ret = gf_asprintf (&cmd_args->log_ident, "%s",
- cmd_args->log_file);
+ /* remove .log suffix */
+ if (NULL != (ptr = strrchr(cmd_args->log_ident, '.'))) {
+ if (strcmp(ptr, ".log") == 0) {
+ ptr[0] = '\0';
}
+ }
- if (ret > 0)
- ret = 0;
- else
- return ret;
+ return ret;
+}
- /* remove .log suffix */
- if (NULL != (ptr = strrchr (cmd_args->log_ident, '.'))) {
- if (strcmp (ptr, ".log") == 0) {
- ptr[0] = '\0';
- }
- }
+int
+gf_thread_cleanup_xint(pthread_t thread)
+{
+ int ret = 0;
+ void *res = NULL;
- return ret;
+ ret = pthread_cancel(thread);
+ if (ret != 0)
+ goto error_return;
+
+ ret = pthread_join(thread, &res);
+ if (ret != 0)
+ goto error_return;
+
+ if (res != PTHREAD_CANCELED)
+ goto error_return;
+
+ ret = 0;
+
+error_return:
+ return ret;
+}
+
+void
+gf_thread_set_vname(pthread_t thread, const char *name, va_list args)
+{
+ char thread_name[GF_THREAD_NAME_LIMIT];
+ int ret;
+
+ /* Initialize the thread name with the prefix (not NULL terminated). */
+ memcpy(thread_name, GF_THREAD_NAME_PREFIX,
+ sizeof(GF_THREAD_NAME_PREFIX) - 1);
+
+ ret = vsnprintf(thread_name + sizeof(GF_THREAD_NAME_PREFIX) - 1,
+ sizeof(thread_name) - sizeof(GF_THREAD_NAME_PREFIX) + 1,
+ name, args);
+ if (ret < 0) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED,
+ "name=%s", name, NULL);
+ return;
+ }
+
+ if (ret >= sizeof(thread_name)) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_THREAD_NAME_TOO_LONG,
+ "name=%s", thread_name, NULL);
+ }
+
+#ifdef GF_LINUX_HOST_OS
+ ret = pthread_setname_np(thread, thread_name);
+#elif defined(__NetBSD__)
+ ret = pthread_setname_np(thread, thread_name, NULL);
+#elif defined(__FreeBSD__)
+ pthread_set_name_np(thread, thread_name);
+ ret = 0;
+#else
+ ret = ENOSYS;
+#endif
+ if (ret != 0) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, ret, LG_MSG_SET_THREAD_FAILED,
+ "name=%s", thread_name, NULL);
+ }
+}
+
+void
+gf_thread_set_name(pthread_t thread, const char *name, ...)
+{
+ va_list args;
+
+ va_start(args, name);
+ gf_thread_set_vname(thread, name, args);
+ va_end(args);
}
int
-gf_thread_cleanup_xint (pthread_t thread)
+gf_thread_vcreate(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg, const char *name,
+ va_list args)
{
- int ret = 0;
- void *res = NULL;
+ sigset_t set, old;
+ int ret;
- ret = pthread_cancel (thread);
- if (ret != 0)
- goto error_return;
+ sigemptyset(&old);
+ sigfillset(&set);
+ sigdelset(&set, SIGSEGV);
+ sigdelset(&set, SIGBUS);
+ sigdelset(&set, SIGILL);
+ sigdelset(&set, SIGSYS);
+ sigdelset(&set, SIGFPE);
+ sigdelset(&set, SIGABRT);
- ret = pthread_join (thread, &res);
- if (ret != 0)
- goto error_return;
+ pthread_sigmask(SIG_BLOCK, &set, &old);
- if (res != PTHREAD_CANCELED)
- goto error_return;
+ ret = pthread_create(thread, attr, start_routine, arg);
+ if (ret != 0) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_THREAD_CREATE_FAILED,
+ NULL);
+ ret = -1;
+ } else if (name != NULL) {
+ gf_thread_set_vname(*thread, name, args);
+ }
- ret = 0;
+ pthread_sigmask(SIG_SETMASK, &old, NULL);
- error_return:
- return ret;
+ return ret;
}
int
-gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine)(void *), void *arg)
+gf_thread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg, const char *name,
+ ...)
{
- sigset_t set, old;
- int ret;
+ va_list args;
+ int ret;
- sigemptyset (&set);
+ va_start(args, name);
+ ret = gf_thread_vcreate(thread, attr, start_routine, arg, name, args);
+ va_end(args);
- sigfillset (&set);
- sigdelset (&set, SIGSEGV);
- sigdelset (&set, SIGBUS);
- sigdelset (&set, SIGILL);
- sigdelset (&set, SIGSYS);
- sigdelset (&set, SIGFPE);
- sigdelset (&set, SIGABRT);
+ return ret;
+}
- pthread_sigmask (SIG_BLOCK, &set, &old);
+int
+gf_thread_create_detached(pthread_t *thread, void *(*start_routine)(void *),
+ void *arg, const char *name, ...)
+{
+ pthread_attr_t attr;
+ va_list args;
+ int ret = -1;
- ret = pthread_create (thread, attr, start_routine, arg);
+ ret = pthread_attr_init(&attr);
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_ATTR_INIT_FAILED,
+ NULL);
+ return -1;
+ }
- pthread_sigmask (SIG_SETMASK, &old, NULL);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- return ret;
+ va_start(args, name);
+ ret = gf_thread_vcreate(thread, &attr, start_routine, arg, name, args);
+ va_end(args);
+
+ pthread_attr_destroy(&attr);
+
+ return ret;
}
int
-gf_skip_header_section (int fd, int header_len)
+gf_skip_header_section(int fd, int header_len)
{
- int ret = -1;
+ int ret = -1;
- ret = lseek (fd, header_len, SEEK_SET);
- if (ret == (off_t) -1) {
- gf_msg ("", GF_LOG_ERROR, 0, LG_MSG_SKIP_HEADER_FAILED,
- "Failed to skip header section");
- } else {
- ret = 0;
- }
+ ret = sys_lseek(fd, header_len, SEEK_SET);
+ if (ret == (off_t)-1) {
+ gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_SKIP_HEADER_FAILED, NULL);
+ } else {
+ ret = 0;
+ }
- return ret;
+ return ret;
}
+/* Below function is use to check at runtime if pid is running */
+
gf_boolean_t
-gf_is_service_running (char *pidfile, int *pid)
+gf_is_pid_running(int pid)
{
- FILE *file = NULL;
- gf_boolean_t running = _gf_false;
- int ret = 0;
- int fno = 0;
+#ifdef __FreeBSD__
+ int ret = -1;
- file = fopen (pidfile, "r+");
- if (!file)
- goto out;
+ ret = sys_kill(pid, 0);
+ if (ret < 0) {
+ return _gf_false;
+ }
+#else
+ char fname[32] = {
+ 0,
+ };
+ int fd = -1;
- fno = fileno (file);
- ret = lockf (fno, F_TEST, 0);
- if (ret == -1)
- running = _gf_true;
- if (!pid)
- goto out;
+ snprintf(fname, sizeof(fname), "/proc/%d/cmdline", pid);
- ret = fscanf (file, "%d", pid);
- if (ret <= 0) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Unable to read pidfile: %s", pidfile);
- *pid = -1;
- }
+ fd = sys_open(fname, O_RDONLY, 0);
+ if (fd < 0) {
+ return _gf_false;
+ }
+
+ sys_close(fd);
+#endif
+ return _gf_true;
+}
+
+gf_boolean_t
+gf_is_service_running(char *pidfile, int *pid)
+{
+ FILE *file = NULL;
+ gf_boolean_t running = _gf_false;
+ int ret = 0;
+ int fno = 0;
+
+ file = fopen(pidfile, "r+");
+ if (!file) {
+ goto out;
+ }
+
+ fno = fileno(file);
+ ret = lockf(fno, F_TEST, 0);
+ if (ret == -1) {
+ running = _gf_true;
+ }
+
+ ret = fscanf(file, "%d", pid);
+ if (ret <= 0) {
+ gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, "pidfile=%s",
+ pidfile, NULL);
+ *pid = -1;
+ running = _gf_false;
+ goto out;
+ }
+
+ running = gf_is_pid_running(*pid);
+out:
+ if (file)
+ fclose(file);
+ return running;
+}
+
+/* Check if the pid is > 0 */
+gf_boolean_t
+gf_valid_pid(const char *pid, int length)
+{
+ gf_boolean_t ret = _gf_true;
+ pid_t value = 0;
+ char *end_ptr = NULL;
+ if (length <= 0) {
+ ret = _gf_false;
+ goto out;
+ }
+
+ value = strtol(pid, &end_ptr, 10);
+ if (value <= 0) {
+ ret = _gf_false;
+ }
out:
- if (file)
- fclose (file);
- return running;
+ return ret;
}
static int
-dht_is_linkfile_key (dict_t *this, char *key, data_t *value, void *data)
+dht_is_linkfile_key(dict_t *this, char *key, data_t *value, void *data)
{
- gf_boolean_t *linkfile_key_found = NULL;
+ gf_boolean_t *linkfile_key_found = NULL;
- if (!data)
- goto out;
+ if (!data)
+ goto out;
- linkfile_key_found = data;
+ linkfile_key_found = data;
- *linkfile_key_found = _gf_true;
+ *linkfile_key_found = _gf_true;
out:
- return 0;
+ return 0;
}
-
gf_boolean_t
-dht_is_linkfile (struct iatt *buf, dict_t *dict)
+dht_is_linkfile(struct iatt *buf, dict_t *dict)
{
- gf_boolean_t linkfile_key_found = _gf_false;
+ gf_boolean_t linkfile_key_found = _gf_false;
- if (!IS_DHT_LINKFILE_MODE (buf))
- return _gf_false;
+ if (!IS_DHT_LINKFILE_MODE(buf))
+ return _gf_false;
- dict_foreach_fnmatch (dict, "*."DHT_LINKFILE_STR, dht_is_linkfile_key,
- &linkfile_key_found);
+ dict_foreach_fnmatch(dict, "*." DHT_LINKFILE_STR, dht_is_linkfile_key,
+ &linkfile_key_found);
- return linkfile_key_found;
+ return linkfile_key_found;
}
int
-gf_check_log_format (const char *value)
+gf_check_log_format(const char *value)
{
- int log_format = -1;
+ int log_format = -1;
- if (!strcasecmp (value, GF_LOG_FORMAT_NO_MSG_ID))
- log_format = gf_logformat_traditional;
- else if (!strcasecmp (value, GF_LOG_FORMAT_WITH_MSG_ID))
- log_format = gf_logformat_withmsgid;
+ if (!strcasecmp(value, GF_LOG_FORMAT_NO_MSG_ID))
+ log_format = gf_logformat_traditional;
+ else if (!strcasecmp(value, GF_LOG_FORMAT_WITH_MSG_ID))
+ log_format = gf_logformat_withmsgid;
- if (log_format == -1)
- gf_msg (THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG,
- "Invalid log-format. possible values are "
- GF_LOG_FORMAT_NO_MSG_ID "|" GF_LOG_FORMAT_WITH_MSG_ID);
+ if (log_format == -1)
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG,
+ "possible_values=" GF_LOG_FORMAT_NO_MSG_ID
+ "|" GF_LOG_FORMAT_WITH_MSG_ID,
+ NULL);
- return log_format;
+ return log_format;
}
int
-gf_check_logger (const char *value)
+gf_check_logger(const char *value)
{
- int logger = -1;
+ int logger = -1;
- if (!strcasecmp (value, GF_LOGGER_GLUSTER_LOG))
- logger = gf_logger_glusterlog;
- else if (!strcasecmp (value, GF_LOGGER_SYSLOG))
- logger = gf_logger_syslog;
+ if (!strcasecmp(value, GF_LOGGER_GLUSTER_LOG))
+ logger = gf_logger_glusterlog;
+ else if (!strcasecmp(value, GF_LOGGER_SYSLOG))
+ logger = gf_logger_syslog;
- if (logger == -1)
- gf_msg (THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG,
- "Invalid logger. possible values are "
- GF_LOGGER_GLUSTER_LOG "|" GF_LOGGER_SYSLOG);
+ if (logger == -1)
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG,
+ "possible_values=" GF_LOGGER_GLUSTER_LOG "|" GF_LOGGER_SYSLOG,
+ NULL);
- return logger;
+ return logger;
}
/* gf_compare_sockaddr compares the given addresses @addr1 and @addr2 for
@@ -3463,30 +4301,28 @@ gf_check_logger (const char *value)
* https://www.opensource.apple.com/source/postfix/postfix-197/postfix/src/util/sock_addr.c
*/
gf_boolean_t
-gf_compare_sockaddr (const struct sockaddr *addr1,
- const struct sockaddr *addr2)
+gf_compare_sockaddr(const struct sockaddr *addr1, const struct sockaddr *addr2)
{
- GF_ASSERT (addr1 != NULL);
- GF_ASSERT (addr2 != NULL);
-
- /* Obviously, the addresses don't match if their families are different
- */
- if (addr1->sa_family != addr2->sa_family)
- return _gf_false;
+ GF_ASSERT(addr1 != NULL);
+ GF_ASSERT(addr2 != NULL);
+ /* Obviously, the addresses don't match if their families are different
+ */
+ if (addr1->sa_family != addr2->sa_family)
+ return _gf_false;
- if (AF_INET == addr1->sa_family) {
- if (((struct sockaddr_in *)addr1)->sin_addr.s_addr ==
- ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
- return _gf_true;
+ if (AF_INET == addr1->sa_family) {
+ if (((struct sockaddr_in *)addr1)->sin_addr.s_addr ==
+ ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
+ return _gf_true;
- } else if (AF_INET6 == addr1->sa_family) {
- if (memcmp ((char *)&((struct sockaddr_in6 *)addr1)->sin6_addr,
- (char *)&((struct sockaddr_in6 *)addr2)->sin6_addr,
- sizeof (struct in6_addr)) == 0)
- return _gf_true;
- }
- return _gf_false;
+ } else if (AF_INET6 == addr1->sa_family) {
+ if (memcmp((char *)&((struct sockaddr_in6 *)addr1)->sin6_addr,
+ (char *)&((struct sockaddr_in6 *)addr2)->sin6_addr,
+ sizeof(struct in6_addr)) == 0)
+ return _gf_true;
+ }
+ return _gf_false;
}
/*
@@ -3495,129 +4331,167 @@ gf_compare_sockaddr (const struct sockaddr *addr1,
*/
int
-gf_set_timestamp (const char *src, const char* dest)
-{
- struct stat sb = {0, };
- struct timeval new_time[2] = {{0, },{0,}};
- int ret = 0;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_ASSERT (src);
- GF_ASSERT (dest);
-
- ret = stat (src, &sb);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- LG_MSG_FILE_STAT_FAILED, "stat on %s", src);
- goto out;
- }
- new_time[0].tv_sec = sb.st_atime;
- new_time[0].tv_usec = ST_ATIM_NSEC (&sb)/1000;
+gf_set_timestamp(const char *src, const char *dest)
+{
+ struct stat sb = {
+ 0,
+ };
+#if defined(HAVE_UTIMENSAT)
+ struct timespec new_time[2] = {{
+ 0,
+ },
+ {
+ 0,
+ }};
+#else
+ struct timeval new_time[2] = {{
+ 0,
+ },
+ {
+ 0,
+ }};
+#endif
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT(this);
+ GF_ASSERT(src);
+ GF_ASSERT(dest);
+
+ ret = sys_stat(src, &sb);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED,
+ "stat=%s", src, NULL);
+ goto out;
+ }
+ /* The granularity is nano seconds if `utimensat()` is available,
+ * and micro seconds otherwise.
+ */
+#if defined(HAVE_UTIMENSAT)
+ new_time[0].tv_sec = sb.st_atime;
+ new_time[0].tv_nsec = ST_ATIM_NSEC(&sb);
+
+ new_time[1].tv_sec = sb.st_mtime;
+ new_time[1].tv_nsec = ST_MTIM_NSEC(&sb);
+
+ /* dirfd = 0 is ignored because `dest` is an absolute path. */
+ ret = sys_utimensat(AT_FDCWD, dest, new_time, AT_SYMLINK_NOFOLLOW);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMENSAT_FAILED,
+ "dest=%s", dest, NULL);
+ }
+#else
+ new_time[0].tv_sec = sb.st_atime;
+ new_time[0].tv_usec = ST_ATIM_NSEC(&sb) / 1000;
- new_time[1].tv_sec = sb.st_mtime;
- new_time[1].tv_usec = ST_MTIM_NSEC (&sb)/1000;
+ new_time[1].tv_sec = sb.st_mtime;
+ new_time[1].tv_usec = ST_MTIM_NSEC(&sb) / 1000;
- /* The granularity is micro seconds as per the current
- * requiremnt. Hence using 'utimes'. This can be updated
- * to 'utimensat' if we need timestamp in nanoseconds.
- */
- ret = utimes (dest, new_time);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED,
- "utimes on %s", dest);
- }
+ ret = sys_utimes(dest, new_time);
+ if (ret) {
+ gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED,
+ "dest=%s", dest, NULL);
+ }
+#endif
out:
- return ret;
+ return ret;
}
static void
-gf_backtrace_end (char *buf, size_t frames)
+gf_backtrace_end(char *buf, size_t frames)
{
- size_t pos = 0;
+ size_t pos = 0;
- if (!buf)
- return;
+ if (!buf)
+ return;
- pos = strlen (buf);
+ pos = strlen(buf);
- frames = min(frames, GF_BACKTRACE_LEN - pos -1);
+ frames = min(frames, GF_BACKTRACE_LEN - pos - 1);
- if (frames <= 0)
- return;
+ if (0 == frames)
+ return;
- memset (buf+pos, ')', frames);
- buf[pos+frames] = '\0';
+ memset(buf + pos, ')', frames);
+ buf[pos + frames] = '\0';
}
/*Returns bytes written*/
static int
-gf_backtrace_append (char *buf, size_t pos, char *framestr)
+gf_backtrace_append(char *buf, size_t pos, char *framestr)
{
- if (pos >= GF_BACKTRACE_LEN)
- return -1;
- return snprintf (buf+pos, GF_BACKTRACE_LEN-pos, "(--> %s ", framestr);
+ if (pos >= GF_BACKTRACE_LEN)
+ return -1;
+ return snprintf(buf + pos, GF_BACKTRACE_LEN - pos, "(--> %s ", framestr);
}
static int
-gf_backtrace_fillframes (char *buf)
-{
- void *array[GF_BACKTRACE_FRAME_COUNT];
- size_t frames = 0;
- FILE *fp = NULL;
- char callingfn[GF_BACKTRACE_FRAME_COUNT-2][1024] = {{0},};
- int ret = -1;
- int fd = -1;
- size_t idx = 0;
- size_t pos = 0;
- size_t inc = 0;
- char tmpl[32] = "/tmp/btXXXXXX";
-
- frames = backtrace (array, GF_BACKTRACE_FRAME_COUNT);
- if (!frames)
- return -1;
-
- fd = gf_mkostemp (tmpl, 0, O_RDWR);
- if (fd == -1)
- return -1;
-
- /*The most recent two frames are the calling function and
- * gf_backtrace_save, which we can infer.*/
-
- backtrace_symbols_fd (&array[2], frames-2, fd);
-
- fp = fdopen (fd, "r");
- if (!fp) {
- close (fd);
- ret = -1;
- goto out;
- }
+gf_backtrace_fillframes(char *buf)
+{
+ void *array[GF_BACKTRACE_FRAME_COUNT];
+ size_t frames = 0;
+ FILE *fp = NULL;
+ char callingfn[GF_BACKTRACE_FRAME_COUNT - 2][1024] = {
+ {0},
+ };
+ int ret = -1;
+ int fd = -1;
+ size_t idx = 0;
+ size_t pos = 0;
+ size_t inc = 0;
+ char tmpl[] = "/tmp/glfs-bt-XXXXXX";
+
+ frames = backtrace(array, GF_BACKTRACE_FRAME_COUNT);
+ if (!frames)
+ return -1;
- ret = fseek (fp, 0L, SEEK_SET);
- if (ret)
- goto out;
+ /* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
+ fd = mkstemp(tmpl);
+ if (fd == -1)
+ return -1;
- pos = 0;
- for (idx = 0; idx < frames - 2; idx++) {
- ret = fscanf (fp, "%s", callingfn[idx]);
- if (ret == EOF)
- break;
- inc = gf_backtrace_append (buf, pos, callingfn[idx]);
- if (inc == -1)
- break;
- pos += inc;
- }
- gf_backtrace_end (buf, idx);
+ /* Calling unlink so that when the file is closed or program
+ * terminates the temporary file is deleted.
+ */
+ ret = sys_unlink(tmpl);
+ if (ret < 0) {
+ gf_smsg(THIS->name, GF_LOG_INFO, 0, LG_MSG_FILE_DELETE_FAILED,
+ "temporary_file=%s", tmpl, NULL);
+ }
+
+ /*The most recent two frames are the calling function and
+ * gf_backtrace_save, which we can infer.*/
+
+ backtrace_symbols_fd(&array[2], frames - 2, fd);
+
+ fp = fdopen(fd, "r");
+ if (!fp) {
+ sys_close(fd);
+ goto out;
+ }
+
+ ret = fseek(fp, 0L, SEEK_SET);
+ if (ret)
+ goto out;
+
+ pos = 0;
+ for (idx = 0; idx < frames - 2; idx++) {
+ ret = fscanf(fp, "%1023s", callingfn[idx]);
+ if (ret == EOF)
+ break;
+ inc = gf_backtrace_append(buf, pos, callingfn[idx]);
+ if (inc == -1)
+ break;
+ pos += inc;
+ }
+ gf_backtrace_end(buf, idx);
out:
- if (fp)
- fclose (fp);
-
- unlink (tmpl);
-
- return (idx > 0)? 0: -1;
+ if (fp)
+ fclose(fp);
+ return (idx > 0) ? 0 : -1;
}
/* Optionally takes @buf to save backtrace. If @buf is NULL, uses the
@@ -3628,66 +4502,69 @@ out:
* when there is a real-use for that.*/
char *
-gf_backtrace_save (char *buf)
+gf_backtrace_save(char *buf)
{
- char *bt = NULL;
+ char *bt = NULL;
- if (!buf) {
- bt = THIS->ctx->btbuf;
- GF_ASSERT (bt);
+ if (!buf) {
+ bt = THIS->ctx->btbuf;
+ GF_ASSERT(bt);
- } else {
- bt = buf;
-
- }
+ } else {
+ bt = buf;
+ }
- if ((0 == gf_backtrace_fillframes (bt)))
- return bt;
+ if ((0 == gf_backtrace_fillframes(bt)))
+ return bt;
- gf_msg (THIS->name, GF_LOG_WARNING, 0, LG_MSG_BACKTRACE_SAVE_FAILED,
- "Failed to save the backtrace.");
- return NULL;
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_BACKTRACE_SAVE_FAILED, NULL);
+ return NULL;
}
gf_loglevel_t
-fop_log_level (glusterfs_fop_t fop, int op_errno)
-{
- /* if gfid doesn't exist ESTALE comes */
- if (op_errno == ENOENT || op_errno == ESTALE)
- return GF_LOG_DEBUG;
-
- if ((fop == GF_FOP_ENTRYLK) ||
- (fop == GF_FOP_FENTRYLK) ||
- (fop == GF_FOP_FINODELK) ||
- (fop == GF_FOP_INODELK) ||
- (fop == GF_FOP_LK)) {
- /*
- * if non-blocking lock fails EAGAIN comes
- * if locks xlator is not loaded ENOSYS comes
- */
- if (op_errno == EAGAIN || op_errno == ENOSYS)
- return GF_LOG_DEBUG;
- }
-
- if ((fop == GF_FOP_GETXATTR) ||
- (fop == GF_FOP_FGETXATTR)) {
- if (op_errno == ENOTSUP || op_errno == ENODATA)
- return GF_LOG_DEBUG;
- }
+fop_log_level(glusterfs_fop_t fop, int op_errno)
+{
+ /* if gfid doesn't exist ESTALE comes */
+ if (op_errno == ENOENT || op_errno == ESTALE)
+ return GF_LOG_DEBUG;
- if ((fop == GF_FOP_SETXATTR) ||
- (fop == GF_FOP_FSETXATTR) ||
- (fop == GF_FOP_REMOVEXATTR) ||
- (fop == GF_FOP_FREMOVEXATTR)) {
- if (op_errno == ENOTSUP)
- return GF_LOG_DEBUG;
+ if ((fop == GF_FOP_ENTRYLK) || (fop == GF_FOP_FENTRYLK) ||
+ (fop == GF_FOP_FINODELK) || (fop == GF_FOP_INODELK) ||
+ (fop == GF_FOP_LK)) {
+ /*
+ * if non-blocking lock fails EAGAIN comes
+ * if locks xlator is not loaded ENOSYS comes
+ */
+ if (op_errno == EAGAIN || op_errno == ENOSYS)
+ return GF_LOG_DEBUG;
+ }
+
+ if ((fop == GF_FOP_GETXATTR) || (fop == GF_FOP_FGETXATTR)) {
+ if (op_errno == ENOTSUP || op_errno == ENODATA)
+ return GF_LOG_DEBUG;
+ }
+
+ if ((fop == GF_FOP_SETXATTR) || (fop == GF_FOP_FSETXATTR) ||
+ (fop == GF_FOP_REMOVEXATTR) || (fop == GF_FOP_FREMOVEXATTR)) {
+ if (op_errno == ENOTSUP)
+ return GF_LOG_DEBUG;
+ }
+
+ if (fop == GF_FOP_MKNOD || fop == GF_FOP_MKDIR)
+ if (op_errno == EEXIST)
+ return GF_LOG_DEBUG;
+
+ if (fop == GF_FOP_SEEK) {
+#ifdef HAVE_SEEK_HOLE
+ if (op_errno == ENXIO) {
+ return GF_LOG_DEBUG;
}
+#else
+ return GF_LOG_DEBUG;
+#endif
+ }
- if (fop == GF_FOP_MKNOD || fop == GF_FOP_MKDIR)
- if (op_errno == EEXIST)
- return GF_LOG_DEBUG;
-
- return GF_LOG_ERROR;
+ return GF_LOG_ERROR;
}
/* This function will build absolute path of file/directory from the
@@ -3705,116 +4582,115 @@ fop_log_level (glusterfs_fop_t fop, int op_errno)
*/
int32_t
-gf_build_absolute_path (char *current_path, char *relative_path, char **path)
-{
- char *absolute_path = NULL;
- char *token = NULL;
- char *component = NULL;
- char *saveptr = NULL;
- char *end = NULL;
- int ret = 0;
- size_t relativepath_len = 0;
- size_t currentpath_len = 0;
- size_t max_absolutepath_len = 0;
-
- GF_ASSERT (current_path);
- GF_ASSERT (relative_path);
- GF_ASSERT (path);
-
- if (!path || !current_path || !relative_path) {
- ret = -EFAULT;
- goto err;
- }
- /* Check for current and relative path
- * current path should be absolute one and start from '/'
- * relative path should not start from '/'
- */
- currentpath_len = strlen (current_path);
- if (current_path[0] != '/' || (currentpath_len > PATH_MAX)) {
- gf_msg (THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
- "Wrong value for current path %s", current_path);
- ret = -EINVAL;
- goto err;
- }
-
- relativepath_len = strlen (relative_path);
- if (relative_path[0] == '/' || (relativepath_len > PATH_MAX)) {
- gf_msg (THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
- "Wrong value for relative path %s", relative_path);
- ret = -EINVAL;
+gf_build_absolute_path(char *current_path, char *relative_path, char **path)
+{
+ char *absolute_path = NULL;
+ char *token = NULL;
+ char *component = NULL;
+ char *saveptr = NULL;
+ char *end = NULL;
+ int ret = 0;
+ size_t relativepath_len = 0;
+ size_t currentpath_len = 0;
+ size_t max_absolutepath_len = 0;
+
+ GF_ASSERT(current_path);
+ GF_ASSERT(relative_path);
+ GF_ASSERT(path);
+
+ if (!path || !current_path || !relative_path) {
+ ret = -EFAULT;
+ goto err;
+ }
+ /* Check for current and relative path
+ * current path should be absolute one and start from '/'
+ * relative path should not start from '/'
+ */
+ currentpath_len = strlen(current_path);
+ if (current_path[0] != '/' || (currentpath_len > PATH_MAX)) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_WRONG_VALUE,
+ "current-path=%s", current_path, NULL);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ relativepath_len = strlen(relative_path);
+ if (relative_path[0] == '/' || (relativepath_len > PATH_MAX)) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_WRONG_VALUE,
+ "relative-path=%s", relative_path, NULL);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* It is maximum possible value for absolute path */
+ max_absolutepath_len = currentpath_len + relativepath_len + 2;
+
+ absolute_path = GF_CALLOC(1, max_absolutepath_len, gf_common_mt_char);
+ if (!absolute_path) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ absolute_path[0] = '\0';
+
+ /* If current path is root i.e contains only "/", we do not
+ * need to copy it
+ */
+ if (strcmp(current_path, "/") != 0) {
+ strcpy(absolute_path, current_path);
+
+ /* We trim '/' at the end for easier string manipulation */
+ gf_path_strip_trailing_slashes(absolute_path);
+ }
+
+ /* Used to spilt relative path based on '/' */
+ component = gf_strdup(relative_path);
+ if (!component) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* In the relative path, we want to consider ".." and "."
+ * if token is ".." , we just need to reduce one level hierarchy
+ * if token is "." , we just ignore it
+ * if token is NULL , end of relative path
+ * if absolute path becomes '\0' and still "..", then it is a bad
+ * relative path, it points to out of boundary area and stop
+ * building the absolute path
+ * All other cases we just concatenate token to the absolute path
+ */
+ for (token = strtok_r(component, "/", &saveptr),
+ end = strchr(absolute_path, '\0');
+ token; token = strtok_r(NULL, "/", &saveptr)) {
+ if (strcmp(token, ".") == 0)
+ continue;
+
+ else if (strcmp(token, "..") == 0) {
+ if (absolute_path[0] == '\0') {
+ ret = -EACCES;
goto err;
- }
-
- /* It is maximum possible value for absolute path */
- max_absolutepath_len = currentpath_len + relativepath_len + 2;
-
- absolute_path = GF_CALLOC (1, max_absolutepath_len, gf_common_mt_char);
- if (!absolute_path) {
- ret = -ENOMEM;
- goto err;
- }
- absolute_path[0] = '\0';
-
- /* If current path is root i.e contains only "/", we do not
- * need to copy it
- */
- if (strcmp (current_path, "/") != 0) {
- strcpy (absolute_path, current_path);
+ }
- /* We trim '/' at the end for easier string manipulation */
- gf_path_strip_trailing_slashes (absolute_path);
- }
-
- /* Used to spilt relative path based on '/' */
- component = gf_strdup (relative_path);
- if (!component) {
- ret = -ENOMEM;
- goto err;
- }
-
- /* In the relative path, we want to consider ".." and "."
- * if token is ".." , we just need to reduce one level hierarchy
- * if token is "." , we just ignore it
- * if token is NULL , end of relative path
- * if absolute path becomes '\0' and still "..", then it is a bad
- * relative path, it points to out of boundary area and stop
- * building the absolute path
- * All other cases we just concatenate token to the absolute path
- */
- for (token = strtok_r (component, "/", &saveptr),
- end = strchr (absolute_path, '\0'); token;
- token = strtok_r (NULL, "/", &saveptr)) {
- if (strcmp (token, ".") == 0)
- continue;
-
- else if (strcmp (token, "..") == 0) {
-
- if (absolute_path[0] == '\0') {
- ret = -EACCES;
- goto err;
- }
-
- end = strrchr (absolute_path, '/');
- *end = '\0';
- } else {
- ret = snprintf (end, max_absolutepath_len -
- strlen (absolute_path), "/%s", token);
- end = strchr (absolute_path , '\0');
- }
+ end = strrchr(absolute_path, '/');
+ *end = '\0';
+ } else {
+ ret = snprintf(end, max_absolutepath_len - strlen(absolute_path),
+ "/%s", token);
+ end = strchr(absolute_path, '\0');
}
+ }
- if (strlen (absolute_path) > PATH_MAX) {
- ret = -EINVAL;
- goto err;
- }
- *path = gf_strdup (absolute_path);
+ if (strlen(absolute_path) > PATH_MAX) {
+ ret = -EINVAL;
+ goto err;
+ }
+ *path = gf_strdup(absolute_path);
err:
- if (component)
- GF_FREE (component);
- if (absolute_path)
- GF_FREE (absolute_path);
- return ret;
+ if (component)
+ GF_FREE(component);
+ if (absolute_path)
+ GF_FREE(absolute_path);
+ return ret;
}
/* This is an utility function which will recursively delete
@@ -3825,67 +4701,84 @@ err:
* @return 0 on success and -1 on failure.
*/
int
-recursive_rmdir (const char *delete_path)
-{
- int ret = -1;
- char path[PATH_MAX] = {0,};
- struct stat st = {0,};
- DIR *dir = NULL;
- struct dirent *entry = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- GF_VALIDATE_OR_GOTO (this->name, delete_path, out);
-
- dir = opendir (delete_path);
- if (!dir) {
- gf_msg_debug (this->name, 0, "Failed to open directory %s. "
- "Reason : %s", delete_path, strerror (errno));
- ret = 0;
- goto out;
- }
-
- GF_FOR_EACH_ENTRY_IN_DIR (entry, dir);
- while (entry) {
- snprintf (path, PATH_MAX, "%s/%s", delete_path, entry->d_name);
- ret = lstat (path, &st);
- if (ret == -1) {
- gf_msg_debug (this->name, 0, "Failed to stat entry %s :"
- " %s", path, strerror (errno));
- goto out;
- }
-
- if (S_ISDIR (st.st_mode))
- ret = recursive_rmdir (path);
- else
- ret = unlink (path);
-
- if (ret) {
- gf_msg_debug (this->name, 0, " Failed to remove %s. "
- "Reason : %s", path, strerror (errno));
- }
-
- gf_msg_debug (this->name, 0, "%s %s", ret ?
- "Failed to remove" : "Removed", entry->d_name);
-
- GF_FOR_EACH_ENTRY_IN_DIR (entry, dir);
- }
-
- ret = closedir (dir);
- if (ret) {
- gf_msg_debug (this->name, 0, "Failed to close dir %s. Reason :"
- " %s", delete_path, strerror (errno));
- }
+recursive_rmdir(const char *delete_path)
+{
+ int ret = -1;
+ char path[PATH_MAX] = {
+ 0,
+ };
+ struct stat st = {
+ 0,
+ };
+ DIR *dir = NULL;
+ struct dirent *entry = NULL;
+ struct dirent scratch[2] = {
+ {
+ 0,
+ },
+ };
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT(this);
+ GF_VALIDATE_OR_GOTO(this->name, delete_path, out);
+
+ dir = sys_opendir(delete_path);
+ if (!dir) {
+ gf_msg_debug(this->name, 0,
+ "Failed to open directory %s. "
+ "Reason : %s",
+ delete_path, strerror(errno));
+ ret = 0;
+ goto out;
+ }
+
+ while ((entry = sys_readdir(dir, scratch))) {
+ if (gf_irrelevant_entry(entry))
+ continue;
+ snprintf(path, PATH_MAX, "%s/%s", delete_path, entry->d_name);
+ ret = sys_lstat(path, &st);
+ if (ret == -1) {
+ gf_msg_debug(this->name, 0,
+ "Failed to stat entry %s :"
+ " %s",
+ path, strerror(errno));
+ (void)sys_closedir(dir);
+ goto out;
+ }
+
+ if (S_ISDIR(st.st_mode))
+ ret = recursive_rmdir(path);
+ else
+ ret = sys_unlink(path);
- ret = rmdir (delete_path);
if (ret) {
- gf_msg_debug (this->name, 0, "Failed to rmdir: %s,err: %s",
- delete_path, strerror (errno));
- }
+ gf_msg_debug(this->name, 0,
+ " Failed to remove %s. "
+ "Reason : %s",
+ path, strerror(errno));
+ }
+
+ gf_msg_debug(this->name, 0, "%s %s",
+ ret ? "Failed to remove" : "Removed", entry->d_name);
+ }
+
+ ret = sys_closedir(dir);
+ if (ret) {
+ gf_msg_debug(this->name, 0,
+ "Failed to close dir %s. Reason :"
+ " %s",
+ delete_path, strerror(errno));
+ }
+
+ ret = sys_rmdir(delete_path);
+ if (ret) {
+ gf_msg_debug(this->name, 0, "Failed to rmdir: %s,err: %s", delete_path,
+ strerror(errno));
+ }
out:
- return ret;
+ return ret;
}
/*
* Input: Array of strings 'array' terminating in NULL
@@ -3894,121 +4787,679 @@ out:
* Output: Index of the element in the array if found, '-1' otherwise
*/
int
-gf_get_index_by_elem (char **array, char *elem)
+gf_get_index_by_elem(char **array, char *elem)
{
- int i = 0;
+ int i = 0;
- for (i = 0; array[i]; i++) {
- if (strcmp (elem, array[i]) == 0)
- return i;
- }
+ for (i = 0; array[i]; i++) {
+ if (strcmp(elem, array[i]) == 0)
+ return i;
+ }
- return -1;
+ return -1;
}
static int
-get_pathinfo_host (char *pathinfo, char *hostname, size_t size)
+get_pathinfo_host(char *pathinfo, char *hostname, size_t size)
{
- char *start = NULL;
- char *end = NULL;
- int ret = -1;
- int i = 0;
+ char *start = NULL;
+ char *end = NULL;
+ int ret = -1;
+ int i = 0;
- if (!pathinfo)
- goto out;
+ if (!pathinfo)
+ goto out;
- start = strchr (pathinfo, ':');
- if (!start)
- goto out;
+ start = strchr(pathinfo, ':');
+ if (!start)
+ goto out;
- end = strrchr (pathinfo, ':');
- if (start == end)
- goto out;
+ end = strrchr(pathinfo, ':');
+ if (start == end)
+ goto out;
- memset (hostname, 0, size);
- i = 0;
- while (++start != end)
- hostname[i++] = *start;
- ret = 0;
+ memset(hostname, 0, size);
+ i = 0;
+ while (++start != end)
+ hostname[i++] = *start;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/*Note: 'pathinfo' should be gathered only from one brick*/
int
-glusterfs_is_local_pathinfo (char *pathinfo, gf_boolean_t *is_local)
+glusterfs_is_local_pathinfo(char *pathinfo, gf_boolean_t *is_local)
{
- int ret = 0;
- char pathinfohost[1024] = {0};
- char localhost[1024] = {0};
+ int ret = 0;
+ char pathinfohost[1024] = {0};
+ char localhost[1024] = {0};
- *is_local = _gf_false;
- ret = get_pathinfo_host (pathinfo, pathinfohost, sizeof (pathinfohost));
- if (ret)
- goto out;
+ *is_local = _gf_false;
+ ret = get_pathinfo_host(pathinfo, pathinfohost, sizeof(pathinfohost));
+ if (ret)
+ goto out;
- ret = gethostname (localhost, sizeof (localhost));
- if (ret)
- goto out;
+ ret = gethostname(localhost, sizeof(localhost));
+ if (ret)
+ goto out;
- if (!strcmp (localhost, pathinfohost))
- *is_local = _gf_true;
+ if (!strcmp(localhost, pathinfohost))
+ *is_local = _gf_true;
out:
- return ret;
+ return ret;
}
ssize_t
-gf_nread (int fd, void *buf, size_t count)
-{
- ssize_t ret = 0;
- ssize_t read_bytes = 0;
-
- for (read_bytes = 0; read_bytes < count; read_bytes += ret) {
- ret = read (fd, buf + read_bytes, count - read_bytes);
- if (ret == 0) {
- break;
- } else if (ret < 0) {
- if (errno == EINTR)
- ret = 0;
- else
- goto out;
- }
+gf_nread(int fd, void *buf, size_t count)
+{
+ ssize_t ret = 0;
+ ssize_t read_bytes = 0;
+
+ for (read_bytes = 0; read_bytes < count; read_bytes += ret) {
+ ret = sys_read(fd, buf + read_bytes, count - read_bytes);
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ if (errno == EINTR)
+ ret = 0;
+ else
+ goto out;
}
+ }
- ret = read_bytes;
+ ret = read_bytes;
out:
- return ret;
+ return ret;
}
ssize_t
-gf_nwrite (int fd, const void *buf, size_t count)
-{
- ssize_t ret = 0;
- ssize_t written = 0;
-
- for (written = 0; written != count; written += ret) {
- ret = write (fd, buf + written, count - written);
- if (ret < 0) {
- if (errno == EINTR)
- ret = 0;
- else
- goto out;
- }
+gf_nwrite(int fd, const void *buf, size_t count)
+{
+ ssize_t ret = 0;
+ ssize_t written = 0;
+
+ for (written = 0; written != count; written += ret) {
+ ret = sys_write(fd, buf + written, count - written);
+ if (ret < 0) {
+ if (errno == EINTR)
+ ret = 0;
+ else
+ goto out;
}
+ }
- ret = written;
+ ret = written;
out:
- return ret;
+ return ret;
+}
+
+void
+gf_free_mig_locks(lock_migration_info_t *locks)
+{
+ lock_migration_info_t *current = NULL;
+ lock_migration_info_t *temp = NULL;
+
+ if (!locks)
+ return;
+
+ if (list_empty(&locks->list))
+ return;
+
+ list_for_each_entry_safe(current, temp, &locks->list, list)
+ {
+ list_del_init(&current->list);
+ GF_FREE(current->client_uid);
+ GF_FREE(current);
+ }
+}
+
+void
+_mask_cancellation(void)
+{
+ (void)pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
}
void
-_mask_cancellation (void)
+_unmask_cancellation(void)
+{
+ (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+}
+
+/* This is a wrapper function to add a pointer to a list,
+ * which doesn't contain list member
+ */
+struct list_node *
+_list_node_add(void *ptr, struct list_head *list,
+ int (*compare)(struct list_head *, struct list_head *))
+{
+ struct list_node *node = NULL;
+
+ if (ptr == NULL || list == NULL)
+ goto out;
+
+ node = GF_CALLOC(1, sizeof(struct list_node), gf_common_list_node);
+
+ if (node == NULL)
+ goto out;
+
+ node->ptr = ptr;
+ if (compare)
+ list_add_order(&node->list, list, compare);
+ else
+ list_add_tail(&node->list, list);
+out:
+ return node;
+}
+
+struct list_node *
+list_node_add(void *ptr, struct list_head *list)
+{
+ return _list_node_add(ptr, list, NULL);
+}
+
+struct list_node *
+list_node_add_order(void *ptr, struct list_head *list,
+ int (*compare)(struct list_head *, struct list_head *))
{
- (void) pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
+ return _list_node_add(ptr, list, compare);
}
void
-_unmask_cancellation (void)
+list_node_del(struct list_node *node)
+{
+ if (node == NULL)
+ return;
+
+ list_del_init(&node->list);
+ GF_FREE(node);
+}
+
+const char *
+fop_enum_to_pri_string(glusterfs_fop_t fop)
+{
+ switch (fop) {
+ case GF_FOP_OPEN:
+ case GF_FOP_STAT:
+ case GF_FOP_FSTAT:
+ case GF_FOP_LOOKUP:
+ case GF_FOP_ACCESS:
+ case GF_FOP_READLINK:
+ case GF_FOP_OPENDIR:
+ case GF_FOP_STATFS:
+ case GF_FOP_READDIR:
+ case GF_FOP_READDIRP:
+ case GF_FOP_GETACTIVELK:
+ case GF_FOP_SETACTIVELK:
+ case GF_FOP_ICREATE:
+ case GF_FOP_NAMELINK:
+ return "HIGH";
+
+ case GF_FOP_CREATE:
+ case GF_FOP_FLUSH:
+ case GF_FOP_LK:
+ case GF_FOP_INODELK:
+ case GF_FOP_FINODELK:
+ case GF_FOP_ENTRYLK:
+ case GF_FOP_FENTRYLK:
+ case GF_FOP_UNLINK:
+ case GF_FOP_SETATTR:
+ case GF_FOP_FSETATTR:
+ case GF_FOP_MKNOD:
+ case GF_FOP_MKDIR:
+ case GF_FOP_RMDIR:
+ case GF_FOP_SYMLINK:
+ case GF_FOP_RENAME:
+ case GF_FOP_LINK:
+ case GF_FOP_SETXATTR:
+ case GF_FOP_GETXATTR:
+ case GF_FOP_FGETXATTR:
+ case GF_FOP_FSETXATTR:
+ case GF_FOP_REMOVEXATTR:
+ case GF_FOP_FREMOVEXATTR:
+ case GF_FOP_IPC:
+ case GF_FOP_LEASE:
+ return "NORMAL";
+
+ case GF_FOP_READ:
+ case GF_FOP_WRITE:
+ case GF_FOP_FSYNC:
+ case GF_FOP_TRUNCATE:
+ case GF_FOP_FTRUNCATE:
+ case GF_FOP_FSYNCDIR:
+ case GF_FOP_XATTROP:
+ case GF_FOP_FXATTROP:
+ case GF_FOP_RCHECKSUM:
+ case GF_FOP_ZEROFILL:
+ case GF_FOP_FALLOCATE:
+ case GF_FOP_SEEK:
+ return "LOW";
+
+ case GF_FOP_NULL:
+ case GF_FOP_FORGET:
+ case GF_FOP_RELEASE:
+ case GF_FOP_RELEASEDIR:
+ case GF_FOP_GETSPEC:
+ case GF_FOP_MAXVALUE:
+ case GF_FOP_DISCARD:
+ return "LEAST";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+const char *
+gf_inode_type_to_str(ia_type_t type)
+{
+ static const char *const str_ia_type[] = {
+ "UNKNOWN", "REGULAR FILE", "DIRECTORY", "LINK",
+ "BLOCK DEVICE", "CHARACTER DEVICE", "PIPE", "SOCKET"};
+ return str_ia_type[type];
+}
+
+gf_boolean_t
+gf_is_zero_filled_stat(struct iatt *buf)
+{
+ if (!buf)
+ return 1;
+
+ /* Do not use st_dev because it is transformed to store the xlator id
+ * in place of the device number. Do not use st_ino because by this time
+ * we've already mapped the root ino to 1 so it is not guaranteed to be
+ * 0.
+ */
+ if ((buf->ia_nlink == 0) && (buf->ia_ctime == 0))
+ return 1;
+
+ return 0;
+}
+
+void
+gf_zero_fill_stat(struct iatt *buf)
+{
+ buf->ia_nlink = 0;
+ buf->ia_ctime = 0;
+}
+
+gf_boolean_t
+gf_is_valid_xattr_namespace(char *key)
+{
+ static char *xattr_namespaces[] = {"trusted.", "system.", "user.",
+ "security.", NULL};
+ int i = 0;
+
+ for (i = 0; xattr_namespaces[i]; i++) {
+ if (strncmp(key, xattr_namespaces[i], strlen(xattr_namespaces[i])) == 0)
+ return _gf_true;
+ }
+
+ return _gf_false;
+}
+
+ino_t
+gfid_to_ino(uuid_t gfid)
+{
+ ino_t ino = 0;
+ int32_t i;
+
+ for (i = 8; i < 16; i++) {
+ ino <<= 8;
+ ino += (uint8_t)gfid[i];
+ }
+
+ return ino;
+}
+
+int
+gf_bits_count(uint64_t n)
+{
+ int val = 0;
+#if defined(__GNUC__) || defined(__clang__)
+ val = __builtin_popcountll(n);
+#else
+ n -= (n >> 1) & 0x5555555555555555ULL;
+ n = ((n >> 2) & 0x3333333333333333ULL) + (n & 0x3333333333333333ULL);
+ n = (n + (n >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ n += n >> 8;
+ n += n >> 16;
+ n += n >> 32;
+ val = n & 0xFF;
+#endif
+ return val;
+}
+
+int
+gf_bits_index(uint64_t n)
+{
+#if defined(__GNUC__) || defined(__clang__)
+ return __builtin_ffsll(n) - 1;
+#else
+ return ffsll(n) - 1;
+#endif
+}
+
+const char *
+gf_fop_string(glusterfs_fop_t fop)
+{
+ if ((fop > GF_FOP_NULL) && (fop < GF_FOP_MAXVALUE))
+ return gf_fop_list[fop];
+ return "INVALID";
+}
+
+int
+gf_fop_int(char *fop)
+{
+ int i = 0;
+
+ for (i = GF_FOP_NULL + 1; i < GF_FOP_MAXVALUE; i++) {
+ if (strcasecmp(fop, gf_fop_list[i]) == 0)
+ return i;
+ }
+ return -1;
+}
+
+int
+close_fds_except(int *fdv, size_t count)
+{
+ int i = 0;
+ size_t j = 0;
+ gf_boolean_t should_close = _gf_true;
+#ifdef GF_LINUX_HOST_OS
+ DIR *d = NULL;
+ struct dirent *de = NULL;
+ struct dirent scratch[2] = {
+ {
+ 0,
+ },
+ };
+ char *e = NULL;
+
+ d = sys_opendir("/proc/self/fd");
+ if (!d)
+ return -1;
+
+ for (;;) {
+ should_close = _gf_true;
+
+ errno = 0;
+ de = sys_readdir(d, scratch);
+ if (!de || errno != 0)
+ break;
+ i = strtoul(de->d_name, &e, 10);
+ if (*e != '\0' || i == dirfd(d))
+ continue;
+
+ for (j = 0; j < count; j++) {
+ if (i == fdv[j]) {
+ should_close = _gf_false;
+ break;
+ }
+ }
+ if (should_close)
+ sys_close(i);
+ }
+ sys_closedir(d);
+#else /* !GF_LINUX_HOST_OS */
+ struct rlimit rl;
+ int ret = -1;
+
+ ret = getrlimit(RLIMIT_NOFILE, &rl);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < rl.rlim_cur; i++) {
+ should_close = _gf_true;
+ for (j = 0; j < count; j++) {
+ if (i == fdv[j]) {
+ should_close = _gf_false;
+ break;
+ }
+ }
+ if (should_close)
+ sys_close(i);
+ }
+#endif /* !GF_LINUX_HOST_OS */
+ return 0;
+}
+
+/**
+ * gf_getgrouplist - get list of groups to which a user belongs
+ *
+ * A convenience wrapper for getgrouplist(3).
+ *
+ * @param user - same as in getgrouplist(3)
+ * @param group - same as in getgrouplist(3)
+ * @param groups - pointer to a gid_t pointer
+ *
+ * gf_getgrouplist allocates a gid_t buffer which is big enough to
+ * hold the list of auxiliary group ids for user, up to the GF_MAX_AUX_GROUPS
+ * threshold. Upon successful invocation groups will be pointed to that buffer.
+ *
+ * @return success: the number of auxiliary group ids retrieved
+ * failure: -1
+ */
+int
+gf_getgrouplist(const char *user, gid_t group, gid_t **groups)
+{
+ int ret = -1;
+ int ngroups = SMALL_GROUP_COUNT;
+
+ *groups = GF_CALLOC(sizeof(gid_t), ngroups, gf_common_mt_groups_t);
+ if (!*groups)
+ return -1;
+
+ /*
+ * We are running getgrouplist() in a loop until we succeed (or hit
+ * certain exit conditions, see the comments below). This is because
+ * the indicated number of auxiliary groups that we obtain in case of
+ * the failure of the first invocation is not guaranteed to keep its
+ * validity upon the next invocation with a gid buffer of that size.
+ */
+ for (;;) {
+ int ngroups_old = ngroups;
+ ret = getgrouplist(user, group, *groups, &ngroups);
+ if (ret != -1)
+ break;
+
+ if (ngroups >= GF_MAX_AUX_GROUPS) {
+ /*
+ * This should not happen as GF_MAX_AUX_GROUPS is set
+ * to the max value of number of supported auxiliary
+ * groups across all platforms supported by GlusterFS.
+ * However, if it still happened some way, we wouldn't
+ * care about the incompleteness of the result, we'd
+ * just go on with what we got.
+ */
+ return GF_MAX_AUX_GROUPS;
+ } else if (ngroups <= ngroups_old) {
+ /*
+ * There is an edge case that getgrouplist() fails but
+ * ngroups remains the same. This is actually not
+ * specified in getgrouplist(3), but implementations
+ * can do this upon internal failure[1]. To avoid
+ * falling into an infinite loop when this happens, we
+ * break the loop if the getgrouplist call failed
+ * without an increase in the indicated group number.
+ *
+ * [1]
+ * https://sourceware.org/git/?p=glibc.git;a=blob;f=grp/initgroups.c;hb=refs/heads/release/2.25/master#l168
+ */
+ GF_FREE(*groups);
+ return -1;
+ }
+
+ *groups = GF_REALLOC(*groups, ngroups * sizeof(gid_t));
+ if (!*groups)
+ return -1;
+ }
+ return ret;
+}
+
+int
+glusterfs_compute_sha256(const unsigned char *content, size_t size,
+ char *sha256_hash)
+{
+ SHA256_CTX sha256;
+
+ SHA256_Init(&sha256);
+ SHA256_Update(&sha256, (const unsigned char *)(content), size);
+ SHA256_Final((unsigned char *)sha256_hash, &sha256);
+
+ return 0;
+}
+
+/* * Safe wrapper function for strncpy.
+ * This wrapper makes sure that when there is no null byte among the first n in
+ * source srting for strncpy function call, the string placed in dest will be
+ * null-terminated.
+ */
+
+char *
+gf_strncpy(char *dest, const char *src, const size_t dest_size)
+{
+ strncpy(dest, src, dest_size - 1);
+ dest[dest_size - 1] = '\0';
+ return dest;
+}
+
+int
+gf_replace_old_iatt_in_dict(dict_t *xdata)
+{
+ int ret;
+ struct old_iatt *o_iatt; /* old iatt structure */
+ struct iatt *c_iatt; /* current iatt */
+
+ if (!xdata) {
+ return 0;
+ }
+
+ ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&c_iatt);
+ if (ret < 0) {
+ return 0;
+ }
+
+ o_iatt = GF_CALLOC(1, sizeof(struct old_iatt), gf_common_mt_char);
+ if (!o_iatt) {
+ return -1;
+ }
+
+ oldiatt_from_iatt(o_iatt, c_iatt);
+
+ ret = dict_set_bin(xdata, DHT_IATT_IN_XDATA_KEY, o_iatt,
+ sizeof(struct old_iatt));
+ if (ret) {
+ GF_FREE(o_iatt);
+ }
+
+ return ret;
+}
+
+int
+gf_replace_new_iatt_in_dict(dict_t *xdata)
+{
+ int ret;
+ struct old_iatt *o_iatt; /* old iatt structure */
+ struct iatt *c_iatt; /* new iatt */
+
+ if (!xdata) {
+ return 0;
+ }
+
+ ret = dict_get_bin(xdata, DHT_IATT_IN_XDATA_KEY, (void **)&o_iatt);
+ if (ret < 0) {
+ return 0;
+ }
+
+ c_iatt = GF_CALLOC(1, sizeof(struct iatt), gf_common_mt_char);
+ if (!c_iatt) {
+ return -1;
+ }
+
+ iatt_from_oldiatt(c_iatt, o_iatt);
+
+ ret = dict_set_bin(xdata, DHT_IATT_IN_XDATA_KEY, c_iatt,
+ sizeof(struct iatt));
+ if (ret) {
+ GF_FREE(c_iatt);
+ }
+
+ return ret;
+}
+
+xlator_cmdline_option_t *
+find_xlator_option_in_cmd_args_t(const char *option_name, cmd_args_t *args)
+{
+ xlator_cmdline_option_t *pos = NULL;
+ xlator_cmdline_option_t *tmp = NULL;
+
+ list_for_each_entry_safe(pos, tmp, &args->xlator_options, cmd_args)
+ {
+ if (strcmp(pos->key, option_name) == 0)
+ return pos;
+ }
+ return NULL;
+}
+
+int
+gf_d_type_from_ia_type(ia_type_t type)
+{
+ switch (type) {
+ case IA_IFDIR:
+ return DT_DIR;
+ case IA_IFCHR:
+ return DT_CHR;
+ case IA_IFBLK:
+ return DT_BLK;
+ case IA_IFIFO:
+ return DT_FIFO;
+ case IA_IFLNK:
+ return DT_LNK;
+ case IA_IFREG:
+ return DT_REG;
+ case IA_IFSOCK:
+ return DT_SOCK;
+ default:
+ return DT_UNKNOWN;
+ }
+}
+
+int
+gf_nanosleep(uint64_t nsec)
+{
+ struct timespec req;
+ struct timespec rem;
+ int ret = -1;
+
+ req.tv_sec = nsec / GF_SEC_IN_NS;
+ req.tv_nsec = nsec % GF_SEC_IN_NS;
+
+ do {
+ ret = nanosleep(&req, &rem);
+ req = rem;
+ } while (ret == -1 && errno == EINTR);
+
+ return ret;
+}
+
+int
+gf_syncfs(int fd)
+{
+ int ret = 0;
+#if defined(HAVE_SYNCFS)
+ /* Linux with glibc recent enough. */
+ ret = syncfs(fd);
+#elif defined(HAVE_SYNCFS_SYS)
+ /* Linux with no library function. */
+ ret = syscall(SYS_syncfs, fd);
+#else
+ /* Fallback to generic UNIX stuff. */
+ sync();
+#endif
+ return ret;
+}
+
+char **
+get_xattrs_to_heal()
{
- (void) pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
+ return xattrs_to_heal;
}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
deleted file mode 100644
index 77a8cdd51c7..00000000000
--- a/libglusterfs/src/common-utils.h
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- 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
-#define _COMMON_UTILS_H
-
-#include <stdint.h>
-#include <sys/uio.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <pthread.h>
-#include <openssl/md5.h>
-#ifndef GF_BSD_HOST_OS
-#include <alloca.h>
-#endif
-#include <limits.h>
-#include <fnmatch.h>
-
-void trap (void);
-
-#define GF_UNIVERSAL_ANSWER 42 /* :O */
-
-/* To solve type punned error */
-#define VOID(ptr) ((void **) ((void *) ptr))
-
-#include "logging.h"
-#include "glusterfs.h"
-#include "locking.h"
-#include "mem-pool.h"
-#include "compat-uuid.h"
-#include "uuid.h"
-#include "libglusterfs-messages.h"
-
-#define STRINGIFY(val) #val
-#define TOSTRING(val) STRINGIFY(val)
-
-#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))
-#define floor(a,b) (((a)/((b)?(b):1))*(b))
-
-#define IPv4_ADDR_SIZE 32
-
-
-#define GF_UNIT_KB 1024ULL
-#define GF_UNIT_MB 1048576ULL
-#define GF_UNIT_GB 1073741824ULL
-#define GF_UNIT_TB 1099511627776ULL
-#define GF_UNIT_PB 1125899906842624ULL
-
-#define GF_UNIT_B_STRING "B"
-#define GF_UNIT_KB_STRING "KB"
-#define GF_UNIT_MB_STRING "MB"
-#define GF_UNIT_GB_STRING "GB"
-#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 GF_SELINUX_XATTR_KEY "security.selinux"
-
-#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 2049
-#define GF_CLIENT_PORT_CEILING 1024
-#define GF_PORT_MAX 65535
-
-#define GF_MINUTE_IN_SECONDS 60
-#define GF_HOUR_IN_SECONDS (60*60)
-#define GF_DAY_IN_SECONDS (24*60*60)
-#define GF_WEEK_IN_SECONDS (7*24*60*60)
-
-/* Default timeout for both barrier and changelog translator */
-#define BARRIER_TIMEOUT "120"
-
-/* Default value of signing waiting time to sign a file for bitrot */
-#define SIGNING_TIMEOUT "120"
-
-enum _gf_boolean
-{
- _gf_false = 0,
- _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,
- GF_CLIENT_PID_NO_ROOT_SQUASH = -4,
- GF_CLIENT_PID_QUOTA_MOUNT = -5,
- GF_CLIENT_PID_AFR_SELF_HEALD = -6,
- GF_CLIENT_PID_GLFS_HEAL = -7,
- GF_CLIENT_PID_BITD = -8,
- GF_CLIENT_PID_SCRUB = -9,
- GF_CLIENT_PID_TIER_DEFRAG = -10
-};
-
-enum _gf_xlator_ipc_targets {
- GF_IPC_TARGET_CHANGELOG = 0,
- GF_IPC_TARGET_CTR = 1
-};
-
-typedef enum _gf_boolean gf_boolean_t;
-typedef enum _gf_client_pid gf_client_pid_t;
-typedef enum _gf_xlator_ipc_targets _gf_xlator_ipc_targets_t;
-
-/* The DHT file rename operation is not a straightforward rename.
- * It involves creating linkto and linkfiles, and can unlink or rename the
- * source file depending on the hashed and cached subvols for the source
- * and target files. this makes it difficult for geo-rep to figure out that
- * a rename operation has taken place.
- *
- * We now send a special key and the values of the source and target pargfids
- * and basenames to indicate to changelog that the operation in question
- * should be treated as a rename. We are explicitly filling and sending this
- * as a binary value in the dictionary as the unlink op will not have the
- * source file information. The lengths of the src and target basenames
- * are used to calculate where to start reading the names in the structure.
- * XFS allows a max of 255 chars for filenames but other file systems might
- * not have such restrictions
- */
-typedef struct dht_changelog_rename_info {
- uuid_t old_pargfid;
- uuid_t new_pargfid;
- int32_t oldname_len;
- int32_t newname_len;
- char buffer[1];
- } dht_changelog_rename_info_t;
-
-
-typedef int (*gf_cmp) (void *, void *);
-
-void gf_global_variable_init(void);
-
-int32_t gf_resolve_ip6 (const char *hostname, uint16_t port, int family,
- void **dnscache, struct addrinfo **addr_info);
-
-void gf_log_dump_graph (FILE *specfp, glusterfs_graph_t *graph);
-void gf_print_trace (int32_t signal, glusterfs_ctx_t *ctx);
-int gf_set_log_file_path (cmd_args_t *cmd_args);
-int gf_set_log_ident (cmd_args_t *cmd_args);
-
-#define VECTORSIZE(count) (count * (sizeof (struct iovec)))
-
-#define STRLEN_0(str) (strlen(str) + 1)
-
-#define VALIDATE_OR_GOTO(arg,label) do { \
- if (!arg) { \
- errno = EINVAL; \
- gf_msg_callingfn ((this ? (this->name) : \
- "(Govinda! Govinda!)"), \
- GF_LOG_WARNING, EINVAL, \
- LG_MSG_INVALID_ARG, \
- "invalid argument: " #arg); \
- goto label; \
- } \
- } while (0)
-
-#define GF_VALIDATE_OR_GOTO(name,arg,label) do { \
- if (!arg) { \
- errno = EINVAL; \
- gf_msg_callingfn (name, GF_LOG_ERROR, errno, \
- LG_MSG_INVALID_ARG, \
- "invalid argument: " #arg); \
- goto label; \
- } \
- } while (0)
-
-#define GF_VALIDATE_OR_GOTO_WITH_ERROR(name, arg, label, errno, error) do { \
- if (!arg) { \
- errno = error; \
- gf_msg_callingfn (name, GF_LOG_ERROR, EINVAL, \
- LG_MSG_INVALID_ARG, \
- "invalid argument: " #arg); \
- goto label; \
- } \
- }while (0)
-
-#define GF_CHECK_ALLOC(arg, retval, label) do { \
- if (!(arg)) { \
- retval = -ENOMEM; \
- goto label; \
- } \
- } while (0) \
-
-#define GF_CHECK_ALLOC_AND_LOG(name, item, retval, msg, errlabel) do { \
- if (!(item)) { \
- (retval) = -ENOMEM; \
- gf_msg (name, GF_LOG_CRITICAL, ENOMEM, \
- LG_MSG_NO_MEMORY, (msg)); \
- goto errlabel; \
- } \
- } 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 { \
- GF_VALIDATE_OR_GOTO (name, arg, label); \
- if ((arg[0]) != '/') { \
- errno = EINVAL; \
- gf_msg_callingfn (name, GF_LOG_ERROR, EINVAL, \
- LG_MSG_INVALID_ARG, \
- "invalid argument: " #arg); \
- goto label; \
- } \
- } 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_REMOVE_INTERNAL_XATTR(pattern, dict) \
- do { \
- if (!dict) { \
- gf_msg (this->name, GF_LOG_ERROR, 0, \
- LG_MSG_DICT_NULL, "dict is null"); \
- break; \
- } \
- dict_foreach_fnmatch (dict, pattern, \
- dict_remove_foreach_fn, \
- NULL); \
- } while (0)
-
-#define GF_IF_INTERNAL_XATTR_GOTO(pattern, dict, op_errno, label) \
- do { \
- if (!dict) { \
- gf_msg (this->name, GF_LOG_ERROR, 0, \
- LG_MSG_DICT_NULL, \
- "setxattr dict is null"); \
- goto label; \
- } \
- if (dict_foreach_fnmatch (dict, pattern, \
- dict_null_foreach_fn, \
- NULL) > 0) { \
- op_errno = EPERM; \
- gf_msg (this->name, GF_LOG_ERROR, op_errno, \
- LG_MSG_NO_PERM, \
- "attempt to set internal" \
- " xattr: %s", pattern); \
- goto label; \
- } \
- } while (0)
-
-#define GF_IF_NATIVE_XATTR_GOTO(pattern, key, op_errno, label) \
- do { \
- if (!key) { \
- gf_msg (this->name, GF_LOG_ERROR, 0, \
- LG_MSG_NO_KEY, \
- "no key for removexattr"); \
- goto label; \
- } \
- if (!fnmatch (pattern, key, 0)) { \
- op_errno = EPERM; \
- gf_msg (this->name, GF_LOG_ERROR, op_errno, \
- LG_MSG_NO_PERM, \
- "attempt to remove internal " \
- "xattr: %s", key); \
- goto label; \
- } \
- } while (0)
-
-
-#define GF_FILE_CONTENT_REQUESTED(_xattr_req,_content_limit) \
- (dict_get_uint64 (_xattr_req, "glusterfs.content", _content_limit) == 0)
-
-#ifdef DEBUG
-#define GF_ASSERT(x) assert (x);
-#else
-#define GF_ASSERT(x) \
- do { \
- if (!(x)) { \
- gf_msg_callingfn ("", GF_LOG_ERROR, 0, \
- LG_MSG_ASSERTION_FAILED, \
- "Assertion failed: " #x); \
- } \
- } while (0)
-#endif
-
-#define GF_UUID_ASSERT(u) \
- if (gf_uuid_is_null (u))\
- GF_ASSERT (!"uuid null");
-
-#define GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, op_errno) \
- (((frame->root->pid == GF_CLIENT_PID_GSYNCD) && \
- (op_errno == EEXIST || op_errno == ENOENT))?0:1) \
-
-union gf_sock_union {
- struct sockaddr_storage storage;
- struct sockaddr_in6 sin6;
- struct sockaddr_in sin;
- struct sockaddr sa;
-};
-
-#define GF_HIDDEN_PATH ".glusterfs"
-
-#define IOV_MIN(n) min(IOV_MAX,n)
-
-#define GF_FOR_EACH_ENTRY_IN_DIR(entry, dir) \
- do {\
- entry = NULL;\
- if (dir) { \
- entry = readdir (dir); \
- while (entry && (!strcmp (entry->d_name, ".") || \
- !fnmatch ("*.tmp", entry->d_name, 0) || \
- !strcmp (entry->d_name, ".."))) { \
- entry = readdir (dir); \
- } \
- } \
- } while (0)
-
-static inline void
-iov_free (struct iovec *vector, int count)
-{
- int i;
-
- for (i = 0; i < count; i++)
- FREE (vector[i].iov_base);
-
- GF_FREE (vector);
-}
-
-
-static inline int
-iov_length (const struct iovec *vector, int count)
-{
- int i = 0;
- size_t size = 0;
-
- for (i = 0; i < count; i++)
- size += vector[i].iov_len;
-
- return size;
-}
-
-
-static inline struct iovec *
-iov_dup (const struct iovec *vector, int count)
-{
- int bytecount = 0;
- int i;
- struct iovec *newvec = NULL;
-
- bytecount = (count * sizeof (struct iovec));
- newvec = GF_MALLOC (bytecount, gf_common_mt_iovec);
- if (!newvec)
- return NULL;
-
- for (i = 0; i < count; i++) {
- newvec[i].iov_len = vector[i].iov_len;
- newvec[i].iov_base = vector[i].iov_base;
- }
-
- return newvec;
-}
-
-
-static inline int
-iov_subset (struct iovec *orig, int orig_count,
- off_t src_offset, off_t dst_offset,
- struct iovec *new)
-{
- int new_count = 0;
- int i;
- off_t offset = 0;
- size_t start_offset = 0;
- size_t end_offset = 0;
-
-
- for (i = 0; i < orig_count; i++) {
- if ((offset + orig[i].iov_len < src_offset)
- || (offset > dst_offset)) {
- goto not_subset;
- }
-
- if (!new) {
- goto count_only;
- }
-
- start_offset = 0;
- end_offset = orig[i].iov_len;
-
- if (src_offset >= offset) {
- start_offset = (src_offset - offset);
- }
-
- if (dst_offset <= (offset + orig[i].iov_len)) {
- end_offset = (dst_offset - offset);
- }
-
- new[new_count].iov_base = orig[i].iov_base + start_offset;
- new[new_count].iov_len = end_offset - start_offset;
-
- count_only:
- new_count++;
-
- not_subset:
- offset += orig[i].iov_len;
- }
-
- return new_count;
-}
-
-
-static inline void
-iov_unload (char *buf, const struct iovec *vector, int count)
-{
- int i;
- int copied = 0;
-
- for (i = 0; i < count; i++) {
- memcpy (buf + copied, vector[i].iov_base, vector[i].iov_len);
- copied += vector[i].iov_len;
- }
-}
-
-
-static inline size_t
-iov_load (const struct iovec *vector, int count, char *buf, int size)
-{
- size_t left = size;
- size_t cp = 0;
- int ret = 0;
- int i = 0;
-
- while (left && i < count) {
- cp = min (vector[i].iov_len, left);
- if (vector[i].iov_base != buf + (size - left))
- memcpy (vector[i].iov_base, buf + (size - left), cp);
- ret += cp;
- left -= cp;
- if (left)
- i++;
- }
-
- return ret;
-}
-
-
-static inline size_t
-iov_copy (const struct iovec *dst, int dcnt,
- const struct iovec *src, int scnt)
-{
- size_t ret = 0;
- size_t left = 0;
- size_t min_i = 0;
- int s_i = 0, s_ii = 0;
- int d_i = 0, d_ii = 0;
-
- ret = min (iov_length (dst, dcnt), iov_length (src, scnt));
- left = ret;
-
- while (left) {
- min_i = min (dst[d_i].iov_len - d_ii, src[s_i].iov_len - s_ii);
- memcpy (dst[d_i].iov_base + d_ii, src[s_i].iov_base + s_ii,
- min_i);
-
- d_ii += min_i;
- if (d_ii == dst[d_i].iov_len) {
- d_ii = 0;
- d_i++;
- }
-
- s_ii += min_i;
- if (s_ii == src[s_i].iov_len) {
- s_ii = 0;
- s_i++;
- }
-
- left -= min_i;
- }
-
- return ret;
-}
-
-
-static inline int
-mem_0filled (const char *buf, size_t size)
-{
- int i = 0;
- int ret = 0;
-
- for (i = 0; i < size; i++) {
- ret = buf[i];
- if (ret)
- break;
- }
-
- return ret;
-}
-
-
-static inline int
-iov_0filled (struct iovec *vector, int count)
-{
- int i = 0;
- int ret = 0;
-
- for (i = 0; i < count; i++) {
- ret = mem_0filled (vector[i].iov_base, vector[i].iov_len);
- if (ret)
- break;
- }
-
- return ret;
-}
-
-
-static inline void *
-memdup (const void *ptr, size_t size)
-{
- void *newptr = NULL;
-
- newptr = GF_MALLOC (size, gf_common_mt_memdup);
- if (!newptr)
- return NULL;
-
- memcpy (newptr, ptr, 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, /* MMM DD hh:mm:ss */
- gf_timefmt_F_HMS, /* YYYY-MM-DD hhmmss */
- gf_timefmt_dirent,
- gf_timefmt_s,
- gf_timefmt_last
-} gf_timefmts;
-
-static inline char *
-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 == (gf_timefmts) - 1)
- _gf_timestuff (&timefmt_last, &fmts, &zeros);
- if (timefmt_last < fmt) fmt = gf_timefmt_default;
- if (utime && gmtime_r (&utime, &tm) != NULL) {
- strftime (dst, sz_dst, fmts[fmt], &tm);
- } else {
- strncpy (dst, "N/A", sz_dst);
- }
- return dst;
-}
-
-int
-mkdir_p (char *path, mode_t mode, gf_boolean_t allow_symlinks);
-/*
- * rounds up nr to power of two. If nr is already a power of two, just returns
- * nr
- */
-
-int
-gf_lstat_dir (const char *path, struct stat *stbuf_in);
-
-int32_t gf_roundup_power_of_two (int32_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 (int32_t nr);
-
-char *gf_trim (char *string);
-int gf_strsplit (const char *str, const char *delim,
- char ***tokens, int *token_count);
-int gf_volume_name_validate (const char *volume_name);
-
-int gf_string2long (const char *str, long *n);
-int gf_string2ulong (const char *str, unsigned long *n);
-int gf_string2int (const char *str, int *n);
-int gf_string2uint (const char *str, unsigned int *n);
-int gf_string2double (const char *str, double *n);
-int gf_string2longlong (const char *str, long long *n);
-int gf_string2ulonglong (const char *str, unsigned long long *n);
-
-int gf_string2int8 (const char *str, int8_t *n);
-int gf_string2int16 (const char *str, int16_t *n);
-int gf_string2int32 (const char *str, int32_t *n);
-int gf_string2int64 (const char *str, int64_t *n);
-int gf_string2uint8 (const char *str, uint8_t *n);
-int gf_string2uint16 (const char *str, uint16_t *n);
-int gf_string2uint32 (const char *str, uint32_t *n);
-int gf_string2uint64 (const char *str, uint64_t *n);
-
-int gf_strstr (const char *str, const char *delim, const char *match);
-
-int gf_string2ulong_base10 (const char *str, unsigned long *n);
-int gf_string2uint_base10 (const char *str, unsigned int *n);
-int gf_string2uint8_base10 (const char *str, uint8_t *n);
-int gf_string2uint16_base10 (const char *str, uint16_t *n);
-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_string2bytesize_size (const char *str, size_t *n);
-int gf_string2bytesize_uint64 (const char *str, uint64_t *n);
-int gf_string2bytesize_int64 (const char *str, int64_t *n);
-int gf_string2percent_or_bytesize (const char *str, double *n,
- gf_boolean_t *is_percent);
-
-int gf_string2boolean (const char *str, gf_boolean_t *b);
-int gf_string2percent (const char *str, double *n);
-int gf_string2time (const char *str, uint32_t *n);
-
-int gf_lockfd (int fd);
-int gf_unlockfd (int fd);
-
-int get_checksum_for_file (int fd, uint32_t *checksum);
-int log_base2 (unsigned long x);
-
-int get_checksum_for_path (char *path, uint32_t *checksum);
-int get_file_mtime (const char *path, time_t *stamp);
-char *gf_resolve_path_parent (const char *path);
-
-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);
-
-gf_boolean_t mask_match (const uint32_t a, const uint32_t b, const uint32_t m);
-gf_boolean_t gf_is_ip_in_net (const char *network, const char *ip_str);
-char valid_host_name (char *address, int length);
-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);
-gf_boolean_t valid_mount_auth_address (char *address);
-gf_boolean_t valid_ipv4_subnetwork (const char *address);
-gf_boolean_t gf_sock_union_equal_addr (union gf_sock_union *a,
- union gf_sock_union *b);
-char *gf_rev_dns_lookup (const char *ip);
-
-char *uuid_utoa (uuid_t uuid);
-char *uuid_utoa_r (uuid_t uuid, char *dst);
-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);
-int gf_canonicalize_path (char *path);
-char *generate_glusterfs_ctx_id (void);
-char *gf_get_reserved_ports();
-int gf_process_reserved_ports (gf_boolean_t ports[], uint32_t ceiling);
-gf_boolean_t
-gf_ports_reserved (char *blocked_port, gf_boolean_t *ports, uint32_t ceiling);
-int gf_get_hostname_from_ip (char *client_ip, char **hostname);
-gf_boolean_t gf_is_local_addr (char *hostname);
-gf_boolean_t gf_is_same_address (char *host1, char *host2);
-void md5_wrapper(const unsigned char *data, size_t len, char *md5);
-int gf_set_timestamp (const char *src, const char* dest);
-
-int gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine)(void *), void *arg);
-gf_boolean_t
-gf_is_service_running (char *pidfile, int *pid);
-int
-gf_skip_header_section (int fd, int header_len);
-
-struct iatt;
-struct _dict;
-
-gf_boolean_t
-dht_is_linkfile (struct iatt *buf, struct _dict *dict);
-
-int
-gf_check_log_format (const char *value);
-
-int
-gf_check_logger (const char *value);
-
-gf_boolean_t
-gf_compare_sockaddr (const struct sockaddr *addr1,
- const struct sockaddr *addr2);
-
-char *
-gf_backtrace_save (char *buf);
-
-void
-gf_backtrace_done (char *buf);
-
-gf_loglevel_t
-fop_log_level (glusterfs_fop_t fop, int op_errno);
-
-int32_t
-gf_build_absolute_path (char *current_path, char *relative_path, char **path);
-
-int
-recursive_rmdir (const char *delete_path);
-
-int
-gf_get_index_by_elem (char **array, char *elem);
-
-int
-glusterfs_is_local_pathinfo (char *pathinfo, gf_boolean_t *local);
-
-int
-gf_thread_cleanup_xint (pthread_t thread);
-
-ssize_t
-gf_nread (int fd, void *buf, size_t count);
-
-ssize_t
-gf_nwrite (int fd, const void *buf, size_t count);
-
-void _mask_cancellation (void);
-void _unmask_cancellation (void);
-
-#endif /* _COMMON_UTILS_H */
diff --git a/libglusterfs/src/compat-errno.c b/libglusterfs/src/compat-errno.c
index 3674596ad71..df57e243239 100644
--- a/libglusterfs/src/compat-errno.c
+++ b/libglusterfs/src/compat-errno.c
@@ -10,8 +10,7 @@
#include <stdint.h>
-#include "compat-errno.h"
-
+#include "glusterfs/compat-errno.h"
static int32_t gf_error_to_errno_array[1024];
static int32_t gf_errno_to_error_array[1024];
@@ -20,912 +19,937 @@ static int32_t gf_compat_errno_init_done;
#ifdef GF_SOLARIS_HOST_OS
static void
-init_compat_errno_arrays ()
+init_compat_errno_arrays()
{
-/* ENOMSG 35 / * No message of desired type */
- gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
- gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
-
-/* EIDRM 36 / * Identifier removed */
- gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
- gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
-
-/* ECHRNG 37 / * Channel number out of range */
- gf_error_to_errno_array[GF_ERROR_CODE_CHRNG] = ECHRNG;
- gf_errno_to_error_array[ECHRNG] = GF_ERROR_CODE_CHRNG;
-
-/* EL2NSYNC 38 / * Level 2 not synchronized */
- gf_error_to_errno_array[GF_ERROR_CODE_L2NSYNC] = EL2NSYNC;
- gf_errno_to_error_array[EL2NSYNC] = GF_ERROR_CODE_L2NSYNC;
-
-/* EL3HLT 39 / * Level 3 halted */
- gf_error_to_errno_array[GF_ERROR_CODE_L3HLT] = EL3HLT;
- gf_errno_to_error_array[EL3HLT] = GF_ERROR_CODE_L3HLT;
-
-/* EL3RST 40 / * Level 3 reset */
- gf_error_to_errno_array[GF_ERROR_CODE_L3RST] = EL3RST;
- gf_errno_to_error_array[EL3RST] = GF_ERROR_CODE_L3RST;
-
-/* ELNRNG 41 / * Link number out of range */
- gf_error_to_errno_array[GF_ERROR_CODE_LNRNG] = ELNRNG;
- gf_errno_to_error_array[ELNRNG] = GF_ERROR_CODE_LNRNG;
-
-/* EUNATCH 42 / * Protocol driver not attached */
- gf_error_to_errno_array[GF_ERROR_CODE_UNATCH] = EUNATCH;
- gf_errno_to_error_array[EUNATCH] = GF_ERROR_CODE_UNATCH;
-
-/* ENOCSI 43 / * No CSI structure available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOCSI] = ENOCSI;
- gf_errno_to_error_array[ENOCSI] = GF_ERROR_CODE_NOCSI;
-
-/* EL2HLT 44 / * Level 2 halted */
- gf_error_to_errno_array[GF_ERROR_CODE_L2HLT] = EL2HLT;
- gf_errno_to_error_array[EL2HLT] = GF_ERROR_CODE_L2HLT;
-
-/* EDEADLK 45 / * Deadlock condition. */
- gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
- gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
-
-/* ENOLCK 46 / * No record locks available. */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
- gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
-
-/* ECANCELED 47 / * Operation canceled */
- gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
- gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
-
-/* ENOTSUP 48 / * Operation not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTSUPP] = ENOTSUP;
- gf_errno_to_error_array[ENOTSUP] = GF_ERROR_CODE_NOTSUPP;
-
-/* Filesystem Quotas */
-/* EDQUOT 49 / * Disc quota exceeded */
- gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
- gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
-
-/* Convergent Error Returns */
-/* EBADE 50 / * invalid exchange */
- gf_error_to_errno_array[GF_ERROR_CODE_BADE] = EBADE;
- gf_errno_to_error_array[EBADE] = GF_ERROR_CODE_BADE;
-/* EBADR 51 / * invalid request descriptor */
- gf_error_to_errno_array[GF_ERROR_CODE_BADR] = EBADR;
- gf_errno_to_error_array[EBADR] = GF_ERROR_CODE_BADR;
-/* EXFULL 52 / * exchange full */
- gf_error_to_errno_array[GF_ERROR_CODE_XFULL] = EXFULL;
- gf_errno_to_error_array[EXFULL] = GF_ERROR_CODE_XFULL;
-/* ENOANO 53 / * no anode */
- gf_error_to_errno_array[GF_ERROR_CODE_NOANO] = ENOANO;
- gf_errno_to_error_array[ENOANO] = GF_ERROR_CODE_NOANO;
-/* EBADRQC 54 / * invalid request code */
- gf_error_to_errno_array[GF_ERROR_CODE_BADRQC] = EBADRQC;
- gf_errno_to_error_array[EBADRQC] = GF_ERROR_CODE_BADRQC;
-/* EBADSLT 55 / * invalid slot */
- gf_error_to_errno_array[GF_ERROR_CODE_BADSLT] = EBADSLT;
- gf_errno_to_error_array[EBADSLT] = GF_ERROR_CODE_BADSLT;
-/* EDEADLOCK 56 / * file locking deadlock error */
-/* This is same as EDEADLK on linux */
- gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLOCK;
- gf_errno_to_error_array[EDEADLOCK] = GF_ERROR_CODE_DEADLK;
-
-/* EBFONT 57 / * bad font file fmt */
- gf_error_to_errno_array[GF_ERROR_CODE_BFONT] = EBFONT;
- gf_errno_to_error_array[EBFONT] = GF_ERROR_CODE_BFONT;
-
-/* Interprocess Robust Locks */
-/* EOWNERDEAD 58 / * process died with the lock */
- gf_error_to_errno_array[GF_ERROR_CODE_OWNERDEAD] = EOWNERDEAD;
- gf_errno_to_error_array[EOWNERDEAD] = GF_ERROR_CODE_OWNERDEAD;
-/* ENOTRECOVERABLE 59 / * lock is not recoverable */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTRECOVERABLE] = ENOTRECOVERABLE;
- gf_errno_to_error_array[ENOTRECOVERABLE] = GF_ERROR_CODE_NOTRECOVERABLE;
-
-/* stream problems */
-/* ENOSTR 60 / * Device not a stream */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSTR] = ENOSTR;
- gf_errno_to_error_array[ENOSTR] = GF_ERROR_CODE_NOSTR;
-/* ENODATA 61 / * no data (for no delay io) */
- gf_error_to_errno_array[GF_ERROR_CODE_NODATA] = ENODATA;
- gf_errno_to_error_array[ENODATA] = GF_ERROR_CODE_NODATA;
-/* ETIME 62 / * timer expired */
- gf_error_to_errno_array[GF_ERROR_CODE_TIME] = ETIME;
- gf_errno_to_error_array[ETIME] = GF_ERROR_CODE_TIME;
-/* ENOSR 63 / * out of streams resources */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSR] = ENOSR;
- gf_errno_to_error_array[ENOSR] = GF_ERROR_CODE_NOSR;
-
-/* ENONET 64 / * Machine is not on the network */
- gf_error_to_errno_array[GF_ERROR_CODE_NONET] = ENONET;
- gf_errno_to_error_array[ENONET] = GF_ERROR_CODE_NONET;
-/* ENOPKG 65 / * Package not installed */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPKG] = ENOPKG;
- gf_errno_to_error_array[ENOPKG] = GF_ERROR_CODE_NOPKG;
-/* EREMOTE 66 / * The object is remote */
- gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
- gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
-/* ENOLINK 67 / * the link has been severed */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
- gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
-/* EADV 68 / * advertise error */
- gf_error_to_errno_array[GF_ERROR_CODE_ADV] = EADV;
- gf_errno_to_error_array[EADV] = GF_ERROR_CODE_ADV;
-/* ESRMNT 69 / * srmount error */
- gf_error_to_errno_array[GF_ERROR_CODE_SRMNT] = ESRMNT;
- gf_errno_to_error_array[ESRMNT] = GF_ERROR_CODE_SRMNT;
-
-/* ECOMM 70 / * Communication error on send */
- gf_error_to_errno_array[GF_ERROR_CODE_COMM] = ECOMM;
- gf_errno_to_error_array[ECOMM] = GF_ERROR_CODE_COMM;
-/* EPROTO 71 / * Protocol error */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
- gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
-
-/* Interprocess Robust Locks */
-/* ELOCKUNMAPPED 72 / * locked lock was unmapped */
- gf_error_to_errno_array[GF_ERROR_CODE_LOCKUNMAPPED] = ELOCKUNMAPPED;
- gf_errno_to_error_array[ELOCKUNMAPPED] = GF_ERROR_CODE_LOCKUNMAPPED;
-
-/* ENOTACTIVE 73 / * Facility is not active */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTACTIVE] = ENOTACTIVE;
- gf_errno_to_error_array[ENOTACTIVE] = GF_ERROR_CODE_NOTACTIVE;
-/* EMULTIHOP 74 / * multihop attempted */
- gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
- gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
-/* EBADMSG 77 / * trying to read unreadable message */
- gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
- gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
-/* ENAMETOOLONG 78 / * path name is too long */
- gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
- gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
-/* EOVERFLOW 79 / * value too large to be stored in data type */
- gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
- gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
-/* ENOTUNIQ 80 / * given log. name not unique */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTUNIQ] = ENOTUNIQ;
- gf_errno_to_error_array[ENOTUNIQ] = GF_ERROR_CODE_NOTUNIQ;
-/* EBADFD 81 / * f.d. invalid for this operation */
- gf_error_to_errno_array[GF_ERROR_CODE_BADFD] = EBADFD;
- gf_errno_to_error_array[EBADFD] = GF_ERROR_CODE_BADFD;
-/* EREMCHG 82 / * Remote address changed */
- gf_error_to_errno_array[GF_ERROR_CODE_REMCHG] = EREMCHG;
- gf_errno_to_error_array[EREMCHG] = GF_ERROR_CODE_REMCHG;
-
-/* shared library problems */
-/* ELIBACC 83 / * Can't access a needed shared lib. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBACC] = ELIBACC;
- gf_errno_to_error_array[ELIBACC] = GF_ERROR_CODE_LIBACC;
-/* ELIBBAD 84 / * Accessing a corrupted shared lib. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBBAD] = ELIBBAD;
- gf_errno_to_error_array[ELIBBAD] = GF_ERROR_CODE_LIBBAD;
-/* ELIBSCN 85 / * .lib section in a.out corrupted. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBSCN] = ELIBSCN;
- gf_errno_to_error_array[ELIBSCN] = GF_ERROR_CODE_LIBSCN;
-/* ELIBMAX 86 / * Attempting to link in too many libs. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBMAX] = ELIBMAX;
- gf_errno_to_error_array[ELIBMAX] = GF_ERROR_CODE_LIBMAX;
-/* ELIBEXEC 87 / * Attempting to exec a shared library. */
- gf_error_to_errno_array[GF_ERROR_CODE_LIBEXEC] = ELIBEXEC;
- gf_errno_to_error_array[ELIBEXEC] = GF_ERROR_CODE_LIBEXEC;
-/* EILSEQ 88 / * Illegal byte sequence. */
- gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
- gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
-/* ENOSYS 89 / * Unsupported file system operation */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
- gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
-/* ELOOP 90 / * Symbolic link loop */
- gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
- gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
-/* ERESTART 91 / * Restartable system call */
- gf_error_to_errno_array[GF_ERROR_CODE_RESTART] = ERESTART;
- gf_errno_to_error_array[ERESTART] = GF_ERROR_CODE_RESTART;
-/* ESTRPIPE 92 / * if pipe/FIFO, don't sleep in stream head */
- gf_error_to_errno_array[GF_ERROR_CODE_STRPIPE] = ESTRPIPE;
- gf_errno_to_error_array[ESTRPIPE] = GF_ERROR_CODE_STRPIPE;
-/* ENOTEMPTY 93 / * directory not empty */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
- gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
-/* EUSERS 94 / * Too many users (for UFS) */
- gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
- gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
-
-/* BSD Networking Software */
- /* argument errors */
-/* ENOTSOCK 95 / * Socket operation on non-socket */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
- gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
-/* EDESTADDRREQ 96 / * Destination address required */
- gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
- gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
-/* EMSGSIZE 97 / * Message too long */
- gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
- gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
-/* EPROTOTYPE 98 / * Protocol wrong type for socket */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
- gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
-/* ENOPROTOOPT 99 / * Protocol not available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
- gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
-/* EPROTONOSUPPORT 120 / * Protocol not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
- gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
-/* ESOCKTNOSUPPORT 121 / * Socket type not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
- gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
-
-/* EOPNOTSUPP 122 / * Operation not supported on socket */
- gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
- gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
-/* EPFNOSUPPORT 123 / * Protocol family not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
- gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
-/* EAFNOSUPPORT 124 / * Address family not supported by */
- /* protocol family */
- gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
- gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
-/* EADDRINUSE 125 / * Address already in use */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
- gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
-/* EADDRNOTAVAIL 126 / * Can't assign requested address */
- /* operational errors */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
- gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
-/* ENETDOWN 127 / * Network is down */
- gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
- gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
-/* ENETUNREACH 128 / * Network is unreachable */
- gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
- gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
-/* ENETRESET 129 / * Network dropped connection because */
- /* of reset */
- gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
- gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
-/* ECONNABORTED 130 / * Software caused connection abort */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
- gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
-/* ECONNRESET 131 / * Connection reset by peer */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
- gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
-/* ENOBUFS 132 / * No buffer space available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
- gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
-/* EISCONN 133 / * Socket is already connected */
- gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
- gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
-/* ENOTCONN 134 / * Socket is not connected */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
- gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
-/* XENIX has 135 - 142 */
-/* ESHUTDOWN 143 / * Can't send after socket shutdown */
- gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
- gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
-/* ETOOMANYREFS 144 / * Too many references: can't splice */
- gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
- gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
-/* ETIMEDOUT 145 / * Connection timed out */
- gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
- gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
-
-/* ECONNREFUSED 146 / * Connection refused */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
- gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
-/* EHOSTDOWN 147 / * Host is down */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
- gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
-/* EHOSTUNREACH 148 / * No route to host */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
- gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
-/* EALREADY 149 / * operation already in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
- gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
-/* EINPROGRESS 150 / * operation now in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
- gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
-
-/* SUN Network File System */
-/* ESTALE 151 / * Stale NFS file handle */
- gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
- gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
-
- return ;
+ /* ENOMSG 35 / * No message of desired type */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
+ gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
+
+ /* EIDRM 36 / * Identifier removed */
+ gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
+ gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
+
+ /* ECHRNG 37 / * Channel number out of range */
+ gf_error_to_errno_array[GF_ERROR_CODE_CHRNG] = ECHRNG;
+ gf_errno_to_error_array[ECHRNG] = GF_ERROR_CODE_CHRNG;
+
+ /* EL2NSYNC 38 / * Level 2 not synchronized */
+ gf_error_to_errno_array[GF_ERROR_CODE_L2NSYNC] = EL2NSYNC;
+ gf_errno_to_error_array[EL2NSYNC] = GF_ERROR_CODE_L2NSYNC;
+
+ /* EL3HLT 39 / * Level 3 halted */
+ gf_error_to_errno_array[GF_ERROR_CODE_L3HLT] = EL3HLT;
+ gf_errno_to_error_array[EL3HLT] = GF_ERROR_CODE_L3HLT;
+
+ /* EL3RST 40 / * Level 3 reset */
+ gf_error_to_errno_array[GF_ERROR_CODE_L3RST] = EL3RST;
+ gf_errno_to_error_array[EL3RST] = GF_ERROR_CODE_L3RST;
+
+ /* ELNRNG 41 / * Link number out of range */
+ gf_error_to_errno_array[GF_ERROR_CODE_LNRNG] = ELNRNG;
+ gf_errno_to_error_array[ELNRNG] = GF_ERROR_CODE_LNRNG;
+
+ /* EUNATCH 42 / * Protocol driver not attached */
+ gf_error_to_errno_array[GF_ERROR_CODE_UNATCH] = EUNATCH;
+ gf_errno_to_error_array[EUNATCH] = GF_ERROR_CODE_UNATCH;
+
+ /* ENOCSI 43 / * No CSI structure available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOCSI] = ENOCSI;
+ gf_errno_to_error_array[ENOCSI] = GF_ERROR_CODE_NOCSI;
+
+ /* EL2HLT 44 / * Level 2 halted */
+ gf_error_to_errno_array[GF_ERROR_CODE_L2HLT] = EL2HLT;
+ gf_errno_to_error_array[EL2HLT] = GF_ERROR_CODE_L2HLT;
+
+ /* EDEADLK 45 / * Deadlock condition. */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
+ gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
+
+ /* ENOLCK 46 / * No record locks available. */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
+ gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
+
+ /* ECANCELED 47 / * Operation canceled */
+ gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
+ gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
+
+ /* ENOTSUP 48 / * Operation not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTSUPP] = ENOTSUP;
+ gf_errno_to_error_array[ENOTSUP] = GF_ERROR_CODE_NOTSUPP;
+
+ /* Filesystem Quotas */
+ /* EDQUOT 49 / * Disc quota exceeded */
+ gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
+ gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
+
+ /* Convergent Error Returns */
+ /* EBADE 50 / * invalid exchange */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADE] = EBADE;
+ gf_errno_to_error_array[EBADE] = GF_ERROR_CODE_BADE;
+ /* EBADR 51 / * invalid request descriptor */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADR] = EBADR;
+ gf_errno_to_error_array[EBADR] = GF_ERROR_CODE_BADR;
+ /* EXFULL 52 / * exchange full */
+ gf_error_to_errno_array[GF_ERROR_CODE_XFULL] = EXFULL;
+ gf_errno_to_error_array[EXFULL] = GF_ERROR_CODE_XFULL;
+ /* ENOANO 53 / * no anode */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOANO] = ENOANO;
+ gf_errno_to_error_array[ENOANO] = GF_ERROR_CODE_NOANO;
+ /* EBADRQC 54 / * invalid request code */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADRQC] = EBADRQC;
+ gf_errno_to_error_array[EBADRQC] = GF_ERROR_CODE_BADRQC;
+ /* EBADSLT 55 / * invalid slot */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADSLT] = EBADSLT;
+ gf_errno_to_error_array[EBADSLT] = GF_ERROR_CODE_BADSLT;
+ /* EDEADLOCK 56 / * file locking deadlock error */
+ /* This is same as EDEADLK on linux */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLOCK;
+ gf_errno_to_error_array[EDEADLOCK] = GF_ERROR_CODE_DEADLK;
+
+ /* EBFONT 57 / * bad font file fmt */
+ gf_error_to_errno_array[GF_ERROR_CODE_BFONT] = EBFONT;
+ gf_errno_to_error_array[EBFONT] = GF_ERROR_CODE_BFONT;
+
+ /* Interprocess Robust Locks */
+ /* EOWNERDEAD 58 / * process died with the lock */
+ gf_error_to_errno_array[GF_ERROR_CODE_OWNERDEAD] = EOWNERDEAD;
+ gf_errno_to_error_array[EOWNERDEAD] = GF_ERROR_CODE_OWNERDEAD;
+ /* ENOTRECOVERABLE 59 / * lock is not recoverable */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTRECOVERABLE] = ENOTRECOVERABLE;
+ gf_errno_to_error_array[ENOTRECOVERABLE] = GF_ERROR_CODE_NOTRECOVERABLE;
+
+ /* stream problems */
+ /* ENOSTR 60 / * Device not a stream */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSTR] = ENOSTR;
+ gf_errno_to_error_array[ENOSTR] = GF_ERROR_CODE_NOSTR;
+ /* ENODATA 61 / * no data (for no delay io) */
+ gf_error_to_errno_array[GF_ERROR_CODE_NODATA] = ENODATA;
+ gf_errno_to_error_array[ENODATA] = GF_ERROR_CODE_NODATA;
+ /* ETIME 62 / * timer expired */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIME] = ETIME;
+ gf_errno_to_error_array[ETIME] = GF_ERROR_CODE_TIME;
+ /* ENOSR 63 / * out of streams resources */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSR] = ENOSR;
+ gf_errno_to_error_array[ENOSR] = GF_ERROR_CODE_NOSR;
+
+ /* ENONET 64 / * Machine is not on the network */
+ gf_error_to_errno_array[GF_ERROR_CODE_NONET] = ENONET;
+ gf_errno_to_error_array[ENONET] = GF_ERROR_CODE_NONET;
+ /* ENOPKG 65 / * Package not installed */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPKG] = ENOPKG;
+ gf_errno_to_error_array[ENOPKG] = GF_ERROR_CODE_NOPKG;
+ /* EREMOTE 66 / * The object is remote */
+ gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
+ gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
+ /* ENOLINK 67 / * the link has been severed */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
+ gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
+ /* EADV 68 / * advertise error */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADV] = EADV;
+ gf_errno_to_error_array[EADV] = GF_ERROR_CODE_ADV;
+ /* ESRMNT 69 / * srmount error */
+ gf_error_to_errno_array[GF_ERROR_CODE_SRMNT] = ESRMNT;
+ gf_errno_to_error_array[ESRMNT] = GF_ERROR_CODE_SRMNT;
+
+ /* ECOMM 70 / * Communication error on send */
+ gf_error_to_errno_array[GF_ERROR_CODE_COMM] = ECOMM;
+ gf_errno_to_error_array[ECOMM] = GF_ERROR_CODE_COMM;
+ /* EPROTO 71 / * Protocol error */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
+ gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
+
+ /* Interprocess Robust Locks */
+ /* ELOCKUNMAPPED 72 / * locked lock was unmapped */
+ gf_error_to_errno_array[GF_ERROR_CODE_LOCKUNMAPPED] = ELOCKUNMAPPED;
+ gf_errno_to_error_array[ELOCKUNMAPPED] = GF_ERROR_CODE_LOCKUNMAPPED;
+
+ /* ENOTACTIVE 73 / * Facility is not active */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTACTIVE] = ENOTACTIVE;
+ gf_errno_to_error_array[ENOTACTIVE] = GF_ERROR_CODE_NOTACTIVE;
+ /* EMULTIHOP 74 / * multihop attempted */
+ gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
+ gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
+ /* EBADMSG 77 / * trying to read unreadable message */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
+ gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
+ /* ENAMETOOLONG 78 / * path name is too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
+ gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
+ /* EOVERFLOW 79 / * value too large to be stored in data type */
+ gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
+ gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
+ /* ENOTUNIQ 80 / * given log. name not unique */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTUNIQ] = ENOTUNIQ;
+ gf_errno_to_error_array[ENOTUNIQ] = GF_ERROR_CODE_NOTUNIQ;
+ /* EBADFD 81 / * f.d. invalid for this operation */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADFD] = EBADFD;
+ gf_errno_to_error_array[EBADFD] = GF_ERROR_CODE_BADFD;
+ /* EREMCHG 82 / * Remote address changed */
+ gf_error_to_errno_array[GF_ERROR_CODE_REMCHG] = EREMCHG;
+ gf_errno_to_error_array[EREMCHG] = GF_ERROR_CODE_REMCHG;
+
+ /* shared library problems */
+ /* ELIBACC 83 / * Can't access a needed shared lib. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBACC] = ELIBACC;
+ gf_errno_to_error_array[ELIBACC] = GF_ERROR_CODE_LIBACC;
+ /* ELIBBAD 84 / * Accessing a corrupted shared lib. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBBAD] = ELIBBAD;
+ gf_errno_to_error_array[ELIBBAD] = GF_ERROR_CODE_LIBBAD;
+ /* ELIBSCN 85 / * .lib section in a.out corrupted. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBSCN] = ELIBSCN;
+ gf_errno_to_error_array[ELIBSCN] = GF_ERROR_CODE_LIBSCN;
+ /* ELIBMAX 86 / * Attempting to link in too many libs. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBMAX] = ELIBMAX;
+ gf_errno_to_error_array[ELIBMAX] = GF_ERROR_CODE_LIBMAX;
+ /* ELIBEXEC 87 / * Attempting to exec a shared library. */
+ gf_error_to_errno_array[GF_ERROR_CODE_LIBEXEC] = ELIBEXEC;
+ gf_errno_to_error_array[ELIBEXEC] = GF_ERROR_CODE_LIBEXEC;
+ /* EILSEQ 88 / * Illegal byte sequence. */
+ gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
+ gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
+ /* ENOSYS 89 / * Unsupported file system operation */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
+ gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
+ /* ELOOP 90 / * Symbolic link loop */
+ gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
+ gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
+ /* ERESTART 91 / * Restartable system call */
+ gf_error_to_errno_array[GF_ERROR_CODE_RESTART] = ERESTART;
+ gf_errno_to_error_array[ERESTART] = GF_ERROR_CODE_RESTART;
+ /* ESTRPIPE 92 / * if pipe/FIFO, don't sleep in stream head */
+ gf_error_to_errno_array[GF_ERROR_CODE_STRPIPE] = ESTRPIPE;
+ gf_errno_to_error_array[ESTRPIPE] = GF_ERROR_CODE_STRPIPE;
+ /* ENOTEMPTY 93 / * directory not empty */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
+ gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
+ /* EUSERS 94 / * Too many users (for UFS) */
+ gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
+ gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
+
+ /* BSD Networking Software */
+ /* argument errors */
+ /* ENOTSOCK 95 / * Socket operation on non-socket */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
+ gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
+ /* EDESTADDRREQ 96 / * Destination address required */
+ gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
+ gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
+ /* EMSGSIZE 97 / * Message too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
+ gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
+ /* EPROTOTYPE 98 / * Protocol wrong type for socket */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
+ gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
+ /* ENOPROTOOPT 99 / * Protocol not available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
+ gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
+ /* EPROTONOSUPPORT 120 / * Protocol not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
+ gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
+ /* ESOCKTNOSUPPORT 121 / * Socket type not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
+ gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
+
+ /* EOPNOTSUPP 122 / * Operation not supported on socket */
+ gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
+ gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
+ /* EPFNOSUPPORT 123 / * Protocol family not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
+ gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
+ /* EAFNOSUPPORT 124 / * Address family not supported by */
+ /* protocol family */
+ gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
+ gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
+ /* EADDRINUSE 125 / * Address already in use */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
+ gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
+ /* EADDRNOTAVAIL 126 / * Can't assign requested address */
+ /* operational errors */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
+ gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
+ /* ENETDOWN 127 / * Network is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
+ gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
+ /* ENETUNREACH 128 / * Network is unreachable */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
+ gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
+ /* ENETRESET 129 / * Network dropped connection because */
+ /* of reset */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
+ gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
+ /* ECONNABORTED 130 / * Software caused connection abort */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
+ gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
+ /* ECONNRESET 131 / * Connection reset by peer */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
+ gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
+ /* ENOBUFS 132 / * No buffer space available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
+ gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
+ /* EISCONN 133 / * Socket is already connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
+ gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
+ /* ENOTCONN 134 / * Socket is not connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
+ gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
+ /* XENIX has 135 - 142 */
+ /* ESHUTDOWN 143 / * Can't send after socket shutdown */
+ gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
+ gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
+ /* ETOOMANYREFS 144 / * Too many references: can't splice */
+ gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
+ gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
+ /* ETIMEDOUT 145 / * Connection timed out */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
+ gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
+
+ /* ECONNREFUSED 146 / * Connection refused */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
+ gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
+ /* EHOSTDOWN 147 / * Host is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
+ gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
+ /* EHOSTUNREACH 148 / * No route to host */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
+ gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
+ /* EALREADY 149 / * operation already in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
+ gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
+ /* EINPROGRESS 150 / * operation now in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
+ gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
+
+ /* SUN Network File System */
+ /* ESTALE 151 / * Stale NFS file handle */
+ gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
+ gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
+
+ return;
}
#endif /* GF_SOLARIS_HOST_OS */
#ifdef GF_DARWIN_HOST_OS
static void
-init_compat_errno_arrays ()
+init_compat_errno_arrays()
{
- /* EDEADLK 11 / * Resource deadlock would occur */
- gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
- gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
-
- /* EAGAIN 35 / * Try Again */
- gf_error_to_errno_array[GF_ERROR_CODE_AGAIN] = EAGAIN;
- gf_errno_to_error_array[EAGAIN] = GF_ERROR_CODE_AGAIN;
-
- /* EINPROGRESS 36 / * Operation now in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
- gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
-
- /* EALREADY 37 / * Operation already in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
- gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
-
- /* ENOTSOCK 38 / * Socket operation on non-socket */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
- gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
-
- /* EDESTADDRREQ 39 / * Destination address required */
- gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
- gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
-
- /* EMSGSIZE 40 / * Message too long */
- gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
- gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
-
- /* EPROTOTYPE 41 / * Protocol wrong type for socket */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
- gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
-
- /* ENOPROTOOPT 42 / * Protocol not available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
- gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
-
- /* EPROTONOSUPPORT 43 / * Protocol not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
- gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
-
- /* ESOCKTNOSUPPORT 44 / * Socket type not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
- gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
-
- /* EOPNOTSUPP 45 / * Operation not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
- gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
-
- /* EPFNOSUPPORT 46 / * Protocol family not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
- gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
-
- /* EAFNOSUPPORT 47 / * Address family not supported by protocol family */
- gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
- gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
-
- /* EADDRINUSE 48 / * Address already in use */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
- gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
-
- /* EADDRNOTAVAIL 49 / * Can't assign requested address */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
- gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
-
- /* ENETDOWN 50 / * Network is down */
- gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
- gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
-
- /* ENETUNREACH 51 / * Network is unreachable */
- gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
- gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
-
- /* ENETRESET 52 / * Network dropped connection on reset */
- gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
- gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
-
- /* ECONNABORTED 53 / * Software caused connection abort */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
- gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
-
- /* ECONNRESET 54 / * Connection reset by peer */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
- gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
-
- /* ENOBUFS 55 / * No buffer space available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
- gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
-
- /* EISCONN 56 / * Socket is already connected */
- gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
- gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
-
- /* ENOTCONN 57 / * Socket is not connected */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
- gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
-
- /* ESHUTDOWN 58 / * Can't send after socket shutdown */
- gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
- gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
-
- /* ETOOMANYREFS 59 / * Too many references: can't splice */
- gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
- gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
-
- /* ETIMEDOUT 60 / * Operation timed out */
- gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
- gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
-
- /* ECONNREFUSED 61 / * Connection refused */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
- gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
-
- /* ELOOP 62 / * Too many levels of symbolic links */
- gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
- gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
-
- /* ENAMETOOLONG 63 / * File name too long */
- gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
- gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
-
- /* EHOSTDOWN 64 / * Host is down */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
- gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
-
- /* EHOSTUNREACH 65 / * No route to host */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
- gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
-
- /* ENOTEMPTY 66 / * Directory not empty */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
- gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
-
- /* EPROCLIM 67 / * Too many processes */
- gf_error_to_errno_array[GF_ERROR_CODE_PROCLIM] = EPROCLIM;
- gf_errno_to_error_array[EPROCLIM] = GF_ERROR_CODE_PROCLIM;
-
- /* EUSERS 68 / * Too many users */
- gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
- gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
-
- /* EDQUOT 69 / * Disc quota exceeded */
- gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
- gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
-
- /* ESTALE 70 / * Stale NFS file handle */
- gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
- gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
-
- /* EREMOTE 71 / * Too many levels of remote in path */
- gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
- gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
-
- /* EBADRPC 72 / * RPC struct is bad */
- gf_error_to_errno_array[GF_ERROR_CODE_BADRPC] = EBADRPC;
- gf_errno_to_error_array[EBADRPC] = GF_ERROR_CODE_BADRPC;
-
- /* ERPCMISMATCH 73 / * RPC version wrong */
- gf_error_to_errno_array[GF_ERROR_CODE_RPCMISMATCH] = ERPCMISMATCH;
- gf_errno_to_error_array[ERPCMISMATCH] = GF_ERROR_CODE_RPCMISMATCH;
-
- /* EPROGUNAVAIL 74 / * RPC prog. not avail */
- gf_error_to_errno_array[GF_ERROR_CODE_PROGUNAVAIL] = EPROGUNAVAIL;
- gf_errno_to_error_array[EPROGUNAVAIL] = GF_ERROR_CODE_PROGUNAVAIL;
-
- /* EPROGMISMATCH 75 / * Program version wrong */
- gf_error_to_errno_array[GF_ERROR_CODE_PROGMISMATCH] = EPROGMISMATCH;
- gf_errno_to_error_array[EPROGMISMATCH] = GF_ERROR_CODE_PROGMISMATCH;
-
- /* EPROCUNAVAIL 76 / * Bad procedure for program */
- gf_error_to_errno_array[GF_ERROR_CODE_PROCUNAVAIL] = EPROCUNAVAIL;
- gf_errno_to_error_array[EPROCUNAVAIL] = GF_ERROR_CODE_PROCUNAVAIL;
-
- /* ENOLCK 77 / * No locks available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
- gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
-
- /* ENOSYS 78 / * Function not implemented */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
- gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
-
- /* EFTYPE 79 / * Inappropriate file type or format */
- gf_error_to_errno_array[GF_ERROR_CODE_FTYPE] = EFTYPE;
- gf_errno_to_error_array[EFTYPE] = GF_ERROR_CODE_FTYPE;
-
- /* EAUTH 80 / * Authentication error */
- gf_error_to_errno_array[GF_ERROR_CODE_AUTH] = EAUTH;
- gf_errno_to_error_array[EAUTH] = GF_ERROR_CODE_AUTH;
-
- /* ENEEDAUTH 81 / * Need authenticator */
- gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
- gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
-/* Intelligent device errors */
-/* EPWROFF 82 / * Device power is off */
- gf_error_to_errno_array[GF_ERROR_CODE_PWROFF] = EPWROFF;
- gf_errno_to_error_array[EPWROFF] = GF_ERROR_CODE_PWROFF;
-/* EDEVERR 83 / * Device error, e.g. paper out */
- gf_error_to_errno_array[GF_ERROR_CODE_DEVERR] = EDEVERR;
- gf_errno_to_error_array[EDEVERR] = GF_ERROR_CODE_DEVERR;
-
- /* EOVERFLOW 84 / * Value too large to be stored in data type */
- gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
- gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
-
-/* Program loading errors */
-/* EBADEXEC 85 / * Bad executable */
- gf_error_to_errno_array[GF_ERROR_CODE_BADEXEC] = EBADEXEC;
- gf_errno_to_error_array[EBADEXEC] = GF_ERROR_CODE_BADEXEC;
-
-/* EBADARCH 86 / * Bad CPU type in executable */
- gf_error_to_errno_array[GF_ERROR_CODE_BADARCH] = EBADARCH;
- gf_errno_to_error_array[EBADARCH] = GF_ERROR_CODE_BADARCH;
-
-/* ESHLIBVERS 87 / * Shared library version mismatch */
- gf_error_to_errno_array[GF_ERROR_CODE_SHLIBVERS] = ESHLIBVERS;
- gf_errno_to_error_array[ESHLIBVERS] = GF_ERROR_CODE_SHLIBVERS;
-
-/* EBADMACHO 88 / * Malformed Macho file */
- gf_error_to_errno_array[GF_ERROR_CODE_BADMACHO] = EBADMACHO;
- gf_errno_to_error_array[EBADMACHO] = GF_ERROR_CODE_BADMACHO;
+ /* EDEADLK 11 / * Resource deadlock would occur */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
+ gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
+
+ /* EAGAIN 35 / * Try Again */
+ gf_error_to_errno_array[GF_ERROR_CODE_AGAIN] = EAGAIN;
+ gf_errno_to_error_array[EAGAIN] = GF_ERROR_CODE_AGAIN;
+
+ /* EINPROGRESS 36 / * Operation now in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
+ gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
+
+ /* EALREADY 37 / * Operation already in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
+ gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
+
+ /* ENOTSOCK 38 / * Socket operation on non-socket
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
+ gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
+
+ /* EDESTADDRREQ 39 / * Destination address required */
+ gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
+ gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
+
+ /* EMSGSIZE 40 / * Message too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
+ gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
+
+ /* EPROTOTYPE 41 / * Protocol wrong type for socket
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
+ gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
+
+ /* ENOPROTOOPT 42 / * Protocol not available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
+ gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
+
+ /* EPROTONOSUPPORT 43 / * Protocol not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
+ gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
+
+ /* ESOCKTNOSUPPORT 44 / * Socket type not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
+ gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
+
+ /* EOPNOTSUPP 45 / * Operation not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
+ gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
+
+ /* EPFNOSUPPORT 46 / * Protocol family not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
+ gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
+
+ /* EAFNOSUPPORT 47 / * Address family not supported by
+ * protocol family */
+ gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
+ gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
+
+ /* EADDRINUSE 48 / * Address already in use */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
+ gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
+
+ /* EADDRNOTAVAIL 49 / * Can't assign requested address
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
+ gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
+
+ /* ENETDOWN 50 / * Network is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
+ gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
+
+ /* ENETUNREACH 51 / * Network is unreachable */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
+ gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
+
+ /* ENETRESET 52 / * Network dropped connection on
+ * reset */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
+ gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
+
+ /* ECONNABORTED 53 / * Software caused connection abort
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
+ gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
+
+ /* ECONNRESET 54 / * Connection reset by peer */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
+ gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
+
+ /* ENOBUFS 55 / * No buffer space available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
+ gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
+
+ /* EISCONN 56 / * Socket is already connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
+ gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
+
+ /* ENOTCONN 57 / * Socket is not connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
+ gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
+
+ /* ESHUTDOWN 58 / * Can't send after socket shutdown
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
+ gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
+
+ /* ETOOMANYREFS 59 / * Too many references: can't
+ * splice */
+ gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
+ gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
+
+ /* ETIMEDOUT 60 / * Operation timed out */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
+ gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
+
+ /* ECONNREFUSED 61 / * Connection refused */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
+ gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
+
+ /* ELOOP 62 / * Too many levels of symbolic
+ * links */
+ gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
+ gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
+
+ /* ENAMETOOLONG 63 / * File name too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
+ gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
+
+ /* EHOSTDOWN 64 / * Host is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
+ gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
+
+ /* EHOSTUNREACH 65 / * No route to host */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
+ gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
+
+ /* ENOTEMPTY 66 / * Directory not empty */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
+ gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
+
+ /* EPROCLIM 67 / * Too many processes */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROCLIM] = EPROCLIM;
+ gf_errno_to_error_array[EPROCLIM] = GF_ERROR_CODE_PROCLIM;
+
+ /* EUSERS 68 / * Too many users */
+ gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
+ gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
+
+ /* EDQUOT 69 / * Disc quota exceeded */
+ gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
+ gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
+
+ /* ESTALE 70 / * Stale NFS file handle */
+ gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
+ gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
+
+ /* EREMOTE 71 / * Too many levels of remote in
+ * path */
+ gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
+ gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
+
+ /* EBADRPC 72 / * RPC struct is bad */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADRPC] = EBADRPC;
+ gf_errno_to_error_array[EBADRPC] = GF_ERROR_CODE_BADRPC;
+
+ /* ERPCMISMATCH 73 / * RPC version wrong */
+ gf_error_to_errno_array[GF_ERROR_CODE_RPCMISMATCH] = ERPCMISMATCH;
+ gf_errno_to_error_array[ERPCMISMATCH] = GF_ERROR_CODE_RPCMISMATCH;
+
+ /* EPROGUNAVAIL 74 / * RPC prog. not avail */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROGUNAVAIL] = EPROGUNAVAIL;
+ gf_errno_to_error_array[EPROGUNAVAIL] = GF_ERROR_CODE_PROGUNAVAIL;
+
+ /* EPROGMISMATCH 75 / * Program version wrong */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROGMISMATCH] = EPROGMISMATCH;
+ gf_errno_to_error_array[EPROGMISMATCH] = GF_ERROR_CODE_PROGMISMATCH;
+
+ /* EPROCUNAVAIL 76 / * Bad procedure for program */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROCUNAVAIL] = EPROCUNAVAIL;
+ gf_errno_to_error_array[EPROCUNAVAIL] = GF_ERROR_CODE_PROCUNAVAIL;
+
+ /* ENOLCK 77 / * No locks available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
+ gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
+
+ /* ENOSYS 78 / * Function not implemented */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
+ gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
+
+ /* EFTYPE 79 / * Inappropriate file type or
+ * format */
+ gf_error_to_errno_array[GF_ERROR_CODE_FTYPE] = EFTYPE;
+ gf_errno_to_error_array[EFTYPE] = GF_ERROR_CODE_FTYPE;
+
+ /* EAUTH 80 / * Authentication error */
+ gf_error_to_errno_array[GF_ERROR_CODE_AUTH] = EAUTH;
+ gf_errno_to_error_array[EAUTH] = GF_ERROR_CODE_AUTH;
+
+ /* ENEEDAUTH 81 / * Need authenticator */
+ gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
+ gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
+ /* Intelligent device errors */
+ /* EPWROFF 82 / * Device power is off */
+ gf_error_to_errno_array[GF_ERROR_CODE_PWROFF] = EPWROFF;
+ gf_errno_to_error_array[EPWROFF] = GF_ERROR_CODE_PWROFF;
+ /* EDEVERR 83 / * Device error, e.g. paper out */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEVERR] = EDEVERR;
+ gf_errno_to_error_array[EDEVERR] = GF_ERROR_CODE_DEVERR;
+
+ /* EOVERFLOW 84 / * Value too large to be stored in
+ * data type */
+ gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
+ gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
+
+ /* Program loading errors */
+ /* EBADEXEC 85 / * Bad executable */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADEXEC] = EBADEXEC;
+ gf_errno_to_error_array[EBADEXEC] = GF_ERROR_CODE_BADEXEC;
+
+ /* EBADARCH 86 / * Bad CPU type in executable */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADARCH] = EBADARCH;
+ gf_errno_to_error_array[EBADARCH] = GF_ERROR_CODE_BADARCH;
+
+ /* ESHLIBVERS 87 / * Shared library version mismatch */
+ gf_error_to_errno_array[GF_ERROR_CODE_SHLIBVERS] = ESHLIBVERS;
+ gf_errno_to_error_array[ESHLIBVERS] = GF_ERROR_CODE_SHLIBVERS;
+
+ /* EBADMACHO 88 / * Malformed Macho file */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADMACHO] = EBADMACHO;
+ gf_errno_to_error_array[EBADMACHO] = GF_ERROR_CODE_BADMACHO;
#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;
+ /* 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
- /* ECANCELED 89 / * Operation canceled */
- gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
- gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
-
- /* EIDRM 90 / * Identifier removed */
- gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
- gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
- /* ENOMSG 91 / * No message of desired type */
- gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
- gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
-
- /* EILSEQ 92 / * Illegal byte sequence */
- gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
- gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
-
- /* ENOATTR 93 / * Attribute not found */
- gf_error_to_errno_array[GF_ERROR_CODE_NOATTR] = ENOATTR;
- gf_errno_to_error_array[ENOATTR] = GF_ERROR_CODE_NOATTR;
-
- /* EBADMSG 94 / * Bad message */
- gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
- gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
-
- /* EMULTIHOP 95 / * Reserved */
- gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
- gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
-
- /* ENODATA 96 / * No message available on STREAM */
- gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
- gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
-
- /* ENOLINK 97 / * Reserved */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
- gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
-
- /* ENOSR 98 / * No STREAM resources */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSR] = ENOSR;
- gf_errno_to_error_array[ENOSR] = GF_ERROR_CODE_NOSR;
-
- /* ENOSTR 99 / * Not a STREAM */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSTR] = ENOSTR;
- gf_errno_to_error_array[ENOSTR] = GF_ERROR_CODE_NOSTR;
-
-/* EPROTO 100 / * Protocol error */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
- gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
-/* ETIME 101 / * STREAM ioctl timeout */
- gf_error_to_errno_array[GF_ERROR_CODE_TIME] = ETIME;
- gf_errno_to_error_array[ETIME] = GF_ERROR_CODE_TIME;
-
-/* This value is only discrete when compiling __DARWIN_UNIX03, or KERNEL */
-/* EOPNOTSUPP 102 / * Operation not supported on socket */
- gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
- gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
-
-/* ENOPOLICY 103 / * No such policy registered */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPOLICY] = ENOPOLICY;
- gf_errno_to_error_array[ENOPOLICY] = GF_ERROR_CODE_NOPOLICY;
-
- return ;
+ /* ECANCELED 89 / * Operation canceled */
+ gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
+ gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
+
+ /* EIDRM 90 / * Identifier removed */
+ gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
+ gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
+ /* ENOMSG 91 / * No message of desired type */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
+ gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
+
+ /* EILSEQ 92 / * Illegal byte sequence */
+ gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
+ gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
+
+ /* ENOATTR 93 / * Attribute not found */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOATTR] = ENOATTR;
+ gf_errno_to_error_array[ENOATTR] = GF_ERROR_CODE_NOATTR;
+
+ /* EBADMSG 94 / * Bad message */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
+ gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
+
+ /* EMULTIHOP 95 / * Reserved */
+ gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
+ gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
+
+ /* ENODATA 96 / * No message available on STREAM
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
+ gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
+
+ /* ENOLINK 97 / * Reserved */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
+ gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
+
+ /* ENOSR 98 / * No STREAM resources */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSR] = ENOSR;
+ gf_errno_to_error_array[ENOSR] = GF_ERROR_CODE_NOSR;
+
+ /* ENOSTR 99 / * Not a STREAM */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSTR] = ENOSTR;
+ gf_errno_to_error_array[ENOSTR] = GF_ERROR_CODE_NOSTR;
+
+ /* EPROTO 100 / * Protocol error */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
+ gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
+ /* ETIME 101 / * STREAM ioctl timeout */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIME] = ETIME;
+ gf_errno_to_error_array[ETIME] = GF_ERROR_CODE_TIME;
+
+ /* This value is only discrete when compiling __DARWIN_UNIX03, or KERNEL */
+ /* EOPNOTSUPP 102 / * Operation not supported on
+ * socket */
+ gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
+ gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
+
+ /* ENOPOLICY 103 / * No such policy registered */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPOLICY] = ENOPOLICY;
+ gf_errno_to_error_array[ENOPOLICY] = GF_ERROR_CODE_NOPOLICY;
+
+ return;
}
#endif /* GF_DARWIN_HOST_OS */
#ifdef GF_BSD_HOST_OS
static void
-init_compat_errno_arrays ()
+init_compat_errno_arrays()
{
- /* Quite a bit of things changed in FreeBSD - current */
-
- /* EAGAIN 35 / * Try Again */
- gf_error_to_errno_array[GF_ERROR_CODE_AGAIN] = EAGAIN;
- gf_errno_to_error_array[EAGAIN] = GF_ERROR_CODE_AGAIN;
-
- /* EDEADLK 11 / * Resource deadlock would occur */
- gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
- gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
-
- /* EINPROGRESS 36 / * Operation now in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
- gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
-
- /* EALREADY 37 / * Operation already in progress */
- gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
- gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
-
- /* ENOTSOCK 38 / * Socket operation on non-socket */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
- gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
-
- /* EDESTADDRREQ 39 / * Destination address required */
- gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
- gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
-
- /* EMSGSIZE 40 / * Message too long */
- gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
- gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
-
- /* EPROTOTYPE 41 / * Protocol wrong type for socket */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
- gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
-
- /* ENOPROTOOPT 42 / * Protocol not available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
- gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
-
- /* EPROTONOSUPPORT 43 / * Protocol not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
- gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
-
- /* ESOCKTNOSUPPORT 44 / * Socket type not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
- gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
-
- /* EOPNOTSUPP 45 / * Operation not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
- gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
-
- /* EPFNOSUPPORT 46 / * Protocol family not supported */
- gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
- gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
-
- /* EAFNOSUPPORT 47 / * Address family not supported by protocol family */
- gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
- gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
+ /* Quite a bit of things changed in FreeBSD - current */
+
+ /* EAGAIN 35 / * Try Again */
+ gf_error_to_errno_array[GF_ERROR_CODE_AGAIN] = EAGAIN;
+ gf_errno_to_error_array[EAGAIN] = GF_ERROR_CODE_AGAIN;
+
+ /* EDEADLK 11 / * Resource deadlock would occur */
+ gf_error_to_errno_array[GF_ERROR_CODE_DEADLK] = EDEADLK;
+ gf_errno_to_error_array[EDEADLK] = GF_ERROR_CODE_DEADLK;
+
+ /* EINPROGRESS 36 / * Operation now in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_INPROGRESS] = EINPROGRESS;
+ gf_errno_to_error_array[EINPROGRESS] = GF_ERROR_CODE_INPROGRESS;
+
+ /* EALREADY 37 / * Operation already in progress */
+ gf_error_to_errno_array[GF_ERROR_CODE_ALREADY] = EALREADY;
+ gf_errno_to_error_array[EALREADY] = GF_ERROR_CODE_ALREADY;
+
+ /* ENOTSOCK 38 / * Socket operation on non-socket
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTSOCK] = ENOTSOCK;
+ gf_errno_to_error_array[ENOTSOCK] = GF_ERROR_CODE_NOTSOCK;
+
+ /* EDESTADDRREQ 39 / * Destination address required */
+ gf_error_to_errno_array[GF_ERROR_CODE_DESTADDRREQ] = EDESTADDRREQ;
+ gf_errno_to_error_array[EDESTADDRREQ] = GF_ERROR_CODE_DESTADDRREQ;
+
+ /* EMSGSIZE 40 / * Message too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_MSGSIZE] = EMSGSIZE;
+ gf_errno_to_error_array[EMSGSIZE] = GF_ERROR_CODE_MSGSIZE;
+
+ /* EPROTOTYPE 41 / * Protocol wrong type for socket
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTOTYPE] = EPROTOTYPE;
+ gf_errno_to_error_array[EPROTOTYPE] = GF_ERROR_CODE_PROTOTYPE;
+
+ /* ENOPROTOOPT 42 / * Protocol not available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOPROTOOPT] = ENOPROTOOPT;
+ gf_errno_to_error_array[ENOPROTOOPT] = GF_ERROR_CODE_NOPROTOOPT;
+
+ /* EPROTONOSUPPORT 43 / * Protocol not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTONOSUPPORT] = EPROTONOSUPPORT;
+ gf_errno_to_error_array[EPROTONOSUPPORT] = GF_ERROR_CODE_PROTONOSUPPORT;
+
+ /* ESOCKTNOSUPPORT 44 / * Socket type not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_SOCKTNOSUPPORT] = ESOCKTNOSUPPORT;
+ gf_errno_to_error_array[ESOCKTNOSUPPORT] = GF_ERROR_CODE_SOCKTNOSUPPORT;
+
+ /* EOPNOTSUPP 45 / * Operation not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_OPNOTSUPP] = EOPNOTSUPP;
+ gf_errno_to_error_array[EOPNOTSUPP] = GF_ERROR_CODE_OPNOTSUPP;
+
+ /* EPFNOSUPPORT 46 / * Protocol family not supported */
+ gf_error_to_errno_array[GF_ERROR_CODE_PFNOSUPPORT] = EPFNOSUPPORT;
+ gf_errno_to_error_array[EPFNOSUPPORT] = GF_ERROR_CODE_PFNOSUPPORT;
+
+ /* EAFNOSUPPORT 47 / * Address family not supported by
+ * protocol family */
+ gf_error_to_errno_array[GF_ERROR_CODE_AFNOSUPPORT] = EAFNOSUPPORT;
+ gf_errno_to_error_array[EAFNOSUPPORT] = GF_ERROR_CODE_AFNOSUPPORT;
+
+ /* EADDRINUSE 48 / * Address already in use */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
+ gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
+
+ /* EADDRNOTAVAIL 49 / * Can't assign requested address
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
+ gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
+
+ /* ENETDOWN 50 / * Network is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
+ gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
+
+ /* ENETUNREACH 51 / * Network is unreachable */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
+ gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
+
+ /* ENETRESET 52 / * Network dropped connection on
+ * reset */
+ gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
+ gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
+
+ /* ECONNABORTED 53 / * Software caused connection abort
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
+ gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
+
+ /* ECONNRESET 54 / * Connection reset by peer */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
+ gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
+
+ /* ENOBUFS 55 / * No buffer space available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
+ gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
+
+ /* EISCONN 56 / * Socket is already connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
+ gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
+
+ /* ENOTCONN 57 / * Socket is not connected */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
+ gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
+
+ /* ESHUTDOWN 58 / * Can't send after socket shutdown
+ */
+ gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
+ gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
+
+ /* ETOOMANYREFS 59 / * Too many references: can't
+ * splice */
+ gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
+ gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
+
+ /* ETIMEDOUT 60 / * Operation timed out */
+ gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
+ gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
+
+ /* ECONNREFUSED 61 / * Connection refused */
+ gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
+ gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
+
+ /* ELOOP 62 / * Too many levels of symbolic
+ * links */
+ gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
+ gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
+
+ /* ENAMETOOLONG 63 / * File name too long */
+ gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
+ gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
+
+ /* EHOSTDOWN 64 / * Host is down */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
+ gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
+
+ /* EHOSTUNREACH 65 / * No route to host */
+ gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
+ gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
+
+ /* ENOTEMPTY 66 / * Directory not empty */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
+ gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
+
+ /* EPROCLIM 67 / * Too many processes */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROCLIM] = EPROCLIM;
+ gf_errno_to_error_array[EPROCLIM] = GF_ERROR_CODE_PROCLIM;
+
+ /* EUSERS 68 / * Too many users */
+ gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
+ gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
+
+ /* EDQUOT 69 / * Disc quota exceeded */
+ gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
+ gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
+
+ /* ESTALE 70 / * Stale NFS file handle */
+ gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
+ gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
+
+ /* EREMOTE 71 / * Too many levels of remote in
+ * path */
+ gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
+ gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
+
+ /* EBADRPC 72 / * RPC struct is bad */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADRPC] = EBADRPC;
+ gf_errno_to_error_array[EBADRPC] = GF_ERROR_CODE_BADRPC;
+
+ /* ERPCMISMATCH 73 / * RPC version wrong */
+ gf_error_to_errno_array[GF_ERROR_CODE_RPCMISMATCH] = ERPCMISMATCH;
+ gf_errno_to_error_array[ERPCMISMATCH] = GF_ERROR_CODE_RPCMISMATCH;
+
+ /* EPROGUNAVAIL 74 / * RPC prog. not avail */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROGUNAVAIL] = EPROGUNAVAIL;
+ gf_errno_to_error_array[EPROGUNAVAIL] = GF_ERROR_CODE_PROGUNAVAIL;
+
+ /* EPROGMISMATCH 75 / * Program version wrong */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROGMISMATCH] = EPROGMISMATCH;
+ gf_errno_to_error_array[EPROGMISMATCH] = GF_ERROR_CODE_PROGMISMATCH;
+
+ /* EPROCUNAVAIL 76 / * Bad procedure for program */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROCUNAVAIL] = EPROCUNAVAIL;
+ gf_errno_to_error_array[EPROCUNAVAIL] = GF_ERROR_CODE_PROCUNAVAIL;
+
+ /* ENOLCK 77 / * No locks available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
+ gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
- /* EADDRINUSE 48 / * Address already in use */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRINUSE] = EADDRINUSE;
- gf_errno_to_error_array[EADDRINUSE] = GF_ERROR_CODE_ADDRINUSE;
+ /* ENOSYS 78 / * Function not implemented */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
+ gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
- /* EADDRNOTAVAIL 49 / * Can't assign requested address */
- gf_error_to_errno_array[GF_ERROR_CODE_ADDRNOTAVAIL] = EADDRNOTAVAIL;
- gf_errno_to_error_array[EADDRNOTAVAIL] = GF_ERROR_CODE_ADDRNOTAVAIL;
+ /* EFTYPE 79 / * Inappropriate file type or
+ * format */
+ gf_error_to_errno_array[GF_ERROR_CODE_FTYPE] = EFTYPE;
+ gf_errno_to_error_array[EFTYPE] = GF_ERROR_CODE_FTYPE;
+
+ /* EAUTH 80 / * Authentication error */
+ gf_error_to_errno_array[GF_ERROR_CODE_AUTH] = EAUTH;
+ gf_errno_to_error_array[EAUTH] = GF_ERROR_CODE_AUTH;
+
+ /* ENEEDAUTH 81 / * Need authenticator */
+ gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
+ gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
+
+ /* EIDRM 82 / * Identifier removed */
+ gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
+ gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
- /* ENETDOWN 50 / * Network is down */
- gf_error_to_errno_array[GF_ERROR_CODE_NETDOWN] = ENETDOWN;
- gf_errno_to_error_array[ENETDOWN] = GF_ERROR_CODE_NETDOWN;
+ /* ENOMSG 83 / * No message of desired type */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
+ gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
- /* ENETUNREACH 51 / * Network is unreachable */
- gf_error_to_errno_array[GF_ERROR_CODE_NETUNREACH] = ENETUNREACH;
- gf_errno_to_error_array[ENETUNREACH] = GF_ERROR_CODE_NETUNREACH;
+ /* EOVERFLOW 84 / * Value too large to be stored in
+ * data type */
+ gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
+ gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
- /* ENETRESET 52 / * Network dropped connection on reset */
- gf_error_to_errno_array[GF_ERROR_CODE_NETRESET] = ENETRESET;
- gf_errno_to_error_array[ENETRESET] = GF_ERROR_CODE_NETRESET;
+ /* ECANCELED 85 / * Operation canceled */
+ gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
+ gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
- /* ECONNABORTED 53 / * Software caused connection abort */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNABORTED] = ECONNABORTED;
- gf_errno_to_error_array[ECONNABORTED] = GF_ERROR_CODE_CONNABORTED;
+ /* EILSEQ 86 / * Illegal byte sequence */
+ gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
+ gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
- /* ECONNRESET 54 / * Connection reset by peer */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNRESET] = ECONNRESET;
- gf_errno_to_error_array[ECONNRESET] = GF_ERROR_CODE_CONNRESET;
-
- /* ENOBUFS 55 / * No buffer space available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOBUFS] = ENOBUFS;
- gf_errno_to_error_array[ENOBUFS] = GF_ERROR_CODE_NOBUFS;
-
- /* EISCONN 56 / * Socket is already connected */
- gf_error_to_errno_array[GF_ERROR_CODE_ISCONN] = EISCONN;
- gf_errno_to_error_array[EISCONN] = GF_ERROR_CODE_ISCONN;
-
- /* ENOTCONN 57 / * Socket is not connected */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTCONN] = ENOTCONN;
- gf_errno_to_error_array[ENOTCONN] = GF_ERROR_CODE_NOTCONN;
-
- /* ESHUTDOWN 58 / * Can't send after socket shutdown */
- gf_error_to_errno_array[GF_ERROR_CODE_SHUTDOWN] = ESHUTDOWN;
- gf_errno_to_error_array[ESHUTDOWN] = GF_ERROR_CODE_SHUTDOWN;
-
- /* ETOOMANYREFS 59 / * Too many references: can't splice */
- gf_error_to_errno_array[GF_ERROR_CODE_TOOMANYREFS] = ETOOMANYREFS;
- gf_errno_to_error_array[ETOOMANYREFS] = GF_ERROR_CODE_TOOMANYREFS;
-
- /* ETIMEDOUT 60 / * Operation timed out */
- gf_error_to_errno_array[GF_ERROR_CODE_TIMEDOUT] = ETIMEDOUT;
- gf_errno_to_error_array[ETIMEDOUT] = GF_ERROR_CODE_TIMEDOUT;
-
- /* ECONNREFUSED 61 / * Connection refused */
- gf_error_to_errno_array[GF_ERROR_CODE_CONNREFUSED] = ECONNREFUSED;
- gf_errno_to_error_array[ECONNREFUSED] = GF_ERROR_CODE_CONNREFUSED;
-
- /* ELOOP 62 / * Too many levels of symbolic links */
- gf_error_to_errno_array[GF_ERROR_CODE_LOOP] = ELOOP;
- gf_errno_to_error_array[ELOOP] = GF_ERROR_CODE_LOOP;
-
- /* ENAMETOOLONG 63 / * File name too long */
- gf_error_to_errno_array[GF_ERROR_CODE_NAMETOOLONG] = ENAMETOOLONG;
- gf_errno_to_error_array[ENAMETOOLONG] = GF_ERROR_CODE_NAMETOOLONG;
-
- /* EHOSTDOWN 64 / * Host is down */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTDOWN] = EHOSTDOWN;
- gf_errno_to_error_array[EHOSTDOWN] = GF_ERROR_CODE_HOSTDOWN;
-
- /* EHOSTUNREACH 65 / * No route to host */
- gf_error_to_errno_array[GF_ERROR_CODE_HOSTUNREACH] = EHOSTUNREACH;
- gf_errno_to_error_array[EHOSTUNREACH] = GF_ERROR_CODE_HOSTUNREACH;
-
- /* ENOTEMPTY 66 / * Directory not empty */
- gf_error_to_errno_array[GF_ERROR_CODE_NOTEMPTY] = ENOTEMPTY;
- gf_errno_to_error_array[ENOTEMPTY] = GF_ERROR_CODE_NOTEMPTY;
-
- /* EPROCLIM 67 / * Too many processes */
- gf_error_to_errno_array[GF_ERROR_CODE_PROCLIM] = EPROCLIM;
- gf_errno_to_error_array[EPROCLIM] = GF_ERROR_CODE_PROCLIM;
-
- /* EUSERS 68 / * Too many users */
- gf_error_to_errno_array[GF_ERROR_CODE_USERS] = EUSERS;
- gf_errno_to_error_array[EUSERS] = GF_ERROR_CODE_USERS;
-
- /* EDQUOT 69 / * Disc quota exceeded */
- gf_error_to_errno_array[GF_ERROR_CODE_DQUOT] = EDQUOT;
- gf_errno_to_error_array[EDQUOT] = GF_ERROR_CODE_DQUOT;
-
- /* ESTALE 70 / * Stale NFS file handle */
- gf_error_to_errno_array[GF_ERROR_CODE_STALE] = ESTALE;
- gf_errno_to_error_array[ESTALE] = GF_ERROR_CODE_STALE;
-
- /* EREMOTE 71 / * Too many levels of remote in path */
- gf_error_to_errno_array[GF_ERROR_CODE_REMOTE] = EREMOTE;
- gf_errno_to_error_array[EREMOTE] = GF_ERROR_CODE_REMOTE;
-
- /* EBADRPC 72 / * RPC struct is bad */
- gf_error_to_errno_array[GF_ERROR_CODE_BADRPC] = EBADRPC;
- gf_errno_to_error_array[EBADRPC] = GF_ERROR_CODE_BADRPC;
-
- /* ERPCMISMATCH 73 / * RPC version wrong */
- gf_error_to_errno_array[GF_ERROR_CODE_RPCMISMATCH] = ERPCMISMATCH;
- gf_errno_to_error_array[ERPCMISMATCH] = GF_ERROR_CODE_RPCMISMATCH;
-
- /* EPROGUNAVAIL 74 / * RPC prog. not avail */
- gf_error_to_errno_array[GF_ERROR_CODE_PROGUNAVAIL] = EPROGUNAVAIL;
- gf_errno_to_error_array[EPROGUNAVAIL] = GF_ERROR_CODE_PROGUNAVAIL;
-
- /* EPROGMISMATCH 75 / * Program version wrong */
- gf_error_to_errno_array[GF_ERROR_CODE_PROGMISMATCH] = EPROGMISMATCH;
- gf_errno_to_error_array[EPROGMISMATCH] = GF_ERROR_CODE_PROGMISMATCH;
-
- /* EPROCUNAVAIL 76 / * Bad procedure for program */
- gf_error_to_errno_array[GF_ERROR_CODE_PROCUNAVAIL] = EPROCUNAVAIL;
- gf_errno_to_error_array[EPROCUNAVAIL] = GF_ERROR_CODE_PROCUNAVAIL;
-
- /* ENOLCK 77 / * No locks available */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLCK] = ENOLCK;
- gf_errno_to_error_array[ENOLCK] = GF_ERROR_CODE_NOLCK;
-
- /* ENOSYS 78 / * Function not implemented */
- gf_error_to_errno_array[GF_ERROR_CODE_NOSYS] = ENOSYS;
- gf_errno_to_error_array[ENOSYS] = GF_ERROR_CODE_NOSYS;
-
- /* EFTYPE 79 / * Inappropriate file type or format */
- gf_error_to_errno_array[GF_ERROR_CODE_FTYPE] = EFTYPE;
- gf_errno_to_error_array[EFTYPE] = GF_ERROR_CODE_FTYPE;
-
- /* EAUTH 80 / * Authentication error */
- gf_error_to_errno_array[GF_ERROR_CODE_AUTH] = EAUTH;
- gf_errno_to_error_array[EAUTH] = GF_ERROR_CODE_AUTH;
-
- /* ENEEDAUTH 81 / * Need authenticator */
- gf_error_to_errno_array[GF_ERROR_CODE_NEEDAUTH] = ENEEDAUTH;
- gf_errno_to_error_array[ENEEDAUTH] = GF_ERROR_CODE_NEEDAUTH;
-
- /* EIDRM 82 / * Identifier removed */
- gf_error_to_errno_array[GF_ERROR_CODE_IDRM] = EIDRM;
- gf_errno_to_error_array[EIDRM] = GF_ERROR_CODE_IDRM;
-
- /* ENOMSG 83 / * No message of desired type */
- gf_error_to_errno_array[GF_ERROR_CODE_NOMSG] = ENOMSG;
- gf_errno_to_error_array[ENOMSG] = GF_ERROR_CODE_NOMSG;
-
- /* EOVERFLOW 84 / * Value too large to be stored in data type */
- gf_error_to_errno_array[GF_ERROR_CODE_OVERFLOW] = EOVERFLOW;
- gf_errno_to_error_array[EOVERFLOW] = GF_ERROR_CODE_OVERFLOW;
-
- /* ECANCELED 85 / * Operation canceled */
- gf_error_to_errno_array[GF_ERROR_CODE_CANCELED] = ECANCELED;
- gf_errno_to_error_array[ECANCELED] = GF_ERROR_CODE_CANCELED;
-
- /* EILSEQ 86 / * Illegal byte sequence */
- gf_error_to_errno_array[GF_ERROR_CODE_ILSEQ] = EILSEQ;
- gf_errno_to_error_array[EILSEQ] = GF_ERROR_CODE_ILSEQ;
-
- /* ENOATTR 87 / * Attribute not found */
- gf_error_to_errno_array[GF_ERROR_CODE_NOATTR] = ENOATTR;
- gf_errno_to_error_array[ENOATTR] = GF_ERROR_CODE_NOATTR;
+ /* ENOATTR 87 / * Attribute not found */
+ 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;
+ /* 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;
- gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
+ /* EBADMSG 89 / * Bad message */
+ gf_error_to_errno_array[GF_ERROR_CODE_BADMSG] = EBADMSG;
+ gf_errno_to_error_array[EBADMSG] = GF_ERROR_CODE_BADMSG;
#ifdef __NetBSD__
- /* ENODATA 89 / * No message available */
- gf_error_to_errno_array[GF_ERROR_CODE_NODATA] = ENODATA;
- gf_errno_to_error_array[ENODATA] = GF_ERROR_CODE_NODATA;
+ /* ENODATA 89 / * No message available */
+ gf_error_to_errno_array[GF_ERROR_CODE_NODATA] = ENODATA;
+ gf_errno_to_error_array[ENODATA] = GF_ERROR_CODE_NODATA;
#endif
- /* EMULTIHOP 90 / * Multihop attempted */
- gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
- gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
-
- /* ENOLINK 91 / * Link has been severed */
- gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
- gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
+ /* EMULTIHOP 90 / * Multihop attempted */
+ gf_error_to_errno_array[GF_ERROR_CODE_MULTIHOP] = EMULTIHOP;
+ gf_errno_to_error_array[EMULTIHOP] = GF_ERROR_CODE_MULTIHOP;
- /* EPROTO 92 / * Protocol error */
- gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
- gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
+ /* ENOLINK 91 / * Link has been severed */
+ gf_error_to_errno_array[GF_ERROR_CODE_NOLINK] = ENOLINK;
+ gf_errno_to_error_array[ENOLINK] = GF_ERROR_CODE_NOLINK;
+ /* EPROTO 92 / * Protocol error */
+ gf_error_to_errno_array[GF_ERROR_CODE_PROTO] = EPROTO;
+ gf_errno_to_error_array[EPROTO] = GF_ERROR_CODE_PROTO;
- return ;
+ return;
}
#endif /* GF_BSD_HOST_OS */
#ifdef GF_LINUX_HOST_OS
static void
-init_compat_errno_arrays ()
+init_compat_errno_arrays()
{
- /* Things are fine. Everything should work seemlessly on GNU/Linux machines */
- return ;
+ /* Things are fine. Everything should work seemlessly on GNU/Linux machines
+ */
+ return;
}
#endif /* GF_LINUX_HOST_OS */
-
static void
-init_errno_arrays ()
+init_errno_arrays()
{
- int i;
- for (i=0; i < GF_ERROR_CODE_UNKNOWN; i++) {
- gf_errno_to_error_array[i] = i;
- gf_error_to_errno_array[i] = i;
- }
- /* Now change the order if it needs to be. */
- init_compat_errno_arrays();
-
- return;
+ int i;
+ for (i = 0; i < GF_ERROR_CODE_UNKNOWN; i++) {
+ gf_errno_to_error_array[i] = i;
+ gf_error_to_errno_array[i] = i;
+ }
+ /* Now change the order if it needs to be. */
+ init_compat_errno_arrays();
+
+ return;
}
int32_t
-gf_errno_to_error (int32_t op_errno)
+gf_errno_to_error(int32_t op_errno)
{
- if (!gf_compat_errno_init_done) {
- init_errno_arrays ();
- gf_compat_errno_init_done = 1;
- }
+ if (!gf_compat_errno_init_done) {
+ init_errno_arrays();
+ gf_compat_errno_init_done = 1;
+ }
- if ((op_errno > GF_ERROR_CODE_SUCCESS) && (op_errno < GF_ERROR_CODE_UNKNOWN))
- return gf_errno_to_error_array[op_errno];
+ if ((op_errno > GF_ERROR_CODE_SUCCESS) &&
+ (op_errno < GF_ERROR_CODE_UNKNOWN))
+ return gf_errno_to_error_array[op_errno];
- return op_errno;
+ return op_errno;
}
-
int32_t
-gf_error_to_errno (int32_t error)
+gf_error_to_errno(int32_t error)
{
- if (!gf_compat_errno_init_done) {
- init_errno_arrays ();
- gf_compat_errno_init_done = 1;
- }
+ if (!gf_compat_errno_init_done) {
+ init_errno_arrays();
+ gf_compat_errno_init_done = 1;
+ }
- if ((error > GF_ERROR_CODE_SUCCESS) && (error < GF_ERROR_CODE_UNKNOWN))
- return gf_error_to_errno_array[error];
+ if ((error > GF_ERROR_CODE_SUCCESS) && (error < GF_ERROR_CODE_UNKNOWN))
+ return gf_error_to_errno_array[error];
- return error;
+ return error;
}
diff --git a/libglusterfs/src/compat-errno.h b/libglusterfs/src/compat-errno.h
deleted file mode 100644
index 6f46157e697..00000000000
--- a/libglusterfs/src/compat-errno.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- 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__
-#define __COMPAT_ERRNO_H__
-
-#include <errno.h>
-
-#define GF_ERROR_CODE_SUCCESS 0
-#define GF_ERROR_CODE_UNKNOWN 1024
-#define GF_ERRNO_UNKNOWN 1024
-
-#define GF_ERROR_CODE_PERM 1 /* Operation not permitted */
-#define GF_ERROR_CODE_NOENT 2 /* No such file or directory */
-#define GF_ERROR_CODE_SRCH 3 /* No such process */
-#define GF_ERROR_CODE_INTR 4 /* Interrupted system call */
-#define GF_ERROR_CODE_IO 5 /* I/O error */
-#define GF_ERROR_CODE_NXIO 6 /* No such device or address */
-#define GF_ERROR_CODE_2BIG 7 /* Argument list too long */
-#define GF_ERROR_CODE_NOEXEC 8 /* Exec format error */
-#define GF_ERROR_CODE_BADF 9 /* Bad file number */
-#define GF_ERROR_CODE_CHILD 10 /* No child processes */
-#define GF_ERROR_CODE_AGAIN 11 /* Try again */
-#define GF_ERROR_CODE_NOMEM 12 /* Out of memory */
-#define GF_ERROR_CODE_ACCES 13 /* Permission denied */
-#define GF_ERROR_CODE_FAULT 14 /* Bad address */
-#define GF_ERROR_CODE_NOTBLK 15 /* Block device required */
-#define GF_ERROR_CODE_BUSY 16 /* Device or resource busy */
-#define GF_ERROR_CODE_EXIST 17 /* File exists */
-#define GF_ERROR_CODE_XDEV 18 /* Cross-device link */
-#define GF_ERROR_CODE_NODEV 19 /* No such device */
-#define GF_ERROR_CODE_NOTDIR 20 /* Not a directory */
-#define GF_ERROR_CODE_ISDIR 21 /* Is a directory */
-#define GF_ERROR_CODE_INVAL 22 /* Invalid argument */
-#define GF_ERROR_CODE_NFILE 23 /* File table overflow */
-#define GF_ERROR_CODE_MFILE 24 /* Too many open files */
-#define GF_ERROR_CODE_NOTTY 25 /* Not a typewriter */
-#define GF_ERROR_CODE_TXTBSY 26 /* Text file busy */
-#define GF_ERROR_CODE_FBIG 27 /* File too large */
-#define GF_ERROR_CODE_NOSPC 28 /* No space left on device */
-#define GF_ERROR_CODE_SPIPE 29 /* Illegal seek */
-#define GF_ERROR_CODE_ROFS 30 /* Read-only file system */
-#define GF_ERROR_CODE_MLINK 31 /* Too many links */
-#define GF_ERROR_CODE_PIPE 32 /* Broken pipe */
-#define GF_ERROR_CODE_DOM 33 /* Math argument out of domain of func */
-#define GF_ERROR_CODE_RANGE 34 /* Math result not representable */
-#define GF_ERROR_CODE_DEADLK 35 /* Resource deadlock would occur */
-#define GF_ERROR_CODE_NAMETOOLONG 36 /* File name too long */
-#define GF_ERROR_CODE_NOLCK 37 /* No record locks available */
-#define GF_ERROR_CODE_NOSYS 38 /* Function not implemented */
-#define GF_ERROR_CODE_NOTEMPTY 39 /* Directory not empty */
-#define GF_ERROR_CODE_LOOP 40 /* Too many symbolic links encountered */
-
-#define GF_ERROR_CODE_NOMSG 42 /* No message of desired type */
-#define GF_ERROR_CODE_IDRM 43 /* Identifier removed */
-#define GF_ERROR_CODE_CHRNG 44 /* Channel number out of range */
-#define GF_ERROR_CODE_L2NSYNC 45 /* Level 2 not synchronized */
-#define GF_ERROR_CODE_L3HLT 46 /* Level 3 halted */
-#define GF_ERROR_CODE_L3RST 47 /* Level 3 reset */
-#define GF_ERROR_CODE_LNRNG 48 /* Link number out of range */
-#define GF_ERROR_CODE_UNATCH 49 /* Protocol driver not attached */
-#define GF_ERROR_CODE_NOCSI 50 /* No CSI structure available */
-#define GF_ERROR_CODE_L2HLT 51 /* Level 2 halted */
-#define GF_ERROR_CODE_BADE 52 /* Invalid exchange */
-#define GF_ERROR_CODE_BADR 53 /* Invalid request descriptor */
-#define GF_ERROR_CODE_XFULL 54 /* Exchange full */
-#define GF_ERROR_CODE_NOANO 55 /* No anode */
-#define GF_ERROR_CODE_BADRQC 56 /* Invalid request code */
-#define GF_ERROR_CODE_BADSLT 57 /* Invalid slot */
-#define GF_ERROR_CODE_BFONT 59 /* Bad font file format */
-#define GF_ERROR_CODE_NOSTR 60 /* Device not a stream */
-#define GF_ERROR_CODE_NODATA 61 /* No data available */
-#define GF_ERROR_CODE_TIME 62 /* Timer expired */
-#define GF_ERROR_CODE_NOSR 63 /* Out of streams resources */
-#define GF_ERROR_CODE_NONET 64 /* Machine is not on the network */
-#define GF_ERROR_CODE_NOPKG 65 /* Package not installed */
-#define GF_ERROR_CODE_REMOTE 66 /* Object is remote */
-#define GF_ERROR_CODE_NOLINK 67 /* Link has been severed */
-#define GF_ERROR_CODE_ADV 68 /* Advertise error */
-#define GF_ERROR_CODE_SRMNT 69 /* Srmount error */
-#define GF_ERROR_CODE_COMM 70 /* Communication error on send */
-#define GF_ERROR_CODE_PROTO 71 /* Protocol error */
-#define GF_ERROR_CODE_MULTIHOP 72 /* Multihop attempted */
-#define GF_ERROR_CODE_DOTDOT 73 /* RFS specific error */
-#define GF_ERROR_CODE_BADMSG 74 /* Not a data message */
-#define GF_ERROR_CODE_OVERFLOW 75 /* Value too large for defined data type */
-#define GF_ERROR_CODE_NOTUNIQ 76 /* Name not unique on network */
-#define GF_ERROR_CODE_BADFD 77 /* File descriptor in bad state */
-#define GF_ERROR_CODE_REMCHG 78 /* Remote address changed */
-#define GF_ERROR_CODE_LIBACC 79 /* Can not access a needed shared library */
-#define GF_ERROR_CODE_LIBBAD 80 /* Accessing a corrupted shared library */
-#define GF_ERROR_CODE_LIBSCN 81 /* .lib section in a.out corrupted */
-#define GF_ERROR_CODE_LIBMAX 82 /* Attempting to link in too many shared libraries */
-#define GF_ERROR_CODE_LIBEXEC 83 /* Cannot exec a shared library directly */
-#define GF_ERROR_CODE_ILSEQ 84 /* Illegal byte sequence */
-#define GF_ERROR_CODE_RESTART 85 /* Interrupted system call should be restarted */
-#define GF_ERROR_CODE_STRPIPE 86 /* Streams pipe error */
-#define GF_ERROR_CODE_USERS 87 /* Too many users */
-#define GF_ERROR_CODE_NOTSOCK 88 /* Socket operation on non-socket */
-#define GF_ERROR_CODE_DESTADDRREQ 89 /* Destination address required */
-#define GF_ERROR_CODE_MSGSIZE 90 /* Message too long */
-#define GF_ERROR_CODE_PROTOTYPE 91 /* Protocol wrong type for socket */
-#define GF_ERROR_CODE_NOPROTOOPT 92 /* Protocol not available */
-#define GF_ERROR_CODE_PROTONOSUPPORT 93 /* Protocol not supported */
-#define GF_ERROR_CODE_SOCKTNOSUPPORT 94 /* Socket type not supported */
-#define GF_ERROR_CODE_OPNOTSUPP 95 /* Operation not supported on transport endpoint */
-#define GF_ERROR_CODE_PFNOSUPPORT 96 /* Protocol family not supported */
-#define GF_ERROR_CODE_AFNOSUPPORT 97 /* Address family not supported by protocol */
-#define GF_ERROR_CODE_ADDRINUSE 98 /* Address already in use */
-#define GF_ERROR_CODE_ADDRNOTAVAIL 99 /* Cannot assign requested address */
-#define GF_ERROR_CODE_NETDOWN 100 /* Network is down */
-#define GF_ERROR_CODE_NETUNREACH 101 /* Network is unreachable */
-#define GF_ERROR_CODE_NETRESET 102 /* Network dropped connection because of reset */
-#define GF_ERROR_CODE_CONNABORTED 103 /* Software caused connection abort */
-#define GF_ERROR_CODE_CONNRESET 104 /* Connection reset by peer */
-#define GF_ERROR_CODE_NOBUFS 105 /* No buffer space available */
-#define GF_ERROR_CODE_ISCONN 106 /* Transport endpoint is already connected */
-#define GF_ERROR_CODE_NOTCONN 107 /* Transport endpoint is not connected */
-#define GF_ERROR_CODE_SHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
-#define GF_ERROR_CODE_TOOMANYREFS 109 /* Too many references: cannot splice */
-#define GF_ERROR_CODE_TIMEDOUT 110 /* Connection timed out */
-#define GF_ERROR_CODE_CONNREFUSED 111 /* Connection refused */
-#define GF_ERROR_CODE_HOSTDOWN 112 /* Host is down */
-#define GF_ERROR_CODE_HOSTUNREACH 113 /* No route to host */
-#define GF_ERROR_CODE_ALREADY 114 /* Operation already in progress */
-#define GF_ERROR_CODE_INPROGRESS 115 /* Operation now in progress */
-#define GF_ERROR_CODE_ALREADY 114 /* Operation already in progress */
-#define GF_ERROR_CODE_INPROGRESS 115 /* Operation now in progress */
-#define GF_ERROR_CODE_STALE 116 /* Stale NFS file handle */
-#define GF_ERROR_CODE_UCLEAN 117 /* Structure needs cleaning */
-#define GF_ERROR_CODE_NOTNAM 118 /* Not a XENIX named type file */
-#define GF_ERROR_CODE_NAVAIL 119 /* No XENIX semaphores available */
-#define GF_ERROR_CODE_ISNAM 120 /* Is a named type file */
-#define GF_ERROR_CODE_REMOTEIO 121 /* Remote I/O error */
-#define GF_ERROR_CODE_DQUOT 122 /* Quota exceeded */
-#define GF_ERROR_CODE_NOMEDIUM 123 /* No medium found */
-#define GF_ERROR_CODE_MEDIUMTYPE 124 /* Wrong medium type */
-#define GF_ERROR_CODE_CANCELED 125 /* Operation Canceled */
-#define GF_ERROR_CODE_NOKEY 126 /* Required key not available */
-#define GF_ERROR_CODE_KEYEXPIRED 127 /* Key has expired */
-#define GF_ERROR_CODE_KEYREVOKED 128 /* Key has been revoked */
-#define GF_ERROR_CODE_KEYREJECTED 129 /* Key was rejected by service */
-
-/* for robust mutexes */
-#define GF_ERROR_CODE_OWNERDEAD 130 /* Owner died */
-#define GF_ERROR_CODE_NOTRECOVERABLE 131 /* State not recoverable */
-
-
-
-/* Should never be seen by user programs */
-#define GF_ERROR_CODE_RESTARTSYS 512
-#define GF_ERROR_CODE_RESTARTNOINTR 513
-#define GF_ERROR_CODE_RESTARTNOHAND 514 /* restart if no handler.. */
-#define GF_ERROR_CODE_NOIOCTLCMD 515 /* No ioctl command */
-#define GF_ERROR_CODE_RESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
-
-/* Defined for the NFSv3 protocol */
-#define GF_ERROR_CODE_BADHANDLE 521 /* Illegal NFS file handle */
-#define GF_ERROR_CODE_NOTSYNC 522 /* Update synchronization mismatch */
-#define GF_ERROR_CODE_BADCOOKIE 523 /* Cookie is stale */
-#define GF_ERROR_CODE_NOTSUPP 524 /* Operation is not supported */
-#define GF_ERROR_CODE_TOOSMALL 525 /* Buffer or request is too small */
-#define GF_ERROR_CODE_SERVERFAULT 526 /* An untranslatable error occurred */
-#define GF_ERROR_CODE_BADTYPE 527 /* Type not supported by server */
-#define GF_ERROR_CODE_JUKEBOX 528 /* Request initiated, but will not complete before timeout */
-#define GF_ERROR_CODE_IOCBQUEUED 529 /* iocb queued, will get completion event */
-#define GF_ERROR_CODE_IOCBRETRY 530 /* iocb queued, will trigger a retry */
-
-/* Darwin OS X */
-#define GF_ERROR_CODE_NOPOLICY 701
-#define GF_ERROR_CODE_BADMACHO 702
-#define GF_ERROR_CODE_PWROFF 703
-#define GF_ERROR_CODE_DEVERR 704
-#define GF_ERROR_CODE_BADARCH 705
-#define GF_ERROR_CODE_BADEXEC 706
-#define GF_ERROR_CODE_SHLIBVERS 707
-
-
-
-/* Solaris */
-/* ENOTACTIVE 73 / * Facility is not active */
-#define GF_ERROR_CODE_NOTACTIVE 801
-/* ELOCKUNMAPPED 72 / * locked lock was unmapped */
-#define GF_ERROR_CODE_LOCKUNMAPPED 802
-
-/* BSD system */
-#define GF_ERROR_CODE_PROCLIM 901 /* Too many processes */
-#define GF_ERROR_CODE_BADRPC 902 /* RPC struct is bad */
-#define GF_ERROR_CODE_RPCMISMATCH 903 /* RPC version wrong */
-#define GF_ERROR_CODE_PROGUNAVAIL 904 /* RPC prog. not avail */
-#define GF_ERROR_CODE_PROGMISMATCH 905 /* Program version wrong */
-#define GF_ERROR_CODE_PROCUNAVAIL 905 /* Bad procedure for program */
-#define GF_ERROR_CODE_FTYPE 906 /* Inappropriate file type or format */
-#define GF_ERROR_CODE_AUTH 907 /* Authentication error */
-#define GF_ERROR_CODE_NEEDAUTH 908 /* Need authenticator */
-#define GF_ERROR_CODE_DOOFUS 909 /* Programming error */
-
-#define GF_ERROR_CODE_NOATTR GF_ERROR_CODE_NODATA /* Attribute not found */
-
-/* Either one of enodata or enoattr will be there in system */
-#ifndef ENOATTR
-#define ENOATTR ENODATA
-#endif /* ENOATTR */
-
-#ifndef ENODATA
-#define ENODATA ENOATTR
-#endif /* ENODATA */
-
-#ifndef EBADFD
-#define EBADFD EBADRPC
-#endif /* EBADFD */
-
-/* These functions are defined for all the OS flags, but content will
- * be different for each OS flag.
- */
-int32_t gf_errno_to_error (int32_t op_errno);
-int32_t gf_error_to_errno (int32_t error);
-
-#endif /* __COMPAT_ERRNO_H__ */
diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c
index e50f27bff90..8a05a30a8fe 100644
--- a/libglusterfs/src/compat.c
+++ b/libglusterfs/src/compat.c
@@ -8,7 +8,6 @@
cases as published by the Free Software Foundation.
*/
-#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
@@ -16,566 +15,604 @@
#include <sys/types.h>
#include <dirent.h>
-#ifdef GF_SOLARIS_HOST_OS
-#include "logging.h"
-#endif /* GF_SOLARIS_HOST_OS */
-
-#include "compat.h"
-#include "common-utils.h"
-#include "iatt.h"
-#include "inode.h"
-#include "run.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/compat.h"
+#include "glusterfs/iatt.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/run.h"
+#include "glusterfs/libglusterfs-messages.h"
#ifdef GF_SOLARIS_HOST_OS
int
-solaris_fsetxattr(int fd, const char* key, const char *value, size_t size,
+solaris_fsetxattr(int fd, const char *key, const char *value, size_t size,
int flags)
{
- int attrfd = -1;
- int ret = 0;
-
- attrfd = openat (fd, key, flags|O_CREAT|O_WRONLY|O_XATTR, 0777);
- if (attrfd >= 0) {
- ftruncate (attrfd, 0);
- ret = write (attrfd, value, size);
- close (attrfd);
- } else {
- if (errno != ENOENT)
- gf_msg ("libglusterfs", GF_LOG_ERROR, errno,
- LG_MSG_SET_ATTRIBUTE_FAILED, "Couldn't set "
- "extended attribute for %d", fd);
- return -1;
- }
-
- return 0;
+ int attrfd = -1;
+ int ret = 0;
+
+ attrfd = openat(fd, key, flags | O_CREAT | O_WRONLY | O_XATTR, 0777);
+ if (attrfd >= 0) {
+ ftruncate(attrfd, 0);
+ ret = write(attrfd, value, size);
+ close(attrfd);
+ } else {
+ if (errno != ENOENT)
+ gf_msg("libglusterfs", GF_LOG_ERROR, errno,
+ LG_MSG_SET_ATTRIBUTE_FAILED,
+ "Couldn't set "
+ "extended attribute for %d",
+ fd);
+ return -1;
+ }
+
+ return 0;
}
-
int
-solaris_fgetxattr(int fd, const char* key, char *value, size_t size)
+solaris_fgetxattr(int fd, const char *key, char *value, size_t size)
{
- int attrfd = -1;
- int ret = 0;
-
- attrfd = openat (fd, key, O_RDONLY|O_XATTR);
- if (attrfd >= 0) {
- if (size == 0) {
- struct stat buf;
- fstat (attrfd, &buf);
- ret = buf.st_size;
- } else {
- ret = read (attrfd, value, size);
- }
- close (attrfd);
+ int attrfd = -1;
+ int ret = 0;
+
+ attrfd = openat(fd, key, O_RDONLY | O_XATTR);
+ if (attrfd >= 0) {
+ if (size == 0) {
+ struct stat buf;
+ fstat(attrfd, &buf);
+ ret = buf.st_size;
} else {
- if (errno != ENOENT)
- gf_msg ("libglusterfs", GF_LOG_INFO, errno,
- LG_MSG_READ_ATTRIBUTE_FAILED, "Couldn't read "
- "extended attribute for the file %d", fd);
- if (errno == ENOENT)
- errno = ENODATA;
- return -1;
+ ret = read(attrfd, value, size);
}
-
- return ret;
+ close(attrfd);
+ } else {
+ if (errno != ENOENT)
+ gf_msg("libglusterfs", GF_LOG_INFO, errno,
+ LG_MSG_READ_ATTRIBUTE_FAILED,
+ "Couldn't read "
+ "extended attribute for the file %d",
+ fd);
+ if (errno == ENOENT)
+ errno = ENODATA;
+ return -1;
+ }
+
+ return ret;
}
/* Solaris does not support xattr for symlinks and dev files. Since gfid and
other trusted attributes are stored as xattrs, we need to provide support for
- them. A mapped regular file is stored in the /.glusterfs_xattr_inode of the export dir.
- All xattr ops related to the special files are redirected to this map file.
+ them. A mapped regular file is stored in the /.glusterfs_xattr_inode of the
+ export dir. All xattr ops related to the special files are redirected to this
+ map file.
*/
int
-make_export_path (const char *real_path, char **path)
+make_export_path(const char *real_path, char **path)
{
- int ret = -1;
- char *tmp = NULL;
- char *export_path = NULL;
- char *dup = NULL;
- char *ptr = NULL;
- char *freeptr = NULL;
- uuid_t gfid = {0, };
-
- export_path = GF_CALLOC (1, sizeof (char) * PATH_MAX, 0);
- if (!export_path)
- goto out;
+ int ret = -1;
+ char *tmp = NULL;
+ char *export_path = NULL;
+ char *dup = NULL;
+ char *ptr = NULL;
+ char *freeptr = NULL;
+ uuid_t gfid = {
+ 0,
+ };
+
+ export_path = GF_CALLOC(1, sizeof(char) * PATH_MAX, 0);
+ if (!export_path)
+ goto out;
- dup = gf_strdup (real_path);
- if (!dup)
- goto out;
+ dup = gf_strdup(real_path);
+ if (!dup)
+ goto out;
- freeptr = dup;
- ret = solaris_getxattr ("/", GFID_XATTR_KEY, gfid, 16);
- /* Return value of getxattr */
+ freeptr = dup;
+ ret = solaris_getxattr("/", GFID_XATTR_KEY, gfid, 16);
+ /* Return value of getxattr */
+ if (ret == 16) {
+ if (__is_root_gfid(gfid)) {
+ strcat(export_path, "/");
+ ret = 0;
+ goto done;
+ }
+ }
+
+ do {
+ ptr = strtok_r(dup, "/", &tmp);
+ if (!ptr)
+ break;
+ strcat(export_path, dup);
+ ret = solaris_getxattr(export_path, GFID_XATTR_KEY, gfid, 16);
if (ret == 16) {
- if (__is_root_gfid (gfid)){
- strcat (export_path, "/");
- ret = 0;
- goto done;
- }
+ if (__is_root_gfid(gfid)) {
+ ret = 0;
+ goto done;
+ }
}
+ strcat(export_path, "/");
+ dup = tmp;
+ } while (ptr);
- do {
- ptr = strtok_r (dup, "/", &tmp);
- if (!ptr)
- break;
- strcat (export_path, dup);
- ret = solaris_getxattr (export_path, GFID_XATTR_KEY, gfid, 16);
- if (ret == 16) {
- if (__is_root_gfid (gfid)) {
- ret = 0;
- goto done;
- }
- }
- strcat (export_path, "/");
- dup = tmp;
- } while (ptr);
-
- goto out;
+ goto out;
done:
- if (!ret) {
- *path = export_path;
- }
+ if (!ret) {
+ *path = export_path;
+ }
out:
- GF_FREE (freeptr);
- if (ret && export_path)
- GF_FREE (export_path);
+ GF_FREE(freeptr);
+ if (ret && export_path)
+ GF_FREE(export_path);
- return ret;
+ return ret;
}
int
-solaris_xattr_resolve_path (const char *real_path, char **path)
+solaris_xattr_resolve_path(const char *real_path, char **path)
{
- int ret = -1;
- char *export_path = NULL;
- char xattr_path[PATH_MAX] = {0, };
- struct stat lstatbuf = {0, };
- struct iatt stbuf = {0, };
- struct stat statbuf = {0, };
-
- ret = lstat (real_path, &lstatbuf);
- if (ret != 0 )
- return ret;
- iatt_from_stat (&stbuf, &lstatbuf);
- if (IA_ISREG(stbuf.ia_type) || IA_ISDIR(stbuf.ia_type))
- return -1;
-
- ret = make_export_path (real_path, &export_path);
- if (!ret && export_path) {
- strcat (export_path, "/"GF_SOLARIS_XATTR_DIR);
- if (lstat (export_path, &statbuf)) {
- ret = mkdir (export_path, 0777);
- if (ret && (errno != EEXIST)) {
- gf_msg_debug (THIS->name, 0, "mkdir failed,"
- " errno: %d", errno);
- goto out;
- }
- }
+ int ret = -1;
+ char *export_path = NULL;
+ char xattr_path[PATH_MAX] = {
+ 0,
+ };
+ struct stat lstatbuf = {
+ 0,
+ };
+ struct iatt stbuf = {
+ 0,
+ };
+ struct stat statbuf = {
+ 0,
+ };
+
+ ret = lstat(real_path, &lstatbuf);
+ if (ret != 0)
+ return ret;
+ iatt_from_stat(&stbuf, &lstatbuf);
+ if (IA_ISREG(stbuf.ia_type) || IA_ISDIR(stbuf.ia_type))
+ return -1;
+
+ ret = make_export_path(real_path, &export_path);
+ if (!ret && export_path) {
+ strcat(export_path, "/" GF_SOLARIS_XATTR_DIR);
+ if (lstat(export_path, &statbuf)) {
+ ret = mkdir(export_path, 0755);
+ if (ret && (errno != EEXIST)) {
+ gf_msg_debug(THIS->name, 0,
+ "mkdir failed,"
+ " errno: %d",
+ errno);
+ goto out;
+ }
+ }
- snprintf(xattr_path, PATH_MAX, "%s%s%lu", export_path,
- "/", stbuf.ia_ino);
+ snprintf(xattr_path, PATH_MAX, "%s%s%lu", export_path, "/",
+ stbuf.ia_ino);
- ret = lstat (xattr_path, &statbuf);
+ ret = lstat(xattr_path, &statbuf);
- if (ret) {
- ret = mknod (xattr_path, S_IFREG|O_WRONLY, 0);
- if (ret && (errno != EEXIST)) {
- gf_msg (THIS->name, GF_LOG_WARNING, errno,
- LG_MSG_FILE_OP_FAILED, "Failed to "
- "create mapped file %s", xattr_path);
- goto out;
- }
- }
- *path = gf_strdup (xattr_path);
+ if (ret) {
+ ret = mknod(xattr_path, S_IFREG | O_WRONLY, 0);
+ if (ret && (errno != EEXIST)) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to "
+ "create mapped file %s",
+ xattr_path);
+ goto out;
+ }
}
+ *path = gf_strdup(xattr_path);
+ }
out:
- GF_FREE (export_path);
- if (*path)
- return 0;
- else
- return -1;
+ GF_FREE(export_path);
+ if (*path)
+ return 0;
+ else
+ return -1;
}
int
-solaris_setxattr(const char *path, const char* key, const char *value,
+solaris_setxattr(const char *path, const char *key, const char *value,
size_t size, int flags)
{
- int attrfd = -1;
- int ret = 0;
- char *mapped_path = NULL;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
- if (!ret) {
- attrfd = attropen (mapped_path, key, flags|O_CREAT|O_WRONLY,
- 0777);
- } else {
- attrfd = attropen (path, key, flags|O_CREAT|O_WRONLY, 0777);
- }
- if (attrfd >= 0) {
- ftruncate (attrfd, 0);
- ret = write (attrfd, value, size);
- close (attrfd);
- ret = 0;
- } else {
- if (errno != ENOENT)
- gf_msg ("libglusterfs", GF_LOG_ERROR, errno,
- LG_MSG_SET_ATTRIBUTE_FAILED, "Couldn't set "
- "extended attribute for %s", path);
- ret = -1;
- }
- GF_FREE (mapped_path);
- return ret;
+ int attrfd = -1;
+ int ret = 0;
+ char *mapped_path = NULL;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+ if (!ret) {
+ attrfd = attropen(mapped_path, key, flags | O_CREAT | O_WRONLY, 0777);
+ } else {
+ attrfd = attropen(path, key, flags | O_CREAT | O_WRONLY, 0777);
+ }
+ if (attrfd >= 0) {
+ ftruncate(attrfd, 0);
+ ret = write(attrfd, value, size);
+ close(attrfd);
+ ret = 0;
+ } else {
+ if (errno != ENOENT)
+ gf_msg("libglusterfs", GF_LOG_ERROR, errno,
+ LG_MSG_SET_ATTRIBUTE_FAILED,
+ "Couldn't set "
+ "extended attribute for %s",
+ path);
+ ret = -1;
+ }
+ GF_FREE(mapped_path);
+ return ret;
}
-
int
solaris_listxattr(const char *path, char *list, size_t size)
{
- int attrdirfd = -1;
- ssize_t len = 0;
- DIR *dirptr = NULL;
- struct dirent *dent = NULL;
- int newfd = -1;
- char *mapped_path = NULL;
- int ret = -1;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
- if (!ret) {
- attrdirfd = attropen (mapped_path, ".", O_RDONLY, 0);
- } else {
- attrdirfd = attropen (path, ".", O_RDONLY, 0);
- }
- if (attrdirfd >= 0) {
- newfd = dup(attrdirfd);
- dirptr = fdopendir(newfd);
- if (dirptr) {
- while ((dent = readdir(dirptr))) {
- size_t listlen = strlen(dent->d_name);
- if (!strcmp(dent->d_name, ".") ||
- !strcmp(dent->d_name, "..")) {
- /* we don't want "." and ".." here */
- continue;
- }
- if (size == 0) {
- /* return the current size of the list
- of extended attribute names*/
- len += listlen + 1;
- } else {
- /* check size and copy entry + null
- into list. */
- if ((len + listlen + 1) > size) {
- errno = ERANGE;
- len = -1;
- break;
- } else {
- strncpy(list + len, dent->d_name, listlen);
- len += listlen;
- list[len] = '\0';
- ++len;
- }
- }
- }
-
- if (closedir(dirptr) == -1) {
- close (attrdirfd);
- len = -1;
- goto out;
- }
+ int attrdirfd = -1;
+ ssize_t len = 0;
+ DIR *dirptr = NULL;
+ struct dirent *dent = NULL;
+ int newfd = -1;
+ char *mapped_path = NULL;
+ int ret = -1;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+ if (!ret) {
+ attrdirfd = attropen(mapped_path, ".", O_RDONLY, 0);
+ } else {
+ attrdirfd = attropen(path, ".", O_RDONLY, 0);
+ }
+ if (attrdirfd >= 0) {
+ newfd = dup(attrdirfd);
+ dirptr = fdopendir(newfd);
+ if (dirptr) {
+ while ((dent = readdir(dirptr))) {
+ size_t listlen = strlen(dent->d_name);
+ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
+ /* we don't want "." and ".." here */
+ continue;
+ }
+ if (size == 0) {
+ /* return the current size of the list
+ of extended attribute names*/
+ len += listlen + 1;
} else {
- close (attrdirfd);
+ /* check size and copy entry + null
+ into list. */
+ if ((len + listlen + 1) > size) {
+ errno = ERANGE;
len = -1;
- goto out;
+ break;
+ } else {
+ strncpy(list + len, dent->d_name, listlen);
+ len += listlen;
+ list[len] = '\0';
+ ++len;
+ }
}
- close (attrdirfd);
+ }
+
+ if (closedir(dirptr) == -1) {
+ close(attrdirfd);
+ len = -1;
+ goto out;
+ }
+ } else {
+ close(attrdirfd);
+ len = -1;
+ goto out;
}
+ close(attrdirfd);
+ }
out:
- GF_FREE (mapped_path);
- return len;
+ GF_FREE(mapped_path);
+ return len;
}
-
int
solaris_flistxattr(int fd, char *list, size_t size)
{
- int attrdirfd = -1;
- ssize_t len = 0;
- DIR *dirptr = NULL;
- struct dirent *dent = NULL;
- int newfd = -1;
-
- attrdirfd = openat (fd, ".", O_RDONLY, 0);
- if (attrdirfd >= 0) {
- newfd = dup(attrdirfd);
- dirptr = fdopendir(newfd);
- if (dirptr) {
- while ((dent = readdir(dirptr))) {
- size_t listlen = strlen(dent->d_name);
- if (!strcmp(dent->d_name, ".") ||
- !strcmp(dent->d_name, "..")) {
- /* we don't want "." and ".." here */
- continue;
- }
- if (size == 0) {
- /* return the current size of the list
- of extended attribute names*/
- len += listlen + 1;
- } else {
- /* check size and copy entry + null
- into list. */
- if ((len + listlen + 1) > size) {
- errno = ERANGE;
- len = -1;
- break;
- } else {
- strncpy(list + len, dent->d_name, listlen);
- len += listlen;
- list[len] = '\0';
- ++len;
- }
- }
- }
-
- if (closedir(dirptr) == -1) {
- close (attrdirfd);
- return -1;
- }
+ int attrdirfd = -1;
+ ssize_t len = 0;
+ DIR *dirptr = NULL;
+ struct dirent *dent = NULL;
+ int newfd = -1;
+
+ attrdirfd = openat(fd, ".", O_RDONLY, 0);
+ if (attrdirfd >= 0) {
+ newfd = dup(attrdirfd);
+ dirptr = fdopendir(newfd);
+ if (dirptr) {
+ while ((dent = readdir(dirptr))) {
+ size_t listlen = strlen(dent->d_name);
+ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
+ /* we don't want "." and ".." here */
+ continue;
+ }
+ if (size == 0) {
+ /* return the current size of the list
+ of extended attribute names*/
+ len += listlen + 1;
} else {
- close (attrdirfd);
- return -1;
+ /* check size and copy entry + null
+ into list. */
+ if ((len + listlen + 1) > size) {
+ errno = ERANGE;
+ len = -1;
+ break;
+ } else {
+ strncpy(list + len, dent->d_name, listlen);
+ len += listlen;
+ list[len] = '\0';
+ ++len;
+ }
}
- close (attrdirfd);
+ }
+
+ if (closedir(dirptr) == -1) {
+ close(attrdirfd);
+ return -1;
+ }
+ } else {
+ close(attrdirfd);
+ return -1;
}
- return len;
+ close(attrdirfd);
+ }
+ return len;
}
-
int
-solaris_removexattr(const char *path, const char* key)
+solaris_removexattr(const char *path, const char *key)
{
- int ret = -1;
- int attrfd = -1;
- char *mapped_path = NULL;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
- if (!ret) {
- attrfd = attropen (mapped_path, ".", O_RDONLY, 0);
- } else {
- attrfd = attropen (path, ".", O_RDONLY, 0);
- }
- if (attrfd >= 0) {
- ret = unlinkat (attrfd, key, 0);
- close (attrfd);
- } else {
- if (errno == ENOENT)
- errno = ENODATA;
- ret = -1;
- }
-
- GF_FREE (mapped_path);
-
- return ret;
+ int ret = -1;
+ int attrfd = -1;
+ char *mapped_path = NULL;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+ if (!ret) {
+ attrfd = attropen(mapped_path, ".", O_RDONLY, 0);
+ } else {
+ attrfd = attropen(path, ".", O_RDONLY, 0);
+ }
+ if (attrfd >= 0) {
+ ret = unlinkat(attrfd, key, 0);
+ close(attrfd);
+ } else {
+ if (errno == ENOENT)
+ errno = ENODATA;
+ ret = -1;
+ }
+
+ GF_FREE(mapped_path);
+
+ return ret;
}
int
-solaris_getxattr(const char *path,
- const char* key,
- char *value,
- size_t size)
+solaris_getxattr(const char *path, const char *key, char *value, size_t size)
{
- int attrfd = -1;
- int ret = 0;
- char *mapped_path = NULL;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
- if (!ret) {
- attrfd = attropen (mapped_path, key, O_RDONLY, 0);
+ int attrfd = -1;
+ int ret = 0;
+ char *mapped_path = NULL;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+ if (!ret) {
+ attrfd = attropen(mapped_path, key, O_RDONLY, 0);
+ } else {
+ attrfd = attropen(path, key, O_RDONLY, 0);
+ }
+
+ if (attrfd >= 0) {
+ if (size == 0) {
+ struct stat buf;
+ fstat(attrfd, &buf);
+ ret = buf.st_size;
} else {
- attrfd = attropen (path, key, O_RDONLY, 0);
+ ret = read(attrfd, value, size);
}
-
- if (attrfd >= 0) {
- if (size == 0) {
- struct stat buf;
- fstat (attrfd, &buf);
- ret = buf.st_size;
- } else {
- ret = read (attrfd, value, size);
- }
- close (attrfd);
- } else {
- if (errno != ENOENT)
- gf_msg ("libglusterfs", GF_LOG_INFO, errno,
- LG_MSG_READ_ATTRIBUTE_FAILED, "Couldn't read "
- "extended attribute for the file %s", path);
- if (errno == ENOENT)
- errno = ENODATA;
- ret = -1;
- }
- GF_FREE (mapped_path);
- return ret;
+ close(attrfd);
+ } else {
+ if (errno != ENOENT)
+ gf_msg("libglusterfs", GF_LOG_INFO, errno,
+ LG_MSG_READ_ATTRIBUTE_FAILED,
+ "Couldn't read "
+ "extended attribute for the file %s",
+ path);
+ if (errno == ENOENT)
+ errno = ENODATA;
+ ret = -1;
+ }
+ GF_FREE(mapped_path);
+ return ret;
}
-
-char* strsep(char** str, const char* delims)
+char *
+strsep(char **str, const char *delims)
{
- char* token;
-
- if (*str==NULL) {
- /* No more tokens */
- return NULL;
+ char *token;
+
+ if (*str == NULL) {
+ /* No more tokens */
+ return NULL;
+ }
+
+ token = *str;
+ while (**str != '\0') {
+ if (strchr(delims, **str) != NULL) {
+ **str = '\0';
+ (*str)++;
+ return token;
}
-
- token=*str;
- while (**str!='\0') {
- if (strchr(delims,**str)!=NULL) {
- **str='\0';
- (*str)++;
- return token;
- }
- (*str)++;
- }
- /* There is no other token */
- *str=NULL;
- return token;
+ (*str)++;
+ }
+ /* There is no other token */
+ *str = NULL;
+ return token;
}
/* Code comes from libiberty */
int
-vasprintf (char **result, const char *format, va_list args)
+vasprintf(char **result, const char *format, va_list args)
{
- return gf_vasprintf(result, format, args);
+ return gf_vasprintf(result, format, args);
}
int
-asprintf (char **buf, const char *fmt, ...)
+asprintf(char **buf, const char *fmt, ...)
{
- int status;
- va_list ap;
+ int status;
+ va_list ap;
- va_start (ap, fmt);
- status = vasprintf (buf, fmt, ap);
- va_end (ap);
- return status;
+ va_start(ap, fmt);
+ status = vasprintf(buf, fmt, ap);
+ va_end(ap);
+ return status;
}
-int solaris_unlink (const char *path)
+int
+solaris_unlink(const char *path)
{
- char *mapped_path = NULL;
- struct stat stbuf = {0, };
- int ret = -1;
-
- ret = solaris_xattr_resolve_path (path, &mapped_path);
-
-
- if (!ret && mapped_path) {
- if (lstat(path, &stbuf)) {
- gf_msg (THIS->name, GF_LOG_WARNING, errno,
- LG_MSG_FILE_OP_FAILED, "Stat failed on "
- "mapped file %s", mapped_path);
- goto out;
- }
- if (stbuf.st_nlink == 1) {
- if(remove (mapped_path))
- gf_msg (THIS->name, GF_LOG_WARNING, errno,
- LG_MSG_FILE_OP_FAILED, "Failed to "
- "remove mapped file %s", mapped_path);
- }
-
+ char *mapped_path = NULL;
+ struct stat stbuf = {
+ 0,
+ };
+ int ret = -1;
+
+ ret = solaris_xattr_resolve_path(path, &mapped_path);
+
+ if (!ret && mapped_path) {
+ if (lstat(path, &stbuf)) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Stat failed on "
+ "mapped file %s",
+ mapped_path);
+ goto out;
}
+ if (stbuf.st_nlink == 1) {
+ if (remove(mapped_path))
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to "
+ "remove mapped file %s",
+ mapped_path);
+ }
+ }
out:
- GF_FREE (mapped_path);
+ GF_FREE(mapped_path);
- return unlink (path);
+ return unlink(path);
}
int
-solaris_rename (const char *old_path, const char *new_path)
+solaris_rename(const char *old_path, const char *new_path)
{
- char *mapped_path = NULL;
- int ret = -1;
-
- ret = solaris_xattr_resolve_path (new_path, &mapped_path);
+ char *mapped_path = NULL;
+ int ret = -1;
+ ret = solaris_xattr_resolve_path(new_path, &mapped_path);
- if (!ret && mapped_path) {
- if (!remove (mapped_path))
- gf_msg (THIS->name, GF_LOG_WARNING, errno,
- LG_MSG_FILE_OP_FAILED, "Failed to remove "
- "mapped file %s.", mapped_path);
- GF_FREE (mapped_path);
- }
-
- return rename(old_path, new_path);
+ if (!ret && mapped_path) {
+ if (!remove(mapped_path))
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to remove "
+ "mapped file %s.",
+ mapped_path);
+ GF_FREE(mapped_path);
+ }
+ return rename(old_path, new_path);
}
char *
-mkdtemp (char *tempstring)
+mkdtemp(char *tempstring)
{
- char *new_string = NULL;
- int ret = 0;
+ char *new_string = NULL;
+ int ret = 0;
- new_string = mkstemp (tempstring);
- if (!new_string)
- goto out;
+ new_string = mkstemp(tempstring);
+ if (!new_string)
+ goto out;
- ret = mkdir (new_string, 0700);
- if (ret < 0)
- new_string = NULL;
+ ret = mkdir(new_string, 0700);
+ if (ret < 0)
+ new_string = NULL;
out:
- return new_string;
+ return new_string;
}
#endif /* GF_SOLARIS_HOST_OS */
+#ifdef GF_BSD_HOST_OS
+void
+gf_extattr_list_reshape(char *bsd_list, ssize_t size)
+{
+ /*
+ * the format of bsd_list is
+ * <attr_len>attr<attr_len>attr...
+ * we try to reformat it as Linux's
+ * attr<\0>attr<\0>...
+ * */
+ if (NULL == bsd_list || size <= 0)
+ return;
+
+ size_t i = 0, j;
+
+ while (i < size) {
+ size_t attr_len = bsd_list[i];
+
+ for (j = i; j < i + attr_len; ++j)
+ bsd_list[j] = bsd_list[j + 1];
+ bsd_list[j] = '\0';
+
+ i += attr_len + 1;
+ gf_msg_debug("syscall", 0, "syscall debug: %lu", attr_len);
+ }
+}
+#endif /* GF_BSD_HOST_OS */
+
#ifndef HAVE_STRNLEN
size_t
strnlen(const char *string, size_t maxlen)
{
- int len = 0;
- while ((len < maxlen) && string[len])
- len++;
- return len;
+ int len = 0;
+ while ((len < maxlen) && string[len])
+ len++;
+ return len;
}
#endif /* STRNLEN */
int
-gf_umount_lazy (char *xlname, char *path, int rmdir_flag)
+gf_umount_lazy(char *xlname, char *path, int rmdir_flag)
{
- int ret = -1;
- runner_t runner = {0,};
+ int ret = -1;
+ runner_t runner = {
+ 0,
+ };
- runinit (&runner);
+ runinit(&runner);
#ifdef GF_LINUX_HOST_OS
- runner_add_args (&runner, _PATH_UMOUNT, "-l", path, NULL);
+ runner_add_args(&runner, _PATH_UMOUNT, "-l", path, NULL);
#else
- if (rmdir_flag)
- runner_add_args (&runner, SBIN_DIR "/umountd",
- "-r", path, NULL);
- else
- runner_add_args (&runner, SBIN_DIR "/umountd",
- path, NULL);
+ if (rmdir_flag)
+ runner_add_args(&runner, SBIN_DIR "/umountd", "-r", path, NULL);
+ else
+ runner_add_args(&runner, SBIN_DIR "/umountd", path, NULL);
#endif
- ret = runner_run (&runner);
- if (ret) {
- gf_msg (xlname, GF_LOG_ERROR, errno, LG_MSG_UNMOUNT_FAILED,
- "Lazy unmount of %s", path);
- }
+ ret = runner_run(&runner);
+ if (ret) {
+ gf_msg(xlname, GF_LOG_ERROR, errno, LG_MSG_UNMOUNT_FAILED,
+ "Lazy unmount of %s", path);
+ }
#ifdef GF_LINUX_HOST_OS
- if (!ret && rmdir_flag) {
- ret = rmdir (path);
- if (ret)
- gf_msg (xlname, GF_LOG_WARNING, errno,
- LG_MSG_DIR_OP_FAILED, "rmdir %s", path);
- }
+ if (!ret && rmdir_flag) {
+ ret = sys_rmdir(path);
+ if (ret)
+ gf_msg(xlname, GF_LOG_WARNING, errno, LG_MSG_DIR_OP_FAILED,
+ "rmdir %s", path);
+ }
#endif
- return ret;
+ return ret;
}
diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h
deleted file mode 100644
index 458a751c2f4..00000000000
--- a/libglusterfs/src/compat.h
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- 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__
-#define __COMPAT_H__
-
-#include <stdint.h>
-#include "dict.h"
-
-#ifndef LLONG_MAX
-#define LLONG_MAX __LONG_LONG_MAX__ /* compat with old gcc */
-#endif /* LLONG_MAX */
-
-
-#ifdef GF_LINUX_HOST_OS
-
-#define UNIX_PATH_MAX 108
-
-#include <sys/un.h>
-#include <linux/limits.h>
-#include <sys/xattr.h>
-#include <linux/xattr.h>
-#include <endian.h>
-#ifdef HAVE_LINUX_FALLOC_H
-#include <linux/falloc.h>
-#endif
-
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#endif
-
-#ifndef _PATH_UMOUNT
-#define _PATH_UMOUNT "/bin/umount"
-#endif
-#endif /* GF_LINUX_HOST_OS */
-
-#ifdef HAVE_XATTR_H
-#include <sys/xattr.h>
-#endif
-
-/*
- * Define the fallocate flags in case we do not have the header. This also
- * accounts for older systems that do not define FALLOC_FL_PUNCH_HOLE.
- */
-
-#ifndef FALLOC_FL_KEEP_SIZE
-#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */
-#endif
-#ifndef FALLOC_FL_PUNCH_HOLE
-#define FALLOC_FL_PUNCH_HOLE 0x02 /* de-allocates range */
-#endif
-
-
-#ifndef HAVE_LLISTXATTR
-
-/* This part is valid only incase of old glibc which doesn't support
- * 'llistxattr()' system calls.
- */
-
-#define lremovexattr(path,key) removexattr(path,key)
-#define llistxattr(path,key,size) listxattr(path,key,size)
-#define lgetxattr(path, key, value, size) getxattr(path,key,value,size)
-#define lsetxattr(path,key,value,size,flags) setxattr(path,key,value,size,flags)
-
-#endif /* HAVE_LLISTXATTR */
-
-
-#ifdef GF_DARWIN_HOST_OS
-#include <machine/endian.h>
-#include <libkern/OSByteOrder.h>
-
-#define htobe16(x) OSSwapHostToBigInt16(x)
-#define htole16(x) OSSwapHostToLittleInt16(x)
-#define be16toh(x) OSSwapBigToHostInt16(x)
-#define le16toh(x) OSSwapLittleToHostInt16(x)
-
-#define htobe32(x) OSSwapHostToBigInt32(x)
-#define htole32(x) OSSwapHostToLittleInt32(x)
-#define be32toh(x) OSSwapBigToHostInt32(x)
-#define le32toh(x) OSSwapLittleToHostInt32(x)
-
-#define htobe64(x) OSSwapHostToBigInt64(x)
-#define htole64(x) OSSwapHostToLittleInt64(x)
-#define be64toh(x) OSSwapBigToHostInt64(x)
-#define le64toh(x) OSSwapLittleToHostInt64(x)
-
-#endif
-
-
-#ifdef GF_BSD_HOST_OS
-/* In case of FreeBSD and NetBSD */
-
-#define UNIX_PATH_MAX 104
-#include <sys/types.h>
-
-#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
-#define sighandler_t sig_t
-#endif
-
-#ifdef __FreeBSD__
-#undef ino_t
-#define ino_t uint64_t
-#endif /* __FreeBSD__ */
-
-#ifndef ino64_t
-#define ino64_t ino_t
-#endif
-
-#ifndef EUCLEAN
-#define EUCLEAN 0
-#endif
-
-#include <netinet/in.h>
-#ifndef s6_addr16
-#define s6_addr16 __u6_addr.__u6_addr16
-#endif
-#ifndef s6_addr32
-#define s6_addr32 __u6_addr.__u6_addr32
-#endif
-
-/* Posix dictates NAME_MAX to be used */
-# ifndef NAME_MAX
-# ifdef MAXNAMLEN
-# define NAME_MAX MAXNAMLEN
-# else
-# define NAME_MAX 255
-# endif
-# endif
-
-#define F_GETLK64 F_GETLK
-#define F_SETLK64 F_SETLK
-#define F_SETLKW64 F_SETLKW
-#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */
-#define FALLOC_FL_PUNCH_HOLE 0x02 /* de-allocates range */
-
-#ifndef _PATH_UMOUNT
- #define _PATH_UMOUNT "/sbin/umount"
-#endif
-#endif /* GF_BSD_HOST_OS */
-
-#ifdef GF_DARWIN_HOST_OS
-#include <machine/endian.h>
-#include <libkern/OSByteOrder.h>
-
-#define htobe16(x) OSSwapHostToBigInt16(x)
-#define htole16(x) OSSwapHostToLittleInt16(x)
-#define be16toh(x) OSSwapBigToHostInt16(x)
-#define le16toh(x) OSSwapLittleToHostInt16(x)
-
-#define htobe32(x) OSSwapHostToBigInt32(x)
-#define htole32(x) OSSwapHostToLittleInt32(x)
-#define be32toh(x) OSSwapBigToHostInt32(x)
-#define le32toh(x) OSSwapLittleToHostInt32(x)
-
-#define htobe64(x) OSSwapHostToBigInt64(x)
-#define htole64(x) OSSwapHostToLittleInt64(x)
-#define be64toh(x) OSSwapBigToHostInt64(x)
-#define le64toh(x) OSSwapLittleToHostInt64(x)
-
-#define UNIX_PATH_MAX 104
-/* OSX Yosemite now has this defined */
-#ifndef AT_SYMLINK_NOFOLLOW
-#define AT_SYMLINK_NOFOLLOW 0x100
-#endif
-#include <sys/types.h>
-
-#include <sys/un.h>
-#include <sys/xattr.h>
-#include <limits.h>
-
-#include <libgen.h>
-
-
-#if __DARWIN_64_BIT_INO_T == 0
-# error '64 bit ino_t is must for GlusterFS to work, Compile with "CFLAGS=-D__DARWIN_64_BIT_INO_T"'
-#endif /* __DARWIN_64_BIT_INO_T */
-
-
-#if __DARWIN_64_BIT_INO_T == 0
-# error '64 bit ino_t is must for GlusterFS to work, Compile with "CFLAGS=-D__DARWIN_64_BIT_INO_T"'
-#endif /* __DARWIN_64_BIT_INO_T */
-
-#ifndef sighandler_t
-#define sighandler_t sig_t
-#endif
-
-#ifndef EUCLEAN
-#define EUCLEAN 0
-#endif
-
-#include <netinet/in.h>
-#ifndef s6_addr16
-#define s6_addr16 __u6_addr.__u6_addr16
-#endif
-#ifndef s6_addr32
-#define s6_addr32 __u6_addr.__u6_addr32
-#endif
-
-/* Posix dictates NAME_MAX to be used */
-# ifndef NAME_MAX
-# ifdef MAXNAMLEN
-# define NAME_MAX MAXNAMLEN
-# else
-# define NAME_MAX 255
-# endif
-# endif
-
-#define F_GETLK64 F_GETLK
-#define F_SETLK64 F_SETLK
-#define F_SETLKW64 F_SETLKW
-
-#ifndef FTW_CONTINUE
- #define FTW_CONTINUE 0
-#endif
-
-int32_t gf_darwin_compat_listxattr (int len, dict_t *dict, int size);
-int32_t gf_darwin_compat_getxattr (const char *key, dict_t *dict);
-int32_t gf_darwin_compat_setxattr (dict_t *dict);
-
-#ifndef _PATH_UMOUNT
- #define _PATH_UMOUNT "/sbin/umount"
-#endif
-#endif /* GF_DARWIN_HOST_OS */
-
-#ifdef GF_SOLARIS_HOST_OS
-
-#define UNIX_PATH_MAX 108
-#define EUCLEAN 117
-
-#include <sys/un.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/fcntl.h>
-#include <libgen.h>
-#include <sys/mkdev.h>
-
-#ifndef lchmod
-#define lchmod chmod
-#endif
-
-#define lgetxattr(path, key, value, size) solaris_getxattr(path,key,value,size)
-enum {
- ATTR_CREATE = 1,
-#define XATTR_CREATE ATTR_CREATE
- ATTR_REPLACE = 2
-#define XATTR_REPLACE ATTR_REPLACE
-};
-
-/* This patch is not present in Solaris 10 and before */
-#ifndef dirfd
-#define dirfd(dirp) ((dirp)->dd_fd)
-#endif
-
-/* Posix dictates NAME_MAX to be used */
-# ifndef NAME_MAX
-# ifdef MAXNAMLEN
-# define NAME_MAX MAXNAMLEN
-# else
-# define NAME_MAX 255
-# endif
-# endif
-
-#include <netinet/in.h>
-#ifndef s6_addr16
-#define S6_ADDR16(x) ((uint16_t*) ((char*)&(x).s6_addr))
-#endif
-#ifndef s6_addr32
-#define s6_addr32 _S6_un._S6_u32
-#endif
-
-#define lutimes(filename,times) utimes(filename,times)
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-enum {
- DT_UNKNOWN = 0,
-# define DT_UNKNOWN DT_UNKNOWN
- DT_FIFO = 1,
-# define DT_FIFO DT_FIFO
- DT_CHR = 2,
-# define DT_CHR DT_CHR
- DT_DIR = 4,
-# define DT_DIR DT_DIR
- DT_BLK = 6,
-# define DT_BLK DT_BLK
- DT_REG = 8,
-# define DT_REG DT_REG
- DT_LNK = 10,
-# define DT_LNK DT_LNK
- DT_SOCK = 12,
-# define DT_SOCK DT_SOCK
- DT_WHT = 14
-# define DT_WHT DT_WHT
-};
-
-#ifndef _PATH_MOUNTED
- #define _PATH_MOUNTED "/etc/mtab"
-#endif
-#ifndef _PATH_UMOUNT
- #define _PATH_UMOUNT "/sbin/umount"
-#endif
-
-#ifndef O_ASYNC
- #ifdef FASYNC
- #define O_ASYNC FASYNC
- #else
- #define O_ASYNC 0
- #endif
-#endif
-
-#ifndef FTW_CONTINUE
- #define FTW_CONTINUE 0
-#endif
-
-int asprintf(char **string_ptr, const char *format, ...);
-
-int vasprintf (char **result, const char *format, va_list args);
-char* strsep(char** str, const char* delims);
-int solaris_listxattr(const char *path, char *list, size_t size);
-int solaris_removexattr(const char *path, const char* key);
-int solaris_getxattr(const char *path, const char* key,
- char *value, size_t size);
-int solaris_setxattr(const char *path, const char* key, const char *value,
- size_t size, int flags);
-int solaris_fgetxattr(int fd, const char* key,
- char *value, size_t size);
-int solaris_fsetxattr(int fd, const char* key, const char *value,
- size_t size, int flags);
-int solaris_flistxattr(int fd, char *list, size_t size);
-
-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);
-
-#endif /* GF_SOLARIS_HOST_OS */
-
-#ifndef HAVE_ARGP
-#include "argp.h"
-#else
-#include <argp.h>
-#endif /* HAVE_ARGP */
-
-#ifndef HAVE_STRNLEN
-size_t strnlen(const char *string, size_t maxlen);
-#endif /* STRNLEN */
-
-#ifndef strdupa
-#define strdupa(s) \
- (__extension__ \
- ({ \
- __const char *__old = (s); \
- size_t __len = strlen (__old) + 1; \
- char *__new = (char *) __builtin_alloca (__len); \
- (char *) memcpy (__new, __old, __len); \
- }))
-#endif
-
-#define GF_DIR_ALIGN(x) (((x) + sizeof (uint64_t) - 1) & ~(sizeof (uint64_t) - 1))
-
-#include <sys/types.h>
-#include <dirent.h>
-
-static inline int32_t
-dirent_size (struct dirent *entry)
-{
- int32_t size = -1;
-
-#ifdef GF_BSD_HOST_OS
- size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
-#endif
-#ifdef GF_DARWIN_HOST_OS
- size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_namlen);
-#endif
-#ifdef GF_LINUX_HOST_OS
- size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
-#endif
-#ifdef GF_SOLARIS_HOST_OS
- size = GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + entry->d_reclen);
-#endif
- 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 */
-#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec)
-#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec)
-#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.tv_nsec)
-#define ST_ATIM_NSEC_SET(stbuf, val) ((stbuf)->st_atim.tv_nsec = (val))
-#define ST_MTIM_NSEC_SET(stbuf, val) ((stbuf)->st_mtim.tv_nsec = (val))
-#define ST_CTIM_NSEC_SET(stbuf, val) ((stbuf)->st_ctim.tv_nsec = (val))
-#elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC)
-/* FreeBSD, NetBSD */
-#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec)
-#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec)
-#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.tv_nsec)
-#define ST_ATIM_NSEC_SET(stbuf, val) ((stbuf)->st_atimespec.tv_nsec = (val))
-#define ST_MTIM_NSEC_SET(stbuf, val) ((stbuf)->st_mtimespec.tv_nsec = (val))
-#define ST_CTIM_NSEC_SET(stbuf, val) ((stbuf)->st_ctimespec.tv_nsec = (val))
-#else
-#define ST_ATIM_NSEC(stbuf) (0)
-#define ST_CTIM_NSEC(stbuf) (0)
-#define ST_MTIM_NSEC(stbuf) (0)
-#define ST_ATIM_NSEC_SET(stbuf, val) do { } while (0);
-#define ST_MTIM_NSEC_SET(stbuf, val) do { } while (0);
-#define ST_CTIM_NSEC_SET(stbuf, val) do { } while (0);
-#endif
-
-#ifndef IXDR_GET_LONG
-#define IXDR_GET_LONG(buf) ((long)IXDR_GET_U_INT32(buf))
-#endif
-
-#ifndef IXDR_PUT_LONG
-#define IXDR_PUT_LONG(buf, v) ((long)IXDR_PUT_INT32(buf, (long)(v)))
-#endif
-
-#ifndef IXDR_GET_U_LONG
-#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf))
-#endif
-
-#ifndef IXDR_PUT_U_LONG
-#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
-
-int gf_umount_lazy(char *xlname, char *path, int rmdir);
-
-#endif /* __COMPAT_H__ */
diff --git a/libglusterfs/src/ctr-messages.h b/libglusterfs/src/ctr-messages.h
deleted file mode 100644
index 27de07a0d8e..00000000000
--- a/libglusterfs/src/ctr-messages.h
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- Copyright (c) 2013 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 _component_MESSAGES_H_
-#define _component_MESSAGES_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glfs-message-id.h"
-
-/* NOTE: Rules for message additions
- * 1) Each instance of a message is _better_ left with a unique message ID, even
- * if the message format is the same. Reasoning is that, if the message
- * format needs to change in one instance, the other instances are not
- * impacted or the new change does not change the ID of the instance being
- * modified.
- * 2) Addition of a message,
- * - Should increment the GLFS_NUM_MESSAGES
- * - Append to the list of messages defined, towards the end
- * - Retain macro naming as glfs_msg_X (for redability across developers)
- * NOTE: Rules for message format modifications
- * 3) Check acorss the code if the message ID macro in question is reused
- * anywhere. If reused then then the modifications should ensure correctness
- * everywhere, or needs a new message ID as (1) above was not adhered to. If
- * not used anywhere, proceed with the required modification.
- * NOTE: Rules for message deletion
- * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
- * anywhere, then can be deleted, but will leave a hole by design, as
- * addition rules specify modification to the end of the list and not filling
- * holes.
- */
-
-#define GLFS_COMP_BASE GLFS_MSGID_COMP_CTR
-#define GLFS_NUM_MESSAGES 56
-#define GLFS_MSGID_END (GLFS_COMP_BASE + GLFS_NUM_MESSAGES + 1)
-/* Messaged with message IDs */
-#define glfs_msg_start_x GLFS_COMP_BASE, "Invalid: Start of messages"
-/*------------*/
-
-#define CTR_MSG_CREATE_CTR_LOCAL_ERROR_WIND (GLFS_COMP_BASE + 1)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_FILL_CTR_LOCAL_ERROR_UNWIND (GLFS_COMP_BASE + 2)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_FILL_CTR_LOCAL_ERROR_WIND (GLFS_COMP_BASE + 3)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_LINK_WIND_FAILED (GLFS_COMP_BASE + 4)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_WRITEV_WIND_FAILED (GLFS_COMP_BASE + 5)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_WRITEV_UNWIND_FAILED (GLFS_COMP_BASE + 6)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_SETATTR_WIND_FAILED (GLFS_COMP_BASE + 7)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_SETATTR_UNWIND_FAILED (GLFS_COMP_BASE + 8)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_FREMOVEXATTR_UNWIND_FAILED (GLFS_COMP_BASE + 9)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_FREMOVEXATTR_WIND_FAILED (GLFS_COMP_BASE + 10)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_REMOVEXATTR_WIND_FAILED (GLFS_COMP_BASE + 11)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_REMOVEXATTR_UNWIND_FAILED (GLFS_COMP_BASE + 12)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_TRUNCATE_WIND_FAILED (GLFS_COMP_BASE + 13)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_TRUNCATE_UNWIND_FAILED (GLFS_COMP_BASE + 14)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_FTRUNCATE_UNWIND_FAILED (GLFS_COMP_BASE + 15)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_FTRUNCATE_WIND_FAILED (GLFS_COMP_BASE + 16)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_RENAME_WIND_FAILED (GLFS_COMP_BASE + 17)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_RENAME_UNWIND_FAILED (GLFS_COMP_BASE + 18)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_ACCESS_CTR_INODE_CONTEXT_FAILED (GLFS_COMP_BASE + 19)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_ADD_HARDLINK_FAILED (GLFS_COMP_BASE + 20)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_DELETE_HARDLINK_FAILED (GLFS_COMP_BASE + 21)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_UPDATE_HARDLINK_FAILED (GLFS_COMP_BASE + 22)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_GET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED (GLFS_COMP_BASE + 23)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_SET_CTR_RESPONSE_LINK_COUNT_XDATA_FAILED (GLFS_COMP_BASE + 24)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_UNLINK_UNWIND_FAILED (GLFS_COMP_BASE + 25)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_UNLINK_WIND_FAILED (GLFS_COMP_BASE + 26)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_XDATA_NULL (GLFS_COMP_BASE + 27)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_FSYNC_WIND_FAILED (GLFS_COMP_BASE + 28)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_FSYNC_UNWIND_FAILED (GLFS_COMP_BASE + 29)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_MKNOD_UNWIND_FAILED (GLFS_COMP_BASE + 30)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_MKNOD_WIND_FAILED (GLFS_COMP_BASE + 31)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_CREATE_WIND_FAILED (GLFS_COMP_BASE + 32)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_CREATE_UNWIND_FAILED (GLFS_COMP_BASE + 33)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_RECORD_WIND_FAILED (GLFS_COMP_BASE + 34)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INSERT_READV_WIND_FAILED (GLFS_COMP_BASE + 35)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_GET_GFID_FROM_DICT_FAILED (GLFS_COMP_BASE + 36)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_SET (GLFS_COMP_BASE + 37)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_FATAL_ERROR (GLFS_COMP_BASE + 38)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_DANGLING_VOLUME (GLFS_COMP_BASE + 39)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_CALLOC_FAILED (GLFS_COMP_BASE + 40)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_EXTRACT_CTR_XLATOR_OPTIONS_FAILED (GLFS_COMP_BASE + 41)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INIT_DB_PARAMS_FAILED (GLFS_COMP_BASE + 42)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_CREATE_LOCAL_MEMORY_POOL_FAILED (GLFS_COMP_BASE + 43)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_MEM_ACC_INIT_FAILED (GLFS_COMP_BASE + 44)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_CLOSE_DB_CONN_FAILED (GLFS_COMP_BASE + 45)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_FILL_UNWIND_TIME_REC_ERROR (GLFS_COMP_BASE + 46)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_WRONG_FOP_PATH (GLFS_COMP_BASE + 47)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_CONSTRUCT_DB_PATH_FAILED (GLFS_COMP_BASE + 48)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_SET_VALUE_TO_SQL_PARAM_FAILED (GLFS_COMP_BASE + 49)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_XLATOR_DISABLED (GLFS_COMP_BASE + 50)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_HARDLINK_MISSING_IN_LIST (GLFS_COMP_BASE + 51)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_ADD_HARDLINK_TO_LIST_FAILED (GLFS_COMP_BASE + 52)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_INIT_LOCK_FAILED (GLFS_COMP_BASE + 53)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_COPY_FAILED (GLFS_COMP_BASE + 54)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_EXTRACT_DB_PARAM_OPTIONS_FAILED (GLFS_COMP_BASE + 55)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define CTR_MSG_ADD_HARDLINK_TO_CTR_INODE_CONTEXT_FAILED (GLFS_COMP_BASE + 56)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-/*------------*/
-#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
-
-#endif /* !_component_MESSAGES_H_ */
diff --git a/libglusterfs/src/ctx.c b/libglusterfs/src/ctx.c
index c70d97bc5d4..3d890b04ec9 100644
--- a/libglusterfs/src/ctx.c
+++ b/libglusterfs/src/ctx.c
@@ -9,39 +9,89 @@
*/
#include <pthread.h>
-#include "globals.h"
-#include "glusterfs.h"
+#include "glusterfs/globals.h"
+#include "glusterfs/glusterfs.h"
+#include "timer-wheel.h"
glusterfs_ctx_t *
-glusterfs_ctx_new ()
+glusterfs_ctx_new()
{
- int ret = 0;
- glusterfs_ctx_t *ctx = NULL;
-
- /* no GF_CALLOC here, gf_acct_mem_set_enable is not
- yet decided at this point */
- ctx = calloc (1, sizeof (*ctx));
- if (!ctx) {
- ret = -1;
- goto out;
- }
+ glusterfs_ctx_t *ctx = NULL;
+
+ /* no GF_CALLOC here, gf_acct_mem_set_enable is not
+ yet decided at this point */
+ ctx = CALLOC(1, sizeof(*ctx));
+ if (!ctx) {
+ goto out;
+ }
+
+ ctx->mem_acct_enable = gf_global_mem_acct_enable_get();
+
+ INIT_LIST_HEAD(&ctx->graphs);
+ INIT_LIST_HEAD(&ctx->mempool_list);
+ INIT_LIST_HEAD(&ctx->volfile_list);
- ctx->mem_acct_enable = gf_global_mem_acct_enable_get();
+ ctx->daemon_pipe[0] = -1;
+ ctx->daemon_pipe[1] = -1;
- INIT_LIST_HEAD (&ctx->graphs);
- INIT_LIST_HEAD (&ctx->mempool_list);
+ ctx->log.loglevel = DEFAULT_LOG_LEVEL;
- ctx->daemon_pipe[0] = -1;
- ctx->daemon_pipe[1] = -1;
+#if defined(RUN_WITH_MEMCHECK)
+ ctx->cmd_args.vgtool = _gf_memcheck;
+#elif defined(RUN_WITH_DRD)
+ ctx->cmd_args.vgtool = _gf_drd;
+#else
+ ctx->cmd_args.vgtool = _gf_none;
+#endif
- ret = pthread_mutex_init (&ctx->lock, NULL);
- if (ret) {
- free (ctx);
- ctx = NULL;
- }
+ /* lock is never destroyed! */
+ if (LOCK_INIT(&ctx->lock)) {
+ free(ctx);
+ ctx = NULL;
+ goto out;
+ }
+ GF_ATOMIC_INIT(ctx->stats.max_dict_pairs, 0);
+ GF_ATOMIC_INIT(ctx->stats.total_pairs_used, 0);
+ GF_ATOMIC_INIT(ctx->stats.total_dicts_used, 0);
out:
- return ctx;
+ return ctx;
+}
+
+static void
+glusterfs_ctx_tw_destroy(struct gf_ctx_tw *ctx_tw)
+{
+ if (ctx_tw->timer_wheel)
+ gf_tw_cleanup_timers(ctx_tw->timer_wheel);
+
+ GF_FREE(ctx_tw);
}
+struct tvec_base *
+glusterfs_ctx_tw_get(glusterfs_ctx_t *ctx)
+{
+ struct gf_ctx_tw *ctx_tw = NULL;
+
+ LOCK(&ctx->lock);
+ {
+ if (ctx->tw) {
+ ctx_tw = GF_REF_GET(ctx->tw);
+ } else {
+ ctx_tw = GF_CALLOC(1, sizeof(struct gf_ctx_tw),
+ gf_common_mt_tw_ctx);
+ ctx_tw->timer_wheel = gf_tw_init_timers();
+ GF_REF_INIT(ctx_tw, glusterfs_ctx_tw_destroy);
+ ctx->tw = ctx_tw;
+ }
+ }
+ UNLOCK(&ctx->lock);
+
+ return ctx_tw->timer_wheel;
+}
+
+void
+glusterfs_ctx_tw_put(glusterfs_ctx_t *ctx)
+{
+ GF_REF_PUT(ctx->tw);
+}
diff --git a/libglusterfs/src/daemon.c b/libglusterfs/src/daemon.c
index 348e3ad4083..0a3e5438325 100644
--- a/libglusterfs/src/daemon.c
+++ b/libglusterfs/src/daemon.c
@@ -8,59 +8,58 @@
cases as published by the Free Software Foundation.
*/
-#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
-#include "daemon.h"
+#include "glusterfs/daemon.h"
int
-os_daemon_return (int nochdir, int noclose)
+os_daemon_return(int nochdir, int noclose)
{
- pid_t pid = -1;
- int ret = -1;
- FILE *ptr = NULL;
+ pid_t pid = -1;
+ int ret = -1;
+ FILE *ptr = NULL;
- ret = fork();
- if (ret)
- return ret;
+ ret = fork();
+ if (ret)
+ return ret;
- pid = setsid();
+ pid = setsid();
- if (pid == -1) {
- ret = -1;
- goto out;
- }
+ if (pid == -1) {
+ ret = -1;
+ goto out;
+ }
- if (!nochdir)
- ret = chdir("/");
+ if (!nochdir)
+ ret = chdir("/");
- if (!noclose) {
- ptr = freopen (DEVNULLPATH, "r", stdin);
- if (!ptr)
- goto out;
+ if (!noclose) {
+ ptr = freopen(DEVNULLPATH, "r", stdin);
+ if (!ptr)
+ goto out;
- ptr = freopen (DEVNULLPATH, "w", stdout);
- if (!ptr)
- goto out;
+ ptr = freopen(DEVNULLPATH, "w", stdout);
+ if (!ptr)
+ goto out;
- ptr = freopen (DEVNULLPATH, "w", stderr);
- if (!ptr)
- goto out;
- }
+ ptr = freopen(DEVNULLPATH, "w", stderr);
+ if (!ptr)
+ goto out;
+ }
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
-os_daemon (int nochdir, int noclose)
+os_daemon(int nochdir, int noclose)
{
- int ret = -1;
+ int ret = -1;
- ret = os_daemon_return (nochdir, noclose);
- if (ret <= 0)
- return ret;
+ ret = os_daemon_return(nochdir, noclose);
+ if (ret <= 0)
+ return ret;
- _exit (0);
+ _exit(0);
}
diff --git a/libglusterfs/src/default-args.c b/libglusterfs/src/default-args.c
new file mode 100644
index 00000000000..a0ba1cfb299
--- /dev/null
+++ b/libglusterfs/src/default-args.c
@@ -0,0 +1,1651 @@
+/*
+ Copyright (c) 2008-2015 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 "glusterfs/defaults.h"
+
+int
+args_lookup_store(default_args_t *args, loc_t *loc, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_lookup_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata, struct iatt *postparent)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_stat_store(default_args_t *args, loc_t *loc, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_stat_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *buf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->stat = *buf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fstat_store(default_args_t *args, fd_t *fd, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fstat_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *buf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (buf)
+ args->stat = *buf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_truncate_store(default_args_t *args, loc_t *loc, off_t off, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->offset = off;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_truncate_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (postbuf)
+ args->poststat = *postbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_ftruncate_store(default_args_t *args, fd_t *fd, off_t off, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->offset = off;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_ftruncate_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (postbuf)
+ args->poststat = *postbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_access_store(default_args_t *args, loc_t *loc, int32_t mask, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mask = mask;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_access_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readlink_store(default_args_t *args, loc_t *loc, size_t size,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->size = size;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readlink_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, const char *path, struct iatt *stbuf,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (path)
+ args->buf = gf_strdup(path);
+ if (stbuf)
+ args->stat = *stbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_mknod_store(default_args_t *args, loc_t *loc, mode_t mode, dev_t rdev,
+ mode_t umask, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mode = mode;
+ args->rdev = rdev;
+ args->umask = umask;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_mknod_cbk_store(default_args_cbk_t *args, int op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_mkdir_store(default_args_t *args, loc_t *loc, mode_t mode, mode_t umask,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mode = mode;
+ args->umask = umask;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_mkdir_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_unlink_store(default_args_t *args, loc_t *loc, int xflag, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->xflag = xflag;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_unlink_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_rmdir_store(default_args_t *args, loc_t *loc, int flags, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->flags = flags;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_rmdir_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_symlink_store(default_args_t *args, const char *linkname, loc_t *loc,
+ mode_t umask, dict_t *xdata)
+{
+ args->linkname = gf_strdup(linkname);
+ args->umask = umask;
+ loc_copy(&args->loc, loc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_symlink_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_rename_store(default_args_t *args, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, oldloc);
+ loc_copy(&args->loc2, newloc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_rename_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (buf)
+ args->stat = *buf;
+ if (preoldparent)
+ args->preparent = *preoldparent;
+ if (postoldparent)
+ args->postparent = *postoldparent;
+ if (prenewparent)
+ args->preparent2 = *prenewparent;
+ if (postnewparent)
+ args->postparent2 = *postnewparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_link_store(default_args_t *args, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, oldloc);
+ loc_copy(&args->loc2, newloc);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_link_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_create_store(default_args_t *args, loc_t *loc, int32_t flags, mode_t mode,
+ mode_t umask, fd_t *fd, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->flags = flags;
+ args->mode = mode;
+ args->umask = umask;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_create_cbk_store(default_args_cbk_t *args, 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)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (buf)
+ args->stat = *buf;
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_open_store(default_args_t *args, loc_t *loc, int32_t flags, fd_t *fd,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->flags = flags;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_open_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ fd_t *fd, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readv_store(default_args_t *args, fd_t *fd, size_t size, off_t off,
+ uint32_t flags, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->size = size;
+ args->offset = off;
+ args->flags = flags;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readv_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iovec *vector, int32_t count, struct iatt *stbuf,
+ struct iobref *iobref, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0) {
+ args->vector = iov_dup(vector, count);
+ args->count = count;
+ args->stat = *stbuf;
+ args->iobref = iobref_ref(iobref);
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_writev_store(default_args_t *args, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->vector = iov_dup(vector, count);
+ args->count = count;
+ args->offset = off;
+ args->flags = flags;
+ args->iobref = iobref_ref(iobref);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_writev_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0)
+ args->poststat = *postbuf;
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_put_store(default_args_t *args, loc_t *loc, mode_t mode, mode_t umask,
+ uint32_t flags, struct iovec *vector, int32_t count, off_t off,
+ struct iobref *iobref, dict_t *xattr, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mode = mode;
+ args->umask = umask;
+ args->flags = flags;
+ args->vector = iov_dup(vector, count);
+ args->count = count;
+ args->offset = off;
+ args->iobref = iobref_ref(iobref);
+ if (xattr)
+ args->xattr = dict_ref(xattr);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_put_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0)
+ args->stat = *buf;
+ if (inode)
+ args->inode = inode_ref(inode);
+ if (preparent)
+ args->preparent = *preparent;
+ if (postparent)
+ args->postparent = *postparent;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+int
+args_flush_store(default_args_t *args, fd_t *fd, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_flush_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fsync_store(default_args_t *args, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->datasync = datasync;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fsync_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (postbuf)
+ args->poststat = *postbuf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_opendir_store(default_args_t *args, loc_t *loc, fd_t *fd, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_opendir_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, fd_t *fd, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (fd)
+ args->fd = fd_ref(fd);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fsyncdir_store(default_args_t *args, fd_t *fd, int32_t datasync,
+ dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->datasync = datasync;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+int
+args_fsyncdir_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_statfs_store(default_args_t *args, loc_t *loc, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_statfs_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct statvfs *buf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->statvfs = *buf;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_setxattr_store(default_args_t *args, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ /* TODO */
+ if (dict)
+ args->xattr = dict_ref(dict);
+ args->flags = flags;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_setxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_getxattr_store(default_args_t *args, loc_t *loc, const char *name,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+
+ if (name)
+ args->name = gf_strdup(name);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_getxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *dict, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (dict)
+ args->xattr = dict_ref(dict);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fsetxattr_store(default_args_t *args, fd_t *fd, dict_t *dict,
+ int32_t flags, dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+
+ if (dict)
+ args->xattr = dict_ref(dict);
+ args->flags = flags;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fsetxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fgetxattr_store(default_args_t *args, fd_t *fd, const char *name,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+
+ if (name)
+ args->name = gf_strdup(name);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fgetxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *dict, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (dict)
+ args->xattr = dict_ref(dict);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_removexattr_store(default_args_t *args, loc_t *loc, const char *name,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->name = gf_strdup(name);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_removexattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fremovexattr_store(default_args_t *args, fd_t *fd, const char *name,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+ args->name = gf_strdup(name);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fremovexattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_lk_store(default_args_t *args, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->cmd = cmd;
+ args->lock = *lock;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_lk_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct gf_flock *lock, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->lock = *lock;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_inodelk_store(default_args_t *args, const char *volume, loc_t *loc,
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+{
+ if (volume)
+ args->volume = gf_strdup(volume);
+
+ loc_copy(&args->loc, loc);
+ args->cmd = cmd;
+ args->lock = *lock;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_inodelk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_finodelk_store(default_args_t *args, const char *volume, fd_t *fd,
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ if (volume)
+ args->volume = gf_strdup(volume);
+
+ args->cmd = cmd;
+ args->lock = *lock;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_finodelk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_entrylk_store(default_args_t *args, const char *volume, loc_t *loc,
+ const char *name, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
+{
+ if (volume)
+ args->volume = gf_strdup(volume);
+
+ loc_copy(&args->loc, loc);
+
+ args->entrylkcmd = cmd;
+ args->entrylktype = type;
+
+ if (name)
+ args->name = gf_strdup(name);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_entrylk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fentrylk_store(default_args_t *args, const char *volume, fd_t *fd,
+ const char *name, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata)
+{
+ if (volume)
+ args->volume = gf_strdup(volume);
+
+ if (fd)
+ args->fd = fd_ref(fd);
+ args->entrylkcmd = cmd;
+ args->entrylktype = type;
+ if (name)
+ args->name = gf_strdup(name);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fentrylk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_readdirp_store(default_args_t *args, fd_t *fd, size_t size, off_t off,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+ args->size = size;
+ args->offset = off;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_readdirp_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, gf_dirent_t *entries, dict_t *xdata)
+{
+ gf_dirent_t *stub_entry = NULL, *entry = NULL;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret > 0) {
+ list_for_each_entry(entry, &entries->list, list)
+ {
+ stub_entry = gf_dirent_for_name(entry->d_name);
+ if (!stub_entry)
+ goto out;
+ stub_entry->d_off = entry->d_off;
+ stub_entry->d_ino = entry->d_ino;
+ stub_entry->d_stat = entry->d_stat;
+ stub_entry->d_type = entry->d_type;
+ if (entry->inode)
+ stub_entry->inode = inode_ref(entry->inode);
+ if (entry->dict)
+ stub_entry->dict = dict_ref(entry->dict);
+ list_add_tail(&stub_entry->list, &args->entries.list);
+ }
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+out:
+ return 0;
+}
+
+int
+args_readdir_store(default_args_t *args, fd_t *fd, size_t size, off_t off,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+ args->size = size;
+ args->offset = off;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_readdir_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, gf_dirent_t *entries, dict_t *xdata)
+{
+ gf_dirent_t *stub_entry = NULL, *entry = NULL;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret > 0) {
+ list_for_each_entry(entry, &entries->list, list)
+ {
+ stub_entry = gf_dirent_for_name(entry->d_name);
+ if (!stub_entry)
+ goto out;
+ stub_entry->d_off = entry->d_off;
+ stub_entry->d_ino = entry->d_ino;
+ stub_entry->d_type = entry->d_type;
+ list_add_tail(&stub_entry->list, &args->entries.list);
+ }
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+out:
+ return 0;
+}
+
+int
+args_rchecksum_store(default_args_t *args, fd_t *fd, off_t offset, int32_t len,
+ dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+ args->offset = offset;
+ args->size = len;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_rchecksum_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, uint32_t weak_checksum,
+ uint8_t *strong_checksum, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0) {
+ args->weak_checksum = weak_checksum;
+ args->strong_checksum = gf_memdup(strong_checksum,
+ SHA256_DIGEST_LENGTH);
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_xattrop_store(default_args_t *args, loc_t *loc, gf_xattrop_flags_t optype,
+ dict_t *xattr, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+
+ args->optype = optype;
+ args->xattr = dict_ref(xattr);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_xattrop_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xattr, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xattr)
+ args->xattr = dict_ref(xattr);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fxattrop_store(default_args_t *args, fd_t *fd, gf_xattrop_flags_t optype,
+ dict_t *xattr, dict_t *xdata)
+{
+ args->fd = fd_ref(fd);
+
+ args->optype = optype;
+ args->xattr = dict_ref(xattr);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fxattrop_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xattr, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xattr)
+ args->xattr = dict_ref(xattr);
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_setattr_store(default_args_t *args, loc_t *loc, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+
+ if (stbuf)
+ args->stat = *stbuf;
+
+ args->valid = valid;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_setattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fsetattr_store(default_args_t *args, fd_t *fd, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ if (stbuf)
+ args->stat = *stbuf;
+
+ args->valid = valid;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+int
+args_fsetattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_fallocate_store(default_args_t *args, fd_t *fd, int32_t mode, off_t offset,
+ size_t len, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->flags = mode;
+ args->offset = offset;
+ args->size = len;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_fallocate_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_discard_store(default_args_t *args, fd_t *fd, off_t offset, size_t len,
+ dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->offset = offset;
+ args->size = len;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_discard_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_zerofill_store(default_args_t *args, fd_t *fd, off_t offset, off_t len,
+ dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->offset = offset;
+ args->size = len;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_zerofill_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (statpre)
+ args->prestat = *statpre;
+ if (statpost)
+ args->poststat = *statpost;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_ipc_store(default_args_t *args, int32_t op, dict_t *xdata)
+{
+ args->cmd = op;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_ipc_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_seek_store(default_args_t *args, fd_t *fd, off_t offset,
+ gf_seek_what_t what, dict_t *xdata)
+{
+ if (fd)
+ args->fd = fd_ref(fd);
+
+ args->offset = offset;
+ args->what = what;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_seek_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ off_t offset, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ args->offset = offset;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_getactivelk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, lock_migration_info_t *locklist,
+ dict_t *xdata)
+{
+ lock_migration_info_t *stub_entry = NULL, *entry = NULL;
+ int ret = 0;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ /*op_ret needs to carry the number of locks present in the list*/
+ if (op_ret > 0) {
+ list_for_each_entry(entry, &locklist->list, list)
+ {
+ stub_entry = GF_CALLOC(1, sizeof(*stub_entry), gf_common_mt_char);
+ if (!stub_entry) {
+ ret = -1;
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&stub_entry->list);
+ stub_entry->flock = entry->flock;
+
+ stub_entry->lk_flags = entry->lk_flags;
+
+ stub_entry->client_uid = gf_strdup(entry->client_uid);
+ if (!stub_entry->client_uid) {
+ GF_FREE(stub_entry);
+ ret = -1;
+ goto out;
+ }
+
+ list_add_tail(&stub_entry->list, &args->locklist.list);
+ }
+ }
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+out:
+ return ret;
+}
+
+int
+args_setactivelk_store(default_args_t *args, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata)
+{
+ lock_migration_info_t *stub_entry = NULL, *entry = NULL;
+ int ret = 0;
+
+ list_for_each_entry(entry, &locklist->list, list)
+ {
+ stub_entry = GF_CALLOC(1, sizeof(*stub_entry), gf_common_mt_lock_mig);
+ if (!stub_entry) {
+ ret = -1;
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&stub_entry->list);
+ stub_entry->flock = entry->flock;
+
+ stub_entry->lk_flags = entry->lk_flags;
+
+ stub_entry->client_uid = gf_strdup(entry->client_uid);
+ if (!stub_entry->client_uid) {
+ GF_FREE(stub_entry);
+ ret = -1;
+ goto out;
+ }
+
+ list_add_tail(&stub_entry->list, &args->locklist.list);
+ }
+
+ loc_copy(&args->loc, loc);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+out:
+ return ret;
+}
+
+void
+args_lease_store(default_args_t *args, loc_t *loc, struct gf_lease *lease,
+ dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->lease = *lease;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return;
+}
+
+void
+args_lease_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct gf_lease *lease, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret == 0)
+ args->lease = *lease;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+}
+
+int
+args_icreate_store(default_args_t *args, loc_t *loc, mode_t mode, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+ args->mode = mode;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_namelink_store(default_args_t *args, loc_t *loc, dict_t *xdata)
+{
+ loc_copy(&args->loc, loc);
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ return 0;
+}
+
+int
+args_copy_file_range_store(default_args_t *args, fd_t *fd_in, off64_t off_in,
+ fd_t *fd_out, off64_t off_out, size_t len,
+ uint32_t flags, dict_t *xdata)
+{
+ if (fd_in)
+ args->fd = fd_ref(fd_in);
+ if (fd_out)
+ args->fd_dst = fd_ref(fd_out);
+ args->size = len;
+ args->off_in = off_in;
+ args->off_out = off_out;
+ args->flags = flags;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+int
+args_copy_file_range_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *stbuf,
+ struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (op_ret >= 0) {
+ if (postbuf_dst)
+ args->poststat = *postbuf_dst;
+ if (prebuf_dst)
+ args->prestat = *prebuf_dst;
+ if (stbuf)
+ args->stat = *stbuf;
+ }
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ return 0;
+}
+
+void
+args_cbk_wipe(default_args_cbk_t *args_cbk)
+{
+ if (!args_cbk)
+ return;
+ if (args_cbk->inode)
+ inode_unref(args_cbk->inode);
+
+ GF_FREE((char *)args_cbk->buf);
+
+ GF_FREE(args_cbk->vector);
+
+ if (args_cbk->iobref)
+ iobref_unref(args_cbk->iobref);
+
+ if (args_cbk->fd)
+ fd_unref(args_cbk->fd);
+
+ if (args_cbk->xattr)
+ dict_unref(args_cbk->xattr);
+
+ GF_FREE(args_cbk->strong_checksum);
+
+ if (args_cbk->xdata)
+ dict_unref(args_cbk->xdata);
+
+ if (!list_empty(&args_cbk->entries.list))
+ gf_dirent_free(&args_cbk->entries);
+}
+
+void
+args_wipe(default_args_t *args)
+{
+ if (!args)
+ return;
+
+ loc_wipe(&args->loc);
+
+ loc_wipe(&args->loc2);
+
+ if (args->fd)
+ fd_unref(args->fd);
+
+ GF_FREE((char *)args->linkname);
+
+ GF_FREE(args->vector);
+
+ if (args->iobref)
+ iobref_unref(args->iobref);
+
+ if (args->xattr)
+ dict_unref(args->xattr);
+
+ if (args->xdata)
+ dict_unref(args->xdata);
+
+ GF_FREE((char *)args->name);
+
+ GF_FREE((char *)args->volume);
+}
+
+void
+args_cbk_init(default_args_cbk_t *args_cbk)
+{
+ INIT_LIST_HEAD(&args_cbk->entries);
+}
diff --git a/libglusterfs/src/defaults-tmpl.c b/libglusterfs/src/defaults-tmpl.c
new file mode 100644
index 00000000000..3cf707f42aa
--- /dev/null
+++ b/libglusterfs/src/defaults-tmpl.c
@@ -0,0 +1,247 @@
+/*
+ Copyright (c) 2008-2015 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.c:
+ This file contains functions, which are used to fill the 'fops', 'cbk'
+ structures in the xlator structures, if they are not written. Here, all the
+ function calls are plainly forwarded to the first child of the xlator, and
+ all the *_cbk function does plain STACK_UNWIND of the frame, and returns.
+
+ This function also implements *_resume () functions, which does same
+ operation as a fop().
+
+ All the functions are plain enough to understand.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs/xlator.h"
+#include "glusterfs/defaults.h"
+
+#pragma generate
+
+struct xlator_fops _default_fops = {
+ .create = default_create,
+ .open = default_open,
+ .stat = default_stat,
+ .readlink = default_readlink,
+ .mknod = default_mknod,
+ .mkdir = default_mkdir,
+ .unlink = default_unlink,
+ .rmdir = default_rmdir,
+ .symlink = default_symlink,
+ .rename = default_rename,
+ .link = default_link,
+ .truncate = default_truncate,
+ .readv = default_readv,
+ .writev = default_writev,
+ .statfs = default_statfs,
+ .flush = default_flush,
+ .fsync = default_fsync,
+ .setxattr = default_setxattr,
+ .getxattr = default_getxattr,
+ .fsetxattr = default_fsetxattr,
+ .fgetxattr = default_fgetxattr,
+ .removexattr = default_removexattr,
+ .fremovexattr = default_fremovexattr,
+ .opendir = default_opendir,
+ .readdir = default_readdir,
+ .readdirp = default_readdirp,
+ .fsyncdir = default_fsyncdir,
+ .access = default_access,
+ .ftruncate = default_ftruncate,
+ .fstat = default_fstat,
+ .lk = default_lk,
+ .inodelk = default_inodelk,
+ .finodelk = default_finodelk,
+ .entrylk = default_entrylk,
+ .fentrylk = default_fentrylk,
+ .lookup = default_lookup,
+ .rchecksum = default_rchecksum,
+ .xattrop = default_xattrop,
+ .fxattrop = default_fxattrop,
+ .setattr = default_setattr,
+ .fsetattr = default_fsetattr,
+ .fallocate = default_fallocate,
+ .discard = default_discard,
+ .zerofill = default_zerofill,
+ .ipc = default_ipc,
+ .seek = default_seek,
+
+ .getspec = default_getspec,
+ .getactivelk = default_getactivelk,
+ .setactivelk = default_setactivelk,
+ .put = default_put,
+ .icreate = default_icreate,
+ .namelink = default_namelink,
+ .copy_file_range = default_copy_file_range,
+};
+struct xlator_fops *default_fops = &_default_fops;
+
+/*
+ * Remaining functions don't follow the fop calling conventions, so they're
+ * not generated.
+ */
+
+int32_t
+default_forget(xlator_t *this, inode_t *inode)
+{
+ gf_log_callingfn(this->name, GF_LOG_DEBUG,
+ "xlator does not "
+ "implement forget_cbk");
+ return 0;
+}
+
+int32_t
+default_releasedir(xlator_t *this, fd_t *fd)
+{
+ gf_log_callingfn(this->name, GF_LOG_DEBUG,
+ "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_DEBUG,
+ "xlator does not "
+ "implement release_cbk");
+ return 0;
+}
+
+/* notify */
+int
+default_notify(xlator_t *this, int32_t event, void *data, ...)
+{
+ GF_UNUSED int ret = 0;
+ xlator_t *victim = data;
+
+ glusterfs_graph_t *graph = NULL;
+
+ GF_VALIDATE_OR_GOTO("notify", this, out);
+ graph = this->graph;
+ GF_VALIDATE_OR_GOTO(this->name, graph, out);
+
+ switch (event) {
+ case GF_EVENT_PARENT_UP:
+ case GF_EVENT_PARENT_DOWN: {
+ xlator_list_t *list = this->children;
+
+ while (list) {
+ if (victim && victim->cleanup_starting)
+ xlator_notify(list->xlator, event, victim);
+ else
+ xlator_notify(list->xlator, event, this);
+ list = list->next;
+ }
+ } break;
+ case GF_EVENT_CHILD_CONNECTING:
+ 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_* & AUTH_FAILED event specially, send
+ * it to fuse.
+ */
+ if (!parent && this->ctx && this->ctx->master) {
+ xlator_notify(this->ctx->master, event, this->graph, NULL);
+ }
+
+ while (parent) {
+ if (parent->xlator->init_succeeded)
+ xlator_notify(parent->xlator, event, this, NULL);
+ parent = parent->next;
+ }
+
+ if (event == GF_EVENT_CHILD_DOWN &&
+ !(this->ctx && this->ctx->master) && (graph->top == this)) {
+ /* Make sure this is not a daemon with master xlator */
+ pthread_mutex_lock(&graph->mutex);
+ {
+ if (graph->parent_down ==
+ graph_total_client_xlator(graph)) {
+ graph->used = 0;
+ pthread_cond_broadcast(&graph->child_down_cond);
+ }
+ }
+ pthread_mutex_unlock(&graph->mutex);
+ }
+ } break;
+ case GF_EVENT_UPCALL: {
+ xlator_list_t *parent = this->parents;
+
+ if (!parent && this->ctx && this->ctx->master)
+ xlator_notify(this->ctx->master, event, data, NULL);
+
+ while (parent) {
+ if (parent->xlator->init_succeeded)
+ xlator_notify(parent->xlator, event, data, NULL);
+ parent = parent->next;
+ }
+ } break;
+ case GF_EVENT_CHILD_PING: {
+ xlator_list_t *parent = this->parents;
+
+ while (parent) {
+ if (parent->xlator->init_succeeded)
+ XLATOR_NOTIFY(ret, parent->xlator, event, this, data);
+ parent = parent->next;
+ }
+ } break;
+ case GF_EVENT_CLEANUP: {
+ xlator_list_t *list = this->children;
+
+ while (list) {
+ xlator_notify(list->xlator, event, this);
+ list = list->next;
+ }
+ } break;
+
+ default: {
+ xlator_list_t *parent = this->parents;
+
+ while (parent) {
+ if (parent->xlator->init_succeeded)
+ xlator_notify(parent->xlator, event, this, NULL);
+ parent = parent->next;
+ }
+ }
+ /*
+ * Apparently our picky-about-everything else coding standard allows
+ * adjacent same-indendation-level close braces. Clearly it has
+ * nothing to do with readability.
+ */
+ }
+out:
+ return 0;
+}
+
+int32_t
+default_mem_acct_init(xlator_t *this)
+{
+ int ret = -1;
+
+ ret = xlator_mem_acct_init(this, gf_common_mt_end);
+
+ return ret;
+}
+
+void
+default_fini(xlator_t *this)
+{
+ if (this && this->private)
+ GF_FREE(this->private);
+}
diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c
deleted file mode 100644
index 2a4b20cebd8..00000000000
--- a/libglusterfs/src/defaults.c
+++ /dev/null
@@ -1,3167 +0,0 @@
-/*
- 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.c:
- This file contains functions, which are used to fill the 'fops', 'cbk'
- structures in the xlator structures, if they are not written. Here, all the
- function calls are plainly forwared to the first child of the xlator, and
- all the *_cbk function does plain STACK_UNWIND of the frame, and returns.
-
- This function also implements *_resume () functions, which does same
- operation as a fop().
-
- All the functions are plain enough to understand.
-*/
-
-#include "xlator.h"
-#include "defaults.h"
-#include "libglusterfs-messages.h"
-
-/* FAILURE_CBK function section */
-
-int32_t
-default_lookup_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, NULL, NULL,
- NULL, NULL);
- return 0;
-}
-
-int32_t
-default_stat_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_truncate_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_ftruncate_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_access_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (access, frame, -1, op_errno, NULL);
- return 0;
-}
-
-int32_t
-default_readlink_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_mknod_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
- return 0;
-}
-
-int32_t
-default_mkdir_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
- return 0;
-}
-
-int32_t
-default_unlink_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_rmdir_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_symlink_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_rename_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_link_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_create_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_open_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_readv_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, -1, NULL,
- NULL, NULL);
- return 0;
-}
-
-int32_t
-default_writev_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_flush_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (flush, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-
-int32_t
-default_fsync_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_fstat_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_opendir_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_fsyncdir_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, op_errno, NULL);
- return 0;
-}
-
-int32_t
-default_statfs_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (statfs, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_setxattr_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int32_t
-default_fsetxattr_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-
-int32_t
-default_fgetxattr_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_getxattr_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_xattrop_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (xattrop, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_fxattrop_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fxattrop, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_removexattr_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int32_t
-default_fremovexattr_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fremovexattr, frame, -1, op_errno, NULL);
- return 0;
-}
-
-int32_t
-default_lk_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (lk, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_inodelk_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (inodelk, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int32_t
-default_finodelk_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (finodelk, frame, -1, op_errno, NULL);
- return 0;
-}
-
-int32_t
-default_entrylk_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (entrylk, frame, -1, op_errno, NULL);
- return 0;
-}
-
-int32_t
-default_fentrylk_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fentrylk, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int32_t
-default_rchecksum_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (rchecksum, frame, -1, op_errno, -1, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_readdir_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_readdirp_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_setattr_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_fsetattr_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_fallocate_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT(fallocate, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_discard_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT(discard, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-int32_t
-default_zerofill_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT(zerofill, frame, -1, op_errno, NULL, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-default_getspec_failure_cbk (call_frame_t *frame, int32_t op_errno)
-{
- STACK_UNWIND_STRICT (getspec, frame, -1, op_errno, NULL);
- return 0;
-}
-
-/* _cbk_resume section */
-
-int32_t
-default_lookup_cbk_resume (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 *xdata,
- struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- xdata, postparent);
- return 0;
-}
-
-int32_t
-default_stat_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-
-int32_t
-default_truncate_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
-}
-
-int32_t
-default_ftruncate_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
-}
-
-int32_t
-default_access_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-default_readlink_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- const char *path, struct iatt *buf, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf,
- xdata);
- return 0;
-}
-
-
-int32_t
-default_mknod_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-default_mkdir_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-default_unlink_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
-}
-
-int32_t
-default_rmdir_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
-}
-
-
-int32_t
-default_symlink_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-int32_t
-default_rename_cbk_resume (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, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent, xdata);
- return 0;
-}
-
-
-int32_t
-default_link_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-int32_t
-default_create_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-int32_t
-default_open_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
- return 0;
-}
-
-int32_t
-default_readv_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
- return 0;
-}
-
-
-int32_t
-default_writev_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
- return 0;
-}
-
-
-int32_t
-default_flush_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-
-int32_t
-default_fsync_cbk_resume (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)
-{
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
-}
-
-int32_t
-default_fstat_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-int32_t
-default_opendir_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
- return 0;
-}
-
-int32_t
-default_fsyncdir_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-default_statfs_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct statvfs *buf, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-
-int32_t
-default_setxattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int32_t
-default_fsetxattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-
-int32_t
-default_fgetxattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-
-int32_t
-default_getxattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-int32_t
-default_xattrop_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-int32_t
-default_fxattrop_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-
-int32_t
-default_removexattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int32_t
-default_fremovexattr_cbk_resume (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_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- 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, xdata);
- return 0;
-}
-
-int32_t
-default_inodelk_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int32_t
-default_finodelk_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-default_entrylk_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int32_t
-default_fentrylk_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int32_t
-default_rchecksum_cbk_resume (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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_checksum,
- strong_checksum, xdata);
- return 0;
-}
-
-
-int32_t
-default_readdir_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- 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, xdata);
- return 0;
-}
-
-
-int32_t
-default_readdirp_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- 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, xdata);
- return 0;
-}
-
-int32_t
-default_setattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
- return 0;
-}
-
-int32_t
-default_fsetattr_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
- return 0;
-}
-
-int32_t
-default_fallocate_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *pre, struct iatt *post,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno,
- pre, post, xdata);
- return 0;
-}
-
-int32_t
-default_discard_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata)
-{
- STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, pre, post, xdata);
- return 0;
-}
-
-int32_t
-default_zerofill_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata)
-{
- STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, pre,
- post, xdata);
- return 0;
-}
-
-
-int32_t
-default_getspec_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, char *spec_data)
-{
- STACK_UNWIND_STRICT (getspec, frame, op_ret, op_errno, spec_data);
- return 0;
-}
-
-/* _CBK function section */
-
-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 *xdata, struct iatt *postparent)
-{
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- 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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-
-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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- 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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- 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,
- dict_t *xdata)
-{
- 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, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf,
- xdata);
- return 0;
-}
-
-
-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, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
- return 0;
-}
-
-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, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode,
- 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, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
- 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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
-}
-
-
-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, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent, xdata);
- return 0;
-}
-
-
-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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
- return 0;
-}
-
-
-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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-
-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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-
-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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- 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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- 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,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
- return 0;
-}
-
-int32_t
-default_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata)
-{
- STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, pre, post, xdata);
- return 0;
-}
-
-int32_t
-default_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata)
-{
- STACK_UNWIND_STRICT(discard, frame, op_ret, op_errno, pre, post, xdata);
- return 0;
-}
-
-int32_t
-default_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata)
-{
- STACK_UNWIND_STRICT(zerofill, frame, op_ret, op_errno, pre,
- post, xdata);
- return 0;
-}
-
-
-int32_t
-default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, char *spec_data)
-{
- STACK_UNWIND_STRICT (getspec, frame, op_ret, op_errno, spec_data);
- return 0;
-}
-
-
-int32_t
-default_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (ipc, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-/* RESUME */
-
-int32_t
-default_fgetxattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- 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 *xdata)
-{
- STACK_WIND (frame, default_fsetxattr_cbk, FIRST_CHILD(this),
- 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 *xdata)
-{
- STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_fsyncdir_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),
- 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,
- 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,
- 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, uint32_t flags, dict_t *xdata)
-{
- STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this),
- 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, 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, umask,
- fd, xdata);
- return 0;
-}
-
-int32_t
-default_link_resume (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, xdata);
- return 0;
-}
-
-int32_t
-default_rename_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
-{
- STACK_WIND (frame, default_rename_cbk, FIRST_CHILD(this),
- 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, mode_t umask,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD(this),
- 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,
- int xflag, dict_t *xdata)
-{
- STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this),
- 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, mode_t umask, dict_t *xdata)
-{
- STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this),
- 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, mode_t umask, dict_t *xdata)
-{
- STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_access_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_xattrop_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_fxattrop_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_lk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata);
- return 0;
-}
-
-
-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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_inodelk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- 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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_finodelk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk,
- 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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_entrylk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->entrylk,
- 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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_fentrylk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fentrylk,
- 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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_rchecksum_cbk, FIRST_CHILD(this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_readdir_cbk, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND (frame, default_readdirp_cbk, FIRST_CHILD(this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- 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 *xdata)
-{
- STACK_WIND (frame, default_lookup_cbk, FIRST_CHILD(this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid, xdata);
- return 0;
-}
-
-int32_t
-default_fallocate_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
-{
- STACK_WIND(frame, default_fallocate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset, len,
- xdata);
- return 0;
-}
-
-int32_t
-default_discard_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, size_t len, dict_t *xdata)
-{
- STACK_WIND(frame, default_discard_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->discard, fd, offset, len,
- xdata);
- return 0;
-}
-
-int32_t
-default_zerofill_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, off_t len, dict_t *xdata)
-{
- STACK_WIND(frame, default_zerofill_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->zerofill, fd, offset, len,
- xdata);
- return 0;
-}
-
-
-int32_t
-default_ipc_resume (call_frame_t *frame, xlator_t *this, int32_t op,
- dict_t *xdata)
-{
- STACK_WIND (frame, default_ipc_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc,
- op, xdata);
- return 0;
-}
-
-
-/* FOPS */
-
-int32_t
-default_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->opendir, loc, fd, xdata);
- return 0;
-}
-
-int32_t
-default_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, flags, xdata);
- return 0;
-}
-
-int32_t
-default_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, uint32_t flags,
- struct iobref *iobref, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count,
- off, 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, uint32_t flags, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, mode_t umask, fd_t *fd, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, mode_t umask, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata);
- return 0;
-}
-
-int32_t
-default_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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,
- mode_t umask, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, mode_t umask, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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_TAIL (frame, 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata);
- return 0;
-}
-
-
-int32_t
-default_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk, 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk, 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->entrylk, 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fentrylk, 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
- return 0;
-}
-
-int32_t
-default_stat (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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 *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- 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,
- dict_t *xdata)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid,
- xdata);
- return 0;
-}
-
-int32_t
-default_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
-{
- STACK_WIND_TAIL(frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset,
- len, xdata);
- return 0;
-}
-
-int32_t
-default_discard(call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, size_t len, dict_t *xdata)
-{
- STACK_WIND_TAIL(frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->discard, fd, offset, len,
- xdata);
- return 0;
-}
-
-int32_t
-default_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, off_t len, dict_t *xdata)
-{
- STACK_WIND_TAIL(frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->zerofill, fd, offset, len,
- xdata);
- return 0;
-}
-
-
-int32_t
-default_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata)
-{
- STACK_WIND_TAIL (frame,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->ipc,
- op, xdata);
- return 0;
-}
-
-
-int32_t
-default_forget (xlator_t *this, inode_t *inode)
-{
- gf_msg_callingfn (this->name, GF_LOG_WARNING, 0,
- LG_MSG_XLATOR_DOES_NOT_IMPLEMENT, "xlator does not "
- "implement forget_cbk");
- return 0;
-}
-
-
-int32_t
-default_releasedir (xlator_t *this, fd_t *fd)
-{
- gf_msg_callingfn (this->name, GF_LOG_WARNING, 0,
- LG_MSG_XLATOR_DOES_NOT_IMPLEMENT, "xlator does not "
- "implement releasedir_cbk");
- return 0;
-}
-
-int32_t
-default_release (xlator_t *this, fd_t *fd)
-{
- gf_msg_callingfn (this->name, GF_LOG_WARNING, 0,
- LG_MSG_XLATOR_DOES_NOT_IMPLEMENT, "xlator does not "
- "implement release_cbk");
- return 0;
-}
-
-/* End of FOP/_CBK/_RESUME section */
-
-
-/* Management operations */
-
-int32_t
-default_getspec (call_frame_t *frame, xlator_t *this, const char *key,
- int32_t flags)
-{
- STACK_WIND_TAIL (frame, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getspec, key, flags);
- return 0;
-}
-
-
-struct xlator_fops _default_fops = {
- .create = default_create,
- .open = default_open,
- .stat = default_stat,
- .readlink = default_readlink,
- .mknod = default_mknod,
- .mkdir = default_mkdir,
- .unlink = default_unlink,
- .rmdir = default_rmdir,
- .symlink = default_symlink,
- .rename = default_rename,
- .link = default_link,
- .truncate = default_truncate,
- .readv = default_readv,
- .writev = default_writev,
- .statfs = default_statfs,
- .flush = default_flush,
- .fsync = default_fsync,
- .setxattr = default_setxattr,
- .getxattr = default_getxattr,
- .fsetxattr = default_fsetxattr,
- .fgetxattr = default_fgetxattr,
- .removexattr = default_removexattr,
- .fremovexattr = default_fremovexattr,
- .opendir = default_opendir,
- .readdir = default_readdir,
- .readdirp = default_readdirp,
- .fsyncdir = default_fsyncdir,
- .access = default_access,
- .ftruncate = default_ftruncate,
- .fstat = default_fstat,
- .lk = default_lk,
- .inodelk = default_inodelk,
- .finodelk = default_finodelk,
- .entrylk = default_entrylk,
- .fentrylk = default_fentrylk,
- .lookup = default_lookup,
- .rchecksum = default_rchecksum,
- .xattrop = default_xattrop,
- .fxattrop = default_fxattrop,
- .setattr = default_setattr,
- .fsetattr = default_fsetattr,
- .fallocate = default_fallocate,
- .discard = default_discard,
- .zerofill = default_zerofill,
-
- .getspec = default_getspec,
-};
-struct xlator_fops *default_fops = &_default_fops;
-
-/* notify */
-int
-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;
-
- while (list) {
- xlator_notify (list->xlator, event, this);
- list = list->next;
- }
- }
- break;
- case GF_EVENT_CHILD_CONNECTING:
- 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_* & AUTH_FAILED event specially, send it to fuse */
- if (!parent && this->ctx && this->ctx->master)
- xlator_notify (this->ctx->master, event, this->graph, NULL);
-
- while (parent) {
- if (parent->xlator->init_succeeded)
- xlator_notify (parent->xlator, event,
- this, NULL);
- parent = parent->next;
- }
- }
- break;
- case GF_EVENT_UPCALL:
- {
- xlator_list_t *parent = this->parents;
-
- if (!parent && this->ctx && this->ctx->master)
- xlator_notify (this->ctx->master, event, data, NULL);
-
- while (parent) {
- if (parent->xlator->init_succeeded)
- xlator_notify (parent->xlator, event,
- data, NULL);
- parent = parent->next;
- }
- }
- break;
- default:
- {
- xlator_list_t *parent = this->parents;
- while (parent) {
- if (parent->xlator->init_succeeded)
- xlator_notify (parent->xlator, event,
- this, NULL);
- parent = parent->next;
- }
- }
- }
-
- return 0;
-}
-
-int32_t
-default_mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- ret = xlator_mem_acct_init (this, gf_common_mt_end);
-
- return ret;
-}
-
-/*ARGS_ STORE section*/
-int
-args_lookup_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- dict_t *xdata, struct iatt *postparent)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (inode)
- args->inode = inode_ref (inode);
- if (buf)
- args->stat = *buf;
- if (postparent)
- args->postparent = *postparent;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_stat_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *buf, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (op_ret == 0)
- args->stat = *buf;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_fstat_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *buf, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (buf)
- args->stat = *buf;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_truncate_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (prebuf)
- args->prestat = *prebuf;
- if (postbuf)
- args->poststat = *postbuf;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_ftruncate_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (prebuf)
- args->prestat = *prebuf;
- if (postbuf)
- args->poststat = *postbuf;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_access_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_readlink_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- const char *path, struct iatt *stbuf, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (path)
- args->buf = gf_strdup (path);
- if (stbuf)
- args->stat = *stbuf;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_mknod_cbk_store (default_args_cbk_t *args, int op_ret,
- int32_t op_errno, inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (inode)
- args->inode = inode_ref (inode);
- if (buf)
- args->stat = *buf;
- if (preparent)
- args->preparent = *preparent;
- if (postparent)
- args->postparent = *postparent;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_mkdir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (inode)
- args->inode = inode_ref (inode);
- if (buf)
- args->stat = *buf;
- if (preparent)
- args->preparent = *preparent;
- if (postparent)
- args->postparent = *postparent;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_unlink_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (preparent)
- args->preparent = *preparent;
- if (postparent)
- args->postparent = *postparent;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_rmdir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (preparent)
- args->preparent = *preparent;
- if (postparent)
- args->postparent = *postparent;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_symlink_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (inode)
- args->inode = inode_ref (inode);
- if (buf)
- args->stat = *buf;
- if (preparent)
- args->preparent = *preparent;
- if (postparent)
- args->postparent = *postparent;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_rename_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (buf)
- args->stat = *buf;
- if (preoldparent)
- args->preparent = *preoldparent;
- if (postoldparent)
- args->postparent = *postoldparent;
- if (prenewparent)
- args->preparent2 = *prenewparent;
- if (postnewparent)
- args->postparent2 = *postnewparent;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_link_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (inode)
- args->inode = inode_ref (inode);
- if (buf)
- args->stat = *buf;
- if (preparent)
- args->preparent = *preparent;
- if (postparent)
- args->postparent = *postparent;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_create_cbk_store (default_args_cbk_t *args,
- 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)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (fd)
- args->fd = fd_ref (fd);
- if (inode)
- args->inode = inode_ref (inode);
- if (buf)
- args->stat = *buf;
- if (preparent)
- args->preparent = *preparent;
- if (postparent)
- args->postparent = *postparent;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_open_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- fd_t *fd, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (fd)
- args->fd = fd_ref (fd);
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_readv_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (op_ret >= 0) {
- args->vector = iov_dup (vector, count);
- args->count = count;
- args->stat = *stbuf;
- args->iobref = iobref_ref (iobref);
- }
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_writev_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (op_ret >= 0)
- args->poststat = *postbuf;
- if (prebuf)
- args->prestat = *prebuf;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_flush_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_fsync_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (prebuf)
- args->prestat = *prebuf;
- if (postbuf)
- args->poststat = *postbuf;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_opendir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- fd_t *fd, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (fd)
- args->fd = fd_ref (fd);
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_fsyncdir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_statfs_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct statvfs *buf, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (op_ret == 0)
- args->statvfs = *buf;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_setxattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_getxattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (dict)
- args->xattr = dict_ref (dict);
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_fsetxattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_fgetxattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (dict)
- args->xattr = dict_ref (dict);
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_removexattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_fremovexattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_lk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct gf_flock *lock, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (op_ret == 0)
- args->lock = *lock;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_inodelk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_finodelk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_entrylk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_fentrylk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_readdirp_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata)
-{
- gf_dirent_t *stub_entry = NULL, *entry = NULL;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (op_ret > 0) {
- list_for_each_entry (entry, &entries->list, list) {
- stub_entry = gf_dirent_for_name (entry->d_name);
- if (!stub_entry)
- goto out;
- stub_entry->d_off = entry->d_off;
- stub_entry->d_ino = entry->d_ino;
- stub_entry->d_stat = entry->d_stat;
- stub_entry->d_type = entry->d_type;
- if (entry->inode)
- stub_entry->inode = inode_ref (entry->inode);
- if (entry->dict)
- stub_entry->dict = dict_ref (entry->dict);
- list_add_tail (&stub_entry->list,
- &args->entries.list);
- }
- }
- if (xdata)
- args->xdata = dict_ref (xdata);
-out:
- return 0;
-}
-
-
-int
-args_readdir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata)
-{
- gf_dirent_t *stub_entry = NULL, *entry = NULL;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (op_ret > 0) {
- list_for_each_entry (entry, &entries->list, list) {
- stub_entry = gf_dirent_for_name (entry->d_name);
- if (!stub_entry)
- goto out;
- stub_entry->d_off = entry->d_off;
- stub_entry->d_ino = entry->d_ino;
- stub_entry->d_type = entry->d_type;
- list_add_tail (&stub_entry->list,
- &args->entries.list);
- }
- }
- if (xdata)
- args->xdata = dict_ref (xdata);
-out:
- return 0;
-}
-
-
-int
-args_rchecksum_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- uint32_t weak_checksum, uint8_t *strong_checksum,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (op_ret >= 0) {
- args->weak_checksum =
- weak_checksum;
- args->strong_checksum =
- memdup (strong_checksum, MD5_DIGEST_LENGTH);
- }
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_xattrop_cbk_store (default_args_cbk_t *args, int32_t op_ret,
- int32_t op_errno, dict_t *xattr, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xattr)
- args->xattr = dict_ref (xattr);
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_fxattrop_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- dict_t *xattr, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xattr)
- args->xattr = dict_ref (xattr);
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_setattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (statpre)
- args->prestat = *statpre;
- if (statpost)
- args->poststat = *statpost;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-
-int
-args_fsetattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (statpre)
- args->prestat = *statpre;
- if (statpost)
- args->poststat = *statpost;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_fallocate_cbk_store(default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (statpre)
- args->prestat = *statpre;
- if (statpost)
- args->poststat = *statpost;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_discard_cbk_store(default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (statpre)
- args->prestat = *statpre;
- if (statpost)
- args->poststat = *statpost;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_zerofill_cbk_store(default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (statpre)
- args->prestat = *statpre;
- if (statpost)
- args->poststat = *statpost;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-int
-args_ipc_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
-
- return 0;
-}
-
-void
-args_cbk_wipe (default_args_cbk_t *args_cbk)
-{
- if (!args_cbk)
- return;
- if (args_cbk->inode)
- inode_unref (args_cbk->inode);
-
- GF_FREE ((char *)args_cbk->buf);
-
- GF_FREE (args_cbk->vector);
-
- if (args_cbk->iobref)
- iobref_unref (args_cbk->iobref);
-
- if (args_cbk->fd)
- fd_unref (args_cbk->fd);
-
- if (args_cbk->xattr)
- dict_unref (args_cbk->xattr);
-
- GF_FREE (args_cbk->strong_checksum);
-
- if (args_cbk->xdata)
- dict_unref (args_cbk->xdata);
-
- if (!list_empty (&args_cbk->entries.list))
- gf_dirent_free (&args_cbk->entries);
-}
-/* end of ARGS_ STORE section*/
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
deleted file mode 100644
index 68d23974b35..00000000000
--- a/libglusterfs/src/defaults.h
+++ /dev/null
@@ -1,1413 +0,0 @@
-/*
- 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:
- This file contains definition of default fops and mops functions.
-*/
-
-#ifndef _DEFAULTS_H
-#define _DEFAULTS_H
-
-#include "xlator.h"
-
-typedef struct {
- int op_ret;
- int op_errno;
- inode_t *inode;
- struct iatt stat;
- struct iatt prestat;
- struct iatt poststat;
- struct iatt preparent; /* @preoldparent in rename_cbk */
- struct iatt postparent; /* @postoldparent in rename_cbk */
- struct iatt preparent2; /* @prenewparent in rename_cbk */
- struct iatt postparent2; /* @postnewparent in rename_cbk */
- const char *buf;
- struct iovec *vector;
- int count;
- struct iobref *iobref;
- fd_t *fd;
- struct statvfs statvfs;
- dict_t *xattr;
- struct gf_flock lock;
- uint32_t weak_checksum;
- uint8_t *strong_checksum;
- dict_t *xdata;
- gf_dirent_t entries;
- int valid; /* If the response is valid or not. For call-stub it is
- always valid irrespective of this */
-} default_args_cbk_t;
-
-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);
-
-
-extern struct xlator_fops *default_fops;
-
-/* Management Operations */
-
-int32_t default_getspec (call_frame_t *frame,
- xlator_t *this,
- const char *key,
- int32_t flag);
-
-int32_t default_rchecksum (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, off_t offset,
- int32_t len, dict_t *xdata);
-
-/* FileSystem operations */
-int32_t default_lookup (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xdata);
-
-int32_t default_stat (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, dict_t *xdata);
-
-int32_t default_fstat (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata);
-
-int32_t default_truncate (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- off_t offset, dict_t *xdata);
-
-int32_t default_ftruncate (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset, dict_t *xdata);
-
-int32_t default_access (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t mask, dict_t *xdata);
-
-int32_t default_readlink (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- 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, mode_t umask, dict_t *xdata);
-
-int32_t default_mkdir (call_frame_t *frame, xlator_t *this,
- 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, int xflag, dict_t *xdata);
-
-int32_t default_rmdir (call_frame_t *frame, xlator_t *this,
- 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, mode_t umask,
- dict_t *xdata);
-
-int32_t default_rename (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc, dict_t *xdata);
-
-int32_t default_link (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- 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,
- 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,
- dict_t *xdata);
-
-int32_t default_readv (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset,
- uint32_t flags, dict_t *xdata);
-
-int32_t default_writev (call_frame_t *frame,
- 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 (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata);
-
-int32_t default_fsync (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync, dict_t *xdata);
-
-int32_t default_opendir (call_frame_t *frame,
- xlator_t *this,
- 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, dict_t *xdata);
-
-int32_t default_statfs (call_frame_t *frame,
- xlator_t *this,
- 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, dict_t *xdata);
-
-int32_t default_getxattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- 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, dict_t *xdata);
-
-int32_t default_fgetxattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- const char *name, dict_t *xdata);
-
-int32_t default_removexattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- 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, 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, 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, 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, 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, dict_t *xdata);
-
-int32_t default_readdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- 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, 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 *xdata);
-
-int32_t default_fxattrop (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- gf_xattrop_flags_t flags,
- 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, dict_t *xdata);
-
-int32_t default_fsetattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iatt *stbuf,
- int32_t valid, dict_t *xdata);
-
-int32_t default_fallocate(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t keep_size, off_t offset,
- size_t len, dict_t *xdata);
-
-int32_t default_discard(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset,
- size_t len, dict_t *xdata);
-
-int32_t default_zerofill(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset,
- off_t len, dict_t *xdata);
-
-int32_t default_ipc (call_frame_t *frame, xlator_t *this, int32_t op,
- dict_t *xdata);
-
-
-/* Resume */
-int32_t default_getspec_resume (call_frame_t *frame,
- xlator_t *this,
- const char *key,
- int32_t flag);
-
-int32_t default_rchecksum_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, off_t offset,
- 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 *xdata);
-
-int32_t default_stat_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, dict_t *xdata);
-
-int32_t default_fstat_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata);
-
-int32_t default_truncate_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- off_t offset, dict_t *xdata);
-
-int32_t default_ftruncate_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset, dict_t *xdata);
-
-int32_t default_access_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t mask, dict_t *xdata);
-
-int32_t default_readlink_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- 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, mode_t umask,
- dict_t *xdata);
-
-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, int xflag, dict_t *xdata);
-
-int32_t default_rmdir_resume (call_frame_t *frame, xlator_t *this,
- 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, mode_t umask,
- dict_t *xdata);
-
-int32_t default_rename_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc, dict_t *xdata);
-
-int32_t default_link_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- 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,
- 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, dict_t *xdata);
-
-int32_t default_readv_resume (call_frame_t *frame,
- 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, uint32_t flags,
- struct iobref *iobref, dict_t *xdata);
-
-int32_t default_flush_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata);
-
-int32_t default_fsync_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync, dict_t *xdata);
-
-int32_t default_opendir_resume (call_frame_t *frame,
- xlator_t *this,
- 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, dict_t *xdata);
-
-int32_t default_statfs_resume (call_frame_t *frame,
- xlator_t *this,
- 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, dict_t *xdata);
-
-int32_t default_getxattr_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- 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, dict_t *xdata);
-
-int32_t default_fgetxattr_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- const char *name, dict_t *xdata);
-
-int32_t default_removexattr_resume (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- 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, 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, 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, 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, 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, dict_t *xdata);
-
-int32_t default_readdir_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- 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, 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 *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 *xdata);
-int32_t default_rchecksum_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, off_t offset,
- 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, dict_t *xdata);
-
-int32_t default_fsetattr_resume (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iatt *stbuf,
- int32_t valid, dict_t *xdata);
-
-int32_t default_fallocate_resume(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t keep_size, off_t offset,
- size_t len, dict_t *xdata);
-
-int32_t default_discard_resume(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset,
- size_t len, dict_t *xdata);
-
-int32_t default_zerofill_resume(call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset,
- off_t len, dict_t *xdata);
-
-int32_t default_ipc_resume (call_frame_t *frame, xlator_t *this,
- int32_t op, dict_t *xdata);
-
-
-/* _cbk_resume */
-
-int32_t
-default_lookup_cbk_resume (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 * xdata,
- struct iatt *postparent);
-
-int32_t
-default_stat_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t * xdata);
-
-
-int32_t
-default_truncate_cbk_resume (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);
-
-int32_t
-default_ftruncate_cbk_resume (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);
-
-int32_t
-default_access_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- dict_t * xdata);
-
-int32_t
-default_readlink_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, const char *path,
- struct iatt *buf, dict_t * xdata);
-
-
-int32_t
-default_mknod_cbk_resume (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);
-
-int32_t
-default_mkdir_cbk_resume (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);
-
-int32_t
-default_unlink_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t * xdata);
-
-int32_t
-default_rmdir_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t * xdata);
-
-
-int32_t
-default_symlink_cbk_resume (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);
-
-
-int32_t
-default_rename_cbk_resume (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, dict_t * xdata);
-
-
-int32_t
-default_link_cbk_resume (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);
-
-
-int32_t
-default_create_cbk_resume (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);
-
-int32_t
-default_open_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, fd_t * fd,
- dict_t * xdata);
-
-int32_t
-default_readv_cbk_resume (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);
-
-
-int32_t
-default_writev_cbk_resume (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);
-
-
-int32_t
-default_flush_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata);
-
-
-
-int32_t
-default_fsync_cbk_resume (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);
-
-int32_t
-default_fstat_cbk_resume (call_frame_t * frame, void *cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t * xdata);
-
-int32_t
-default_opendir_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- fd_t * fd, dict_t * xdata);
-
-int32_t
-default_fsyncdir_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * xdata);
-
-int32_t
-default_statfs_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- struct statvfs *buf, dict_t * xdata);
-
-
-int32_t
-default_setxattr_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * xdata);
-
-
-int32_t
-default_fsetxattr_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * xdata);
-
-
-
-int32_t
-default_fgetxattr_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * dict,
- dict_t * xdata);
-
-
-int32_t
-default_getxattr_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * dict, dict_t * xdata);
-
-int32_t
-default_xattrop_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- dict_t * dict, dict_t * xdata);
-
-int32_t
-default_fxattrop_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * dict, dict_t * xdata);
-
-
-int32_t
-default_removexattr_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * xdata);
-
-int32_t
-default_fremovexattr_cbk_resume (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_resume (call_frame_t * frame, void *cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno,
- struct gf_flock *lock, dict_t * xdata);
-
-int32_t
-default_inodelk_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- dict_t * xdata);
-
-
-int32_t
-default_finodelk_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * xdata);
-
-int32_t
-default_entrylk_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- dict_t * xdata);
-
-int32_t
-default_fentrylk_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, dict_t * xdata);
-
-
-int32_t
-default_rchecksum_cbk_resume (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, dict_t * xdata);
-
-
-int32_t
-default_readdir_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- gf_dirent_t * entries, dict_t * xdata);
-
-
-int32_t
-default_readdirp_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, gf_dirent_t * entries,
- dict_t * xdata);
-
-int32_t
-default_setattr_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t * xdata);
-
-int32_t
-default_fsetattr_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t * xdata);
-
-int32_t default_fallocate_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t * xdata);
-
-int32_t default_discard_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t * xdata);
-
-int32_t default_zerofill_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret,
- int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t * xdata);
-
-int32_t
-default_getspec_cbk_resume (call_frame_t * frame, void *cookie,
- xlator_t * this, int32_t op_ret, int32_t op_errno,
- char *spec_data);
-
-/* _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 *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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, dict_t *xdata);
-
-int32_t default_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata);
-
-int32_t default_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata);
-
-int32_t default_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata);
-
-int32_t default_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-int32_t
-default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, char *spec_data);
-
-int32_t
-default_lookup_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_stat_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-
-int32_t
-default_truncate_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_ftruncate_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_access_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_readlink_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-
-int32_t
-default_mknod_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_mkdir_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_unlink_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_rmdir_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_symlink_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_rename_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_link_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_create_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_open_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_readv_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_writev_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_flush_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fsync_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fstat_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_opendir_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fsyncdir_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_statfs_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_setxattr_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fsetxattr_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fgetxattr_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_getxattr_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_xattrop_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fxattrop_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_removexattr_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fremovexattr_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_lk_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_inodelk_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_finodelk_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_entrylk_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fentrylk_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_rchecksum_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_readdir_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_readdirp_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_setattr_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fsetattr_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_fallocate_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_discard_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_zerofill_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_getspec_failure_cbk (call_frame_t *frame, int32_t op_errno);
-
-int32_t
-default_mem_acct_init (xlator_t *this);
-
-int
-args_lookup_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- dict_t *xdata, struct iatt *postparent);
-
-
-int
-args_stat_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *buf, dict_t *xdata);
-
-int
-args_fstat_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *buf, dict_t *xdata);
-
-int
-args_truncate_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata);
-
-
-int
-args_ftruncate_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata);
-
-
-int
-args_access_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-
-int
-args_readlink_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- const char *path, struct iatt *stbuf, dict_t *xdata);
-
-int
-args_mknod_cbk_store (default_args_cbk_t *args, int32_t op_ret,
- int32_t op_errno, inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata);
-
-int
-args_mkdir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata);
-
-int
-args_unlink_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata);
-
-int
-args_rmdir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata);
-
-int
-args_symlink_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata);
-
-
-int
-args_rename_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata);
-
-int
-args_link_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata);
-
-int
-args_create_cbk_store (default_args_cbk_t *args,
- 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);
-
-int
-args_open_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- fd_t *fd, dict_t *xdata);
-
-int
-args_readv_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata);
-
-int
-args_writev_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata);
-
-
-int
-args_flush_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-
-int
-args_fsync_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata);
-
-int
-args_opendir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- fd_t *fd, dict_t *xdata);
-
-int
-args_fsyncdir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-int
-args_statfs_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct statvfs *buf, dict_t *xdata);
-
-int
-args_setxattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret,
- int32_t op_errno, dict_t *xdata);
-
-int
-args_getxattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata);
-
-int
-args_fsetxattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-int
-args_fgetxattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata);
-
-int
-args_removexattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-int
-args_fremovexattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-int
-args_lk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct gf_flock *lock, dict_t *xdata);
-
-
-int
-args_inodelk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-int
-args_finodelk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-int
-args_entrylk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-int
-args_fentrylk_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-
-int
-args_readdirp_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata);
-
-
-int
-args_readdir_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata);
-
-
-int
-args_rchecksum_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- uint32_t weak_checksum, uint8_t *strong_checksum,
- dict_t *xdata);
-
-
-int
-args_xattrop_cbk_store (default_args_cbk_t *args, int32_t op_ret,
- int32_t op_errno, dict_t *xattr, dict_t *xdata);
-
-
-int
-args_fxattrop_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- dict_t *xattr, dict_t *xdata);
-
-int
-args_setattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata);
-
-
-int
-args_fsetattr_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata);
-
-int
-args_fallocate_cbk_store(default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata);
-
-int
-args_discard_cbk_store(default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata);
-
-int
-args_zerofill_cbk_store(default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost,
- dict_t *xdata);
-
-int
-args_ipc_cbk_store (default_args_cbk_t *args,
- int32_t op_ret, int32_t op_errno, dict_t *xdata);
-
-void
-args_cbk_wipe (default_args_cbk_t *args_cbk);
-/* end of ARGS_ STORE section*/
-#endif /* _DEFAULTS_H */
diff --git a/libglusterfs/src/dict.c b/libglusterfs/src/dict.c
index c58ce803f64..1d9be9217a6 100644
--- a/libglusterfs/src/dict.c
+++ b/libglusterfs/src/dict.c
@@ -16,152 +16,227 @@
#include <limits.h>
#include <fnmatch.h>
-#include "glusterfs.h"
-#include "common-utils.h"
-#include "dict.h"
-#include "hashfn.h"
-#include "logging.h"
-#include "compat.h"
-#include "byte-order.h"
-#include "globals.h"
-#include "statedump.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/dict.h"
+#define XXH_INLINE_ALL
+#include "xxhash.h"
+#include "glusterfs/compat.h"
+#include "glusterfs/compat-errno.h"
+#include "glusterfs/byte-order.h"
+#include "glusterfs/statedump.h"
+#include "glusterfs/libglusterfs-messages.h"
struct dict_cmp {
- dict_t *dict;
- gf_boolean_t (*value_ignore) (char *k);
+ dict_t *dict;
+ gf_boolean_t (*value_ignore)(char *k);
};
-data_t *
-get_new_data ()
+#define VALIDATE_DATA_AND_LOG(data, type, key, ret_val) \
+ do { \
+ if (!data || !data->data) { \
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG, \
+ "data is NULL"); \
+ return ret_val; \
+ } \
+ /* Not of the asked type, or old version */ \
+ if ((data->data_type != type) && \
+ (data->data_type != GF_DATA_TYPE_STR_OLD)) { \
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG, \
+ "key %s, %s type asked, has %s type", key, \
+ data_type_name[type], \
+ data_type_name[data->data_type]); \
+ } \
+ } while (0)
+
+static data_t *
+get_new_data()
{
- data_t *data = NULL;
+ data_t *data = mem_get(THIS->ctx->dict_data_pool);
- data = mem_get0 (THIS->ctx->dict_data_pool);
- if (!data) {
- return NULL;
- }
+ if (!data)
+ return NULL;
+
+ GF_ATOMIC_INIT(data->refcount, 0);
+ data->is_static = _gf_false;
- LOCK_INIT (&data->lock);
- return data;
+ return data;
}
-dict_t *
-get_new_dict_full (int size_hint)
+static dict_t *
+get_new_dict_full(int size_hint)
{
- dict_t *dict = mem_get0 (THIS->ctx->dict_pool);
+ dict_t *dict = mem_get0(THIS->ctx->dict_pool);
- if (!dict) {
- return NULL;
- }
-
- dict->hash_size = size_hint;
- if (size_hint == 1) {
- /*
- * This is the only case we ever see currently. If we ever
- * need to support resizing the hash table, the resize function
- * will have to take into account the possibility that
- * "members" is not separately allocated (i.e. don't just call
- * realloc() blindly.
- */
- dict->members = &dict->members_internal;
- }
- else {
- /*
- * We actually need to allocate space for size_hint *pointers*
- * but we actually allocate space for one *structure*. Since
- * a data_pair_t consists of five pointers, we're wasting four
- * pointers' worth for N=1, and will overrun what we allocated
- * for N>5. If anybody ever starts using size_hint, we'll need
- * to fix this.
- */
- GF_ASSERT (size_hint <=
- (sizeof(data_pair_t) / sizeof(data_pair_t *)));
- dict->members = mem_get0 (THIS->ctx->dict_pair_pool);
- if (!dict->members) {
- mem_put (dict);
- return NULL;
- }
+ if (!dict) {
+ return NULL;
+ }
+
+ dict->hash_size = size_hint;
+ if (size_hint == 1) {
+ /*
+ * This is the only case we ever see currently. If we ever
+ * need to support resizing the hash table, the resize function
+ * will have to take into account the possibility that
+ * "members" is not separately allocated (i.e. don't just call
+ * realloc() blindly.
+ */
+ dict->members = &dict->members_internal;
+ } else {
+ /*
+ * We actually need to allocate space for size_hint *pointers*
+ * but we actually allocate space for one *structure*. Since
+ * a data_pair_t consists of five pointers, we're wasting four
+ * pointers' worth for N=1, and will overrun what we allocated
+ * for N>5. If anybody ever starts using size_hint, we'll need
+ * to fix this.
+ */
+ GF_ASSERT(size_hint <= (sizeof(data_pair_t) / sizeof(data_pair_t *)));
+ dict->members = mem_get0(THIS->ctx->dict_pair_pool);
+ if (!dict->members) {
+ mem_put(dict);
+ return NULL;
}
+ }
- LOCK_INIT (&dict->lock);
+ dict->free_pair.key = NULL;
+ dict->totkvlen = 0;
+ LOCK_INIT(&dict->lock);
- return dict;
+ return dict;
}
dict_t *
-get_new_dict (void)
+dict_new(void)
{
- return get_new_dict_full (1);
+ dict_t *dict = get_new_dict_full(1);
+
+ if (dict)
+ dict_ref(dict);
+
+ return dict;
}
-dict_t *
-dict_new (void)
+int32_t
+is_data_equal(data_t *one, data_t *two)
{
- dict_t *dict = NULL;
+ struct iatt *iatt1, *iatt2;
+ struct mdata_iatt *mdata_iatt1, *mdata_iatt2;
- dict = get_new_dict_full(1);
+ if (!one || !two || !one->data || !two->data) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "input arguments are provided "
+ "with value data_t as NULL");
+ return -1;
+ }
- if (dict)
- dict_ref (dict);
+ if (one == two)
+ return 1;
- return dict;
-}
+ if (one->data == two->data)
+ return 1;
-int32_t
-is_data_equal (data_t *one,
- data_t *two)
-{
- if (!one || !two || !one->data || !two->data) {
- gf_msg_callingfn ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG,
- "input arguments are provided "
- "with value data_t as NULL");
- return -1;
- }
+ if (one->data_type != two->data_type) {
+ return 0;
+ }
- if (one == two)
- return 1;
+ if (one->data_type == GF_DATA_TYPE_IATT) {
+ if ((one->len < sizeof(struct iatt)) ||
+ (two->len < sizeof(struct iatt))) {
+ return 0;
+ }
+
+ iatt1 = (struct iatt *)one->data;
+ iatt2 = (struct iatt *)two->data;
- if (one->len != two->len)
+ /* Two iatt structs are considered equal if main fields are
+ * equal, even if times differ.
+ * TODO: maybe when ctime if fully operational we could
+ * enforce time matching. */
+ if (iatt1->ia_ino != iatt2->ia_ino) {
+ return 0;
+ }
+ if (iatt1->ia_type != iatt2->ia_type) {
+ return 0;
+ }
+ if ((iatt1->ia_type == IA_IFBLK) || (iatt1->ia_type == IA_IFCHR)) {
+ if (iatt1->ia_rdev != iatt2->ia_rdev) {
return 0;
+ }
+ }
+ if (gf_uuid_compare(iatt1->ia_gfid, iatt2->ia_gfid) != 0) {
+ return 0;
+ }
- if (one->data == two->data)
- return 1;
+ /* TODO: ia_uid, ia_gid, ia_prot and ia_size can be changed
+ * with some commands. Here we don't have enough
+ * information to decide if they should match or not. */
+ /*
+ if ((iatt1->ia_uid != iatt2->ia_uid) ||
+ (iatt1->ia_gid != iatt2->ia_gid) ||
+ (st_mode_from_ia(iatt1->ia_prot, iatt1->ia_type) !=
+ st_mode_from_ia(iatt2->ia_prot,
+ iatt2->ia_type))) { return 0;
+ }
+ if (iatt1->ia_type == IA_IFREG) {
+ if (iatt1->ia_size != iatt2->ia_size) {
+ return 0;
+ }
+ }
+ */
+ return 1;
+ }
+ if (one->data_type == GF_DATA_TYPE_MDATA) {
+ if ((one->len < sizeof(struct mdata_iatt)) ||
+ (two->len < sizeof(struct mdata_iatt))) {
+ return 0;
+ }
+ mdata_iatt1 = (struct mdata_iatt *)one->data;
+ mdata_iatt2 = (struct mdata_iatt *)two->data;
+
+ if (mdata_iatt1->ia_atime != mdata_iatt2->ia_atime ||
+ mdata_iatt1->ia_mtime != mdata_iatt2->ia_mtime ||
+ mdata_iatt1->ia_ctime != mdata_iatt2->ia_ctime ||
+ mdata_iatt1->ia_atime_nsec != mdata_iatt2->ia_atime_nsec ||
+ mdata_iatt1->ia_mtime_nsec != mdata_iatt2->ia_mtime_nsec ||
+ mdata_iatt1->ia_ctime_nsec != mdata_iatt2->ia_ctime_nsec) {
+ return 0;
+ }
+ return 1;
+ }
+
+ if (one->len != two->len)
+ return 0;
- if (memcmp (one->data, two->data, one->len) == 0)
- return 1;
+ if (memcmp(one->data, two->data, one->len) == 0)
+ return 1;
- return 0;
+ return 0;
}
static int
-key_value_cmp (dict_t *one, char *key1, data_t *value1, void *data)
+key_value_cmp(dict_t *one, char *key1, data_t *value1, void *data)
{
- struct dict_cmp *cmp = data;
- dict_t *two = NULL;
- data_t *value2 = NULL;
+ struct dict_cmp *cmp = data;
+ dict_t *two = cmp->dict;
+ data_t *value2 = dict_get(two, key1);
- two = cmp->dict;
- value2 = dict_get (two, key1);
+ if (value2) {
+ if (cmp->value_ignore && cmp->value_ignore(key1))
+ return 0;
- if (value2) {
- if (cmp->value_ignore && cmp->value_ignore (key1))
- return 0;
+ if (is_data_equal(value1, value2) == 1)
+ return 0;
+ }
- if (is_data_equal (value1, value2) == 1)
- return 0;
- }
-
- if (value2 == NULL) {
- gf_msg_debug (THIS->name, 0, "'%s' found only on one dict",
- key1);
- } else {
- gf_msg_debug (THIS->name, 0, "'%s' is different in two dicts "
- "(%u, %u)", key1, value1->len, value2->len);
- }
+ if (value2 == NULL) {
+ gf_msg_debug(THIS->name, 0, "'%s' found only on one dict", key1);
+ } else {
+ gf_msg_debug(THIS->name, 0,
+ "'%s' is different in two dicts "
+ "(%u, %u)",
+ key1, value1->len, value2->len);
+ }
- return -1;
+ return -1;
}
/* If both dicts are NULL then equal. If one of the dicts is NULL but the
@@ -172,1031 +247,1087 @@ key_value_cmp (dict_t *one, char *key1, data_t *value1, void *data)
* different.
*/
gf_boolean_t
-are_dicts_equal (dict_t *one, dict_t *two,
- gf_boolean_t (*match) (dict_t *d, char *k, data_t *v,
- void *data),
- gf_boolean_t (*value_ignore) (char *k))
-{
- int num_matches1 = 0;
- int num_matches2 = 0;
- struct dict_cmp cmp = {0};
-
- if (one == two)
- return _gf_true;
-
- if (!match)
- match = dict_match_everything;
-
- cmp.dict = two;
- cmp.value_ignore = value_ignore;
- if (!two) {
- num_matches1 = dict_foreach_match (one, match, NULL,
- dict_null_foreach_fn, NULL);
- goto done;
- } else {
- num_matches1 = dict_foreach_match (one, match, NULL,
- key_value_cmp, &cmp);
- }
+are_dicts_equal(dict_t *one, dict_t *two,
+ gf_boolean_t (*match)(dict_t *d, char *k, data_t *v,
+ void *data),
+ gf_boolean_t (*value_ignore)(char *k))
+{
+ int num_matches1 = 0;
+ int num_matches2 = 0;
+ struct dict_cmp cmp = {0};
+
+ if (one == two)
+ return _gf_true;
- if (num_matches1 == -1)
- return _gf_false;
+ if (!match)
+ match = dict_match_everything;
- if ((num_matches1 == one->count) && (one->count == two->count))
- return _gf_true;
+ if ((one == NULL) || (two == NULL)) {
+ num_matches1 = dict_foreach_match(one ? one : two, match, NULL,
+ dict_null_foreach_fn, NULL);
+ goto done;
+ }
- num_matches2 = dict_foreach_match (two, match, NULL,
- dict_null_foreach_fn, NULL);
-done:
- /* If the number of matches is same in 'two' then for all the
- * valid-keys that exist in 'one' the value matched and no extra valid
- * keys exist in 'two' alone. Otherwise there exists at least one extra
- * valid-key in 'two' which doesn't exist in 'one' */
- if (num_matches1 == num_matches2)
- return _gf_true;
+ cmp.dict = two;
+ cmp.value_ignore = value_ignore;
+ num_matches1 = dict_foreach_match(one, match, NULL, key_value_cmp, &cmp);
+
+ if (num_matches1 == -1)
return _gf_false;
+
+ if ((num_matches1 == one->count) && (one->count == two->count))
+ return _gf_true;
+
+ num_matches2 = dict_foreach_match(two, match, NULL, dict_null_foreach_fn,
+ NULL);
+done:
+ /* If the number of matches is same in 'two' then for all the
+ * valid-keys that exist in 'one' the value matched and no extra valid
+ * keys exist in 'two' alone. Otherwise there exists at least one extra
+ * valid-key in 'two' which doesn't exist in 'one' */
+ if (num_matches1 == num_matches2)
+ return _gf_true;
+ return _gf_false;
}
void
-data_destroy (data_t *data)
+data_destroy(data_t *data)
{
- if (data) {
- LOCK_DESTROY (&data->lock);
-
- if (!data->is_static)
- GF_FREE (data->data);
+ if (data) {
+ if (!data->is_static)
+ GF_FREE(data->data);
- data->len = 0xbabababa;
- if (!data->is_const)
- mem_put (data);
- }
+ data->len = 0xbabababa;
+ mem_put(data);
+ }
}
data_t *
-data_copy (data_t *old)
+data_copy(data_t *old)
{
- if (!old) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, 0, LG_MSG_NULL_PTR,
- "old is NULL");
- return NULL;
- }
+ if (!old) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, 0, LG_MSG_NULL_PTR,
+ "old is NULL");
+ return NULL;
+ }
- data_t *newdata = mem_get0 (THIS->ctx->dict_data_pool);
- if (!newdata) {
- return NULL;
- }
+ data_t *newdata = mem_get0(THIS->ctx->dict_data_pool);
+ if (!newdata) {
+ return NULL;
+ }
- if (old) {
- newdata->len = old->len;
- if (old->data) {
- newdata->data = memdup (old->data, old->len);
- if (!newdata->data)
- goto err_out;
- }
- }
+ newdata->len = old->len;
+ if (old->data) {
+ newdata->data = gf_memdup(old->data, old->len);
+ if (!newdata->data)
+ goto err_out;
+ }
+ newdata->data_type = old->data_type;
- LOCK_INIT (&newdata->lock);
- return newdata;
+ return newdata;
err_out:
+ mem_put(newdata);
- FREE (newdata->data);
- mem_put (newdata);
-
- return NULL;
+ return NULL;
}
+/* Always need to be called under lock
+ * Always this and key variables are not null -
+ * checked by callers.
+ */
static data_pair_t *
-dict_lookup_common (dict_t *this, char *key)
-{
- int hashval = 0;
- if (!this || !key) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG,
- "!this || !key (%s)", key);
- return NULL;
- }
-
- /* If the divisor is 1, the modulo is always 0,
- * in such case avoid hash calculation.
- */
- if (this->hash_size != 1)
- hashval = SuperFastHash (key, strlen (key)) % this->hash_size;
+dict_lookup_common(const dict_t *this, const char *key, const uint32_t hash)
+{
+ int hashval = 0;
+ data_pair_t *pair;
- data_pair_t *pair;
+ /* If the divisor is 1, the modulo is always 0,
+ * in such case avoid hash calculation.
+ */
+ if (this->hash_size != 1)
+ hashval = hash % this->hash_size;
- for (pair = this->members[hashval]; pair != NULL; pair = pair->hash_next) {
- if (pair->key && !strcmp (pair->key, key))
- return pair;
- }
+ for (pair = this->members[hashval]; pair != NULL; pair = pair->hash_next) {
+ if (pair->key && (hash == pair->key_hash) && !strcmp(pair->key, key))
+ return pair;
+ }
- return NULL;
+ return NULL;
}
int32_t
-dict_lookup (dict_t *this, char *key, data_t **data)
+dict_lookup(dict_t *this, char *key, data_t **data)
{
- if (!this || !key || !data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!this || !key || "
- "!data");
- return -1;
- }
+ if (!this || !key || !data) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || !key || "
+ "!data");
+ return -1;
+ }
- data_pair_t *tmp = NULL;
- LOCK (&this->lock);
- {
- tmp = dict_lookup_common (this, key);
- }
- UNLOCK (&this->lock);
+ data_pair_t *tmp = NULL;
- if (!tmp)
- return -1;
+ uint32_t hash = (uint32_t)XXH64(key, strlen(key), 0);
- *data = tmp->value;
- return 0;
+ LOCK(&this->lock);
+ {
+ tmp = dict_lookup_common(this, key, hash);
+ }
+ UNLOCK(&this->lock);
+
+ if (!tmp)
+ return -1;
+
+ *data = tmp->value;
+ return 0;
}
static int32_t
-dict_set_lk (dict_t *this, char *key, data_t *value, gf_boolean_t replace)
-{
- int hashval = 0;
- data_pair_t *pair;
- char key_free = 0;
- int tmp = 0;
- int ret = 0;
-
- if (!key) {
- ret = gf_asprintf (&key, "ref:%p", value);
- if (-1 == ret) {
- return -1;
- }
- key_free = 1;
- }
+dict_set_lk(dict_t *this, char *key, const int key_len, data_t *value,
+ const uint32_t hash, gf_boolean_t replace)
+{
+ int hashval = 0;
+ data_pair_t *pair;
+ int key_free = 0;
+ uint32_t key_hash;
+ int keylen;
+
+ if (!key) {
+ keylen = gf_asprintf(&key, "ref:%p", value);
+ if (-1 == keylen) {
+ return -1;
+ }
+ key_free = 1;
+ key_hash = (uint32_t)XXH64(key, keylen, 0);
+ } else {
+ keylen = key_len;
+ key_hash = hash;
+ }
+
+ /* Search for a existing key if 'replace' is asked for */
+ if (replace) {
+ pair = dict_lookup_common(this, key, key_hash);
+ if (pair) {
+ data_t *unref_data = pair->value;
+ pair->value = data_ref(value);
+ this->totkvlen += (value->len - unref_data->len);
+ data_unref(unref_data);
+ if (key_free)
+ GF_FREE(key);
+ /* Indicates duplicate key */
+ return 0;
+ }
+ }
+
+ if (this->free_pair.key) { /* the free_pair is used */
+ pair = mem_get(THIS->ctx->dict_pair_pool);
+ if (!pair) {
+ if (key_free)
+ GF_FREE(key);
+ return -1;
+ }
+ } else { /* assign the pair to the free pair */
+ pair = &this->free_pair;
+ }
+
+ if (key_free) {
+ /* It's ours. Use it. */
+ pair->key = key;
+ key_free = 0;
+ } else {
+ pair->key = (char *)GF_MALLOC(keylen + 1, gf_common_mt_char);
+ if (!pair->key) {
+ if (pair != &this->free_pair) {
+ mem_put(pair);
+ }
+ return -1;
+ }
+ strcpy(pair->key, key);
+ }
+ pair->key_hash = key_hash;
+ pair->value = data_ref(value);
+ this->totkvlen += (keylen + 1 + value->len);
+
+ /* If the divisor is 1, the modulo is always 0,
+ * in such case avoid hash calculation.
+ */
+ if (this->hash_size != 1) {
+ hashval = (key_hash % this->hash_size);
+ }
+ pair->hash_next = this->members[hashval];
+ this->members[hashval] = pair;
+
+ pair->next = this->members_list;
+ pair->prev = NULL;
+ if (this->members_list)
+ this->members_list->prev = pair;
+ this->members_list = pair;
+ this->count++;
+
+ if (key_free)
+ GF_FREE(key);
+
+ if (this->max_count < this->count)
+ this->max_count = this->count;
+ return 0;
+}
- /* If the divisor is 1, the modulo is always 0,
- * in such case avoid hash calculation.
- */
- if (this->hash_size != 1) {
- tmp = SuperFastHash (key, strlen (key));
- hashval = (tmp % this->hash_size);
- }
+int32_t
+dict_set(dict_t *this, char *key, data_t *value)
+{
+ if (key)
+ return dict_setn(this, key, strlen(key), value);
+ else
+ return dict_setn(this, NULL, 0, value);
+}
- /* Search for a existing key if 'replace' is asked for */
- if (replace) {
- pair = dict_lookup_common (this, key);
-
- if (pair) {
- data_t *unref_data = pair->value;
- pair->value = data_ref (value);
- data_unref (unref_data);
- if (key_free)
- GF_FREE (key);
- /* Indicates duplicate key */
- return 0;
- }
- }
+int32_t
+dict_setn(dict_t *this, char *key, const int keylen, data_t *value)
+{
+ int32_t ret;
+ uint32_t key_hash = 0;
- if (this->free_pair_in_use) {
- pair = mem_get0 (THIS->ctx->dict_pair_pool);
- if (!pair) {
- if (key_free)
- GF_FREE (key);
- return -1;
- }
- }
- else {
- pair = &this->free_pair;
- this->free_pair_in_use = _gf_true;
- }
+ if (!this || !value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || !value for "
+ "key=%s",
+ key);
+ return -1;
+ }
- if (key_free) {
- /* It's ours. Use it. */
- pair->key = key;
- key_free = 0;
- }
- else {
- pair->key = (char *) GF_CALLOC (1, strlen (key) + 1,
- gf_common_mt_char);
- if (!pair->key) {
- if (pair == &this->free_pair) {
- this->free_pair_in_use = _gf_false;
- }
- else {
- mem_put (pair);
- }
- return -1;
- }
- strcpy (pair->key, key);
- }
- pair->value = data_ref (value);
+ if (key) {
+ key_hash = (uint32_t)XXH64(key, keylen, 0);
+ }
- pair->hash_next = this->members[hashval];
- this->members[hashval] = pair;
+ LOCK(&this->lock);
- pair->next = this->members_list;
- pair->prev = NULL;
- if (this->members_list)
- this->members_list->prev = pair;
- this->members_list = pair;
- this->count++;
+ ret = dict_set_lk(this, key, keylen, value, key_hash, 1);
- if (key_free)
- GF_FREE (key);
- return 0;
+ UNLOCK(&this->lock);
+
+ return ret;
}
int32_t
-dict_set (dict_t *this,
- char *key,
- data_t *value)
+dict_add(dict_t *this, char *key, data_t *value)
{
- int32_t ret;
+ if (key)
+ return dict_addn(this, key, strlen(key), value);
+ else
+ return dict_addn(this, NULL, 0, value);
+}
- if (!this || !value) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!this || !value for "
- "key=%s", key);
- return -1;
- }
+int32_t
+dict_addn(dict_t *this, char *key, const int keylen, data_t *value)
+{
+ int32_t ret;
+ uint32_t key_hash = 0;
- LOCK (&this->lock);
+ if (!this || !value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || !value for key=%s", key);
+ return -1;
+ }
- ret = dict_set_lk (this, key, value, 1);
+ if (key) {
+ key_hash = (uint32_t)XXH64(key, keylen, 0);
+ }
- UNLOCK (&this->lock);
+ LOCK(&this->lock);
- return ret;
+ ret = dict_set_lk(this, key, keylen, value, key_hash, 0);
+
+ UNLOCK(&this->lock);
+
+ return ret;
}
+data_t *
+dict_get(dict_t *this, char *key)
+{
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || key=%s", (key) ? key : "()");
+ return NULL;
+ }
-int32_t
-dict_add (dict_t *this, char *key, data_t *value)
+ return dict_getn(this, key, strlen(key));
+}
+
+data_t *
+dict_getn(dict_t *this, char *key, const int keylen)
{
- int32_t ret;
+ data_pair_t *pair;
+ uint32_t hash;
- if (!this || !value) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG,
- "!this || !value for key=%s", key);
- return -1;
- }
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || key=%s", (key) ? key : "()");
+ return NULL;
+ }
- LOCK (&this->lock);
+ hash = (uint32_t)XXH64(key, keylen, 0);
- ret = dict_set_lk (this, key, value, 0);
+ LOCK(&this->lock);
+ {
+ pair = dict_lookup_common(this, key, hash);
+ }
+ UNLOCK(&this->lock);
- UNLOCK (&this->lock);
+ if (pair)
+ return pair->value;
- return ret;
+ return NULL;
}
-
-data_t *
-dict_get (dict_t *this, char *key)
+int
+dict_key_count(dict_t *this)
{
- data_pair_t *pair;
-
- if (!this || !key) {
- gf_msg_callingfn ("dict", GF_LOG_INFO, EINVAL,
- LG_MSG_INVALID_ARG,
- "!this || key=%s", (key) ? key : "()");
- return NULL;
- }
+ int ret = -1;
- LOCK (&this->lock);
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict passed is NULL");
+ return ret;
+ }
- pair = dict_lookup_common (this, key);
+ LOCK(&this->lock);
+ {
+ ret = this->count;
+ }
+ UNLOCK(&this->lock);
- UNLOCK (&this->lock);
+ return ret;
+}
- if (pair)
- return pair->value;
+void
+dict_del(dict_t *this, char *key)
+{
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || key=%s", key);
+ return;
+ }
- return NULL;
+ return dict_deln(this, key, strlen(key));
}
void
-dict_del (dict_t *this, char *key)
+dict_deln(dict_t *this, char *key, const int keylen)
{
- int hashval = 0;
+ int hashval = 0;
+ uint32_t hash;
- if (!this || !key) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!this || key=%s", key);
- return;
- }
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!this || key=%s", key);
+ return;
+ }
- LOCK (&this->lock);
+ hash = (uint32_t)XXH64(key, keylen, 0);
- /* If the divisor is 1, the modulo is always 0,
- * in such case avoid hash calculation.
- */
- if (this->hash_size != 1)
- hashval = SuperFastHash (key, strlen (key)) % this->hash_size;
+ LOCK(&this->lock);
- data_pair_t *pair = this->members[hashval];
- data_pair_t *prev = NULL;
+ /* If the divisor is 1, the modulo is always 0,
+ * in such case avoid hash calculation.
+ */
+ if (this->hash_size != 1)
+ hashval = hash % this->hash_size;
- while (pair) {
- if (strcmp (pair->key, key) == 0) {
- if (prev)
- prev->hash_next = pair->hash_next;
- else
- this->members[hashval] = pair->hash_next;
+ data_pair_t *pair = this->members[hashval];
+ data_pair_t *prev = NULL;
- data_unref (pair->value);
+ while (pair) {
+ if ((hash == pair->key_hash) && strcmp(pair->key, key) == 0) {
+ if (prev)
+ prev->hash_next = pair->hash_next;
+ else
+ this->members[hashval] = pair->hash_next;
- if (pair->prev)
- pair->prev->next = pair->next;
- else
- this->members_list = pair->next;
+ this->totkvlen -= pair->value->len;
+ data_unref(pair->value);
- if (pair->next)
- pair->next->prev = pair->prev;
+ if (pair->prev)
+ pair->prev->next = pair->next;
+ else
+ this->members_list = pair->next;
- GF_FREE (pair->key);
- if (pair == &this->free_pair) {
- this->free_pair_in_use = _gf_false;
- }
- else {
- mem_put (pair);
- }
- this->count--;
- break;
- }
+ if (pair->next)
+ pair->next->prev = pair->prev;
- prev = pair;
- pair = pair->hash_next;
+ this->totkvlen -= (strlen(pair->key) + 1);
+ GF_FREE(pair->key);
+ if (pair == &this->free_pair) {
+ this->free_pair.key = NULL;
+ } else {
+ mem_put(pair);
+ }
+ this->count--;
+ break;
}
- UNLOCK (&this->lock);
+ prev = pair;
+ pair = pair->hash_next;
+ }
- return;
+ UNLOCK(&this->lock);
+
+ return;
}
void
-dict_destroy (dict_t *this)
+dict_destroy(dict_t *this)
{
- if (!this) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is NULL");
- return;
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return;
+ }
+
+ data_pair_t *pair = this->members_list;
+ data_pair_t *prev = this->members_list;
+ glusterfs_ctx_t *ctx = NULL;
+ uint64_t current_max = 0;
+ uint32_t total_pairs = 0;
+
+ LOCK_DESTROY(&this->lock);
+
+ while (prev) {
+ pair = pair->next;
+ data_unref(prev->value);
+ GF_FREE(prev->key);
+ if (prev != &this->free_pair) {
+ mem_put(prev);
+ } else {
+ this->free_pair.key = NULL;
}
+ total_pairs++;
+ prev = pair;
+ }
- data_pair_t *pair = this->members_list;
- data_pair_t *prev = this->members_list;
+ this->totkvlen = 0;
+ if (this->members != &this->members_internal) {
+ mem_put(this->members);
+ }
- LOCK_DESTROY (&this->lock);
+ free(this->extra_stdfree);
- while (prev) {
- pair = pair->next;
- data_unref (prev->value);
- GF_FREE (prev->key);
- if (prev != &this->free_pair) {
- mem_put (prev);
- }
- prev = pair;
- }
+ /* update 'ctx->stats.dict.details' using max_count */
+ ctx = THIS->ctx;
- if (this->members != &this->members_internal) {
- mem_put (this->members);
- }
+ /* NOTE: below logic is not totaly race proof */
+ /* thread0 and thread1 gets current_max as 10 */
+ /* thread0 has 'this->max_count as 11 */
+ /* thread1 has 'this->max_count as 20 */
+ /* thread1 goes ahead and sets the max_dict_pairs to 20 */
+ /* thread0 then goes and sets it to 11 */
+ /* As it is for information purpose only, no functionality will be
+ broken by this, but a point to consider about ATOMIC macros. */
+ current_max = GF_ATOMIC_GET(ctx->stats.max_dict_pairs);
+ if (current_max < this->max_count)
+ GF_ATOMIC_INIT(ctx->stats.max_dict_pairs, this->max_count);
- GF_FREE (this->extra_free);
- free (this->extra_stdfree);
+ GF_ATOMIC_ADD(ctx->stats.total_pairs_used, total_pairs);
+ GF_ATOMIC_INC(ctx->stats.total_dicts_used);
- if (!this->is_static)
- mem_put (this);
+ mem_put(this);
- return;
+ return;
}
void
-dict_unref (dict_t *this)
+dict_unref(dict_t *this)
{
- int32_t ref;
-
- if (!this) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is NULL");
- return;
- }
+ uint64_t ref = 0;
- LOCK (&this->lock);
-
- this->refcount--;
- ref = this->refcount;
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return;
+ }
- UNLOCK (&this->lock);
+ ref = GF_ATOMIC_DEC(this->refcount);
- if (!ref)
- dict_destroy (this);
+ if (!ref)
+ dict_destroy(this);
}
dict_t *
-dict_ref (dict_t *this)
+dict_ref(dict_t *this)
{
- if (!this) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is NULL");
- return NULL;
- }
-
- LOCK (&this->lock);
-
- this->refcount++;
-
- UNLOCK (&this->lock);
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_DEBUG, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return NULL;
+ }
- return this;
+ GF_ATOMIC_INC(this->refcount);
+ return this;
}
void
-data_unref (data_t *this)
+data_unref(data_t *this)
{
+ uint64_t ref;
- int32_t ref;
-
- if (!this) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is NULL");
- return;
- }
-
- LOCK (&this->lock);
-
- this->refcount--;
- ref = this->refcount;
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "data is NULL");
+ return;
+ }
- UNLOCK (&this->lock);
+ ref = GF_ATOMIC_DEC(this->refcount);
- if (!ref)
- data_destroy (this);
+ if (!ref)
+ data_destroy(this);
}
data_t *
-data_ref (data_t *this)
+data_ref(data_t *this)
{
- if (!this) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is NULL");
- return NULL;
- }
-
- LOCK (&this->lock);
-
- this->refcount++;
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "data is NULL");
+ return NULL;
+ }
- UNLOCK (&this->lock);
+ GF_ATOMIC_INC(this->refcount);
- return this;
+ return this;
}
data_t *
-int_to_data (int64_t value)
+int_to_data(int64_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
- ret = gf_asprintf (&data->data, "%"PRId64, value);
- if (-1 == ret) {
- gf_msg_debug ("dict", 0, "asprintf failed");
- return NULL;
- }
- data->len = strlen (data->data) + 1;
+ data->len = gf_asprintf(&data->data, "%" PRId64, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
- return data;
+ return data;
}
data_t *
-data_from_int64 (int64_t value)
+data_from_int64(int64_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRId64, value);
- if (-1 == ret) {
- gf_msg_debug ("dict", 0, "asprintf failed");
- return NULL;
- }
- data->len = strlen (data->data) + 1;
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRId64, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
- return data;
+ return data;
}
data_t *
-data_from_int32 (int32_t value)
+data_from_int32(int32_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRId32, value);
- if (-1 == ret) {
- gf_msg_debug ("dict", 0, "asprintf failed");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRId32, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
- return data;
+ return data;
}
data_t *
-data_from_int16 (int16_t value)
+data_from_int16(int16_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRId16, value);
- if (-1 == ret) {
- gf_msg_debug ("dict", 0, "asprintf failed");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRId16, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
- return data;
+ return data;
}
data_t *
-data_from_int8 (int8_t value)
+data_from_int8(int8_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%d", value);
- if (-1 == ret) {
- gf_msg_debug ("dict", 0, "asprintf failed");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%d", value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_INT;
- return data;
+ return data;
}
data_t *
-data_from_uint64 (uint64_t value)
+data_from_uint64(uint64_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRIu64, value);
- if (-1 == ret) {
- gf_msg_debug ("dict", 0, "asprintf failed");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRIu64, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_UINT;
- return data;
+ return data;
}
-static data_t *
-data_from_double (double value)
+data_t *
+data_from_double(double value)
{
- data_t *data = NULL;
- int ret = 0;
-
- data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
- ret = gf_asprintf (&data->data, "%f", value);
- if (ret == -1) {
- return NULL;
- }
- data->len = strlen (data->data) + 1;
+ data->len = gf_asprintf(&data->data, "%f", value);
+ if (data->len == -1) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_DOUBLE;
- return data;
+ return data;
}
-
data_t *
-data_from_uint32 (uint32_t value)
+data_from_uint32(uint32_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRIu32, value);
- if (-1 == ret) {
- gf_msg_debug ("dict", 0, "asprintf failed");
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRIu32, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_UINT;
- return data;
+ return data;
}
-
data_t *
-data_from_uint16 (uint16_t value)
+data_from_uint16(uint16_t value)
{
- int ret = 0;
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data) {
- return NULL;
- }
- ret = gf_asprintf (&data->data, "%"PRIu16, value);
- if (-1 == ret) {
- return NULL;
- }
+ if (!data) {
+ return NULL;
+ }
+ data->len = gf_asprintf(&data->data, "%" PRIu16, value);
+ if (-1 == data->len) {
+ gf_msg_debug("dict", 0, "asprintf failed");
+ data_destroy(data);
+ return NULL;
+ }
- data->len = strlen (data->data) + 1;
+ data->len++; /* account for terminating NULL */
+ data->data_type = GF_DATA_TYPE_UINT;
- return data;
+ return data;
}
static data_t *
-data_from_ptr_common (void *value, gf_boolean_t is_static)
+data_from_ptr_common(void *value, gf_boolean_t is_static)
{
- /* it is valid to set 0/NULL as a value, no need to check *value */
+ /* it is valid to set 0/NULL as a value, no need to check *value */
- data_t *data = get_new_data ();
- if (!data) {
- return NULL;
- }
+ data_t *data = get_new_data();
+ if (!data) {
+ return NULL;
+ }
- data->data = value;
- data->is_static = is_static;
+ data->data = value;
+ data->len = 0;
+ data->is_static = is_static;
- return data;
+ data->data_type = GF_DATA_TYPE_PTR;
+ return data;
}
data_t *
-str_to_data (char *value)
+str_to_data(char *value)
{
- if (!value) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "value is NULL");
- return NULL;
- }
- data_t *data = get_new_data ();
+ if (!value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "value is NULL");
+ return NULL;
+ }
- if (!data) {
- return NULL;
- }
- data->len = strlen (value) + 1;
+ return strn_to_data(value, strlen(value));
+}
+
+data_t *
+strn_to_data(char *value, const int vallen)
+{
+ if (!value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "value is NULL");
+ return NULL;
+ }
+ data_t *data = get_new_data();
+
+ if (!data) {
+ return NULL;
+ }
+ data->len = vallen + 1;
+ data->data_type = GF_DATA_TYPE_STR;
- data->data = value;
- data->is_static = 1;
+ data->data = value;
+ data->is_static = _gf_true;
- return data;
+ return data;
}
-data_t *
-data_from_dynstr (char *value)
+static data_t *
+data_from_dynstr(char *value)
{
- if (!value) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "value is NULL");
- return NULL;
- }
+ if (!value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "value is NULL");
+ return NULL;
+ }
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data)
- return NULL;
- data->len = strlen (value) + 1;
- data->data = value;
+ if (!data)
+ return NULL;
+ data->len = strlen(value) + 1;
+ data->data = value;
+ data->data_type = GF_DATA_TYPE_STR;
- return data;
+ return data;
}
data_t *
-data_from_dynptr (void *value, int32_t len)
+data_from_dynptr(void *value, int32_t len)
{
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data)
- return NULL;
+ if (!data)
+ return NULL;
- data->len = len;
- data->data = value;
+ data->len = len;
+ data->data = value;
+ data->data_type = GF_DATA_TYPE_PTR;
- return data;
+ return data;
}
data_t *
-bin_to_data (void *value, int32_t len)
+bin_to_data(void *value, int32_t len)
{
- if (!value) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "value is NULL");
- return NULL;
- }
+ if (!value) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "value is NULL");
+ return NULL;
+ }
- data_t *data = get_new_data ();
+ data_t *data = get_new_data();
- if (!data)
- return NULL;
+ if (!data)
+ return NULL;
- data->is_static = 1;
- data->len = len;
- data->data = value;
+ data->is_static = _gf_true;
+ data->len = len;
+ data->data = value;
- return data;
+ return data;
}
+static char *data_type_name[GF_DATA_TYPE_MAX] = {
+ [GF_DATA_TYPE_UNKNOWN] = "unknown",
+ [GF_DATA_TYPE_STR_OLD] = "string-old-version",
+ [GF_DATA_TYPE_INT] = "integer",
+ [GF_DATA_TYPE_UINT] = "unsigned integer",
+ [GF_DATA_TYPE_DOUBLE] = "float",
+ [GF_DATA_TYPE_STR] = "string",
+ [GF_DATA_TYPE_PTR] = "pointer",
+ [GF_DATA_TYPE_GFUUID] = "gf-uuid",
+ [GF_DATA_TYPE_IATT] = "iatt",
+ [GF_DATA_TYPE_MDATA] = "mdata",
+};
+
int64_t
-data_to_int64 (data_t *data)
+data_to_int64(data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return -1;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+ char *endptr = NULL;
+ int64_t value = 0;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
- return (int64_t) strtoull (str, NULL, 0);
-}
+ errno = 0;
+ value = strtoll(data->data, &endptr, 0);
+
+ if (endptr && *endptr != '\0')
+ /* Unrecognized characters at the end of string. */
+ errno = EINVAL;
+ if (errno) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, errno,
+ LG_MSG_DATA_CONVERSION_ERROR,
+ "Error in data conversion: '%s' can't "
+ "be represented as int64_t",
+ data->data);
+ return -1;
+ }
+ return value;
+}
+
+/* Like above but implies signed range check. */
+
+#define DATA_TO_RANGED_SIGNED(endptr, value, data, type, min, max) \
+ do { \
+ errno = 0; \
+ value = strtoll(data->data, &endptr, 0); \
+ if (endptr && *endptr != '\0') \
+ errno = EINVAL; \
+ if (errno || value > max || value < min) { \
+ gf_msg_callingfn("dict", GF_LOG_WARNING, errno, \
+ LG_MSG_DATA_CONVERSION_ERROR, \
+ "Error in data conversion: '%s' can't " \
+ "be represented as " #type, \
+ data->data); \
+ return -1; \
+ } \
+ return (type)value; \
+ } while (0)
int32_t
-data_to_int32 (data_t *data)
+data_to_int32(data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return -1;
- }
-
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+ char *endptr = NULL;
+ int64_t value = 0;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- return strtoul (str, NULL, 0);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
+ DATA_TO_RANGED_SIGNED(endptr, value, data, int32_t, INT_MIN, INT_MAX);
}
int16_t
-data_to_int16 (data_t *data)
+data_to_int16(data_t *data)
{
- int16_t value = 0;
-
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "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);
+ char *endptr = NULL;
+ int64_t value = 0;
- if ((value > SHRT_MAX) || (value < SHRT_MIN)) {
- errno = ERANGE;
- gf_msg_callingfn ("dict", GF_LOG_WARNING, errno,
- LG_MSG_DATA_CONVERSION_ERROR, "Error in data"
- " conversion: detected overflow");
- return -1;
- }
-
- return (int16_t)value;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
+ DATA_TO_RANGED_SIGNED(endptr, value, data, int16_t, SHRT_MIN, SHRT_MAX);
}
-
int8_t
-data_to_int8 (data_t *data)
+data_to_int8(data_t *data)
{
- int8_t value = 0;
-
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return -1;
- }
-
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+ char *endptr = NULL;
+ int64_t value = 0;
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- value = strtol (str, NULL, 0);
-
- if ((value > SCHAR_MAX) || (value < SCHAR_MIN)) {
- errno = ERANGE;
- gf_msg_callingfn ("dict", GF_LOG_WARNING, errno,
- LG_MSG_DATA_CONVERSION_ERROR, "Error in data"
- " conversion: detected overflow");
- return -1;
- }
-
- return (int8_t)value;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, "null", -1);
+ DATA_TO_RANGED_SIGNED(endptr, value, data, int8_t, CHAR_MIN, CHAR_MAX);
}
-
uint64_t
-data_to_uint64 (data_t *data)
+data_to_uint64(data_t *data)
{
- if (!data)
- return -1;
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ char *endptr = NULL;
+ uint64_t value = 0;
- return strtoll (str, NULL, 0);
-}
+ errno = 0;
+ value = strtoull(data->data, &endptr, 0);
+
+ if (endptr && *endptr != '\0')
+ errno = EINVAL;
+ if (errno) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, errno,
+ LG_MSG_DATA_CONVERSION_ERROR,
+ "Error in data conversion: '%s' can't "
+ "be represented as uint64_t",
+ data->data);
+ return -1;
+ }
+ return value;
+}
+
+/* Like above but implies unsigned range check. */
+
+#define DATA_TO_RANGED_UNSIGNED(endptr, value, data, type, max) \
+ do { \
+ errno = 0; \
+ value = strtoull(data->data, &endptr, 0); \
+ if (endptr && *endptr != '\0') \
+ errno = EINVAL; \
+ if (errno || value > max) { \
+ gf_msg_callingfn("dict", GF_LOG_WARNING, errno, \
+ LG_MSG_DATA_CONVERSION_ERROR, \
+ "Error in data conversion: '%s' can't " \
+ "be represented as " #type, \
+ data->data); \
+ return -1; \
+ } \
+ return (type)value; \
+ } while (0)
uint32_t
-data_to_uint32 (data_t *data)
+data_to_uint32(data_t *data)
{
- if (!data)
- return -1;
-
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
-
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ char *endptr = NULL;
+ uint64_t value = 0;
- return strtol (str, NULL, 0);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
+ DATA_TO_RANGED_UNSIGNED(endptr, value, data, uint32_t, UINT_MAX);
}
uint16_t
-data_to_uint16 (data_t *data)
+data_to_uint16(data_t *data)
{
- uint16_t value = 0;
-
- if (!data)
- return -1;
-
- char *str = alloca (data->len + 1);
- if (!str)
- return -1;
-
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ char *endptr = NULL;
+ uint64_t value = 0;
- errno = 0;
- value = strtol (str, NULL, 0);
-
- if ((USHRT_MAX - value) < 0) {
- errno = ERANGE;
- gf_msg_callingfn ("dict", GF_LOG_WARNING, errno,
- LG_MSG_DATA_CONVERSION_ERROR,
- "Error in data conversion: "
- "overflow detected");
- return -1;
- }
-
- return (uint16_t)value;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
+ DATA_TO_RANGED_UNSIGNED(endptr, value, data, uint16_t, USHRT_MAX);
}
uint8_t
-data_to_uint8 (data_t *data)
+data_to_uint8(data_t *data)
{
- uint32_t value = 0;
-
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "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);
+ char *endptr = NULL;
+ uint64_t value = 0;
- if ((UCHAR_MAX - (uint8_t)value) < 0) {
- errno = ERANGE;
- gf_msg_callingfn ("dict", GF_LOG_WARNING, errno,
- LG_MSG_DATA_CONVERSION_ERROR, "data "
- "conversion overflow detected");
- return -1;
- }
-
- return (uint8_t) value;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, "null", -1);
+ DATA_TO_RANGED_UNSIGNED(endptr, value, data, uint8_t, UCHAR_MAX);
}
char *
-data_to_str (data_t *data)
+data_to_str(data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return NULL;
- }
- return data->data;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, "null", NULL);
+ return data->data;
}
void *
-data_to_ptr (data_t *data)
+data_to_ptr(data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return NULL;
- }
- return data->data;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, "null", NULL);
+ return data->data;
}
void *
-data_to_bin (data_t *data)
+data_to_bin(data_t *data)
{
- if (!data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "data is NULL");
- return NULL;
- }
- return data->data;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, "null", NULL);
+ return data->data;
+}
+
+struct iatt *
+data_to_iatt(data_t *data, char *key)
+{
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_IATT, key, NULL);
+
+ /* We only check for smaller size. If it's bigger we simply ignore
+ * the extra data. This way it's easy to do changes in the future that
+ * pass more data but are backward compatible (if the initial contents
+ * of the struct are maintained, of course). */
+ if (data->len < sizeof(struct iatt)) {
+ gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF,
+ "key=%s", key, NULL);
+ return NULL;
+ }
+
+ return (struct iatt *)data->data;
}
int
-dict_null_foreach_fn (dict_t *d, char *k,
- data_t *v, void *tmp)
+dict_null_foreach_fn(dict_t *d, char *k, data_t *v, void *tmp)
{
- return 0;
+ return 0;
}
int
-dict_remove_foreach_fn (dict_t *d, char *k,
- data_t *v, void *_tmp)
-{
- if (!d || !k) {
- gf_msg ("glusterfs", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ENTRY, "%s is NULL",
- d?"key":"dictionary");
- return -1;
- }
+dict_remove_foreach_fn(dict_t *d, char *k, data_t *v, void *_tmp)
+{
+ if (!d || !k) {
+ gf_smsg("glusterfs", GF_LOG_WARNING, EINVAL, LG_MSG_KEY_OR_VALUE_NULL,
+ "d=%s", d ? "key" : "dictionary", NULL);
+ return -1;
+ }
- dict_del (d, k);
- return 0;
+ dict_del(d, k);
+ return 0;
}
gf_boolean_t
-dict_match_everything (dict_t *d, char *k, data_t *v, void *data)
+dict_match_everything(dict_t *d, char *k, data_t *v, void *data)
{
- return _gf_true;
+ return _gf_true;
}
int
-dict_foreach (dict_t *dict,
- int (*fn)(dict_t *this,
- char *key,
- data_t *value,
- void *data),
- void *data)
+dict_foreach(dict_t *dict,
+ int (*fn)(dict_t *this, char *key, data_t *value, void *data),
+ void *data)
{
- int ret = 0;
+ int ret = dict_foreach_match(dict, dict_match_everything, NULL, fn, data);
- ret = dict_foreach_match (dict, dict_match_everything, NULL, fn, data);
-
- if (ret > 0)
- ret = 0;
+ if (ret > 0)
+ ret = 0;
- return ret;
+ return ret;
}
/* return values:
@@ -1205,50 +1336,44 @@ dict_foreach (dict_t *dict,
+n = n number of matches
*/
int
-dict_foreach_match (dict_t *dict,
- gf_boolean_t (*match)(dict_t *this,
- char *key,
- data_t *value,
- void *mdata),
- void *match_data,
- int (*action)(dict_t *this,
- char *key,
- data_t *value,
- void *adata),
- void *action_data)
-{
- if (!dict || !match || !action) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict|match|action is "
- "NULL");
- return -1;
- }
+dict_foreach_match(dict_t *dict,
+ gf_boolean_t (*match)(dict_t *this, char *key, data_t *value,
+ void *mdata),
+ void *match_data,
+ int (*action)(dict_t *this, char *key, data_t *value,
+ void *adata),
+ void *action_data)
+{
+ if (!dict || !match || !action) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict|match|action is "
+ "NULL");
+ return -1;
+ }
- int ret = -1;
- int count = 0;
- data_pair_t *pairs = NULL;
- data_pair_t *next = NULL;
-
- pairs = dict->members_list;
- while (pairs) {
- next = pairs->next;
- if (match (dict, pairs->key, pairs->value, match_data)) {
- ret = action (dict, pairs->key, pairs->value,
- action_data);
- if (ret < 0)
- return ret;
- count++;
- }
- pairs = next;
+ int ret = -1;
+ int count = 0;
+ data_pair_t *pairs = dict->members_list;
+ data_pair_t *next = NULL;
+
+ while (pairs) {
+ next = pairs->next;
+ if (match(dict, pairs->key, pairs->value, match_data)) {
+ ret = action(dict, pairs->key, pairs->value, action_data);
+ if (ret < 0)
+ return ret;
+ count++;
}
+ pairs = next;
+ }
- return count;
+ return count;
}
static gf_boolean_t
-dict_fnmatch (dict_t *d, char *k, data_t *val, void *match_data)
+dict_fnmatch(dict_t *d, char *k, data_t *val, void *match_data)
{
- return (fnmatch (match_data, k, 0) == 0);
+ return (fnmatch(match_data, k, 0) == 0);
}
/* return values:
-1 = failure,
@@ -1256,17 +1381,14 @@ dict_fnmatch (dict_t *d, char *k, data_t *val, void *match_data)
+n = n number of matches
*/
int
-dict_foreach_fnmatch (dict_t *dict, char *pattern,
- int (*fn)(dict_t *this,
- char *key,
- data_t *value,
- void *data),
- void *data)
+dict_foreach_fnmatch(dict_t *dict, char *pattern,
+ int (*fn)(dict_t *this, char *key, data_t *value,
+ void *data),
+ void *data)
{
- return dict_foreach_match (dict, dict_fnmatch, pattern, fn, data);
+ return dict_foreach_match(dict, dict_fnmatch, pattern, fn, data);
}
-
/**
* dict_keys_join - pack the keys of the dictionary in a buffer.
*
@@ -1281,89 +1403,85 @@ dict_foreach_fnmatch (dict_t *dict, char *pattern,
*/
int
-dict_keys_join (void *value, int size, dict_t *dict,
- int (*filter_fn)(char *k))
+dict_keys_join(void *value, int size, dict_t *dict, int (*filter_fn)(char *k))
{
- int len = 0;
- data_pair_t *pairs = NULL;
- data_pair_t *next = NULL;
+ int len = 0;
+ data_pair_t *pairs = dict->members_list;
+ data_pair_t *next = NULL;
- pairs = dict->members_list;
- while (pairs) {
- next = pairs->next;
+ while (pairs) {
+ next = pairs->next;
- if (filter_fn && filter_fn (pairs->key)){
- pairs = next;
- continue;
- }
+ if (filter_fn && filter_fn(pairs->key)) {
+ pairs = next;
+ continue;
+ }
- if (value && (size > len))
- strncpy (value + len, pairs->key, size - len);
+ if (value && (size > len))
+ strncpy(value + len, pairs->key, size - len);
- len += (strlen (pairs->key) + 1);
+ len += (strlen(pairs->key) + 1);
- pairs = next;
- }
+ pairs = next;
+ }
- return len;
+ return len;
}
static int
-dict_copy_one (dict_t *unused, char *key, data_t *value, void *newdict)
+dict_copy_one(dict_t *unused, char *key, data_t *value, void *newdict)
{
- return dict_set ((dict_t *)newdict, key, (value));
+ return dict_set((dict_t *)newdict, key, (value));
}
dict_t *
-dict_copy (dict_t *dict,
- dict_t *new)
+dict_copy(dict_t *dict, dict_t *new)
{
- if (!dict) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is NULL");
- return NULL;
- }
+ if (!dict) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return NULL;
+ }
- if (!new)
- new = get_new_dict_full (dict->hash_size);
+ if (!new)
+ new = get_new_dict_full(dict->hash_size);
- dict_foreach (dict, dict_copy_one, new);
+ dict_foreach(dict, dict_copy_one, new);
- return new;
+ return new;
}
int
-dict_reset (dict_t *dict)
-{
- int32_t ret = -1;
- if (!dict) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is NULL");
- goto out;
- }
- dict_foreach (dict, dict_remove_foreach_fn, NULL);
- ret = 0;
+dict_reset(dict_t *dict)
+{
+ int32_t ret = -1;
+ if (!dict) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ goto out;
+ }
+ dict_foreach(dict, dict_remove_foreach_fn, NULL);
+ ret = 0;
out:
- return ret;
+ return ret;
}
dict_t *
-dict_copy_with_ref (dict_t *dict,
- dict_t *new)
+dict_copy_with_ref(dict_t *dict, dict_t *new)
{
- dict_t *local_new = NULL;
+ dict_t *local_new = NULL;
- GF_VALIDATE_OR_GOTO("dict", dict, fail);
+ GF_VALIDATE_OR_GOTO("dict", dict, fail);
- if (new == NULL) {
- local_new = dict_new ();
- GF_VALIDATE_OR_GOTO("dict", local_new, fail);
- new = local_new;
- }
+ if (new == NULL) {
+ local_new = dict_new();
+ GF_VALIDATE_OR_GOTO("dict", local_new, fail);
+ new = local_new;
+ }
- dict_foreach (dict, dict_copy_one, new);
+ dict_foreach(dict, dict_copy_one, new);
fail:
- return new;
+ return new;
}
/*
@@ -1377,938 +1495,1292 @@ fail:
* -val error, val = errno
*/
-
static int
-dict_get_with_ref (dict_t *this, char *key, data_t **data)
+dict_get_with_refn(dict_t *this, char *key, const int keylen, data_t **data)
{
- data_pair_t * pair = NULL;
- int ret = -ENOENT;
+ data_pair_t *pair = NULL;
+ int ret = -ENOENT;
+ uint32_t hash;
- if (!this || !key || !data) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG,
- "dict OR key (%s) is NULL", key);
- ret = -EINVAL;
- goto err;
- }
+ hash = (uint32_t)XXH64(key, keylen, 0);
- LOCK (&this->lock);
- {
- pair = dict_lookup_common (this, key);
- }
- UNLOCK (&this->lock);
+ LOCK(&this->lock);
+ {
+ pair = dict_lookup_common(this, key, hash);
if (pair) {
- ret = 0;
- *data = data_ref (pair->value);
+ ret = 0;
+ *data = data_ref(pair->value);
}
+ }
+ UNLOCK(&this->lock);
-err:
- return ret;
+ return ret;
+}
+
+int
+dict_get_with_ref(dict_t *this, char *key, data_t **data)
+{
+ if (!this || !key || !data) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict OR key (%s) is NULL", key);
+ return -EINVAL;
+ }
+
+ return dict_get_with_refn(this, key, strlen(key), data);
}
static int
-data_to_ptr_common (data_t *data, void **val)
+data_to_ptr_common(data_t *data, void **val)
{
- int ret = 0;
+ int ret = 0;
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- *val = data->data;
+ *val = data->data;
err:
- return ret;
+ return ret;
}
-
static int
-data_to_int8_ptr (data_t *data, int8_t *val)
+data_to_int8_ptr(data_t *data, int8_t *val)
{
- int ret = 0;
- char * str = NULL;
-
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ int ret = 0;
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- errno = 0;
- *val = strtol (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtol(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-data_to_int16_ptr (data_t *data, int16_t *val)
+data_to_int16_ptr(data_t *data, int16_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- *val = strtol (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtol(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-data_to_int32_ptr (data_t *data, int32_t *val)
+data_to_int32_ptr(data_t *data, int32_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- *val = strtol (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtol(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-data_to_int64_ptr (data_t *data, int64_t *val)
+data_to_int64_ptr(data_t *data, int64_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
-
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- errno = 0;
- *val = strtoll (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoll(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-data_to_uint16_ptr (data_t *data, uint16_t *val)
+data_to_uint16_ptr(data_t *data, uint16_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
-
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- errno = 0;
- *val = strtoul (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoul(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-data_to_uint32_ptr (data_t *data, uint32_t *val)
+data_to_uint32_ptr(data_t *data, uint32_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- *val = strtoul (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoul(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-data_to_uint64_ptr (data_t *data, uint64_t *val)
+data_to_uint64_ptr(data_t *data, uint64_t *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- *val = strtoull (str, NULL, 0);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtoull(data->data, NULL, 0);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
static int
-data_to_double_ptr (data_t *data, double *val)
+data_to_double_ptr(data_t *data, double *val)
{
- int ret = 0;
- char * str = NULL;
+ int ret = 0;
- if (!data || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- str = alloca (data->len + 1);
- if (!str) {
- ret = -ENOMEM;
- goto err;
- }
- memcpy (str, data->data, data->len);
- str[data->len] = '\0';
-
- errno = 0;
- *val = strtod (str, NULL);
- if (errno != 0)
- ret = -errno;
+ errno = 0;
+ *val = strtod(data->data, NULL);
+ if (errno != 0)
+ ret = -errno;
err:
- return ret;
+ return ret;
}
int
-dict_get_int8 (dict_t *this, char *key, int8_t *val)
+dict_get_int8(dict_t *this, char *key, int8_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
- ret = data_to_int8_ptr (data, val);
+ ret = data_to_int8_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
-
int
-dict_set_int8 (dict_t *this, char *key, int8_t val)
+dict_set_int8(dict_t *this, char *key, int8_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- data = data_from_int8 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = data_from_int8(val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_int16 (dict_t *this, char *key, int16_t *val)
+dict_get_int16(dict_t *this, char *key, int16_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
- ret = data_to_int16_ptr (data, val);
+ ret = data_to_int16_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
+int
+dict_set_int16(dict_t *this, char *key, int16_t val)
+{
+ data_t *data = NULL;
+ int ret = 0;
+
+ data = data_from_int16(val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
+
+err:
+ return ret;
+}
int
-dict_set_int16 (dict_t *this, char *key, int16_t val)
+dict_get_int32n(dict_t *this, char *key, const int keylen, int32_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- data = data_from_int16 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!this || !key || !val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_get_with_refn(this, key, keylen, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
+
+ ret = data_to_int32_ptr(data, val);
err:
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
int
-dict_get_int32 (dict_t *this, char *key, int32_t *val)
+dict_get_int32(dict_t *this, char *key, int32_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
- ret = data_to_int32_ptr (data, val);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
+
+ ret = data_to_int32_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
+int
+dict_set_int32n(dict_t *this, char *key, const int keylen, int32_t val)
+{
+ data_t *data = NULL;
+ int ret = 0;
+
+ data = data_from_int32(val);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_setn(this, key, keylen, data);
+ if (ret < 0)
+ data_destroy(data);
+
+err:
+ return ret;
+}
int
-dict_set_int32 (dict_t *this, char *key, int32_t val)
+dict_set_int32(dict_t *this, char *key, int32_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_int32(val);
+ int ret = 0;
- data = data_from_int32 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_int64 (dict_t *this, char *key, int64_t *val)
+dict_get_int64(dict_t *this, char *key, int64_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
- ret = data_to_int64_ptr (data, val);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
+
+ ret = data_to_int64_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
-
int
-dict_set_int64 (dict_t *this, char *key, int64_t val)
+dict_set_int64(dict_t *this, char *key, int64_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_int64(val);
+ int ret = 0;
- data = data_from_int64 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_uint16 (dict_t *this, char *key, uint16_t *val)
+dict_get_uint16(dict_t *this, char *key, uint16_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
- ret = data_to_uint16_ptr (data, val);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, key, -EINVAL);
+
+ ret = data_to_uint16_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
-
int
-dict_set_uint16 (dict_t *this, char *key, uint16_t val)
+dict_set_uint16(dict_t *this, char *key, uint16_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_uint16(val);
+ int ret = 0;
- data = data_from_uint16 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_uint32 (dict_t *this, char *key, uint32_t *val)
+dict_get_uint32(dict_t *this, char *key, uint32_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
- ret = data_to_uint32_ptr (data, val);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, key, -EINVAL);
+
+ ret = data_to_uint32_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
-
-
int
-dict_set_uint32 (dict_t *this, char *key, uint32_t val)
+dict_set_uint32(dict_t *this, char *key, uint32_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_uint32(val);
+ int ret = 0;
- data = data_from_uint32 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_uint64 (dict_t *this, char *key, uint64_t *val)
+dict_get_uint64(dict_t *this, char *key, uint64_t *val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
- goto err;
- }
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
- ret = data_to_uint64_ptr (data, val);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_UINT, key, -EINVAL);
+
+ ret = data_to_uint64_ptr(data, val);
err:
- if (data)
- data_unref (data);
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
-
int
-dict_set_uint64 (dict_t *this, char *key, uint64_t val)
+dict_set_uint64(dict_t *this, char *key, uint64_t val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_uint64(val);
+ int ret = 0;
- data = data_from_uint64 (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
+/*
+ * dict_check_flag can be used to check a one bit flag in an array of flags
+ * The flag argument indicates the bit position (within the array of bits).
+ * Currently limited to max of 256 flags for a key.
+ * return value,
+ * 1 : flag is set
+ * 0 : flag is not set
+ * <0: Error
+ */
int
-dict_get_double (dict_t *this, char *key, double *val)
+dict_check_flag(dict_t *this, char *key, int flag)
{
- data_t *data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = -ENOENT;
+
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (BIT_VALUE((unsigned char *)(data->data), flag))
+ ret = 1;
+ else
+ ret = 0;
- if (!this || !key || !val) {
- ret = -EINVAL;
+ data_unref(data);
+ return ret;
+}
+
+/*
+ * _dict_modify_flag can be used to set/clear a bit flag in an array of flags
+ * flag: indicates the bit position. limited to max of DICT_MAX_FLAGS.
+ * op: Indicates operation DICT_FLAG_SET / DICT_FLAG_CLEAR
+ */
+static int
+_dict_modify_flag(dict_t *this, char *key, int flag, int op)
+{
+ data_t *data = NULL;
+ int ret = 0;
+ data_pair_t *pair = NULL;
+ char *ptr = NULL;
+ int hashval = 0;
+ uint32_t hash;
+
+ if (!this || !key) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict OR key (%s) is NULL", key);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /*
+ * Using a size of 32 bytes to support max of 256
+ * flags in a single key. This should be suffcient.
+ */
+ GF_ASSERT(flag >= 0 && flag < DICT_MAX_FLAGS);
+
+ hash = (uint32_t)XXH64(key, strlen(key), 0);
+ LOCK(&this->lock);
+ {
+ pair = dict_lookup_common(this, key, hash);
+
+ if (pair) {
+ data = pair->value;
+ if (op == DICT_FLAG_SET)
+ BIT_SET((unsigned char *)(data->data), flag);
+ else
+ BIT_CLEAR((unsigned char *)(data->data), flag);
+ } else {
+ ptr = GF_CALLOC(1, DICT_MAX_FLAGS / 8, gf_common_mt_char);
+ if (!ptr) {
+ gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
+ "flag bit array", NULL);
+ ret = -ENOMEM;
goto err;
- }
+ }
+
+ data = data_from_dynptr(ptr, DICT_MAX_FLAGS / 8);
+
+ if (!data) {
+ gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY, "data",
+ NULL);
+ GF_FREE(ptr);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ if (op == DICT_FLAG_SET)
+ BIT_SET((unsigned char *)(data->data), flag);
+ else
+ BIT_CLEAR((unsigned char *)(data->data), flag);
+
+ if (this->free_pair.key) { /* the free pair is in use */
+ pair = mem_get0(THIS->ctx->dict_pair_pool);
+ if (!pair) {
+ gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
+ "dict pair", NULL);
+ ret = -ENOMEM;
+ goto err;
+ }
+ } else { /* use the free pair */
+ pair = &this->free_pair;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
+ pair->key = (char *)GF_MALLOC(strlen(key) + 1, gf_common_mt_char);
+ if (!pair->key) {
+ gf_smsg("dict", GF_LOG_ERROR, ENOMEM, LG_MSG_NO_MEMORY,
+ "dict pair", NULL);
+ ret = -ENOMEM;
goto err;
+ }
+ strcpy(pair->key, key);
+ pair->key_hash = hash;
+ pair->value = data_ref(data);
+ this->totkvlen += (strlen(key) + 1 + data->len);
+ hashval = hash % this->hash_size;
+ pair->hash_next = this->members[hashval];
+ this->members[hashval] = pair;
+
+ pair->next = this->members_list;
+ pair->prev = NULL;
+ if (this->members_list)
+ this->members_list->prev = pair;
+ this->members_list = pair;
+ this->count++;
+
+ if (this->max_count < this->count)
+ this->max_count = this->count;
}
+ }
- ret = data_to_double_ptr (data, val);
+ UNLOCK(&this->lock);
+ return 0;
err:
- if (data)
- data_unref (data);
- return ret;
+ if (key && this)
+ UNLOCK(&this->lock);
+
+ if (pair) {
+ if (pair->key) {
+ GF_FREE(pair->key);
+ pair->key = NULL;
+ }
+ if (pair != &this->free_pair) {
+ mem_put(pair);
+ }
+ }
+
+ if (data)
+ data_destroy(data);
+
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_DICT_SET_FAILED, "key=%s", key,
+ NULL);
+
+ return ret;
}
+/*
+ * Todo:
+ * Add below primitives as needed:
+ * dict_check_flags(this, key, flag...): variadic function to check
+ * multiple flags at a time.
+ * dict_set_flags(this, key, flag...): set multiple flags
+ * dict_clear_flags(this, key, flag...): reset multiple flags
+ */
+
int
-dict_set_double (dict_t *this, char *key, double val)
+dict_set_flag(dict_t *this, char *key, int flag)
{
- data_t * data = NULL;
- int ret = 0;
+ return _dict_modify_flag(this, key, flag, DICT_FLAG_SET);
+}
- data = data_from_double (val);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+int
+dict_clear_flag(dict_t *this, char *key, int flag)
+{
+ return _dict_modify_flag(this, key, flag, DICT_FLAG_CLEAR);
+}
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+int
+dict_get_double(dict_t *this, char *key, double *val)
+{
+ data_t *data = NULL;
+ int ret = 0;
+
+ if (!val) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_DOUBLE, key, -EINVAL);
+
+ ret = data_to_double_ptr(data, val);
err:
- return ret;
+ if (data)
+ data_unref(data);
+ return ret;
}
int
-dict_set_static_ptr (dict_t *this, char *key, void *ptr)
+dict_set_double(dict_t *this, char *key, double val)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_double(val);
+ int ret = 0;
- data = data_from_ptr_common (ptr, _gf_true);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_set_dynptr (dict_t *this, char *key, void *ptr, size_t len)
+dict_set_static_ptr(dict_t *this, char *key, void *ptr)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_ptr_common(ptr, _gf_true);
+ int ret = 0;
- data = data_from_dynptr (ptr, len);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
int
-dict_get_ptr (dict_t *this, char *key, void **ptr)
+dict_set_dynptr(dict_t *this, char *key, void *ptr, size_t len)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = data_from_dynptr(ptr, len);
+ int ret = 0;
- if (!this || !key || !ptr) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
- ret = data_to_ptr_common (data, ptr);
- if (ret != 0) {
- goto err;
- }
+err:
+ return ret;
+}
+
+int
+dict_get_ptr(dict_t *this, char *key, void **ptr)
+{
+ data_t *data = NULL;
+ int ret = 0;
+
+ if (!ptr) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, key, -EINVAL);
+
+ ret = data_to_ptr_common(data, ptr);
+ if (ret != 0) {
+ goto err;
+ }
err:
- if (data)
- data_unref (data);
+ if (data)
+ data_unref(data);
- return ret;
+ return ret;
}
int
-dict_get_ptr_and_len (dict_t *this, char *key, void **ptr, int *len)
+dict_get_ptr_and_len(dict_t *this, char *key, void **ptr, int *len)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!this || !key || !ptr) {
- ret = -EINVAL;
- goto err;
- }
+ if (!ptr) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret != 0) {
- goto err;
- }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret != 0) {
+ goto err;
+ }
- *len = data->len;
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, key, -EINVAL);
- ret = data_to_ptr_common (data, ptr);
- if (ret != 0) {
- goto err;
- }
+ *len = data->len;
+
+ ret = data_to_ptr_common(data, ptr);
+ if (ret != 0) {
+ goto err;
+ }
err:
- if (data)
- data_unref (data);
+ if (data)
+ data_unref(data);
- return ret;
+ return ret;
}
+/* Get string - with known key length */
int
-dict_set_ptr (dict_t *this, char *key, void *ptr)
+dict_get_strn(dict_t *this, char *key, const int keylen, char **str)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = -EINVAL;
- data = data_from_ptr_common (ptr, _gf_false);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!this || !key || !str) {
+ goto err;
+ }
+ ret = dict_get_with_refn(this, key, keylen, &data);
+ if (ret < 0) {
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, key, -EINVAL);
+
+ *str = data->data;
err:
- return ret;
-}
+ if (data)
+ data_unref(data);
+ return ret;
+}
int
-dict_get_str (dict_t *this, char *key, char **str)
+dict_get_str(dict_t *this, char *key, char **str)
{
- data_t * data = NULL;
- int ret = -EINVAL;
+ data_t *data = NULL;
+ int ret = -EINVAL;
- if (!this || !key || !str) {
- goto err;
- }
+ if (!str) {
+ goto err;
+ }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
- ret = dict_get_with_ref (this, key, &data);
- if (ret < 0) {
- goto err;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_STR, key, -EINVAL);
- if (!data || !data->data) {
- goto err;
- }
- *str = data->data;
+ *str = data->data;
err:
- if (data)
- data_unref (data);
+ if (data)
+ data_unref(data);
- return ret;
+ return ret;
}
int
-dict_set_str (dict_t *this, char *key, char *str)
+dict_set_str(dict_t *this, char *key, char *str)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = str_to_data(str);
+ int ret = 0;
- data = str_to_data (str);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
err:
- return ret;
+ return ret;
}
+/* Set string - with known key length */
int
-dict_set_dynstr_with_alloc (dict_t *this, char *key, const char *str)
+dict_set_strn(dict_t *this, char *key, const int keylen, char *str)
{
- char *alloc_str = NULL;
- int ret = -1;
+ data_t *data = NULL;
+ int ret = 0;
- alloc_str = gf_strdup (str);
- if (!alloc_str)
- return -1;
+ data = str_to_data(str);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set_dynstr (this, key, alloc_str);
- if (ret == -EINVAL)
- GF_FREE (alloc_str);
+ ret = dict_setn(this, key, keylen, data);
+ if (ret < 0)
+ data_destroy(data);
- return ret;
+err:
+ return ret;
}
+/* Set string - with known key length and known value length */
int
-dict_set_dynstr (dict_t *this, char *key, char *str)
+dict_set_nstrn(dict_t *this, char *key, const int keylen, char *str,
+ const int vallen)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = strn_to_data(str, vallen);
+ int ret = 0;
- data = data_from_dynstr (str);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_set (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_setn(this, key, keylen, data);
+ if (ret < 0)
+ data_destroy(data);
err:
+ return ret;
+}
+
+int
+dict_set_dynstr_with_alloc(dict_t *this, char *key, const char *str)
+{
+ char *alloc_str = gf_strdup(str);
+ int ret = -1;
+
+ if (!alloc_str)
return ret;
+
+ ret = dict_set_dynstr(this, key, alloc_str);
+ if (ret == -EINVAL)
+ GF_FREE(alloc_str);
+
+ return ret;
}
int
-dict_add_dynstr_with_alloc (dict_t *this, char *key, char *str)
+dict_set_dynstr(dict_t *this, char *key, char *str)
{
- data_t *data = NULL;
- int ret = 0;
- char *alloc_str = NULL;
+ const int keylen = strlen(key);
+ return dict_set_dynstrn(this, key, keylen, str);
+}
- alloc_str = gf_strdup (str);
- if (!alloc_str)
- goto out;
+int
+dict_set_dynstrn(dict_t *this, char *key, const int keylen, char *str)
+{
+ data_t *data = data_from_dynstr(str);
+ int ret = 0;
- data = data_from_dynstr (alloc_str);
- if (!data) {
- GF_FREE (alloc_str);
- ret = -EINVAL;
- goto out;
- }
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- ret = dict_add (this, key, data);
- if (ret < 0)
- data_destroy (data);
+ ret = dict_setn(this, key, keylen, data);
+ if (ret < 0)
+ data_destroy(data);
-out:
- return ret;
+err:
+ return ret;
}
+/* This function is called only by the volgen for now.
+ Check how else you can handle it */
+int
+dict_set_option(dict_t *this, char *key, char *str)
+{
+ data_t *data = data_from_dynstr(str);
+ int ret = 0;
+
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ data->data_type = GF_DATA_TYPE_STR_OLD;
+ ret = dict_set(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
+err:
+ return ret;
+}
int
-dict_get_bin (dict_t *this, char *key, void **bin)
+dict_add_dynstr_with_alloc(dict_t *this, char *key, char *str)
{
- data_t * data = NULL;
- int ret = -EINVAL;
+ data_t *data = NULL;
+ int ret = 0;
+ char *alloc_str = gf_strdup(str);
- if (!this || !key || !bin) {
- goto err;
- }
+ if (!alloc_str)
+ goto out;
- ret = dict_get_with_ref (this, key, &data);
- if (ret < 0) {
- goto err;
- }
+ data = data_from_dynstr(alloc_str);
+ if (!data) {
+ GF_FREE(alloc_str);
+ ret = -EINVAL;
+ goto out;
+ }
- if (!data || !data->data) {
- goto err;
- }
- *bin = data->data;
+ ret = dict_add(this, key, data);
+ if (ret < 0)
+ data_destroy(data);
+
+out:
+ return ret;
+}
+
+int
+dict_get_bin(dict_t *this, char *key, void **bin)
+{
+ data_t *data = NULL;
+ int ret = -EINVAL;
+
+ if (!bin) {
+ goto err;
+ }
+
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_PTR, key, ret);
+
+ *bin = data->data;
err:
- if (data)
- data_unref (data);
+ if (data)
+ data_unref(data);
- return ret;
+ return ret;
}
-
+/********************************************************************
+ *
+ * dict_set_bin_common:
+ * This is the common function to set key and its value in
+ * dictionary. Flag(is_static) should be set appropriately based
+ * on the type of memory type used for value(*ptr). If flag is set
+ * to false value(*ptr) will be freed using GF_FREE() on destroy.
+ *
+ *******************************************************************/
static int
-dict_set_bin_common (dict_t *this, char *key, void *ptr, size_t size,
- gf_boolean_t is_static)
+dict_set_bin_common(dict_t *this, char *key, void *ptr, size_t size,
+ gf_boolean_t is_static, gf_dict_data_type_t type)
{
- data_t * data = NULL;
- int ret = 0;
+ data_t *data = NULL;
+ int ret = 0;
- if (!ptr || (size > ULONG_MAX)) {
- ret = -EINVAL;
- goto err;
- }
+ if (!ptr || (size > DICT_KEY_VALUE_MAX_SIZE)) {
+ ret = -EINVAL;
+ goto err;
+ }
- data = bin_to_data (ptr, size);
- if (!data) {
- ret = -EINVAL;
- goto err;
- }
+ data = bin_to_data(ptr, size);
+ if (!data) {
+ ret = -EINVAL;
+ goto err;
+ }
- data->is_static = is_static;
+ data->is_static = is_static;
+ data->data_type = type;
- ret = dict_set (this, key, data);
- if (ret < 0) {
- /* don't free data->data, let callers handle it */
- data->data = NULL;
- data_destroy (data);
- }
+ ret = dict_set(this, key, data);
+ if (ret < 0) {
+ /* don't free data->data, let callers handle it */
+ data->data = NULL;
+ data_destroy(data);
+ }
err:
- return ret;
+ return ret;
}
+/********************************************************************
+ *
+ * dict_set_bin:
+ * Set key and its value in the dictionary. This function should
+ * be called if the value is stored in dynamic memory.
+ *
+ *******************************************************************/
int
-dict_set_bin (dict_t *this, char *key, void *ptr, size_t size)
+dict_set_bin(dict_t *this, char *key, void *ptr, size_t size)
{
- return dict_set_bin_common (this, key, ptr, size, _gf_false);
+ return dict_set_bin_common(this, key, ptr, size, _gf_false,
+ GF_DATA_TYPE_PTR);
}
+/********************************************************************
+ *
+ * dict_set_static_bin:
+ * Set key and its value in the dictionary. This function should
+ * be called if the value is stored in static memory.
+ *
+ *******************************************************************/
+int
+dict_set_static_bin(dict_t *this, char *key, void *ptr, size_t size)
+{
+ return dict_set_bin_common(this, key, ptr, size, _gf_true,
+ GF_DATA_TYPE_PTR);
+}
+/* */
int
-dict_set_static_bin (dict_t *this, char *key, void *ptr, size_t size)
+dict_set_gfuuid(dict_t *this, char *key, uuid_t gfid, bool is_static)
{
- return dict_set_bin_common (this, key, ptr, size, _gf_true);
+ return dict_set_bin_common(this, key, gfid, sizeof(uuid_t), is_static,
+ GF_DATA_TYPE_GFUUID);
}
+int
+dict_get_gfuuid(dict_t *this, char *key, uuid_t *gfid)
+{
+ data_t *data = NULL;
+ int ret = -EINVAL;
+
+ if (!gfid) {
+ goto err;
+ }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_GFUUID, key, -EINVAL);
+
+ memcpy(*gfid, data->data, min(data->len, sizeof(uuid_t)));
+
+err:
+ if (data)
+ data_unref(data);
+
+ return ret;
+}
+
+int
+dict_set_mdata(dict_t *this, char *key, struct mdata_iatt *mdata,
+ bool is_static)
+{
+ return dict_set_bin_common(this, key, mdata, sizeof(struct mdata_iatt),
+ is_static, GF_DATA_TYPE_MDATA);
+}
+
+int
+dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata)
+{
+ data_t *data = NULL;
+ int ret = -EINVAL;
+
+ if (!mdata) {
+ goto err;
+ }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_MDATA, key, -EINVAL);
+ if (data->len < sizeof(struct mdata_iatt)) {
+ gf_smsg("glusterfs", GF_LOG_ERROR, ENOBUFS, LG_MSG_UNDERSIZED_BUF,
+ "key=%s", key, NULL);
+ ret = -ENOBUFS;
+ goto err;
+ }
+
+ memcpy(mdata, data->data, min(data->len, sizeof(struct mdata_iatt)));
+
+err:
+ if (data)
+ data_unref(data);
+
+ return ret;
+}
+
+int
+dict_set_iatt(dict_t *this, char *key, struct iatt *iatt, bool is_static)
+{
+ return dict_set_bin_common(this, key, iatt, sizeof(struct iatt), is_static,
+ GF_DATA_TYPE_IATT);
+}
+
+int
+dict_get_iatt(dict_t *this, char *key, struct iatt *iatt)
+{
+ data_t *data = NULL;
+ int ret = -EINVAL;
+
+ if (!iatt) {
+ goto err;
+ }
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ goto err;
+ }
+
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_IATT, key, -EINVAL);
+
+ memcpy(iatt, data->data, min(data->len, sizeof(struct iatt)));
+
+err:
+ if (data)
+ data_unref(data);
+
+ return ret;
+}
/**
* dict_get_str_boolean - get a boolean value based on string representation.
@@ -2334,41 +2806,77 @@ dict_set_static_bin (dict_t *this, char *key, void *ptr, size_t size)
*/
int
-dict_get_str_boolean (dict_t *this, char *key, int default_val)
+dict_get_str_boolean(dict_t *this, char *key, int default_val)
{
- data_t *data = NULL;
- gf_boolean_t boo = _gf_false;
- int ret = 0;
+ data_t *data = NULL;
+ gf_boolean_t boo = _gf_false;
+ int ret = 0;
- ret = dict_get_with_ref (this, key, &data);
- if (ret < 0) {
- if (ret == -ENOENT)
- ret = default_val;
- else
- ret = -1;
- goto err;
- }
-
- GF_ASSERT (data);
+ ret = dict_get_with_ref(this, key, &data);
+ if (ret < 0) {
+ if (ret == -ENOENT)
+ ret = default_val;
+ else
+ ret = -1;
+ goto err;
+ }
- if (!data->data) {
- ret = -1;
- goto err;
- }
+ VALIDATE_DATA_AND_LOG(data, GF_DATA_TYPE_INT, key, -EINVAL);
- ret = gf_string2boolean (data->data, &boo);
- if (ret == -1)
- goto err;
+ ret = gf_strn2boolean(data->data, data->len - 1, &boo);
+ if (ret == -1)
+ goto err;
- ret = boo;
+ ret = boo;
err:
- if (data)
- data_unref (data);
+ if (data)
+ data_unref(data);
- return ret;
+ return ret;
}
+int
+dict_rename_key(dict_t *this, char *key, char *replace_key)
+{
+ data_pair_t *pair = NULL;
+ int ret = -EINVAL;
+ uint32_t hash;
+ uint32_t replacekey_hash;
+ int replacekey_len;
+
+ /* replacing a key by itself is a NO-OP */
+ if (strcmp(key, replace_key) == 0)
+ return 0;
+
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ return ret;
+ }
+
+ hash = (uint32_t)XXH64(key, strlen(key), 0);
+ replacekey_len = strlen(replace_key);
+ replacekey_hash = (uint32_t)XXH64(replace_key, replacekey_len, 0);
+
+ LOCK(&this->lock);
+ {
+ /* no need to data_ref(pair->value), dict_set_lk() does it */
+ pair = dict_lookup_common(this, key, hash);
+ if (!pair)
+ ret = -ENODATA;
+ else
+ ret = dict_set_lk(this, replace_key, replacekey_len, pair->value,
+ replacekey_hash, 1);
+ }
+ UNLOCK(&this->lock);
+
+ if (!ret)
+ /* only delete the key on success */
+ dict_del(this, key);
+
+ return ret;
+}
/**
* Serialization format:
@@ -2378,10 +2886,6 @@ err:
* 4 4 4 <key len> <value len>
*/
-#define DICT_HDR_LEN 4
-#define DICT_DATA_HDR_KEY_LEN 4
-#define DICT_DATA_HDR_VAL_LEN 4
-
/**
* dict_serialized_length_lk - return the length of serialized dict. This
* procedure has to be called with this->lock held.
@@ -2392,64 +2896,21 @@ err:
*/
int
-dict_serialized_length_lk (dict_t *this)
+dict_serialized_length_lk(dict_t *this)
{
- int ret = -EINVAL;
- int count = 0;
- int len = 0;
- data_pair_t * pair = NULL;
-
- len = DICT_HDR_LEN;
- count = this->count;
-
- if (count < 0) {
- gf_msg ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_COUNT_LESS_THAN_ZERO, "count (%d) < 0!", count);
- goto out;
- }
+ int ret = -EINVAL;
+ int count = this->count;
+ const int keyhdrlen = DICT_DATA_HDR_KEY_LEN + DICT_DATA_HDR_VAL_LEN;
- pair = this->members_list;
-
- while (count) {
- if (!pair) {
- gf_msg ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_COUNT_LESS_THAN_DATA_PAIRS,
- "less than count data pairs found!");
- goto out;
- }
-
- len += DICT_DATA_HDR_KEY_LEN + DICT_DATA_HDR_VAL_LEN;
-
- if (!pair->key) {
- gf_msg ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_NULL_PTR, "pair->key is null!");
- goto out;
- }
-
- len += strlen (pair->key) + 1 /* for '\0' */;
-
- if (!pair->value) {
- gf_msg ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_NULL_PTR, "pair->value is null!");
- goto out;
- }
+ if (count < 0) {
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_COUNT_LESS_THAN_ZERO,
+ "count=%d", count, NULL);
+ goto out;
+ }
- if (pair->value->len < 0) {
- gf_msg ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_VALUE_LENGTH_LESS_THAN_ZERO,
- "value->len (%d) < 0", pair->value->len);
- goto out;
- }
-
- len += pair->value->len;
-
- pair = pair->next;
- count--;
- }
-
- ret = len;
+ ret = DICT_HDR_LEN + this->totkvlen + (count * keyhdrlen);
out:
- return ret;
+ return ret;
}
/**
@@ -2458,92 +2919,80 @@ out:
*
* @this: dict to serialize
* @buf: buffer to serialize into. This must be
- * atleast dict_serialized_length (this) large
+ * at least dict_serialized_length (this) large
*
* @return: success: 0
* failure: -errno
*/
-int
-dict_serialize_lk (dict_t *this, char *buf)
+static int
+dict_serialize_lk(dict_t *this, char *buf)
{
- int ret = -1;
- data_pair_t * pair = NULL;
- int32_t count = 0;
- int32_t keylen = 0;
- int32_t vallen = 0;
- int32_t netword = 0;
+ int ret = -1;
+ data_pair_t *pair = this->members_list;
+ int32_t count = this->count;
+ int32_t keylen = 0;
+ int32_t netword = 0;
+ if (!buf) {
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL);
+ goto out;
+ }
- if (!buf) {
- gf_msg ("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
- "buf is null!");
- goto out;
- }
+ if (count < 0) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO,
+ "count=%d", count, NULL);
+ goto out;
+ }
+ netword = hton32(count);
+ memcpy(buf, &netword, sizeof(netword));
+ buf += DICT_HDR_LEN;
- count = this->count;
- if (count < 0) {
- gf_msg ("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO,
- "count (%d) < 0!", count);
- goto out;
+ while (count) {
+ if (!pair) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT,
+ NULL);
+ goto out;
}
- netword = hton32 (count);
- memcpy (buf, &netword, sizeof(netword));
- buf += DICT_HDR_LEN;
- pair = this->members_list;
-
- while (count) {
- if (!pair) {
- gf_msg ("dict", GF_LOG_ERROR, 0,
- LG_MSG_PAIRS_LESS_THAN_COUNT,
- "less than count data pairs found!");
- goto out;
- }
-
- if (!pair->key) {
- gf_msg ("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR,
- "pair->key is null!");
- goto out;
- }
+ if (!pair->key) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL);
+ goto out;
+ }
- keylen = strlen (pair->key);
- netword = hton32 (keylen);
- memcpy (buf, &netword, sizeof(netword));
- buf += DICT_DATA_HDR_KEY_LEN;
+ keylen = strlen(pair->key);
+ netword = hton32(keylen);
+ memcpy(buf, &netword, sizeof(netword));
+ buf += DICT_DATA_HDR_KEY_LEN;
- if (!pair->value) {
- gf_msg ("dict", GF_LOG_ERROR, 0,
- LG_MSG_NULL_PTR,
- "pair->value is null!");
- goto out;
- }
-
- vallen = pair->value->len;
- netword = hton32 (vallen);
- memcpy (buf, &netword, sizeof(netword));
- buf += DICT_DATA_HDR_VAL_LEN;
+ if (!pair->value) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_PTR, NULL);
+ goto out;
+ }
- memcpy (buf, pair->key, keylen);
- buf += keylen;
- *buf++ = '\0';
+ netword = hton32(pair->value->len);
+ memcpy(buf, &netword, sizeof(netword));
+ buf += DICT_DATA_HDR_VAL_LEN;
- if (pair->value->data) {
- memcpy (buf, pair->value->data, vallen);
- buf += vallen;
- }
+ memcpy(buf, pair->key, keylen);
+ buf += keylen;
+ *buf++ = '\0';
- pair = pair->next;
- count--;
+ if (pair->value->data) {
+ memcpy(buf, pair->value->data, pair->value->len);
+ buf += pair->value->len;
}
- ret = 0;
+ pair = pair->next;
+ count--;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
/**
* dict_serialized_length - return the length of serialized dict
*
@@ -2553,24 +3002,24 @@ out:
*/
int
-dict_serialized_length (dict_t *this)
+dict_serialized_length(dict_t *this)
{
- int ret = -EINVAL;
+ int ret = -EINVAL;
- if (!this) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is null!");
- goto out;
- }
+ if (!this) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is null!");
+ goto out;
+ }
- LOCK (&this->lock);
- {
- ret = dict_serialized_length_lk (this);
- }
- UNLOCK (&this->lock);
+ LOCK(&this->lock);
+ {
+ ret = dict_serialized_length_lk(this);
+ }
+ UNLOCK(&this->lock);
out:
- return ret;
+ return ret;
}
/**
@@ -2578,33 +3027,32 @@ out:
*
* @this: dict to serialize
* @buf: buffer to serialize into. This must be
- * atleast dict_serialized_length (this) large
+ * at least dict_serialized_length (this) large
*
* @return: success: 0
* failure: -errno
*/
int
-dict_serialize (dict_t *this, char *buf)
+dict_serialize(dict_t *this, char *buf)
{
- int ret = -1;
+ int ret = -1;
- if (!this || !buf) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is null!");
- goto out;
- }
+ if (!this || !buf) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is null!");
+ goto out;
+ }
- LOCK (&this->lock);
- {
- ret = dict_serialize_lk (this, buf);
- }
- UNLOCK (&this->lock);
+ LOCK(&this->lock);
+ {
+ ret = dict_serialize_lk(this, buf);
+ }
+ UNLOCK(&this->lock);
out:
- return ret;
+ return ret;
}
-
/**
* dict_unserialize - unserialize a buffer into a dict
*
@@ -2617,130 +3065,137 @@ out:
*/
int32_t
-dict_unserialize (char *orig_buf, int32_t size, dict_t **fill)
-{
- char *buf = NULL;
- int ret = -1;
- int32_t count = 0;
- int i = 0;
-
- data_t * value = NULL;
- char * key = NULL;
- int32_t keylen = 0;
- int32_t vallen = 0;
- int32_t hostord = 0;
-
- buf = orig_buf;
-
- if (!buf) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "buf is null!");
- goto out;
- }
-
- if (size == 0) {
- gf_msg_callingfn ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "size is 0!");
- goto out;
- }
+dict_unserialize(char *orig_buf, int32_t size, dict_t **fill)
+{
+ char *buf = orig_buf;
+ int ret = -1;
+ int32_t count = 0;
+ int i = 0;
+
+ data_t *value = NULL;
+ char *key = NULL;
+ int32_t keylen = 0;
+ int32_t vallen = 0;
+ int32_t hostord = 0;
+
+ if (!buf) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "buf is null!");
+ goto out;
+ }
+
+ if (size == 0) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "size is 0!");
+ goto out;
+ }
+
+ if (!fill) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "fill is null!");
+ goto out;
+ }
+
+ if (!*fill) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "*fill is null!");
+ goto out;
+ }
+
+ if ((buf + DICT_HDR_LEN) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized buffer "
+ "passed. available (%lu) < required (%lu)",
+ (long)(orig_buf + size), (long)(buf + DICT_HDR_LEN));
+ goto out;
+ }
+
+ memcpy(&hostord, buf, sizeof(hostord));
+ count = ntoh32(hostord);
+ buf += DICT_HDR_LEN;
+
+ if (count < 0) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO,
+ "count=%d", count, NULL);
+ goto out;
+ }
+
+ /* count will be set by the dict_set's below */
+ (*fill)->count = 0;
+
+ for (i = 0; i < count; i++) {
+ if ((buf + DICT_DATA_HDR_KEY_LEN) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized "
+ "buffer passed. available (%lu) < "
+ "required (%lu)",
+ (long)(orig_buf + size),
+ (long)(buf + DICT_DATA_HDR_KEY_LEN));
+ goto out;
+ }
+ memcpy(&hostord, buf, sizeof(hostord));
+ keylen = ntoh32(hostord);
+ buf += DICT_DATA_HDR_KEY_LEN;
+
+ if ((buf + DICT_DATA_HDR_VAL_LEN) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized "
+ "buffer passed. available (%lu) < "
+ "required (%lu)",
+ (long)(orig_buf + size),
+ (long)(buf + DICT_DATA_HDR_VAL_LEN));
+ goto out;
+ }
+ memcpy(&hostord, buf, sizeof(hostord));
+ vallen = ntoh32(hostord);
+ buf += DICT_DATA_HDR_VAL_LEN;
+
+ if ((keylen < 0) || (vallen < 0)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized length passed "
+ "key:%d val:%d",
+ keylen, vallen);
+ goto out;
+ }
+ if ((buf + keylen) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized buffer passed. "
+ "available (%lu) < required (%lu)",
+ (long)(orig_buf + size), (long)(buf + keylen));
+ goto out;
+ }
+ key = buf;
+ buf += keylen + 1; /* for '\0' */
+
+ if ((buf + vallen) > (orig_buf + size)) {
+ gf_msg_callingfn("dict", GF_LOG_ERROR, 0, LG_MSG_UNDERSIZED_BUF,
+ "undersized buffer passed. "
+ "available (%lu) < required (%lu)",
+ (long)(orig_buf + size), (long)(buf + vallen));
+ goto out;
+ }
+ value = get_new_data();
- if (!fill) {
- gf_msg_callingfn ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "fill is null!");
- goto out;
- }
-
- if (!*fill) {
- gf_msg_callingfn ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "*fill is null!");
- goto out;
- }
-
- if ((buf + DICT_HDR_LEN) > (orig_buf + size)) {
- gf_msg_callingfn ("dict", GF_LOG_ERROR, 0,
- LG_MSG_UNDERSIZED_BUF, "undersized buffer "
- "passed. available (%lu) < required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + DICT_HDR_LEN));
- goto out;
- }
-
- memcpy (&hostord, buf, sizeof(hostord));
- count = ntoh32 (hostord);
- buf += DICT_HDR_LEN;
-
- if (count < 0) {
- gf_msg ("dict", GF_LOG_ERROR, 0, LG_MSG_COUNT_LESS_THAN_ZERO,
- "count (%d) <= 0", count);
- goto out;
+ if (!value) {
+ ret = -1;
+ goto out;
}
+ value->len = vallen;
+ value->data = gf_memdup(buf, vallen);
+ value->data_type = GF_DATA_TYPE_STR_OLD;
+ value->is_static = _gf_false;
+ buf += vallen;
- /* count will be set by the dict_set's below */
- (*fill)->count = 0;
-
- for (i = 0; i < count; i++) {
- if ((buf + DICT_DATA_HDR_KEY_LEN) > (orig_buf + size)) {
- gf_msg_callingfn ("dict", GF_LOG_ERROR, 0,
- LG_MSG_UNDERSIZED_BUF, "undersized "
- "buffer passed. available (%lu) < "
- "required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + DICT_DATA_HDR_KEY_LEN));
- goto out;
- }
- memcpy (&hostord, buf, sizeof(hostord));
- keylen = ntoh32 (hostord);
- buf += DICT_DATA_HDR_KEY_LEN;
-
- if ((buf + DICT_DATA_HDR_VAL_LEN) > (orig_buf + size)) {
- gf_msg_callingfn ("dict", GF_LOG_ERROR, 0,
- LG_MSG_UNDERSIZED_BUF, "undersized "
- "buffer passed. available (%lu) < "
- "required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + DICT_DATA_HDR_VAL_LEN));
- goto out;
- }
- memcpy (&hostord, buf, sizeof(hostord));
- vallen = ntoh32 (hostord);
- buf += DICT_DATA_HDR_VAL_LEN;
-
- if ((buf + keylen) > (orig_buf + size)) {
- gf_msg_callingfn ("dict", GF_LOG_ERROR, 0,
- LG_MSG_UNDERSIZED_BUF,
- "undersized buffer passed. "
- "available (%lu) < required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + keylen));
- goto out;
- }
- key = buf;
- buf += keylen + 1; /* for '\0' */
-
- if ((buf + vallen) > (orig_buf + size)) {
- gf_msg_callingfn ("dict", GF_LOG_ERROR, 0,
- LG_MSG_UNDERSIZED_BUF,
- "undersized buffer passed. "
- "available (%lu) < required (%lu)",
- (long)(orig_buf + size),
- (long)(buf + vallen));
- goto out;
- }
- value = get_new_data ();
- value->len = vallen;
-value->data = memdup (buf, vallen);
- value->is_static = 0;
- buf += vallen;
-
- dict_add (*fill, key, value);
- }
+ ret = dict_addn(*fill, key, keylen, value);
+ if (ret < 0)
+ goto out;
+ }
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
/**
* dict_allocate_and_serialize - serialize a dictionary into an allocated buffer
*
@@ -2753,45 +3208,45 @@ out:
*/
int32_t
-dict_allocate_and_serialize (dict_t *this, char **buf, u_int *length)
+dict_allocate_and_serialize(dict_t *this, char **buf, u_int *length)
{
- int ret = -EINVAL;
- ssize_t len = 0;
+ int ret = -EINVAL;
+ ssize_t len = 0;
- if (!this || !buf) {
- gf_msg_debug ("dict", 0, "dict OR buf is NULL");
- goto out;
- }
+ if (!this || !buf) {
+ gf_msg_debug("dict", 0, "dict OR buf is NULL");
+ goto out;
+ }
- LOCK (&this->lock);
- {
- len = dict_serialized_length_lk (this);
- if (len < 0) {
- ret = len;
- goto unlock;
- }
+ LOCK(&this->lock);
+ {
+ len = dict_serialized_length_lk(this);
+ if (len < 0) {
+ ret = len;
+ goto unlock;
+ }
- *buf = GF_CALLOC (1, len, gf_common_mt_char);
- if (*buf == NULL) {
- ret = -ENOMEM;
- goto unlock;
- }
+ *buf = GF_MALLOC(len, gf_common_mt_char);
+ if (*buf == NULL) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
- ret = dict_serialize_lk (this, *buf);
- if (ret < 0) {
- GF_FREE (*buf);
- *buf = NULL;
- goto unlock;
- }
+ ret = dict_serialize_lk(this, *buf);
+ if (ret < 0) {
+ GF_FREE(*buf);
+ *buf = NULL;
+ goto unlock;
+ }
- if (length != NULL) {
- *length = len;
- }
+ if (length != NULL) {
+ *length = len;
}
+ }
unlock:
- UNLOCK (&this->lock);
+ UNLOCK(&this->lock);
out:
- return ret;
+ return ret;
}
/**
@@ -2804,183 +3259,231 @@ out:
* @delimiter : the delimiter to separate the values
*
* @return : 0 -> success
- * : -errno -> faliure
+ * : -errno -> failure
*/
int
-dict_serialize_value_with_delim_lk (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_msg ("dict", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "buf is null");
- goto out;
- }
+dict_serialize_value_with_delim_lk(dict_t *this, char *buf, int32_t *serz_len,
+ char delimiter)
+{
+ int ret = -1;
+ int32_t count = this->count;
+ int32_t vallen = 0;
+ int32_t total_len = 0;
+ data_pair_t *pair = this->members_list;
- count = this->count;
- if (count < 0) {
- gf_msg ("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
- "count (%d) < 0", count);
- goto out;
- }
+ if (!buf) {
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, NULL);
+ goto out;
+ }
- pair = this->members_list;
+ if (count < 0) {
+ gf_smsg("dict", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, "count=%d",
+ count, NULL);
+ goto out;
+ }
- while (count) {
- if (!pair) {
- gf_msg ("dict", GF_LOG_ERROR, 0,
- LG_MSG_PAIRS_LESS_THAN_COUNT,
- "less than count data pairs found");
- goto out;
- }
+ while (count) {
+ if (!pair) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_PAIRS_LESS_THAN_COUNT,
+ NULL);
+ goto out;
+ }
- if (!pair->key || !pair->value) {
- gf_msg ("dict", GF_LOG_ERROR, 0,
- LG_MSG_KEY_OR_VALUE_NULL,
- "key or value is null");
- goto out;
- }
+ if (!pair->key || !pair->value) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_KEY_OR_VALUE_NULL, NULL);
+ goto out;
+ }
- if (!pair->value->data) {
- gf_msg ("dict", GF_LOG_ERROR, 0,
- LG_MSG_NULL_VALUE_IN_DICT,
- "null value found in dict");
- goto out;
- }
+ if (!pair->value->data) {
+ gf_smsg("dict", GF_LOG_ERROR, 0, LG_MSG_NULL_VALUE_IN_DICT, NULL);
+ goto out;
+ }
- vallen = pair->value->len - 1; // length includes \0
- memcpy (buf, pair->value->data, vallen);
- buf += vallen;
- *buf++ = delimiter;
+ vallen = pair->value->len - 1; // length includes \0
+ memcpy(buf, pair->value->data, vallen);
+ buf += vallen;
+ *buf++ = delimiter;
- total_len += (vallen + 1);
+ total_len += (vallen + 1);
- pair = pair->next;
- count--;
- }
+ pair = pair->next;
+ count--;
+ }
- *--buf = '\0'; // remove the last delimiter
- total_len--; // adjust the length
- ret = 0;
+ *--buf = '\0'; // remove the last delimiter
+ total_len--; // adjust the length
+ ret = 0;
- if (serz_len)
- *serz_len = total_len;
+ if (serz_len)
+ *serz_len = total_len;
- out:
- return ret;
+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_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is null!");
- goto out;
- }
-
- LOCK (&this->lock);
- {
- ret = dict_serialize_value_with_delim_lk (this, buf, serz_len,
- delimiter);
- }
- UNLOCK (&this->lock);
+dict_serialize_value_with_delim(dict_t *this, char *buf, int32_t *serz_len,
+ char delimiter)
+{
+ int ret = -1;
+
+ if (!this || !buf) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is null!");
+ goto out;
+ }
+
+ LOCK(&this->lock);
+ {
+ ret = dict_serialize_value_with_delim_lk(this, buf, serz_len,
+ delimiter);
+ }
+ UNLOCK(&this->lock);
out:
- return ret;
+ return ret;
}
int
-dict_dump_to_str (dict_t *dict, char *dump, int dumpsize, char *format)
+dict_dump_to_str(dict_t *dict, char *dump, int dumpsize, char *format)
{
- int ret = 0;
- int dumplen = 0;
- data_pair_t *trav = NULL;
-
- for (trav = dict->members_list; trav; trav = trav->next) {
- ret = snprintf (&dump[dumplen], dumpsize - dumplen,
- format, trav->key, trav->value->data);
- if ((ret == -1) || !ret)
- return ret;
+ int ret = 0;
+ int dumplen = 0;
+ data_pair_t *trav = NULL;
- dumplen += ret;
- }
+ if (!dict)
return 0;
+
+ for (trav = dict->members_list; trav; trav = trav->next) {
+ ret = snprintf(&dump[dumplen], dumpsize - dumplen, format, trav->key,
+ trav->value->data);
+ if ((ret == -1) || !ret)
+ return ret;
+
+ dumplen += ret;
+ }
+ return 0;
}
void
-dict_dump_to_log (dict_t *dict)
-{
- int ret = -1;
- char dump[64*1024] = {0,};
- char *format = "(%s:%s)";
+dict_dump_to_log(dict_t *dict)
+{
+ int ret = -1;
+ char *dump = NULL;
+ const int dump_size = 64 * 1024;
+ char *format = "(%s:%s)";
+
+ if (!dict) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ goto out;
+ }
+
+ dump = GF_MALLOC(dump_size, gf_common_mt_char);
+ if (!dump) {
+ gf_msg_callingfn("dict", GF_LOG_WARNING, ENOMEM, LG_MSG_NO_MEMORY,
+ "dump buffer is NULL");
+ goto out;
+ }
+
+ ret = dict_dump_to_str(dict, dump, dump_size, format);
+ if (ret) {
+ gf_smsg("dict", GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, NULL);
+ goto out;
+ }
+ gf_smsg("dict", GF_LOG_INFO, 0, LG_MSG_DICT_ERROR, "dict=%p", dict,
+ "dump=%s", dump, NULL);
+out:
+ GF_FREE(dump);
- if (!dict) {
- gf_msg_callingfn ("dict", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is NULL");
- return;
- }
+ return;
+}
- ret = dict_dump_to_str (dict, dump, sizeof(dump), format);
- if (ret) {
- gf_msg ("dict", GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT,
- "Failed to log dictionary");
- return;
- }
- gf_msg_callingfn ("dict", GF_LOG_INFO, 0, LG_MSG_DICT_ERROR,
- "dict=%p (%s)", dict, dump);
+void
+dict_dump_to_statedump(dict_t *dict, char *dict_name, char *domain)
+{
+ int ret = -1;
+ char *dump = NULL;
+ const int dump_size = 64 * 1024;
+ char key[4096] = {
+ 0,
+ };
+ char *format = "\n\t%s:%s";
+
+ if (!dict) {
+ gf_msg_callingfn(domain, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "dict is NULL");
+ goto out;
+ }
+
+ dump = GF_MALLOC(dump_size, gf_common_mt_char);
+ if (!dump) {
+ gf_msg_callingfn(domain, GF_LOG_WARNING, ENOMEM, LG_MSG_NO_MEMORY,
+ "dump buffer is NULL");
+ goto out;
+ }
+
+ ret = dict_dump_to_str(dict, dump, dump_size, format);
+ if (ret) {
+ gf_smsg(domain, GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT, "name=%s",
+ dict_name, NULL);
+ goto out;
+ }
+ gf_proc_dump_build_key(key, domain, "%s", dict_name);
+ gf_proc_dump_write(key, "%s", dump);
- return;
+out:
+ GF_FREE(dump);
+
+ return;
}
-void
-dict_dump_to_statedump (dict_t *dict, char *dict_name, char *domain)
+dict_t *
+dict_for_key_value(const char *name, const char *value, size_t size,
+ gf_boolean_t is_static)
{
- int ret = -1;
- char dump[64*1024] = {0,};
- char key[4096] = {0,};
- char *format = "\n\t%s:%s";
+ dict_t *xattr = dict_new();
+ int ret = 0;
- if (!dict) {
- gf_msg_callingfn (domain, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "dict is NULL");
- return;
- }
+ if (!xattr)
+ return NULL;
- ret = dict_dump_to_str (dict, dump, sizeof(dump), format);
- if (ret) {
- gf_msg (domain, GF_LOG_WARNING, 0, LG_MSG_FAILED_TO_LOG_DICT,
- "Failed to log dictionary %s", dict_name);
- return;
- }
- gf_proc_dump_build_key (key, domain, dict_name);
- gf_proc_dump_write (key, "%s", dump);
+ if (is_static)
+ ret = dict_set_static_bin(xattr, (char *)name, (void *)value, size);
+ else
+ ret = dict_set_bin(xattr, (char *)name, (void *)value, size);
- return;
+ if (ret) {
+ dict_destroy(xattr);
+ xattr = NULL;
+ }
+
+ return xattr;
}
-dict_t *
-dict_for_key_value (const char *name, const char *value, size_t size)
+/*
+ * "strings" should be NULL terminated strings array.
+ */
+int
+dict_has_key_from_array(dict_t *dict, char **strings, gf_boolean_t *result)
{
- dict_t *xattr = NULL;
- int ret = 0;
+ int i = 0;
+ uint32_t hash = 0;
- xattr = dict_new ();
- if (!xattr)
- return NULL;
+ if (!dict || !strings || !result)
+ return -EINVAL;
- ret = dict_set_static_bin (xattr, (char *)name, (void *)value, size);
- if (ret) {
- dict_destroy (xattr);
- xattr = NULL;
- }
-
- return xattr;
+ LOCK(&dict->lock);
+ {
+ for (i = 0; strings[i]; i++) {
+ hash = (uint32_t)XXH64(strings[i], strlen(strings[i]), 0);
+ if (dict_lookup_common(dict, strings[i], hash)) {
+ *result = _gf_true;
+ goto unlock;
+ }
+ }
+ *result = _gf_false;
+ }
+unlock:
+ UNLOCK(&dict->lock);
+ return 0;
}
diff --git a/libglusterfs/src/dict.h b/libglusterfs/src/dict.h
deleted file mode 100644
index c5b82677e2e..00000000000
--- a/libglusterfs/src/dict.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- 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
-#define _DICT_H
-
-#include <inttypes.h>
-#include <sys/uio.h>
-#include <pthread.h>
-
-#include "common-utils.h"
-#include "libglusterfs-messages.h"
-
-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_msg (this->name, GF_LOG_WARNING, 0, \
- LG_MSG_DICT_SERIAL_FAILED, \
- "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 { \
- if (!len) \
- break; \
- to = dict_new(); \
- GF_VALIDATE_OR_GOTO (xl->name, to, labl); \
- \
- ret = dict_unserialize (buff, len, &to); \
- if (ret < 0) { \
- gf_msg (xl->name, GF_LOG_WARNING, 0, \
- LG_MSG_DICT_UNSERIAL_FAILED, \
- "failed to unserialize dictionary (%s)", \
- (#to)); \
- \
- ope = EINVAL; \
- goto labl; \
- } \
- \
- } while (0)
-
-struct _data {
- unsigned char is_static:1;
- unsigned char is_const:1;
- int32_t len;
- char *data;
- int32_t refcount;
- gf_lock_t lock;
-};
-
-struct _data_pair {
- struct _data_pair *hash_next;
- struct _data_pair *prev;
- struct _data_pair *next;
- data_t *value;
- char *key;
-};
-
-struct _dict {
- unsigned char is_static:1;
- int32_t hash_size;
- int32_t count;
- int32_t refcount;
- data_pair_t **members;
- data_pair_t *members_list;
- char *extra_free;
- char *extra_stdfree;
- gf_lock_t lock;
- data_pair_t *members_internal;
- data_pair_t free_pair;
- gf_boolean_t free_pair_in_use;
-};
-
-typedef gf_boolean_t (*dict_match_t) (dict_t *d, char *k, data_t *v,
- void *data);
-
-int32_t is_data_equal (data_t *one, data_t *two);
-void data_destroy (data_t *data);
-
-/* function to set a key/value pair (overwrite existing if matches the key */
-int32_t dict_set (dict_t *this, char *key, data_t *value);
-/* function to set a new key/value pair (without checking for duplicate) */
-int32_t dict_add (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, u_int *length);
-
-void dict_destroy (dict_t *dict);
-void dict_unref (dict_t *dict);
-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_t **data);
-/*
- TODO: provide converts for different byte sizes, signedness, and void *
- */
-data_t *int_to_data (int64_t value);
-data_t *str_to_data (char *value);
-data_t *data_from_dynstr (char *value);
-data_t *data_from_dynptr (void *value, int32_t len);
-data_t *bin_to_data (void *value, int32_t len);
-data_t *static_str_to_data (char *value);
-data_t *static_bin_to_data (void *value);
-
-int64_t data_to_int64 (data_t *data);
-int32_t data_to_int32 (data_t *data);
-int16_t data_to_int16 (data_t *data);
-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_int64 (int64_t value);
-data_t *data_from_int32 (int32_t value);
-data_t *data_from_int16 (int16_t value);
-data_t *data_from_int8 (int8_t value);
-
-data_t *data_from_uint64 (uint64_t value);
-data_t *data_from_uint32 (uint32_t value);
-data_t *data_from_uint16 (uint16_t value);
-
-char *data_to_str (data_t *data);
-void *data_to_bin (data_t *data);
-void *data_to_ptr (data_t *data);
-
-data_t *get_new_data ();
-data_t * data_copy (data_t *old);
-dict_t *get_new_dict_full (int size_hint);
-dict_t *get_new_dict ();
-
-int dict_foreach (dict_t *this,
- int (*fn)(dict_t *this,
- char *key,
- data_t *value,
- void *data),
- void *data);
-
-int dict_foreach_fnmatch (dict_t *dict, char *pattern,
- int (*fn)(dict_t *this,
- char *key,
- data_t *value,
- void *data),
- void *data);
-
-int
-dict_foreach_match (dict_t *dict,
- gf_boolean_t (*match)(dict_t *this,
- char *key,
- data_t *value,
- void *mdata),
- void *match_data,
- int (*action)(dict_t *this,
- char *key,
- data_t *value,
- void *adata),
- void *action_data);
-
-int dict_null_foreach_fn (dict_t *d, char *k,
- data_t *v, void *tmp);
-int dict_remove_foreach_fn (dict_t *d, char *k,
- data_t *v, void *tmp);
-dict_t *dict_copy (dict_t *this, dict_t *new);
-int dict_keys_join (void *value, int size, dict_t *dict,
- int (*filter_fn)(char *key));
-
-/* CLEANED UP FUNCTIONS DECLARATIONS */
-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);
-
-GF_MUST_CHECK int dict_get_int16 (dict_t *this, char *key, int16_t *val);
-GF_MUST_CHECK int dict_set_int16 (dict_t *this, char *key, int16_t val);
-
-GF_MUST_CHECK int dict_get_int32 (dict_t *this, char *key, int32_t *val);
-GF_MUST_CHECK int dict_set_int32 (dict_t *this, char *key, int32_t val);
-
-GF_MUST_CHECK int dict_get_int64 (dict_t *this, char *key, int64_t *val);
-GF_MUST_CHECK int dict_set_int64 (dict_t *this, char *key, int64_t val);
-
-GF_MUST_CHECK int dict_get_uint16 (dict_t *this, char *key, uint16_t *val);
-GF_MUST_CHECK int dict_set_uint16 (dict_t *this, char *key, uint16_t val);
-
-GF_MUST_CHECK int dict_get_uint32 (dict_t *this, char *key, uint32_t *val);
-GF_MUST_CHECK int dict_set_uint32 (dict_t *this, char *key, uint32_t val);
-
-GF_MUST_CHECK int dict_get_uint64 (dict_t *this, char *key, uint64_t *val);
-GF_MUST_CHECK int dict_set_uint64 (dict_t *this, char *key, uint64_t val);
-
-GF_MUST_CHECK int dict_get_double (dict_t *this, char *key, double *val);
-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);
-
-GF_MUST_CHECK int dict_get_bin (dict_t *this, char *key, void **ptr);
-GF_MUST_CHECK int dict_set_bin (dict_t *this, char *key, void *ptr, size_t size);
-GF_MUST_CHECK int dict_set_static_bin (dict_t *this, char *key, void *ptr, size_t size);
-
-GF_MUST_CHECK int dict_set_str (dict_t *this, char *key, char *str);
-GF_MUST_CHECK int dict_set_dynstr (dict_t *this, char *key, char *str);
-GF_MUST_CHECK int dict_set_dynstr_with_alloc (dict_t *this, char *key, const char *str);
-GF_MUST_CHECK int dict_add_dynstr_with_alloc (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_to_statedump (dict_t *dict, char *dict_name, char *domain);
-
-void
-dict_dump_to_log (dict_t *dict);
-
-int
-dict_dump_to_str (dict_t *dict, char *dump, int dumpsize, char *format);
-gf_boolean_t
-dict_match_everything (dict_t *d, char *k, data_t *v, void *data);
-
-dict_t *
-dict_for_key_value (const char *name, const char *value, size_t size);
-
-gf_boolean_t
-are_dicts_equal (dict_t *one, dict_t *two,
- gf_boolean_t (*match) (dict_t *d, char *k, data_t *v,
- void *data),
- gf_boolean_t (*value_ignore) (char *k));
-#endif
diff --git a/libglusterfs/src/event-epoll.c b/libglusterfs/src/event-epoll.c
index 78eff9398a6..fb4fb845b40 100644
--- a/libglusterfs/src/event-epoll.c
+++ b/libglusterfs/src/event-epoll.c
@@ -8,761 +8,839 @@
cases as published by the Free Software Foundation.
*/
-#include <sys/poll.h>
#include <pthread.h>
-#include <unistd.h>
-#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
-#include <string.h>
-
-#include "logging.h"
-#include "event.h"
-#include "mem-pool.h"
-#include "common-utils.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/gf-event.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/libglusterfs-messages.h"
#ifdef HAVE_SYS_EPOLL_H
#include <sys/epoll.h>
-
struct event_slot_epoll {
- int fd;
- int events;
- int gen;
- int ref;
- int do_close;
- int in_handler;
- void *data;
- event_handler_t handler;
- gf_lock_t lock;
+ int fd;
+ int events;
+ int gen;
+ int idx;
+ gf_atomic_t ref;
+ int do_close;
+ int in_handler;
+ int handled_error;
+ void *data;
+ event_handler_t handler;
+ gf_lock_t lock;
+ struct list_head poller_death;
};
struct event_thread_data {
- struct event_pool *event_pool;
- int event_index;
+ struct event_pool *event_pool;
+ int event_index;
};
static struct event_slot_epoll *
-__event_newtable (struct event_pool *event_pool, int table_idx)
+__event_newtable(struct event_pool *event_pool, int table_idx)
{
- struct event_slot_epoll *table = NULL;
- int i = -1;
+ struct event_slot_epoll *table = NULL;
+ int i = -1;
- table = GF_CALLOC (sizeof (*table), EVENT_EPOLL_SLOTS,
- gf_common_mt_ereg);
- if (!table)
- return NULL;
+ table = GF_CALLOC(sizeof(*table), EVENT_EPOLL_SLOTS, gf_common_mt_ereg);
+ if (!table)
+ return NULL;
- for (i = 0; i < EVENT_EPOLL_SLOTS; i++) {
- table[i].fd = -1;
- LOCK_INIT (&table[i].lock);
- }
+ for (i = 0; i < EVENT_EPOLL_SLOTS; i++) {
+ table[i].fd = -1;
+ LOCK_INIT(&table[i].lock);
+ INIT_LIST_HEAD(&table[i].poller_death);
+ }
- event_pool->ereg[table_idx] = table;
- event_pool->slots_used[table_idx] = 0;
+ event_pool->ereg[table_idx] = table;
+ event_pool->slots_used[table_idx] = 0;
- return table;
+ return table;
}
-
static int
-__event_slot_alloc (struct event_pool *event_pool, int fd)
+event_slot_ref(struct event_slot_epoll *slot)
{
- int i = 0;
- int table_idx = -1;
- int gen = -1;
- struct event_slot_epoll *table = NULL;
-
- for (i = 0; i < EVENT_EPOLL_TABLES; i++) {
- switch (event_pool->slots_used[i]) {
- case EVENT_EPOLL_SLOTS:
- continue;
- case 0:
- if (!event_pool->ereg[i]) {
- table = __event_newtable (event_pool, i);
- if (!table)
- return -1;
- } else {
- table = event_pool->ereg[i];
- }
- break;
- default:
- table = event_pool->ereg[i];
- break;
- }
-
- if (table)
- /* break out of the loop */
- break;
- }
-
- if (!table)
- return -1;
-
- table_idx = i;
-
- for (i = 0; i < EVENT_EPOLL_SLOTS; i++) {
- if (table[i].fd == -1) {
- /* wipe everything except bump the generation */
- gen = table[i].gen;
- memset (&table[i], 0, sizeof (table[i]));
- table[i].gen = gen + 1;
-
- LOCK_INIT (&table[i].lock);
-
- table[i].fd = fd;
- event_pool->slots_used[table_idx]++;
-
- break;
- }
- }
-
- return table_idx * EVENT_EPOLL_SLOTS + i;
-}
+ if (!slot)
+ return -1;
+ return GF_ATOMIC_INC(slot->ref);
+}
static int
-event_slot_alloc (struct event_pool *event_pool, int fd)
+__event_slot_alloc(struct event_pool *event_pool, int fd,
+ char notify_poller_death, struct event_slot_epoll **slot)
{
- int idx = -1;
+ int i = 0;
+ int j = 0;
+ int table_idx = -1;
+ int gen = -1;
+ struct event_slot_epoll *table = NULL;
+
+retry:
+
+ while (i < EVENT_EPOLL_TABLES) {
+ switch (event_pool->slots_used[i]) {
+ case EVENT_EPOLL_SLOTS:
+ break;
+ case 0:
+ if (!event_pool->ereg[i]) {
+ table = __event_newtable(event_pool, i);
+ if (!table)
+ return -1;
+ } else {
+ table = event_pool->ereg[i];
+ }
+ break;
+ default:
+ table = event_pool->ereg[i];
+ break;
+ }
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_slot_alloc (event_pool, fd);
- }
- pthread_mutex_unlock (&event_pool->mutex);
+ if (table)
+ /* break out of the loop */
+ break;
+ i++;
+ }
- return idx;
-}
+ if (!table)
+ return -1;
+ table_idx = i;
+ for (j = 0; j < EVENT_EPOLL_SLOTS; j++) {
+ if (table[j].fd == -1) {
+ /* wipe everything except bump the generation */
+ gen = table[j].gen;
+ memset(&table[j], 0, sizeof(table[j]));
+ table[j].gen = gen + 1;
-static void
-__event_slot_dealloc (struct event_pool *event_pool, int idx)
-{
- int table_idx = 0;
- int offset = 0;
- struct event_slot_epoll *table = NULL;
- struct event_slot_epoll *slot = NULL;
+ LOCK_INIT(&table[j].lock);
+ INIT_LIST_HEAD(&table[j].poller_death);
- table_idx = idx / EVENT_EPOLL_SLOTS;
- offset = idx % EVENT_EPOLL_SLOTS;
+ table[j].fd = fd;
+ if (notify_poller_death) {
+ table[j].idx = table_idx * EVENT_EPOLL_SLOTS + j;
+ list_add_tail(&table[j].poller_death,
+ &event_pool->poller_death);
+ }
- table = event_pool->ereg[table_idx];
- if (!table)
- return;
+ event_pool->slots_used[table_idx]++;
- slot = &table[offset];
- slot->gen++;
+ break;
+ }
+ }
+
+ if (j == EVENT_EPOLL_SLOTS) {
+ table = NULL;
+ i++;
+ goto retry;
+ } else {
+ (*slot) = &table[j];
+ event_slot_ref(*slot);
+ return table_idx * EVENT_EPOLL_SLOTS + j;
+ }
+}
+
+static int
+event_slot_alloc(struct event_pool *event_pool, int fd,
+ char notify_poller_death, struct event_slot_epoll **slot)
+{
+ int idx = -1;
- slot->fd = -1;
- event_pool->slots_used[table_idx]--;
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ idx = __event_slot_alloc(event_pool, fd, notify_poller_death, slot);
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
- return;
+ return idx;
}
+static void
+__event_slot_dealloc(struct event_pool *event_pool, int idx)
+{
+ int table_idx = 0;
+ int offset = 0;
+ struct event_slot_epoll *table = NULL;
+ struct event_slot_epoll *slot = NULL;
+ int fd = -1;
+
+ table_idx = idx / EVENT_EPOLL_SLOTS;
+ offset = idx % EVENT_EPOLL_SLOTS;
+
+ table = event_pool->ereg[table_idx];
+ if (!table)
+ return;
+
+ slot = &table[offset];
+ slot->gen++;
+
+ fd = slot->fd;
+ slot->fd = -1;
+ slot->handled_error = 0;
+ slot->in_handler = 0;
+ list_del_init(&slot->poller_death);
+ if (fd != -1)
+ event_pool->slots_used[table_idx]--;
+
+ return;
+}
static void
-event_slot_dealloc (struct event_pool *event_pool, int idx)
+event_slot_dealloc(struct event_pool *event_pool, int idx)
{
- pthread_mutex_lock (&event_pool->mutex);
- {
- __event_slot_dealloc (event_pool, idx);
- }
- pthread_mutex_unlock (&event_pool->mutex);
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ __event_slot_dealloc(event_pool, idx);
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
- return;
+ return;
}
-
static struct event_slot_epoll *
-event_slot_get (struct event_pool *event_pool, int idx)
+event_slot_get(struct event_pool *event_pool, int idx)
{
- struct event_slot_epoll *slot = NULL;
- struct event_slot_epoll *table = NULL;
- int table_idx = 0;
- int offset = 0;
-
- table_idx = idx / EVENT_EPOLL_SLOTS;
- offset = idx % EVENT_EPOLL_SLOTS;
+ struct event_slot_epoll *slot = NULL;
+ struct event_slot_epoll *table = NULL;
+ int table_idx = 0;
+ int offset = 0;
- table = event_pool->ereg[table_idx];
- if (!table)
- return NULL;
+ table_idx = idx / EVENT_EPOLL_SLOTS;
+ offset = idx % EVENT_EPOLL_SLOTS;
- slot = &table[offset];
+ table = event_pool->ereg[table_idx];
+ if (!table)
+ return NULL;
- LOCK (&slot->lock);
- {
- slot->ref++;
- }
- UNLOCK (&slot->lock);
+ slot = &table[offset];
- return slot;
+ event_slot_ref(slot);
+ return slot;
}
-
static void
-event_slot_unref (struct event_pool *event_pool, struct event_slot_epoll *slot,
- int idx)
+__event_slot_unref(struct event_pool *event_pool, struct event_slot_epoll *slot,
+ int idx)
{
- int ref = -1;
- int fd = -1;
- int do_close = 0;
-
- LOCK (&slot->lock);
- {
- ref = --slot->ref;
- fd = slot->fd;
- do_close = slot->do_close;
- }
- UNLOCK (&slot->lock);
-
- if (ref)
- /* slot still alive */
- goto done;
-
- event_slot_dealloc (event_pool, idx);
-
- if (do_close)
- close (fd);
+ int ref = -1;
+ int fd = -1;
+ int do_close = 0;
+
+ ref = GF_ATOMIC_DEC(slot->ref);
+ if (ref)
+ /* slot still alive */
+ goto done;
+
+ LOCK(&slot->lock);
+ {
+ fd = slot->fd;
+ do_close = slot->do_close;
+ slot->do_close = 0;
+ }
+ UNLOCK(&slot->lock);
+
+ __event_slot_dealloc(event_pool, idx);
+
+ if (do_close)
+ sys_close(fd);
done:
- return;
+ return;
}
+static void
+event_slot_unref(struct event_pool *event_pool, struct event_slot_epoll *slot,
+ int idx)
+{
+ int ref = -1;
+ int fd = -1;
+ int do_close = 0;
+
+ ref = GF_ATOMIC_DEC(slot->ref);
+ if (ref)
+ /* slot still alive */
+ goto done;
+
+ LOCK(&slot->lock);
+ {
+ fd = slot->fd;
+ do_close = slot->do_close;
+ slot->do_close = 0;
+ }
+ UNLOCK(&slot->lock);
+
+ event_slot_dealloc(event_pool, idx);
+
+ if (do_close)
+ sys_close(fd);
+done:
+ return;
+}
static struct event_pool *
-event_pool_new_epoll (int count, int eventthreadcount)
+event_pool_new_epoll(int count, int eventthreadcount)
{
- struct event_pool *event_pool = NULL;
- int epfd = -1;
+ struct event_pool *event_pool = NULL;
+ int epfd = -1;
- event_pool = GF_CALLOC (1, sizeof (*event_pool),
- gf_common_mt_event_pool);
+ event_pool = GF_CALLOC(1, sizeof(*event_pool), gf_common_mt_event_pool);
- if (!event_pool)
- goto out;
+ if (!event_pool)
+ goto out;
- epfd = epoll_create (count);
-
- if (epfd == -1) {
- gf_msg ("epoll", GF_LOG_ERROR, errno,
- LG_MSG_EPOLL_FD_CREATE_FAILED, "epoll fd creation "
- "failed");
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- event_pool = NULL;
- goto out;
- }
+ epfd = epoll_create(count);
- event_pool->fd = epfd;
+ if (epfd == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_CREATE_FAILED,
+ NULL);
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ event_pool = NULL;
+ goto out;
+ }
- event_pool->count = count;
+ event_pool->fd = epfd;
- event_pool->eventthreadcount = eventthreadcount;
+ event_pool->count = count;
+ INIT_LIST_HEAD(&event_pool->poller_death);
+ event_pool->eventthreadcount = eventthreadcount;
+ event_pool->auto_thread_count = 0;
- pthread_mutex_init (&event_pool->mutex, NULL);
+ pthread_mutex_init(&event_pool->mutex, NULL);
out:
- return event_pool;
+ return event_pool;
}
-
static void
-__slot_update_events (struct event_slot_epoll *slot, int poll_in, int poll_out)
+__slot_update_events(struct event_slot_epoll *slot, int poll_in, int poll_out)
{
- switch (poll_in) {
- case 1:
- slot->events |= EPOLLIN;
- break;
- case 0:
- slot->events &= ~EPOLLIN;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_msg ("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN,
- "invalid poll_in value %d", poll_in);
- break;
- }
-
- switch (poll_out) {
- case 1:
- slot->events |= EPOLLOUT;
- break;
- case 0:
- slot->events &= ~EPOLLOUT;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_msg ("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT,
- "invalid poll_out value %d", poll_out);
- break;
- }
+ switch (poll_in) {
+ case 1:
+ slot->events |= EPOLLIN;
+ break;
+ case 0:
+ slot->events &= ~EPOLLIN;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN,
+ "value=%d", poll_in, NULL);
+ break;
+ }
+
+ switch (poll_out) {
+ case 1:
+ slot->events |= EPOLLOUT;
+ break;
+ case 0:
+ slot->events &= ~EPOLLOUT;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT,
+ "value=%d", poll_out, NULL);
+ break;
+ }
}
-
int
-event_register_epoll (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out)
+event_register_epoll(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death)
{
- int idx = -1;
- int ret = -1;
- int destroy = 0;
- struct epoll_event epoll_event = {0, };
- struct event_data *ev_data = (void *)&epoll_event.data;
- struct event_slot_epoll *slot = NULL;
-
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- /* TODO: Even with the below check, there is a possiblity of race,
- * What if the destroy mode is set after the check is done.
- * Not sure of the best way to prevent this race, ref counting
- * is one possibility.
- * There is no harm in registering and unregistering the fd
- * even after destroy mode is set, just that such fds will remain
- * open until unregister is called, also the events on that fd will be
- * notified, until one of the poller thread is alive.
- */
- pthread_mutex_lock (&event_pool->mutex);
- {
- destroy = event_pool->destroy;
- }
- pthread_mutex_unlock (&event_pool->mutex);
-
- if (destroy == 1)
- goto out;
-
- idx = event_slot_alloc (event_pool, fd);
- if (idx == -1) {
- gf_msg ("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND,
- "could not find slot for fd=%d", fd);
- return -1;
- }
-
- slot = event_slot_get (event_pool, idx);
-
- assert (slot->fd == fd);
-
- LOCK (&slot->lock);
- {
- /* make epoll 'singleshot', which
- means we need to re-add the fd with
- epoll_ctl(EPOLL_CTL_MOD) after delivery of every
- single event. This assures us that while a poller
- thread has picked up and is processing an event,
- another poller will not try to pick this at the same
- time as well.
- */
-
- slot->events = EPOLLPRI | EPOLLONESHOT;
- slot->handler = handler;
- slot->data = data;
-
- __slot_update_events (slot, poll_in, poll_out);
-
- epoll_event.events = slot->events;
- ev_data->idx = idx;
- ev_data->gen = slot->gen;
-
- ret = epoll_ctl (event_pool->fd, EPOLL_CTL_ADD, fd,
- &epoll_event);
- /* check ret after UNLOCK() to avoid deadlock in
- event_slot_unref()
- */
- }
- UNLOCK (&slot->lock);
-
- if (ret == -1) {
- gf_msg ("epoll", GF_LOG_ERROR, errno,
- LG_MSG_EPOLL_FD_ADD_FAILED, "failed to add fd(=%d) to "
- "epoll fd(=%d)", fd, event_pool->fd);
- event_slot_unref (event_pool, slot, idx);
- idx = -1;
- }
-
- /* keep slot->ref (do not event_slot_unref) if successful */
+ int idx = -1;
+ int ret = -1;
+ int destroy = 0;
+ struct epoll_event epoll_event = {
+ 0,
+ };
+ struct event_data *ev_data = (void *)&epoll_event.data;
+ struct event_slot_epoll *slot = NULL;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ /* TODO: Even with the below check, there is a possibility of race,
+ * What if the destroy mode is set after the check is done.
+ * Not sure of the best way to prevent this race, ref counting
+ * is one possibility.
+ * There is no harm in registering and unregistering the fd
+ * even after destroy mode is set, just that such fds will remain
+ * open until unregister is called, also the events on that fd will be
+ * notified, until one of the poller thread is alive.
+ */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ destroy = event_pool->destroy;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ if (destroy == 1)
+ goto out;
+
+ idx = event_slot_alloc(event_pool, fd, notify_poller_death, &slot);
+ if (idx == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd,
+ NULL);
+ return -1;
+ }
+
+ assert(slot->fd == fd);
+
+ LOCK(&slot->lock);
+ {
+ /* make epoll 'singleshot', which
+ means we need to re-add the fd with
+ epoll_ctl(EPOLL_CTL_MOD) after delivery of every
+ single event. This assures us that while a poller
+ thread has picked up and is processing an event,
+ another poller will not try to pick this at the same
+ time as well.
+ */
+
+ slot->events = EPOLLPRI | EPOLLHUP | EPOLLERR | EPOLLONESHOT;
+ slot->handler = handler;
+ slot->data = data;
+
+ __slot_update_events(slot, poll_in, poll_out);
+
+ epoll_event.events = slot->events;
+ ev_data->idx = idx;
+ ev_data->gen = slot->gen;
+
+ ret = epoll_ctl(event_pool->fd, EPOLL_CTL_ADD, fd, &epoll_event);
+ /* check ret after UNLOCK() to avoid deadlock in
+ event_slot_unref()
+ */
+ }
+ UNLOCK(&slot->lock);
+
+ if (ret == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_ADD_FAILED,
+ "fd=%d", fd, "epoll_fd=%d", event_pool->fd, NULL);
+ event_slot_unref(event_pool, slot, idx);
+ idx = -1;
+ }
+
+ /* keep slot->ref (do not event_slot_unref) if successful */
out:
- return idx;
+ return idx;
}
-
static int
-event_unregister_epoll_common (struct event_pool *event_pool, int fd,
- int idx, int do_close)
+event_unregister_epoll_common(struct event_pool *event_pool, int fd, int idx,
+ int do_close)
{
- int ret = -1;
- struct event_slot_epoll *slot = NULL;
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- slot = event_slot_get (event_pool, idx);
-
- assert (slot->fd == fd);
-
- LOCK (&slot->lock);
- {
- ret = epoll_ctl (event_pool->fd, EPOLL_CTL_DEL, fd, NULL);
-
- if (ret == -1) {
- gf_msg ("epoll", GF_LOG_ERROR, errno,
- LG_MSG_EPOLL_FD_DEL_FAILED, "fail to del "
- "fd(=%d) from epoll fd(=%d)", fd,
- event_pool->fd);
- goto unlock;
- }
-
- slot->do_close = do_close;
- slot->gen++; /* detect unregister in dispatch_handler() */
+ int ret = -1;
+ struct event_slot_epoll *slot = NULL;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ /* During shutdown, it may happen that a socket registration with
+ * the event sub-system may fail and an rpc_transport_unref() may
+ * be called for such an unregistered socket with idx == -1. This
+ * may cause the following assert(slot->fd == fd) to fail.
+ */
+ if (idx < 0)
+ goto out;
+
+ slot = event_slot_get(event_pool, idx);
+ if (!slot) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd,
+ "idx=%d", idx, NULL);
+ return -1;
+ }
+
+ assert(slot->fd == fd);
+
+ LOCK(&slot->lock);
+ {
+ ret = epoll_ctl(event_pool->fd, EPOLL_CTL_DEL, fd, NULL);
+
+ if (ret == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_DEL_FAILED,
+ "fd=%d", fd, "epoll_fd=%d", event_pool->fd, NULL);
+ goto unlock;
}
+
+ slot->do_close = do_close;
+ slot->gen++; /* detect unregister in dispatch_handler() */
+ }
unlock:
- UNLOCK (&slot->lock);
+ UNLOCK(&slot->lock);
- event_slot_unref (event_pool, slot, idx); /* one for event_register() */
- event_slot_unref (event_pool, slot, idx); /* one for event_slot_get() */
+ event_slot_unref(event_pool, slot, idx); /* one for event_register() */
+ event_slot_unref(event_pool, slot, idx); /* one for event_slot_get() */
out:
- return ret;
+ return ret;
}
-
static int
-event_unregister_epoll (struct event_pool *event_pool, int fd, int idx_hint)
+event_unregister_epoll(struct event_pool *event_pool, int fd, int idx_hint)
{
- int ret = -1;
+ int ret = -1;
- ret = event_unregister_epoll_common (event_pool, fd, idx_hint, 0);
+ ret = event_unregister_epoll_common(event_pool, fd, idx_hint, 0);
- return ret;
+ return ret;
}
-
static int
-event_unregister_close_epoll (struct event_pool *event_pool, int fd,
- int idx_hint)
+event_unregister_close_epoll(struct event_pool *event_pool, int fd,
+ int idx_hint)
{
- int ret = -1;
+ int ret = -1;
- ret = event_unregister_epoll_common (event_pool, fd, idx_hint, 1);
+ ret = event_unregister_epoll_common(event_pool, fd, idx_hint, 1);
- return ret;
+ return ret;
}
-
static int
-event_select_on_epoll (struct event_pool *event_pool, int fd, int idx,
- int poll_in, int poll_out)
+event_select_on_epoll(struct event_pool *event_pool, int fd, int idx,
+ int poll_in, int poll_out)
{
- int ret = -1;
- struct event_slot_epoll *slot = NULL;
- struct epoll_event epoll_event = {0, };
- struct event_data *ev_data = (void *)&epoll_event.data;
-
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- slot = event_slot_get (event_pool, idx);
-
- assert (slot->fd == fd);
-
- LOCK (&slot->lock);
- {
- __slot_update_events (slot, poll_in, poll_out);
-
- epoll_event.events = slot->events;
- ev_data->idx = idx;
- ev_data->gen = slot->gen;
-
- if (slot->in_handler)
- /* in_handler indicates at least one thread
- executing event_dispatch_epoll_handler()
- which will perform epoll_ctl(EPOLL_CTL_MOD)
- anyways (because of EPOLLET)
-
- This not only saves a system call, but also
- avoids possibility of another epoll thread
- parallely picking up the next event while the
- ongoing handler is still in progress (and
- resulting in unnecessary contention on
- rpc_transport_t->mutex).
- */
- goto unlock;
-
- ret = epoll_ctl (event_pool->fd, EPOLL_CTL_MOD, fd,
- &epoll_event);
- if (ret == -1) {
- gf_msg ("epoll", GF_LOG_ERROR, errno,
- LG_MSG_EPOLL_FD_MODIFY_FAILED, "failed to "
- "modify fd(=%d) events to %d", fd,
- epoll_event.events);
- }
- }
+ int ret = -1;
+ struct event_slot_epoll *slot = NULL;
+ struct epoll_event epoll_event = {
+ 0,
+ };
+ struct event_data *ev_data = (void *)&epoll_event.data;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ slot = event_slot_get(event_pool, idx);
+ if (!slot) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd,
+ "idx=%d", idx, NULL);
+ return -1;
+ }
+
+ assert(slot->fd == fd);
+
+ LOCK(&slot->lock);
+ {
+ __slot_update_events(slot, poll_in, poll_out);
+
+ epoll_event.events = slot->events;
+ ev_data->idx = idx;
+ ev_data->gen = slot->gen;
+
+ if (slot->in_handler)
+ /*
+ * in_handler indicates at least one thread
+ * executing event_dispatch_epoll_handler()
+ * which will perform epoll_ctl(EPOLL_CTL_MOD)
+ * anyways (because of EPOLLET)
+ *
+ * This not only saves a system call, but also
+ * avoids possibility of another epoll thread
+ * picking up the next event while the ongoing
+ * handler is still in progress (and resulting
+ * in unnecessary contention on rpc_transport_t->mutex).
+ */
+ goto unlock;
+
+ ret = epoll_ctl(event_pool->fd, EPOLL_CTL_MOD, fd, &epoll_event);
+ if (ret == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, errno, LG_MSG_EPOLL_FD_MODIFY_FAILED,
+ "fd=%d", fd, "events=%d", epoll_event.events, NULL);
+ }
+ }
unlock:
- UNLOCK (&slot->lock);
+ UNLOCK(&slot->lock);
- event_slot_unref (event_pool, slot, idx);
+ event_slot_unref(event_pool, slot, idx);
out:
- return idx;
+ return idx;
}
-
static int
-event_dispatch_epoll_handler (struct event_pool *event_pool,
- struct epoll_event *event)
+event_dispatch_epoll_handler(struct event_pool *event_pool,
+ struct epoll_event *event)
{
- struct event_data *ev_data = NULL;
- struct event_slot_epoll *slot = NULL;
- event_handler_t handler = NULL;
- void *data = NULL;
- int idx = -1;
- int gen = -1;
- int ret = -1;
- int fd = -1;
-
- ev_data = (void *)&event->data;
- handler = NULL;
- data = NULL;
-
- idx = ev_data->idx;
- gen = ev_data->gen;
-
- slot = event_slot_get (event_pool, idx);
-
- LOCK (&slot->lock);
- {
- fd = slot->fd;
- if (fd == -1) {
- gf_msg ("epoll", GF_LOG_ERROR, 0,
- LG_MSG_STALE_FD_FOUND, "stale fd found on "
- "idx=%d, gen=%d, events=%d, slot->gen=%d",
- idx, gen, event->events, slot->gen);
- /* fd got unregistered in another thread */
- goto pre_unlock;
- }
-
- if (gen != slot->gen) {
- gf_msg ("epoll", GF_LOG_ERROR, 0,
- LG_MSG_GENERATION_MISMATCH, "generation "
- "mismatch on idx=%d, gen=%d, slot->gen=%d, "
- "slot->fd=%d", idx, gen, slot->gen, slot->fd);
- /* slot was re-used and therefore is another fd! */
- goto pre_unlock;
- }
-
- handler = slot->handler;
- data = slot->data;
-
- slot->in_handler++;
- }
-pre_unlock:
- UNLOCK (&slot->lock);
-
- if (!handler)
- goto out;
-
- ret = handler (fd, idx, data,
- (event->events & (EPOLLIN|EPOLLPRI)),
- (event->events & (EPOLLOUT)),
- (event->events & (EPOLLERR|EPOLLHUP)));
-
- LOCK (&slot->lock);
- {
- slot->in_handler--;
-
- if (gen != slot->gen) {
- /* event_unregister() happened while we were
- in handler()
- */
- gf_msg_debug ("epoll", 0, "generation bumped on idx=%d"
- " from gen=%d to slot->gen=%d, fd=%d, "
- "slot->fd=%d", idx, gen, slot->gen, fd,
- slot->fd);
- goto post_unlock;
- }
-
- /* This call also picks up the changes made by another
- thread calling event_select_on_epoll() while this
- thread was busy in handler()
- */
- if (slot->in_handler == 0) {
- event->events = slot->events;
- ret = epoll_ctl (event_pool->fd, EPOLL_CTL_MOD,
- fd, event);
- }
- }
-post_unlock:
- UNLOCK (&slot->lock);
-out:
- event_slot_unref (event_pool, slot, idx);
+ struct event_data *ev_data = NULL;
+ struct event_slot_epoll *slot = NULL;
+ event_handler_t handler = NULL;
+ void *data = NULL;
+ int idx = -1;
+ int gen = -1;
+ int ret = -1;
+ int fd = -1;
+ gf_boolean_t handled_error_previously = _gf_false;
+
+ ev_data = (void *)&event->data;
+ handler = NULL;
+ data = NULL;
+
+ idx = ev_data->idx;
+ gen = ev_data->gen;
+
+ slot = event_slot_get(event_pool, idx);
+ if (!slot) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "idx=%d", idx,
+ NULL);
+ return -1;
+ }
+
+ LOCK(&slot->lock);
+ {
+ fd = slot->fd;
+ if (fd == -1) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_STALE_FD_FOUND, "idx=%d",
+ idx, "gen=%d", gen, "events=%d", event->events,
+ "slot->gen=%d", slot->gen, NULL);
+ /* fd got unregistered in another thread */
+ goto pre_unlock;
+ }
- return ret;
-}
+ if (gen != slot->gen) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_GENERATION_MISMATCH,
+ "idx=%d", idx, "gen=%d", gen, "slot->gen=%d", slot->gen,
+ "slot->fd=%d", slot->fd, NULL);
+ /* slot was re-used and therefore is another fd! */
+ goto pre_unlock;
+ }
+ handler = slot->handler;
+ data = slot->data;
-static void *
-event_dispatch_epoll_worker (void *data)
-{
- struct epoll_event event;
- int ret = -1;
- struct event_thread_data *ev_data = data;
- struct event_pool *event_pool;
- int myindex = -1;
- int timetodie = 0;
+ if (slot->in_handler > 0) {
+ /* Another handler is inprogress, skip this one. */
+ handler = NULL;
+ goto pre_unlock;
+ }
- GF_VALIDATE_OR_GOTO ("event", ev_data, out);
+ if (slot->handled_error) {
+ handled_error_previously = _gf_true;
+ } else {
+ slot->handled_error = (event->events & (EPOLLERR | EPOLLHUP));
+ slot->in_handler++;
+ }
+ }
+pre_unlock:
+ UNLOCK(&slot->lock);
- event_pool = ev_data->event_pool;
- myindex = ev_data->event_index;
+ ret = 0;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ if (!handler)
+ goto out;
- gf_msg ("epoll", GF_LOG_INFO, 0, LG_MSG_STARTED_EPOLL_THREAD, "Started"
- " thread with index %d", myindex);
+ if (!handled_error_previously) {
+ handler(fd, idx, gen, data, (event->events & (EPOLLIN | EPOLLPRI)),
+ (event->events & (EPOLLOUT)),
+ (event->events & (EPOLLERR | EPOLLHUP)), 0);
+ }
+out:
+ event_slot_unref(event_pool, slot, idx);
- pthread_mutex_lock (&event_pool->mutex);
- {
- event_pool->activethreadcount++;
- }
- pthread_mutex_unlock (&event_pool->mutex);
+ return ret;
+}
- for (;;) {
+static void *
+event_dispatch_epoll_worker(void *data)
+{
+ struct epoll_event event;
+ int ret = -1;
+ struct event_thread_data *ev_data = data;
+ struct event_pool *event_pool;
+ int myindex = -1;
+ int timetodie = 0, gen = 0;
+ struct list_head poller_death_notify;
+ struct event_slot_epoll *slot = NULL, *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO("event", ev_data, out);
+
+ event_pool = ev_data->event_pool;
+ myindex = ev_data->event_index;
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ gf_smsg("epoll", GF_LOG_INFO, 0, LG_MSG_STARTED_EPOLL_THREAD, "index=%d",
+ myindex - 1, NULL);
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ event_pool->activethreadcount++;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ for (;;) {
+ if (event_pool->eventthreadcount < myindex) {
+ /* ...time to die, thread count was decreased below
+ * this threads index */
+ /* Start with extra safety at this point, reducing
+ * lock conention in normal case when threads are not
+ * reconfigured always */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
if (event_pool->eventthreadcount < myindex) {
- /* ...time to die, thread count was decreased below
- * this threads index */
- /* Start with extra safety at this point, reducing
- * lock conention in normal case when threads are not
- * reconfigured always */
- pthread_mutex_lock (&event_pool->mutex);
- {
- if (event_pool->eventthreadcount <
- myindex) {
- /* if found true in critical section,
- * die */
- event_pool->pollers[myindex - 1] = 0;
- event_pool->activethreadcount--;
- timetodie = 1;
- pthread_cond_broadcast (&event_pool->cond);
- }
- }
- pthread_mutex_unlock (&event_pool->mutex);
- if (timetodie) {
- gf_msg ("epoll", GF_LOG_INFO, 0,
- LG_MSG_EXITED_EPOLL_THREAD, "Exited "
- "thread with index %d", myindex);
- goto out;
- }
+ while (event_pool->poller_death_sliced) {
+ pthread_cond_wait(&event_pool->cond,
+ &event_pool->mutex);
+ }
+
+ INIT_LIST_HEAD(&poller_death_notify);
+ /* if found true in critical section,
+ * die */
+ event_pool->pollers[myindex - 1] = 0;
+ event_pool->activethreadcount--;
+ timetodie = 1;
+ gen = ++event_pool->poller_gen;
+ list_for_each_entry(slot, &event_pool->poller_death,
+ poller_death)
+ {
+ event_slot_ref(slot);
+ }
+
+ list_splice_init(&event_pool->poller_death,
+ &poller_death_notify);
+ event_pool->poller_death_sliced = 1;
+ pthread_cond_broadcast(&event_pool->cond);
+ }
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+ if (timetodie) {
+ list_for_each_entry(slot, &poller_death_notify, poller_death)
+ {
+ slot->handler(slot->fd, 0, gen, slot->data, 0, 0, 0, 1);
}
- ret = epoll_wait (event_pool->fd, &event, 1, -1);
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ list_for_each_entry_safe(slot, tmp, &poller_death_notify,
+ poller_death)
+ {
+ __event_slot_unref(event_pool, slot, slot->idx);
+ }
+
+ list_splice(&poller_death_notify,
+ &event_pool->poller_death);
+ event_pool->poller_death_sliced = 0;
+ pthread_cond_broadcast(&event_pool->cond);
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
- if (ret == 0)
- /* timeout */
- continue;
+ gf_smsg("epoll", GF_LOG_INFO, 0, LG_MSG_EXITED_EPOLL_THREAD,
+ "index=%d", myindex, NULL);
- if (ret == -1 && errno == EINTR)
- /* sys call */
- continue;
+ goto out;
+ }
+ }
+
+ ret = epoll_wait(event_pool->fd, &event, 1, -1);
- ret = event_dispatch_epoll_handler (event_pool, &event);
+ if (ret == 0)
+ /* timeout */
+ continue;
+
+ if (ret == -1 && errno == EINTR)
+ /* sys call */
+ continue;
+
+ ret = event_dispatch_epoll_handler(event_pool, &event);
+ if (ret) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_DISPATCH_HANDLER_FAILED,
+ NULL);
}
+ }
out:
- if (ev_data)
- GF_FREE (ev_data);
- return NULL;
+ if (ev_data)
+ GF_FREE(ev_data);
+ return NULL;
}
/* Attempts to start the # of configured pollers, ensuring at least the first
* is started in a joinable state */
static int
-event_dispatch_epoll (struct event_pool *event_pool)
+event_dispatch_epoll(struct event_pool *event_pool)
{
- int i = 0;
- pthread_t t_id;
- int pollercount = 0;
- int ret = -1;
- struct event_thread_data *ev_data = NULL;
-
- /* Start the configured number of pollers */
- pthread_mutex_lock (&event_pool->mutex);
- {
- pollercount = event_pool->eventthreadcount;
-
- /* Set to MAX if greater */
- if (pollercount > EVENT_MAX_THREADS)
- pollercount = EVENT_MAX_THREADS;
-
- /* Default pollers to 1 in case this is incorrectly set */
- if (pollercount <= 0)
- pollercount = 1;
-
- event_pool->activethreadcount++;
-
- for (i = 0; i < pollercount; i++) {
- ev_data = GF_CALLOC (1, sizeof (*ev_data),
- gf_common_mt_event_pool);
- if (!ev_data) {
- if (i == 0) {
- /* Need to suceed creating 0'th
- * thread, to joinable and wait */
- break;
- } else {
- /* Inability to create other threads
- * are a lesser evil, and ignored */
- continue;
- }
- }
-
- ev_data->event_pool = event_pool;
- ev_data->event_index = i + 1;
-
- ret = pthread_create (&t_id, NULL,
- event_dispatch_epoll_worker,
- ev_data);
- if (!ret) {
- event_pool->pollers[i] = t_id;
-
- /* mark all threads other than one in index 0
- * as detachable. Errors can be ignored, they
- * spend their time as zombies if not detched
- * and the thread counts are decreased */
- if (i != 0)
- pthread_detach (event_pool->pollers[i]);
- } else {
- gf_msg ("epoll", GF_LOG_WARNING, 0,
- LG_MSG_START_EPOLL_THREAD_FAILED,
- "Failed to start thread for index %d",
- i);
- if (i == 0) {
- GF_FREE (ev_data);
- break;
- } else {
- GF_FREE (ev_data);
- continue;
- }
- }
+ int i = 0;
+ pthread_t t_id;
+ int pollercount = 0;
+ int ret = -1;
+ struct event_thread_data *ev_data = NULL;
+
+ /* Start the configured number of pollers */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ pollercount = event_pool->eventthreadcount;
+
+ /* Set to MAX if greater */
+ if (pollercount > EVENT_MAX_THREADS)
+ pollercount = EVENT_MAX_THREADS;
+
+ /* Default pollers to 1 in case this is incorrectly set */
+ if (pollercount <= 0)
+ pollercount = 1;
+
+ event_pool->activethreadcount++;
+
+ for (i = 0; i < pollercount; i++) {
+ ev_data = GF_CALLOC(1, sizeof(*ev_data), gf_common_mt_event_pool);
+ if (!ev_data) {
+ if (i == 0) {
+ /* Need to succeed creating 0'th
+ * thread, to joinable and wait */
+ break;
+ } else {
+ /* Inability to create other threads
+ * are a lesser evil, and ignored */
+ continue;
+ }
+ }
+
+ ev_data->event_pool = event_pool;
+ ev_data->event_index = i + 1;
+
+ ret = gf_thread_create(&t_id, NULL, event_dispatch_epoll_worker,
+ ev_data, "epoll%03hx", i & 0x3ff);
+ if (!ret) {
+ event_pool->pollers[i] = t_id;
+
+ /* mark all threads other than one in index 0
+ * as detachable. Errors can be ignored, they
+ * spend their time as zombies if not detched
+ * and the thread counts are decreased */
+ if (i != 0)
+ pthread_detach(event_pool->pollers[i]);
+ } else {
+ gf_smsg("epoll", GF_LOG_WARNING, 0,
+ LG_MSG_START_EPOLL_THREAD_FAILED, "index=%d", i, NULL);
+ if (i == 0) {
+ GF_FREE(ev_data);
+ break;
+ } else {
+ GF_FREE(ev_data);
+ continue;
}
+ }
}
- pthread_mutex_unlock (&event_pool->mutex);
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
- /* Just wait for the first thread, that is created in a joinable state
- * and will never die, ensuring this function never returns */
- if (event_pool->pollers[0] != 0)
- pthread_join (event_pool->pollers[0], NULL);
+ /* Just wait for the first thread, that is created in a joinable state
+ * and will never die, ensuring this function never returns */
+ if (event_pool->pollers[0] != 0)
+ pthread_join(event_pool->pollers[0], NULL);
- pthread_mutex_lock (&event_pool->mutex);
- {
- event_pool->activethreadcount--;
- }
- pthread_mutex_unlock (&event_pool->mutex);
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ event_pool->activethreadcount--;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
- return ret;
+ return ret;
}
/**
@@ -775,85 +853,80 @@ event_dispatch_epoll (struct event_pool *event_pool)
*/
static int
-event_pool_dispatched_unlocked (struct event_pool *event_pool)
+event_pool_dispatched_unlocked(struct event_pool *event_pool)
{
- return (event_pool->pollers[0] != 0);
-
+ return (event_pool->pollers[0] != 0);
}
-
int
-event_reconfigure_threads_epoll (struct event_pool *event_pool, int value)
+event_reconfigure_threads_epoll(struct event_pool *event_pool, int value)
{
- int i;
- int ret = 0;
- pthread_t t_id;
- int oldthreadcount;
- struct event_thread_data *ev_data = NULL;
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- /* Reconfigure to 0 threads is allowed only in destroy mode */
- if (event_pool->destroy == 1) {
- value = 0;
- } else {
- /* Set to MAX if greater */
- if (value > EVENT_MAX_THREADS)
- value = EVENT_MAX_THREADS;
-
- /* Default pollers to 1 in case this is set incorrectly */
- if (value <= 0)
- value = 1;
- }
+ int i;
+ int ret = 0;
+ pthread_t t_id;
+ int oldthreadcount;
+ struct event_thread_data *ev_data = NULL;
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ /* Reconfigure to 0 threads is allowed only in destroy mode */
+ if (event_pool->destroy == 1) {
+ value = 0;
+ } else {
+ /* Set to MAX if greater */
+ if (value > EVENT_MAX_THREADS)
+ value = EVENT_MAX_THREADS;
+
+ /* Default pollers to 1 in case this is set incorrectly */
+ if (value <= 0)
+ value = 1;
+ }
- oldthreadcount = event_pool->eventthreadcount;
-
- /* Start 'worker' threads as necessary only if event_dispatch()
- * was called before. If event_dispatch() was not called, there
- * will be no epoll 'worker' threads running yet. */
-
- if (event_pool_dispatched_unlocked(event_pool)
- && (oldthreadcount < value)) {
- /* create more poll threads */
- for (i = oldthreadcount; i < value; i++) {
- /* Start a thread if the index at this location
- * is a 0, so that the older thread is confirmed
- * as dead */
- if (event_pool->pollers[i] == 0) {
- ev_data = GF_CALLOC (1,
- sizeof (*ev_data),
- gf_common_mt_event_pool);
- if (!ev_data) {
- continue;
- }
-
- ev_data->event_pool = event_pool;
- ev_data->event_index = i + 1;
-
- ret = pthread_create (&t_id, NULL,
- event_dispatch_epoll_worker,
- ev_data);
- if (ret) {
- gf_msg ("epoll", GF_LOG_WARNING,
- 0,
- LG_MSG_START_EPOLL_THREAD_FAILED,
- "Failed to start thread"
- " for index %d", i);
- GF_FREE (ev_data);
- } else {
- pthread_detach (t_id);
- event_pool->pollers[i] = t_id;
- }
- }
- }
+ oldthreadcount = event_pool->eventthreadcount;
+
+ /* Start 'worker' threads as necessary only if event_dispatch()
+ * was called before. If event_dispatch() was not called, there
+ * will be no epoll 'worker' threads running yet. */
+
+ if (event_pool_dispatched_unlocked(event_pool) &&
+ (oldthreadcount < value)) {
+ /* create more poll threads */
+ for (i = oldthreadcount; i < value; i++) {
+ /* Start a thread if the index at this location
+ * is a 0, so that the older thread is confirmed
+ * as dead */
+ if (event_pool->pollers[i] == 0) {
+ ev_data = GF_CALLOC(1, sizeof(*ev_data),
+ gf_common_mt_event_pool);
+ if (!ev_data) {
+ continue;
+ }
+
+ ev_data->event_pool = event_pool;
+ ev_data->event_index = i + 1;
+
+ ret = gf_thread_create(&t_id, NULL,
+ event_dispatch_epoll_worker, ev_data,
+ "epoll%03hx", i & 0x3ff);
+ if (ret) {
+ gf_smsg("epoll", GF_LOG_WARNING, 0,
+ LG_MSG_START_EPOLL_THREAD_FAILED, "index=%d", i,
+ NULL);
+ GF_FREE(ev_data);
+ } else {
+ pthread_detach(t_id);
+ event_pool->pollers[i] = t_id;
+ }
}
-
- /* if value decreases, threads will terminate, themselves */
- event_pool->eventthreadcount = value;
+ }
}
- pthread_mutex_unlock (&event_pool->mutex);
- return 0;
+ /* if value decreases, threads will terminate, themselves */
+ event_pool->eventthreadcount = value;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ return 0;
}
/* This function is the destructor for the event_pool data structure
@@ -861,43 +934,99 @@ event_reconfigure_threads_epoll (struct event_pool *event_pool, int value)
* else will lead to crashes.
*/
static int
-event_pool_destroy_epoll (struct event_pool *event_pool)
+event_pool_destroy_epoll(struct event_pool *event_pool)
{
- int ret = 0, i = 0, j = 0;
- struct event_slot_epoll *table = NULL;
-
- ret = close (event_pool->fd);
-
- for (i = 0; i < EVENT_EPOLL_TABLES; i++) {
- if (event_pool->ereg[i]) {
- table = event_pool->ereg[i];
- event_pool->ereg[i] = NULL;
- for (j = 0; j < EVENT_EPOLL_SLOTS; j++) {
- LOCK_DESTROY (&table[j].lock);
- }
- GF_FREE (table);
- }
+ int ret = 0, i = 0, j = 0;
+ struct event_slot_epoll *table = NULL;
+
+ ret = sys_close(event_pool->fd);
+
+ for (i = 0; i < EVENT_EPOLL_TABLES; i++) {
+ if (event_pool->ereg[i]) {
+ table = event_pool->ereg[i];
+ event_pool->ereg[i] = NULL;
+ for (j = 0; j < EVENT_EPOLL_SLOTS; j++) {
+ LOCK_DESTROY(&table[j].lock);
+ }
+ GF_FREE(table);
+ }
+ }
+
+ pthread_mutex_destroy(&event_pool->mutex);
+ pthread_cond_destroy(&event_pool->cond);
+
+ GF_FREE(event_pool->evcache);
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+
+ return ret;
+}
+
+static int
+event_handled_epoll(struct event_pool *event_pool, int fd, int idx, int gen)
+{
+ struct event_slot_epoll *slot = NULL;
+ struct epoll_event epoll_event = {
+ 0,
+ };
+ struct event_data *ev_data = (void *)&epoll_event.data;
+ int ret = 0;
+
+ slot = event_slot_get(event_pool, idx);
+ if (!slot) {
+ gf_smsg("epoll", GF_LOG_ERROR, 0, LG_MSG_SLOT_NOT_FOUND, "fd=%d", fd,
+ "idx=%d", idx, NULL);
+ return -1;
+ }
+
+ assert(slot->fd == fd);
+
+ LOCK(&slot->lock);
+ {
+ slot->in_handler--;
+
+ if (gen != slot->gen) {
+ /* event_unregister() happened while we were
+ in handler()
+ */
+ gf_msg_debug("epoll", 0,
+ "generation bumped on idx=%d"
+ " from gen=%d to slot->gen=%d, fd=%d, "
+ "slot->fd=%d",
+ idx, gen, slot->gen, fd, slot->fd);
+ goto unlock;
}
- pthread_mutex_destroy (&event_pool->mutex);
- pthread_cond_destroy (&event_pool->cond);
+ /* This call also picks up the changes made by another
+ thread calling event_select_on_epoll() while this
+ thread was busy in handler()
+ */
+ if (slot->in_handler == 0) {
+ epoll_event.events = slot->events;
+ ev_data->idx = idx;
+ ev_data->gen = gen;
+
+ ret = epoll_ctl(event_pool->fd, EPOLL_CTL_MOD, fd, &epoll_event);
+ }
+ }
+unlock:
+ UNLOCK(&slot->lock);
- GF_FREE (event_pool->evcache);
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
+ event_slot_unref(event_pool, slot, idx);
- return ret;
+ return ret;
}
struct event_ops event_ops_epoll = {
- .new = event_pool_new_epoll,
- .event_register = event_register_epoll,
- .event_select_on = event_select_on_epoll,
- .event_unregister = event_unregister_epoll,
- .event_unregister_close = event_unregister_close_epoll,
- .event_dispatch = event_dispatch_epoll,
- .event_reconfigure_threads = event_reconfigure_threads_epoll,
- .event_pool_destroy = event_pool_destroy_epoll
+ .new = event_pool_new_epoll,
+ .event_register = event_register_epoll,
+ .event_select_on = event_select_on_epoll,
+ .event_unregister = event_unregister_epoll,
+ .event_unregister_close = event_unregister_close_epoll,
+ .event_dispatch = event_dispatch_epoll,
+ .event_reconfigure_threads = event_reconfigure_threads_epoll,
+ .event_pool_destroy = event_pool_destroy_epoll,
+ .event_handled = event_handled_epoll,
};
#endif
diff --git a/libglusterfs/src/event-history.c b/libglusterfs/src/event-history.c
index 95484a4322b..379fed866be 100644
--- a/libglusterfs/src/event-history.c
+++ b/libglusterfs/src/event-history.c
@@ -8,76 +8,75 @@
cases as published by the Free Software Foundation.
*/
-#include "event-history.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/event-history.h"
+#include "glusterfs/libglusterfs-messages.h"
eh_t *
-eh_new (size_t buffer_size, gf_boolean_t use_buffer_once,
- void (*destroy_buffer_data) (void *data))
+eh_new(size_t buffer_size, gf_boolean_t use_buffer_once,
+ void (*destroy_buffer_data)(void *data))
{
- eh_t *history = NULL;
- buffer_t *buffer = NULL;
+ eh_t *history = NULL;
+ buffer_t *buffer = NULL;
- history = GF_CALLOC (1, sizeof (eh_t), gf_common_mt_eh_t);
- if (!history) {
- goto out;
- }
+ history = GF_CALLOC(1, sizeof(eh_t), gf_common_mt_eh_t);
+ if (!history) {
+ goto out;
+ }
- buffer = cb_buffer_new (buffer_size, use_buffer_once,
- destroy_buffer_data);
- if (!buffer) {
- GF_FREE (history);
- history = NULL;
- goto out;
- }
+ buffer = cb_buffer_new(buffer_size, use_buffer_once, destroy_buffer_data);
+ if (!buffer) {
+ GF_FREE(history);
+ history = NULL;
+ goto out;
+ }
- history->buffer = buffer;
+ history->buffer = buffer;
- pthread_mutex_init (&history->lock, NULL);
+ pthread_mutex_init(&history->lock, NULL);
out:
- return history;
+ return history;
}
void
-eh_dump (eh_t *history, void *data,
- int (dump_fn) (circular_buffer_t *buffer, void *data))
+eh_dump(eh_t *history, void *data,
+ int(dump_fn)(circular_buffer_t *buffer, void *data))
{
- if (!history) {
- gf_msg_debug ("event-history", 0, "history is NULL");
- goto out;
- }
+ if (!history) {
+ gf_msg_debug("event-history", 0, "history is NULL");
+ goto out;
+ }
- cb_buffer_dump (history->buffer, data, dump_fn);
+ cb_buffer_dump(history->buffer, data, dump_fn);
out:
- return;
+ return;
}
int
-eh_save_history (eh_t *history, void *data)
+eh_save_history(eh_t *history, void *data)
{
- int ret = -1;
+ int ret = -1;
- ret = cb_add_entry_buffer (history->buffer, data);
+ ret = cb_add_entry_buffer(history->buffer, data);
- return ret;
+ return ret;
}
int
-eh_destroy (eh_t *history)
+eh_destroy(eh_t *history)
{
- if (!history) {
- gf_msg ("event-history", GF_LOG_INFO, 0, LG_MSG_INVALID_ARG,
- "history for the xlator is NULL");
- return -1;
- }
+ if (!history) {
+ gf_msg("event-history", GF_LOG_INFO, 0, LG_MSG_INVALID_ARG,
+ "history for the xlator is NULL");
+ return -1;
+ }
- cb_buffer_destroy (history->buffer);
- history->buffer = NULL;
+ cb_buffer_destroy(history->buffer);
+ history->buffer = NULL;
- pthread_mutex_destroy (&history->lock);
+ pthread_mutex_destroy(&history->lock);
- GF_FREE (history);
+ GF_FREE(history);
- return 0;
+ return 0;
}
diff --git a/libglusterfs/src/event-history.h b/libglusterfs/src/event-history.h
deleted file mode 100644
index de5d47cdfee..00000000000
--- a/libglusterfs/src/event-history.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- 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
-
-#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,
- void (*destroy_data) (void *data));
-
-int
-eh_save_history (eh_t *history, void *string);
-
-int
-eh_destroy (eh_t *history);
-
-#endif /* _EH_H */
diff --git a/libglusterfs/src/event-poll.c b/libglusterfs/src/event-poll.c
index 51c0cf1f4e7..2cba963f096 100644
--- a/libglusterfs/src/event-poll.c
+++ b/libglusterfs/src/event-poll.c
@@ -16,485 +16,465 @@
#include <errno.h>
#include <string.h>
-#include "logging.h"
-#include "event.h"
-#include "mem-pool.h"
-#include "common-utils.h"
-#include "libglusterfs-messages.h"
-
-
+#include "glusterfs/logging.h"
+#include "glusterfs/gf-event.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/libglusterfs-messages.h"
struct event_slot_poll {
- int fd;
- int events;
- void *data;
- event_handler_t handler;
+ int fd;
+ int events;
+ void *data;
+ event_handler_t handler;
};
-
static int
-event_register_poll (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out);
+event_register_poll(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death);
-
-static int
-__flush_fd (int fd, int idx, void *data,
- int poll_in, int poll_out, int poll_err)
+static void
+__flush_fd(int fd, int idx, int gen, void *data, int poll_in, int poll_out,
+ int poll_err, char event_thread_died)
{
- char buf[64];
- int ret = -1;
+ char buf[64];
+ int ret = -1;
- if (!poll_in)
- return ret;
+ if (!poll_in)
+ return;
- do {
- ret = read (fd, buf, 64);
- if (ret == -1 && errno != EAGAIN) {
- gf_msg ("poll", GF_LOG_ERROR, errno,
- LG_MSG_FILE_OP_FAILED, "read on %d returned "
- "error", fd);
- }
- } while (ret == 64);
+ do {
+ ret = sys_read(fd, buf, 64);
+ if (ret == -1 && errno != EAGAIN) {
+ gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_READ_FILE_FAILED,
+ "fd=%d", fd, NULL);
+ }
+ } while (ret == 64);
- return ret;
+ return;
}
-
static int
-__event_getindex (struct event_pool *event_pool, int fd, int idx)
+__event_getindex(struct event_pool *event_pool, int fd, int idx)
{
- int ret = -1;
- int i = 0;
+ int ret = -1;
+ int i = 0;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- /* lookup in used space based on index provided */
- if (idx > -1 && idx < event_pool->used) {
- if (event_pool->reg[idx].fd == fd) {
- ret = idx;
- goto out;
- }
+ /* lookup in used space based on index provided */
+ if (idx > -1 && idx < event_pool->used) {
+ if (event_pool->reg[idx].fd == fd) {
+ ret = idx;
+ goto out;
}
+ }
- /* search in used space, if lookup fails */
- for (i = 0; i < event_pool->used; i++) {
- if (event_pool->reg[i].fd == fd) {
- ret = i;
- break;
- }
+ /* search in used space, if lookup fails */
+ for (i = 0; i < event_pool->used; i++) {
+ if (event_pool->reg[i].fd == fd) {
+ ret = i;
+ break;
}
+ }
out:
- return ret;
+ return ret;
}
-
static struct event_pool *
-event_pool_new_poll (int count, int eventthreadcount)
+event_pool_new_poll(int count, int eventthreadcount)
{
- struct event_pool *event_pool = NULL;
- int ret = -1;
+ struct event_pool *event_pool = NULL;
+ int ret = -1;
- event_pool = GF_CALLOC (1, sizeof (*event_pool),
- gf_common_mt_event_pool);
+ event_pool = GF_CALLOC(1, sizeof(*event_pool), gf_common_mt_event_pool);
- if (!event_pool)
- return NULL;
+ if (!event_pool)
+ return NULL;
- event_pool->count = count;
- event_pool->reg = GF_CALLOC (event_pool->count,
- sizeof (*event_pool->reg),
- gf_common_mt_reg);
+ event_pool->count = count;
+ event_pool->reg = GF_CALLOC(event_pool->count, sizeof(*event_pool->reg),
+ gf_common_mt_reg);
- if (!event_pool->reg) {
- GF_FREE (event_pool);
- return NULL;
- }
+ if (!event_pool->reg) {
+ GF_FREE(event_pool);
+ return NULL;
+ }
- pthread_mutex_init (&event_pool->mutex, NULL);
+ pthread_mutex_init(&event_pool->mutex, NULL);
- ret = pipe (event_pool->breaker);
+ ret = pipe(event_pool->breaker);
- if (ret == -1) {
- gf_msg ("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED,
- "pipe creation failed");
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- return NULL;
- }
+ if (ret == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_PIPE_CREATE_FAILED, NULL);
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ return NULL;
+ }
- ret = fcntl (event_pool->breaker[0], F_SETFL, O_NONBLOCK);
- if (ret == -1) {
- gf_msg ("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED,
- "could not set pipe to non blocking mode");
- close (event_pool->breaker[0]);
- close (event_pool->breaker[1]);
- event_pool->breaker[0] = event_pool->breaker[1] = -1;
-
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- return NULL;
- }
+ ret = fcntl(event_pool->breaker[0], F_SETFL, O_NONBLOCK);
+ if (ret == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED, NULL);
+ sys_close(event_pool->breaker[0]);
+ sys_close(event_pool->breaker[1]);
+ event_pool->breaker[0] = event_pool->breaker[1] = -1;
- ret = fcntl (event_pool->breaker[1], F_SETFL, O_NONBLOCK);
- if (ret == -1) {
- gf_msg ("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED,
- "could not set pipe to non blocking mode");
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ return NULL;
+ }
- close (event_pool->breaker[0]);
- close (event_pool->breaker[1]);
- event_pool->breaker[0] = event_pool->breaker[1] = -1;
+ ret = fcntl(event_pool->breaker[1], F_SETFL, O_NONBLOCK);
+ if (ret == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, errno, LG_MSG_SET_PIPE_FAILED, NULL);
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- return NULL;
- }
+ sys_close(event_pool->breaker[0]);
+ sys_close(event_pool->breaker[1]);
+ event_pool->breaker[0] = event_pool->breaker[1] = -1;
- ret = event_register_poll (event_pool, event_pool->breaker[0],
- __flush_fd, NULL, 1, 0);
- if (ret == -1) {
- gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_REGISTER_PIPE_FAILED,
- "could not register pipe fd with poll event loop");
- close (event_pool->breaker[0]);
- close (event_pool->breaker[1]);
- event_pool->breaker[0] = event_pool->breaker[1] = -1;
-
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
- return NULL;
- }
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ return NULL;
+ }
+
+ ret = event_register_poll(event_pool, event_pool->breaker[0], __flush_fd,
+ NULL, 1, 0, 0);
+ if (ret == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_REGISTER_PIPE_FAILED, NULL);
+ sys_close(event_pool->breaker[0]);
+ sys_close(event_pool->breaker[1]);
+ event_pool->breaker[0] = event_pool->breaker[1] = -1;
- if (eventthreadcount > 1) {
- gf_msg ("poll", GF_LOG_INFO, 0,
- LG_MSG_POLL_IGNORE_MULTIPLE_THREADS, "Currently poll "
- "does not use multiple event processing threads, "
- "thread count (%d) ignored", eventthreadcount);
- }
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
+ return NULL;
+ }
- return event_pool;
-}
+ if (eventthreadcount > 1) {
+ gf_smsg("poll", GF_LOG_INFO, 0, LG_MSG_POLL_IGNORE_MULTIPLE_THREADS,
+ "count=%d", eventthreadcount, NULL);
+ }
+ /* although, eventhreadcount for poll implementation is always
+ * going to be 1, eventthreadcount needs to be set to 1 so that
+ * rpcsvc_request_handler() thread scaling works flawlessly in
+ * both epoll and poll models
+ */
+ event_pool->eventthreadcount = 1;
+
+ return event_pool;
+}
static int
-event_register_poll (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out)
+event_register_poll(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death)
{
- int idx = -1;
+ int idx = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- pthread_mutex_lock (&event_pool->mutex);
- {
- if (event_pool->count == event_pool->used)
- {
- event_pool->count += 256;
-
- event_pool->reg = GF_REALLOC (event_pool->reg,
- event_pool->count *
- sizeof (*event_pool->reg));
- if (!event_pool->reg)
- goto unlock;
- }
-
- idx = event_pool->used++;
-
- event_pool->reg[idx].fd = fd;
- event_pool->reg[idx].events = POLLPRI;
- event_pool->reg[idx].handler = handler;
- event_pool->reg[idx].data = data;
-
- switch (poll_in) {
- case 1:
- event_pool->reg[idx].events |= POLLIN;
- break;
- case 0:
- event_pool->reg[idx].events &= ~POLLIN;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_msg ("poll", GF_LOG_ERROR, 0,
- LG_MSG_INVALID_POLL_IN,
- "invalid poll_in value %d", poll_in);
- break;
- }
-
- switch (poll_out) {
- case 1:
- event_pool->reg[idx].events |= POLLOUT;
- break;
- case 0:
- event_pool->reg[idx].events &= ~POLLOUT;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- gf_msg ("poll", GF_LOG_ERROR, 0,
- LG_MSG_INVALID_POLL_OUT,
- "invalid poll_out value %d", poll_out);
- break;
- }
-
- event_pool->changed = 1;
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ if (event_pool->count == event_pool->used) {
+ event_pool->count += 256;
+
+ event_pool->reg = GF_REALLOC(
+ event_pool->reg, event_pool->count * sizeof(*event_pool->reg));
+ if (!event_pool->reg)
+ goto unlock;
+ }
+
+ idx = event_pool->used++;
+
+ event_pool->reg[idx].fd = fd;
+ event_pool->reg[idx].events = POLLPRI;
+ event_pool->reg[idx].handler = handler;
+ event_pool->reg[idx].data = data;
+
+ switch (poll_in) {
+ case 1:
+ event_pool->reg[idx].events |= POLLIN;
+ break;
+ case 0:
+ event_pool->reg[idx].events &= ~POLLIN;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_IN,
+ "value=%d", poll_in, NULL);
+ break;
+ }
+ switch (poll_out) {
+ case 1:
+ event_pool->reg[idx].events |= POLLOUT;
+ break;
+ case 0:
+ event_pool->reg[idx].events &= ~POLLOUT;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INVALID_POLL_OUT,
+ "value=%d", poll_out, NULL);
+ break;
}
+
+ event_pool->changed = 1;
+ }
unlock:
- pthread_mutex_unlock (&event_pool->mutex);
+ pthread_mutex_unlock(&event_pool->mutex);
out:
- return idx;
+ return idx;
}
-
static int
-event_unregister_poll (struct event_pool *event_pool, int fd, int idx_hint)
+event_unregister_poll(struct event_pool *event_pool, int fd, int idx_hint)
{
- int idx = -1;
+ int idx = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_getindex (event_pool, fd, idx_hint);
-
- if (idx == -1) {
- gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND,
- "index not found for fd=%d (idx_hint=%d)",
- fd, idx_hint);
- errno = ENOENT;
- goto unlock;
- }
-
- event_pool->reg[idx] = event_pool->reg[--event_pool->used];
- event_pool->changed = 1;
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ idx = __event_getindex(event_pool, fd, idx_hint);
+
+ if (idx == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d",
+ fd, "idx_hint=%d", idx_hint, NULL);
+ errno = ENOENT;
+ goto unlock;
}
+
+ event_pool->reg[idx] = event_pool->reg[--event_pool->used];
+ event_pool->changed = 1;
+ }
unlock:
- pthread_mutex_unlock (&event_pool->mutex);
+ pthread_mutex_unlock(&event_pool->mutex);
out:
- return idx;
+ return idx;
}
-
static int
-event_unregister_close_poll (struct event_pool *event_pool, int fd,
- int idx_hint)
+event_unregister_close_poll(struct event_pool *event_pool, int fd, int idx_hint)
{
- int ret = -1;
+ int ret = -1;
- ret = event_unregister_poll (event_pool, fd, idx_hint);
+ ret = event_unregister_poll(event_pool, fd, idx_hint);
- close (fd);
+ sys_close(fd);
- return ret;
+ return ret;
}
-
static int
-event_select_on_poll (struct event_pool *event_pool, int fd, int idx_hint,
- int poll_in, int poll_out)
+event_select_on_poll(struct event_pool *event_pool, int fd, int idx_hint,
+ int poll_in, int poll_out)
{
- int idx = -1;
+ int idx = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_getindex (event_pool, fd, idx_hint);
-
- if (idx == -1) {
- gf_msg ("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND,
- "index not found for fd=%d (idx_hint=%d)",
- fd, idx_hint);
- errno = ENOENT;
- goto unlock;
- }
-
- switch (poll_in) {
- case 1:
- event_pool->reg[idx].events |= POLLIN;
- break;
- case 0:
- event_pool->reg[idx].events &= ~POLLIN;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- /* TODO: log error */
- break;
- }
-
- switch (poll_out) {
- case 1:
- event_pool->reg[idx].events |= POLLOUT;
- break;
- case 0:
- event_pool->reg[idx].events &= ~POLLOUT;
- break;
- case -1:
- /* do nothing */
- break;
- default:
- /* TODO: log error */
- break;
- }
-
- if (poll_in + poll_out > -2)
- event_pool->changed = 1;
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ idx = __event_getindex(event_pool, fd, idx_hint);
+
+ if (idx == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d",
+ fd, "idx_hint=%d", idx_hint, NULL);
+ errno = ENOENT;
+ goto unlock;
}
+
+ switch (poll_in) {
+ case 1:
+ event_pool->reg[idx].events |= POLLIN;
+ break;
+ case 0:
+ event_pool->reg[idx].events &= ~POLLIN;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ /* TODO: log error */
+ break;
+ }
+
+ switch (poll_out) {
+ case 1:
+ event_pool->reg[idx].events |= POLLOUT;
+ break;
+ case 0:
+ event_pool->reg[idx].events &= ~POLLOUT;
+ break;
+ case -1:
+ /* do nothing */
+ break;
+ default:
+ /* TODO: log error */
+ break;
+ }
+
+ if (poll_in + poll_out > -2)
+ event_pool->changed = 1;
+ }
unlock:
- pthread_mutex_unlock (&event_pool->mutex);
+ pthread_mutex_unlock(&event_pool->mutex);
out:
- return idx;
+ return idx;
}
-
static int
-event_dispatch_poll_handler (struct event_pool *event_pool,
- struct pollfd *ufds, int i)
+event_dispatch_poll_handler(struct event_pool *event_pool, struct pollfd *ufds,
+ int i)
{
- event_handler_t handler = NULL;
- void *data = NULL;
- int idx = -1;
- int ret = 0;
-
- handler = NULL;
- data = NULL;
-
- pthread_mutex_lock (&event_pool->mutex);
- {
- idx = __event_getindex (event_pool, ufds[i].fd, i);
-
- if (idx == -1) {
- gf_msg ("poll", GF_LOG_ERROR, 0,
- LG_MSG_INDEX_NOT_FOUND, "index not found for "
- "fd=%d (idx_hint=%d)", ufds[i].fd, i);
- goto unlock;
- }
-
- handler = event_pool->reg[idx].handler;
- data = event_pool->reg[idx].data;
+ event_handler_t handler = NULL;
+ void *data = NULL;
+ int idx = -1;
+ int ret = 0;
+
+ handler = NULL;
+ data = NULL;
+
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ idx = __event_getindex(event_pool, ufds[i].fd, i);
+
+ if (idx == -1) {
+ gf_smsg("poll", GF_LOG_ERROR, 0, LG_MSG_INDEX_NOT_FOUND, "fd=%d",
+ ufds[i].fd, "idx_hint=%d", i, NULL);
+ goto unlock;
}
+
+ handler = event_pool->reg[idx].handler;
+ data = event_pool->reg[idx].data;
+ }
unlock:
- pthread_mutex_unlock (&event_pool->mutex);
+ pthread_mutex_unlock(&event_pool->mutex);
- if (handler)
- ret = handler (ufds[i].fd, idx, data,
- (ufds[i].revents & (POLLIN|POLLPRI)),
- (ufds[i].revents & (POLLOUT)),
- (ufds[i].revents & (POLLERR|POLLHUP|POLLNVAL)));
+ if (handler)
+ handler(ufds[i].fd, idx, 0, data,
+ (ufds[i].revents & (POLLIN | POLLPRI)),
+ (ufds[i].revents & (POLLOUT)),
+ (ufds[i].revents & (POLLERR | POLLHUP | POLLNVAL)), 0);
- return ret;
+ return ret;
}
-
static int
-event_dispatch_poll_resize (struct event_pool *event_pool,
- struct pollfd *ufds, int size)
+event_dispatch_poll_resize(struct event_pool *event_pool, struct pollfd *ufds,
+ int size)
{
- int i = 0;
+ int i = 0;
- pthread_mutex_lock (&event_pool->mutex);
- {
- if (event_pool->changed == 0) {
- goto unlock;
- }
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ if (event_pool->changed == 0) {
+ goto unlock;
+ }
- if (event_pool->used > event_pool->evcache_size) {
- GF_FREE (event_pool->evcache);
+ if (event_pool->used > event_pool->evcache_size) {
+ GF_FREE(event_pool->evcache);
- event_pool->evcache = ufds = NULL;
+ event_pool->evcache = ufds = NULL;
- event_pool->evcache_size = event_pool->used;
+ event_pool->evcache_size = event_pool->used;
- ufds = GF_CALLOC (sizeof (struct pollfd),
- event_pool->evcache_size,
- gf_common_mt_pollfd);
- if (!ufds)
- goto unlock;
- event_pool->evcache = ufds;
- }
+ ufds = GF_CALLOC(sizeof(struct pollfd), event_pool->evcache_size,
+ gf_common_mt_pollfd);
+ if (!ufds)
+ goto unlock;
+ event_pool->evcache = ufds;
+ }
- for (i = 0; i < event_pool->used; i++) {
- ufds[i].fd = event_pool->reg[i].fd;
- ufds[i].events = event_pool->reg[i].events;
- ufds[i].revents = 0;
- }
+ if (ufds == NULL) {
+ goto unlock;
+ }
- size = i;
+ for (i = 0; i < event_pool->used; i++) {
+ ufds[i].fd = event_pool->reg[i].fd;
+ ufds[i].events = event_pool->reg[i].events;
+ ufds[i].revents = 0;
}
+
+ size = i;
+ }
unlock:
- pthread_mutex_unlock (&event_pool->mutex);
+ pthread_mutex_unlock(&event_pool->mutex);
- return size;
+ return size;
}
-
static int
-event_dispatch_poll (struct event_pool *event_pool)
+event_dispatch_poll(struct event_pool *event_pool)
{
- struct pollfd *ufds = NULL;
- int size = 0;
- int i = 0;
- int ret = -1;
+ struct pollfd *ufds = NULL;
+ int size = 0;
+ int i = 0;
+ int ret = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- pthread_mutex_lock (&event_pool->mutex);
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ event_pool->activethreadcount = 1;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ while (1) {
+ pthread_mutex_lock(&event_pool->mutex);
{
- event_pool->activethreadcount = 1;
+ if (event_pool->destroy == 1) {
+ event_pool->activethreadcount = 0;
+ pthread_cond_broadcast(&event_pool->cond);
+ pthread_mutex_unlock(&event_pool->mutex);
+ return 0;
+ }
}
- pthread_mutex_unlock (&event_pool->mutex);
-
- while (1) {
- pthread_mutex_lock (&event_pool->mutex);
- {
- if (event_pool->destroy == 1) {
- event_pool->activethreadcount = 0;
- pthread_cond_broadcast (&event_pool->cond);
- pthread_mutex_unlock (&event_pool->mutex);
- return 0;
- }
- }
- pthread_mutex_unlock (&event_pool->mutex);
-
- size = event_dispatch_poll_resize (event_pool, ufds, size);
- ufds = event_pool->evcache;
-
- ret = poll (ufds, size, 1);
-
- if (ret == 0)
- /* timeout */
- continue;
-
- if (ret == -1 && errno == EINTR)
- /* sys call */
- continue;
-
- for (i = 0; i < size; i++) {
- if (!ufds[i].revents)
- continue;
-
- event_dispatch_poll_handler (event_pool, ufds, i);
- }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ size = event_dispatch_poll_resize(event_pool, ufds, size);
+ ufds = event_pool->evcache;
+
+ ret = poll(ufds, size, 1);
+
+ if (ret == 0)
+ /* timeout */
+ continue;
+
+ if (ret == -1 && errno == EINTR)
+ /* sys call */
+ continue;
+
+ for (i = 0; i < size; i++) {
+ if (!ufds[i].revents)
+ continue;
+
+ event_dispatch_poll_handler(event_pool, ufds, i);
}
+ }
out:
- return -1;
+ return -1;
}
int
-event_reconfigure_threads_poll (struct event_pool *event_pool, int value)
+event_reconfigure_threads_poll(struct event_pool *event_pool, int value)
{
- /* No-op for poll */
+ /* No-op for poll */
- return 0;
+ return 0;
}
/* This function is the destructor for the event_pool data structure
@@ -502,33 +482,32 @@ event_reconfigure_threads_poll (struct event_pool *event_pool, int value)
* else will lead to crashes.
*/
static int
-event_pool_destroy_poll (struct event_pool *event_pool)
+event_pool_destroy_poll(struct event_pool *event_pool)
{
- int ret = 0;
+ int ret = 0;
- ret = close (event_pool->breaker[0]);
- if (ret)
- return ret;
+ ret = sys_close(event_pool->breaker[0]);
+ if (ret)
+ return ret;
- ret = close (event_pool->breaker[1]);
- if (ret)
- return ret;
+ ret = sys_close(event_pool->breaker[1]);
+ if (ret)
+ return ret;
- event_pool->breaker[0] = event_pool->breaker[1] = -1;
+ event_pool->breaker[0] = event_pool->breaker[1] = -1;
- GF_FREE (event_pool->reg);
- GF_FREE (event_pool);
+ GF_FREE(event_pool->reg);
+ GF_FREE(event_pool);
- return ret;
+ return ret;
}
struct event_ops event_ops_poll = {
- .new = event_pool_new_poll,
- .event_register = event_register_poll,
- .event_select_on = event_select_on_poll,
- .event_unregister = event_unregister_poll,
- .event_unregister_close = event_unregister_close_poll,
- .event_dispatch = event_dispatch_poll,
- .event_reconfigure_threads = event_reconfigure_threads_poll,
- .event_pool_destroy = event_pool_destroy_poll
-};
+ .new = event_pool_new_poll,
+ .event_register = event_register_poll,
+ .event_select_on = event_select_on_poll,
+ .event_unregister = event_unregister_poll,
+ .event_unregister_close = event_unregister_close_poll,
+ .event_dispatch = event_dispatch_poll,
+ .event_reconfigure_threads = event_reconfigure_threads_poll,
+ .event_pool_destroy = event_pool_destroy_poll};
diff --git a/libglusterfs/src/event.c b/libglusterfs/src/event.c
index aeef67107f5..402c253ca25 100644
--- a/libglusterfs/src/event.c
+++ b/libglusterfs/src/event.c
@@ -16,261 +16,290 @@
#include <errno.h>
#include <string.h>
-#include "logging.h"
-#include "event.h"
-#include "mem-pool.h"
-#include "common-utils.h"
-#include "libglusterfs-messages.h"
-
-
+#include "glusterfs/gf-event.h"
+#include "glusterfs/timespec.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/libglusterfs-messages.h"
+#include "glusterfs/syscall.h"
struct event_pool *
-event_pool_new (int count, int eventthreadcount)
+gf_event_pool_new(int count, int eventthreadcount)
{
- struct event_pool *event_pool = NULL;
- extern struct event_ops event_ops_poll;
+ struct event_pool *event_pool = NULL;
+ extern struct event_ops event_ops_poll;
#ifdef HAVE_SYS_EPOLL_H
- extern struct event_ops event_ops_epoll;
+ extern struct event_ops event_ops_epoll;
- event_pool = event_ops_epoll.new (count, eventthreadcount);
+ event_pool = event_ops_epoll.new(count, eventthreadcount);
- if (event_pool) {
- event_pool->ops = &event_ops_epoll;
- } else {
- gf_msg ("event", GF_LOG_WARNING, 0, LG_MSG_FALLBACK_TO_POLL,
- "falling back to poll based event handling");
- }
+ if (event_pool) {
+ event_pool->ops = &event_ops_epoll;
+ } else {
+ gf_msg("event", GF_LOG_WARNING, 0, LG_MSG_FALLBACK_TO_POLL,
+ "falling back to poll based event handling");
+ }
#endif
- if (!event_pool) {
- event_pool = event_ops_poll.new (count, eventthreadcount);
+ if (!event_pool) {
+ event_pool = event_ops_poll.new(count, eventthreadcount);
- if (event_pool)
- event_pool->ops = &event_ops_poll;
- }
+ if (event_pool)
+ event_pool->ops = &event_ops_poll;
+ }
- return event_pool;
+ return event_pool;
}
-
int
-event_register (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out)
+gf_event_register(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death)
{
- int ret = -1;
+ int ret = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- ret = event_pool->ops->event_register (event_pool, fd, handler, data,
- poll_in, poll_out);
+ ret = event_pool->ops->event_register(
+ event_pool, fd, handler, data, poll_in, poll_out, notify_poller_death);
out:
- return ret;
+ return ret;
}
-
int
-event_unregister (struct event_pool *event_pool, int fd, int idx)
+gf_event_unregister(struct event_pool *event_pool, int fd, int idx)
{
- int ret = -1;
+ int ret = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- ret = event_pool->ops->event_unregister (event_pool, fd, idx);
+ ret = event_pool->ops->event_unregister(event_pool, fd, idx);
out:
- return ret;
+ return ret;
}
-
int
-event_unregister_close (struct event_pool *event_pool, int fd, int idx)
+gf_event_unregister_close(struct event_pool *event_pool, int fd, int idx)
{
- int ret = -1;
+ int ret = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- ret = event_pool->ops->event_unregister_close (event_pool, fd, idx);
+ ret = event_pool->ops->event_unregister_close(event_pool, fd, idx);
out:
- return ret;
+ return ret;
}
-
int
-event_select_on (struct event_pool *event_pool, int fd, int idx_hint,
- int poll_in, int poll_out)
+gf_event_select_on(struct event_pool *event_pool, int fd, int idx_hint,
+ int poll_in, int poll_out)
{
- int ret = -1;
+ int ret = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- ret = event_pool->ops->event_select_on (event_pool, fd, idx_hint,
- poll_in, poll_out);
+ ret = event_pool->ops->event_select_on(event_pool, fd, idx_hint, poll_in,
+ poll_out);
out:
- return ret;
+ return ret;
}
-
int
-event_dispatch (struct event_pool *event_pool)
+gf_event_dispatch(struct event_pool *event_pool)
{
- int ret = -1;
+ int ret = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- ret = event_pool->ops->event_dispatch (event_pool);
- if (ret)
- goto out;
+ ret = event_pool->ops->event_dispatch(event_pool);
+ if (ret)
+ goto out;
out:
- return ret;
+ return ret;
}
int
-event_reconfigure_threads (struct event_pool *event_pool, int value)
+gf_event_reconfigure_threads(struct event_pool *event_pool, int value)
{
- int ret = -1;
+ int ret = -1;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- /* call event refresh function */
- ret = event_pool->ops->event_reconfigure_threads (event_pool,
- value);
+ /* call event refresh function */
+ ret = event_pool->ops->event_reconfigure_threads(event_pool, value);
out:
- return ret;
+ return ret;
}
int
-event_pool_destroy (struct event_pool *event_pool)
+gf_event_pool_destroy(struct event_pool *event_pool)
{
- int ret = -1;
- int destroy = 0, activethreadcount = 0;
+ int ret = -1;
+ int destroy = 0, activethreadcount = 0;
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
- pthread_mutex_lock (&event_pool->mutex);
- {
- destroy = event_pool->destroy;
- activethreadcount = event_pool->activethreadcount;
- }
- pthread_mutex_unlock (&event_pool->mutex);
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ destroy = event_pool->destroy;
+ activethreadcount = event_pool->activethreadcount;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
- if (!destroy || (activethreadcount > 0))
- goto out;
+ if (!destroy || (activethreadcount > 0)) {
+ goto out;
+ }
- ret = event_pool->ops->event_pool_destroy (event_pool);
+ ret = event_pool->ops->event_pool_destroy(event_pool);
out:
- return ret;
+ return ret;
}
-int
-poller_destroy_handler (int fd, int idx, void *data,
- int poll_out, int poll_in, int poll_err)
+void
+poller_destroy_handler(int fd, int idx, int gen, void *data, int poll_out,
+ int poll_in, int poll_err, char event_thread_exit)
{
- int readfd = -1;
- char buf = '\0';
+ struct event_destroy_data *destroy = NULL;
+ int readfd = -1;
+ char buf = '\0';
- readfd = *(int *)data;
- if (readfd < 0)
- return -1;
+ destroy = data;
+ readfd = destroy->readfd;
+ if (readfd < 0) {
+ goto out;
+ }
- while (read (readfd, &buf, 1) > 0) {
- }
- return 0;
+ while (sys_read(readfd, &buf, 1) > 0) {
+ }
+
+out:
+ gf_event_handled(destroy->pool, fd, idx, gen);
+
+ return;
}
/* This function destroys all the poller threads.
- * Note: to be called before event_pool_destroy is called.
+ * Note: to be called before gf_event_pool_destroy is called.
* The order in which cleaning is performed:
* - Register a pipe fd(this is for waking threads in poll()/epoll_wait())
- * - Set the destroy mode, which this no new event registration will succede
- * - Reconfigure the thread count to 0(this will succede only in destroy mode)
+ * - Set the destroy mode, which this no new event registration will succeed
+ * - Reconfigure the thread count to 0(this will succeed only in destroy mode)
* - Wake up all the threads in poll() or epoll_wait(), so that they can
* destroy themselves.
* - Wait for the thread to join(which will happen only after all the other
* threads are destroyed)
*/
int
-event_dispatch_destroy (struct event_pool *event_pool)
+gf_event_dispatch_destroy(struct event_pool *event_pool)
{
- int ret = -1;
- int fd[2] = {-1};
- int idx = -1;
- int flags = 0;
- struct timespec sleep_till = {0, };
-
- GF_VALIDATE_OR_GOTO ("event", event_pool, out);
-
- ret = pipe (fd);
- if (ret < 0)
- goto out;
-
- /* Make the read end of the pipe nonblocking */
- flags = fcntl(fd[0], F_GETFL);
- flags |= O_NONBLOCK;
- ret = fcntl(fd[0], F_SETFL, flags);
- if (ret < 0)
- goto out;
-
- /* Make the write end of the pipe nonblocking */
- flags = fcntl(fd[1], F_GETFL);
- flags |= O_NONBLOCK;
- fcntl(fd[1], F_SETFL, flags);
- if (ret < 0)
- goto out;
-
- /* From the main thread register an event on the pipe fd[0],
+ int ret = -1, threadcount = 0;
+ int fd[2] = {-1};
+ int idx = -1;
+ int flags = 0;
+ struct timespec sleep_till = {
+ 0,
+ };
+ struct event_destroy_data data = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO("event", event_pool, out);
+
+ ret = pipe(fd);
+ if (ret < 0)
+ goto out;
+
+ /* Make the read end of the pipe nonblocking */
+ flags = fcntl(fd[0], F_GETFL);
+ flags |= O_NONBLOCK;
+ ret = fcntl(fd[0], F_SETFL, flags);
+ if (ret < 0)
+ goto out;
+
+ /* Make the write end of the pipe nonblocking */
+ flags = fcntl(fd[1], F_GETFL);
+ flags |= O_NONBLOCK;
+ ret = fcntl(fd[1], F_SETFL, flags);
+ if (ret < 0)
+ goto out;
+
+ data.pool = event_pool;
+ data.readfd = fd[1];
+
+ /* From the main thread register an event on the pipe fd[0],
+ */
+ idx = gf_event_register(event_pool, fd[0], poller_destroy_handler, &data, 1,
+ 0, 0);
+ if (idx < 0)
+ goto out;
+
+ /* Enter the destroy mode first, set this before reconfiguring to 0
+ * threads, to prevent further reconfigure to thread count > 0.
+ */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ threadcount = event_pool->eventthreadcount;
+ event_pool->destroy = 1;
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
+
+ ret = gf_event_reconfigure_threads(event_pool, 0);
+ if (ret < 0)
+ goto out;
+
+ /* Write something onto the write end of the pipe(fd[1]) so that
+ * poll wakes up and calls the handler, poller_destroy_handler()
+ */
+ pthread_mutex_lock(&event_pool->mutex);
+ {
+ /* Write to pipe(fd[1]) and then wait for 1 second or until
+ * a poller thread that is dying, broadcasts. Make sure we
+ * do not loop forever by limiting to 10 retries
*/
- idx = event_register (event_pool, fd[0], poller_destroy_handler,
- &fd[1], 1, 0);
- if (idx < 0)
- goto out;
-
- /* Enter the destroy mode first, set this before reconfiguring to 0
- * threads, to prevent further reconfigure to thread count > 0.
- */
- pthread_mutex_lock (&event_pool->mutex);
- {
- event_pool->destroy = 1;
+ int retry = 0;
+
+ while (event_pool->activethreadcount > 0 &&
+ (retry++ < (threadcount + 10))) {
+ if (sys_write(fd[1], "dummy", 6) == -1) {
+ break;
+ }
+ timespec_now_realtime(&sleep_till);
+ sleep_till.tv_sec += 1;
+ ret = pthread_cond_timedwait(&event_pool->cond, &event_pool->mutex,
+ &sleep_till);
+ if (ret) {
+ gf_msg_debug("event", 0,
+ "thread cond-timedwait failed "
+ "active-thread-count: %d, "
+ "retry: %d",
+ event_pool->activethreadcount, retry);
+ }
}
- pthread_mutex_unlock (&event_pool->mutex);
+ }
+ pthread_mutex_unlock(&event_pool->mutex);
- ret = event_reconfigure_threads (event_pool, 0);
- if (ret < 0)
- goto out;
+ ret = gf_event_unregister(event_pool, fd[0], idx);
- /* Write something onto the write end of the pipe(fd[1]) so that
- * poll wakes up and calls the handler, poller_destroy_handler()
- */
- pthread_mutex_lock (&event_pool->mutex);
- {
- /* Write to pipe(fd[1]) and then wait for 1 second or until
- * a poller thread that is dying, broadcasts. Make sure we
- * do not loop forever by limiting to 10 retries
- */
- int retry = 0;
-
- while (event_pool->activethreadcount > 0 && retry++ < 10) {
- if (write (fd[1], "dummy", 6) == -1)
- break;
- sleep_till.tv_sec = time (NULL) + 1;
- ret = pthread_cond_timedwait (&event_pool->cond,
- &event_pool->mutex,
- &sleep_till);
- }
- }
- pthread_mutex_unlock (&event_pool->mutex);
+out:
+ if (fd[0] != -1)
+ sys_close(fd[0]);
+ if (fd[1] != -1)
+ sys_close(fd[1]);
+
+ return ret;
+}
- ret = event_unregister (event_pool, fd[0], idx);
+int
+gf_event_handled(struct event_pool *event_pool, int fd, int idx, int gen)
+{
+ int ret = 0;
- out:
- if (fd[0] != -1)
- close (fd[0]);
- if (fd[1] != -1)
- close (fd[1]);
+ if (event_pool->ops->event_handled)
+ ret = event_pool->ops->event_handled(event_pool, fd, idx, gen);
- return ret;
+ return ret;
}
diff --git a/libglusterfs/src/event.h b/libglusterfs/src/event.h
deleted file mode 100644
index b01ef24bb8e..00000000000
--- a/libglusterfs/src/event.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- 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_
-#define _EVENT_H_
-
-#include <pthread.h>
-
-struct event_pool;
-struct event_ops;
-struct event_slot_poll;
-struct event_slot_epoll;
-struct event_data {
- int idx;
- int gen;
-} __attribute__ ((__packed__, __may_alias__));
-
-
-typedef int (*event_handler_t) (int fd, int idx, void *data,
- int poll_in, int poll_out, int poll_err);
-
-#define EVENT_EPOLL_TABLES 1024
-#define EVENT_EPOLL_SLOTS 1024
-#define EVENT_MAX_THREADS 32
-
-struct event_pool {
- struct event_ops *ops;
-
- int fd;
- int breaker[2];
-
- int count;
- struct event_slot_poll *reg;
- struct event_slot_epoll *ereg[EVENT_EPOLL_TABLES];
- int slots_used[EVENT_EPOLL_TABLES];
-
- int used;
- int changed;
-
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-
- void *evcache;
- int evcache_size;
-
- /* NOTE: Currently used only when event processing is done using
- * epoll. */
- int eventthreadcount; /* number of event threads to execute. */
- pthread_t pollers[EVENT_MAX_THREADS]; /* poller thread_id store,
- * and live status */
- int destroy;
- int activethreadcount;
-};
-
-struct event_ops {
- struct event_pool * (*new) (int count, int eventthreadcount);
-
- int (*event_register) (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out);
-
- int (*event_select_on) (struct event_pool *event_pool, int fd, int idx,
- int poll_in, int poll_out);
-
- int (*event_unregister) (struct event_pool *event_pool, int fd, int idx);
-
- int (*event_unregister_close) (struct event_pool *event_pool, int fd,
- int idx);
-
- int (*event_dispatch) (struct event_pool *event_pool);
-
- int (*event_reconfigure_threads) (struct event_pool *event_pool,
- int newcount);
- int (*event_pool_destroy) (struct event_pool *event_pool);
-};
-
-struct event_pool *event_pool_new (int count, int eventthreadcount);
-int event_select_on (struct event_pool *event_pool, int fd, int idx,
- int poll_in, int poll_out);
-int event_register (struct event_pool *event_pool, int fd,
- event_handler_t handler,
- void *data, int poll_in, int poll_out);
-int event_unregister (struct event_pool *event_pool, int fd, int idx);
-int event_unregister_close (struct event_pool *event_pool, int fd, int idx);
-int event_dispatch (struct event_pool *event_pool);
-int event_reconfigure_threads (struct event_pool *event_pool, int value);
-int event_pool_destroy (struct event_pool *event_pool);
-int event_dispatch_destroy (struct event_pool *event_pool);
-#endif /* _EVENT_H_ */
diff --git a/libglusterfs/src/events.c b/libglusterfs/src/events.c
new file mode 100644
index 00000000000..33157549897
--- /dev/null
+++ b/libglusterfs/src/events.c
@@ -0,0 +1,136 @@
+/*
+ Copyright (c) 2016 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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdarg.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include "glusterfs/syscall.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/globals.h"
+#include "glusterfs/events.h"
+
+#define EVENT_HOST "127.0.0.1"
+#define EVENT_PORT 24009
+
+int
+_gf_event(eventtypes_t event, const char *fmt, ...)
+{
+ int ret = 0;
+ int sock = -1;
+ char *eventstr = NULL;
+ va_list arguments;
+ char *msg = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char *host = NULL;
+ struct addrinfo hints;
+ struct addrinfo *result = NULL;
+ struct addrinfo *iter_result_ptr = NULL;
+ xlator_t *this = THIS;
+ char *volfile_server_transport = NULL;
+
+ /* Global context */
+ ctx = this->ctx;
+
+ if (event < 0 || event >= EVENT_LAST) {
+ ret = EVENT_ERROR_INVALID_INPUTS;
+ goto out;
+ }
+
+ if (ctx) {
+ volfile_server_transport = ctx->cmd_args.volfile_server_transport;
+ }
+ if (!volfile_server_transport) {
+ volfile_server_transport = "tcp";
+ }
+
+ /* host = NULL returns localhost */
+ if (ctx && ctx->cmd_args.volfile_server &&
+ (strcmp(volfile_server_transport, "unix"))) {
+ /* If it is client code then volfile_server is set
+ use that information to push the events. */
+ host = ctx->cmd_args.volfile_server;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_ADDRCONFIG;
+
+ if ((getaddrinfo(host, TOSTRING(EVENT_PORT), &hints, &result)) != 0) {
+ ret = EVENT_ERROR_RESOLVE;
+ goto out;
+ }
+
+ // iterate over the result and break when socket creation is success.
+ for (iter_result_ptr = result; iter_result_ptr != NULL;
+ iter_result_ptr = iter_result_ptr->ai_next) {
+ sock = socket(iter_result_ptr->ai_family, iter_result_ptr->ai_socktype,
+ iter_result_ptr->ai_protocol);
+ if (sock != -1) {
+ break;
+ }
+ }
+ /*
+ * If none of the addrinfo structures lead to a successful socket
+ * creation, socket creation has failed.
+ */
+ if (sock < 0) {
+ ret = EVENT_ERROR_SOCKET;
+ goto out;
+ }
+
+ va_start(arguments, fmt);
+ ret = gf_vasprintf(&msg, fmt, arguments);
+ va_end(arguments);
+
+ if (ret < 0) {
+ ret = EVENT_ERROR_INVALID_INPUTS;
+ goto out;
+ }
+
+ ret = gf_asprintf(&eventstr, "%u %d %s", (unsigned)gf_time(), event, msg);
+ GF_FREE(msg);
+ if (ret <= 0) {
+ ret = EVENT_ERROR_MSG_FORMAT;
+ goto out;
+ }
+
+ /* Send Message */
+ if (sendto(sock, eventstr, strlen(eventstr), 0, result->ai_addr,
+ result->ai_addrlen) <= 0) {
+ ret = EVENT_ERROR_SEND;
+ goto out;
+ }
+
+ ret = EVENT_SEND_OK;
+
+out:
+ if (sock >= 0) {
+ sys_close(sock);
+ }
+
+ /* Allocated by gf_asprintf */
+ if (eventstr)
+ GF_FREE(eventstr);
+
+ if (result)
+ freeaddrinfo(result);
+
+ return ret;
+}
diff --git a/libglusterfs/src/fd-lk.c b/libglusterfs/src/fd-lk.c
index 01c6c1a0157..c2d34f81c9c 100644
--- a/libglusterfs/src/fd-lk.c
+++ b/libglusterfs/src/fd-lk.c
@@ -8,480 +8,426 @@
cases as published by the Free Software Foundation.
*/
-#include "fd-lk.h"
-#include "common-utils.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/fd-lk.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/libglusterfs-messages.h"
int32_t
-_fd_lk_delete_lock (fd_lk_ctx_node_t *lock)
+_fd_lk_delete_lock(fd_lk_ctx_node_t *lock)
{
- int32_t ret = -1;
+ int32_t ret = -1;
- GF_VALIDATE_OR_GOTO ("fd-lk", lock, out);
+ GF_VALIDATE_OR_GOTO("fd-lk", lock, out);
- list_del_init (&lock->next);
+ list_del_init(&lock->next);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
int32_t
-_fd_lk_destroy_lock (fd_lk_ctx_node_t *lock)
+_fd_lk_destroy_lock(fd_lk_ctx_node_t *lock)
{
- int32_t ret = -1;
+ int32_t ret = -1;
- GF_VALIDATE_OR_GOTO ("fd-lk", lock, out);
+ GF_VALIDATE_OR_GOTO("fd-lk", lock, out);
- GF_FREE (lock);
+ GF_FREE(lock);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
-_fd_lk_destroy_lock_list (fd_lk_ctx_t *lk_ctx)
+_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;
+ 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;
+ return ret;
}
int
-fd_lk_ctx_unref (fd_lk_ctx_t *lk_ctx)
+fd_lk_ctx_unref(fd_lk_ctx_t *lk_ctx)
{
- int ref = -1;
+ int ref = -1;
- GF_VALIDATE_OR_GOTO ("fd-lk", lk_ctx, err);
+ 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);
+ ref = GF_ATOMIC_DEC(lk_ctx->ref);
+ if (ref < 0)
+ GF_ASSERT(!ref);
+ if (ref == 0)
+ _fd_lk_destroy_lock_list(lk_ctx);
- if (ref == 0) {
- LOCK_DESTROY (&lk_ctx->lock);
- GF_FREE (lk_ctx);
- }
+ if (ref == 0) {
+ LOCK_DESTROY(&lk_ctx->lock);
+ GF_FREE(lk_ctx);
+ }
- return 0;
+ return 0;
err:
- return -1;
-}
-
-fd_lk_ctx_t *
-_fd_lk_ctx_ref (fd_lk_ctx_t *lk_ctx)
-{
- if (!lk_ctx) {
- gf_msg_callingfn ("fd-lk", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "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_msg_callingfn ("fd-lk", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "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;
+ return -1;
}
fd_lk_ctx_t *
-fd_lk_ctx_try_ref (fd_lk_ctx_t *lk_ctx)
+fd_lk_ctx_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;
+ if (!lk_ctx) {
+ gf_msg_callingfn("fd-lk", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return NULL;
+ }
- new_lk_ctx = _fd_lk_ctx_ref (lk_ctx);
- UNLOCK (&lk_ctx->lock);
+ GF_ATOMIC_INC(lk_ctx->ref);
-out:
- return new_lk_ctx;
+ return lk_ctx;
}
fd_lk_ctx_t *
-fd_lk_ctx_create ()
+fd_lk_ctx_create()
{
- fd_lk_ctx_t *fd_lk_ctx = NULL;
+ 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;
+ 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);
+ INIT_LIST_HEAD(&fd_lk_ctx->lk_list);
- LOCK_INIT (&fd_lk_ctx->lock);
+ LOCK_INIT(&fd_lk_ctx->lock);
- fd_lk_ctx = fd_lk_ctx_ref (fd_lk_ctx);
+ fd_lk_ctx = fd_lk_ctx_ref(fd_lk_ctx);
out:
- return fd_lk_ctx;
+ return fd_lk_ctx;
}
int
-_fd_lk_insert_lock (fd_lk_ctx_t *lk_ctx,
- fd_lk_ctx_node_t *lock)
+_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;
+ 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)
+_fd_lk_get_lock_len(off_t start, off_t end)
{
- if (end == LLONG_MAX)
- return 0;
- else
- return (end - start + 1);
+ 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_new(int32_t cmd, struct gf_flock *flock)
{
- fd_lk_ctx_node_t *new_lock = NULL;
+ 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;
+ /* 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;
+ new_lock->cmd = cmd;
- if (flock) {
- new_lock->fl_type = flock->l_type;
- new_lock->fl_start = flock->l_start;
+ 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;
+ 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));
- }
+ memcpy(&new_lock->user_flock, flock, sizeof(struct gf_flock));
+ }
- INIT_LIST_HEAD (&new_lock->next);
+ INIT_LIST_HEAD(&new_lock->next);
out:
- return new_lock;
+ return new_lock;
}
int32_t
-_fd_lk_delete_unlck_locks (fd_lk_ctx_t *lk_ctx)
+_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;
+ 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);
+ 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);
- }
+ 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;
+ return ret;
}
int
-fd_lk_overlap (fd_lk_ctx_node_t *l1,
- fd_lk_ctx_node_t *l2)
+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;
+ if (l1->fl_end >= l2->fl_start && l2->fl_end >= l1->fl_start)
+ return 1;
- return 0;
+ 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_add_locks(fd_lk_ctx_node_t *l1, fd_lk_ctx_node_t *l2)
{
- fd_lk_ctx_node_t *sum = NULL;
+ fd_lk_ctx_node_t *sum = NULL;
- sum = fd_lk_ctx_node_new (0, NULL);
- if (!sum)
- goto out;
+ 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->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);
+ 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;
+ return sum;
}
/* Subtract two locks */
struct _values {
- fd_lk_ctx_node_t *locks[3];
+ 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)
+_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 separate 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 separate 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;
+ 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 separate 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 separate 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;
+ return ret;
}
static void
-_fd_lk_insert_and_merge (fd_lk_ctx_t *lk_ctx,
- fd_lk_ctx_node_t *lock)
+_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);
+ 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 {
- _fd_lk_destroy_lock (lock);
+ 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)
+print_lock_list(fd_lk_ctx_t *lk_ctx)
{
- fd_lk_ctx_node_t *lk = NULL;
-
- gf_msg_debug ("fd-lk", 0, "lock list:");
-
- list_for_each_entry (lk, &lk_ctx->lk_list, next)
- gf_msg_debug ("fd-lk", 0, "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);
+ fd_lk_ctx_node_t *lk = NULL;
+
+ gf_msg_debug("fd-lk", 0, "lock list:");
+
+ list_for_each_entry(lk, &lk_ctx->lk_list, next)
+ gf_msg_debug("fd-lk", 0,
+ "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)
+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_msg_debug ("fd-lk", 0, "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;
+ 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_msg_debug("fd-lk", 0,
+ "new lock request: 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;
+ return ret;
}
-
gf_boolean_t
-fd_lk_ctx_empty (fd_lk_ctx_t *lk_ctx)
+fd_lk_ctx_empty(fd_lk_ctx_t *lk_ctx)
{
- gf_boolean_t verdict = _gf_true;
+ gf_boolean_t verdict = _gf_true;
- if (!lk_ctx)
- return _gf_true;
+ if (!lk_ctx)
+ return _gf_true;
- LOCK (&lk_ctx->lock);
- {
- verdict = list_empty (&lk_ctx->lk_list);
- }
- UNLOCK (&lk_ctx->lock);
+ LOCK(&lk_ctx->lock);
+ {
+ verdict = list_empty(&lk_ctx->lk_list);
+ }
+ UNLOCK(&lk_ctx->lock);
- return verdict;
+ return verdict;
}
diff --git a/libglusterfs/src/fd-lk.h b/libglusterfs/src/fd-lk.h
deleted file mode 100644
index 1d2ff794c5b..00000000000
--- a/libglusterfs/src/fd-lk.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- 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"
-#include "common-utils.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);
-
-gf_boolean_t
-fd_lk_ctx_empty (fd_lk_ctx_t *lk_ctx);
-
-#endif /* _FD_LK_H */
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c
index 373f8da0f48..62606e91164 100644
--- a/libglusterfs/src/fd.c
+++ b/libglusterfs/src/fd.c
@@ -8,1231 +8,1196 @@
cases as published by the Free Software Foundation.
*/
-#include "fd.h"
-#include "glusterfs.h"
-#include "inode.h"
-#include "dict.h"
-#include "statedump.h"
-#include "libglusterfs-messages.h"
-
+#include "glusterfs/fd.h"
+#include <errno.h> // for EINVAL, errno, ENOMEM
+#include <inttypes.h> // for PRIu64
+#include <stdint.h> // for UINT32_MAX
+#include <string.h> // for NULL, memcpy, memset, size_t
+#include "glusterfs/statedump.h"
static int
-gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr);
-
+gf_fd_fdtable_expand(fdtable_t *fdtable, uint32_t nr);
fd_t *
-__fd_ref (fd_t *fd);
+__fd_ref(fd_t *fd);
static int
-gf_fd_chain_fd_entries (fdentry_t *entries, uint32_t startidx,
- uint32_t endcount)
+gf_fd_chain_fd_entries(fdentry_t *entries, uint32_t startidx, uint32_t endcount)
{
- uint32_t i = 0;
+ uint32_t i = 0;
- if (!entries) {
- gf_msg_callingfn ("fd", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!entries");
- return -1;
- }
+ if (!entries) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!entries");
+ return -1;
+ }
- /* Chain only till the second to last entry because we want to
- * ensure that the last entry has GF_FDTABLE_END.
- */
- for (i = startidx; i < (endcount - 1); i++)
- entries[i].next_free = i + 1;
+ /* Chain only till the second to last entry because we want to
+ * ensure that the last entry has GF_FDTABLE_END.
+ */
+ for (i = startidx; i < (endcount - 1); i++)
+ entries[i].next_free = i + 1;
- /* i has already been incremented up to the last entry. */
- entries[i].next_free = GF_FDTABLE_END;
+ /* i has already been incremented up to the last entry. */
+ entries[i].next_free = GF_FDTABLE_END;
- return 0;
+ return 0;
}
-
static int
-gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr)
+gf_fd_fdtable_expand(fdtable_t *fdtable, uint32_t nr)
{
- fdentry_t *oldfds = NULL;
- uint32_t oldmax_fds = -1;
- int ret = -1;
-
- if (fdtable == NULL || nr > UINT32_MAX) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- ret = EINVAL;
- goto out;
- }
-
- nr /= (1024 / sizeof (fdentry_t));
- nr = gf_roundup_next_power_of_two (nr + 1);
- nr *= (1024 / sizeof (fdentry_t));
-
- oldfds = fdtable->fdentries;
- oldmax_fds = fdtable->max_fds;
-
- fdtable->fdentries = GF_CALLOC (nr, sizeof (fdentry_t),
- gf_common_mt_fdentry_t);
- if (!fdtable->fdentries) {
- ret = ENOMEM;
- goto out;
- }
- fdtable->max_fds = nr;
-
- if (oldfds) {
- uint32_t cpy = oldmax_fds * sizeof (fdentry_t);
- memcpy (fdtable->fdentries, oldfds, cpy);
- }
-
- gf_fd_chain_fd_entries (fdtable->fdentries, oldmax_fds,
- fdtable->max_fds);
-
- /* Now that expansion is done, we must update the fd list
- * head pointer so that the fd allocation functions can continue
- * using the expanded table.
- */
- fdtable->first_free = oldmax_fds;
- GF_FREE (oldfds);
- ret = 0;
+ fdentry_t *oldfds = NULL;
+ uint32_t oldmax_fds = -1;
+ int ret = -1;
+
+ if (fdtable == NULL || nr > UINT32_MAX) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ ret = EINVAL;
+ goto out;
+ }
+
+ nr /= (1024 / sizeof(fdentry_t));
+ nr = gf_roundup_next_power_of_two(nr + 1);
+ nr *= (1024 / sizeof(fdentry_t));
+
+ oldfds = fdtable->fdentries;
+ oldmax_fds = fdtable->max_fds;
+
+ fdtable->fdentries = GF_CALLOC(nr, sizeof(fdentry_t),
+ gf_common_mt_fdentry_t);
+ if (!fdtable->fdentries) {
+ ret = ENOMEM;
+ goto out;
+ }
+ fdtable->max_fds = nr;
+
+ if (oldfds) {
+ uint32_t cpy = oldmax_fds * sizeof(fdentry_t);
+ memcpy(fdtable->fdentries, oldfds, cpy);
+ }
+
+ gf_fd_chain_fd_entries(fdtable->fdentries, oldmax_fds, fdtable->max_fds);
+
+ /* Now that expansion is done, we must update the fd list
+ * head pointer so that the fd allocation functions can continue
+ * using the expanded table.
+ */
+ fdtable->first_free = oldmax_fds;
+ GF_FREE(oldfds);
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
fdtable_t *
-gf_fd_fdtable_alloc (void)
+gf_fd_fdtable_alloc(void)
{
- fdtable_t *fdtable = NULL;
+ fdtable_t *fdtable = NULL;
- fdtable = GF_CALLOC (1, sizeof (*fdtable), gf_common_mt_fdtable_t);
- if (!fdtable)
- return NULL;
+ fdtable = GF_CALLOC(1, sizeof(*fdtable), gf_common_mt_fdtable_t);
+ if (!fdtable)
+ return NULL;
- pthread_mutex_init (&fdtable->lock, NULL);
+ pthread_rwlock_init(&fdtable->lock, NULL);
- pthread_mutex_lock (&fdtable->lock);
- {
- gf_fd_fdtable_expand (fdtable, 0);
- }
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ gf_fd_fdtable_expand(fdtable, 0);
+ }
+ pthread_rwlock_unlock(&fdtable->lock);
- return fdtable;
+ return fdtable;
}
-
static fdentry_t *
-__gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
+__gf_fd_fdtable_get_all_fds(fdtable_t *fdtable, uint32_t *count)
{
- fdentry_t *fdentries = NULL;
+ fdentry_t *fdentries = NULL;
- if (count == NULL) {
- gf_msg_callingfn ("fd", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!count");
- goto out;
- }
+ if (count == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!count");
+ goto out;
+ }
- fdentries = fdtable->fdentries;
- fdtable->fdentries = GF_CALLOC (fdtable->max_fds, sizeof (fdentry_t),
- gf_common_mt_fdentry_t);
- gf_fd_chain_fd_entries (fdtable->fdentries, 0, fdtable->max_fds);
- *count = fdtable->max_fds;
+ fdentries = fdtable->fdentries;
+ fdtable->fdentries = GF_CALLOC(fdtable->max_fds, sizeof(fdentry_t),
+ gf_common_mt_fdentry_t);
+ gf_fd_chain_fd_entries(fdtable->fdentries, 0, fdtable->max_fds);
+ *count = fdtable->max_fds;
out:
- return fdentries;
+ return fdentries;
}
-
fdentry_t *
-gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
+gf_fd_fdtable_get_all_fds(fdtable_t *fdtable, uint32_t *count)
{
- fdentry_t *entries = NULL;
+ fdentry_t *entries = NULL;
- if (fdtable) {
- pthread_mutex_lock (&fdtable->lock);
- {
- entries = __gf_fd_fdtable_get_all_fds (fdtable, count);
- }
- pthread_mutex_unlock (&fdtable->lock);
+ if (fdtable) {
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ entries = __gf_fd_fdtable_get_all_fds(fdtable, count);
}
+ pthread_rwlock_unlock(&fdtable->lock);
+ }
- return entries;
+ return entries;
}
-
static fdentry_t *
-__gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count)
+__gf_fd_fdtable_copy_all_fds(fdtable_t *fdtable, uint32_t *count)
{
- fdentry_t *fdentries = NULL;
- int i = 0;
+ fdentry_t *fdentries = NULL;
+ int i = 0;
- if (count == NULL) {
- gf_msg_callingfn ("fd", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!count");
- goto out;
- }
+ if (count == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!count");
+ goto out;
+ }
- fdentries = GF_CALLOC (fdtable->max_fds, sizeof (fdentry_t),
- gf_common_mt_fdentry_t);
- if (fdentries == NULL) {
- 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;
+ *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);
- }
+ 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;
+ return fdentries;
}
-
fdentry_t *
-gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count)
+gf_fd_fdtable_copy_all_fds(fdtable_t *fdtable, uint32_t *count)
{
- fdentry_t *entries = NULL;
+ 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);
+ if (fdtable) {
+ pthread_rwlock_rdlock(&fdtable->lock);
+ {
+ entries = __gf_fd_fdtable_copy_all_fds(fdtable, count);
}
+ pthread_rwlock_unlock(&fdtable->lock);
+ }
- return entries;
+ return entries;
}
-
void
-gf_fd_fdtable_destroy (fdtable_t *fdtable)
+gf_fd_fdtable_destroy(fdtable_t *fdtable)
{
- struct list_head list = {0, };
- fd_t *fd = NULL;
- fdentry_t *fdentries = NULL;
- uint32_t fd_count = 0;
- int32_t i = 0;
-
- INIT_LIST_HEAD (&list);
-
- if (!fdtable) {
- gf_msg_callingfn ("fd", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!fdtable");
- return;
- }
-
- pthread_mutex_lock (&fdtable->lock);
- {
- fdentries = __gf_fd_fdtable_get_all_fds (fdtable, &fd_count);
- GF_FREE (fdtable->fdentries);
- }
- pthread_mutex_unlock (&fdtable->lock);
-
- if (fdentries != NULL) {
- for (i = 0; i < fd_count; i++) {
- fd = fdentries[i].fd;
- if (fd != NULL) {
- fd_unref (fd);
- }
- }
-
- GF_FREE (fdentries);
- pthread_mutex_destroy (&fdtable->lock);
- GF_FREE (fdtable);
- }
+ struct list_head list = {
+ 0,
+ };
+ fd_t *fd = NULL;
+ fdentry_t *fdentries = NULL;
+ uint32_t fd_count = 0;
+ int32_t i = 0;
+
+ INIT_LIST_HEAD(&list);
+
+ if (!fdtable) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!fdtable");
+ return;
+ }
+
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ fdentries = __gf_fd_fdtable_get_all_fds(fdtable, &fd_count);
+ GF_FREE(fdtable->fdentries);
+ }
+ pthread_rwlock_unlock(&fdtable->lock);
+
+ if (fdentries != NULL) {
+ for (i = 0; i < fd_count; i++) {
+ fd = fdentries[i].fd;
+ if (fd != NULL) {
+ fd_unref(fd);
+ }
+ }
+
+ GF_FREE(fdentries);
+ pthread_rwlock_destroy(&fdtable->lock);
+ GF_FREE(fdtable);
+ }
}
-
int
-gf_fd_unused_get (fdtable_t *fdtable, fd_t *fdptr)
+gf_fd_unused_get(fdtable_t *fdtable, fd_t *fdptr)
{
- int32_t fd = -1;
- fdentry_t *fde = NULL;
- int error;
- int alloc_attempts = 0;
-
- if (fdtable == NULL || fdptr == NULL) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return EINVAL;
- }
-
- pthread_mutex_lock (&fdtable->lock);
- {
- fd_alloc_try_again:
- if (fdtable->first_free != GF_FDTABLE_END) {
- fde = &fdtable->fdentries[fdtable->first_free];
- fd = fdtable->first_free;
- fdtable->first_free = fde->next_free;
- fde->next_free = GF_FDENTRY_ALLOCATED;
- fde->fd = fdptr;
- } else {
- /* If this is true, there is something
- * seriously wrong with our data structures.
- */
- if (alloc_attempts >= 2) {
- gf_msg ("fd", GF_LOG_ERROR, 0,
- LG_MSG_EXPAND_FD_TABLE_FAILED,
- "multiple attempts to expand fd table"
- " have failed.");
- goto out;
- }
- error = gf_fd_fdtable_expand (fdtable,
- fdtable->max_fds + 1);
- if (error) {
- gf_msg ("fd", GF_LOG_ERROR, error,
- LG_MSG_EXPAND_FD_TABLE_FAILED,
- "Cannot expand fdtable");
- goto out;
- }
- ++alloc_attempts;
- /* At this point, the table stands expanded
- * with the first_free referring to the first
- * free entry in the new set of fdentries that
- * have just been allocated. That means, the
- * above logic should just work.
- */
- goto fd_alloc_try_again;
- }
- }
+ int32_t fd = -1;
+ fdentry_t *fde = NULL;
+ int error;
+ int alloc_attempts = 0;
+
+ if (fdtable == NULL || fdptr == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return EINVAL;
+ }
+
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ fd_alloc_try_again:
+ if (fdtable->first_free != GF_FDTABLE_END) {
+ fde = &fdtable->fdentries[fdtable->first_free];
+ fd = fdtable->first_free;
+ fdtable->first_free = fde->next_free;
+ fde->next_free = GF_FDENTRY_ALLOCATED;
+ fde->fd = fdptr;
+ } else {
+ /* If this is true, there is something
+ * seriously wrong with our data structures.
+ */
+ if (alloc_attempts >= 2) {
+ gf_msg("fd", GF_LOG_ERROR, 0, LG_MSG_EXPAND_FD_TABLE_FAILED,
+ "multiple attempts to expand fd table"
+ " have failed.");
+ goto out;
+ }
+ error = gf_fd_fdtable_expand(fdtable, fdtable->max_fds + 1);
+ if (error) {
+ gf_msg("fd", GF_LOG_ERROR, error, LG_MSG_EXPAND_FD_TABLE_FAILED,
+ "Cannot expand fdtable");
+ goto out;
+ }
+ ++alloc_attempts;
+ /* At this point, the table stands expanded
+ * with the first_free referring to the first
+ * free entry in the new set of fdentries that
+ * have just been allocated. That means, the
+ * above logic should just work.
+ */
+ goto fd_alloc_try_again;
+ }
+ }
out:
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_rwlock_unlock(&fdtable->lock);
- return fd;
+ return fd;
}
-
void
-gf_fd_put (fdtable_t *fdtable, int32_t fd)
+gf_fd_put(fdtable_t *fdtable, int32_t fd)
{
- fd_t *fdptr = NULL;
- fdentry_t *fde = NULL;
+ fd_t *fdptr = NULL;
+ fdentry_t *fde = NULL;
- if (fd == GF_ANON_FD_NO)
- return;
-
- if (fdtable == NULL || fd < 0) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return;
- }
+ if (fd == GF_ANON_FD_NO)
+ return;
- if (!(fd < fdtable->max_fds)) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return;
- }
+ if (fdtable == NULL || fd < 0) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return;
+ }
- pthread_mutex_lock (&fdtable->lock);
- {
- fde = &fdtable->fdentries[fd];
- /* 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;
- fdptr = fde->fd;
- fde->fd = NULL;
- fde->next_free = fdtable->first_free;
- fdtable->first_free = fd;
- }
+ if (!(fd < fdtable->max_fds)) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return;
+ }
+
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ fde = &fdtable->fdentries[fd];
+ /* 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;
+ fdptr = fde->fd;
+ fde->fd = NULL;
+ fde->next_free = fdtable->first_free;
+ fdtable->first_free = fd;
+ }
unlock_out:
- pthread_mutex_unlock (&fdtable->lock);
+ pthread_rwlock_unlock(&fdtable->lock);
- if (fdptr) {
- fd_unref (fdptr);
- }
+ if (fdptr) {
+ fd_unref(fdptr);
+ }
}
-
void
-gf_fdptr_put (fdtable_t *fdtable, fd_t *fd)
+gf_fdptr_put(fdtable_t *fdtable, fd_t *fd)
{
- fdentry_t *fde = NULL;
- int32_t i = 0;
-
- if ((fdtable == NULL) || (fd == NULL)) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return;
- }
+ fdentry_t *fde = NULL;
+ int32_t i = 0;
- 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 ((fdtable == NULL) || (fd == NULL)) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return;
+ }
- if (fde == NULL) {
- gf_msg_callingfn ("fd", GF_LOG_WARNING, 0,
- LG_MSG_FD_NOT_FOUND_IN_FDTABLE,
- "fd (%p) is not present in fdtable",
- fd);
- goto unlock_out;
- }
+ pthread_rwlock_wrlock(&fdtable->lock);
+ {
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (fdtable->fdentries[i].fd == fd) {
+ fde = &fdtable->fdentries[i];
+ break;
+ }
+ }
- /* 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;
+ if (fde == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, 0,
+ LG_MSG_FD_NOT_FOUND_IN_FDTABLE,
+ "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);
+ pthread_rwlock_unlock(&fdtable->lock);
- if ((fd != NULL) && (fde != NULL)) {
- fd_unref (fd);
- }
+ if ((fd != NULL) && (fde != NULL)) {
+ fd_unref(fd);
+ }
}
-
fd_t *
-gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd)
+gf_fd_fdptr_get(fdtable_t *fdtable, int64_t fd)
{
- fd_t *fdptr = NULL;
+ fd_t *fdptr = NULL;
- if (fdtable == NULL || fd < 0) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- errno = EINVAL;
- return NULL;
- }
+ if (fdtable == NULL || fd < 0) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ errno = EINVAL;
+ return NULL;
+ }
- if (!(fd < fdtable->max_fds)) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- errno = EINVAL;
- return NULL;
- }
+ if (!(fd < fdtable->max_fds)) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ errno = EINVAL;
+ return NULL;
+ }
- pthread_mutex_lock (&fdtable->lock);
- {
- fdptr = fdtable->fdentries[fd].fd;
- if (fdptr) {
- fd_ref (fdptr);
- }
+ pthread_rwlock_rdlock(&fdtable->lock);
+ {
+ fdptr = fdtable->fdentries[fd].fd;
+ if (fdptr) {
+ fd_ref(fdptr);
}
- pthread_mutex_unlock (&fdtable->lock);
+ }
+ pthread_rwlock_unlock(&fdtable->lock);
- return fdptr;
+ return fdptr;
}
-
fd_t *
-__fd_ref (fd_t *fd)
+__fd_ref(fd_t *fd)
{
- ++fd->refcount;
+ GF_ATOMIC_INC(fd->refcount);
- return fd;
+ return fd;
}
-
fd_t *
-fd_ref (fd_t *fd)
+fd_ref(fd_t *fd)
{
- fd_t *refed_fd = NULL;
-
- if (!fd) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "null fd");
- return NULL;
- }
+ if (!fd) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "null fd");
+ return NULL;
+ }
- LOCK (&fd->inode->lock);
- refed_fd = __fd_ref (fd);
- UNLOCK (&fd->inode->lock);
+ GF_ATOMIC_INC(fd->refcount);
- return refed_fd;
+ return fd;
}
-
-fd_t *
-__fd_unref (fd_t *fd)
+static void
+fd_destroy(fd_t *fd, gf_boolean_t bound)
{
- GF_ASSERT (fd->refcount);
-
- --fd->refcount;
-
- return fd;
+ xlator_t *xl = NULL;
+ int i = 0;
+ xlator_t *old_THIS = NULL;
+
+ if (fd == NULL) {
+ gf_msg_callingfn("xlator", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ goto out;
+ }
+
+ if (fd->inode == NULL) {
+ gf_msg_callingfn("xlator", GF_LOG_ERROR, 0, LG_MSG_FD_INODE_NULL,
+ "fd->inode is NULL");
+ goto out;
+ }
+ if (!fd->_ctx)
+ goto out;
+
+ if (IA_ISDIR(fd->inode->ia_type)) {
+ for (i = 0; i < fd->xl_count; i++) {
+ if (fd->_ctx[i].key) {
+ xl = fd->_ctx[i].xl_key;
+ old_THIS = THIS;
+ THIS = xl;
+ if (!xl->call_cleanup && xl->cbks->releasedir)
+ xl->cbks->releasedir(xl, fd);
+ THIS = old_THIS;
+ }
+ }
+ } else {
+ for (i = 0; i < fd->xl_count; i++) {
+ if (fd->_ctx[i].key) {
+ xl = fd->_ctx[i].xl_key;
+ old_THIS = THIS;
+ THIS = xl;
+ if (!xl->call_cleanup && xl->cbks->release)
+ xl->cbks->release(xl, fd);
+ THIS = old_THIS;
+ }
+ }
+ }
+
+ LOCK_DESTROY(&fd->lock);
+
+ GF_FREE(fd->_ctx);
+ if (bound) {
+ /*Decrease the count only after close happens on file*/
+ LOCK(&fd->inode->lock);
+ {
+ fd->inode->fd_count--;
+ }
+ UNLOCK(&fd->inode->lock);
+ }
+ inode_unref(fd->inode);
+ fd->inode = NULL;
+ fd_lk_ctx_unref(fd->lk_ctx);
+ mem_put(fd);
+out:
+ return;
}
-
-static void
-fd_destroy (fd_t *fd, gf_boolean_t bound)
+void
+fd_close(fd_t *fd)
{
- xlator_t *xl = NULL;
- int i = 0;
- xlator_t *old_THIS = NULL;
+ xlator_t *xl, *old_THIS;
- if (fd == NULL){
- gf_msg_callingfn ("xlator", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- goto out;
- }
+ old_THIS = THIS;
- if (fd->inode == NULL){
- gf_msg_callingfn ("xlator", GF_LOG_ERROR, 0,
- LG_MSG_FD_INODE_NULL,
- "fd->inode is NULL");
- goto out;
- }
- if (!fd->_ctx)
- goto out;
+ for (xl = fd->inode->table->xl->graph->first; xl != NULL; xl = xl->next) {
+ if (!xl->call_cleanup) {
+ THIS = xl;
- if (IA_ISDIR (fd->inode->ia_type)) {
- for (i = 0; i < fd->xl_count; i++) {
- if (fd->_ctx[i].key) {
- xl = fd->_ctx[i].xl_key;
- old_THIS = THIS;
- THIS = xl;
- if (xl->cbks->releasedir)
- xl->cbks->releasedir (xl, fd);
- THIS = old_THIS;
- }
+ if (IA_ISDIR(fd->inode->ia_type)) {
+ if (xl->cbks->fdclosedir != NULL) {
+ xl->cbks->fdclosedir(xl, fd);
}
- } else {
- for (i = 0; i < fd->xl_count; i++) {
- if (fd->_ctx[i].key) {
- xl = fd->_ctx[i].xl_key;
- old_THIS = THIS;
- THIS = xl;
- if (xl->cbks->release)
- xl->cbks->release (xl, fd);
- THIS = old_THIS;
- }
+ } else {
+ if (xl->cbks->fdclose != NULL) {
+ xl->cbks->fdclose(xl, fd);
}
+ }
}
+ }
- LOCK_DESTROY (&fd->lock);
-
- GF_FREE (fd->_ctx);
- if (bound) {
- /*Decrease the count only after close happens on file*/
- LOCK (&fd->inode->lock);
- {
- fd->inode->fd_count--;
- }
- UNLOCK (&fd->inode->lock);
- }
- inode_unref (fd->inode);
- fd->inode = NULL;
- fd_lk_ctx_unref (fd->lk_ctx);
- mem_put (fd);
-out:
- return;
+ THIS = old_THIS;
}
-
void
-fd_unref (fd_t *fd)
+fd_unref(fd_t *fd)
{
- int32_t refcount = 0;
- gf_boolean_t bound = _gf_false;
-
- if (!fd) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "fd is NULL");
- return;
- }
+ int32_t refcount = 0;
+ gf_boolean_t bound = _gf_false;
- LOCK (&fd->inode->lock);
- {
- __fd_unref (fd);
- refcount = fd->refcount;
- if (refcount == 0) {
- if (!list_empty (&fd->inode_list)) {
- list_del_init (&fd->inode_list);
- bound = _gf_true;
- }
- }
-
- }
- UNLOCK (&fd->inode->lock);
+ if (!fd) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "fd is NULL");
+ return;
+ }
+ LOCK(&fd->inode->lock);
+ {
+ refcount = GF_ATOMIC_DEC(fd->refcount);
if (refcount == 0) {
- fd_destroy (fd, bound);
+ if (!list_empty(&fd->inode_list)) {
+ list_del_init(&fd->inode_list);
+ fd->inode->active_fd_count--;
+ bound = _gf_true;
+ }
}
+ }
+ UNLOCK(&fd->inode->lock);
- return ;
-}
+ if (refcount == 0) {
+ fd_destroy(fd, bound);
+ }
+ return;
+}
-fd_t *
-__fd_bind (fd_t *fd)
+static fd_t *
+__fd_bind(fd_t *fd)
{
- list_del_init (&fd->inode_list);
- list_add (&fd->inode_list, &fd->inode->fd_list);
- fd->inode->fd_count++;
+ list_del_init(&fd->inode_list);
+ list_add(&fd->inode_list, &fd->inode->fd_list);
+ fd->inode->fd_count++;
+ fd->inode->active_fd_count++;
- return fd;
+ return fd;
}
-
fd_t *
-fd_bind (fd_t *fd)
+fd_bind(fd_t *fd)
{
- if (!fd || !fd->inode) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "!fd || !fd->inode");
- return NULL;
- }
+ if (!fd || !fd->inode) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "!fd || !fd->inode");
+ return NULL;
+ }
- LOCK (&fd->inode->lock);
- {
- fd = __fd_bind (fd);
- }
- UNLOCK (&fd->inode->lock);
+ LOCK(&fd->inode->lock);
+ {
+ fd = __fd_bind(fd);
+ }
+ UNLOCK(&fd->inode->lock);
- return fd;
+ return fd;
}
-
static fd_t *
-__fd_create (inode_t *inode, uint64_t pid)
+fd_allocate(inode_t *inode, uint64_t pid)
{
- fd_t *fd = NULL;
-
- if (inode == NULL) {
- gf_msg_callingfn ("fd", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return NULL;
- }
-
- fd = mem_get0 (inode->table->fd_mem_pool);
- if (!fd)
- goto out;
+ fd_t *fd;
- fd->xl_count = inode->table->xl->graph->xl_count + 1;
-
- fd->_ctx = GF_CALLOC (1, (sizeof (struct _fd_ctx) * fd->xl_count),
- gf_common_mt_fd_ctx);
- if (!fd->_ctx)
- goto free_fd;
-
- fd->lk_ctx = fd_lk_ctx_create ();
- if (!fd->lk_ctx)
- goto free_fd_ctx;
+ if (inode == NULL) {
+ gf_msg_callingfn("fd", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return NULL;
+ }
- fd->inode = inode_ref (inode);
+ fd = mem_get0(inode->table->fd_mem_pool);
+ if (fd == NULL) {
+ return NULL;
+ }
+
+ fd->xl_count = inode->table->xl->graph->xl_count + 1;
+
+ fd->_ctx = GF_CALLOC(1, (sizeof(struct _fd_ctx) * fd->xl_count),
+ gf_common_mt_fd_ctx);
+ if (fd->_ctx == NULL) {
+ goto failed;
+ }
+
+ fd->lk_ctx = fd_lk_ctx_create();
+ if (fd->lk_ctx != NULL) {
+ /* We need to take a reference from the inode, but we cannot do it
+ * here because this function can be called with the inode lock taken
+ * and inode_ref() takes the inode's table lock. This is the reverse
+ * of the logical lock acquisition order and can cause a deadlock. So
+ * we simply assign the inode here and we delefate the inode reference
+ * responsibility to the caller (when this function succeeds and the
+ * inode lock is released). This is safe because the caller must hold
+ * a reference of the inode to use it, so it's guaranteed that the
+ * number of references won't reach 0 before the caller finishes.
+ *
+ * TODO: minimize use of locks in favor of atomic operations to avoid
+ * these dependencies. */
+ fd->inode = inode;
fd->pid = pid;
- INIT_LIST_HEAD (&fd->inode_list);
-
- LOCK_INIT (&fd->lock);
-out:
+ INIT_LIST_HEAD(&fd->inode_list);
+ LOCK_INIT(&fd->lock);
+ GF_ATOMIC_INIT(fd->refcount, 1);
return fd;
+ }
-free_fd_ctx:
- GF_FREE (fd->_ctx);
-free_fd:
- mem_put (fd);
+ GF_FREE(fd->_ctx);
- return NULL;
-}
+failed:
+ mem_put(fd);
+ return NULL;
+}
fd_t *
-fd_create (inode_t *inode, pid_t pid)
+fd_create_uint64(inode_t *inode, uint64_t pid)
{
- fd_t *fd = NULL;
+ fd_t *fd;
- fd = __fd_create (inode, (uint64_t)pid);
- if (!fd)
- goto out;
-
- fd = fd_ref (fd);
+ fd = fd_allocate(inode, pid);
+ if (fd != NULL) {
+ /* fd_allocate() doesn't get a reference from the inode. We need to
+ * take it here in case of success. */
+ inode_ref(inode);
+ }
-out:
- return fd;
+ return fd;
}
fd_t *
-fd_create_uint64 (inode_t *inode, uint64_t pid)
+fd_create(inode_t *inode, pid_t pid)
{
- fd_t *fd = NULL;
-
- fd = __fd_create (inode, pid);
- if (!fd)
- goto out;
-
- fd = fd_ref (fd);
-
-out:
- return fd;
+ return fd_create_uint64(inode, (uint64_t)pid);
}
-
static fd_t *
-__fd_lookup (inode_t *inode, uint64_t pid)
+__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;
+ 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)
- /* If someone was interested in getting an
- anonymous fd (or was OK getting an anonymous fd),
- they can as well call fd_anonymous() directly */
- continue;
+ list_for_each_entry(iter_fd, &inode->fd_list, inode_list)
+ {
+ if (iter_fd->anonymous)
+ /* If someone was interested in getting an
+ anonymous fd (or was OK getting an anonymous fd),
+ they can as well call fd_anonymous() directly */
+ continue;
- if (!pid || iter_fd->pid == pid) {
- fd = __fd_ref (iter_fd);
- break;
- }
+ if (!pid || iter_fd->pid == pid) {
+ fd = __fd_ref(iter_fd);
+ break;
}
+ }
- return fd;
+ return fd;
}
-
fd_t *
-fd_lookup (inode_t *inode, pid_t pid)
+fd_lookup(inode_t *inode, pid_t pid)
{
- fd_t *fd = NULL;
+ fd_t *fd = NULL;
- if (!inode) {
- gf_msg_callingfn ("fd", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!inode");
- return NULL;
- }
+ if (!inode) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!inode");
+ return NULL;
+ }
- LOCK (&inode->lock);
- {
- fd = __fd_lookup (inode, (uint64_t)pid);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ fd = __fd_lookup(inode, (uint64_t)pid);
+ }
+ UNLOCK(&inode->lock);
- return fd;
+ return fd;
}
fd_t *
-fd_lookup_uint64 (inode_t *inode, uint64_t pid)
+fd_lookup_uint64(inode_t *inode, uint64_t pid)
{
- fd_t *fd = NULL;
+ fd_t *fd = NULL;
- if (!inode) {
- gf_msg_callingfn ("fd", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!inode");
- return NULL;
- }
+ if (!inode) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!inode");
+ return NULL;
+ }
- LOCK (&inode->lock);
- {
- fd = __fd_lookup (inode, pid);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ fd = __fd_lookup(inode, pid);
+ }
+ UNLOCK(&inode->lock);
- return fd;
+ return fd;
}
static fd_t *
-__fd_lookup_anonymous (inode_t *inode)
+__fd_lookup_anonymous(inode_t *inode, int32_t flags)
{
- fd_t *iter_fd = NULL;
- fd_t *fd = NULL;
+ fd_t *iter_fd = NULL;
+ fd_t *fd = NULL;
- if (list_empty (&inode->fd_list))
- return 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;
- }
+ list_for_each_entry(iter_fd, &inode->fd_list, inode_list)
+ {
+ if ((iter_fd->anonymous) && (flags == iter_fd->flags)) {
+ fd = __fd_ref(iter_fd);
+ break;
}
+ }
- return fd;
+ return fd;
}
-static fd_t *
-__fd_anonymous (inode_t *inode)
+fd_t *
+fd_anonymous_with_flags(inode_t *inode, int32_t flags)
{
- fd_t *fd = NULL;
-
- fd = __fd_lookup_anonymous (inode);
+ fd_t *fd = NULL;
+ bool ref = false;
- /* 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);
+ LOCK(&inode->lock);
- if (!fd)
- return NULL;
+ fd = __fd_lookup_anonymous(inode, flags);
- fd->anonymous = _gf_true;
- fd->flags = GF_ANON_FD_FLAGS;
+ /* 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 won't bump up the ref
+ count, so we have to call fd_ref() after bind. */
+ if (fd == NULL) {
+ fd = fd_allocate(inode, 0);
+ if (fd != NULL) {
+ fd->anonymous = _gf_true;
+ fd->flags = GF_ANON_FD_FLAGS | (flags & O_DIRECT);
- __fd_bind (fd);
+ __fd_bind(fd);
- __fd_ref (fd);
+ ref = true;
}
+ }
- return fd;
-}
+ UNLOCK(&inode->lock);
+ if (ref) {
+ /* fd_allocate() doesn't get a reference from the inode. We need to
+ * take it here in case of success. */
+ inode_ref(inode);
+ }
+
+ return fd;
+}
fd_t *
-fd_anonymous (inode_t *inode)
+fd_anonymous(inode_t *inode)
{
- fd_t *fd = NULL;
-
- LOCK (&inode->lock);
- {
- fd = __fd_anonymous (inode);
- }
- UNLOCK (&inode->lock);
-
- return fd;
+ return fd_anonymous_with_flags(inode, 0);
}
-fd_t*
-fd_lookup_anonymous (inode_t *inode)
+fd_t *
+fd_lookup_anonymous(inode_t *inode, int32_t flags)
{
- fd_t *fd = NULL;
-
- if (!inode) {
- gf_msg_callingfn ("fd", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "!inode");
- return NULL;
- }
+ fd_t *fd = NULL;
- LOCK (&inode->lock);
- {
- fd = __fd_lookup_anonymous (inode);
- }
- UNLOCK (&inode->lock);
- return fd;
+ if (!inode) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "!inode");
+ return NULL;
+ }
+
+ LOCK(&inode->lock);
+ {
+ fd = __fd_lookup_anonymous(inode, flags);
+ }
+ UNLOCK(&inode->lock);
+ return fd;
}
gf_boolean_t
-fd_is_anonymous (fd_t *fd)
+fd_is_anonymous(fd_t *fd)
{
- return (fd && fd->anonymous);
+ return (fd && fd->anonymous);
}
-
uint8_t
-fd_list_empty (inode_t *inode)
+fd_list_empty(inode_t *inode)
{
- uint8_t empty = 0;
+ uint8_t empty = 0;
- LOCK (&inode->lock);
- {
- empty = list_empty (&inode->fd_list);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ empty = list_empty(&inode->fd_list);
+ }
+ UNLOCK(&inode->lock);
- return empty;
+ return empty;
}
-
int
-__fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
+__fd_ctx_set(fd_t *fd, xlator_t *xlator, uint64_t value)
{
- 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;
-
- for (index = 0; index < fd->xl_count; index++) {
- if (!fd->_ctx[index].key) {
- if (set_idx == -1)
- set_idx = index;
- /* dont break, to check if key already exists
- further on */
- }
- if (fd->_ctx[index].xl_key == xlator) {
- set_idx = index;
- break;
- }
+ 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;
+
+ for (index = 0; index < fd->xl_count; index++) {
+ if (!fd->_ctx[index].key) {
+ if (set_idx == -1)
+ set_idx = index;
+ /* don't break, to check if key already exists
+ further on */
}
+ if (fd->_ctx[index].xl_key == xlator) {
+ set_idx = index;
+ break;
+ }
+ }
- if (set_idx == -1) {
- set_idx = fd->xl_count;
+ if (set_idx == -1) {
+ set_idx = fd->xl_count;
- new_xl_count = fd->xl_count + xlator->graph->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) {
- ret = -1;
- goto out;
- }
+ tmp = GF_REALLOC(fd->_ctx, (sizeof(struct _fd_ctx) * new_xl_count));
+ if (tmp == NULL) {
+ ret = -1;
+ goto out;
+ }
- fd->_ctx = tmp;
+ fd->_ctx = tmp;
- begin = fd->_ctx;
- begin += (fd->xl_count * sizeof (struct _fd_ctx));
+ begin = fd->_ctx;
+ begin += (fd->xl_count * sizeof(struct _fd_ctx));
- diff = (new_xl_count - fd->xl_count )
- * sizeof (struct _fd_ctx);
+ diff = (new_xl_count - fd->xl_count) * sizeof(struct _fd_ctx);
- memset (begin, 0, diff);
+ memset(begin, 0, diff);
- fd->xl_count = new_xl_count;
- }
+ fd->xl_count = new_xl_count;
+ }
- fd->_ctx[set_idx].xl_key = xlator;
- fd->_ctx[set_idx].value1 = value;
+ fd->_ctx[set_idx].xl_key = xlator;
+ fd->_ctx[set_idx].value1 = value;
out:
- return ret;
+ return ret;
}
-
int
-fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value)
+fd_ctx_set(fd_t *fd, xlator_t *xlator, uint64_t value)
{
- int ret = 0;
+ int ret = 0;
- if (!fd || !xlator) {
- gf_msg_callingfn ("fd", GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "%p %p", fd, xlator);
- return -1;
- }
+ if (!fd || !xlator) {
+ gf_msg_callingfn("fd", GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "%p %p", fd, xlator);
+ return -1;
+ }
- LOCK (&fd->lock);
- {
- ret = __fd_ctx_set (fd, xlator, value);
- }
- UNLOCK (&fd->lock);
+ LOCK(&fd->lock);
+ {
+ ret = __fd_ctx_set(fd, xlator, value);
+ }
+ UNLOCK(&fd->lock);
- return ret;
+ return ret;
}
-
int
-__fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value)
+__fd_ctx_get(fd_t *fd, xlator_t *xlator, uint64_t *value)
{
- int index = 0;
- int ret = 0;
+ int index = 0;
+ int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
- for (index = 0; index < fd->xl_count; index++) {
- if (fd->_ctx[index].xl_key == xlator)
- break;
- }
+ for (index = 0; index < fd->xl_count; index++) {
+ if (fd->_ctx[index].xl_key == xlator)
+ break;
+ }
- if (index == fd->xl_count) {
- ret = -1;
- goto out;
- }
+ if (index == fd->xl_count) {
+ ret = -1;
+ goto out;
+ }
- if (value)
- *value = fd->_ctx[index].value1;
+ if (value)
+ *value = fd->_ctx[index].value1;
out:
- return ret;
+ return ret;
}
-
int
-fd_ctx_get (fd_t *fd, xlator_t *xlator, uint64_t *value)
+fd_ctx_get(fd_t *fd, xlator_t *xlator, uint64_t *value)
{
- int ret = 0;
+ int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
- LOCK (&fd->lock);
- {
- ret = __fd_ctx_get (fd, xlator, value);
- }
- UNLOCK (&fd->lock);
+ LOCK(&fd->lock);
+ {
+ ret = __fd_ctx_get(fd, xlator, value);
+ }
+ UNLOCK(&fd->lock);
- return ret;
+ return ret;
}
-
int
-__fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value)
+__fd_ctx_del(fd_t *fd, xlator_t *xlator, uint64_t *value)
{
- int index = 0;
- int ret = 0;
+ int index = 0;
+ int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
- for (index = 0; index < fd->xl_count; index++) {
- if (fd->_ctx[index].xl_key == xlator)
- break;
- }
+ for (index = 0; index < fd->xl_count; index++) {
+ if (fd->_ctx[index].xl_key == xlator)
+ break;
+ }
- if (index == fd->xl_count) {
- ret = -1;
- goto out;
- }
+ if (index == fd->xl_count) {
+ ret = -1;
+ goto out;
+ }
- if (value)
- *value = fd->_ctx[index].value1;
+ if (value)
+ *value = fd->_ctx[index].value1;
- fd->_ctx[index].key = 0;
- fd->_ctx[index].value1 = 0;
+ fd->_ctx[index].key = 0;
+ fd->_ctx[index].value1 = 0;
out:
- return ret;
+ return ret;
}
-
int
-fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value)
+fd_ctx_del(fd_t *fd, xlator_t *xlator, uint64_t *value)
{
- int ret = 0;
+ int ret = 0;
- if (!fd || !xlator)
- return -1;
+ if (!fd || !xlator)
+ return -1;
- LOCK (&fd->lock);
- {
- ret = __fd_ctx_del (fd, xlator, value);
- }
- UNLOCK (&fd->lock);
+ LOCK(&fd->lock);
+ {
+ ret = __fd_ctx_del(fd, xlator, value);
+ }
+ UNLOCK(&fd->lock);
- return ret;
+ return ret;
}
-
void
-fd_dump (fd_t *fd, char *prefix)
+fd_dump(fd_t *fd, char *prefix)
{
- char key[GF_DUMP_MAX_BUF_LEN];
-
- if (!fd)
- return;
+ char key[GF_DUMP_MAX_BUF_LEN];
- memset(key, 0, sizeof(key));
- gf_proc_dump_write("pid", "%llu", fd->pid);
- gf_proc_dump_write("refcount", "%d", fd->refcount);
- gf_proc_dump_write("flags", "%d", fd->flags);
+ if (!fd)
+ return;
- if (fd->inode) {
- gf_proc_dump_build_key (key, "inode", NULL);
- gf_proc_dump_add_section(key);
- inode_dump (fd->inode, key);
- }
+ gf_proc_dump_write("pid", "%" PRIu64, fd->pid);
+ gf_proc_dump_write("refcount", "%" GF_PRI_ATOMIC,
+ GF_ATOMIC_GET(fd->refcount));
+ gf_proc_dump_write("flags", "%d", fd->flags);
+ if (fd->inode) {
+ gf_proc_dump_build_key(key, "inode", NULL);
+ gf_proc_dump_add_section("%s", key);
+ inode_dump(fd->inode, key);
+ }
}
-
void
-fdentry_dump (fdentry_t *fdentry, char *prefix)
+fdentry_dump(fdentry_t *fdentry, char *prefix)
{
- if (!fdentry)
- return;
+ if (!fdentry)
+ return;
- if (GF_FDENTRY_ALLOCATED != fdentry->next_free)
- return;
+ if (GF_FDENTRY_ALLOCATED != fdentry->next_free)
+ return;
- if (fdentry->fd)
- fd_dump(fdentry->fd, prefix);
+ if (fdentry->fd)
+ fd_dump(fdentry->fd, prefix);
}
-
void
-fdtable_dump (fdtable_t *fdtable, char *prefix)
+fdtable_dump(fdtable_t *fdtable, char *prefix)
{
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 0;
- int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i = 0;
+ int ret = -1;
- if (!fdtable)
- return;
+ if (!fdtable)
+ return;
- ret = pthread_mutex_trylock (&fdtable->lock);
+ ret = pthread_rwlock_tryrdlock(&fdtable->lock);
+ if (ret)
+ goto out;
- if (ret)
- goto out;
+ gf_proc_dump_build_key(key, prefix, "refcount");
+ gf_proc_dump_write(key, "%d", fdtable->refcount);
+ gf_proc_dump_build_key(key, prefix, "maxfds");
+ gf_proc_dump_write(key, "%d", fdtable->max_fds);
+ gf_proc_dump_build_key(key, prefix, "first_free");
+ gf_proc_dump_write(key, "%d", fdtable->first_free);
- memset(key, 0, sizeof(key));
- gf_proc_dump_build_key(key, prefix, "refcount");
- gf_proc_dump_write(key, "%d", fdtable->refcount);
- gf_proc_dump_build_key(key, prefix, "maxfds");
- gf_proc_dump_write(key, "%d", fdtable->max_fds);
- gf_proc_dump_build_key(key, prefix, "first_free");
- gf_proc_dump_write(key, "%d", fdtable->first_free);
-
- for ( i = 0 ; i < fdtable->max_fds; i++) {
- if (GF_FDENTRY_ALLOCATED ==
- fdtable->fdentries[i].next_free) {
- gf_proc_dump_build_key(key, prefix, "fdentry[%d]", i);
- gf_proc_dump_add_section(key);
- fdentry_dump(&fdtable->fdentries[i], key);
- }
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (GF_FDENTRY_ALLOCATED == fdtable->fdentries[i].next_free) {
+ gf_proc_dump_build_key(key, prefix, "fdentry[%d]", i);
+ gf_proc_dump_add_section("%s", key);
+ fdentry_dump(&fdtable->fdentries[i], key);
}
+ }
- pthread_mutex_unlock(&fdtable->lock);
+ pthread_rwlock_unlock(&fdtable->lock);
out:
- if (ret != 0)
- gf_proc_dump_write ("Unable to dump the fdtable",
- "(Lock acquistion failed) %p", fdtable);
- return;
+ if (ret != 0)
+ gf_proc_dump_write("Unable to dump the fdtable",
+ "(Lock acquistion failed) %p", fdtable);
+ return;
}
-
void
-fd_ctx_dump (fd_t *fd, char *prefix)
+fd_ctx_dump(fd_t *fd, char *prefix)
{
- struct _fd_ctx *fd_ctx = NULL;
- xlator_t *xl = NULL;
- int i = 0;
-
-
- if ((fd == NULL) || (fd->_ctx == NULL)) {
- goto out;
- }
-
- LOCK (&fd->lock);
- {
- if (fd->_ctx != NULL) {
- 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->xl_count; i++) {
- fd_ctx[i] = fd->_ctx[i];
- }
- }
- }
+ struct _fd_ctx *fd_ctx = NULL;
+ xlator_t *xl = NULL;
+ int i = 0;
+
+ if ((fd == NULL) || (fd->_ctx == NULL)) {
+ goto out;
+ }
+
+ LOCK(&fd->lock);
+ {
+ if (fd->_ctx != NULL) {
+ 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->xl_count; i++) {
+ fd_ctx[i] = fd->_ctx[i];
+ }
+ }
+ }
unlock:
- UNLOCK (&fd->lock);
+ UNLOCK(&fd->lock);
- if (fd_ctx == NULL) {
- goto out;
- }
+ if (fd_ctx == NULL) {
+ goto out;
+ }
- 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)
- xl->dumpops->fdctx (xl, fd);
- }
+ 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)
+ xl->dumpops->fdctx(xl, fd);
}
+ }
out:
- GF_FREE (fd_ctx);
+ GF_FREE(fd_ctx);
- return;
+ return;
}
void
-fdentry_dump_to_dict (fdentry_t *fdentry, char *prefix, dict_t *dict,
- int *openfds)
+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;
-}
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+ int ret = -1;
-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 (!fdentry)
+ return;
+ if (!dict)
+ return;
- if (!fdtable)
- return;
- if (!dict)
- return;
+ if (GF_FDENTRY_ALLOCATED != fdentry->next_free)
+ return;
- ret = pthread_mutex_trylock (&fdtable->lock);
+ if (fdentry->fd) {
+ snprintf(key, sizeof(key), "%s.pid", prefix);
+ ret = dict_set_uint64(dict, key, fdentry->fd->pid);
if (ret)
- goto out;
+ return;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.fdtable.refcount", prefix);
- ret = dict_set_int32 (dict, key, fdtable->refcount);
+ snprintf(key, sizeof(key), "%s.refcount", prefix);
+ ret = dict_set_int32(dict, key, GF_ATOMIC_GET(fdentry->fd->refcount));
if (ret)
- goto out;
+ return;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.fdtable.maxfds", prefix);
- ret = dict_set_uint32 (dict, key, fdtable->max_fds);
+ snprintf(key, sizeof(key), "%s.flags", prefix);
+ ret = dict_set_int32(dict, key, fdentry->fd->flags);
if (ret)
- goto out;
+ return;
- 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;
+ (*openfds)++;
+ }
+ return;
+}
- 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);
- }
+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_rwlock_tryrdlock(&fdtable->lock);
+ if (ret)
+ return;
+
+ snprintf(key, sizeof(key), "%s.fdtable.refcount", prefix);
+ ret = dict_set_int32(dict, key, fdtable->refcount);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%s.fdtable.maxfds", prefix);
+ ret = dict_set_uint32(dict, key, fdtable->max_fds);
+ if (ret)
+ goto out;
+
+ 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) {
+ 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);
+ snprintf(key, sizeof(key), "%s.fdtable.openfds", prefix);
+ ret = dict_set_int32(dict, key, openfds);
+ if (ret)
+ goto out;
out:
- pthread_mutex_unlock (&fdtable->lock);
- return;
+ pthread_rwlock_unlock(&fdtable->lock);
+ return;
}
diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h
deleted file mode 100644
index a6dc48a0b0e..00000000000
--- a/libglusterfs/src/fd.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- 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_H
-#define _FD_H
-
-#include "list.h"
-#include <sys/types.h>
-#include <unistd.h>
-#include "glusterfs.h"
-#include "locking.h"
-#include "fd-lk.h"
-#include "common-utils.h"
-
-#define GF_ANON_FD_NO -2
-#define GF_ANON_FD_FLAGS (O_RDWR|O_LARGEFILE)
-
-struct _inode;
-struct _dict;
-struct fd_lk_ctx;
-
-struct _fd_ctx {
- union {
- uint64_t key;
- void *xl_key;
- };
- union {
- uint64_t value1;
- void *ptr1;
- };
-};
-
-struct _fd {
- uint64_t pid;
- int32_t flags;
- int32_t refcount;
- struct list_head inode_list;
- struct _inode *inode;
- gf_lock_t lock; /* used ONLY for manipulating
- '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; /* fd which does not have counterpart open
- fd on backend (server for client, posix
- for server). */
-};
-typedef struct _fd fd_t;
-
-
-struct fd_table_entry {
- fd_t *fd;
- int next_free;
-};
-typedef struct fd_table_entry fdentry_t;
-
-
-struct _fdtable {
- int refcount;
- uint32_t max_fds;
- pthread_mutex_t lock;
- fdentry_t *fdentries;
- int first_free;
-};
-typedef struct _fdtable fdtable_t;
-
-
-/* Signifies no more entries in the fd table. */
-#define GF_FDTABLE_END -1
-
-/* This is used to invalidated
- * the next_free value in an fdentry that has been allocated
- */
-#define GF_FDENTRY_ALLOCATED -2
-
-#include "logging.h"
-#include "xlator.h"
-
-
-void
-gf_fd_put (fdtable_t *fdtable, int32_t fd);
-
-
-fd_t *
-gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd);
-
-
-fdtable_t *
-gf_fd_fdtable_alloc (void);
-
-
-int
-gf_fd_unused_get (fdtable_t *fdtable, fd_t *fdptr);
-
-
-fdentry_t *
-gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count);
-
-
-void
-gf_fd_fdtable_destroy (fdtable_t *fdtable);
-
-
-fd_t *
-__fd_ref (fd_t *fd);
-
-
-fd_t *
-fd_ref (fd_t *fd);
-
-
-fd_t *
-__fd_unref (fd_t *fd);
-
-void
-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_lookup_anonymous (inode_t *inode);
-
-fd_t *
-fd_anonymous (inode_t *inode);
-
-
-gf_boolean_t
-fd_is_anonymous (fd_t *fd);
-
-
-uint8_t
-fd_list_empty (struct _inode *inode);
-
-
-fd_t *
-fd_bind (fd_t *fd);
-
-
-int
-fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value);
-
-
-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);
-
-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);
-
-
-int
-__fd_ctx_get (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);
-
-
-void
-gf_fdptr_put (fdtable_t *fdtable, fd_t *fd);
-
-#endif /* _FD_H */
diff --git a/libglusterfs/src/gen-defaults.py b/libglusterfs/src/gen-defaults.py
new file mode 100755
index 00000000000..e31d3a9fe8a
--- /dev/null
+++ b/libglusterfs/src/gen-defaults.py
@@ -0,0 +1,81 @@
+#!/usr/bin/python3
+
+from __future__ import print_function
+import sys
+from generator import ops, fop_subs, cbk_subs, generate
+
+FAILURE_CBK_TEMPLATE = """
+int32_t
+default_@NAME@_failure_cbk (call_frame_t *frame, int32_t op_errno)
+{
+ STACK_UNWIND_STRICT (@NAME@, frame, -1, op_errno, @ERROR_ARGS@);
+ return 0;
+}
+"""
+
+CBK_RESUME_TEMPLATE = """
+int32_t
+default_@NAME@_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, @LONG_ARGS@)
+{
+ STACK_UNWIND_STRICT (@NAME@, frame, op_ret, op_errno,
+ @SHORT_ARGS@);
+ return 0;
+}
+"""
+
+CBK_TEMPLATE = """
+int32_t
+default_@NAME@_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, @LONG_ARGS@)
+{
+ STACK_UNWIND_STRICT (@NAME@, frame, op_ret, op_errno,
+ @SHORT_ARGS@);
+ return 0;
+}
+"""
+
+RESUME_TEMPLATE = """
+int32_t
+default_@NAME@_resume (call_frame_t *frame, xlator_t *this, @LONG_ARGS@)
+{
+ STACK_WIND (frame, default_@NAME@_cbk,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@,
+ @SHORT_ARGS@);
+ return 0;
+}
+"""
+
+FOP_TEMPLATE = """
+int32_t
+default_@NAME@ (
+ call_frame_t *frame,
+ xlator_t *this,
+ @LONG_ARGS@)
+{
+ STACK_WIND_TAIL (frame,
+ FIRST_CHILD(this), FIRST_CHILD(this)->fops->@NAME@,
+ @SHORT_ARGS@);
+ return 0;
+}
+"""
+
+def gen_defaults ():
+ for name in list(ops.keys()):
+ print(generate(FAILURE_CBK_TEMPLATE, name, cbk_subs))
+ for name in list(ops.keys()):
+ print(generate(CBK_RESUME_TEMPLATE, name, cbk_subs))
+ for name in list(ops.keys()):
+ print(generate(CBK_TEMPLATE, name, cbk_subs))
+ for name in list(ops.keys()):
+ print(generate(RESUME_TEMPLATE, name, fop_subs))
+ for name in list(ops.keys()):
+ print(generate(FOP_TEMPLATE, name, fop_subs))
+
+for l in open(sys.argv[1], 'r').readlines():
+ if l.find('#pragma generate') != -1:
+ print("/* BEGIN GENERATED CODE - DO NOT MODIFY */")
+ gen_defaults()
+ print("/* END GENERATED CODE */")
+ else:
+ print(l[:-1])
diff --git a/libglusterfs/src/generator.py b/libglusterfs/src/generator.py
new file mode 100755
index 00000000000..5b7aa4764a0
--- /dev/null
+++ b/libglusterfs/src/generator.py
@@ -0,0 +1,777 @@
+#!/usr/bin/python3
+
+import string
+
+# ops format: 'fop-arg' name type stub-field [nosync]
+# 'cbk-arg' name type
+# 'extra' name type arg-str
+# 'journal' fop-type
+# 'link' inode iatt
+#
+# 'role' indicates the significance of this line to the code generator (sort of
+# our own type).
+#
+# For fop-arg, we first need to know the name and the type of the arg so that
+# we can generate SHORT_ARGS (for function calls) and LONG_ARGS (for
+# declarations). For code that uses stubs, we also need to know the name of
+# the stub field, which might be different than the argument itself. Lastly,
+# for code that uses syncops, we need to know whether whoever wrote the syncop
+# for this fop "forgot" to include this argument. (Editorial: this kind of
+# creeping inconsistency is why we should have used code generation for stubs
+# and syncops as well as defaults all along.) To address this need, we use the
+# optional 'nosync' field for arguments (e.g. mkdir.umask) that we should skip
+# in generated syncop code.
+#
+# 'cbk-arg' is like fop-arg but simpler and used for generating callbacks
+# instead of fop functions.
+#
+# 'extra' is also like fop-arg, but it's another hack for syncops. This time
+# the problem is that some of what would normally be *callback* arguments are
+# instead created in the caller and passed to the syncop. We handle that by
+# adding an entry at the appropriate place in the fop-arg list, with the name
+# and type to generate a declaration and an argument string to generate the
+# actual syncop call.
+#
+# The mere presence of a 'journal' item is sufficient for most of the journal
+# code to recognize that it should do something. However, reconciliation also
+# needs to decide how reconciliation builds the arguments it needs to call down
+# to the syncop layer, based on what's in the journal. To do that, we divide
+# ops into three types and store those types in the ops table. In general,
+# these three types work as follows.
+#
+# For an fd-op, the GFID in the journal is used (in loc.gfid) field to
+# look up an inode, then an anonymous fd is found/created for that inode.
+#
+# For an inode-op, the GFID in the journal is used the same way, but no fd
+# is needed.
+#
+# For an entry-op, the *parent* GFID and name from the journal are used to
+# look up an inode (via loc.pargfid and par.name respectively).
+#
+# The only places this seems to fall down is for link and create. In link,
+# which is generally an entry-op, the source is looked up as though it's an
+# inode-op. In create, we have an fd argument but it's really a return
+# argument so we get a fresh inode instead of looking one up. Those two cases
+# need to be handled as special cases in the reconciliation code.
+#
+# 'link' is (hopefully) the last of the journal/syncop hacks. Much like
+# 'extra', some values that are returned as callback arguments in the normal
+# case are handled differently for syncops. For syncops that create objects
+# (e.g. mkdir) we need to link those objects into our inode table. The 'inode'
+# and 'iatt' fields here give us the information we need to construct the
+# proper inode_link call(s).
+
+ops = {}
+xlator_cbks = {}
+xlator_dumpops = {}
+
+ops['fgetxattr'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'name', 'const char *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'dict', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fsetxattr'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'flags', 'int32_t', 'flags'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['setxattr'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'flags', 'int32_t', 'flags'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['statfs'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'buf', 'struct statvfs *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fsyncdir'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'flags', 'int32_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['opendir'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'fd', 'fd_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fstat'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fsync'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'flags', 'int32_t'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['flush'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['writev'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'vector', 'struct iovec *', 'vector'),
+ ('fop-arg', 'count', 'int32_t'),
+ ('fop-arg', 'off', 'off_t', 'offset'),
+ ('fop-arg', 'flags', 'uint32_t', 'flags'),
+ ('fop-arg', 'iobref', 'struct iobref *'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['readv'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'size', 'size_t'),
+ ('fop-arg', 'offset', 'off_t'),
+ ('fop-arg', 'flags', 'uint32_t'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'vector', 'struct iovec *'),
+ ('cbk-arg', 'count', 'int32_t'),
+ ('cbk-arg', 'stbuf', 'struct iatt *'),
+ ('cbk-arg', 'iobref', 'struct iobref *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['open'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'flags', 'int32_t'),
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'fd', 'fd_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['create'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'flags', 'int32_t', 'flags'),
+ ('fop-arg', 'mode', 'mode_t', 'mode'),
+ ('fop-arg', 'umask', 'mode_t', 'umask', 'nosync'),
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'fd', 'fd_t *'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+ ('link', 'loc.inode', '&iatt'),
+)
+
+ops['link'] = (
+ ('fop-arg', 'oldloc', 'loc_t *', 'loc'),
+ ('fop-arg', 'newloc', 'loc_t *', 'loc2'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['rename'] = (
+ ('fop-arg', 'oldloc', 'loc_t *', 'loc'),
+ ('fop-arg', 'newloc', 'loc_t *', 'loc2'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preoldparent', 'struct iatt *'),
+ ('cbk-arg', 'postoldparent', 'struct iatt *'),
+ ('cbk-arg', 'prenewparent', 'struct iatt *'),
+ ('cbk-arg', 'postnewparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['symlink'] = (
+ ('fop-arg', 'linkpath', 'const char *', 'linkname'),
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'umask', 'mode_t', 'mode', 'nosync'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['rmdir'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'flags', 'int32_t', 'flags'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['unlink'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'flags', 'int32_t', 'flags', 'nosync'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['mkdir'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'mode', 'mode_t', 'mode'),
+ ('fop-arg', 'umask', 'mode_t', 'umask', 'nosync'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+ ('link', 'loc.inode', '&iatt'),
+)
+
+ops['mknod'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'mode', 'mode_t', 'mode'),
+ ('fop-arg', 'rdev', 'dev_t', 'rdev'),
+ ('fop-arg', 'umask', 'mode_t', 'umask', 'nosync'),
+ ('extra', 'iatt', 'struct iatt', '&iatt'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'entry-op'),
+)
+
+ops['readlink'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'size', 'size_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'path', 'const char *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['access'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'mask', 'int32_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['ftruncate'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['getxattr'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'name', 'const char *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'dict', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['xattrop'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'flags', 'gf_xattrop_flags_t', 'optype'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'dict', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['fxattrop'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'flags', 'gf_xattrop_flags_t', 'optype'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'dict', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['removexattr'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'name', 'const char *', 'name'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['fremovexattr'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'name', 'const char *', 'name'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['lk'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'cmd', 'int32_t'),
+ ('fop-arg', 'lock', 'struct gf_flock *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'lock', 'struct gf_flock *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['inodelk'] = (
+ ('fop-arg', 'volume', 'const char *'),
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'cmd', 'int32_t'),
+ ('fop-arg', 'lock', 'struct gf_flock *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['finodelk'] = (
+ ('fop-arg', 'volume', 'const char *'),
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'cmd', 'int32_t'),
+ ('fop-arg', 'lock', 'struct gf_flock *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['entrylk'] = (
+ ('fop-arg', 'volume', 'const char *'),
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'basename', 'const char *'),
+ ('fop-arg', 'cmd', 'entrylk_cmd'),
+ ('fop-arg', 'type', 'entrylk_type'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['fentrylk'] = (
+ ('fop-arg', 'volume', 'const char *'),
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'basename', 'const char *'),
+ ('fop-arg', 'cmd', 'entrylk_cmd'),
+ ('fop-arg', 'type', 'entrylk_type'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['rchecksum'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'offset', 'off_t'),
+ ('fop-arg', 'len', 'int32_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'weak_cksum', 'uint32_t'),
+ ('cbk-arg', 'strong_cksum', 'uint8_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['readdir'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'size', 'size_t'),
+ ('fop-arg', 'off', 'off_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'entries', 'gf_dirent_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['readdirp'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'size', 'size_t'),
+ ('fop-arg', 'off', 'off_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'entries', 'gf_dirent_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['setattr'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'stbuf', 'struct iatt *', 'stat'),
+ ('fop-arg', 'valid', 'int32_t', 'valid'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'statpre', 'struct iatt *'),
+ ('cbk-arg', 'statpost', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['truncate'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'inode-op'),
+)
+
+ops['stat'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['lookup'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ # We could add xdata everywhere automatically if somebody hadn't put
+ # something after it here.
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+)
+
+ops['fsetattr'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'stbuf', 'struct iatt *', 'stat'),
+ ('fop-arg', 'valid', 'int32_t', 'valid'),
+ ('extra', 'preop', 'struct iatt', '&preop'),
+ ('extra', 'postop', 'struct iatt', '&postop'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'statpre', 'struct iatt *'),
+ ('cbk-arg', 'statpost', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['fallocate'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'keep_size', 'int32_t', 'mode'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ ('fop-arg', 'len', 'size_t', 'size'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'pre', 'struct iatt *'),
+ ('cbk-arg', 'post', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['discard'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ ('fop-arg', 'len', 'size_t', 'size'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'pre', 'struct iatt *'),
+ ('cbk-arg', 'post', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['zerofill'] = (
+ ('fop-arg', 'fd', 'fd_t *', 'fd'),
+ ('fop-arg', 'offset', 'off_t', 'offset'),
+ # As e.g. fallocate/discard (above) "len" should really be a size_t.
+ ('fop-arg', 'len', 'off_t', 'size'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'pre', 'struct iatt *'),
+ ('cbk-arg', 'post', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['ipc'] = (
+ ('fop-arg', 'op', 'int32_t'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+ ('journal', 'fd-op'),
+)
+
+ops['seek'] = (
+ ('fop-arg', 'fd', 'fd_t *'),
+ ('fop-arg', 'offset', 'off_t'),
+ ('fop-arg', 'what', 'gf_seek_what_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'offset', 'off_t'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['getspec'] = (
+ ('fop-arg', 'key', 'const char *'),
+ ('fop-arg', 'flags', 'int32_t'),
+ ('cbk-arg', 'spec_data', 'char *'),
+)
+
+ops['lease'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'lease', 'struct gf_lease *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'lease', 'struct gf_lease *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['getactivelk'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'locklist', 'lock_migration_info_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['setactivelk'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'locklist', 'lock_migration_info_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['put'] = (
+ ('fop-arg', 'loc', 'loc_t *', 'loc'),
+ ('fop-arg', 'mode', 'mode_t', 'mode'),
+ ('fop-arg', 'umask', 'mode_t', 'umask'),
+ ('fop-arg', 'flags', 'uint32_t', 'flags'),
+ ('fop-arg', 'vector', 'struct iovec *', 'vector'),
+ ('fop-arg', 'count', 'int32_t'),
+ ('fop-arg', 'off', 'off_t', 'offset'),
+ ('fop-arg', 'iobref', 'struct iobref *'),
+ ('fop-arg', 'dict', 'dict_t *', 'xattr'),
+ ('fop-arg', 'xdata', 'dict_t *', 'xdata'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'preparent', 'struct iatt *'),
+ ('cbk-arg', 'postparent', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['icreate'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'mode', 'mode_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['namelink'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['copy_file_range'] = (
+ ('fop-arg', 'fd_in', 'fd_t *'),
+ ('fop-arg', 'off_in', 'off64_t '),
+ ('fop-arg', 'fd_out', 'fd_t *'),
+ ('fop-arg', 'off_out', 'off64_t '),
+ ('fop-arg', 'len', 'size_t'),
+ ('fop-arg', 'flags', 'uint32_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'stbuf', 'struct iatt *'),
+ ('cbk-arg', 'prebuf_dst', 'struct iatt *'),
+ ('cbk-arg', 'postbuf_dst', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+#####################################################################
+xlator_cbks['forget'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'inode', 'inode_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['release'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['releasedir'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['invalidate'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'inode', 'inode_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['client_destroy'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'client', 'client_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['client_disconnect'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'client', 'client_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_cbks['ictxmerge'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('fn-arg', 'inode', 'inode_t *'),
+ ('fn-arg', 'linked_inode', 'inode_t *'),
+ ('ret-val', 'void', ''),
+)
+
+#####################################################################
+xlator_dumpops['priv'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['inode'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['fd'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['inodectx'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'ino', 'inode_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['fdctx'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['priv_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['inode_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['fd_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['inodectx_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'ino', 'inode_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['fdctx_to_dict'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('fn-arg', 'fd', 'fd_t *'),
+ ('fn-arg', 'dict', 'dict_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+xlator_dumpops['history'] = (
+ ('fn-arg', 'this', 'xlator_t *'),
+ ('ret-val', 'int32_t', '0'),
+)
+
+def get_error_arg (type_str):
+ if type_str.find(" *") != -1:
+ return "NULL"
+ return "-1"
+
+def get_subs (names, types, cbktypes=None):
+ sdict = {}
+ sdict["@SHORT_ARGS@"] = ', '.join(names)
+ # Convert two separate tuples to one of (name, type) sub-tuples.
+ as_tuples = list(zip(types, names))
+ # Convert each sub-tuple into a "type name" string.
+ as_strings = [' '.join(item) for item in as_tuples]
+ # Join all of those into one big string.
+ sdict["@LONG_ARGS@"] = ',\n\t'.join(as_strings)
+ # So much more readable than string.join(map(string.join,zip(...))))
+ sdict["@ERROR_ARGS@"] = ', '.join(list(map(get_error_arg, types)))
+ if cbktypes is not None:
+ sdict["@CBK_ERROR_ARGS@"] = ', '.join(list(map(get_error_arg, cbktypes)))
+ return sdict
+
+def generate (tmpl, name, subs):
+ text = tmpl.replace("@NAME@", name)
+ if name == "writev":
+ # More spurious inconsistency.
+ text = text.replace("@UPNAME@", "WRITE")
+ elif name == "readv":
+ text = text.replace("@UPNAME@", "READ")
+ else:
+ text = text.replace("@UPNAME@", name.upper())
+ for old, new in subs[name].items():
+ text = text.replace(old, new)
+ # TBD: reindent/reformat the result for maximum readability.
+ return text
+
+fop_subs = {}
+cbk_subs = {}
+
+for name, args in ops.items():
+
+ # Create the necessary substitution strings for fops.
+ arg_names = [ a[1] for a in args if a[0] == 'fop-arg']
+ arg_types = [ a[2] for a in args if a[0] == 'fop-arg']
+ cbk_types = [ a[2] for a in args if a[0] == 'cbk-arg']
+ fop_subs[name] = get_subs(arg_names, arg_types, cbk_types)
+
+ # Same thing for callbacks.
+ arg_names = [ a[1] for a in args if a[0] == 'cbk-arg']
+ arg_types = [ a[2] for a in args if a[0] == 'cbk-arg']
+ cbk_subs[name] = get_subs(arg_names, arg_types)
+
+ # Callers can add other subs to these tables, or even create their
+ # own tables, using these same techniques, and then pass the result
+ # to generate() which would Do The Right Thing with them.
diff --git a/libglusterfs/src/gf-dirent.c b/libglusterfs/src/gf-dirent.c
index 3cbef6605db..a809efc97ef 100644
--- a/libglusterfs/src/gf-dirent.c
+++ b/libglusterfs/src/gf-dirent.c
@@ -8,236 +8,232 @@
cases as published by the Free Software Foundation.
*/
-
-
#include <stdio.h>
#include <string.h>
#include <stdint.h>
-#include "compat.h"
-#include "xlator.h"
+#include "glusterfs/compat.h"
+#include "glusterfs/syncop.h"
#define ONE 1ULL
#define PRESENT_D_OFF_BITS 63
#define BACKEND_D_OFF_BITS 63
#define TOP_BIT (ONE << (PRESENT_D_OFF_BITS - 1))
#define MASK (~0ULL)
-#define SHIFT_BITS (max (0, (BACKEND_D_OFF_BITS - PRESENT_D_OFF_BITS + 1)))
+#define SHIFT_BITS (max(0, (BACKEND_D_OFF_BITS - PRESENT_D_OFF_BITS + 1)))
#define PRESENT_MASK (MASK >> (64 - PRESENT_D_OFF_BITS))
static uint64_t
-bits_for (uint64_t num)
+bits_for(uint64_t num)
{
- uint64_t bits = 0, ctrl = 1;
+ uint64_t bits = 0, ctrl = 1;
- while (ctrl < num) {
- ctrl *= 2;
- bits++;
- }
+ while (ctrl < num) {
+ ctrl *= 2;
+ bits++;
+ }
- return bits;
+ return bits;
}
int
-gf_deitransform(xlator_t *this,
- uint64_t offset)
+gf_deitransform(xlator_t *this, uint64_t offset)
{
- int cnt = 0;
- int max = 0;
- int max_bits = 0;
- uint64_t off_mask = 0;
- uint64_t host_mask = 0;
-
- max = glusterfs_get_leaf_count(this->graph);
-
- if (max == 1) {
- cnt = 0;
- goto out;
- }
-
- if (offset & TOP_BIT) {
- /* HUGE d_off */
- max_bits = bits_for (max);
- off_mask = (MASK << max_bits);
- host_mask = ~(off_mask);
-
- cnt = offset & host_mask;
- } else {
- /* small d_off */
- cnt = offset % max;
- }
+ int cnt = 0;
+ int max = 0;
+ int max_bits = 0;
+ uint64_t off_mask = 0;
+ uint64_t host_mask = 0;
+
+ max = glusterfs_get_leaf_count(this->graph);
+
+ if (max == 1) {
+ cnt = 0;
+ goto out;
+ }
+
+ if (offset & TOP_BIT) {
+ /* HUGE d_off */
+ max_bits = bits_for(max);
+ off_mask = (MASK << max_bits);
+ host_mask = ~(off_mask);
+
+ cnt = offset & host_mask;
+ } else {
+ /* small d_off */
+ cnt = offset % max;
+ }
out:
- return cnt;
+ return cnt;
}
uint64_t
-gf_dirent_orig_offset(xlator_t *this,
- uint64_t offset)
+gf_dirent_orig_offset(xlator_t *this, uint64_t offset)
{
- int max = 0;
- int max_bits = 0;
- uint64_t off_mask = 0;
- uint64_t orig_offset;
-
- max = glusterfs_get_leaf_count(this->graph);
-
- if (max == 1) {
- orig_offset = offset;
- goto out;
- }
-
- if (offset & TOP_BIT) {
- /* HUGE d_off */
- max_bits = bits_for (max);
- off_mask = (MASK << max_bits);
- orig_offset = ((offset & ~TOP_BIT) & off_mask) << SHIFT_BITS;
- } else {
- /* small d_off */
- orig_offset = offset / max;
- }
+ int max = 0;
+ int max_bits = 0;
+ uint64_t off_mask = 0;
+ uint64_t orig_offset;
+
+ max = glusterfs_get_leaf_count(this->graph);
+
+ if (max == 1) {
+ orig_offset = offset;
+ goto out;
+ }
+
+ if (offset & TOP_BIT) {
+ /* HUGE d_off */
+ max_bits = bits_for(max);
+ off_mask = (MASK << max_bits);
+ orig_offset = ((offset & ~TOP_BIT) & off_mask) << SHIFT_BITS;
+ } else {
+ /* small d_off */
+ orig_offset = offset / max;
+ }
out:
- return orig_offset;
+ return orig_offset;
}
int
-gf_itransform (xlator_t *this, uint64_t x, uint64_t *y_p, int client_id)
+gf_itransform(xlator_t *this, uint64_t x, uint64_t *y_p, int client_id)
{
- int max = 0;
- uint64_t y = 0;
- uint64_t hi_mask = 0;
- uint64_t off_mask = 0;
- int max_bits = 0;
-
- if (x == ((uint64_t) -1)) {
- y = (uint64_t) -1;
- goto out;
- }
-
- if (!x) {
- y = 0;
- goto out;
- }
-
- max = glusterfs_get_leaf_count(this->graph);
-
- if (max == 1) {
- y = x;
- goto out;
- }
-
- max_bits = bits_for (max);
-
- hi_mask = ~(PRESENT_MASK >> (max_bits + 1));
-
- if (x & hi_mask) {
- /* HUGE d_off */
- off_mask = MASK << max_bits;
- y = TOP_BIT | ((x >> SHIFT_BITS) & off_mask) | client_id;
- } else {
- /* small d_off */
- y = ((x * max) + client_id);
- }
+ int max = 0;
+ uint64_t y = 0;
+ uint64_t hi_mask = 0;
+ uint64_t off_mask = 0;
+ int max_bits = 0;
+
+ if (x == ((uint64_t)-1)) {
+ y = (uint64_t)-1;
+ goto out;
+ }
+
+ if (!x) {
+ y = 0;
+ goto out;
+ }
+
+ max = glusterfs_get_leaf_count(this->graph);
+
+ if (max == 1) {
+ y = x;
+ goto out;
+ }
+
+ max_bits = bits_for(max);
+
+ hi_mask = ~(PRESENT_MASK >> (max_bits + 1));
+
+ if (x & hi_mask) {
+ /* HUGE d_off */
+ off_mask = MASK << max_bits;
+ y = TOP_BIT | ((x >> SHIFT_BITS) & off_mask) | client_id;
+ } else {
+ /* small d_off */
+ y = ((x * max) + client_id);
+ }
out:
- if (y_p)
- *y_p = y;
+ if (y_p)
+ *y_p = y;
- return 0;
+ return 0;
}
gf_dirent_t *
-gf_dirent_for_name (const char *name)
+gf_dirent_for_name(const char *name)
{
- gf_dirent_t *gf_dirent = NULL;
+ gf_dirent_t *gf_dirent = NULL;
- /* TODO: use mem-pool */
- gf_dirent = GF_CALLOC (gf_dirent_size (name), 1,
- gf_common_mt_gf_dirent_t);
- if (!gf_dirent)
- return NULL;
+ /* TODO: use mem-pool */
+ gf_dirent = GF_CALLOC(gf_dirent_size(name), 1, gf_common_mt_gf_dirent_t);
+ if (!gf_dirent)
+ return NULL;
- INIT_LIST_HEAD (&gf_dirent->list);
- strcpy (gf_dirent->d_name, name);
+ INIT_LIST_HEAD(&gf_dirent->list);
+ strcpy(gf_dirent->d_name, name);
- gf_dirent->d_off = 0;
- gf_dirent->d_ino = -1;
- gf_dirent->d_type = 0;
- gf_dirent->d_len = strlen (name);
+ gf_dirent->d_off = 0;
+ gf_dirent->d_ino = -1;
+ gf_dirent->d_type = 0;
+ gf_dirent->d_len = strlen(name);
- return gf_dirent;
+ return gf_dirent;
}
void
-gf_dirent_entry_free (gf_dirent_t *entry)
+gf_dirent_entry_free(gf_dirent_t *entry)
{
- if (!entry)
- return;
+ if (!entry)
+ return;
- if (entry->dict)
- dict_unref (entry->dict);
- if (entry->inode)
- inode_unref (entry->inode);
+ if (entry->dict)
+ dict_unref(entry->dict);
+ if (entry->inode)
+ inode_unref(entry->inode);
- list_del_init (&entry->list);
- GF_FREE (entry);
+ list_del_init(&entry->list);
+ GF_FREE(entry);
}
void
-gf_dirent_free (gf_dirent_t *entries)
+gf_dirent_free(gf_dirent_t *entries)
{
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
- if (!entries)
- return;
+ if (!entries)
+ return;
- if (list_empty (&entries->list))
- return;
+ if (list_empty(&entries->list))
+ return;
- list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- gf_dirent_entry_free (entry);
- }
+ list_for_each_entry_safe(entry, tmp, &entries->list, list)
+ {
+ gf_dirent_entry_free(entry);
+ }
}
gf_dirent_t *
-entry_copy (gf_dirent_t *source)
+entry_copy(gf_dirent_t *source)
{
- gf_dirent_t *sink = NULL;
+ gf_dirent_t *sink = NULL;
- sink = gf_dirent_for_name (source->d_name);
- if (!sink)
- return NULL;
+ sink = gf_dirent_for_name(source->d_name);
+ if (!sink)
+ return NULL;
- sink->d_off = source->d_off;
- sink->d_ino = source->d_ino;
- sink->d_type = source->d_type;
- sink->d_stat = source->d_stat;
- sink->d_len = source->d_len;
+ sink->d_off = source->d_off;
+ sink->d_ino = source->d_ino;
+ sink->d_type = source->d_type;
+ sink->d_stat = source->d_stat;
+ sink->d_len = source->d_len;
- if (source->inode)
- sink->inode = inode_ref (source->inode);
+ if (source->inode)
+ sink->inode = inode_ref(source->inode);
- if (source->dict)
- sink->dict = dict_ref (source->dict);
- return sink;
+ if (source->dict)
+ sink->dict = dict_ref(source->dict);
+ return sink;
}
void
-gf_link_inode_from_dirent (xlator_t *this, inode_t *parent, gf_dirent_t *entry)
+gf_link_inode_from_dirent(xlator_t *this, inode_t *parent, gf_dirent_t *entry)
{
- inode_t *link_inode = NULL;
- inode_t *tmp = NULL;
-
- if (!entry->inode)
- return;
- link_inode = inode_link (entry->inode, parent,
- entry->d_name, &entry->d_stat);
- if (!link_inode)
- return;
-
- inode_lookup (link_inode);
- tmp = entry->inode;
- entry->inode = link_inode;
- inode_unref (tmp);
+ inode_t *link_inode = NULL;
+ inode_t *tmp = NULL;
+
+ if (!entry->inode)
+ return;
+ link_inode = inode_link(entry->inode, parent, entry->d_name,
+ &entry->d_stat);
+ if (!link_inode)
+ return;
+
+ inode_lookup(link_inode);
+ tmp = entry->inode;
+ entry->inode = link_inode;
+ inode_unref(tmp);
}
/* TODO: Currently, with this function, we will be breaking the
@@ -246,14 +242,60 @@ gf_link_inode_from_dirent (xlator_t *this, inode_t *parent, gf_dirent_t *entry)
Need more thoughts before finalizing this function
*/
int
-gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent,
- gf_dirent_t *entries)
+gf_link_inodes_from_dirent(xlator_t *this, inode_t *parent,
+ gf_dirent_t *entries)
{
- gf_dirent_t *entry = NULL;
+ gf_dirent_t *entry = NULL;
- list_for_each_entry (entry, &entries->list, list) {
- gf_link_inode_from_dirent (this, parent, entry);
- }
+ list_for_each_entry(entry, &entries->list, list)
+ {
+ gf_link_inode_from_dirent(this, parent, entry);
+ }
+
+ return 0;
+}
- return 0;
+int
+gf_fill_iatt_for_dirent(gf_dirent_t *entry, inode_t *parent, xlator_t *subvol)
+{
+ loc_t loc = {
+ 0,
+ };
+ int ret = -1;
+ char *path = NULL;
+ struct iatt iatt = {
+ 0,
+ };
+
+ loc.inode = inode_grep(parent->table, parent, entry->d_name);
+ if (!loc.inode) {
+ loc.inode = inode_new(parent->table);
+ gf_uuid_copy(loc.inode->gfid, entry->d_stat.ia_gfid);
+ }
+
+ gf_uuid_copy(loc.pargfid, parent->gfid);
+ loc.name = entry->d_name;
+ loc.parent = inode_ref(parent);
+ ret = inode_path(loc.parent, entry->d_name, &path);
+ loc.path = path;
+ if (ret < 0)
+ goto out;
+
+ ret = syncop_lookup(subvol, &loc, &iatt, NULL, NULL, NULL);
+ if (ret)
+ goto out;
+
+ entry->d_stat = iatt;
+ entry->inode = inode_ref(loc.inode);
+ /* We don't need to link inode here, because as part of readdirp_cbk
+ * we will link all dirents.
+ *
+ * Since we did a proper lookup, we don't need to set need_lookup
+ * flag.
+ */
+
+ ret = 0;
+out:
+ loc_wipe(&loc);
+ return ret;
}
diff --git a/libglusterfs/src/gf-dirent.h b/libglusterfs/src/gf-dirent.h
deleted file mode 100644
index 098a66ace15..00000000000
--- a/libglusterfs/src/gf-dirent.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- 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 _GF_DIRENT_H
-#define _GF_DIRENT_H
-
-#include "iatt.h"
-#include "inode.h"
-
-#define gf_dirent_size(name) (sizeof (gf_dirent_t) + strlen (name) + 1)
-
-int
-gf_deitransform(xlator_t *this, uint64_t y);
-
-int
-gf_itransform (xlator_t *this, uint64_t x, uint64_t *y_p, int client_id);
-
-uint64_t
-gf_dirent_orig_offset (xlator_t *this, uint64_t offset);
-
-
-struct _dir_entry_t {
- struct _dir_entry_t *next;
- char *name;
- char *link;
- struct iatt buf;
-};
-
-
-struct _gf_dirent_t {
- union {
- struct list_head list;
- struct {
- struct _gf_dirent_t *next;
- struct _gf_dirent_t *prev;
- };
- };
- uint64_t d_ino;
- uint64_t d_off;
- uint32_t d_len;
- uint32_t d_type;
- struct iatt d_stat;
- dict_t *dict;
- inode_t *inode;
- char d_name[];
-};
-
-#define DT_ISDIR(mode) (mode == DT_DIR)
-
-gf_dirent_t *gf_dirent_for_name (const char *name);
-gf_dirent_t *entry_copy (gf_dirent_t *source);
-void gf_dirent_entry_free (gf_dirent_t *entry);
-void gf_dirent_free (gf_dirent_t *entries);
-int gf_link_inodes_from_dirent (xlator_t *this, inode_t *parent,
- gf_dirent_t *entries);
-
-void
-gf_link_inode_from_dirent (xlator_t *this, inode_t *parent, gf_dirent_t *entry);
-#endif /* _GF_DIRENT_H */
diff --git a/libglusterfs/src/gfdb/Makefile.am b/libglusterfs/src/gfdb/Makefile.am
deleted file mode 100644
index 30d1b7bcdde..00000000000
--- a/libglusterfs/src/gfdb/Makefile.am
+++ /dev/null
@@ -1,33 +0,0 @@
-libgfdb_la_CFLAGS = -Wall $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \
- $(SQLITE_CFLAGS) -DDATADIR=\"$(localstatedir)\"
-
-libgfdb_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 -fpic \
- -I$(top_srcdir)/libglusterfs/src \
- -DDATADIR=\"$(localstatedir)\"
-
-libgfdb_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
- $(SQLITE_LIBS) $(UUID_LIBS)
-
-libgfdb_la_LDFLAGS = $(GF_LDFLAGS) -version-info $(LIBGLUSTERFS_LT_VERSION)
-
-libgfdbdir = $(includedir)/glusterfs/gfdb
-
-if BUILD_GFDB
- lib_LTLIBRARIES = libgfdb.la
-endif
-
-CONTRIB_BUILDDIR = $(top_builddir)/contrib
-
-libgfdb_la_SOURCES = gfdb_data_store.c gfdb_sqlite3_helper.c\
- gfdb_sqlite3.c
-
-noinst_HEADERS = gfdb_data_store.h gfdb_data_store_types.h gfdb_sqlite3_helper.h\
- gfdb_sqlite3.h gfdb_mem-types.h
-
-libgfdb_HEADERS = gfdb_data_store.h gfdb_data_store_types.h \
- gfdb_sqlite3.h gfdb_mem-types.h gfdb_sqlite3_helper.c
-
-CLEANFILES =
-
-$(top_builddir)/libglusterfs/src/libglusterfs.la:
- $(MAKE) -C $(top_builddir)/libglusterfs/src/ all
diff --git a/libglusterfs/src/gfdb/gfdb_data_store.c b/libglusterfs/src/gfdb/gfdb_data_store.c
deleted file mode 100644
index e409e0ddc69..00000000000
--- a/libglusterfs/src/gfdb/gfdb_data_store.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- Copyright (c) 2015 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 "gfdb_sqlite3.h"
-#include "gfdb_data_store.h"
-#include "list.h"
-#include "libglusterfs-messages.h"
-
-/******************************************************************************
- *
- * Database Connection utils/internals
- *
- * ****************************************************************************/
-
-/* GFDB Connection Node:
- * ~~~~~~~~~~~~~~~~~~~~
- * Represents the connection to the database while using libgfdb
- * The connection node is not thread safe as far as fini_db is concerned.
- * You can use a single connection node
- * to do multithreaded db operations like insert/delete/find of records.
- * But you need to wait for all the operating threads to complete i.e
- * pthread_join() and then do fini_db() to kill the connection node.
- * gfdb_conn_node_t is an opaque structure.
- * */
-struct gfdb_conn_node_t {
- gfdb_connection_t gfdb_connection;
- struct list_head conn_list;
-};
-
-
-/*
- * db_conn_list is the circular linked list which
- * will have all the database connections for the process
- *
- * */
-static gfdb_conn_node_t *db_conn_list;
-
-/*
- * db_conn_mutex is the mutex for db_conn_list
- *
- * */
-static pthread_mutex_t db_conn_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-/*Checks the sanity of the connection node*/
-#define CHECK_CONN_NODE(_conn_node)\
-do {\
- GF_ASSERT (_conn_node);\
- GF_ASSERT (_conn_node->gfdb_connection.gf_db_connection);\
-} while (0)
-
-/* Checks the sanity of the connection node and goto */
-#define CHECK_CONN_NODE_GOTO(_conn_node, label)\
-do {\
- if (!_conn_node) {\
- goto label;\
- };\
- if (!_conn_node->gfdb_connection.gf_db_connection) {\
- goto label;\
- };\
-} while (0)
-
-/*Check if the conn node is first in the list*/
-#define IS_FIRST_NODE(db_conn_list, _conn_node)\
- ((_conn_node == db_conn_list) ? _gf_true : _gf_false)
-
-
-/*Check if the conn node is the only node in the list*/
-#define IS_THE_ONLY_NODE(_conn_node)\
-((_conn_node->conn_list.next == _conn_node->conn_list.prev)\
- ? _gf_true : _gf_false)
-
-
-
-/*Internal Function: Adds connection node to the end of
- * the db connection list.*/
-static int
-add_connection_node (gfdb_conn_node_t *_conn_node) {
- int ret = -1;
-
- GF_ASSERT (_conn_node);
-
- /*Lock the list*/
- ret = pthread_mutex_lock (&db_conn_mutex);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, ret,
- LG_MSG_LOCK_LIST_FAILED, "Failed lock db connection "
- "list %s", strerror(ret));
- ret = -1;
- goto out;
- }
-
- if (db_conn_list == NULL) {
- db_conn_list = _conn_node;
- } else {
- list_add_tail (&_conn_node->conn_list,
- &db_conn_list->conn_list);
- }
-
- /*unlock the list*/
- ret = pthread_mutex_unlock (&db_conn_mutex);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, ret,
- LG_MSG_UNLOCK_LIST_FAILED, "Failed unlock db "
- "connection list %s", strerror(ret));
- ret = -1;
- /*TODO What if the unlock fails.
- * Will it lead to deadlock?
- * Most of the gluster code
- * no check for unlock or destory of mutex!*/
- }
- ret = 0;
-out:
- return ret;
-}
-
-
-/*Internal Function:
- * Delete connection node from the list*/
-static int
-delete_conn_node (gfdb_conn_node_t *_conn_node)
-{
- int ret = -1;
-
- GF_ASSERT (_conn_node);
-
- /*Lock of the list*/
- ret = pthread_mutex_lock (&db_conn_mutex);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, ret,
- LG_MSG_LOCK_LIST_FAILED, "Failed lock on db connection"
- " list %s", strerror(ret));
- goto out;
- }
-
- /*Remove the connection object from list*/
- if (IS_THE_ONLY_NODE(_conn_node)) {
- db_conn_list = NULL;
- GF_FREE (_conn_node);
- } else {
- if (IS_FIRST_NODE(db_conn_list, _conn_node)) {
- db_conn_list = list_entry (db_conn_list->conn_list.next,
- gfdb_conn_node_t,
- conn_list);
- }
- list_del(&_conn_node->conn_list);
- GF_FREE (_conn_node);
- }
-
- /*Release the list lock*/
- ret = pthread_mutex_unlock (&db_conn_mutex);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_WARNING, ret,
- LG_MSG_UNLOCK_LIST_FAILED, "Failed unlock on db "
- "connection list %s", strerror(ret));
- /*TODO What if the unlock fails.
- * Will it lead to deadlock?
- * Most of the gluster code
- * no check for unlock or destory of mutex!*/
- ret = -1;
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
-
-/*Internal function: Used initialize/map db operation of
- * specified type of db plugin*/
-static int
-init_db_operations (gfdb_db_type_t gfdb_db_type,
- gfdb_db_operations_t *gfdb_db_operations) {
-
- int ret = -1;
-
- GF_ASSERT (gfdb_db_operations);
-
- /*Clear the gfdb_db_operations*/
- gfdb_db_operations = memset(gfdb_db_operations, 0,
- sizeof(*gfdb_db_operations));
- switch (gfdb_db_type) {
- case GFDB_SQLITE3:
- gf_sqlite3_fill_db_operations (gfdb_db_operations);
- ret = 0;
- break;
- case GFDB_HYPERDEX:
- case GFDB_HASH_FILE_STORE:
- case GFDB_ROCKS_DB:
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_UNSUPPORTED_PLUGIN, "Plugin not supported");
- break;
- case GFDB_INVALID_DB:
- case GFDB_DB_END:
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_INVALID_DB_TYPE, "Invalid DB Type");
- break;
- }
- return ret;
-}
-
-
-/******************************************************************************
- *
- * LIBGFDB API Functions
- *
- * ****************************************************************************/
-
-
-/*Libgfdb API Function: Used to initialize a db connection
- * (Constructor function for db connection object)
- * Arguments:
- * args : Dictionary containing database specific parameters
- * eg: For sqlite3, pagesize, cachesize, db name, db path
- etc
- * gfdb_db_type : Type of data base used i.e sqlite or hyperdex etc
- * Returns : if successful return the GFDB Connection node to the caller or
- * NULL in case of failure*/
-gfdb_conn_node_t *
-init_db (dict_t *args, gfdb_db_type_t gfdb_db_type)
-{
- int ret = -1;
- gfdb_conn_node_t *_conn_node = NULL;
- gfdb_db_operations_t *db_operations_t = NULL;
-
- /*Create data base connection object*/
- _conn_node = GF_CALLOC (1, sizeof(gfdb_conn_node_t),
- gf_mt_db_conn_node_t);
- if (!_conn_node) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, ENOMEM,
- LG_MSG_NO_MEMORY, "Failed mem alloc for "
- "gfdb_conn_node_t!");
- goto alloc_failed;
- }
-
- /*Init the list component of db conneciton object*/
- INIT_LIST_HEAD (&_conn_node->conn_list);
-
-
- /*Add created connection node to the list*/
- ret = add_connection_node (_conn_node);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_ADD_TO_LIST_FAILED, "Failed to add connection "
- "node to list");
- goto _conn_failed;
- }
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
-
- /*init the db ops object of db connection object*/
- ret = init_db_operations(gfdb_db_type, db_operations_t);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_INIT_DB_FAILED, "Failed initializing database "
- "operation failed.");
- ret = -1;
- goto init_db_failed;
- }
-
- /*Calling the init_db_op of the respected db type*/
- GF_ASSERT (db_operations_t->init_db_op);
- ret = db_operations_t->init_db_op (args, &_conn_node->gfdb_connection.
- gf_db_connection);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_INIT_DB_FAILED, "Failed initializing database");
- ret = -1;
- goto init_db_failed;
- }
- _conn_node->gfdb_connection.gfdb_db_type = gfdb_db_type;
- ret = 0;
-
- return _conn_node;
-
- /*****Error Handling********/
- /* If init_db_operations or init_db of plugin failed delete
- * conn node from the list.
- * connection node will be free by delete_conn_node*/
-init_db_failed:
- ret = delete_conn_node (_conn_node);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_DELETE_FROM_LIST_FAILED, "Failed deleting "
- "connection node from list");
- }
- return NULL;
- /*if adding to the list failed free connection node*/
-_conn_failed:
- GF_FREE (_conn_node);
- /*if allocation failed*/
-alloc_failed:
- return NULL;
- /*****Error Handling********/
-}
-
-
-
-
-
-/*Libgfdb API Function: Used to terminate/de-initialize db connection
- * (Destructor function for db connection object)
- * Arguments:
- * _conn_node : GFDB Connection node
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-fini_db (gfdb_conn_node_t *_conn_node)
-{
- int ret = -1;
- gfdb_db_operations_t *db_operations_t = NULL;
-
- CHECK_CONN_NODE_GOTO (_conn_node, empty);
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
-
- GF_ASSERT (db_operations_t->fini_db_op);
-
- ret = db_operations_t->fini_db_op(&_conn_node->gfdb_connection.
- gf_db_connection);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_CLOSE_CONNECTION_FAILED, "Failed close the db "
- "connection");
- goto out;
- }
-
- ret = delete_conn_node (_conn_node);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_DELETE_FROM_LIST_FAILED, "Failed deleting "
- "connection node from list");
- }
-empty:
- ret = 0;
-out:
- return ret;
-}
-
-
-
-
-
-
-/*Libgfdb API Function: Used to insert/update records in the database
- * NOTE: In current gfdb_sqlite plugin we use that
- * same function to delete the record. Set the
- * gfdb_fop_path to GFDB_FOP_UNDEL to delete the
- * link of inode from GF_FLINK_TB and
- * GFDB_FOP_UNDEL_ALL to delete all the records from
- * GF_FLINK_TB and GF_FILE_TB.
- * TODO: Should seperate this function into the
- * delete_record function
- * Refer CTR Xlator features/changetimerecorder for usage
- * Arguments:
- * _conn_node : GFDB Connection node
- * gfdb_db_record : Record to be inserted/updated
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-insert_record (gfdb_conn_node_t *_conn_node,
- gfdb_db_record_t *gfdb_db_record)
-{
- int ret = 0;
- gfdb_db_operations_t *db_operations_t = NULL;
- void *gf_db_connection = NULL;
-
- CHECK_CONN_NODE(_conn_node);
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
- gf_db_connection = _conn_node->gfdb_connection.gf_db_connection;
-
- if (db_operations_t->insert_record_op) {
-
- ret = db_operations_t->insert_record_op (gf_db_connection,
- gfdb_db_record);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_INSERT_OR_UPDATE_FAILED, "Insert/Update"
- " operation failed!");
- }
- }
-
- return ret;
-}
-
-
-
-
-/*Libgfdb API Function: Used to delete record from the database
- * NOTE: In the current gfdb_sqlite3 plugin
- * implementation this function is dummy.
- * Use the insert_record function.
- * Refer CTR Xlator features/changetimerecorder for usage
- * Arguments:
- * _conn_node : GFDB Connection node
- * gfdb_db_record : Record to be deleted
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-delete_record (gfdb_conn_node_t *_conn_node,
- gfdb_db_record_t *gfdb_db_record)
-{
- int ret = 0;
- gfdb_db_operations_t *db_operations_t = NULL;
- void *gf_db_connection = NULL;
-
- CHECK_CONN_NODE(_conn_node);
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
- gf_db_connection = _conn_node->gfdb_connection.gf_db_connection;
-
- if (db_operations_t->delete_record_op) {
-
- ret = db_operations_t->delete_record_op (gf_db_connection,
- gfdb_db_record);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_DELETE_FAILED, "Delete operation "
- "failed!");
- }
-
- }
-
- return ret;
-}
-
-
-
-
-
-/*Libgfdb API Function: Query all the records from the database
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-find_all(gfdb_conn_node_t *_conn_node, gf_query_callback_t query_callback,
- void *_query_cbk_args) {
- int ret = 0;
- gfdb_db_operations_t *db_operations_t = NULL;
- void *gf_db_connection = NULL;
-
- CHECK_CONN_NODE(_conn_node);
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
- gf_db_connection = _conn_node->gfdb_connection.gf_db_connection;
-
- if (db_operations_t->find_all_op) {
- ret = db_operations_t->find_all_op (gf_db_connection,
- query_callback,
- _query_cbk_args);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_FIND_OP_FAILED, "Find all operation "
- "failed!");
- }
-
- }
-
- return ret;
-}
-
-
-
-/*Libgfdb API Function: Query records/files that have not changed/accessed
- * from a time in past to current time
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * for_time : Time from where the file/s are not
- * changed/accessed
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-find_unchanged_for_time(gfdb_conn_node_t *_conn_node,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *for_time) {
-
- int ret = 0;
- gfdb_db_operations_t *db_operations_t = NULL;
- void *gf_db_connection = NULL;
-
- CHECK_CONN_NODE(_conn_node);
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
- gf_db_connection = _conn_node->gfdb_connection.gf_db_connection;
-
- if (db_operations_t->find_unchanged_for_time_op) {
-
- ret = db_operations_t->find_unchanged_for_time_op
- (gf_db_connection,
- query_callback,
- _query_cbk_args,
- for_time);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_FIND_OP_FAILED, "Find unchanged "
- "operation failed!");
- }
-
- }
-
- return ret;
-}
-
-/*Libgfdb API Function: Query records/files that have changed/accessed from a
- * time in past to current time
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * for_time : Time from where the file/s are
- * changed/accessed
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-find_recently_changed_files(gfdb_conn_node_t *_conn_node,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *from_time) {
-
- int ret = 0;
- gfdb_db_operations_t *db_operations_t = NULL;
- void *gf_db_connection = NULL;
-
- CHECK_CONN_NODE(_conn_node);
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
- gf_db_connection = _conn_node->gfdb_connection.gf_db_connection;
-
- if (db_operations_t->find_recently_changed_files_op) {
-
- ret = db_operations_t->find_recently_changed_files_op (
- gf_db_connection,
- query_callback,
- _query_cbk_args,
- from_time);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_FIND_OP_FAILED,
- "Find changed operation failed!");
- }
-
- }
-
- return ret;
-
-}
-
-/*Libgfdb API Function: Query records/files that have not changed/accessed
- * from a time in past to current time, with
- * a desired frequency
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * for_time : Time from where the file/s are not
- * changed/accessed
- * write_freq_thresold : Desired Write Frequency lower limit
- * read_freq_thresold : Desired Read Frequency lower limit
- * _clear_counters : If true, Clears all the frequency counters of
- * all files.
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-find_unchanged_for_time_freq(gfdb_conn_node_t *_conn_node,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *for_time,
- int write_freq_thresold,
- int read_freq_thresold,
- gf_boolean_t _clear_counters) {
-
- int ret = 0;
- gfdb_db_operations_t *db_operations_t = NULL;
- void *gf_db_connection = NULL;
-
- CHECK_CONN_NODE(_conn_node);
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
- gf_db_connection = _conn_node->gfdb_connection.gf_db_connection;
-
- if (db_operations_t->find_unchanged_for_time_freq_op) {
-
- ret = db_operations_t->find_unchanged_for_time_freq_op(
- gf_db_connection,
- query_callback,
- _query_cbk_args,
- for_time,
- write_freq_thresold,
- read_freq_thresold,
- _clear_counters);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_FIND_OP_FAILED,
- "Find unchanged with freq operation failed!");
- }
-
- }
-
- return ret;
-}
-
-/*Libgfdb API Function: Query records/files that have changed/accessed from a
- * time in past to current time, with
- * a desired frequency
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * for_time : Time from where the file/s are
- * changed/accessed
- * write_freq_thresold : Desired Write Frequency lower limit
- * read_freq_thresold : Desired Read Frequency lower limit
- * _clear_counters : If true, Clears all the frequency counters of
- * all files.
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-find_recently_changed_files_freq(gfdb_conn_node_t *_conn_node,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *from_time,
- int write_freq_thresold,
- int read_freq_thresold,
- gf_boolean_t _clear_counters) {
-
- int ret = 0;
- gfdb_db_operations_t *db_operations_t = NULL;
- void *gf_db_connection = NULL;
-
- CHECK_CONN_NODE(_conn_node);
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
- gf_db_connection = _conn_node->gfdb_connection.gf_db_connection;
-
- if (db_operations_t->find_recently_changed_files_freq_op) {
-
- ret = db_operations_t->find_recently_changed_files_freq_op(
- gf_db_connection,
- query_callback,
- _query_cbk_args,
- from_time,
- write_freq_thresold,
- read_freq_thresold,
- _clear_counters);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_FIND_OP_FAILED,
- "Find changed with freq operation failed!");
- }
-
- }
-
- return ret;
-
-}
-
-
-
-/*Libgfdb API Function: Clear the heat for all the files
- *
- * Arguments:
- * _conn_node : GFDB Connection node
- *
- * Returns : if successful return 0 or
- * -ve value in case of failure
- **/
-
-int
-clear_files_heat (gfdb_conn_node_t *_conn_node) {
- int ret = 0;
- gfdb_db_operations_t *db_operations_t = NULL;
- void *gf_db_connection = NULL;
-
- CHECK_CONN_NODE(_conn_node);
-
- db_operations_t = &_conn_node->gfdb_connection.gfdb_db_operations;
- gf_db_connection = _conn_node->gfdb_connection.gf_db_connection;
-
- if (db_operations_t->clear_files_heat_op) {
- ret = db_operations_t->clear_files_heat_op (gf_db_connection);
- if (ret) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, 0,
- LG_MSG_FIND_OP_FAILED,
- "Clear files heat operation failed!");
- }
- }
-
- return ret;
-}
-
-static const
-char *get_db_path_key()
-{
- return GFDB_SQL_PARAM_DBPATH;
-}
-
-void get_gfdb_methods (gfdb_methods_t *methods)
-{
- methods->init_db = init_db;
- methods->fini_db = fini_db;
- methods->find_unchanged_for_time = find_unchanged_for_time;
- methods->find_recently_changed_files = find_recently_changed_files;
- methods->find_unchanged_for_time_freq = find_unchanged_for_time_freq;
- methods->find_recently_changed_files_freq = find_recently_changed_files_freq;
- methods->get_db_path_key = get_db_path_key;
-}
-
diff --git a/libglusterfs/src/gfdb/gfdb_data_store.h b/libglusterfs/src/gfdb/gfdb_data_store.h
deleted file mode 100644
index 6a7ddcf7212..00000000000
--- a/libglusterfs/src/gfdb/gfdb_data_store.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- Copyright (c) 2015 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 __GFDB_DATA_STORE_H
-#define __GFDB_DATA_STORE_H
-
-
-#include "glusterfs.h"
-#include "xlator.h"
-#include "logging.h"
-#include "common-utils.h"
-#include <time.h>
-#include <sys/time.h>
-
-#include "gfdb_data_store_types.h"
-
-/* GFDB Connection Node:
- * ~~~~~~~~~~~~~~~~~~~~
- * Represents the connection to the database while using libgfdb
- * The connection node is not thread safe as far as fini_db is concerned.
- * You can use a single connection node
- * to do multithreaded db operations like insert/delete/find of records.
- * But you need to wait for all the operating threads to complete i.e
- * pthread_join() and then do fini_db() to kill the connection node.
- * gfdb_conn_node_t is an opaque structure.
- * */
-typedef struct gfdb_conn_node_t gfdb_conn_node_t;
-
-
-
-
-/*Libgfdb API Function: Used to initialize db connection
- * Arguments:
- * args : Dictionary containing database specific parameters
- * eg: For sqlite3, pagesize, cachesize, db name, db path
- etc
- * gfdb_db_type : Type of data base used i.e sqlite or hyperdex etc
- * Returns : if successful return the GFDB Connection Node to the caller or
- * NULL value in case of failure*/
-gfdb_conn_node_t *
-init_db(dict_t *arg, gfdb_db_type_t db_type);
-
-typedef gfdb_conn_node_t * (*init_db_t) (dict_t *args,
- gfdb_db_type_t gfdb_db_type);
-
-
-
-
-/*Libgfdb API Function: Used to terminate/de-initialize db connection
- * (Destructor function for db connection object)
- * Arguments:
- * _conn_node : DB Connection Index of the DB Connection
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-fini_db(gfdb_conn_node_t *);
-
-typedef int (*fini_db_t) (gfdb_conn_node_t *_conn_node);
-
-
-
-/*Libgfdb API Function: Used to insert/updated records in the database
- * NOTE: In current gfdb_sqlite plugin we use that
- * same function to delete the record. Set the
- * gfdb_fop_path to GFDB_FOP_UNDEL to delete the
- * link of inode from GF_FLINK_TB and
- * GFDB_FOP_UNDEL_ALL to delete all the records from
- * GF_FLINK_TB and GF_FILE_TB.
- * TODO: Should seperate this function into the
- * delete_record function
- * Refer CTR Xlator features/changetimerecorder for usage
- * Arguments:
- * _conn_node : GFDB Connection node
- * gfdb_db_record : Record to be inserted/updated
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-insert_record(gfdb_conn_node_t *, gfdb_db_record_t *gfdb_db_record);
-
-
-
-
-/*Libgfdb API Function: Used to delete record from the database
- * NOTE: In the current gfdb_sqlite3 plugin
- * implementation this function is dummy.
- * Use the insert_record function.
- * Refer CTR Xlator features/changetimerecorder for usage
- * Arguments:
- * _conn_node : GFDB Connection node
- * gfdb_db_record : Record to be deleted
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int
-delete_record(gfdb_conn_node_t *, gfdb_db_record_t *gfdb_db_record);
-
-
-
-
-
-/*Libgfdb API Function: Query all the records from the database
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int find_all(gfdb_conn_node_t *, gf_query_callback_t query_callback,
- void *_query_cbk_args);
-
-
-
-
-
-/*Libgfdb API Function: Query records/files that have not changed/accessed
- * from a time in past to current time
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * for_time : Time from where the file/s are not
- * changed/accessed
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int find_unchanged_for_time(gfdb_conn_node_t *,
- gf_query_callback_t query_callback,
- void *_query_cbk_args, gfdb_time_t *for_time);
-
-typedef int (*find_unchanged_for_time_t) (gfdb_conn_node_t *_conn_node,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *for_time);
-
-
-
-
-/*Libgfdb API Function: Query records/files that have changed/accessed from a
- * time in past to current time
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * for_time : Time from where the file/s are
- * changed/accessed
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int find_recently_changed_files(gfdb_conn_node_t *_conn,
- gf_query_callback_t query_callback, void *_query_cbk_args,
- gfdb_time_t *from_time);
-
-typedef int (*find_recently_changed_files_t) (gfdb_conn_node_t *_conn_node,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *from_time);
-
-
-
-
-/*Libgfdb API Function: Query records/files that have not changed/accessed
- * from a time in past to current time, with
- * a desired frequency
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * for_time : Time from where the file/s are not
- * changed/accessed
- * write_freq_thresold : Desired Write Frequency lower limit
- * read_freq_thresold : Desired Read Frequency lower limit
- * _clear_counters : If true, Clears all the frequency counters of
- * all files.
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int find_unchanged_for_time_freq(gfdb_conn_node_t *_conn,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *for_time,
- int write_freq_thresold,
- int read_freq_thresold,
- gf_boolean_t _clear_counters);
-
-typedef int (*find_unchanged_for_time_freq_t) (gfdb_conn_node_t *_conn_node,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *for_time,
- int write_freq_thresold,
- int read_freq_thresold,
- gf_boolean_t _clear_counters);
-
-
-
-
-/*Libgfdb API Function: Query records/files that have changed/accessed from a
- * time in past to current time, with
- * a desired frequency
- * Arguments:
- * _conn_node : GFDB Connection node
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * for_time : Time from where the file/s are
- * changed/accessed
- * write_freq_thresold : Desired Write Frequency lower limit
- * read_freq_thresold : Desired Read Frequency lower limit
- * _clear_counters : If true, Clears all the frequency counters of
- * all files.
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-int find_recently_changed_files_freq(gfdb_conn_node_t *_conn,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *from_time,
- int write_freq_thresold,
- int read_freq_thresold,
- gf_boolean_t _clear_counters);
-
-typedef int (*find_recently_changed_files_freq_t) (gfdb_conn_node_t *_conn_node,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *from_time,
- int write_freq_thresold,
- int read_freq_thresold,
- gf_boolean_t _clear_counters);
-
-typedef const
-char *(*get_db_path_key_t)();
-
-/*Libgfdb API Function: Clear the heat for all the files
- *
- * Arguments:
- * _conn_node : GFDB Connection node
- *
- * Returns : if successful return 0 or
- * -ve value in case of failure
- **/
-int
-clear_files_heat (gfdb_conn_node_t *_conn_node);
-
-typedef struct gfdb_methods_s {
- init_db_t init_db;
- fini_db_t fini_db;
- find_unchanged_for_time_t find_unchanged_for_time;
- find_recently_changed_files_t find_recently_changed_files;
- find_unchanged_for_time_freq_t find_unchanged_for_time_freq;
- find_recently_changed_files_freq_t find_recently_changed_files_freq;
- /* Do not expose dbpath directly. Expose it via an */
- /* access function: get_db_path_key(). */
- char *dbpath;
- get_db_path_key_t get_db_path_key;
-} gfdb_methods_t;
-
-void get_gfdb_methods (gfdb_methods_t *methods);
-
-typedef void (*get_gfdb_methods_t) (gfdb_methods_t *methods);
-
-
-#endif
diff --git a/libglusterfs/src/gfdb/gfdb_data_store_types.h b/libglusterfs/src/gfdb/gfdb_data_store_types.h
deleted file mode 100644
index 2d3c5ede99c..00000000000
--- a/libglusterfs/src/gfdb/gfdb_data_store_types.h
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- Copyright (c) 2015 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 __GFDB_DATA_STORE_TYPE_H
-#define __GFDB_DATA_STORE_TYPE_H
-
-
-#include <time.h>
-#include <sys/time.h>
-#include <string.h>
-
-#include "common-utils.h"
-#include "compat-uuid.h"
-#include "gfdb_mem-types.h"
-#include "dict.h"
-#include "libglusterfs-messages.h"
-
-/*
- * Helps in dynamically choosing log level
- * */
-static inline gf_loglevel_t
-_gfdb_log_level (gf_loglevel_t given_level,
- gf_boolean_t ignore_level)
-{
- return (ignore_level) ? GF_LOG_DEBUG : given_level;
-}
-
-typedef enum gf_db_operation {
- GFDB_INVALID_DB_OP = -1,
- /* Query DB OPS : All the Query DB_OP should be added */
- /* in between START and END */
- GFDB_QUERY_DB_OP_START, /* Start of Query DB_OP */
- GFDB_QUERY_DB_OP,
- GF_FTABLE_EXISTS_DB_OP,
- GFDB_QUERY_DB_OP_END, /* End of Query DB_OP */
- /* Non-Query DB OPS */
- GFDB_DB_CREATE_DB_OP,
- GFDB_GFID_EXIST_DB_OP,
- GFDB_W_INSERT_DB_OP,
- GFDB_WU_INSERT_DB_OP,
- GFDB_W_UPDATE_DB_OP,
- GFDB_WU_UPDATE_DB_OP,
- GFDB_W_DELETE_DB_OP,
- GFDB_UW_DELETE_DB_OP,
- GFDB_WFC_UPDATE_DB_OP,
- GFDB_RFC_UPDATE_DB_OP
-} gf_db_operation_t;
-
-
-#define GF_COL_MAX_NUM 2
-#define GF_COL_ALL " * "
-
-/* Column/fields names used in the DB.
- * If any new field is added should be updated here*/
-#define GF_COL_GF_ID "GF_ID"
-#define GF_COL_GF_PID "GF_PID"
-#define GF_COL_FILE_NAME "FNAME"
-#define GF_COL_FPATH "FPATH"
-#define GF_COL_WSEC "W_SEC"
-#define GF_COL_WMSEC "W_MSEC"
-#define GF_COL_UWSEC "UW_SEC"
-#define GF_COL_UWMSEC "UW_MSEC"
-#define GF_COL_WSEC_READ "W_READ_SEC"
-#define GF_COL_WMSEC_READ "W_READ_MSEC"
-#define GF_COL_UWSEC_READ "UW_READ_SEC"
-#define GF_COL_UWMSEC_READ "UW_READ_MSEC"
-#define GF_COL_WDEL_FLAG "W_DEL_FLAG"
-#define GF_COL_WRITE_FREQ_CNTR "WRITE_FREQ_CNTR"
-#define GF_COL_READ_FREQ_CNTR "READ_FREQ_CNTR"
-#define GF_COL_LINK_UPDATE "LINK_UPDATE"
-
-
-/***********************Time related********************************/
-/*1 sec = 1000000 microsec*/
-#define GFDB_MICROSEC 1000000
-
-/*All the gfdb times are represented using this structure*/
-typedef struct timeval gfdb_time_t;
-
-/*Convert time into seconds*/
-static inline uint64_t
-gfdb_time_2_usec(gfdb_time_t *gfdb_time)
-{
- GF_ASSERT(gfdb_time);
- return ((uint64_t) gfdb_time->tv_sec * GFDB_MICROSEC) + gfdb_time->tv_usec;
-}
-
-
-
-
-
-/******************************************************************************
- *
- * Insert/Update Record related data structures/functions
- *
- * ****************************************************************************/
-
-
-
-
-/*Indicated a generic synchronous write to the db
- * This may or may not be implemented*/
-typedef enum gfdb_sync_type {
- GFDB_INVALID_SYNC = -1,
- GFDB_DB_ASYNC,
- GFDB_DB_SYNC
-} gfdb_sync_type_t;
-
-/*Strings related to the abvove sync type*/
-#define GFDB_STR_DB_ASYNC "async"
-#define GFDB_STR_DB_SYNC "sync"
-
-/*To convert sync type from string to gfdb_sync_type_t*/
-static inline int
-gf_string2gfdbdbsync (char *sync_option)
-{
- int ret = -1;
-
- if (!sync_option)
- goto out;
- if (strcmp(sync_option, GFDB_STR_DB_ASYNC) == 0) {
- ret = GFDB_DB_ASYNC;
- } else if (strcmp(sync_option, GFDB_STR_DB_SYNC) == 0) {
- ret = GFDB_DB_SYNC;
- }
-out:
- return ret;
-}
-
-
-
-
-
-
-/*Indicated different types of db*/
-typedef enum gfdb_db_type {
- GFDB_INVALID_DB = -1,
- GFDB_HASH_FILE_STORE,
- GFDB_ROCKS_DB,
- GFDB_SQLITE3,
- GFDB_HYPERDEX,
- GFDB_DB_END /*Add DB type Entries above this only*/
-} gfdb_db_type_t;
-
-/*String related to the db types*/
-#define GFDB_DATA_STORE "gfdbdatastore"
-#define GFDB_STR_HASH_FILE_STORE "hashfile"
-#define GFDB_STR_ROCKS_DB "rocksdb"
-#define GFDB_STR_SQLITE3 "sqlite3"
-#define GFDB_STR_HYPERDEX "hyperdex"
-
-/*Convert db type in string to gfdb_db_type_t*/
-static inline int
-gf_string2gfdbdbtype (char *db_option)
-{
- int ret = -1;
-
- if (!db_option)
- goto out;
- if (strcmp(db_option, GFDB_STR_HASH_FILE_STORE) == 0) {
- ret = GFDB_HASH_FILE_STORE;
- } else if (strcmp(db_option, GFDB_STR_ROCKS_DB) == 0) {
- ret = GFDB_ROCKS_DB;
- } else if (strcmp(db_option, GFDB_STR_SQLITE3) == 0) {
- ret = GFDB_SQLITE3;
- } else if (strcmp(db_option, GFDB_STR_HYPERDEX) == 0) {
- ret = GFDB_HYPERDEX;
- }
-out:
- return ret;
-}
-
-
-
-
-
-
-
-/*Tells the path of the fop*/
-typedef enum gfdb_fop_path {
- GFDB_FOP_INVALID = -1,
- /*Filler value for zero*/
- GFDB_FOP_PATH_ZERO = 0,
- /*have wind path below this*/
- GFDB_FOP_WIND = 1,
- GFDB_FOP_WDEL = 2,
- /*have unwind path below this*/
- GFDB_FOP_UNWIND = 4,
- /*Delete unwind path*/
- GFDB_FOP_UNDEL = 8,
- GFDB_FOP_UNDEL_ALL = 16
-} gfdb_fop_path_t;
-/*Strings related to the above fop path*/
-#define GFDB_STR_FOP_INVALID "INVALID"
-#define GFDB_STR_FOP_WIND "ENTRY"
-#define GFDB_STR_FOP_UNWIND "EXIT"
-#define GFDB_STR_FOP_WDEL "WDEL"
-#define GFDB_STR_FOP_UNDEL "UNDEL"
-
-static inline gf_boolean_t
-iswindpath(gfdb_fop_path_t gfdb_fop_path)
-{
- return ((gfdb_fop_path == GFDB_FOP_WIND) ||
- (gfdb_fop_path == GFDB_FOP_WDEL)) ?
- _gf_true : _gf_false;
-}
-
-static inline gf_boolean_t
-isunwindpath(gfdb_fop_path_t gfdb_fop_path)
-{
- return (gfdb_fop_path >= GFDB_FOP_UNWIND) ? _gf_true : _gf_false;
-}
-
-
-
-
-
-
-
-/*Tell what type of fop it was
- * Like whether a dentry fop or a inode fop
- * Read fop or a write fop etc*/
-typedef enum gfdb_fop_type {
- GFDB_FOP_INVALID_OP = -1,
- /*Filler value for zero*/
- GFDB_FOP_TYPE_ZERO = 0,
- GFDB_FOP_DENTRY_OP = 1,
- GFDB_FOP_DENTRY_CREATE_OP = 2,
- GFDB_FOP_INODE_OP = 4,
- GFDB_FOP_WRITE_OP = 8,
- GFDB_FOP_READ_OP = 16
-} gfdb_fop_type_t;
-
-#define GFDB_FOP_INODE_WRITE\
- (GFDB_FOP_INODE_OP | GFDB_FOP_WRITE_OP)
-
-#define GFDB_FOP_DENTRY_WRITE\
- (GFDB_FOP_DENTRY_OP | GFDB_FOP_WRITE_OP)
-
-#define GFDB_FOP_CREATE_WRITE\
- (GFDB_FOP_DENTRY_CREATE_OP | GFDB_FOP_WRITE_OP)
-
-#define GFDB_FOP_INODE_READ\
- (GFDB_FOP_INODE_OP | GFDB_FOP_READ_OP)
-
-static inline gf_boolean_t
-isreadfop(gfdb_fop_type_t fop_type)
-{
- return (fop_type & GFDB_FOP_READ_OP) ? _gf_true : _gf_false;
-}
-
-static inline gf_boolean_t
-isdentryfop(gfdb_fop_type_t fop_type)
-{
- return ((fop_type & GFDB_FOP_DENTRY_OP) ||
- (fop_type & GFDB_FOP_DENTRY_CREATE_OP)) ? _gf_true : _gf_false;
-}
-
-static inline gf_boolean_t
-isdentrycreatefop(gfdb_fop_type_t fop_type)
-{
- return (fop_type & GFDB_FOP_DENTRY_CREATE_OP) ?
- _gf_true : _gf_false;
-}
-
-
-
-
-
-
-
-/*The structure that is used to send insert/update the databases
- * using insert_db api*/
-typedef struct gfdb_db_record {
- uuid_t gfid;
- uuid_t pargfid;
- uuid_t old_pargfid;
- char file_name[PATH_MAX];
- char file_path[PATH_MAX];
- char old_file_name[PATH_MAX];
- char old_path[PATH_MAX];
- gfdb_fop_type_t gfdb_fop_type;
- gfdb_fop_path_t gfdb_fop_path;
- /*Time of change or access*/
- gfdb_time_t gfdb_wind_change_time;
- gfdb_time_t gfdb_unwind_change_time;
- /* For crash consistancy while inserting/updating hard links */
- gf_boolean_t islinkupdate;
- /* For link consistency we do a double update i.e mark the link
- * during the wind and during the unwind we update/delete the link.
- * This has a performance hit. We give a choice here whether we need
- * link consistency to be spoton or not using link_consistency flag.
- * This will have only one link update */
- gf_boolean_t link_consistency;
- /* For dentry fops we can choose to ignore recording of unwind time */
- /* For inode fops "record_exit" volume option does the trick, */
- /* but for dentry fops we update the LINK_UPDATE, so an extra */
- /* flag is provided to ignore the recording of the unwind time. */
- gf_boolean_t do_record_uwind_time;
- /* Global flag to record or not record counters */
- gf_boolean_t do_record_counters;
- /* Global flag to Record/Not Record wind or wind time.
- * This flag will overrule do_record_uwind_time*/
- gf_boolean_t do_record_times;
- /* Ignoring errors while inserting.
- * */
- gf_boolean_t ignore_errors;
-} gfdb_db_record_t;
-
-
-
-/*******************************************************************************
- *
- * Query related data structure and functions
- *
- * ****************************************************************************/
-
-
-
-/*Structure used for querying purpose*/
-typedef struct gfdb_query_record {
- /*Inode info*/
- uuid_t gfid;
- /*All the hard link of the inode
- * All the hard links will be queried as
- * "GF_PID,FNAME,FPATH,W_DEL_FLAG,LINK_UPDATE"
- * and multiple hardlinks will be seperated by "::"*/
- /*Do only shallow copy. The gf_query_callback_t */
- /* function should do the deep copy.*/
- char *_link_info_str;
- ssize_t link_info_size;
-} gfdb_query_record_t;
-
-/*Function to create the query_record*/
-static inline gfdb_query_record_t *
-gfdb_query_record_init()
-{
- int ret = -1;
- gfdb_query_record_t *gfdb_query_record = NULL;
-
- gfdb_query_record = GF_CALLOC (1, sizeof(gfdb_query_record_t),
- gf_mt_gfdb_query_record_t);
- if (!gfdb_query_record) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, ENOMEM,
- LG_MSG_NO_MEMORY, "Error allocating memory to "
- "gfdb_query_record ");
- goto out;
- }
- ret = 0;
-out:
- if (ret == -1) {
- GF_FREE (gfdb_query_record);
- }
- return gfdb_query_record;
-}
-
-/*Function to destroy query record*/
-static inline void
-gfdb_query_record_fini(gfdb_query_record_t
- **gfdb_query_record) {
- GF_FREE (*gfdb_query_record);
-}
-
-
-
-
-
-
-
-
-/*Structure to hold the link information*/
-typedef struct gfdb_link_info {
- uuid_t pargfid;
- char file_name[PATH_MAX];
- char file_path[PATH_MAX];
- gf_boolean_t is_link_updated;
- gf_boolean_t is_del_flag_set;
-} gfdb_link_info_t;
-
-/*Create a single link info structure*/
-static inline gfdb_link_info_t *
-gfdb_link_info_init ()
-{
- gfdb_link_info_t *gfdb_link_info = NULL;
-
- gfdb_link_info = GF_CALLOC (1, sizeof(gfdb_link_info_t),
- gf_mt_gfdb_link_info_t);
- if (!gfdb_link_info) {
- gf_msg (GFDB_DATA_STORE, GF_LOG_ERROR, ENOMEM,
- LG_MSG_NO_MEMORY, "Error allocating memory to "
- "gfdb_link_info ");
- }
-
- return gfdb_link_info;
-}
-
-/*Destroy a link info structure*/
-static inline void
-gfdb_link_info_fini(gfdb_link_info_t **gfdb_link_info)
-{
- if (gfdb_link_info)
- GF_FREE (*gfdb_link_info);
-}
-
-
-/*Length of each hard link string */
-#define DEFAULT_LINK_INFO_STR_LEN 1024
-
-/* Parse a single link string into link_info structure
- * Input format of str_link
- * "GF_PID,FNAME,FPATH,W_DEL_FLAG,LINK_UPDATE"
- *
- * */
-static inline int
-str_to_link_info (char *str_link,
- gfdb_link_info_t *link_info)
-{
- int ret = -1;
- const char *delimiter = ",";
- char *token_str = NULL;
- char *saveptr = NULL;
- char gfid[200] = "";
-
- GF_ASSERT (str_link);
- GF_ASSERT (link_info);
-
- /*Parent GFID*/
- token_str = strtok_r(str_link, delimiter, &saveptr);
- if (token_str != NULL) {
- strcpy (gfid, token_str);
- ret = gf_uuid_parse (gfid, link_info->pargfid);
- if (ret == -1)
- goto out;
- }
-
- /*Filename*/
- token_str = strtok_r(NULL, delimiter, &saveptr);
- if (token_str != NULL) {
- strcpy (link_info->file_name, token_str);
- }
-
- /*Filepath*/
- token_str = strtok_r(NULL, delimiter, &saveptr);
- if (token_str != NULL) {
- strcpy (link_info->file_path, token_str);
- }
-
- /*is_link_updated*/
- token_str = strtok_r(NULL, delimiter, &saveptr);
- if (token_str != NULL) {
- link_info->is_link_updated = atoi(token_str);
- if (link_info->is_link_updated != 0 &&
- link_info->is_link_updated != 1) {
- goto out;
- }
- }
-
- /*is_del_flag_set*/
- token_str = strtok_r(NULL, delimiter, &saveptr);
- if (token_str != NULL) {
- link_info->is_del_flag_set = atoi (token_str);
- if (link_info->is_del_flag_set != 0 &&
- link_info->is_del_flag_set != 1) {
- goto out;
- }
- }
- ret = 0;
-out:
- return ret;
-}
-
-
-/*******************************************************************************
- *
- * Signatures for the plugin functions
- * i.e Any plugin should implementment
- * these functions to integrate with
- * libgfdb.
- *
- * ****************************************************************************/
-
-/*Call back function for querying the database*/
-typedef int
-(*gf_query_callback_t)(gfdb_query_record_t *, void *);
-
-/* Used to initialize db connection
- * Arguments:
- * args : Dictionary containing database specific parameters
- * db_conn : pointer to plugin specific data base connection
- * that will be created. If the call is successful
- * db_conn will contain the plugin specific connection
- * If call is unsuccessful will have NULL.
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-typedef int
-(*gfdb_init_db_t)(dict_t *args, void **db_conn);
-
-
-
-
-/* Used to terminate/de-initialize db connection
- * (Destructor function for db connection object)
- * Arguments:
- * db_conn : plugin specific data base connection
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-typedef int
-(*gfdb_fini_db_t)(void **db_conn);
-
-
-
-
-/*Used to insert/updated records in the database
- * Arguments:
- * db_conn : plugin specific data base connection
- * gfdb_db_record : Record to be inserted/updated
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-typedef int
-(*gfdb_insert_record_t)(void *db_conn,
- gfdb_db_record_t *db_record);
-
-
-
-
-/*Used to delete record from the database
- * Arguments:
- * db_conn : plugin specific data base connection
- * gfdb_db_record : Record to be deleted
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-typedef int
-(*gfdb_delete_record_t)(void *db_conn,
- gfdb_db_record_t *db_record);
-
-
-
-
-/* Query all the records from the database
- * Arguments:
- * db_conn : plugin specific data base connection
- * query_callback : Call back function that will be called
- * for every record found
- * _query_cbk_args : Custom argument passed for the call back
- * function query_callback
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-typedef int
-(*gfdb_find_all_t)(void *db_conn,
- gf_query_callback_t query_callback,
- void *_cbk_args);
-
-
-
-
-/* Query records/files that have not changed/accessed
- * from a time in past to current time
- * Arguments:
- * db_conn : plugin specific data base connection
- * query_callback : Call back function that will be called
- * for every record found
- * _cbk_args : Custom argument passed for the call back
- * function query_callback
- * for_time : Time from where the file/s are not
- * changed/accessed
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-typedef int
-(*gfdb_find_unchanged_for_time_t)(void *db_conn,
- gf_query_callback_t query_callback,
- void *_cbk_args,
- gfdb_time_t *_time);
-
-
-
-/* Query records/files that have changed/accessed from a
- * time in past to current time
- * Arguments:
- * db_conn : plugin specific data base connection
- * query_callback : Call back function that will be called
- * for every record found
- * _cbk_args : Custom argument passed for the call back
- * function query_callback
- * _time : Time from where the file/s are
- * changed/accessed
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-typedef int
-(*gfdb_find_recently_changed_files_t)(void *db_conn,
- gf_query_callback_t query_callback,
- void *_cbk_args, gfdb_time_t *_time);
-
-/* Query records/files that have not changed/accessed
- * from a time in past to current time, with
- * a desired frequency
- *
- * Arguments:
- * db_conn : plugin specific data base connection
- * query_callback : Call back function that will be called
- * for every record found
- * _cbk_args : Custom argument passed for the call back
- * function query_callback
- * _time : Time from where the file/s are not
- * changed/accessed
- * _write_freq : Desired Write Frequency lower limit
- * _read_freq : Desired Read Frequency lower limit
- * _clear_counters : If true, Clears all the frequency counters of
- * all files.
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-typedef int
-(*gfdb_find_unchanged_for_time_freq_t)
- (void *db_conn,
- gf_query_callback_t query_callback,
- void *_cbk_args, gfdb_time_t *_time,
- int _write_freq, int _read_freq,
- gf_boolean_t _clear_counters);
-
-
-
-
-/* Query records/files that have changed/accessed from a
- * time in past to current time, with a desired frequency
- * Arguments:
- * db_conn : plugin specific data base connection
- * query_callback : Call back function that will be called
- * for every record found
- * _cbk_args : Custom argument passed for the call back
- * function query_callback
- * _time : Time from where the file/s are
- * changed/accessed
- * _write_freq : Desired Write Frequency lower limit
- * _read_freq : Desired Read Frequency lower limit
- * _clear_counters : If true, Clears all the frequency counters of
- * all files.
- * Returns : if successful return 0 or
- * -ve value in case of failure*/
-typedef int
-(*gfdb_find_recently_changed_files_freq_t)(void *db_conn,
- gf_query_callback_t query_callback,
- void *_cbk_args, gfdb_time_t *_time,
- int _write_freq, int _read_freq,
- gf_boolean_t _clear_counters);
-
-
-typedef int (*gfdb_clear_files_heat_t)(void *db_conn);
-
-
-/*Data structure holding all the above plugin function pointers*/
-typedef struct gfdb_db_operations {
- gfdb_init_db_t init_db_op;
- gfdb_fini_db_t fini_db_op;
- gfdb_insert_record_t insert_record_op;
- gfdb_delete_record_t delete_record_op;
- gfdb_find_all_t find_all_op;
- gfdb_find_unchanged_for_time_t find_unchanged_for_time_op;
- gfdb_find_recently_changed_files_t find_recently_changed_files_op;
- gfdb_find_unchanged_for_time_freq_t
- find_unchanged_for_time_freq_op;
- gfdb_find_recently_changed_files_freq_t
- find_recently_changed_files_freq_op;
- gfdb_clear_files_heat_t clear_files_heat_op;
-} gfdb_db_operations_t;
-
-/*******************************************************************************
- *
- * Database connection object: This objected is maitained by libgfdb for each
- * database connection created.
- * gf_db_connection : DB connection specific to the plugin
- * gfdb_db_operations : Contains all the libgfdb API implementation
- * from the plugin.
- * gfdb_db_type : Type of database
- *
- * ****************************************************************************/
-
-
-typedef struct gfdb_connection {
- void *gf_db_connection;
- gfdb_db_operations_t gfdb_db_operations;
- gfdb_db_type_t gfdb_db_type;
-} gfdb_connection_t;
-
-
-
-
-/*******************************************************************************
- *
- * Macros for get and set db options
- *
- * ****************************************************************************/
-
-
-/*Set param_key : str_value into param_dict*/
-#define SET_DB_PARAM_TO_DICT(comp_name, params_dict, param_key,\
- str_value, ret, error)\
- do {\
- data_t *data = NULL;\
- data = str_to_data (str_value);\
- if (!data)\
- goto error;\
- ret = dict_add (params_dict, param_key, data);\
- if (ret) {\
- gf_msg (comp_name, GF_LOG_ERROR, 0,\
- LG_MSG_SET_PARAM_FAILED, "Failed setting %s "\
- "to params dictionary", param_key);\
- goto error;\
- };\
- } while (0)
-
-/*get str_value of param_key from param_dict*/
-#define GET_DB_PARAM_FROM_DICT(comp_name, params_dict, param_key, str_value,\
- error)\
- do {\
- data_t *data = NULL;\
- data = dict_get (params_dict, param_key);\
- if (!data) {\
- gf_msg (comp_name, GF_LOG_ERROR, 0,\
- LG_MSG_GET_PARAM_FAILED, "Failed to retrieve "\
- "%s from params", param_key);\
- goto error;\
- } else {\
- str_value = data->data;\
- };\
- } while (0)
-
-
-/*get str_value of param_key from param_dict. if param_key is not present
- * set _default_v to str_value */
-#define GET_DB_PARAM_FROM_DICT_DEFAULT(comp_name, params_dict, param_key,\
- str_value, _default_v)\
- do {\
- data_t *data = NULL;\
- data = dict_get (params_dict, param_key);\
- if (!data) {\
- str_value = _default_v;\
- gf_msg (comp_name, GF_LOG_WARNING, 0,\
- LG_MSG_GET_PARAM_FAILED, "Failed to retrieve "\
- "%s from params.Assigning default value: %s",\
- param_key, _default_v);\
- } else {\
- str_value = data->data;\
- };\
- } while (0)
-
-
-#endif
-
-
diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3.c b/libglusterfs/src/gfdb/gfdb_sqlite3.c
deleted file mode 100644
index 08aa7d0a380..00000000000
--- a/libglusterfs/src/gfdb/gfdb_sqlite3.c
+++ /dev/null
@@ -1,1143 +0,0 @@
-/*
- Copyright (c) 2015 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 "gfdb_sqlite3.h"
-#include "gfdb_sqlite3_helper.h"
-#include "libglusterfs-messages.h"
-
-/******************************************************************************
- *
- * Util functions
- *
- * ***************************************************************************/
-gf_sql_connection_t *
-gf_sql_connection_init ()
-{
- gf_sql_connection_t *gf_sql_conn = NULL;
-
- gf_sql_conn = GF_CALLOC (1, sizeof(gf_sql_connection_t),
- gf_mt_sql_connection_t);
- if (gf_sql_conn == NULL) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, ENOMEM,
- LG_MSG_NO_MEMORY, "Error allocating memory to "
- "gf_sql_connection_t ");
- }
-
- return gf_sql_conn;
-}
-
-void
-gf_sql_connection_fini (gf_sql_connection_t **sql_connection)
-{
- if (!sql_connection)
- return;
- GF_FREE (*sql_connection);
- *sql_connection = NULL;
-}
-
-const char *
-gf_sql_jm2str (gf_sql_journal_mode_t jm)
-{
- switch (jm) {
- case gf_sql_jm_delete:
- return GF_SQL_JM_DELETE;
- case gf_sql_jm_truncate:
- return GF_SQL_JM_TRUNCATE;
- case gf_sql_jm_persist:
- return GF_SQL_JM_PERSIST;
- case gf_sql_jm_memory:
- return GF_SQL_JM_MEMORY;
- case gf_sql_jm_wal:
- return GF_SQL_JM_WAL;
- case gf_sql_jm_off:
- return GF_SQL_JM_OFF;
- case gf_sql_jm_invalid:
- break;
- }
- return NULL;
-}
-
-gf_sql_journal_mode_t
-gf_sql_str2jm (const char *jm_str)
-{
- if (!jm_str) {
- return gf_sql_jm_invalid;
- } else if (strcmp(jm_str, GF_SQL_JM_DELETE) == 0) {
- return gf_sql_jm_delete;
- } else if (strcmp(jm_str, GF_SQL_JM_TRUNCATE) == 0) {
- return gf_sql_jm_truncate;
- } else if (strcmp(jm_str, GF_SQL_JM_PERSIST) == 0) {
- return gf_sql_jm_persist;
- } else if (strcmp(jm_str, GF_SQL_JM_MEMORY) == 0) {
- return gf_sql_jm_memory;
- } else if (strcmp(jm_str, GF_SQL_JM_WAL) == 0) {
- return gf_sql_jm_wal;
- } else if (strcmp(jm_str, GF_SQL_JM_OFF) == 0) {
- return gf_sql_jm_off;
- }
- return gf_sql_jm_invalid;
-}
-
-const char *
-gf_sql_av_t2str (gf_sql_auto_vacuum_t sql_av)
-{
- switch (sql_av) {
- case gf_sql_av_none:
- return GF_SQL_AV_NONE;
- case gf_sql_av_full:
- return GF_SQL_AV_FULL;
- case gf_sql_av_incr:
- return GF_SQL_AV_INCR;
- case gf_sql_av_invalid:
- break;
- }
- return NULL;
-}
-
-gf_sql_auto_vacuum_t
-gf_sql_str2av_t (const char *av_str)
-{
- if (!av_str) {
- return gf_sql_sync_invalid;
- } else if (strcmp(av_str, GF_SQL_AV_NONE) == 0) {
- return gf_sql_av_none;
- } else if (strcmp(av_str, GF_SQL_AV_FULL) == 0) {
- return gf_sql_av_full;
- } else if (strcmp(av_str, GF_SQL_AV_INCR) == 0) {
- return gf_sql_av_incr;
- }
- return gf_sql_sync_invalid;
-}
-
-const char *
-gf_sync_t2str (gf_sql_sync_t sql_sync)
-{
- switch (sql_sync) {
- case gf_sql_sync_off:
- return GF_SQL_SYNC_OFF;
- case gf_sql_sync_normal:
- return GF_SQL_SYNC_NORMAL;
- case gf_sql_sync_full:
- return GF_SQL_SYNC_FULL;
- case gf_sql_sync_invalid:
- break;
- }
- return NULL;
-}
-
-gf_sql_sync_t
-gf_sql_str2sync_t (const char *sync_str)
-{
- if (!sync_str) {
- return gf_sql_sync_invalid;
- } else if (strcmp(sync_str, GF_SQL_SYNC_OFF) == 0) {
- return gf_sql_sync_off;
- } else if (strcmp(sync_str, GF_SQL_SYNC_NORMAL) == 0) {
- return gf_sql_sync_normal;
- } else if (strcmp(sync_str, GF_SQL_SYNC_FULL) == 0) {
- return gf_sql_sync_full;
- }
- return gf_sql_sync_invalid;
-}
-
-
-/*TODO replace GF_CALLOC by mem_pool or iobuff if required for performace */
-static char *
-sql_stmt_init ()
-{
- char *sql_stmt = NULL;
-
- sql_stmt = GF_CALLOC (GF_STMT_SIZE_MAX, sizeof(char),
- gf_common_mt_char);
-
- if (!sql_stmt) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, ENOMEM,
- LG_MSG_NO_MEMORY, "Error allocating memory to SQL "
- "Statement ");
- goto out;
- }
-out:
- return sql_stmt;
-}
-
-/*TODO replace GF_FREE by mem_pool or iobuff if required for performace */
-static void
-sql_stmt_fini (char **sql_stmt)
-{
- GF_FREE (*sql_stmt);
-}
-
-/******************************************************************************
- * DB Essential functions used by
- * > gf_open_sqlite3_conn ()
- * > gf_close_sqlite3_conn ()
- * ***************************************************************************/
-static sqlite3 *
-gf_open_sqlite3_conn(char *sqlite3_db_path, int flags)
-{
- sqlite3 *sqlite3_db_conn = NULL;
- int ret = -1;
-
- GF_ASSERT (sqlite3_db_path);
-
- /*Creates DB if not created*/
- ret = sqlite3_open_v2(sqlite3_db_path, &sqlite3_db_conn, flags, NULL);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_DB_ERROR,
- "FATAL: Could open %s : %s",
- sqlite3_db_path, sqlite3_errmsg(sqlite3_db_conn));
- }
- return sqlite3_db_conn;
-}
-
-static int
-gf_close_sqlite3_conn(sqlite3 *sqlite3_db_conn)
-{
- int ret = 0;
-
- GF_ASSERT (sqlite3_db_conn);
-
- if (sqlite3_db_conn) {
- ret = sqlite3_close (sqlite3_db_conn);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CONNECTION_ERROR, "FATAL: sqlite3 close"
- " connection failed %s",
- sqlite3_errmsg(sqlite3_db_conn));
- ret = -1;
- goto out;
- }
- }
- ret = 0;
-out:
- return ret;
-}
-
-/******************************************************************************
-*
-* Database init / fini / create table
-*
-* ***************************************************************************/
-
-
-/*Function to fill db operations*/
-void
-gf_sqlite3_fill_db_operations(gfdb_db_operations_t *gfdb_db_ops)
-{
- GF_ASSERT (gfdb_db_ops);
-
- gfdb_db_ops->init_db_op = gf_sqlite3_init;
- gfdb_db_ops->fini_db_op = gf_sqlite3_fini;
-
- gfdb_db_ops->insert_record_op = gf_sqlite3_insert;
- gfdb_db_ops->delete_record_op = gf_sqlite3_delete;
-
- gfdb_db_ops->find_all_op = gf_sqlite3_find_all;
- gfdb_db_ops->find_unchanged_for_time_op =
- gf_sqlite3_find_unchanged_for_time;
- gfdb_db_ops->find_recently_changed_files_op =
- gf_sqlite3_find_recently_changed_files;
- gfdb_db_ops->find_unchanged_for_time_freq_op =
- gf_sqlite3_find_unchanged_for_time_freq;
- gfdb_db_ops->find_recently_changed_files_freq_op =
- gf_sqlite3_find_recently_changed_files_freq;
-
- gfdb_db_ops->clear_files_heat_op = gf_sqlite3_clear_files_heat;
-}
-
-
-static int
-create_filetable (sqlite3 *sqlite3_db_conn)
-{
- int ret = -1;
- char *sql_stmt = NULL;
- char *sql_strerror = NULL;
-
- GF_ASSERT(sqlite3_db_conn);
-
- sql_stmt = sql_stmt_init();
- if (!sql_stmt) {
- ret = ENOMEM;
- goto out;
- }
-
- GF_CREATE_STMT(sql_stmt);
-
- ret = sqlite3_exec (sqlite3_db_conn, sql_stmt, NULL, NULL,
- &sql_strerror);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
- "Failed executing: %s : %s", sql_stmt, sql_strerror);
- sqlite3_free (sql_strerror);
- ret = -1;
- goto out;
- }
-
-
- ret = 0;
-out:
- sql_stmt_fini (&sql_stmt);
- return ret;
-}
-
-
-
-
-static int
-apply_sql_params_db(gf_sql_connection_t *sql_conn, dict_t *param_dict)
-{
- int ret = -1;
- char *temp_str = NULL;
- char sqlite3_config_str[PATH_MAX] = "";
-
- GF_ASSERT(sql_conn);
- GF_ASSERT(param_dict);
-
- /*Extract sql page_size from param_dict,
- * if not specified default value will be GF_SQL_DEFAULT_PAGE_SIZE*/
- temp_str = NULL;
- GET_DB_PARAM_FROM_DICT_DEFAULT(GFDB_STR_SQLITE3, param_dict,
- GFDB_SQL_PARAM_PAGE_SIZE, temp_str,
- GF_SQL_DEFAULT_PAGE_SIZE);
- sql_conn->page_size = atoi(temp_str);
- /*Apply page_size on the sqlite db*/
- GF_SQLITE3_SET_PRAGMA(sqlite3_config_str, "page_size", "%zd",
- sql_conn->page_size, ret, out);
-
-
-
- /*Extract sql cache size from param_dict,
- * if not specified default value will be
- * GF_SQL_DEFAULT_CACHE_SIZE pages*/
- temp_str = NULL;
- GET_DB_PARAM_FROM_DICT_DEFAULT(GFDB_STR_SQLITE3, param_dict,
- GFDB_SQL_PARAM_CACHE_SIZE, temp_str,
- GF_SQL_DEFAULT_CACHE_SIZE);
- sql_conn->cache_size = atoi(temp_str);
- /*Apply cache size on the sqlite db*/
- GF_SQLITE3_SET_PRAGMA(sqlite3_config_str, "cache_size", "%zd",
- sql_conn->cache_size, ret, out);
-
-
-
-
- /*Extract sql journal mode from param_dict,
- * if not specified default value will be
- * GF_SQL_DEFAULT_JOURNAL_MODE i.e "wal"*/
- temp_str = NULL;
- GET_DB_PARAM_FROM_DICT_DEFAULT(GFDB_STR_SQLITE3, param_dict,
- GFDB_SQL_PARAM_JOURNAL_MODE, temp_str,
- GF_SQL_DEFAULT_JOURNAL_MODE);
- sql_conn->journal_mode = gf_sql_str2jm (temp_str);
- /*Apply journal mode to the sqlite db*/
- GF_SQLITE3_SET_PRAGMA(sqlite3_config_str, "journal_mode", "%s",
- temp_str, ret, out);
-
-
-
- /*Only when the journal mode is WAL, wal_autocheckpoint makes sense*/
- if (sql_conn->journal_mode == gf_sql_jm_wal) {
- /*Extract sql wal auto check point from param_dict
- * if not specified default value will be
- * GF_SQL_DEFAULT_WAL_AUTOCHECKPOINT pages*/
- temp_str = NULL;
- GET_DB_PARAM_FROM_DICT_DEFAULT(GFDB_STR_SQLITE3, param_dict,
- GFDB_SQL_PARAM_WAL_AUTOCHECK, temp_str,
- GF_SQL_DEFAULT_WAL_AUTOCHECKPOINT);
- sql_conn->wal_autocheckpoint = atoi(temp_str);
- /*Apply wal auto check point to the sqlite db*/
- GF_SQLITE3_SET_PRAGMA(sqlite3_config_str, "wal_autocheckpoint",
- "%zd", sql_conn->wal_autocheckpoint, ret, out);
- }
-
-
-
- /*Extract sql synchronous from param_dict
- * if not specified default value will be GF_SQL_DEFAULT_SYNC*/
- temp_str = NULL;
- GET_DB_PARAM_FROM_DICT_DEFAULT(GFDB_STR_SQLITE3, param_dict,
- GFDB_SQL_PARAM_SYNC, temp_str, GF_SQL_DEFAULT_SYNC);
- sql_conn->synchronous = gf_sql_str2sync_t (temp_str);
- /*Apply synchronous to the sqlite db*/
- GF_SQLITE3_SET_PRAGMA(sqlite3_config_str, "synchronous", "%d",
- sql_conn->synchronous, ret, out);
-
-
-
- /*Extract sql auto_vacuum from param_dict
- * if not specified default value will be GF_SQL_DEFAULT_AUTO_VACUUM*/
- temp_str = NULL;
- GET_DB_PARAM_FROM_DICT_DEFAULT(GFDB_STR_SQLITE3, param_dict,
- GFDB_SQL_PARAM_AUTO_VACUUM, temp_str,
- GF_SQL_DEFAULT_AUTO_VACUUM);
- sql_conn->auto_vacuum = gf_sql_str2av_t (temp_str);
- /*Apply auto_vacuum to the sqlite db*/
- GF_SQLITE3_SET_PRAGMA(sqlite3_config_str, "auto_vacuum", "%d",
- sql_conn->auto_vacuum, ret, out);
-
- ret = 0;
-out:
- return ret;
-}
-
-
-
-int
-gf_sqlite3_init (dict_t *args, void **db_conn) {
- int ret = -1;
- gf_sql_connection_t *sql_conn = NULL;
- struct stat stbuf = {0,};
- gf_boolean_t is_dbfile_exist = _gf_false;
- char *temp_str = NULL;
-
- GF_ASSERT (args);
- GF_ASSERT (db_conn);
-
- if (*db_conn != NULL) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CONNECTION_ERROR, "DB Connection is not "
- "empty!");
- return 0;
- }
-
- if (!sqlite3_threadsafe()) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_NOT_MULTITHREAD_MODE,
- "sqlite3 is not in multithreaded mode");
- goto out;
- }
-
- sql_conn = gf_sql_connection_init ();
- if (!sql_conn) {
- goto out;
- }
-
- /*Extract sql db path from args*/
- temp_str = NULL;
- GET_DB_PARAM_FROM_DICT(GFDB_STR_SQLITE3, args,
- GFDB_SQL_PARAM_DBPATH, temp_str, out);
- strncpy(sql_conn->sqlite3_db_path, temp_str, PATH_MAX-1);
- sql_conn->sqlite3_db_path[PATH_MAX-1] = 0;
-
- is_dbfile_exist = (stat (sql_conn->sqlite3_db_path, &stbuf) == 0) ?
- _gf_true : _gf_false;
-
- /*Creates DB if not created*/
- sql_conn->sqlite3_db_conn = gf_open_sqlite3_conn (
- sql_conn->sqlite3_db_path,
- SQLITE_OPEN_READWRITE |
- SQLITE_OPEN_CREATE);
- if (!sql_conn->sqlite3_db_conn) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CONNECTION_ERROR,
- "Failed creating db connection");
- goto out;
- }
-
- /* If the file exist we skip the config part
- * and creation of the schema */
- if (is_dbfile_exist)
- goto db_exists;
-
-
- /*Apply sqlite3 params to database*/
- ret = apply_sql_params_db(sql_conn, args);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_SET_PARAM_FAILED, "Failed applying sql params"
- " to %s", sql_conn->sqlite3_db_path);
- goto out;
- }
-
- /*Create the schema if NOT present*/
- ret = create_filetable (sql_conn->sqlite3_db_conn);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED, "Failed Creating %s Table",
- GF_FILE_TABLE);
- goto out;
- }
-
-db_exists:
- ret = 0;
-out:
- if (ret) {
- gf_sqlite3_fini ((void **)&sql_conn);
- }
-
- *db_conn = sql_conn;
-
- return ret;
-}
-
-
-int
-gf_sqlite3_fini (void **db_conn)
-{
- int ret = -1;
- gf_sql_connection_t *sql_conn = NULL;
-
- GF_ASSERT (db_conn);
- sql_conn = *db_conn;
-
- if (sql_conn) {
- if (sql_conn->sqlite3_db_conn) {
- ret = gf_close_sqlite3_conn(sql_conn->sqlite3_db_conn);
- if (ret) {
- /*Logging of error done in
- * gf_close_sqlite3_conn()*/
- goto out;
- }
- sql_conn->sqlite3_db_conn = NULL;
- }
- gf_sql_connection_fini (&sql_conn);
- }
- *db_conn = sql_conn;
- ret = 0;
-out:
- return ret;
-}
-
-/******************************************************************************
- *
- * INSERT/UPDATE/DELETE Operations
- *
- *
- * ***************************************************************************/
-
-int gf_sqlite3_insert(void *db_conn, gfdb_db_record_t *gfdb_db_record)
-{
- int ret = -1;
- gf_sql_connection_t *sql_conn = db_conn;
-
- CHECK_SQL_CONN(sql_conn, out);
- GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, gfdb_db_record, out);
-
-
- /*This is for debugging bug. Will be removed with a bug fix*/
- if ((GFDB_FOP_WIND == gfdb_db_record->gfdb_fop_path) &&
- (strncmp(gfdb_db_record->file_path, "<gfid", 5) == 0)) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_SKIP_PATH,
- "Skip path <gfid fop=%d",
- gfdb_db_record->gfdb_fop_type);
- goto out;
- }
-
- switch (gfdb_db_record->gfdb_fop_path) {
- case GFDB_FOP_WIND:
- ret = gf_sql_insert_wind(sql_conn, gfdb_db_record);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_INSERT_FAILED, "Failed wind insert");
- goto out;
- }
- break;
- case GFDB_FOP_UNWIND:
- ret = gf_sql_insert_unwind (sql_conn, gfdb_db_record);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_INSERT_FAILED, "Failed unwind insert");
- goto out;
- }
- break;
-
- case GFDB_FOP_WDEL:
- ret = gf_sql_update_delete_wind(sql_conn, gfdb_db_record);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_UPDATE_FAILED, "Failed updating delete "
- "during wind");
- goto out;
- }
- break;
- case GFDB_FOP_UNDEL:
- case GFDB_FOP_UNDEL_ALL:
- ret = gf_sql_delete_unwind(sql_conn, gfdb_db_record);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_DELETE_FAILED, "Failed deleting");
- goto out;
- }
- break;
- case GFDB_FOP_INVALID:
- default:
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_INVALID_FOP,
- "Cannot record to DB: Invalid FOP");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-gf_sqlite3_delete(void *db_conn, gfdb_db_record_t *gfdb_db_record)
-{
- int ret = -1;
- gf_sql_connection_t *sql_conn = db_conn;
-
- CHECK_SQL_CONN(sql_conn, out);
- GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, gfdb_db_record, out);
-
- ret = 0;
-out:
- return ret;
-}
-
-/******************************************************************************
- *
- * SELECT QUERY FUNCTIONS
- *
- *
- * ***************************************************************************/
-
-/*
- * Find All files recorded in the DB
- * Input:
- * query_callback : query callback fuction to handle
- * result records from the query
- * */
-int
-gf_sqlite3_find_all (void *db_conn, gf_query_callback_t query_callback,
- void *query_cbk_args)
-{
- int ret = -1;
- char *query_str = NULL;
- gf_sql_connection_t *sql_conn = db_conn;
- sqlite3_stmt *prep_stmt = NULL;
-
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out);
-
- query_str = "select GF_FILE_TB.GF_ID,"
- " (select group_concat( GF_PID || ',' || FNAME || ','"
- " || FPATH || ',' || W_DEL_FLAG ||',' || LINK_UPDATE , '::')"
- " from GF_FLINK_TB where "
- "GF_FILE_TB.GF_ID = GF_FLINK_TB.GF_ID) from GF_FILE_TB ;";
-
-
- ret = sqlite3_prepare(sql_conn->sqlite3_db_conn, query_str, -1,
- &prep_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing statment %s :"
- "%s", query_str,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- ret = gf_sql_query_function(prep_stmt, query_callback, query_cbk_args);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
- "Failed Query %s", query_str);
- goto out;
- }
-
- ret = 0;
-out:
- sqlite3_finalize(prep_stmt);
- return ret;
-}
-
-
-/*
- * Find recently changed files from the DB
- * Input:
- * query_callback : query callback fuction to handle
- * result records from the query
- * from_time : Time to define what is recent
- * */
-int
-gf_sqlite3_find_recently_changed_files(void *db_conn,
- gf_query_callback_t query_callback,
- void *query_cbk_args,
- gfdb_time_t *from_time)
-{
- int ret = -1;
- char *query_str = NULL;
- gf_sql_connection_t *sql_conn = db_conn;
- sqlite3_stmt *prep_stmt = NULL;
- uint64_t from_time_usec = 0;
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out);
-
- query_str = "select GF_FILE_TB.GF_ID,"
- " (select group_concat( GF_PID || ',' || FNAME || ','"
- " || FPATH || ',' || W_DEL_FLAG ||',' || LINK_UPDATE , '::')"
- " from GF_FLINK_TB where GF_FILE_TB.GF_ID = GF_FLINK_TB.GF_ID)"
- " from GF_FILE_TB where "
- /*First condition: For writes*/
- "((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_WMSEC ") >= ? )"
- " OR "
- /*Second condition: For reads*/
- "((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_RWMSEC ") >= ?)";
-
- from_time_usec = gfdb_time_2_usec(from_time);
-
- ret = sqlite3_prepare(sql_conn->sqlite3_db_conn, query_str, -1,
- &prep_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing statment %s :"
- " %s", query_str,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind write wind time*/
- ret = sqlite3_bind_int64(prep_stmt, 1, from_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding from_time_usec "
- "%"PRIu64" : %s", from_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind read wind time*/
- ret = sqlite3_bind_int64(prep_stmt, 2, from_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding from_time_usec "
- "%"PRIu64" : %s ", from_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the query*/
- ret = gf_sql_query_function(prep_stmt, query_callback, query_cbk_args);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
- "Failed Query %s", query_str);
- goto out;
- }
-
- ret = 0;
-out:
- sqlite3_finalize(prep_stmt);
- return ret;
-}
-
-
-/*
- * Find unchanged files from a specified time from the DB
- * Input:
- * query_callback : query callback fuction to handle
- * result records from the query
- * for_time : Time from where the file/s are not changed
- * */
-int
-gf_sqlite3_find_unchanged_for_time (void *db_conn,
- gf_query_callback_t query_callback,
- void *query_cbk_args,
- gfdb_time_t *for_time)
-{
- int ret = -1;
- char *query_str = NULL;
- gf_sql_connection_t *sql_conn = db_conn;
- sqlite3_stmt *prep_stmt = NULL;
- uint64_t for_time_usec = 0;
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out);
-
- query_str = "select GF_FILE_TB.GF_ID,"
- " (select group_concat( GF_PID || ',' || FNAME || ','"
- " || FPATH || ',' || W_DEL_FLAG ||',' || LINK_UPDATE , '::')"
- " from GF_FLINK_TB where GF_FILE_TB.GF_ID = GF_FLINK_TB.GF_ID)"
- " from GF_FILE_TB where "
- /*First condition: For writes*/
- "((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_WMSEC ") <= ? )"
- " AND "
- /*Second condition: For reads*/
- "((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_RWMSEC ") <= ?)";
-
- for_time_usec = gfdb_time_2_usec(for_time);
-
- ret = sqlite3_prepare(sql_conn->sqlite3_db_conn, query_str, -1,
- &prep_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing statment %s :"
- " %s", query_str,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind write wind time*/
- ret = sqlite3_bind_int64(prep_stmt, 1, for_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
- "%"PRIu64" : %s", for_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind read wind time*/
- ret = sqlite3_bind_int64(prep_stmt, 2, for_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
- "%"PRIu64" : %s", for_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the query*/
- ret = gf_sql_query_function(prep_stmt, query_callback, query_cbk_args);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
- "Failed Query %s", query_str);
- goto out;
- }
-
- ret = 0;
-out:
- sqlite3_finalize(prep_stmt);
- return ret;
-}
-
-
-
-
-
-/*
- * Find recently changed files with a specific frequency from the DB
- * Input:
- * db_conn : db connection object
- * query_callback : query callback fuction to handle
- * result records from the query
- * from_time : Time to define what is recent
- * freq_write_cnt : Frequency thresold for write
- * freq_read_cnt : Frequency thresold for read
- * clear_counters : Clear counters (r/w) for all inodes in DB
- * */
-int
-gf_sqlite3_find_recently_changed_files_freq (void *db_conn,
- gf_query_callback_t query_callback,
- void *query_cbk_args,
- gfdb_time_t *from_time,
- int freq_write_cnt,
- int freq_read_cnt,
- gf_boolean_t clear_counters)
-{
- int ret = -1;
- char *query_str = NULL;
- gf_sql_connection_t *sql_conn = db_conn;
- sqlite3_stmt *prep_stmt = NULL;
- uint64_t from_time_usec = 0;
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, query_callback, out);
-
- query_str = "select GF_FILE_TB.GF_ID,"
- " (select group_concat( GF_PID || ',' || FNAME || ','"
- " || FPATH || ',' || W_DEL_FLAG ||',' || LINK_UPDATE , '::')"
- " from GF_FLINK_TB where GF_FILE_TB.GF_ID = GF_FLINK_TB.GF_ID)"
- " from GF_FILE_TB where "
- /*First condition: For Writes*/
- "( ((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_WMSEC ") >= ? )"
- " AND "" (" GF_COL_TB_WFC " >= ? ) )"
- " OR "
- /*Second condition: For Reads */
- "( ((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_RWMSEC ") >= ?)"
- " AND "" (" GF_COL_TB_RFC " >= ? ) )";
-
- from_time_usec = gfdb_time_2_usec(from_time);
-
- ret = sqlite3_prepare(sql_conn->sqlite3_db_conn, query_str, -1,
- &prep_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing statment %s :"
- " %s", query_str,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind write wind time*/
- ret = sqlite3_bind_int64(prep_stmt, 1, from_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding from_time_usec "
- "%"PRIu64" : %s", from_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind write frequency thresold*/
- ret = sqlite3_bind_int(prep_stmt, 2, freq_write_cnt);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding freq_write_cnt "
- "%d : %s", freq_write_cnt,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
-
- /*Bind read wind time*/
- ret = sqlite3_bind_int64(prep_stmt, 3, from_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding from_time_usec "
- "%"PRIu64" : %s", from_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind read frequency thresold*/
- ret = sqlite3_bind_int(prep_stmt, 4, freq_read_cnt);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding freq_read_cnt "
- "%d : %s", freq_read_cnt,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the query*/
- ret = gf_sql_query_function(prep_stmt, query_callback, query_cbk_args);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
- "Failed Query %s", query_str);
- goto out;
- }
-
-
-
- /*Clear counters*/
- if (clear_counters) {
- ret = gf_sql_clear_counters(sql_conn);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CLEAR_COUNTER_FAILED, "Failed clearing"
- " counters!");
- goto out;
- }
- }
- ret = 0;
-out:
- sqlite3_finalize (prep_stmt);
- return ret;
-}
-
-
-
-
-/*
- * Find unchanged files from a specified time, w.r.t to frequency, from the DB
- * Input:
- * query_callback : query callback fuction to handle
- * result records from the query
- * for_time : Time from where the file/s are not changed
- * freq_write_cnt : Frequency thresold for write
- * freq_read_cnt : Frequency thresold for read
- * clear_counters : Clear counters (r/w) for all inodes in DB
- * */
-int
-gf_sqlite3_find_unchanged_for_time_freq (void *db_conn,
- gf_query_callback_t query_callback,
- void *query_cbk_args,
- gfdb_time_t *for_time,
- int freq_write_cnt,
- int freq_read_cnt,
- gf_boolean_t clear_counters)
-{
- int ret = -1;
- char *query_str = NULL;
- gf_sql_connection_t *sql_conn = db_conn;
- sqlite3_stmt *prep_stmt = NULL;
- uint64_t for_time_usec = 0;
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, query_callback, out);
-
- query_str = "select GF_FILE_TB.GF_ID,"
- " (select group_concat( GF_PID || ',' || FNAME || ','"
- " || FPATH || ',' || W_DEL_FLAG ||',' || LINK_UPDATE , '::')"
- " from GF_FLINK_TB where GF_FILE_TB.GF_ID = GF_FLINK_TB.GF_ID)"
- " from GF_FILE_TB where "
- /*First condition: For Writes
- * Files that have write wind time smaller than for_time
- * OR
- * File that have write wind time greater than for_time,
- * but write_frequency less than freq_write_cnt*/
- "( ((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_WMSEC ") < ? )"
- " OR "
- "( (" GF_COL_TB_WFC " < ? ) AND"
- "((" GF_COL_TB_WSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_WMSEC ") >= ? ) ) )"
- " AND "
- /*Second condition: For Reads
- * Files that have read wind time smaller than for_time
- * OR
- * File that have read wind time greater than for_time,
- * but write_frequency less than freq_write_cnt*/
- "( ((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_RWMSEC ") < ? )"
- " OR "
- "( (" GF_COL_TB_RFC " < ? ) AND"
- "((" GF_COL_TB_RWSEC " * " TOSTRING(GFDB_MICROSEC) " + "
- GF_COL_TB_RWMSEC ") >= ? ) ) )";
-
-
- for_time_usec = gfdb_time_2_usec(for_time);
-
- ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, query_str, -1,
- &prep_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing delete "
- "statment %s : %s", query_str,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind write wind time*/
- ret = sqlite3_bind_int64 (prep_stmt, 1, for_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
- "%"PRIu64" : %s", for_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind write frequency thresold*/
- ret = sqlite3_bind_int (prep_stmt, 2, freq_write_cnt);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding freq_write_cnt"
- " %d : %s", freq_write_cnt,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind write wind time*/
- ret = sqlite3_bind_int64 (prep_stmt, 3, for_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
- "%"PRIu64" : %s", for_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
-
-
- /*Bind read wind time*/
- ret = sqlite3_bind_int64 (prep_stmt, 4, for_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
- "%"PRIu64" : %s", for_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind read frequency thresold*/
- ret = sqlite3_bind_int (prep_stmt, 5, freq_read_cnt);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding freq_read_cnt "
- "%d : %s", freq_read_cnt,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind read wind time*/
- ret = sqlite3_bind_int64 (prep_stmt, 6, for_time_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding for_time_usec "
- "%"PRIu64" : %s", for_time_usec,
- sqlite3_errmsg(sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the query*/
- ret = gf_sql_query_function (prep_stmt, query_callback, query_cbk_args);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
- "Failed Query %s", query_str);
- goto out;
- }
-
-
- /*Clear counters*/
- if (clear_counters) {
- ret = gf_sql_clear_counters (sql_conn);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CLEAR_COUNTER_FAILED, "Failed clearing "
- "counters!");
- goto out;
- }
- }
-
- ret = 0;
-out:
- sqlite3_finalize(prep_stmt);
- return ret;
-}
-
-
-int
-gf_sqlite3_clear_files_heat (void *db_conn)
-{
- int ret = -1;
- gf_sql_connection_t *sql_conn = db_conn;
-
- CHECK_SQL_CONN (sql_conn, out);
-
- ret = gf_sql_clear_counters (sql_conn);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CLEAR_COUNTER_FAILED, "Failed clearing "
- "files heat!");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3.h b/libglusterfs/src/gfdb/gfdb_sqlite3.h
deleted file mode 100644
index 7bcba5a54bd..00000000000
--- a/libglusterfs/src/gfdb/gfdb_sqlite3.h
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- Copyright (c) 2015 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 __GFDB_SQLITE3_H
-#define __GFDB_SQLITE3_H
-
-
-/*Sqlite3 header file*/
-#include <sqlite3.h>
-
-#include "logging.h"
-#include "gfdb_data_store_types.h"
-#include "gfdb_mem-types.h"
-#include "libglusterfs-messages.h"
-
-#define GF_STMT_SIZE_MAX 2048
-
-#define GF_DB_NAME "gfdb.db"
-#define GF_FILE_TABLE "GF_FILE_TB"
-#define GF_FILE_LINK_TABLE "GF_FLINK_TB"
-#define GF_MASTER_TABLE "sqlite_master"
-
-/*Since we have multiple tables to be created we put it in a transaction*/
-#define GF_CREATE_STMT(out_str)\
-do {\
- sprintf (out_str , "BEGIN; CREATE TABLE IF NOT EXISTS "\
- GF_FILE_TABLE\
- "(GF_ID TEXT PRIMARY KEY NOT NULL, "\
- "W_SEC INTEGER NOT NULL DEFAULT 0, "\
- "W_MSEC INTEGER NOT NULL DEFAULT 0, "\
- "UW_SEC INTEGER NOT NULL DEFAULT 0, "\
- "UW_MSEC INTEGER NOT NULL DEFAULT 0, "\
- "W_READ_SEC INTEGER NOT NULL DEFAULT 0, "\
- "W_READ_MSEC INTEGER NOT NULL DEFAULT 0, "\
- "UW_READ_SEC INTEGER NOT NULL DEFAULT 0, "\
- "UW_READ_MSEC INTEGER NOT NULL DEFAULT 0, "\
- "WRITE_FREQ_CNTR INTEGER NOT NULL DEFAULT 1, "\
- "READ_FREQ_CNTR INTEGER NOT NULL DEFAULT 1); "\
- "CREATE TABLE IF NOT EXISTS "\
- GF_FILE_LINK_TABLE\
- "(GF_ID TEXT NOT NULL, "\
- "GF_PID TEXT NOT NULL, "\
- "FNAME TEXT NOT NULL, "\
- "FPATH TEXT NOT NULL, "\
- "W_DEL_FLAG INTEGER NOT NULL DEFAULT 0, "\
- "LINK_UPDATE INTEGER NOT NULL DEFAULT 0, "\
- "PRIMARY KEY ( GF_ID, GF_PID, FNAME) "\
- ");"\
- "COMMIT;"\
- );;\
-} while (0)
-
-
-#define GF_COL_TB_WSEC GF_FILE_TABLE "." GF_COL_WSEC
-#define GF_COL_TB_WMSEC GF_FILE_TABLE "." GF_COL_WMSEC
-#define GF_COL_TB_UWSEC GF_FILE_TABLE "." GF_COL_UWSEC
-#define GF_COL_TB_UWMSEC GF_FILE_TABLE "." GF_COL_UWMSEC
-#define GF_COL_TB_RWSEC GF_FILE_TABLE "." GF_COL_WSEC_READ
-#define GF_COL_TB_RWMSEC GF_FILE_TABLE "." GF_COL_WMSEC_READ
-#define GF_COL_TB_RUWSEC GF_FILE_TABLE "." GF_COL_UWSEC_READ
-#define GF_COL_TB_RUWMSEC GF_FILE_TABLE "." GF_COL_UWMSEC_READ
-#define GF_COL_TB_WFC GF_FILE_TABLE "." GF_COL_WRITE_FREQ_CNTR
-#define GF_COL_TB_RFC GF_FILE_TABLE "." GF_COL_READ_FREQ_CNTR
-
-
-/*******************************************************************************
-* SQLITE3 Connection details and PRAGMA
-* ****************************************************************************/
-
-#define GF_SQL_AV_NONE "none"
-#define GF_SQL_AV_FULL "full"
-#define GF_SQL_AV_INCR "incr"
-
-
-#define GF_SQL_SYNC_OFF "off"
-#define GF_SQL_SYNC_NORMAL "normal"
-#define GF_SQL_SYNC_FULL "full"
-
-#define GF_SQL_JM_DELETE "delete"
-#define GF_SQL_JM_TRUNCATE "truncate"
-#define GF_SQL_JM_PERSIST "persist"
-#define GF_SQL_JM_MEMORY "memory"
-#define GF_SQL_JM_WAL "wal"
-#define GF_SQL_JM_OFF "off"
-
-
-typedef enum gf_sql_auto_vacuum {
- gf_sql_av_none = 0,
- gf_sql_av_full,
- gf_sql_av_incr,
- gf_sql_av_invalid
-} gf_sql_auto_vacuum_t;
-
-typedef enum gf_sql_sync {
- gf_sql_sync_off = 0,
- gf_sql_sync_normal,
- gf_sql_sync_full,
- gf_sql_sync_invalid
-} gf_sql_sync_t;
-
-
-typedef enum gf_sql_journal_mode {
- gf_sql_jm_wal = 0,
- gf_sql_jm_delete,
- gf_sql_jm_truncate,
- gf_sql_jm_persist,
- gf_sql_jm_memory,
- gf_sql_jm_off,
- gf_sql_jm_invalid
-} gf_sql_journal_mode_t;
-
-
-typedef struct gf_sql_connection {
- char sqlite3_db_path[PATH_MAX];
- sqlite3 *sqlite3_db_conn;
- ssize_t cache_size;
- ssize_t page_size;
- ssize_t wal_autocheckpoint;
- gf_sql_journal_mode_t journal_mode;
- gf_sql_sync_t synchronous;
- gf_sql_auto_vacuum_t auto_vacuum;
-} gf_sql_connection_t;
-
-
-
-#define CHECK_SQL_CONN(sql_conn, out)\
-do {\
- GF_VALIDATE_OR_GOTO(GFDB_STR_SQLITE3, sql_conn, out);\
- if (!sql_conn->sqlite3_db_conn) {\
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,\
- LG_MSG_CONNECTION_INIT_FAILED,\
- "sqlite3 connection not initialized");\
- goto out;\
- };\
-} while (0)
-
-#define GF_SQLITE3_SET_PRAGMA(sqlite3_config_str, param_key, format, value,\
- ret, error)\
-do {\
- sprintf(sqlite3_config_str, "PRAGMA " param_key " = " format , value);\
- ret = sqlite3_exec (sql_conn->sqlite3_db_conn, sqlite3_config_str,\
- NULL, NULL, NULL);\
- if (ret != SQLITE_OK) {\
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,\
- "Failed executing: %s : %s",\
- sqlite3_config_str, sqlite3_errmsg\
- (sql_conn->sqlite3_db_conn));\
- ret = -1;\
- goto error;\
- };\
-} while (0)
-
-/************************SQLITE3 PARAMS KEYS***********************************/
-#define GFDB_SQL_PARAM_DBPATH "sql-db-path"
-#define GFDB_SQL_PARAM_CACHE_SIZE "sql-db-cachesize"
-#define GFDB_SQL_PARAM_PAGE_SIZE "sql-db-pagesize"
-#define GFDB_SQL_PARAM_JOURNAL_MODE "sql-db-journalmode"
-#define GFDB_SQL_PARAM_WAL_AUTOCHECK "sql-db-wal-autocheckpoint"
-#define GFDB_SQL_PARAM_SYNC "sql-db-sync"
-#define GFDB_SQL_PARAM_AUTO_VACUUM "sql-db-autovacuum"
-
-#define GF_SQL_DEFAULT_DBPATH ""
-#define GF_SQL_DEFAULT_PAGE_SIZE "4096"
-#define GF_SQL_DEFAULT_CACHE_SIZE "1000"
-#define GF_SQL_DEFAULT_WAL_AUTOCHECKPOINT "1000"
-#define GF_SQL_DEFAULT_JOURNAL_MODE GF_SQL_JM_WAL
-#define GF_SQL_DEFAULT_SYNC GF_SQL_SYNC_NORMAL
-#define GF_SQL_DEFAULT_AUTO_VACUUM GF_SQL_AV_NONE
-
-
-/* Defines the indexs for sqlite params
- * The order should be maintained*/
-typedef enum sqlite_param_index {
- sql_dbpath_ix = 0,
- sql_pagesize_ix,
- sql_cachesize_ix,
- sql_journalmode_ix,
- sql_walautocheck_ix,
- sql_dbsync_ix,
- sql_autovacuum_ix,
- /*This should be in the end*/
- sql_index_max
-} sqlite_param_index_t;
-
-/* Array to hold the sqlite param keys
- * The order should be maintained as sqlite_param_index_t*/
-static char *sqlite_params_keys[] = {
- GFDB_SQL_PARAM_DBPATH,
- GFDB_SQL_PARAM_PAGE_SIZE,
- GFDB_SQL_PARAM_CACHE_SIZE,
- GFDB_SQL_PARAM_JOURNAL_MODE,
- GFDB_SQL_PARAM_WAL_AUTOCHECK,
- GFDB_SQL_PARAM_SYNC,
- GFDB_SQL_PARAM_AUTO_VACUUM
-};
-
-
-/* Array of default values for sqlite params
- * The order should be maintained as sqlite_param_index_t*/
-static char *sqlite_params_default_value[] = {
- GF_SQL_DEFAULT_DBPATH,
- GF_SQL_DEFAULT_PAGE_SIZE,
- GF_SQL_DEFAULT_CACHE_SIZE,
- GF_SQL_DEFAULT_JOURNAL_MODE,
- GF_SQL_DEFAULT_WAL_AUTOCHECKPOINT,
- GF_SQL_DEFAULT_SYNC,
- GF_SQL_DEFAULT_AUTO_VACUUM
-};
-
-/*Extract sql params from page_size to auto_vacumm
- * The dbpath is extracted in a different way*/
-static inline int
-gfdb_set_sql_params(char *comp_name, dict_t *from_dict, dict_t *to_dict)
-{
- sqlite_param_index_t sql_index = sql_pagesize_ix;
- char *_val_str = NULL;
- int ret = -1;
-
- GF_ASSERT (comp_name);
- GF_ASSERT (from_dict);
- GF_ASSERT (to_dict);
-
- /*Extact and Set of the sql params from page_size*/
- for (sql_index = sql_pagesize_ix; sql_index < sql_index_max;
- sql_index++) {
- _val_str = NULL;
- GET_DB_PARAM_FROM_DICT_DEFAULT (comp_name, from_dict,
- sqlite_params_keys[sql_index], _val_str,
- sqlite_params_default_value[sql_index]);
- SET_DB_PARAM_TO_DICT (comp_name, to_dict,
- sqlite_params_keys[sql_index], _val_str, ret, out);
- }
-out:
- return ret;
-}
-
-
-
-
-/*************************SQLITE3 GFDB PLUGINS*********************************/
-
-/*Db init and fini modules*/
-int gf_sqlite3_fini (void **db_conn);
-int gf_sqlite3_init (dict_t *args, void **db_conn);
-
-/*insert/update/delete modules*/
-int gf_sqlite3_insert (void *db_conn, gfdb_db_record_t *);
-int gf_sqlite3_delete (void *db_conn, gfdb_db_record_t *);
-
-/*querying modules*/
-int gf_sqlite3_find_all (void *db_conn, gf_query_callback_t,
- void *_query_cbk_args);
-int gf_sqlite3_find_unchanged_for_time (void *db_conn,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *for_time);
-int gf_sqlite3_find_recently_changed_files (void *db_conn,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *from_time);
-int gf_sqlite3_find_unchanged_for_time_freq (void *db_conn,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *for_time,
- int write_freq_cnt,
- int read_freq_cnt,
- gf_boolean_t clear_counters);
-int gf_sqlite3_find_recently_changed_files_freq (void *db_conn,
- gf_query_callback_t query_callback,
- void *_query_cbk_args,
- gfdb_time_t *from_time,
- int write_freq_cnt,
- int read_freq_cnt,
- gf_boolean_t clear_counters);
-
-int gf_sqlite3_clear_files_heat (void *db_conn);
-
-void gf_sqlite3_fill_db_operations (gfdb_db_operations_t *gfdb_db_ops);
-
-#endif
diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c b/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c
deleted file mode 100644
index 0cc294a5410..00000000000
--- a/libglusterfs/src/gfdb/gfdb_sqlite3_helper.c
+++ /dev/null
@@ -1,1217 +0,0 @@
-/*
- Copyright (c) 2015 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 "gfdb_sqlite3_helper.h"
-
-
-#define GFDB_SQL_STMT_SIZE 256
-
-/*****************************************************************************
- *
- * Helper function to execute actual sql queries
- *
- *
- * ****************************************************************************/
-
-static int
-gf_sql_delete_all (gf_sql_connection_t *sql_conn,
- char *gfid)
-{
- int ret = -1;
- sqlite3_stmt *delete_file_stmt = NULL;
- sqlite3_stmt *delete_link_stmt = NULL;
- char *delete_link_str = "DELETE FROM "
- GF_FILE_LINK_TABLE
- " WHERE GF_ID = ? ;";
- char *delete_file_str = "DELETE FROM "
- GF_FILE_TABLE
- " WHERE GF_ID = ? ;";
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
-
- /*
- * Delete all links associated with this GFID
- *
- * */
- /*Prepare statement for delete all links*/
- ret = sqlite3_prepare(sql_conn->sqlite3_db_conn, delete_link_str, -1,
- &delete_link_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing delete "
- "statment %s : %s", delete_link_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind gfid*/
- ret = sqlite3_bind_text (delete_link_stmt, 1, gfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
- gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
-
- /*Execute the prepare statement*/
- if (sqlite3_step (delete_link_stmt) != SQLITE_DONE) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
- "Failed executing the prepared stmt %s : %s",
- delete_link_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
-
- /*
- * Delete entry from file table associated with this GFID
- *
- * */
- /*Prepare statement for delete all links*/
- ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, delete_file_str, -1,
- &delete_file_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing delete "
- "statment %s : %s", delete_file_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind gfid*/
- ret = sqlite3_bind_text (delete_file_stmt, 1, gfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
- gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the prepare statement*/
- if (sqlite3_step (delete_file_stmt) != SQLITE_DONE) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
- "Failed executing the prepared stmt %s : %s",
- delete_file_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
-out:
- /*Free prepared statement*/
- sqlite3_finalize (delete_file_stmt);
- sqlite3_finalize (delete_link_stmt);
- return ret;
-}
-
-static int
-gf_sql_delete_link (gf_sql_connection_t *sql_conn,
- char *gfid,
- char *pargfid,
- char *basename)
-{
- int ret = -1;
- sqlite3_stmt *delete_stmt = NULL;
- char *delete_str = "DELETE FROM "
- GF_FILE_LINK_TABLE
- " WHERE GF_ID = ? AND GF_PID = ?"
- " AND FNAME = ?;";
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out);
-
- /*Prepare statement*/
- ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, delete_str, -1,
- &delete_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing delete "
- "statment %s : %s", delete_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind gfid*/
- ret = sqlite3_bind_text (delete_stmt, 1, gfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED,
- "Failed binding gfid %s : %s", gfid,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind pargfid*/
- ret = sqlite3_bind_text (delete_stmt, 2, pargfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding parent gfid %s "
- ": %s", pargfid,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind basename*/
- ret = sqlite3_bind_text (delete_stmt, 3, basename, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding basename %s : "
- "%s", basename,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the prepare statement*/
- if (sqlite3_step(delete_stmt) != SQLITE_DONE) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
- "Failed executing the prepared stmt %s : %s",
- delete_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
-
- ret = 0;
-out:
- /*Free prepared statement*/
- sqlite3_finalize (delete_stmt);
- return ret;
-}
-
-
-
-static int
-gf_sql_update_link_flags (gf_sql_connection_t *sql_conn,
- char *gfid,
- char *pargfid,
- char *basename,
- int update_flag,
- gf_boolean_t is_update_or_delete)
-{
- int ret = -1;
- sqlite3_stmt *update_stmt = NULL;
- char *update_column = NULL;
- char update_str[1024] = "";
-
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out);
-
- update_column = (is_update_or_delete) ? "LINK_UPDATE" : "W_DEL_FLAG";
-
- sprintf (update_str, "UPDATE "
- GF_FILE_LINK_TABLE
- " SET %s = ?"
- " WHERE GF_ID = ? AND GF_PID = ? AND FNAME = ?;",
- update_column);
-
- /*Prepare statement*/
- ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, update_str, -1,
- &update_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing update "
- "statment %s : %s", update_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
-
- /*Bind link_update*/
- ret = sqlite3_bind_int (update_stmt, 1, update_flag);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding update_flag %d "
- ": %s", update_flag,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind gfid*/
- ret = sqlite3_bind_text (update_stmt, 2, gfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
- gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind pargfid*/
- ret = sqlite3_bind_text (update_stmt, 3, pargfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding parent gfid %s "
- ": %s", pargfid,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind basename*/
- ret = sqlite3_bind_text (update_stmt, 4, basename, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding basename %s : "
- "%s", basename,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
-
- /*Execute the prepare statement*/
- if (sqlite3_step(update_stmt) != SQLITE_DONE) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
- "Failed executing the prepared stmt %s : %s",
- update_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- /*Free prepared statement*/
- sqlite3_finalize (update_stmt);
- return ret;
-}
-
-
-static int
-gf_sql_insert_link (gf_sql_connection_t *sql_conn,
- char *gfid,
- char *pargfid,
- char *basename,
- char *basepath,
- gf_boolean_t link_consistency,
- gf_boolean_t ignore_errors)
-{
- int ret = -1;
- sqlite3_stmt *insert_stmt = NULL;
- char insert_str[GFDB_SQL_STMT_SIZE] = "";
-
- sprintf (insert_str, "INSERT INTO "
- GF_FILE_LINK_TABLE
- " (GF_ID, GF_PID, FNAME, FPATH,"
- " W_DEL_FLAG, LINK_UPDATE) "
- " VALUES (?, ?, ?, ?, 0, %d);",
- link_consistency);
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basepath, out);
-
- /*Prepare statement*/
- ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, insert_str, -1,
- &insert_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3,
- _gfdb_log_level (GF_LOG_ERROR, ignore_errors),
- 0,
- LG_MSG_PREPARE_FAILED,
- "Failed preparing insert "
- "statment %s : %s", insert_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind gfid*/
- ret = sqlite3_bind_text (insert_stmt, 1, gfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3,
- _gfdb_log_level (GF_LOG_ERROR, ignore_errors),
- 0,
- LG_MSG_BINDING_FAILED,
- "Failed binding gfid %s : %s",
- gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind pargfid*/
- ret = sqlite3_bind_text (insert_stmt, 2, pargfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3,
- _gfdb_log_level (GF_LOG_ERROR, ignore_errors),
- 0, LG_MSG_BINDING_FAILED,
- "Failed binding parent gfid %s "
- ": %s", pargfid,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind basename*/
- ret = sqlite3_bind_text (insert_stmt, 3, basename, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3,
- _gfdb_log_level (GF_LOG_ERROR, ignore_errors),
- 0, LG_MSG_BINDING_FAILED,
- "Failed binding basename %s : %s", basename,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind basepath*/
- ret = sqlite3_bind_text (insert_stmt, 4, basepath, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3,
- _gfdb_log_level (GF_LOG_ERROR, ignore_errors), 0,
- LG_MSG_BINDING_FAILED,
- "Failed binding basepath %s : "
- "%s", basepath,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the prepare statement*/
- if (sqlite3_step (insert_stmt) != SQLITE_DONE) {
- gf_msg (GFDB_STR_SQLITE3,
- _gfdb_log_level (GF_LOG_ERROR, ignore_errors),
- 0, LG_MSG_EXEC_FAILED,
- "Failed executing the prepared "
- "stmt %s %s %s %s %s : %s",
- gfid, pargfid, basename, basepath, insert_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- /*Free prepared statement*/
- sqlite3_finalize (insert_stmt);
- return ret;
-}
-
-
-static int
-gf_sql_update_link (gf_sql_connection_t *sql_conn,
- char *gfid,
- char *pargfid,
- char *basename,
- char *basepath,
- char *old_pargfid,
- char *old_basename,
- gf_boolean_t link_consistency)
-{
- int ret = -1;
- sqlite3_stmt *insert_stmt = NULL;
- char insert_str[GFDB_SQL_STMT_SIZE] = "";
-
- sprintf (insert_str, "INSERT INTO "
- GF_FILE_LINK_TABLE
- " (GF_ID, GF_PID, FNAME, FPATH,"
- " W_DEL_FLAG, LINK_UPDATE) "
- " VALUES (? , ?, ?, ?, 0, %d);",
- link_consistency);
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, pargfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basename, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, basepath, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, old_pargfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, old_basename, out);
-
- /*
- *
- * Delete the old link
- *
- * */
- ret = gf_sql_delete_link (sql_conn, gfid, old_pargfid,
- old_basename);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_DELETE_FAILED, "Failed deleting old link");
- goto out;
- }
-
- /*
- *
- * insert new link
- *
- * */
- /*Prepare statement*/
- ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, insert_str, -1,
- &insert_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing insert "
- "statment %s : %s", insert_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind gfid*/
- ret = sqlite3_bind_text (insert_stmt, 1, gfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
- gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind new pargfid*/
- ret = sqlite3_bind_text (insert_stmt, 2, pargfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding parent gfid %s "
- ": %s", pargfid,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind new basename*/
- ret = sqlite3_bind_text (insert_stmt, 3, basename, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding basename %s : "
- "%s", basename,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind new basepath*/
- ret = sqlite3_bind_text (insert_stmt, 4, basepath, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding basename %s : "
- "%s", basepath,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the prepare statement*/
- if (sqlite3_step (insert_stmt) != SQLITE_DONE) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
- "Failed executing the prepared stmt %s : %s",
- insert_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
-
-
- ret = 0;
-out:
- /*Free prepared statement*/
- sqlite3_finalize (insert_stmt);
- return ret;
-}
-
-static int
-gf_sql_insert_write_wind_time (gf_sql_connection_t *sql_conn,
- char *gfid,
- gfdb_time_t *wind_time)
-{
- int ret = -1;
- sqlite3_stmt *insert_stmt = NULL;
- char *insert_str = "INSERT INTO "
- GF_FILE_TABLE
- "(GF_ID, W_SEC, W_MSEC, UW_SEC, UW_MSEC)"
- " VALUES (?, ?, ?, 0, 0);";
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, wind_time, out);
-
-
- /*Prepare statement*/
- ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, insert_str, -1,
- &insert_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing insert "
- "statment %s : %s", insert_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind gfid*/
- ret = sqlite3_bind_text (insert_stmt, 1, gfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
- gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind wind secs*/
- ret = sqlite3_bind_int (insert_stmt, 2, wind_time->tv_sec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding parent wind "
- "secs %ld : %s", wind_time->tv_sec,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind wind msecs*/
- ret = sqlite3_bind_int (insert_stmt, 3, wind_time->tv_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding parent wind "
- "msecs %ld : %s", wind_time->tv_usec,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the prepare statement*/
- if (sqlite3_step (insert_stmt) != SQLITE_DONE) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
- "Failed executing the prepared stmt GFID:%s %s : %s",
- gfid, insert_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- /*Free prepared statement*/
- sqlite3_finalize (insert_stmt);
- return ret;
-}
-
-
-
-/*Update write/read times for both wind and unwind*/
-static int
-gf_update_time (gf_sql_connection_t *sql_conn,
- char *gfid,
- gfdb_time_t *update_time,
- gf_boolean_t record_counter,
- gf_boolean_t is_wind,
- gf_boolean_t is_read)
-{
- int ret = -1;
- sqlite3_stmt *update_stmt = NULL;
- char update_str[1024] = "";
- char *freq_cntr_str = NULL;
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfid, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, update_time, out);
-
- /*
- * Constructing the prepare statment string.
- *
- * */
- /*For write time*/
- if (!is_read) {
- if (is_wind) {
- /*if record counter is on*/
- freq_cntr_str = (record_counter) ?
- ", WRITE_FREQ_CNTR = WRITE_FREQ_CNTR + 1" : "";
-
- /*Prefectly safe as we will not go array of bound*/
- sprintf (update_str, "UPDATE "
- GF_FILE_TABLE
- " SET W_SEC = ?, W_MSEC = ? "
- " %s"/*place for read freq counters*/
- " WHERE GF_ID = ? ;", freq_cntr_str);
- } else {
- /*Prefectly safe as we will not go array of bound*/
- sprintf (update_str, "UPDATE "
- GF_FILE_TABLE
- " SET UW_SEC = ?, UW_MSEC = ? ;");
- }
- }
- /*For Read Time update*/
- else {
- if (is_wind) {
- /*if record counter is on*/
- freq_cntr_str = (record_counter) ?
- ", READ_FREQ_CNTR = READ_FREQ_CNTR + 1" : "";
-
- /*Prefectly safe as we will not go array of bound*/
- sprintf (update_str, "UPDATE "
- GF_FILE_TABLE
- " SET W_READ_SEC = ?, W_READ_MSEC = ? "
- " %s"/*place for read freq counters*/
- " WHERE GF_ID = ? ;", freq_cntr_str);
- } else {
- /*Prefectly safe as we will not go array of bound*/
- sprintf (update_str, "UPDATE "
- GF_FILE_TABLE
- " SET UW_READ_SEC = ?, UW_READ_MSEC = ? ;");
- }
- }
-
- /*Prepare statement*/
- ret = sqlite3_prepare (sql_conn->sqlite3_db_conn, update_str, -1,
- &update_stmt, 0);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PREPARE_FAILED, "Failed preparing insert "
- "statment %s : %s", update_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind time secs*/
- ret = sqlite3_bind_int (update_stmt, 1, update_time->tv_sec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding parent wind "
- "secs %ld : %s", update_time->tv_sec,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind time msecs*/
- ret = sqlite3_bind_int (update_stmt, 2, update_time->tv_usec);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding parent wind "
- "msecs %ld : %s", update_time->tv_usec,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Bind gfid*/
- ret = sqlite3_bind_text (update_stmt, 3, gfid, -1, NULL);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_BINDING_FAILED, "Failed binding gfid %s : %s",
- gfid, sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- /*Execute the prepare statement*/
- if (sqlite3_step (update_stmt) != SQLITE_DONE) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
- "Failed executing the prepared stmt %s : %s",
- update_str,
- sqlite3_errmsg (sql_conn->sqlite3_db_conn));
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- /*Free prepared statement*/
- sqlite3_finalize (update_stmt);
- return ret;
-}
-
-/******************************************************************************
- *
- * Helper functions for gf_sqlite3_insert()
- *
- *
- * ****************************************************************************/
-
-int
-gf_sql_insert_wind (gf_sql_connection_t *sql_conn,
- gfdb_db_record_t *gfdb_db_record)
-{
- int ret = -1;
- gfdb_time_t *modtime = NULL;
- char *pargfid_str = NULL;
- char *gfid_str = NULL;
- char *old_pargfid_str = NULL;
- gf_boolean_t its_wind = _gf_true;/*remains true for this function*/
-
-
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);
-
-
- gfid_str = gf_strdup (uuid_utoa (gfdb_db_record->gfid));
- if (!gfid_str) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
- goto out;
- }
-
- modtime = &gfdb_db_record->gfdb_wind_change_time;
-
- /* handle all dentry based operations */
- if (isdentryfop (gfdb_db_record->gfdb_fop_type)) {
- /*Parent GFID is always set*/
- pargfid_str = gf_strdup (uuid_utoa (gfdb_db_record->pargfid));
- if (!pargfid_str) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED, "Creating gfid string "
- "failed.");
- goto out;
- }
-
- /* handle create, mknod */
- if (isdentrycreatefop (gfdb_db_record->gfdb_fop_type)) {
- /*insert link*/
- ret = gf_sql_insert_link(sql_conn,
- gfid_str, pargfid_str,
- gfdb_db_record->file_name,
- gfdb_db_record->file_path,
- gfdb_db_record->link_consistency,
- gfdb_db_record->ignore_errors);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_INSERT_FAILED, "Failed "
- "inserting link in DB");
- goto out;
- }
- gfdb_db_record->islinkupdate = gfdb_db_record->
- link_consistency;
-
- /*
- * Only for create/mknod insert wind time
- * for the first time
- * */
- ret = gf_sql_insert_write_wind_time (sql_conn, gfid_str,
- modtime);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_INSERT_FAILED, "Failed "
- "inserting wind time in DB");
- goto out;
- }
- goto out;
- }
- /*handle rename, link */
- else {
- /*rename*/
- if (strlen (gfdb_db_record->old_file_name) != 0) {
- old_pargfid_str = gf_strdup (uuid_utoa (
- gfdb_db_record->old_pargfid));
- if (!old_pargfid_str) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR,
- 0, LG_MSG_CREATE_FAILED,
- "Creating gfid string failed.");
- goto out;
- }
- ret = gf_sql_update_link (sql_conn, gfid_str,
- pargfid_str,
- gfdb_db_record->file_name,
- gfdb_db_record->file_path,
- old_pargfid_str,
- gfdb_db_record->old_file_name,
- gfdb_db_record->
- link_consistency);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR,
- 0, LG_MSG_UPDATE_FAILED,
- "Failed updating link");
- goto out;
- }
- gfdb_db_record->islinkupdate = gfdb_db_record->
- link_consistency;
- }
- /*link*/
- else {
- ret = gf_sql_insert_link (sql_conn,
- gfid_str, pargfid_str,
- gfdb_db_record->file_name,
- gfdb_db_record->file_path,
- gfdb_db_record->link_consistency,
- gfdb_db_record->ignore_errors);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR,
- 0, LG_MSG_INSERT_FAILED,
- "Failed inserting link in DB");
- goto out;
- }
- gfdb_db_record->islinkupdate = gfdb_db_record->
- link_consistency;
- }
- }
- }
-
- /* update times only when said!*/
- if (gfdb_db_record->do_record_times) {
- /*All fops update times read or write*/
- ret = gf_update_time (sql_conn, gfid_str, modtime,
- gfdb_db_record->do_record_counters,
- its_wind,
- isreadfop (gfdb_db_record->gfdb_fop_type));
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_UPDATE_FAILED, "Failed update wind time"
- " in DB");
- goto out;
- }
- }
-
- ret = 0;
-out:
- GF_FREE (gfid_str);
- GF_FREE (pargfid_str);
- GF_FREE (old_pargfid_str);
- return ret;
-}
-
-
-
-
-int
-gf_sql_insert_unwind (gf_sql_connection_t *sql_conn,
- gfdb_db_record_t *gfdb_db_record)
-{
-
- int ret = -1;
- gfdb_time_t *modtime = NULL;
- gf_boolean_t its_wind = _gf_true;/*remains true for this function*/
- char *gfid_str = NULL;
- char *pargfid_str = NULL;
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);
-
- gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid));
- if (!gfid_str) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
- goto out;
- }
-
- /*Only update if recording unwind is set*/
- if (gfdb_db_record->do_record_times &&
- gfdb_db_record->do_record_uwind_time) {
- modtime = &gfdb_db_record->gfdb_unwind_change_time;
- ret = gf_update_time (sql_conn, gfid_str, modtime,
- gfdb_db_record->do_record_counters,
- (!its_wind),
- isreadfop (gfdb_db_record->gfdb_fop_type));
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_UPDATE_FAILED, "Failed update unwind "
- "time in DB");
- goto out;
- }
- }
-
- /*For link creation and changes we use link updated*/
- if (gfdb_db_record->islinkupdate &&
- isdentryfop(gfdb_db_record->gfdb_fop_type)) {
-
- pargfid_str = gf_strdup(uuid_utoa(gfdb_db_record->pargfid));
- if (!pargfid_str) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED,
- "Creating pargfid_str string failed.");
- goto out;
- }
-
- ret = gf_sql_update_link_flags (sql_conn, gfid_str, pargfid_str,
- gfdb_db_record->file_name, 0, _gf_true);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_UPDATE_FAILED, "Failed updating link "
- "flags in unwind");
- goto out;
- }
- }
-
- ret = 0;
-out:
- GF_FREE (gfid_str);
- GF_FREE (pargfid_str);
- return ret;
-}
-
-
-int
-gf_sql_update_delete_wind (gf_sql_connection_t *sql_conn,
- gfdb_db_record_t *gfdb_db_record)
-{
- int ret = -1;
- char *gfid_str = NULL;
- char *pargfid_str = NULL;
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);
-
- gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid));
- if (!gfid_str) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
- goto out;
- }
-
- pargfid_str = gf_strdup (uuid_utoa(gfdb_db_record->pargfid));
- if (!pargfid_str) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED, "Creating pargfid_str "
- "string failed.");
- goto out;
- }
-
- if (gfdb_db_record->link_consistency) {
- ret = gf_sql_update_link_flags (sql_conn, gfid_str, pargfid_str,
- gfdb_db_record->file_name, 1,
- _gf_false);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_UPDATE_FAILED,
- "Failed updating link flags in wind");
- goto out;
- }
- }
-
- ret = 0;
-out:
- GF_FREE (gfid_str);
- GF_FREE (pargfid_str);
- return ret;
-}
-
-int
-gf_sql_delete_unwind (gf_sql_connection_t *sql_conn,
- gfdb_db_record_t *gfdb_db_record)
-{
- int ret = -1;
- char *gfid_str = NULL;
- char *pargfid_str = NULL;
- gfdb_time_t *modtime = NULL;
-
- CHECK_SQL_CONN (sql_conn, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, gfdb_db_record, out);
-
- gfid_str = gf_strdup (uuid_utoa(gfdb_db_record->gfid));
- if (!gfid_str) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED, "Creating gfid string failed.");
- goto out;
- }
-
- /*Nuke all the entries for this GFID from DB*/
- if (gfdb_db_record->gfdb_fop_path == GFDB_FOP_UNDEL_ALL) {
- gf_sql_delete_all(sql_conn, gfid_str);
- }
- /*Remove link entries only*/
- else if (gfdb_db_record->gfdb_fop_path == GFDB_FOP_UNDEL) {
-
- pargfid_str = gf_strdup(uuid_utoa(gfdb_db_record->pargfid));
- if (!pargfid_str) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED, "Creating pargfid_str "
- "string failed.");
- goto out;
- }
-
- /* Special performance case:
- * Updating wind time in unwind for delete. This is done here
- * as in the wind path we will not know whether its the last
- * link or not. For a last link there is not use to update any
- * wind or unwind time!*/
- if (gfdb_db_record->do_record_times) {
- /*Update the wind write times*/
- modtime = &gfdb_db_record->gfdb_wind_change_time;
- ret = gf_update_time (sql_conn, gfid_str, modtime,
- gfdb_db_record->do_record_counters,
- _gf_true,
- isreadfop (gfdb_db_record->gfdb_fop_type));
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_UPDATE_FAILED,
- "Failed update wind time in DB");
- goto out;
- }
- }
-
- modtime = &gfdb_db_record->gfdb_unwind_change_time;
-
- ret = gf_sql_delete_link(sql_conn, gfid_str, pargfid_str,
- gfdb_db_record->file_name);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_DELETE_FAILED, "Failed deleting link");
- goto out;
- }
-
- if (gfdb_db_record->do_record_times &&
- gfdb_db_record->do_record_uwind_time) {
- ret = gf_update_time (sql_conn, gfid_str, modtime,
- gfdb_db_record->do_record_counters,
- _gf_false,
- isreadfop(gfdb_db_record->gfdb_fop_type));
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_UPDATE_FAILED, "Failed update "
- "unwind time in DB");
- goto out;
- }
- }
- } else {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_INVALID_UPLINK, "Invalid unlink option");
- goto out;
- }
- ret = 0;
-out:
- GF_FREE (gfid_str);
- GF_FREE (pargfid_str);
- return ret;
-}
-
-/******************************************************************************
- *
- * Find/Query helper functions
- *
- * ****************************************************************************/
-int
-gf_sql_query_function (sqlite3_stmt *prep_stmt,
- gf_query_callback_t query_callback,
- void *_query_cbk_args)
-{
- int ret = -1;
- gfdb_query_record_t *gfdb_query_record = NULL;
- char *text_column = NULL;
- sqlite3 *db_conn = NULL;
-
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, prep_stmt, out);
- GF_VALIDATE_OR_GOTO (GFDB_STR_SQLITE3, query_callback, out);
-
- db_conn = sqlite3_db_handle(prep_stmt);
-
- gfdb_query_record = gfdb_query_record_init ();
- if (!gfdb_query_record) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_CREATE_FAILED, "Failed to create "
- "gfdb_query_record");
- goto out;
- }
-
- /*Loop to access queried rows*/
- while ((ret = sqlite3_step (prep_stmt)) == SQLITE_ROW) {
-
- /*Clear the query record*/
- memset (gfdb_query_record, 0, sizeof(*gfdb_query_record));
-
- if (sqlite3_column_count(prep_stmt) > 0) {
-
- /*Retriving GFID - column index is 0*/
- text_column = (char *)sqlite3_column_text
- (prep_stmt, 0);
- if (!text_column) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_GET_ID_FAILED, "Failed "
- "retriving GF_ID");
- goto out;
- }
- ret = gf_uuid_parse (text_column, gfdb_query_record->gfid);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_PARSE_FAILED, "Failed parsing "
- "GF_ID");
- goto out;
- }
-
- /*Retrive Link Buffer - column index 1*/
- text_column = (char *)sqlite3_column_text
- (prep_stmt, 1);
- /* Get link string. Do shallow copy here
- * query_callback function should do a
- * deep copy and then do operations on this field*/
- gfdb_query_record->_link_info_str = text_column;
- gfdb_query_record->link_info_size = strlen
- (text_column);
-
- /* Call the call back function provided*/
- ret = query_callback (gfdb_query_record,
- _query_cbk_args);
- if (ret) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_QUERY_CALL_BACK_FAILED,
- "Query Call back failed!");
- goto out;
- }
-
- }
-
- }
-
- if (ret != SQLITE_DONE) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
- LG_MSG_GET_RECORD_FAILED, "Failed retriving records "
- "from db : %s", sqlite3_errmsg (db_conn));
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- gfdb_query_record_fini (&gfdb_query_record);
- return ret;
-}
-
-
-
-int
-gf_sql_clear_counters (gf_sql_connection_t *sql_conn)
-{
- int ret = -1;
- char *sql_strerror = NULL;
- char *query_str = NULL;
-
- CHECK_SQL_CONN (sql_conn, out);
-
- query_str = "UPDATE "
- GF_FILE_TABLE
- " SET " GF_COL_READ_FREQ_CNTR " = 0 , "
- GF_COL_WRITE_FREQ_CNTR " = 0 ;";
-
- ret = sqlite3_exec (sql_conn->sqlite3_db_conn, query_str, NULL, NULL,
- &sql_strerror);
- if (ret != SQLITE_OK) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_EXEC_FAILED,
- "Failed executing: %s : %s",
- query_str, sql_strerror);
- sqlite3_free (sql_strerror);
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3_helper.h b/libglusterfs/src/gfdb/gfdb_sqlite3_helper.h
deleted file mode 100644
index 0d222305d01..00000000000
--- a/libglusterfs/src/gfdb/gfdb_sqlite3_helper.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- Copyright (c) 2015 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 __GFDB_SQLITE3_HELPER_H
-#define __GFDB_SQLITE3_HELPER_H
-
-
-#include "gfdb_sqlite3.h"
-
-/******************************************************************************
- *
- * Helper functions for gf_sqlite3_insert()
- *
- * ****************************************************************************/
-
-
-int
-gf_sql_insert_wind (gf_sql_connection_t *sql_conn,
- gfdb_db_record_t *gfdb_db_record);
-
-int
-gf_sql_insert_unwind (gf_sql_connection_t *sql_conn,
- gfdb_db_record_t *gfdb_db_record);
-
-
-int
-gf_sql_update_delete_wind (gf_sql_connection_t *sql_conn,
- gfdb_db_record_t *gfdb_db_record);
-
-int
-gf_sql_delete_unwind (gf_sql_connection_t *sql_conn,
- gfdb_db_record_t *gfdb_db_record);
-
-
-
-
-
-/******************************************************************************
- *
- * Find/Query helper functions
- *
- * ****************************************************************************/
-
-
-int
-gf_sql_query_function (sqlite3_stmt *prep_stmt,
- gf_query_callback_t query_callback,
- void *_query_cbk_args);
-
-int
-gf_sql_clear_counters (gf_sql_connection_t *sql_conn);
-
-#endif
diff --git a/libglusterfs/src/gidcache.c b/libglusterfs/src/gidcache.c
index f2d98abefc3..64a93802f76 100644
--- a/libglusterfs/src/gidcache.c
+++ b/libglusterfs/src/gidcache.c
@@ -8,45 +8,48 @@
cases as published by the Free Software Foundation.
*/
-#include "gidcache.h"
-#include "mem-pool.h"
+#include "glusterfs/gidcache.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/common-utils.h"
/*
* We treat this as a very simple set-associative LRU cache, with entries aged
* out after a configurable interval. Hardly rocket science, but lots of
* details to worry about.
*/
-#define BUCKET_START(p,n) ((p) + ((n) * AUX_GID_CACHE_ASSOC))
+#define BUCKET_START(p, n) ((p) + ((n)*AUX_GID_CACHE_ASSOC))
/*
* Initialize the cache.
*/
-int gid_cache_init(gid_cache_t *cache, uint32_t timeout)
+int
+gid_cache_init(gid_cache_t *cache, uint32_t timeout)
{
- if (!cache)
- return -1;
+ if (!cache)
+ return -1;
- LOCK_INIT(&cache->gc_lock);
- cache->gc_max_age = timeout;
- cache->gc_nbuckets = AUX_GID_CACHE_BUCKETS;
- memset(cache->gc_cache, 0, sizeof(gid_list_t) * AUX_GID_CACHE_SIZE);
+ LOCK_INIT(&cache->gc_lock);
+ cache->gc_max_age = timeout;
+ cache->gc_nbuckets = AUX_GID_CACHE_BUCKETS;
+ memset(cache->gc_cache, 0, sizeof(gid_list_t) * AUX_GID_CACHE_SIZE);
- return 0;
+ return 0;
}
/*
* Reconfigure the cache timeout.
*/
-int gid_cache_reconf(gid_cache_t *cache, uint32_t timeout)
+int
+gid_cache_reconf(gid_cache_t *cache, uint32_t timeout)
{
- if (!cache)
- return -1;
+ if (!cache)
+ return -1;
- LOCK(&cache->gc_lock);
- cache->gc_max_age = timeout;
- UNLOCK(&cache->gc_lock);
+ LOCK(&cache->gc_lock);
+ cache->gc_max_age = timeout;
+ UNLOCK(&cache->gc_lock);
- return 0;
+ return 0;
}
/*
@@ -54,153 +57,155 @@ int gid_cache_reconf(gid_cache_t *cache, uint32_t timeout)
* an additional allocation and memory copy. The caller should copy the data and
* release (unlock) the cache as soon as possible.
*/
-const gid_list_t *gid_cache_lookup(gid_cache_t *cache, uint64_t id,
- uint64_t uid, uint64_t gid)
+const gid_list_t *
+gid_cache_lookup(gid_cache_t *cache, uint64_t id, uint64_t uid, uint64_t gid)
{
- int bucket;
- int i;
- time_t now;
- const gid_list_t *agl;
-
- LOCK(&cache->gc_lock);
- now = time(NULL);
- bucket = id % cache->gc_nbuckets;
- agl = BUCKET_START(cache->gc_cache, bucket);
- for (i = 0; i < AUX_GID_CACHE_ASSOC; i++, agl++) {
- if (!agl->gl_list)
- continue;
- if (agl->gl_id != id)
- continue;
-
- /*
- @uid and @gid reflect the latest UID/GID of the
- process performing the syscall (taken from frame->root).
-
- If the UID and GID has changed for the PID since the
- time we cached it, we should treat the cache as having
- stale values and query them freshly.
- */
- if (agl->gl_uid != uid || agl->gl_gid != gid)
- break;
-
- /*
- * We don't put new entries in the cache when expiration=0, but
- * there might be entries still in there if expiration was
- * changed very recently. Writing the check this way ensures
- * that they're not used.
- */
- if (now < agl->gl_deadline) {
- return agl;
- }
-
- /*
- * We're not going to find any more UID matches, and reaping
- * is handled further down to maintain LRU order.
- */
- break;
- }
- UNLOCK(&cache->gc_lock);
- return NULL;
+ int bucket;
+ int i;
+ time_t now;
+ const gid_list_t *agl;
+
+ now = gf_time();
+ LOCK(&cache->gc_lock);
+ bucket = id % cache->gc_nbuckets;
+ agl = BUCKET_START(cache->gc_cache, bucket);
+ for (i = 0; i < AUX_GID_CACHE_ASSOC; i++, agl++) {
+ if (!agl->gl_list)
+ continue;
+ if (agl->gl_id != id)
+ continue;
+
+ /*
+ @uid and @gid reflect the latest UID/GID of the
+ process performing the syscall (taken from frame->root).
+
+ If the UID and GID has changed for the PID since the
+ time we cached it, we should treat the cache as having
+ stale values and query them freshly.
+ */
+ if (agl->gl_uid != uid || agl->gl_gid != gid)
+ break;
+
+ /*
+ * We don't put new entries in the cache when expiration=0, but
+ * there might be entries still in there if expiration was
+ * changed very recently. Writing the check this way ensures
+ * that they're not used.
+ */
+ if (now < agl->gl_deadline) {
+ return agl;
+ }
+
+ /*
+ * We're not going to find any more UID matches, and reaping
+ * is handled further down to maintain LRU order.
+ */
+ break;
+ }
+ UNLOCK(&cache->gc_lock);
+ return NULL;
}
/*
* Release an entry found via lookup.
*/
-void gid_cache_release(gid_cache_t *cache, const gid_list_t *agl)
+void
+gid_cache_release(gid_cache_t *cache, const gid_list_t *agl)
{
- UNLOCK(&cache->gc_lock);
+ UNLOCK(&cache->gc_lock);
}
/*
* Add a new list entry to the cache. If an entry for this ID already exists,
* update it.
*/
-int gid_cache_add(gid_cache_t *cache, gid_list_t *gl)
+int
+gid_cache_add(gid_cache_t *cache, gid_list_t *gl)
{
- gid_list_t *agl;
- int bucket;
- int i;
- time_t now;
-
- if (!gl || !gl->gl_list)
- return -1;
-
- if (!cache->gc_max_age)
- return 0;
-
- LOCK(&cache->gc_lock);
- now = time(NULL);
-
- /*
- * Scan for the first free entry or one that matches this id. The id
- * check is added to address a bug where the cache might contain an
- * expired entry for this id. Since lookup occurs in LRU order and
- * does not reclaim entries, it will always return failure on discovery
- * of an expired entry. This leads to duplicate entries being added,
- * which still do not satisfy lookups until the expired entry (and
- * everything before it) is reclaimed.
- *
- * We address this through reuse of an entry already allocated to this
- * id, whether expired or not, since we have obviously already received
- * more recent data. The entry is repopulated with the new data and a new
- * deadline and is pushed forward to reside as the last populated entry in
- * the bucket.
- */
- bucket = gl->gl_id % cache->gc_nbuckets;
- agl = BUCKET_START(cache->gc_cache, bucket);
- for (i = 0; i < AUX_GID_CACHE_ASSOC; ++i, ++agl) {
- if (agl->gl_id == gl->gl_id)
- break;
- if (!agl->gl_list)
- break;
- }
-
- /*
- * The way we allocate free entries naturally places the newest
- * ones at the highest indices, so evicting the lowest makes
- * sense, but that also means we can't just replace it with the
- * one that caused the eviction. That would cause us to thrash
- * the first entry while others remain idle. Therefore, we
- * need to slide the other entries down and add the new one at
- * the end just as if the *last* slot had been free.
- *
- * Deadline expiration is also handled here, since the oldest
- * expired entry will be in the first position. This does mean
- * the bucket can stay full of expired entries if we're idle
- * but, if the small amount of extra memory or scan time before
- * we decide to evict someone ever become issues, we could
- * easily add a reaper thread.
- */
-
- if (i >= AUX_GID_CACHE_ASSOC) {
- /* cache full, evict the first (LRU) entry */
- i = 0;
- agl = BUCKET_START(cache->gc_cache, bucket);
- GF_FREE(agl->gl_list);
- } else if (agl->gl_list) {
- /* evict the old entry we plan to reuse */
- GF_FREE(agl->gl_list);
- }
-
- /*
- * If we have evicted an entry, slide the subsequent populated entries
- * back and populate the last entry.
- */
- for (; i < AUX_GID_CACHE_ASSOC - 1; i++) {
- if (!agl[1].gl_list)
- break;
- agl[0] = agl[1];
- agl++;
- }
-
- agl->gl_id = gl->gl_id;
- agl->gl_uid = gl->gl_uid;
- agl->gl_gid = gl->gl_gid;
- agl->gl_count = gl->gl_count;
- agl->gl_list = gl->gl_list;
- agl->gl_deadline = now + cache->gc_max_age;
-
- UNLOCK(&cache->gc_lock);
-
- return 1;
+ gid_list_t *agl;
+ int bucket;
+ int i;
+ time_t now;
+
+ if (!gl || !gl->gl_list)
+ return -1;
+
+ if (!cache->gc_max_age)
+ return 0;
+
+ now = gf_time();
+ LOCK(&cache->gc_lock);
+
+ /*
+ * Scan for the first free entry or one that matches this id. The id
+ * check is added to address a bug where the cache might contain an
+ * expired entry for this id. Since lookup occurs in LRU order and
+ * does not reclaim entries, it will always return failure on discovery
+ * of an expired entry. This leads to duplicate entries being added,
+ * which still do not satisfy lookups until the expired entry (and
+ * everything before it) is reclaimed.
+ *
+ * We address this through reuse of an entry already allocated to this
+ * id, whether expired or not, since we have obviously already received
+ * more recent data. The entry is repopulated with the new data and a new
+ * deadline and is pushed forward to reside as the last populated entry in
+ * the bucket.
+ */
+ bucket = gl->gl_id % cache->gc_nbuckets;
+ agl = BUCKET_START(cache->gc_cache, bucket);
+ for (i = 0; i < AUX_GID_CACHE_ASSOC; ++i, ++agl) {
+ if (agl->gl_id == gl->gl_id)
+ break;
+ if (!agl->gl_list)
+ break;
+ }
+
+ /*
+ * The way we allocate free entries naturally places the newest
+ * ones at the highest indices, so evicting the lowest makes
+ * sense, but that also means we can't just replace it with the
+ * one that caused the eviction. That would cause us to thrash
+ * the first entry while others remain idle. Therefore, we
+ * need to slide the other entries down and add the new one at
+ * the end just as if the *last* slot had been free.
+ *
+ * Deadline expiration is also handled here, since the oldest
+ * expired entry will be in the first position. This does mean
+ * the bucket can stay full of expired entries if we're idle
+ * but, if the small amount of extra memory or scan time before
+ * we decide to evict someone ever become issues, we could
+ * easily add a reaper thread.
+ */
+
+ if (i >= AUX_GID_CACHE_ASSOC) {
+ /* cache full, evict the first (LRU) entry */
+ i = 0;
+ agl = BUCKET_START(cache->gc_cache, bucket);
+ GF_FREE(agl->gl_list);
+ } else if (agl->gl_list) {
+ /* evict the old entry we plan to reuse */
+ GF_FREE(agl->gl_list);
+ }
+
+ /*
+ * If we have evicted an entry, slide the subsequent populated entries
+ * back and populate the last entry.
+ */
+ for (; i < AUX_GID_CACHE_ASSOC - 1; i++) {
+ if (!agl[1].gl_list)
+ break;
+ agl[0] = agl[1];
+ agl++;
+ }
+
+ agl->gl_id = gl->gl_id;
+ agl->gl_uid = gl->gl_uid;
+ agl->gl_gid = gl->gl_gid;
+ agl->gl_count = gl->gl_count;
+ agl->gl_list = gl->gl_list;
+ agl->gl_deadline = now + cache->gc_max_age;
+
+ UNLOCK(&cache->gc_lock);
+
+ return 1;
}
diff --git a/libglusterfs/src/glfs-message-id.h b/libglusterfs/src/glfs-message-id.h
deleted file mode 100644
index 025ff5b24eb..00000000000
--- a/libglusterfs/src/glfs-message-id.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#ifndef _GLFS_MESSAGE_ID_H_
-#define _GLFS_MESSAGE_ID_H_
-
-/* Base of all message IDs, all message IDs would be
- * greater than this */
-#define GLFS_MSGID_BASE 100000
-
-/* Segment size of allocated range. Any component needing more than this
- * segment size should take multiple segments (at times non contiguous,
- * if extensions are being made post the next segment already allocated) */
-#define GLFS_MSGID_SEGMENT 1000
-
-/* Per module message segments allocated */
-/* NOTE: For any new module add to the end the modules */
-#define GLFS_MSGID_COMP_GLUSTERFSD GLFS_MSGID_BASE
-#define GLFS_MSGID_COMP_GLUSTERFSD_END GLFS_MSGID_COMP_GLUSTERFSD + \
- GLFS_MSGID_SEGMENT
-
-#define GLFS_MSGID_COMP_LIBGLUSTERFS GLFS_MSGID_COMP_GLUSTERFSD_END
-#define GLFS_MSGID_COMP_LIBGLUSTERFS_END GLFS_MSGID_COMP_LIBGLUSTERFS + \
- GLFS_MSGID_SEGMENT
-
-#define GLFS_MSGID_COMP_RPC_LIB GLFS_MSGID_COMP_LIBGLUSTERFS_END
-#define GLFS_MSGID_COMP_RPC_LIB_END GLFS_MSGID_COMP_RPC_LIB + \
- GLFS_MSGID_SEGMENT
-
-#define GLFS_MSGID_COMP_RPC_TRANS_RDMA GLFS_MSGID_COMP_RPC_LIB_END
-#define GLFS_MSGID_COMP_RPC_TRANS_RDMA_END (GLFS_MSGID_COMP_RPC_TRANS_RDMA + \
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_API GLFS_MSGID_COMP_RPC_TRANS_RDMA_END
-#define GLFS_MSGID_COMP_API_END GLFS_MSGID_COMP_API + \
- GLFS_MSGID_SEGMENT
-
-#define GLFS_MSGID_COMP_CLI GLFS_MSGID_COMP_API_END
-#define GLFS_MSGID_COMP_CLI_END GLFS_MSGID_COMP_CLI + \
- GLFS_MSGID_SEGMENT
-
-/* glusterd has a lot of messages, taking 2 segments for the same */
-#define GLFS_MSGID_GLUSTERD GLFS_MSGID_COMP_CLI_END
-#define GLFS_MSGID_GLUSTERD_END GLFS_MSGID_GLUSTERD + \
- GLFS_MSGID_SEGMENT + \
- GLFS_MSGID_SEGMENT
-
-#define GLFS_MSGID_COMP_AFR GLFS_MSGID_GLUSTERD_END
-#define GLFS_MSGID_COMP_AFR_END GLFS_MSGID_COMP_AFR +\
- GLFS_MSGID_SEGMENT
-
-#define GLFS_MSGID_COMP_DHT GLFS_MSGID_COMP_AFR_END
-#define GLFS_MSGID_COMP_DHT_END GLFS_MSGID_COMP_DHT +\
- GLFS_MSGID_SEGMENT
-
-
-/* there is no component called 'common', however reserving this segment
- * for common actions/errors like dict_{get/set}, memory accounting*/
-
-#define GLFS_MSGID_COMP_COMMON GLFS_MSGID_COMP_DHT_END
-#define GLFS_MSGID_COMP_COMMON_END (GLFS_MSGID_COMP_COMMON +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_UPCALL GLFS_MSGID_COMP_COMMON_END
-#define GLFS_MSGID_COMP_UPCALL_END (GLFS_MSGID_COMP_UPCALL +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_NFS GLFS_MSGID_COMP_UPCALL_END
-#define GLFS_MSGID_COMP_NFS_END (GLFS_MSGID_COMP_NFS +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_POSIX GLFS_MSGID_COMP_NFS_END
-#define GLFS_MSGID_COMP_POSIX_END (GLFS_MSGID_COMP_POSIX +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_PC GLFS_MSGID_COMP_POSIX_END
-#define GLFS_MSGID_COMP_PC_END (GLFS_MSGID_COMP_PC +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_PS GLFS_MSGID_COMP_PC_END
-#define GLFS_MSGID_COMP_PS_END (GLFS_MSGID_COMP_PS +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_BITROT_STUB GLFS_MSGID_COMP_PS_END
-#define GLFS_MSGID_COMP_BITROT_STUB_END (GLFS_MSGID_COMP_BITROT_STUB +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_CHANGELOG GLFS_MSGID_COMP_BITROT_STUB_END
-#define GLFS_MSGID_COMP_CHANGELOG_END (GLFS_MSGID_COMP_CHANGELOG +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_BITROT_BITD GLFS_MSGID_COMP_CHANGELOG_END
-#define GLFS_MSGID_COMP_BITROT_BITD_END (GLFS_MSGID_COMP_BITROT_BITD +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_RPC_TRANS_SOCKET GLFS_MSGID_COMP_BITROT_BITD_END
-#define GLFS_MSGID_COMP_RPC_TRANS_SOCKET_END (GLFS_MSGID_COMP_RPC_TRANS_SOCKET + \
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_QUOTA GLFS_MSGID_COMP_RPC_TRANS_SOCKET_END
-#define GLFS_MSGID_COMP_QUOTA_END (GLFS_MSGID_COMP_QUOTA +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_CTR GLFS_MSGID_COMP_QUOTA_END
-#define GLFS_MSGID_COMP_CTR_END (GLFS_MSGID_COMP_CTR+\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_EC GLFS_MSGID_COMP_CTR_END
-#define GLFS_MSGID_COMP_EC_END (GLFS_MSGID_COMP_EC +\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_IO_CACHE GLFS_MSGID_COMP_EC_END
-#define GLFS_MSGID_COMP_IO_CACHE_END (GLFS_MSGID_COMP_IO_CACHE+\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_IO_THREADS GLFS_MSGID_COMP_IO_CACHE_END
-#define GLFS_MSGID_COMP_IO_THREADS_END (GLFS_MSGID_COMP_IO_THREADS+\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_MD_CACHE GLFS_MSGID_COMP_IO_THREADS_END
-#define GLFS_MSGID_COMP_MD_CACHE_END (GLFS_MSGID_COMP_MD_CACHE+\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_OPEN_BEHIND GLFS_MSGID_COMP_MD_CACHE_END
-#define GLFS_MSGID_COMP_OPEN_BEHIND_END (GLFS_MSGID_COMP_OPEN_BEHIND+\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_QUICK_READ GLFS_MSGID_COMP_OPEN_BEHIND_END
-#define GLFS_MSGID_COMP_QUICK_READ_END (GLFS_MSGID_COMP_QUICK_READ+\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_READ_AHEAD GLFS_MSGID_COMP_QUICK_READ_END
-#define GLFS_MSGID_COMP_READ_AHEAD_END (GLFS_MSGID_COMP_READ_AHEAD+\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_READDIR_AHEAD GLFS_MSGID_COMP_READ_AHEAD_END
-#define GLFS_MSGID_COMP_READDIR_AHEAD_END (GLFS_MSGID_COMP_READDIR_AHEAD+\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_SYMLINK_CACHE \
-GLFS_MSGID_COMP_READDIR_AHEAD_END
-#define GLFS_MSGID_COMP_SYMLINK_CACHE_END \
-(GLFS_MSGID_COMP_SYMLINK_CACHE+ \
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_WRITE_BEHIND \
-GLFS_MSGID_COMP_SYMLINK_CACHE_END
-#define GLFS_MSGID_COMP_WRITE_BEHIND_END (GLFS_MSGID_COMP_WRITE_BEHIND+\
- GLFS_MSGID_SEGMENT)
-
-#define GLFS_MSGID_COMP_CHANGELOG_LIB GLFS_MSGID_COMP_WRITE_BEHIND_END
-#define GLFS_MSGID_COMP_CHANGELOG_LIB_END (GLFS_MSGID_COMP_CHANGELOG_LIB+\
- GLFS_MSGID_SEGMENT)
-
-/* --- new segments for messages goes above this line --- */
-
-#endif /* !_GLFS_MESSAGE_ID_H_ */
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c
index 4f48cd169b5..ae06f8be386 100644
--- a/libglusterfs/src/globals.c
+++ b/libglusterfs/src/globals.c
@@ -10,385 +10,357 @@
#include <pthread.h>
-#include "glusterfs.h"
-#include "globals.h"
-#include "xlator.h"
-#include "mem-pool.h"
-#include "syncop.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/syncop.h"
+#include "glusterfs/libglusterfs-messages.h"
const char *gf_fop_list[GF_FOP_MAXVALUE] = {
- [GF_FOP_NULL] = "NULL",
- [GF_FOP_STAT] = "STAT",
- [GF_FOP_READLINK] = "READLINK",
- [GF_FOP_MKNOD] = "MKNOD",
- [GF_FOP_MKDIR] = "MKDIR",
- [GF_FOP_UNLINK] = "UNLINK",
- [GF_FOP_RMDIR] = "RMDIR",
- [GF_FOP_SYMLINK] = "SYMLINK",
- [GF_FOP_RENAME] = "RENAME",
- [GF_FOP_LINK] = "LINK",
- [GF_FOP_TRUNCATE] = "TRUNCATE",
- [GF_FOP_OPEN] = "OPEN",
- [GF_FOP_READ] = "READ",
- [GF_FOP_WRITE] = "WRITE",
- [GF_FOP_STATFS] = "STATFS",
- [GF_FOP_FLUSH] = "FLUSH",
- [GF_FOP_FSYNC] = "FSYNC",
- [GF_FOP_SETXATTR] = "SETXATTR",
- [GF_FOP_GETXATTR] = "GETXATTR",
- [GF_FOP_REMOVEXATTR] = "REMOVEXATTR",
- [GF_FOP_OPENDIR] = "OPENDIR",
- [GF_FOP_FSYNCDIR] = "FSYNCDIR",
- [GF_FOP_ACCESS] = "ACCESS",
- [GF_FOP_CREATE] = "CREATE",
- [GF_FOP_FTRUNCATE] = "FTRUNCATE",
- [GF_FOP_FSTAT] = "FSTAT",
- [GF_FOP_LK] = "LK",
- [GF_FOP_LOOKUP] = "LOOKUP",
- [GF_FOP_READDIR] = "READDIR",
- [GF_FOP_INODELK] = "INODELK",
- [GF_FOP_FINODELK] = "FINODELK",
- [GF_FOP_ENTRYLK] = "ENTRYLK",
- [GF_FOP_FENTRYLK] = "FENTRYLK",
- [GF_FOP_XATTROP] = "XATTROP",
- [GF_FOP_FXATTROP] = "FXATTROP",
- [GF_FOP_FSETXATTR] = "FSETXATTR",
- [GF_FOP_FGETXATTR] = "FGETXATTR",
- [GF_FOP_RCHECKSUM] = "RCHECKSUM",
- [GF_FOP_SETATTR] = "SETATTR",
- [GF_FOP_FSETATTR] = "FSETATTR",
- [GF_FOP_READDIRP] = "READDIRP",
- [GF_FOP_GETSPEC] = "GETSPEC",
- [GF_FOP_FORGET] = "FORGET",
- [GF_FOP_RELEASE] = "RELEASE",
- [GF_FOP_RELEASEDIR] = "RELEASEDIR",
- [GF_FOP_FREMOVEXATTR]= "FREMOVEXATTR",
- [GF_FOP_FALLOCATE] = "FALLOCATE",
- [GF_FOP_DISCARD] = "DISCARD",
- [GF_FOP_ZEROFILL] = "ZEROFILL",
- [GF_FOP_IPC] = "IPC",
+ [GF_FOP_NULL] = "NULL",
+ [GF_FOP_STAT] = "STAT",
+ [GF_FOP_READLINK] = "READLINK",
+ [GF_FOP_MKNOD] = "MKNOD",
+ [GF_FOP_MKDIR] = "MKDIR",
+ [GF_FOP_UNLINK] = "UNLINK",
+ [GF_FOP_RMDIR] = "RMDIR",
+ [GF_FOP_SYMLINK] = "SYMLINK",
+ [GF_FOP_RENAME] = "RENAME",
+ [GF_FOP_LINK] = "LINK",
+ [GF_FOP_TRUNCATE] = "TRUNCATE",
+ [GF_FOP_OPEN] = "OPEN",
+ [GF_FOP_READ] = "READ",
+ [GF_FOP_WRITE] = "WRITE",
+ [GF_FOP_STATFS] = "STATFS",
+ [GF_FOP_FLUSH] = "FLUSH",
+ [GF_FOP_FSYNC] = "FSYNC",
+ [GF_FOP_SETXATTR] = "SETXATTR",
+ [GF_FOP_GETXATTR] = "GETXATTR",
+ [GF_FOP_REMOVEXATTR] = "REMOVEXATTR",
+ [GF_FOP_OPENDIR] = "OPENDIR",
+ [GF_FOP_FSYNCDIR] = "FSYNCDIR",
+ [GF_FOP_ACCESS] = "ACCESS",
+ [GF_FOP_CREATE] = "CREATE",
+ [GF_FOP_FTRUNCATE] = "FTRUNCATE",
+ [GF_FOP_FSTAT] = "FSTAT",
+ [GF_FOP_LK] = "LK",
+ [GF_FOP_LOOKUP] = "LOOKUP",
+ [GF_FOP_READDIR] = "READDIR",
+ [GF_FOP_INODELK] = "INODELK",
+ [GF_FOP_FINODELK] = "FINODELK",
+ [GF_FOP_ENTRYLK] = "ENTRYLK",
+ [GF_FOP_FENTRYLK] = "FENTRYLK",
+ [GF_FOP_XATTROP] = "XATTROP",
+ [GF_FOP_FXATTROP] = "FXATTROP",
+ [GF_FOP_FSETXATTR] = "FSETXATTR",
+ [GF_FOP_FGETXATTR] = "FGETXATTR",
+ [GF_FOP_RCHECKSUM] = "RCHECKSUM",
+ [GF_FOP_SETATTR] = "SETATTR",
+ [GF_FOP_FSETATTR] = "FSETATTR",
+ [GF_FOP_READDIRP] = "READDIRP",
+ [GF_FOP_GETSPEC] = "GETSPEC",
+ [GF_FOP_FORGET] = "FORGET",
+ [GF_FOP_RELEASE] = "RELEASE",
+ [GF_FOP_RELEASEDIR] = "RELEASEDIR",
+ [GF_FOP_FREMOVEXATTR] = "FREMOVEXATTR",
+ [GF_FOP_FALLOCATE] = "FALLOCATE",
+ [GF_FOP_DISCARD] = "DISCARD",
+ [GF_FOP_ZEROFILL] = "ZEROFILL",
+ [GF_FOP_IPC] = "IPC",
+ [GF_FOP_SEEK] = "SEEK",
+ [GF_FOP_LEASE] = "LEASE",
+ [GF_FOP_COMPOUND] = "COMPOUND",
+ [GF_FOP_GETACTIVELK] = "GETACTIVELK",
+ [GF_FOP_SETACTIVELK] = "SETACTIVELK",
+ [GF_FOP_PUT] = "PUT",
+ [GF_FOP_ICREATE] = "ICREATE",
+ [GF_FOP_NAMELINK] = "NAMELINK",
+ [GF_FOP_COPY_FILE_RANGE] = "COPY_FILE_RANGE",
};
+
+const char *gf_upcall_list[GF_UPCALL_FLAGS_MAXVALUE] = {
+ [GF_UPCALL_NULL] = "NULL",
+ [GF_UPCALL] = "UPCALL",
+ [GF_UPCALL_CI_STAT] = "CI_IATT",
+ [GF_UPCALL_CI_XATTR] = "CI_XATTR",
+ [GF_UPCALL_CI_RENAME] = "CI_RENAME",
+ [GF_UPCALL_CI_NLINK] = "CI_UNLINK",
+ [GF_UPCALL_CI_FORGET] = "CI_FORGET",
+ [GF_UPCALL_LEASE_RECALL] = "LEASE_RECALL",
+};
+
/* THIS */
+/* This global ctx is a bad hack to prevent some of the libgfapi crashes.
+ * This should be removed once the patch on resource pool is accepted
+ */
+glusterfs_ctx_t *global_ctx = NULL;
+pthread_mutex_t global_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
xlator_t global_xlator;
-static pthread_key_t this_xlator_key;
-static pthread_key_t synctask_key;
-static pthread_key_t uuid_buf_key;
-static char global_uuid_buf[GF_UUID_BUF_SIZE];
-static pthread_key_t lkowner_buf_key;
-static char global_lkowner_buf[GF_LKOWNER_BUF_SIZE];
static int gf_global_mem_acct_enable = 1;
static pthread_once_t globals_inited = PTHREAD_ONCE_INIT;
+static pthread_key_t free_key;
+
+static __thread xlator_t *thread_xlator = NULL;
+static __thread void *thread_synctask = NULL;
+static __thread void *thread_leaseid = NULL;
+static __thread struct syncopctx thread_syncopctx = {};
+static __thread char thread_uuid_buf[GF_UUID_BUF_SIZE] = {};
+static __thread char thread_lkowner_buf[GF_LKOWNER_BUF_SIZE] = {};
+static __thread char thread_leaseid_buf[GF_LEASE_ID_BUF_SIZE] = {};
int
-gf_global_mem_acct_enable_get (void)
+gf_global_mem_acct_enable_get(void)
{
- return gf_global_mem_acct_enable;
+ return gf_global_mem_acct_enable;
}
int
-gf_global_mem_acct_enable_set (int val)
+gf_global_mem_acct_enable_set(int val)
{
- gf_global_mem_acct_enable = val;
- return 0;
+ gf_global_mem_acct_enable = val;
+ return 0;
}
-void
-glusterfs_this_destroy (void *ptr)
-{
- FREE (ptr);
-}
+static struct xlator_cbks global_cbks = {
+ .forget = NULL,
+ .release = NULL,
+ .releasedir = NULL,
+ .invalidate = NULL,
+ .client_destroy = NULL,
+ .client_disconnect = NULL,
+ .ictxmerge = NULL,
+ .ictxsize = NULL,
+ .fdctxsize = NULL,
+};
+/* This is required to get through the check in graph.c */
+static struct xlator_fops global_fops = {};
-int
-glusterfs_this_init ()
+static int
+global_xl_reconfigure(xlator_t *this, dict_t *options)
{
- int ret = 0;
+ int ret = -1;
+ gf_boolean_t bool_opt = _gf_false;
- ret = pthread_key_create (&this_xlator_key, glusterfs_this_destroy);
- if (ret != 0) {
- gf_msg ("", GF_LOG_WARNING, ret,
- LG_MSG_PTHREAD_KEY_CREATE_FAILED, "failed to create "
- "the pthread key");
- return ret;
- }
+ /* This is not added in volume dump, hence adding the options in log
+ would be helpful for debugging later */
+ dict_dump_to_log(options);
- global_xlator.name = "glusterfs";
- global_xlator.type = "global";
+ GF_OPTION_RECONF("measure-latency", bool_opt, options, bool, out);
+ this->ctx->measure_latency = bool_opt;
- INIT_LIST_HEAD (&global_xlator.volume_options);
+ GF_OPTION_RECONF("metrics-dump-path", this->ctx->config.metrics_dumppath,
+ options, str, out);
- return ret;
-}
-
-
-xlator_t **
-__glusterfs_this_location ()
-{
- xlator_t **this_location = NULL;
- int ret = 0;
-
- this_location = pthread_getspecific (this_xlator_key);
-
- if (!this_location) {
- this_location = CALLOC (1, sizeof (*this_location));
- if (!this_location)
- goto out;
-
- ret = pthread_setspecific (this_xlator_key, this_location);
- if (ret != 0) {
- FREE (this_location);
- this_location = NULL;
- goto out;
- }
- }
+ /* TODO: add more things here */
+ ret = 0;
out:
- if (this_location) {
- if (!*this_location)
- *this_location = &global_xlator;
- }
- return this_location;
+ return ret;
}
-
-xlator_t *
-glusterfs_this_get ()
+static int
+global_xl_init(xlator_t *this)
{
- xlator_t **this_location = NULL;
-
- this_location = __glusterfs_this_location ();
- if (!this_location)
- return &global_xlator;
+ int ret = -1;
+ gf_boolean_t bool_opt = false;
- return *this_location;
-}
-
-
-int
-glusterfs_this_set (xlator_t *this)
-{
- xlator_t **this_location = NULL;
+ GF_OPTION_INIT("measure-latency", bool_opt, bool, out);
+ this->ctx->measure_latency = bool_opt;
- this_location = __glusterfs_this_location ();
- if (!this_location)
- return -ENOMEM;
+ GF_OPTION_INIT("metrics-dump-path", this->ctx->config.metrics_dumppath, str,
+ out);
- *this_location = this;
+ ret = 0;
- return 0;
+out:
+ return ret;
}
-/* SYNCOPCTX */
-static pthread_key_t syncopctx_key;
-
static void
-syncopctx_key_destroy (void *ptr)
+global_xl_fini(xlator_t *this)
{
- struct syncopctx *opctx = ptr;
+ return;
+}
- if (opctx) {
- if (opctx->groups)
- GF_FREE (opctx->groups);
+struct volume_options global_xl_options[] = {
+ {.key = {"measure-latency"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "no",
+ .op_version = {GD_OP_VERSION_4_0_0},
+ .flags = OPT_FLAG_SETTABLE,
+ .tags = {"global", "context"},
+ .description = "Use this option to toggle measuring latency"},
+ {.key = {"metrics-dump-path"},
+ .type = GF_OPTION_TYPE_STR,
+ .default_value = "{{gluster_workdir}}/metrics",
+ .op_version = {GD_OP_VERSION_4_0_0},
+ .flags = OPT_FLAG_SETTABLE,
+ .tags = {"global", "context"},
+ .description = "Use this option to set the metrics dump path"},
+
+ {
+ .key = {NULL},
+ },
+};
- GF_FREE (opctx);
- }
+static volume_opt_list_t global_xl_opt_list;
- return;
+void
+glusterfs_this_init()
+{
+ global_xlator.name = "glusterfs";
+ global_xlator.type = GF_GLOBAL_XLATOR_NAME;
+ global_xlator.cbks = &global_cbks;
+ global_xlator.fops = &global_fops;
+ global_xlator.reconfigure = global_xl_reconfigure;
+ global_xlator.init = global_xl_init;
+ global_xlator.fini = global_xl_fini;
+
+ INIT_LIST_HEAD(&global_xlator.volume_options);
+ INIT_LIST_HEAD(&global_xl_opt_list.list);
+ global_xl_opt_list.given_opt = global_xl_options;
+
+ list_add_tail(&global_xl_opt_list.list, &global_xlator.volume_options);
}
-void *
-syncopctx_getctx ()
+xlator_t **
+__glusterfs_this_location()
{
- void *opctx = NULL;
+ xlator_t **this_location;
- opctx = pthread_getspecific (syncopctx_key);
+ this_location = &thread_xlator;
+ if (*this_location == NULL) {
+ thread_xlator = &global_xlator;
+ }
- return opctx;
+ return this_location;
}
-int
-syncopctx_setctx (void *ctx)
+xlator_t *
+glusterfs_this_get()
{
- int ret = 0;
-
- ret = pthread_setspecific (syncopctx_key, ctx);
-
- return ret;
+ return *__glusterfs_this_location();
}
-static int
-syncopctx_init (void)
+void
+glusterfs_this_set(xlator_t *this)
{
- int ret;
+ thread_xlator = this;
+}
- ret = pthread_key_create (&syncopctx_key, syncopctx_key_destroy);
+/* SYNCOPCTX */
- return ret;
+void *
+syncopctx_getctx()
+{
+ return &thread_syncopctx;
}
/* SYNCTASK */
-int
-synctask_init ()
+void *
+synctask_get()
{
- int ret = 0;
-
- ret = pthread_key_create (&synctask_key, NULL);
-
- return ret;
+ return thread_synctask;
}
-void *
-synctask_get ()
+void
+synctask_set(void *synctask)
{
- void *synctask = NULL;
-
- synctask = pthread_getspecific (synctask_key);
-
- return synctask;
+ thread_synctask = synctask;
}
+// UUID_BUFFER
-int
-synctask_set (void *synctask)
+char *
+glusterfs_uuid_buf_get()
{
- int ret = 0;
-
- pthread_setspecific (synctask_key, synctask);
-
- return ret;
+ return thread_uuid_buf;
}
-//UUID_BUFFER
+/* LKOWNER_BUFFER */
-void
-glusterfs_uuid_buf_destroy (void *ptr)
+char *
+glusterfs_lkowner_buf_get()
{
- FREE (ptr);
+ return thread_lkowner_buf;
}
-int
-glusterfs_uuid_buf_init ()
-{
- int ret = 0;
-
- ret = pthread_key_create (&uuid_buf_key,
- glusterfs_uuid_buf_destroy);
- return ret;
-}
+/* Leaseid buffer */
char *
-glusterfs_uuid_buf_get ()
+glusterfs_leaseid_buf_get()
{
- char *buf;
- int ret = 0;
-
- buf = pthread_getspecific (uuid_buf_key);
- if(!buf) {
- buf = MALLOC (GF_UUID_BUF_SIZE);
- ret = pthread_setspecific (uuid_buf_key, (void *) buf);
- if (ret)
- buf = global_uuid_buf;
- }
- return buf;
-}
+ char *buf = NULL;
-/* LKOWNER_BUFFER */
+ buf = thread_leaseid;
+ if (buf == NULL) {
+ buf = thread_leaseid_buf;
+ thread_leaseid = buf;
+ }
-void
-glusterfs_lkowner_buf_destroy (void *ptr)
+ return buf;
+}
+
+char *
+glusterfs_leaseid_exist()
{
- FREE (ptr);
+ return thread_leaseid;
}
-int
-glusterfs_lkowner_buf_init ()
+static void
+glusterfs_cleanup(void *ptr)
{
- int ret = 0;
+ if (thread_syncopctx.groups != NULL) {
+ GF_FREE(thread_syncopctx.groups);
+ }
- ret = pthread_key_create (&lkowner_buf_key,
- glusterfs_lkowner_buf_destroy);
- return ret;
+ mem_pool_thread_destructor(NULL);
}
-char *
-glusterfs_lkowner_buf_get ()
+void
+gf_thread_needs_cleanup(void)
{
- 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;
+ /* The value stored in free_key TLS is not really used for anything, but
+ * pthread implementation doesn't call the TLS destruction function unless
+ * it's != NULL. This function must be called whenever something is
+ * allocated for this thread so that glusterfs_cleanup() will be called
+ * and resources can be released. */
+ (void)pthread_setspecific(free_key, (void *)1);
}
static void
-gf_globals_init_once ()
+gf_globals_init_once()
{
- int ret = 0;
-
- ret = glusterfs_this_init ();
- if (ret) {
- gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_TRANSLATOR_INIT_FAILED,
- "ERROR: glusterfs-translator init failed");
- goto out;
- }
-
- ret = glusterfs_uuid_buf_init ();
- if(ret) {
- gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_UUID_BUF_INIT_FAILED,
- "ERROR: glusterfs uuid buffer init failed");
- goto out;
- }
-
- ret = glusterfs_lkowner_buf_init ();
- if(ret) {
- gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_LKOWNER_BUF_INIT_FAILED,
- "ERROR: glusterfs lkowner buffer init failed");
- goto out;
- }
-
- ret = synctask_init ();
- if (ret) {
- gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCTASK_INIT_FAILED,
- "ERROR: glusterfs synctask init failed");
- goto out;
- }
-
- ret = syncopctx_init ();
- if (ret) {
- gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_SYNCOPCTX_INIT_FAILED,
- "ERROR: glusterfs syncopctx init failed");
- goto out;
- }
-out:
+ int ret = 0;
+
+ glusterfs_this_init();
+
+ /* This is needed only to cleanup the potential allocation of
+ * thread_syncopctx.groups. */
+ ret = pthread_key_create(&free_key, glusterfs_cleanup);
+ if (ret != 0) {
+ gf_msg("", GF_LOG_ERROR, ret, LG_MSG_PTHREAD_KEY_CREATE_FAILED,
+ "failed to create the pthread key");
+
+ gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_GLOBAL_INIT_FAILED,
+ "Exiting as global initialization failed");
- if (ret) {
- gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_GLOBAL_INIT_FAILED,
- "Exiting as global initialization failed");
- exit (ret);
- }
+ exit(ret);
+ }
}
int
-glusterfs_globals_init (glusterfs_ctx_t *ctx)
+glusterfs_globals_init(glusterfs_ctx_t *ctx)
{
- int ret = 0;
+ int ret = 0;
- gf_log_globals_init (ctx);
+ gf_log_globals_init(ctx, GF_LOG_INFO);
- ret = pthread_once (&globals_inited, gf_globals_init_once);
+ ret = pthread_once(&globals_inited, gf_globals_init_once);
- if (ret)
- gf_msg ("", GF_LOG_CRITICAL, ret, LG_MSG_PTHREAD_FAILED,
- "pthread_once failed");
+ if (ret)
+ gf_msg("", GF_LOG_CRITICAL, ret, LG_MSG_PTHREAD_FAILED,
+ "pthread_once failed");
- return ret;
+ return ret;
}
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
deleted file mode 100644
index 46c9ca27f6c..00000000000
--- a/libglusterfs/src/globals.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- 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
-#define _GLOBALS_H
-
-#define GF_DEFAULT_BASE_PORT 24007
-
-#define GD_OP_VERSION_KEY "operating-version"
-#define GD_MIN_OP_VERSION_KEY "minimum-operating-version"
-#define GD_MAX_OP_VERSION_KEY "maximum-operating-version"
-
-/* Gluster versions - OP-VERSION mapping
- *
- * 3.3.x - 1
- * 3.4.x - 2
- * 3.5.0 - 3
- * 3.5.1 - 30501
- * 3.6.0 - 30600
- * 3.7.0 - 30700
- * 3.7.1 - 30701
- * 3.7.2 - 30702
- *
- * Starting with Gluster v3.6, the op-version will be multi-digit integer values
- * based on the Glusterfs version, instead of a simply incrementing integer
- * value. The op-version for a given X.Y.Z release will be an integer XYZ, with
- * Y and Z 2 digit always 2 digits wide and padded with 0 when needed. This
- * should allow for some gaps between two Y releases for backports of features
- * in Z releases.
- */
-#define GD_OP_VERSION_MIN 1 /* MIN is the fresh start op-version, mostly
- should not change */
-#define GD_OP_VERSION_MAX GD_OP_VERSION_3_7_4 /* MAX VERSION is the maximum
- count in VME table, should
- keep changing with
- introduction of newer
- versions */
-
-#define GD_OP_VERSION_3_6_0 30600 /* Op-Version for GlusterFS 3.6.0 */
-
-#define GD_OP_VERSION_3_7_0 30700 /* Op-version for GlusterFS 3.7.0 */
-
-#define GD_OP_VERSION_3_7_1 30701 /* Op-version for GlusterFS 3.7.1 */
-
-#define GD_OP_VERSION_3_7_2 30702 /* Op-version for GlusterFS 3.7.2 */
-
-#define GD_OP_VERSION_3_7_3 30703 /* Op-version for GlusterFS 3.7.3 */
-
-#define GD_OP_VERSION_3_7_4 30704 /* Op-version for GlusterFS 3.7.4 */
-
-#define GD_OP_VER_PERSISTENT_AFR_XATTRS GD_OP_VERSION_3_6_0
-
-#include "xlator.h"
-
-/* THIS */
-#define THIS (*__glusterfs_this_location())
-#define DECLARE_OLD_THIS xlator_t *old_THIS = THIS
-
-xlator_t **__glusterfs_this_location ();
-xlator_t *glusterfs_this_get ();
-int glusterfs_this_set (xlator_t *);
-
-/* syncopctx */
-void *syncopctx_getctx ();
-int syncopctx_setctx (void *ctx);
-
-/* task */
-void *synctask_get ();
-int synctask_set (void *);
-
-/* uuid_buf */
-char *glusterfs_uuid_buf_get ();
-/* lkowner_buf */
-char *glusterfs_lkowner_buf_get ();
-
-/* init */
-int glusterfs_globals_init (glusterfs_ctx_t *ctx);
-
-extern const char *gf_fop_list[];
-
-/* mem acct enable/disable */
-int gf_global_mem_acct_enable_get (void);
-int gf_global_mem_acct_enable_set (int val);
-#endif /* !_GLOBALS_H */
diff --git a/libglusterfs/src/glusterfs-acl.h b/libglusterfs/src/glusterfs-acl.h
deleted file mode 100644
index 55f94ff0509..00000000000
--- a/libglusterfs/src/glusterfs-acl.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- Copyright (c) 2013 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_ACL_H
-#define _GLUSTERFS_ACL_H
-
-
-/* WARNING: Much if this code is restricted to Linux usage.
- *
- * It would be much cleaner to replace the code with something that is based on
- * libacl (or its libc implementation on *BSD).
- *
- * Initial work for replacing this Linux specific implementation has been
- * started as part of the "Improve POSIX ACLs" feature. Functionality for this
- * feature has been added to the end of this file.
- */
-
-#include <stdint.h>
-#include <sys/types.h> /* For uid_t */
-
-#include "locking.h" /* For gf_lock_t in struct posix_acl_conf */
-
-#define ACL_PROGRAM 100227
-#define ACLV3_VERSION 3
-
-#define POSIX_ACL_MINIMAL_ACE_COUNT 3
-
-#define POSIX_ACL_READ (0x04)
-#define POSIX_ACL_WRITE (0x02)
-#define POSIX_ACL_EXECUTE (0x01)
-
-#define POSIX_ACL_UNDEFINED_TAG (0x00)
-#define POSIX_ACL_USER_OBJ (0x01)
-#define POSIX_ACL_USER (0x02)
-#define POSIX_ACL_GROUP_OBJ (0x04)
-#define POSIX_ACL_GROUP (0x08)
-#define POSIX_ACL_MASK (0x10)
-#define POSIX_ACL_OTHER (0x20)
-
-#define POSIX_ACL_UNDEFINED_ID (-1)
-
-#define POSIX_ACL_XATTR_VERSION (0x02)
-
-#define POSIX_ACL_ACCESS_XATTR "system.posix_acl_access"
-#define POSIX_ACL_DEFAULT_XATTR "system.posix_acl_default"
-
-struct posix_acl_xattr_entry {
- uint16_t tag;
- uint16_t perm;
- uint32_t id;
-};
-
-struct posix_acl_xattr_header {
- uint32_t version;
- struct posix_acl_xattr_entry entries[];
-};
-
-typedef struct posix_acl_xattr_entry posix_acl_xattr_entry;
-typedef struct posix_acl_xattr_header posix_acl_xattr_header;
-
-static inline size_t
-posix_acl_xattr_size (unsigned int count)
-{
- return (sizeof(posix_acl_xattr_header) +
- (count * sizeof(posix_acl_xattr_entry)));
-}
-
-static inline ssize_t
-posix_acl_xattr_count (size_t size)
-{
- if (size < sizeof(posix_acl_xattr_header))
- return (-1);
- size -= sizeof(posix_acl_xattr_header);
- if (size % sizeof(posix_acl_xattr_entry))
- return (-1);
- return (size / sizeof(posix_acl_xattr_entry));
-}
-
-struct posix_ace {
- uint16_t tag;
- uint16_t perm;
- uint32_t id;
-};
-
-
-struct posix_acl {
- int refcnt;
- int count;
- struct posix_ace entries[];
-};
-
-struct posix_acl_ctx {
- uid_t uid;
- gid_t gid;
- mode_t perm;
- struct posix_acl *acl_access;
- struct posix_acl *acl_default;
-};
-
-struct posix_acl_conf {
- gf_lock_t acl_lock;
- uid_t super_uid;
- struct posix_acl *minimal_acl;
-};
-
-
-/* Above this comment, the legacy POSIX ACL support is kept until it is not
- * used anymore. Below you will find the more portable version to support POSIX
- * ACls based on the implementation of libacl (see sys/acl.h). */
-
-/* virtual xattrs passed over RPC, not stored on disk */
-#define GF_POSIX_ACL_ACCESS "glusterfs.posix.acl"
-#define GF_POSIX_ACL_DEFAULT "glusterfs.posix.default_acl"
-#define GF_POSIX_ACL_REQUEST(key) \
- (!strncmp(key, GF_POSIX_ACL_ACCESS, strlen(GF_POSIX_ACL_ACCESS)) || \
- !strncmp(key, GF_POSIX_ACL_DEFAULT, strlen(GF_POSIX_ACL_DEFAULT)))
-
-#ifdef HAVE_SYS_ACL_H /* only NetBSD does not support POSIX ACLs */
-
-#include <sys/acl.h>
-
-static inline const char*
-gf_posix_acl_get_key (const acl_type_t type)
-{
- char *acl_key = NULL;
-
- switch (type) {
- case ACL_TYPE_ACCESS:
- acl_key = GF_POSIX_ACL_ACCESS;
- break;
- case ACL_TYPE_DEFAULT:
- acl_key = GF_POSIX_ACL_DEFAULT;
- break;
- default:
- errno = EINVAL;
- }
-
- return acl_key;
-}
-
-static inline const acl_type_t
-gf_posix_acl_get_type (const char *key)
-{
- acl_type_t type = 0;
-
- if (!strncmp (key, GF_POSIX_ACL_ACCESS, strlen (GF_POSIX_ACL_ACCESS)))
- type = ACL_TYPE_ACCESS;
- else if (!strncmp (key, GF_POSIX_ACL_DEFAULT,
- strlen (GF_POSIX_ACL_DEFAULT)))
- type = ACL_TYPE_DEFAULT;
- else
- errno = EINVAL;
-
- return type;
-}
-
-#endif /* HAVE_SYS_ACL_H */
-#endif /* _GLUSTERFS_ACL_H */
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
deleted file mode 100644
index 18ffbb1f2b1..00000000000
--- a/libglusterfs/src/glusterfs.h
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- Copyright (c) 2008-2015 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
-#define _GLUSTERFS_H
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <netdb.h>
-#include <errno.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <arpa/inet.h>
-#include <sys/poll.h>
-#include <pthread.h>
-#include <limits.h> /* For PATH_MAX */
-
-#include "list.h"
-#include "logging.h"
-#include "lkowner.h"
-#include "compat-uuid.h"
-
-#define GF_YES 1
-#define GF_NO 0
-
-#ifndef O_LARGEFILE
-/* savannah bug #20053, patch for compiling on darwin */
-#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
-/* savannah bug #20050, #20052 */
-#define O_DIRECT 0 /* From asm/fcntl.h */
-#endif
-
-#ifndef O_DIRECTORY
-/* FreeBSD does not need O_DIRECTORY */
-#define O_DIRECTORY 0
-#endif
-
-#ifndef EBADFD
-/* Mac OS X does not have EBADFD */
-#define EBADFD EBADF
-#endif
-
-#ifndef FNM_EXTMATCH
-#define FNM_EXTMATCH 0
-#endif
-
-#define GLUSTERD_MAX_SNAP_NAME 255
-#define ZR_MOUNTPOINT_OPT "mountpoint"
-#define ZR_ATTR_TIMEOUT_OPT "attribute-timeout"
-#define ZR_ENTRY_TIMEOUT_OPT "entry-timeout"
-#define ZR_NEGATIVE_TIMEOUT_OPT "negative-timeout"
-#define ZR_DIRECT_IO_OPT "direct-io-mode"
-#define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check"
-#define ZR_DUMP_FUSE "dump-fuse"
-#define ZR_FUSE_MOUNTOPTS "fuse-mountopts"
-
-#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_REBAL_FIND_LOCAL_SUBVOL "glusterfs.find-local-subvol"
-#define GF_XATTR_VOL_ID_KEY "trusted.glusterfs.volume-id"
-#define GF_XATTR_LOCKINFO_KEY "trusted.glusterfs.lockinfo"
-#define GF_XATTR_GET_REAL_FILENAME_KEY "glusterfs.get_real_filename:"
-#define GF_XATTR_USER_PATHINFO_KEY "glusterfs.pathinfo"
-#define QUOTA_LIMIT_KEY "trusted.glusterfs.quota.limit-set"
-#define QUOTA_LIMIT_OBJECTS_KEY "trusted.glusterfs.quota.limit-objects"
-#define VIRTUAL_QUOTA_XATTR_CLEANUP_KEY "glusterfs.quota-xattr-cleanup"
-#define GF_INTERNAL_IGNORE_DEEM_STATFS "ignore-deem-statfs"
-
-#define GF_READDIR_SKIP_DIRS "readdir-filter-directories"
-
-#define BD_XATTR_KEY "user.glusterfs"
-
-#define XATTR_IS_PATHINFO(x) ((strncmp (x, GF_XATTR_PATHINFO_KEY, \
- strlen (x)) == 0) || \
- (strncmp (x, GF_XATTR_USER_PATHINFO_KEY, \
- strlen (x)) == 0))
-#define XATTR_IS_NODE_UUID(x) (strncmp (x, GF_XATTR_NODE_UUID_KEY, \
- strlen (GF_XATTR_NODE_UUID_KEY)) == 0)
-#define XATTR_IS_LOCKINFO(x) (strncmp (x, GF_XATTR_LOCKINFO_KEY, \
- strlen (GF_XATTR_LOCKINFO_KEY)) == 0)
-
-#define XATTR_IS_BD(x) (strncmp (x, BD_XATTR_KEY, strlen (BD_XATTR_KEY)) == 0)
-
-#define GF_XATTR_LINKINFO_KEY "trusted.distribute.linkinfo"
-#define GFID_XATTR_KEY "trusted.gfid"
-#define PGFID_XATTR_KEY_PREFIX "trusted.pgfid."
-#define VIRTUAL_GFID_XATTR_KEY_STR "glusterfs.gfid.string"
-#define VIRTUAL_GFID_XATTR_KEY "glusterfs.gfid"
-#define UUID_CANONICAL_FORM_LEN 36
-
-#define GET_ANCESTRY_PATH_KEY "glusterfs.ancestry.path"
-#define GET_ANCESTRY_DENTRY_KEY "glusterfs.ancestry.dentry"
-
-#define BITROT_DEFAULT_CURRENT_VERSION (unsigned long)1
-#define BITROT_DEFAULT_SIGNING_VERSION (unsigned long)0
-
-/* on-disk object signature keys */
-#define BITROT_OBJECT_BAD_KEY "trusted.bit-rot.bad-file"
-#define BITROT_CURRENT_VERSION_KEY "trusted.bit-rot.version"
-#define BITROT_SIGNING_VERSION_KEY "trusted.bit-rot.signature"
-
-/* globally usable bad file marker */
-#define GLUSTERFS_BAD_INODE "glusterfs.bad-inode"
-
-/* on-disk size of signing xattr (not the signature itself) */
-#define BITROT_SIGNING_XATTR_SIZE_KEY "trusted.glusterfs.bit-rot.size"
-
-/* GET/SET object signature */
-#define GLUSTERFS_GET_OBJECT_SIGNATURE "trusted.glusterfs.get-signature"
-#define GLUSTERFS_SET_OBJECT_SIGNATURE "trusted.glusterfs.set-signature"
-
-/* operation needs to be durable on-disk */
-#define GLUSTERFS_DURABLE_OP "trusted.glusterfs.durable-op"
-
-/* key for version exchange b/w bitrot stub and changelog */
-#define GLUSTERFS_VERSION_XCHG_KEY "glusterfs.version.xchg"
-
-#define GLUSTERFS_INTERNAL_FOP_KEY "glusterfs-internal-fop"
-#define DHT_CHANGELOG_RENAME_OP_KEY "changelog.rename-op"
-
-#define ZR_FILE_CONTENT_STR "glusterfs.file."
-#define ZR_FILE_CONTENT_STRLEN 15
-
-#define GLUSTERFS_WRITE_IS_APPEND "glusterfs.write-is-append"
-#define GLUSTERFS_WRITE_UPDATE_ATOMIC "glusterfs.write-update-atomic"
-#define GLUSTERFS_OPEN_FD_COUNT "glusterfs.open-fd-count"
-#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 GLUSTERFS_INODELK_DOM_COUNT "glusterfs.inodelk-dom-count"
-#define GFID_TO_PATH_KEY "glusterfs.gfid2path"
-#define GF_XATTR_STIME_PATTERN "trusted.glusterfs.*.stime"
-#define GF_XATTR_TRIGGER_SYNC "glusterfs.geo-rep.trigger-sync"
-
-#define QUOTA_SIZE_KEY "trusted.glusterfs.quota.size"
-
-/* Index xlator related */
-#define GF_XATTROP_INDEX_GFID "glusterfs.xattrop_index_gfid"
-#define GF_XATTROP_INDEX_COUNT "glusterfs.xattrop_index_count"
-
-#define GF_HEAL_INFO "glusterfs.heal-info"
-#define GF_AFR_HEAL_SBRAIN "glusterfs.heal-sbrain"
-#define GF_AFR_SBRAIN_STATUS "replica.split-brain-status"
-#define GF_AFR_SBRAIN_CHOICE "replica.split-brain-choice"
-#define GF_AFR_SPB_CHOICE_TIMEOUT "replica.split-brain-choice-timeout"
-#define GF_AFR_SBRAIN_RESOLVE "replica.split-brain-heal-finalize"
-#define GF_AFR_REPLACE_BRICK "trusted.replace-brick"
-#define GF_AFR_DIRTY "trusted.afr.dirty"
-
-#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 GLUSTERFS_MARKER_DONT_ACCOUNT_KEY "glusters.marker.dont-account"
-#define GLUSTERFS_RDMA_INLINE_THRESHOLD (2048)
-#define GLUSTERFS_RDMA_MAX_HEADER_SIZE (228) /* (sizeof (rdma_header_t) \
- + RDMA_MAX_SEGMENTS \
- * sizeof (rdma_read_chunk_t))
- */
-
-#define GLUSTERFS_RPC_REPLY_SIZE 24
-
-#define STARTING_EVENT_THREADS 1
-
-#define ZR_FILE_CONTENT_REQUEST(key) (!strncmp(key, ZR_FILE_CONTENT_STR, \
- ZR_FILE_CONTENT_STRLEN))
-
-#define DEFAULT_VAR_RUN_DIRECTORY DATADIR "/run/gluster"
-#define DEFAULT_GLUSTERFSD_MISC_DIRETORY DATADIR "/lib/misc/glusterfsd"
-#ifdef GF_LINUX_HOST_OS
-#define GLUSTERD_DEFAULT_WORKDIR DATADIR "/lib/glusterd"
-#else
-#define GLUSTERD_DEFAULT_WORKDIR DATADIR "/db/glusterd"
-#endif
-#define GF_REPLICATE_TRASH_DIR ".landfill"
-
-/* GlusterFS's maximum supported Auxiliary 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 65535
-
-#define GF_UUID_BUF_SIZE 50
-
-#define GF_REBALANCE_TID_KEY "rebalance-id"
-#define GF_REMOVE_BRICK_TID_KEY "remove-brick-id"
-
-#define UUID_CANONICAL_FORM_LEN 36
-
-/* Adding this here instead of any glusterd*.h files as it is also required by
- * cli
- */
-#define DEFAULT_GLUSTERD_SOCKFILE DATADIR "/run/glusterd.socket"
-
-/* features/marker-quota also needs to have knowledge of link-files so as to
- * exclude them from accounting.
- */
-#define DHT_LINKFILE_MODE (S_ISVTX)
-
-#define IS_DHT_LINKFILE_MODE(iabuf) ((st_mode_from_ia ((iabuf)->ia_prot, \
- (iabuf)->ia_type) & ~S_IFMT)\
- == DHT_LINKFILE_MODE)
-#define DHT_LINKFILE_STR "linkto"
-#define DHT_COMMITHASH_STR "commithash"
-
-#define DHT_SKIP_NON_LINKTO_UNLINK "unlink-only-if-dht-linkto-file"
-#define DHT_SKIP_OPEN_FD_UNLINK "dont-unlink-for-open-fd"
-#define DHT_IATT_IN_XDATA_KEY "dht-get-iatt-in-xattr"
-
-/*CTR requires inode dentry link count from posix*/
-#define CTR_RESPONSE_LINK_COUNT_XDATA "ctr_response_link_count"
-#define CTR_REQUEST_LINK_COUNT_XDATA "ctr_request_link_count"
-
-#define GF_LOG_LRU_BUFSIZE_DEFAULT 5
-#define GF_LOG_LRU_BUFSIZE_MIN 0
-#define GF_LOG_LRU_BUFSIZE_MAX 20
-#define GF_LOG_LRU_BUFSIZE_MIN_STR "0"
-#define GF_LOG_LRU_BUFSIZE_MAX_STR "20"
-
-#define GF_LOG_FLUSH_TIMEOUT_DEFAULT 120
-#define GF_LOG_FLUSH_TIMEOUT_MIN 30
-#define GF_LOG_FLUSH_TIMEOUT_MAX 300
-#define GF_LOG_FLUSH_TIMEOUT_MIN_STR "30"
-#define GF_LOG_FLUSH_TIMEOUT_MAX_STR "300"
-
-#define GF_BACKTRACE_LEN 4096
-#define GF_BACKTRACE_FRAME_COUNT 7
-
-
-/* NOTE: add members ONLY at the end (just before _MAXVALUE) */
-typedef enum {
- GF_FOP_NULL = 0,
- GF_FOP_STAT,
- GF_FOP_READLINK,
- GF_FOP_MKNOD,
- GF_FOP_MKDIR,
- GF_FOP_UNLINK,
- GF_FOP_RMDIR,
- GF_FOP_SYMLINK,
- GF_FOP_RENAME,
- GF_FOP_LINK,
- GF_FOP_TRUNCATE,
- GF_FOP_OPEN,
- GF_FOP_READ,
- GF_FOP_WRITE,
- GF_FOP_STATFS,
- GF_FOP_FLUSH,
- GF_FOP_FSYNC, /* 16 */
- GF_FOP_SETXATTR,
- GF_FOP_GETXATTR,
- GF_FOP_REMOVEXATTR,
- GF_FOP_OPENDIR,
- GF_FOP_FSYNCDIR,
- GF_FOP_ACCESS,
- GF_FOP_CREATE,
- GF_FOP_FTRUNCATE,
- GF_FOP_FSTAT, /* 25 */
- GF_FOP_LK,
- GF_FOP_LOOKUP,
- GF_FOP_READDIR,
- GF_FOP_INODELK,
- GF_FOP_FINODELK,
- GF_FOP_ENTRYLK,
- GF_FOP_FENTRYLK,
- GF_FOP_XATTROP,
- GF_FOP_FXATTROP,
- GF_FOP_FGETXATTR,
- GF_FOP_FSETXATTR,
- GF_FOP_RCHECKSUM,
- GF_FOP_SETATTR,
- GF_FOP_FSETATTR,
- GF_FOP_READDIRP,
- GF_FOP_FORGET,
- GF_FOP_RELEASE,
- GF_FOP_RELEASEDIR,
- GF_FOP_GETSPEC,
- GF_FOP_FREMOVEXATTR,
- GF_FOP_FALLOCATE,
- GF_FOP_DISCARD,
- GF_FOP_ZEROFILL,
- GF_FOP_IPC,
- GF_FOP_MAXVALUE,
-} glusterfs_fop_t;
-
-
-typedef enum {
- GF_MGMT_NULL = 0,
- GF_MGMT_MAXVALUE,
-} glusterfs_mgmt_t;
-
-typedef enum {
- GF_OP_TYPE_NULL = 0,
- GF_OP_TYPE_FOP,
- GF_OP_TYPE_MGMT,
- GF_OP_TYPE_MAX,
-} gf_op_type_t;
-
-/* NOTE: all the miscellaneous flags used by GlusterFS should be listed here */
-typedef enum {
- GF_LK_GETLK = 0,
- GF_LK_SETLK,
- GF_LK_SETLKW,
- GF_LK_RESLK_LCK,
- GF_LK_RESLK_LCKW,
- GF_LK_RESLK_UNLCK,
- GF_LK_GETLK_FD,
-} glusterfs_lk_cmds_t;
-
-
-typedef enum {
- GF_LK_F_RDLCK = 0,
- GF_LK_F_WRLCK,
- GF_LK_F_UNLCK,
- GF_LK_EOL,
-} glusterfs_lk_types_t;
-
-typedef enum {
- F_RESLK_LCK = 200,
- F_RESLK_LCKW,
- F_RESLK_UNLCK,
- F_GETLK_FD,
-} glusterfs_lk_recovery_cmds_t;
-
-typedef enum {
- GF_LOCK_POSIX,
- GF_LOCK_INTERNAL
-} gf_lk_domain_t;
-
-
-typedef enum {
- ENTRYLK_LOCK,
- ENTRYLK_UNLOCK,
- ENTRYLK_LOCK_NB
-} entrylk_cmd;
-
-
-typedef enum {
- ENTRYLK_RDLCK,
- ENTRYLK_WRLCK
-} entrylk_type;
-
-
-typedef enum {
- GF_XATTROP_ADD_ARRAY,
- GF_XATTROP_ADD_ARRAY64,
- GF_XATTROP_OR_ARRAY,
- GF_XATTROP_AND_ARRAY,
- GF_XATTROP_GET_AND_SET
-} gf_xattrop_flags_t;
-
-#define GF_SET_IF_NOT_PRESENT 0x1 /* default behaviour */
-#define GF_SET_OVERWRITE 0x2 /* Overwrite with the buf given */
-#define GF_SET_DIR_ONLY 0x4
-#define GF_SET_EPOCH_TIME 0x8 /* used by afr dir lookup selfheal */
-
-/* key value which quick read uses to get small files in lookup cbk */
-#define GF_CONTENT_KEY "glusterfs.content"
-
-struct _xlator_cmdline_option {
- struct list_head cmd_args;
- char *volume;
- char *key;
- char *value;
-};
-typedef struct _xlator_cmdline_option xlator_cmdline_option_t;
-
-struct _server_cmdline {
- struct list_head list;
- char *volfile_server;
- char *transport;
- int port;
-};
-typedef struct _server_cmdline server_cmdline_t;
-
-#define GF_OPTION_ENABLE _gf_true
-#define GF_OPTION_DISABLE _gf_false
-#define GF_OPTION_DEFERRED 2
-
-struct _cmd_args {
- /* basic options */
- char *volfile_server;
- server_cmdline_t *curr_server;
- /* List of backup volfile servers, including original */
- struct list_head volfile_servers;
- char *volfile;
- char *log_server;
- gf_loglevel_t log_level;
- char *log_file;
- char *log_ident;
- gf_log_logger_t logger;
- gf_log_format_t log_format;
- uint32_t log_buf_size;
- uint32_t log_flush_timeout;
- int32_t max_connect_attempts;
- char *print_exports;
- char *print_netgroups;
- /* advanced options */
- uint32_t volfile_server_port;
- char *volfile_server_transport;
- uint32_t log_server_port;
- char *pid_file;
- char *sock_file;
- int no_daemon_mode;
- char *run_id;
- int debug_mode;
- int read_only;
- int acl;
- int selinux;
- int enable_ino32;
- int worm;
- int mac_compat;
- int fopen_keep_cache;
- int gid_timeout;
- char gid_timeout_set;
- int aux_gfid_mount;
-
- /* need a process wide timer-wheel? */
- int global_timer_wheel;
-
- struct list_head xlator_options; /* list of xlator_option_t */
-
- /* fuse options */
- int fuse_direct_io_mode;
- char *use_readdirp;
- int no_root_squash;
- int volfile_check;
- double fuse_entry_timeout;
- double fuse_negative_timeout;
- double fuse_attribute_timeout;
- char *volume_name;
- int fuse_nodev;
- int fuse_nosuid;
- char *dump_fuse;
- pid_t client_pid;
- int client_pid_set;
- unsigned uid_map_root;
- int background_qlen;
- int congestion_threshold;
- char *fuse_mountopts;
- int mem_acct;
- int resolve_gids;
-
- /* key args */
- char *mount_point;
- char *volfile_id;
-
- /* required for portmap */
- int brick_port;
- char *brick_name;
- int brick_port2;
-
- /* Should management connections use SSL? */
- int secure_mgmt;
-};
-typedef struct _cmd_args cmd_args_t;
-
-
-struct _glusterfs_graph {
- struct list_head list;
- char graph_uuid[128];
- struct timeval dob;
- void *first;
- void *top; /* selected by -n */
- uint32_t leaf_count;
- int xl_count;
- int id; /* Used in logging */
- int used; /* Should be set when fuse gets
- first CHILD_UP */
- uint32_t volfile_checksum;
-};
-typedef struct _glusterfs_graph glusterfs_graph_t;
-
-
-typedef int32_t (*glusterfsd_mgmt_event_notify_fn_t) (int32_t event, void *data,
- ...);
-
-typedef enum {
- MGMT_SSL_NEVER = 0,
- MGMT_SSL_COPY_IO,
- MGMT_SSL_ALWAYS
-} mgmt_ssl_t;
-
-struct tvec_base;
-
-struct _glusterfs_ctx {
- cmd_args_t cmd_args;
- char *process_uuid;
- FILE *pidfp;
- char fin;
- void *timer;
- void *ib;
- struct call_pool *pool;
- void *event_pool;
- void *iobuf_pool;
- void *logbuf_pool;
- pthread_mutex_t lock;
- size_t page_size;
- struct list_head graphs; /* double linked list of graphs - one per volfile parse */
- glusterfs_graph_t *active; /* the latest graph in use */
- void *master; /* fuse, or libglusterfsclient (however, not protocol/server) */
- void *mgmt; /* xlator implementing MOPs for centralized logging, volfile server */
- void *listener; /* listener of the commands from glusterd */
- unsigned char measure_latency; /* toggle switch for latency measurement */
- pthread_t sigwaiter;
- char *cmdlinestr;
- struct mem_pool *stub_mem_pool;
- unsigned char cleanup_started;
- 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;
-
- glusterfsd_mgmt_event_notify_fn_t notify; /* Used for xlators to make
- call to fsd-mgmt */
- gf_log_handle_t log; /* all logging related variables */
-
- int mem_acct_enable;
-
- int daemon_pipe[2];
-
- struct clienttable *clienttable;
-
- /*
- * Should management connections use SSL? This is the only place we
- * can put it where both daemon-startup and socket code will see it.
- *
- * Why is it an int? Because we're included before common-utils.h,
- * which defines gf_boolean_t (what we really want). It doesn't make
- * any sense, but it's not worth turning the codebase upside-down to
- * fix it. Thus, an int.
- */
- int secure_mgmt;
-
- /*
- * Should *our* server/inbound connections use SSL? This is only true
- * if we're glusterd and secure_mgmt is set, or if we're glusterfsd
- * and SSL is set on the I/O path. It should never be set e.g. for
- * NFS.
- */
- mgmt_ssl_t secure_srvr;
- /* Buffer to 'save' backtrace even under OOM-kill like situations*/
- char btbuf[GF_BACKTRACE_LEN];
-
- pthread_mutex_t notify_lock;
- pthread_cond_t notify_cond;
- int notifying;
-
- struct tvec_base *timer_wheel; /* global timer-wheel instance */
-
-};
-typedef struct _glusterfs_ctx glusterfs_ctx_t;
-
-glusterfs_ctx_t *glusterfs_ctx_new (void);
-
-typedef enum {
- GF_EVENT_PARENT_UP = 1,
- GF_EVENT_POLLIN,
- GF_EVENT_POLLOUT,
- GF_EVENT_POLLERR,
- GF_EVENT_CHILD_UP,
- GF_EVENT_CHILD_DOWN,
- GF_EVENT_CHILD_CONNECTING,
- GF_EVENT_CHILD_MODIFIED,
- GF_EVENT_TRANSPORT_CLEANUP,
- GF_EVENT_TRANSPORT_CONNECTED,
- 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_VOLUME_BARRIER_OP,
- GF_EVENT_UPCALL,
- GF_EVENT_MAXVAL,
-} glusterfs_event_t;
-
-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;
-};
-
-#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))
-
-/*
- * If present, this has the following effects:
- *
- * glusterd enables privileged commands over TCP
- *
- * all code enables SSL for outbound connections to management port
- *
- * glusterd enables SSL for inbound connections
- *
- * Servers and clients enable/disable SSL among themselves by other means.
- * Making secure management connections conditional on a file is a bit of a
- * hack, but we don't have any other place for such global settings across
- * all of the affected components. Making it a compile-time option would
- * reduce functionality, both for users and for testing (which can now be
- * done using secure connections for all tests without change elsewhere).
- *
- */
-#define SECURE_ACCESS_FILE GLUSTERD_DEFAULT_WORKDIR "/secure-access"
-
-int glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx);
-int glusterfs_graph_destroy_residual (glusterfs_graph_t *graph);
-int glusterfs_graph_deactivate (glusterfs_graph_t *graph);
-int glusterfs_graph_destroy (glusterfs_graph_t *graph);
-int glusterfs_get_leaf_count (glusterfs_graph_t *graph);
-int glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx);
-glusterfs_graph_t *glusterfs_graph_construct (FILE *fp);
-glusterfs_graph_t *glusterfs_graph_new ();
-int glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,
- glusterfs_graph_t *newgraph);
-
-#endif /* _GLUSTERFS_H */
diff --git a/libglusterfs/src/glusterfs/async.h b/libglusterfs/src/glusterfs/async.h
new file mode 100644
index 00000000000..d1d70ae0bc7
--- /dev/null
+++ b/libglusterfs/src/glusterfs/async.h
@@ -0,0 +1,209 @@
+/*
+ Copyright (c) 2019 Red Hat, Inc <https://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_ASYNC_H__
+#define __GLUSTERFS_ASYNC_H__
+
+#define _LGPL_SOURCE
+
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+
+#ifdef URCU_OLD
+
+/* TODO: Fix the include paths. Since this is a .h included from many places
+ * it makes no sense to append a '-I$(CONTRIBDIR)/userspace-rcu/' to each
+ * Makefile.am. I've also seen some problems with CI builders (they
+ * failed to find the include files, but the same source on another setup
+ * is working fine). */
+#include "wfcqueue.h"
+#include "wfstack.h"
+
+#else /* !URCU_OLD */
+
+#include <urcu/wfcqueue.h>
+#include <urcu/wfstack.h>
+
+#endif /* URCU_OLD */
+
+#include "glusterfs/xlator.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/list.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+/* This is the name prefix that all worker threads will have. A number will
+ * be added to differentiate them. */
+#define GF_ASYNC_THREAD_NAME "tpw"
+
+/* This value determines the maximum number of threads that are allowed. */
+#define GF_ASYNC_MAX_THREADS 128
+
+/* This value determines how many additional threads will be started but will
+ * remain inactive until they are explicitly activated by the leader. This is
+ * useful to react faster to bursts of load, but at the same time we minimize
+ * contention if they are not really needed to handle current load.
+ *
+ * TODO: Instead of a fixed number, it would probably be better to use a
+ * prcentage of the available cores. */
+#define GF_ASYNC_SPARE_THREADS 2
+
+/* This value determines the signal used to wake the leader when new work has
+ * been added to the queue. To do so we reuse SIGALRM, since the most logical
+ * candidates (SIGUSR1/SIGUSR2) are already used. This signal must not be used
+ * by anything else in the process. */
+#define GF_ASYNC_SIGQUEUE SIGALRM
+
+/* This value determines the signal that will be used to transfer leader role
+ * to other workers. */
+#define GF_ASYNC_SIGCTRL SIGVTALRM
+
+#define gf_async_warning(_err, _msg, _args...) \
+ gf_msg("async", GF_LOG_WARNING, -(_err), LG_MSG_ASYNC_WARNING, _msg, \
+ ##_args)
+
+#define gf_async_error(_err, _msg, _args...) \
+ gf_msg("async", GF_LOG_ERROR, -(_err), LG_MSG_ASYNC_FAILURE, _msg, ##_args)
+
+#define gf_async_fatal(_err, _msg, _args...) \
+ do { \
+ GF_ABORT("Critical error in async module. Unable to continue. (" _msg \
+ "). Error %d.", \
+ ##_args, -(_err)); \
+ } while (0)
+
+struct _gf_async;
+typedef struct _gf_async gf_async_t;
+
+struct _gf_async_worker;
+typedef struct _gf_async_worker gf_async_worker_t;
+
+struct _gf_async_queue;
+typedef struct _gf_async_queue gf_async_queue_t;
+
+struct _gf_async_control;
+typedef struct _gf_async_control gf_async_control_t;
+
+typedef void (*gf_async_callback_f)(xlator_t *xl, gf_async_t *async);
+
+struct _gf_async {
+ /* TODO: remove dependency on xl/THIS. */
+ xlator_t *xl;
+ gf_async_callback_f cbk;
+ struct cds_wfcq_node queue;
+};
+
+struct _gf_async_worker {
+ /* Used to send asynchronous jobs related to the worker. */
+ gf_async_t async;
+
+ /* Member of the available workers stack. */
+ struct cds_wfs_node stack;
+
+ /* Thread object of the current worker. */
+ pthread_t thread;
+
+ /* Unique identifier of this worker. */
+ int32_t id;
+
+ /* Indicates if this worker is enabled. */
+ bool running;
+};
+
+struct _gf_async_queue {
+ /* Structures needed to manage a wait-free queue. For better performance
+ * they are placed in two different cache lines, as recommended by URCU
+ * documentation, even though in our case some threads will be producers
+ * and consumers at the same time. */
+ struct cds_wfcq_head head __attribute__((aligned(64)));
+ struct cds_wfcq_tail tail __attribute__((aligned(64)));
+};
+
+#define GF_ASYNC_COUNTS(_run, _stop) (((uint32_t)(_run) << 16) + (_stop))
+#define GF_ASYNC_COUNT_RUNNING(_count) ((_count) >> 16)
+#define GF_ASYNC_COUNT_STOPPING(_count) ((_count)&65535)
+
+struct _gf_async_control {
+ gf_async_queue_t queue;
+
+ /* Stack of unused workers. */
+ struct __cds_wfs_stack available;
+
+ /* Array of preallocated worker structures. */
+ gf_async_worker_t *table;
+
+ /* Used to synchronize main thread with workers on termination. */
+ pthread_barrier_t sync;
+
+ /* The id of the last thread that will be used for synchronization. */
+ pthread_t sync_thread;
+
+ /* Signal mask to wait for control signals from leader. */
+ sigset_t sigmask_ctrl;
+
+ /* Signal mask to wait for queued items. */
+ sigset_t sigmask_queue;
+
+ /* Saved signal handlers. */
+ struct sigaction handler_ctrl;
+ struct sigaction handler_queue;
+
+ /* PID of the current process. */
+ pid_t pid;
+
+ /* Maximum number of allowed threads. */
+ uint32_t max_threads;
+
+ /* Current number of running and stopping workers. This value is split
+ * into 2 16-bits fields to track both counters atomically at the same
+ * time. */
+ uint32_t counts;
+
+ /* It's used to control whether the asynchronous infrastructure is used
+ * or not. */
+ bool enabled;
+};
+
+extern gf_async_control_t gf_async_ctrl;
+
+int32_t
+gf_async_init(glusterfs_ctx_t *ctx);
+
+void
+gf_async_fini(void);
+
+void
+gf_async_adjust_threads(int32_t threads);
+
+static inline void
+gf_async(gf_async_t *async, xlator_t *xl, gf_async_callback_f cbk)
+{
+ if (!gf_async_ctrl.enabled) {
+ cbk(xl, async);
+ return;
+ }
+
+ async->xl = xl;
+ async->cbk = cbk;
+ cds_wfcq_node_init(&async->queue);
+ if (caa_unlikely(!cds_wfcq_enqueue(&gf_async_ctrl.queue.head,
+ &gf_async_ctrl.queue.tail,
+ &async->queue))) {
+ /* The queue was empty, so the leader could be sleeping. We need to
+ * wake it so that the new item can be processed. If the queue was not
+ * empty, we don't need to do anything special since the leader will
+ * take care of it. */
+ if (caa_unlikely(kill(gf_async_ctrl.pid, GF_ASYNC_SIGQUEUE) < 0)) {
+ gf_async_fatal(errno, "Unable to wake leader worker.");
+ };
+ }
+}
+
+#endif /* !__GLUSTERFS_ASYNC_H__ */
diff --git a/libglusterfs/src/glusterfs/atomic.h b/libglusterfs/src/glusterfs/atomic.h
new file mode 100644
index 00000000000..ced81748218
--- /dev/null
+++ b/libglusterfs/src/glusterfs/atomic.h
@@ -0,0 +1,459 @@
+/*
+ Copyright (c) 2017 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 _ATOMIC_H
+#define _ATOMIC_H
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include "glusterfs/locking.h"
+
+/* Macros used to join two arguments and generate a new macro name. */
+#define GF_ATOMIC_MACRO_1(_macro) _macro
+#define GF_ATOMIC_MACRO(_base, _name) GF_ATOMIC_MACRO_1(_base##_name)
+
+/* There's a problem on 32-bit architectures when we try to use atomic
+ * builtins with 64-bit types. Only way to solve the problem is to use
+ * a mutex to protect the access to the atomic, but we don't want to
+ * use mutexes for other smaller types that could work with the atomic
+ * builtins.
+ *
+ * So on each atomic type we add a field for the mutex if atomic operation
+ * is not supported and a dummy zero size field if it's supported. This way
+ * we can have different atomic types, some with a mutex and some without.
+ *
+ * To define these types, we use two macros:
+ *
+ * GF_ATOMIC_MUTEX_FIELD_0 = char lk[0]
+ * GF_ATOMIC_MUTEX_FILED_1 = gf_lock_t lk
+ *
+ * Both macros define the 'lk' field that will be used in the atomic
+ * structure. One when the atomic is supported by the architecture and
+ * another when not. We need to define the field even if it won't be
+ * used. Otherwise the compiler will return an error.
+ *
+ * Now we need to take the mutex or not depending on the existence of
+ * the mutex field in the structure. To do so we check the size of the
+ * structure, and if it's bigger than uint64_t (all structures with a
+ * mutex will be bigger), we use the mutex-based version. Otherwise we
+ * use the atomic builtin. This check is easily optimized out by the
+ * compiler, leaving a clean and efficient compiled code. */
+
+#define GF_ATOMIC_MUTEX_FIELD_0 char lk[0]
+#define GF_ATOMIC_MUTEX_FIELD_1 gf_lock_t lk
+
+/* We'll use SIZEOF_LONG to determine the architecture. 32-bit machines
+ * will have 4 here, while 64-bit machines will have 8. If additional
+ * needs or restrictions appear on other platforms, these tests can be
+ * extended to handle them. */
+
+/* GF_ATOMIC_SIZE_X macros map each type size to one of the
+ * GF_ATOMIC_MUTEX_FIELD_X macros, depending on detected conditions. */
+
+#if defined(HAVE_ATOMIC_BUILTINS) || defined(HAVE_SYNC_BUILTINS)
+
+#define GF_ATOMIC_SIZE_1 GF_ATOMIC_MUTEX_FIELD_0
+#define GF_ATOMIC_SIZE_2 GF_ATOMIC_MUTEX_FIELD_0
+#define GF_ATOMIC_SIZE_4 GF_ATOMIC_MUTEX_FIELD_0
+
+#if SIZEOF_LONG >= 8
+#define GF_ATOMIC_SIZE_8 GF_ATOMIC_MUTEX_FIELD_0
+#endif
+
+#endif /* HAVE_(ATOMIC|SYNC)_BUILTINS */
+
+/* Any GF_ATOMIC_SIZE_X macro not yet defined will use the mutex version */
+#ifndef GF_ATOMIC_SIZE_1
+#define GF_ATOMIC_SIZE_1 GF_ATOMIC_MUTEX_FIELD_1
+#endif
+
+#ifndef GF_ATOMIC_SIZE_2
+#define GF_ATOMIC_SIZE_2 GF_ATOMIC_MUTEX_FIELD_1
+#endif
+
+#ifndef GF_ATOMIC_SIZE_4
+#define GF_ATOMIC_SIZE_4 GF_ATOMIC_MUTEX_FIELD_1
+#endif
+
+#ifndef GF_ATOMIC_SIZE_8
+#define GF_ATOMIC_SIZE_8 GF_ATOMIC_MUTEX_FIELD_1
+#endif
+
+/* This macro is used to define all atomic types supported. First field
+ * represents the size of the type in bytes, and the second one the name. */
+#define GF_ATOMIC_TYPE(_size, _name) \
+ typedef struct _gf_atomic_##_name##_t { \
+ GF_ATOMIC_MACRO(GF_ATOMIC_SIZE_, _size); \
+ _name##_t value; \
+ } gf_atomic_##_name##_t
+
+/* The atomic types we support */
+GF_ATOMIC_TYPE(1, int8); /* gf_atomic_int8_t */
+GF_ATOMIC_TYPE(2, int16); /* gf_atomic_int16_t */
+GF_ATOMIC_TYPE(4, int32); /* gf_atomic_int32_t */
+GF_ATOMIC_TYPE(8, int64); /* gf_atomic_int64_t */
+GF_ATOMIC_TYPE(SIZEOF_LONG, intptr); /* gf_atomic_intptr_t */
+GF_ATOMIC_TYPE(1, uint8); /* gf_atomic_uint8_t */
+GF_ATOMIC_TYPE(2, uint16); /* gf_atomic_uint16_t */
+GF_ATOMIC_TYPE(4, uint32); /* gf_atomic_uint32_t */
+GF_ATOMIC_TYPE(8, uint64); /* gf_atomic_uint64_t */
+GF_ATOMIC_TYPE(SIZEOF_LONG, uintptr); /* gf_atomic_uintptr_t */
+
+/* Define the default atomic type as int64_t */
+#define gf_atomic_t gf_atomic_int64_t
+
+/* This macro will choose between the mutex based version and the atomic
+ * builtin version depending on the size of the atomic structure. */
+#define GF_ATOMIC_CHOOSE(_atomic, _op, _args...) \
+ ((sizeof(_atomic) > sizeof(uint64_t)) \
+ ? ({ \
+ GF_ATOMIC_MACRO(GF_ATOMIC_LOCK_, _op) \
+ (_atomic, ##_args); \
+ }) \
+ : ({ \
+ GF_ATOMIC_MACRO(GF_ATOMIC_BASE_, _op) \
+ (_atomic, ##_args); \
+ }))
+
+/* Macros to implement the mutex-based atomics. */
+#define GF_ATOMIC_OP_PREPARE(_atomic, _name) \
+ typeof(_atomic) *__atomic = &(_atomic); \
+ gf_lock_t *__lock = (gf_lock_t *)&__atomic->lk; \
+ LOCK(__lock); \
+ typeof(__atomic->value) _name = __atomic->value
+
+#define GF_ATOMIC_OP_STORE(_value) (__atomic->value = (_value))
+
+#define GF_ATOMIC_OP_RETURN(_value) \
+ ({ \
+ UNLOCK(__lock); \
+ _value; \
+ })
+
+#define GF_ATOMIC_LOCK_INIT(_atomic, _value) \
+ do { \
+ typeof(_atomic) *__atomic = &(_atomic); \
+ LOCK_INIT((gf_lock_t *)&__atomic->lk); \
+ __atomic->value = (_value); \
+ } while (0)
+
+#define GF_ATOMIC_LOCK_GET(_atomic) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_ADD(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value += (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_SUB(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value -= (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_AND(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value &= (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_OR(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value |= (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_XOR(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value ^= (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_NAND(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value = ~(__value & (_value))); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_FETCH_ADD(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value + (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_FETCH_SUB(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value - (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_FETCH_AND(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value &(_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_FETCH_OR(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value | (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_FETCH_XOR(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(__value ^ (_value)); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_FETCH_NAND(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(~(__value & (_value))); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_SWAP(_atomic, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ GF_ATOMIC_OP_STORE(_value); \
+ GF_ATOMIC_OP_RETURN(__value); \
+ })
+
+#define GF_ATOMIC_LOCK_CMP_SWAP(_atomic, _expected, _value) \
+ ({ \
+ GF_ATOMIC_OP_PREPARE(_atomic, __value); \
+ bool __ret = (__value == (_expected)); \
+ if (__ret) { \
+ GF_ATOMIC_OP_STORE(_value); \
+ } \
+ GF_ATOMIC_OP_RETURN(__ret); \
+ })
+
+#if defined(HAVE_ATOMIC_BUILTINS)
+
+/* If compiler supports __atomic builtins, we use them. */
+
+#define GF_ATOMIC_BASE_INIT(_atomic, _value) \
+ __atomic_store_n(&(_atomic).value, (_value), __ATOMIC_RELEASE)
+
+#define GF_ATOMIC_BASE_GET(_atomic) \
+ __atomic_load_n(&(_atomic).value, __ATOMIC_ACQUIRE)
+
+#define GF_ATOMIC_BASE_ADD(_atomic, _value) \
+ __atomic_add_fetch(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_SUB(_atomic, _value) \
+ __atomic_sub_fetch(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_AND(_atomic, _value) \
+ __atomic_and_fetch(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_OR(_atomic, _value) \
+ __atomic_or_fetch(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_XOR(_atomic, _value) \
+ __atomic_xor_fetch(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_NAND(_atomic, _value) \
+ __atomic_nand_fetch(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_FETCH_ADD(_atomic, _value) \
+ __atomic_fetch_add(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_FETCH_SUB(_atomic, _value) \
+ __atomic_fetch_sub(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_FETCH_AND(_atomic, _value) \
+ __atomic_fetch_and(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_FETCH_OR(_atomic, _value) \
+ __atomic_fetch_or(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_FETCH_XOR(_atomic, _value) \
+ __atomic_fetch_xor(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_FETCH_NAND(_atomic, _value) \
+ __atomic_fetch_nand(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_SWAP(_atomic, _value) \
+ __atomic_exchange_n(&(_atomic).value, (_value), __ATOMIC_ACQ_REL)
+
+#define GF_ATOMIC_BASE_CMP_SWAP(_atomic, _expected, _value) \
+ ({ \
+ typeof((_atomic).value) __expected = (_expected); \
+ __atomic_compare_exchange_n(&(_atomic).value, &__expected, (_value), \
+ 0, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE); \
+ })
+
+#elif defined(HAVE_SYNC_BUILTINS)
+
+/* If compiler doesn't support __atomic builtins but supports __sync builtins,
+ * we use them. */
+
+#define GF_ATOMIC_BASE_INIT(_atomic, _value) \
+ do { \
+ (_atomic).value = (_value); \
+ __sync_synchronize(); \
+ } while (0)
+
+#define GF_ATOMIC_BASE_ADD(_atomic, _value) \
+ __sync_add_and_fetch(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_SUB(_atomic, _value) \
+ __sync_sub_and_fetch(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_AND(_atomic, _value) \
+ __sync_and_and_fetch(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_OR(_atomic, _value) \
+ __sync_or_and_fetch(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_XOR(_atomic, _value) \
+ __sync_xor_and_fetch(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_NAND(_atomic, _value) \
+ __sync_nand_and_fetch(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_FETCH_ADD(_atomic, _value) \
+ __sync_fetch_and_add(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_FETCH_SUB(_atomic, _value) \
+ __sync_fetch_and_sub(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_FETCH_AND(_atomic, _value) \
+ __sync_fetch_and_and(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_FETCH_OR(_atomic, _value) \
+ __sync_fetch_and_or(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_FETCH_XOR(_atomic, _value) \
+ __sync_fetch_and_xor(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_FETCH_NAND(_atomic, _value) \
+ __sync_fetch_and_nand(&(_atomic).value, (_value))
+
+#define GF_ATOMIC_BASE_SWAP(_atomic, _value) \
+ ({ \
+ __sync_synchronize(); \
+ __sync_lock_test_and_set(&(_atomic).value, (_value)); \
+ })
+
+#define GF_ATOMIC_BASE_CMP_SWAP(_atomic, _expected, _value) \
+ __sync_bool_compare_and_swap(&(_atomic).value, (_expected), (_value))
+
+#define GF_ATOMIC_BASE_GET(_atomic) GF_ATOMIC_BASE_ADD(_atomic, 0)
+
+#else /* !HAVE_ATOMIC_BUILTINS && !HAVE_SYNC_BUILTINS */
+
+/* The compiler doesn't support any atomic builtin. We fallback to the
+ * mutex-based implementation. */
+
+#define GF_ATOMIC_BASE_INIT(_atomic, _value) \
+ GF_ATOMIC_LOCK_INIT(_atomic, _value)
+
+#define GF_ATOMIC_BASE_GET(_atomic) GF_ATOMIC_LOCK_GET(_atomic)
+
+#define GF_ATOMIC_BASE_ADD(_atomic, _value) GF_ATOMIC_LOCK_ADD(_atomic, _value)
+
+#define GF_ATOMIC_BASE_SUB(_atomic, _value) GF_ATOMIC_LOCK_SUB(_atomic, _value)
+
+#define GF_ATOMIC_BASE_AND(_atomic, _value) GF_ATOMIC_LOCK_AND(_atomic, _value)
+
+#define GF_ATOMIC_BASE_OR(_atomic, _value) GF_ATOMIC_LOCK_OR(_atomic, _value)
+
+#define GF_ATOMIC_BASE_XOR(_atomic, _value) GF_ATOMIC_LOCK_XOR(_atomic, _value)
+
+#define GF_ATOMIC_BASE_NAND(_atomic, _value) \
+ GF_ATOMIC_LOCK_NAND(_atomic, _value)
+
+#define GF_ATOMIC_BASE_FETCH_ADD(_atomic, _value) \
+ GF_ATOMIC_LOCK_FETCH_ADD(_atomic, _value)
+
+#define GF_ATOMIC_BASE_FETCH_SUB(_atomic, _value) \
+ GF_ATOMIC_LOCK_FETCH_SUB(_atomic, _value)
+
+#define GF_ATOMIC_BASE_FETCH_AND(_atomic, _value) \
+ GF_ATOMIC_LOCK_FETCH_AND(_atomic, _value)
+
+#define GF_ATOMIC_BASE_FETCH_OR(_atomic, _value) \
+ GF_ATOMIC_LOCK_FETCH_OR(_atomic, _value)
+
+#define GF_ATOMIC_BASE_FETCH_XOR(_atomic, _value) \
+ GF_ATOMIC_LOCK_FETCH_XOR(_atomic, _value)
+
+#define GF_ATOMIC_BASE_FETCH_NAND(_atomic, _value) \
+ GF_ATOMIC_LOCK_FETCH_NAND(_atomic, _value)
+
+#define GF_ATOMIC_BASE_SWAP(_atomic, _value) \
+ GF_ATOMIC_LOCK_SWAP(_atomic, _value)
+
+#define GF_ATOMIC_BASE_CMP_SWAP(_atomic, _expected, _value) \
+ GF_ATOMIC_LOCK_CMP_SWAP(_atomic, _expected, _value)
+
+#endif /* HAVE_(ATOMIC|SYNC)_BUILTINS */
+
+/* Here we declare the real atomic macros available to the user. */
+
+/* All macros have a 'gf_atomic_xxx' as 1st argument */
+
+#define GF_ATOMIC_INIT(_atomic, _value) GF_ATOMIC_CHOOSE(_atomic, INIT, _value)
+#define GF_ATOMIC_GET(_atomic) GF_ATOMIC_CHOOSE(_atomic, GET)
+#define GF_ATOMIC_ADD(_atomic, _value) GF_ATOMIC_CHOOSE(_atomic, ADD, _value)
+#define GF_ATOMIC_SUB(_atomic, _value) GF_ATOMIC_CHOOSE(_atomic, SUB, _value)
+#define GF_ATOMIC_AND(_atomic, _value) GF_ATOMIC_CHOOSE(_atomic, AND, _value)
+#define GF_ATOMIC_OR(_atomic, _value) GF_ATOMIC_CHOOSE(_atomic, OR, _value)
+#define GF_ATOMIC_XOR(_atomic, _value) GF_ATOMIC_CHOOSE(_atomic, XOR, _value)
+#define GF_ATOMIC_NAND(_atomic, _value) GF_ATOMIC_CHOOSE(_atomic, NAND, _value)
+
+#define GF_ATOMIC_FETCH_ADD(_atomic, _value) \
+ GF_ATOMIC_CHOOSE(_atomic, FETCH_ADD, _value)
+
+#define GF_ATOMIC_FETCH_SUB(_atomic, _value) \
+ GF_ATOMIC_CHOOSE(_atomic, FETCH_SUB, _value)
+
+#define GF_ATOMIC_FETCH_AND(_atomic, _value) \
+ GF_ATOMIC_CHOOSE(_atomic, FETCH_AND, _value)
+
+#define GF_ATOMIC_FETCH_OR(_atomic, _value) \
+ GF_ATOMIC_CHOOSE(_atomic, FETCH_OR, _value)
+
+#define GF_ATOMIC_FETCH_XOR(_atomic, _value) \
+ GF_ATOMIC_CHOOSE(_atomic, FETCH_XOR, _value)
+
+#define GF_ATOMIC_FETCH_NAND(_atomic, _value) \
+ GF_ATOMIC_CHOOSE(_atomic, FETCH_NAND, _value)
+
+#define GF_ATOMIC_SWAP(_atomic, _value) GF_ATOMIC_CHOOSE(_atomic, SWAP, _value)
+
+#define GF_ATOMIC_CMP_SWAP(_atomic, _expected, _value) \
+ GF_ATOMIC_CHOOSE(_atomic, CMP_SWAP, _expected, _value)
+
+#define GF_ATOMIC_INC(_atomic) GF_ATOMIC_ADD(_atomic, 1)
+#define GF_ATOMIC_DEC(_atomic) GF_ATOMIC_SUB(_atomic, 1)
+#define GF_ATOMIC_FETCH_INC(_atomic) GF_ATOMIC_FETCH_ADD(_atomic, 1)
+#define GF_ATOMIC_FETCH_DEC(_atomic) GF_ATOMIC_FETCH_SUB(_atomic, 1)
+
+#endif /* _ATOMIC_H */
diff --git a/libglusterfs/src/glusterfs/byte-order.h b/libglusterfs/src/glusterfs/byte-order.h
new file mode 100644
index 00000000000..fd8cef9e58d
--- /dev/null
+++ b/libglusterfs/src/glusterfs/byte-order.h
@@ -0,0 +1,279 @@
+/*
+ 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
+#define _BYTE_ORDER_H
+
+#include <inttypes.h>
+
+#define LS1 0x00ffU
+#define MS1 0xff00U
+#define LS2 0x0000ffffU
+#define MS2 0xffff0000U
+#define LS4 0x00000000ffffffffULL
+#define MS4 0xffffffff00000000ULL
+
+static uint16_t (*hton16)(uint16_t);
+static uint32_t (*hton32)(uint32_t);
+static uint64_t (*hton64)(uint64_t);
+
+#define ntoh16 hton16
+#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)))
+
+static inline uint16_t
+__swap16(uint16_t x)
+{
+ return do_swap2(x);
+}
+
+static inline uint32_t
+__swap32(uint32_t x)
+{
+ return do_swap4(x);
+}
+
+static inline uint64_t
+__swap64(uint64_t x)
+{
+ return do_swap8(x);
+}
+
+static inline uint16_t
+__noswap16(uint16_t x)
+{
+ return x;
+}
+
+static inline uint32_t
+__noswap32(uint32_t x)
+{
+ return x;
+}
+
+static inline uint64_t
+__noswap64(uint64_t x)
+{
+ return x;
+}
+
+static inline uint16_t
+__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;
+ }
+
+ return hton16(i);
+}
+
+static inline uint32_t
+__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;
+ }
+
+ return hton32(i);
+}
+
+static inline uint64_t
+__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;
+ }
+
+ return hton64(i);
+}
+
+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/glusterfs/call-stub.h b/libglusterfs/src/glusterfs/call-stub.h
new file mode 100644
index 00000000000..8237ea459bf
--- /dev/null
+++ b/libglusterfs/src/glusterfs/call-stub.h
@@ -0,0 +1,622 @@
+/*
+ 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 _CALL_STUB_H_
+#define _CALL_STUB_H_
+
+#include "glusterfs/xlator.h"
+#include "glusterfs/defaults.h"
+#include "glusterfs/default-args.h"
+#include "glusterfs/stack.h"
+#include "glusterfs/list.h"
+
+typedef struct _call_stub {
+ struct list_head list;
+ call_frame_t *frame;
+ struct mem_pool *stub_mem_pool; /* pointer to stub mempool in ctx_t */
+ uint32_t jnl_meta_len;
+ uint32_t jnl_data_len;
+ void (*serialize)(struct _call_stub *, char *, char *);
+ union {
+ fop_lookup_t lookup;
+ fop_stat_t stat;
+ fop_fstat_t fstat;
+ fop_truncate_t truncate;
+ fop_ftruncate_t ftruncate;
+ fop_access_t access;
+ fop_readlink_t readlink;
+ fop_mknod_t mknod;
+ fop_mkdir_t mkdir;
+ fop_unlink_t unlink;
+ fop_rmdir_t rmdir;
+ fop_symlink_t symlink;
+ fop_rename_t rename;
+ fop_link_t link;
+ fop_create_t create;
+ fop_open_t open;
+ fop_readv_t readv;
+ fop_writev_t writev;
+ fop_flush_t flush;
+ fop_fsync_t fsync;
+ fop_opendir_t opendir;
+ fop_fsyncdir_t fsyncdir;
+ fop_statfs_t statfs;
+ fop_setxattr_t setxattr;
+ fop_getxattr_t getxattr;
+ fop_fgetxattr_t fgetxattr;
+ fop_fsetxattr_t fsetxattr;
+ fop_removexattr_t removexattr;
+ fop_fremovexattr_t fremovexattr;
+ fop_lk_t lk;
+ fop_inodelk_t inodelk;
+ fop_finodelk_t finodelk;
+ fop_entrylk_t entrylk;
+ fop_fentrylk_t fentrylk;
+ fop_readdir_t readdir;
+ fop_readdirp_t readdirp;
+ fop_rchecksum_t rchecksum;
+ fop_xattrop_t xattrop;
+ fop_fxattrop_t fxattrop;
+ fop_setattr_t setattr;
+ fop_fsetattr_t fsetattr;
+ fop_fallocate_t fallocate;
+ fop_discard_t discard;
+ fop_zerofill_t zerofill;
+ fop_ipc_t ipc;
+ fop_seek_t seek;
+ fop_lease_t lease;
+ fop_getactivelk_t getactivelk;
+ fop_setactivelk_t setactivelk;
+ fop_put_t put;
+ fop_icreate_t icreate;
+ fop_namelink_t namelink;
+ fop_copy_file_range_t copy_file_range;
+ } fn;
+
+ union {
+ fop_lookup_cbk_t lookup;
+ fop_stat_cbk_t stat;
+ fop_fstat_cbk_t fstat;
+ fop_truncate_cbk_t truncate;
+ fop_ftruncate_cbk_t ftruncate;
+ fop_access_cbk_t access;
+ fop_readlink_cbk_t readlink;
+ fop_mknod_cbk_t mknod;
+ fop_mkdir_cbk_t mkdir;
+ fop_unlink_cbk_t unlink;
+ fop_rmdir_cbk_t rmdir;
+ fop_symlink_cbk_t symlink;
+ fop_rename_cbk_t rename;
+ fop_link_cbk_t link;
+ fop_create_cbk_t create;
+ fop_open_cbk_t open;
+ fop_readv_cbk_t readv;
+ fop_writev_cbk_t writev;
+ fop_flush_cbk_t flush;
+ fop_fsync_cbk_t fsync;
+ fop_opendir_cbk_t opendir;
+ fop_fsyncdir_cbk_t fsyncdir;
+ fop_statfs_cbk_t statfs;
+ fop_setxattr_cbk_t setxattr;
+ fop_getxattr_cbk_t getxattr;
+ fop_fgetxattr_cbk_t fgetxattr;
+ fop_fsetxattr_cbk_t fsetxattr;
+ fop_removexattr_cbk_t removexattr;
+ fop_fremovexattr_cbk_t fremovexattr;
+ fop_lk_cbk_t lk;
+ fop_inodelk_cbk_t inodelk;
+ fop_finodelk_cbk_t finodelk;
+ fop_entrylk_cbk_t entrylk;
+ fop_fentrylk_cbk_t fentrylk;
+ fop_readdir_cbk_t readdir;
+ fop_readdirp_cbk_t readdirp;
+ fop_rchecksum_cbk_t rchecksum;
+ fop_xattrop_cbk_t xattrop;
+ fop_fxattrop_cbk_t fxattrop;
+ fop_setattr_cbk_t setattr;
+ fop_fsetattr_cbk_t fsetattr;
+ fop_fallocate_cbk_t fallocate;
+ fop_discard_cbk_t discard;
+ fop_zerofill_cbk_t zerofill;
+ fop_ipc_cbk_t ipc;
+ fop_seek_cbk_t seek;
+ fop_lease_cbk_t lease;
+ fop_getactivelk_cbk_t getactivelk;
+ fop_setactivelk_cbk_t setactivelk;
+ fop_put_cbk_t put;
+ fop_icreate_cbk_t icreate;
+ fop_namelink_cbk_t namelink;
+ fop_copy_file_range_cbk_t copy_file_range;
+ } fn_cbk;
+ glusterfs_fop_t fop;
+ gf_boolean_t poison;
+ char wind;
+ default_args_t args;
+ default_args_cbk_t args_cbk;
+} call_stub_t;
+
+call_stub_t *
+fop_lookup_stub(call_frame_t *frame, fop_lookup_t fn, loc_t *loc,
+ dict_t *xdata);
+
+call_stub_t *
+fop_lookup_cbk_stub(call_frame_t *frame, fop_lookup_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata, struct iatt *postparent);
+call_stub_t *
+fop_stat_stub(call_frame_t *frame, fop_stat_t fn, 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, dict_t *xdata);
+call_stub_t *
+fop_fstat_stub(call_frame_t *frame, fop_fstat_t fn, 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, dict_t *xdata);
+
+call_stub_t *
+fop_truncate_stub(call_frame_t *frame, fop_truncate_t fn, loc_t *loc, off_t off,
+ dict_t *xdata);
+
+call_stub_t *
+fop_truncate_cbk_stub(call_frame_t *frame, fop_truncate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ 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,
+ dict_t *xdata);
+
+call_stub_t *
+fop_ftruncate_cbk_stub(call_frame_t *frame, fop_ftruncate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ 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,
+ 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, dict_t *xdata);
+
+call_stub_t *
+fop_readlink_stub(call_frame_t *frame, fop_readlink_t fn, loc_t *loc,
+ size_t size, dict_t *xdata);
+
+call_stub_t *
+fop_readlink_cbk_stub(call_frame_t *frame, fop_readlink_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, const char *path,
+ 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, mode_t umask, dict_t *xdata);
+
+call_stub_t *
+fop_mknod_cbk_stub(call_frame_t *frame, fop_mknod_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, 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,
+ mode_t umask, dict_t *xdata);
+
+call_stub_t *
+fop_mkdir_cbk_stub(call_frame_t *frame, fop_mkdir_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata);
+
+call_stub_t *
+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, fop_unlink_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ 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,
+ dict_t *xdata);
+
+call_stub_t *
+fop_rmdir_cbk_stub(call_frame_t *frame, fop_rmdir_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ 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, mode_t umask, dict_t *xdata);
+
+call_stub_t *
+fop_symlink_cbk_stub(call_frame_t *frame, fop_symlink_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, 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, dict_t *xdata);
+
+call_stub_t *
+fop_rename_cbk_stub(call_frame_t *frame, fop_rename_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, 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,
+ dict_t *xdata);
+
+call_stub_t *
+fop_link_cbk_stub(call_frame_t *frame, fop_link_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, 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, mode_t umask, fd_t *fd, dict_t *xdata);
+
+call_stub_t *
+fop_create_cbk_stub(call_frame_t *frame, fop_create_cbk_t fn, 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);
+
+call_stub_t *
+fop_open_stub(call_frame_t *frame, fop_open_t fn, loc_t *loc, int32_t flags,
+ fd_t *fd, 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, 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, uint32_t flags, dict_t *xdata);
+
+call_stub_t *
+fop_readv_cbk_stub(call_frame_t *frame, fop_readv_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iovec *vector, int32_t count,
+ struct iatt *stbuf, struct iobref *iobref, dict_t *xdata);
+
+call_stub_t *
+fop_writev_stub(call_frame_t *frame, fop_writev_t fn, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
+
+call_stub_t *
+fop_writev_cbk_stub(call_frame_t *frame, fop_writev_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf,
+ dict_t *xdata);
+
+call_stub_t *
+fop_flush_stub(call_frame_t *frame, fop_flush_t fn, 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, dict_t *xdata);
+
+call_stub_t *
+fop_fsync_stub(call_frame_t *frame, fop_fsync_t fn, fd_t *fd, int32_t datasync,
+ dict_t *xdata);
+
+call_stub_t *
+fop_fsync_cbk_stub(call_frame_t *frame, fop_fsync_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf, 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,
+ 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, dict_t *xdata);
+
+call_stub_t *
+fop_fsyncdir_stub(call_frame_t *frame, fop_fsyncdir_t fn, fd_t *fd,
+ 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, dict_t *xdata);
+
+call_stub_t *
+fop_statfs_stub(call_frame_t *frame, fop_statfs_t fn, 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, 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, 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, dict_t *xdata);
+
+call_stub_t *
+fop_getxattr_stub(call_frame_t *frame, fop_getxattr_t fn, loc_t *loc,
+ 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 *xdata);
+
+call_stub_t *
+fop_fsetxattr_stub(call_frame_t *frame, fop_fsetxattr_t fn, fd_t *fd,
+ dict_t *dict, 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, dict_t *xdata);
+
+call_stub_t *
+fop_fgetxattr_stub(call_frame_t *frame, fop_fgetxattr_t fn, fd_t *fd,
+ 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 *xdata);
+
+call_stub_t *
+fop_removexattr_stub(call_frame_t *frame, fop_removexattr_t fn, loc_t *loc,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, dict_t *xdata);
+
+call_stub_t *
+fop_readdirp_stub(call_frame_t *frame, fop_readdirp_t fn, fd_t *fd, size_t size,
+ 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, 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, 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, dict_t *xdata);
+
+call_stub_t *
+fop_rchecksum_cbk_stub(call_frame_t *frame, fop_rchecksum_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, uint32_t weak_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 *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, 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 *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, 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, dict_t *xdata);
+
+call_stub_t *
+fop_setattr_cbk_stub(call_frame_t *frame, fop_setattr_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ 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, dict_t *xdata);
+
+call_stub_t *
+fop_fsetattr_cbk_stub(call_frame_t *frame, fop_setattr_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata);
+
+call_stub_t *
+fop_fallocate_stub(call_frame_t *frame, fop_fallocate_t fn, fd_t *fd,
+ int32_t mode, off_t offset, size_t len, dict_t *xdata);
+
+call_stub_t *
+fop_fallocate_cbk_stub(call_frame_t *frame, fop_fallocate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata);
+
+call_stub_t *
+fop_discard_stub(call_frame_t *frame, fop_discard_t fn, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata);
+
+call_stub_t *
+fop_discard_cbk_stub(call_frame_t *frame, fop_discard_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata);
+
+call_stub_t *
+fop_zerofill_stub(call_frame_t *frame, fop_zerofill_t fn, fd_t *fd,
+ off_t offset, off_t len, dict_t *xdata);
+
+call_stub_t *
+fop_zerofill_cbk_stub(call_frame_t *frame, fop_zerofill_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata);
+
+call_stub_t *
+fop_ipc_stub(call_frame_t *frame, fop_ipc_t fn, int32_t op, dict_t *xdata);
+
+call_stub_t *
+fop_ipc_cbk_stub(call_frame_t *frame, fop_ipc_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+call_stub_t *
+fop_seek_stub(call_frame_t *frame, fop_seek_t fn, fd_t *fd, off_t offset,
+ gf_seek_what_t what, dict_t *xdata);
+
+call_stub_t *
+fop_seek_cbk_stub(call_frame_t *frame, fop_seek_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, off_t offset, dict_t *xdata);
+
+call_stub_t *
+fop_lease_stub(call_frame_t *frame, fop_lease_t fn, loc_t *loc,
+ struct gf_lease *lease, dict_t *xdata);
+
+call_stub_t *
+fop_lease_cbk_stub(call_frame_t *frame, fop_lease_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, struct gf_lease *lease, dict_t *xdata);
+
+call_stub_t *
+fop_getactivelk_stub(call_frame_t *frame, fop_getactivelk_t fn, loc_t *loc,
+ dict_t *xdata);
+
+call_stub_t *
+fop_getactivelk_cbk_stub(call_frame_t *frame, fop_getactivelk_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ lock_migration_info_t *lmi, dict_t *xdata);
+
+call_stub_t *
+fop_setactivelk_stub(call_frame_t *frame, fop_setactivelk_t fn, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata);
+
+call_stub_t *
+fop_setactivelk_cbk_stub(call_frame_t *frame, fop_setactivelk_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+call_stub_t *
+fop_put_stub(call_frame_t *frame, fop_put_t fn, loc_t *loc, mode_t mode,
+ mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,
+ off_t offset, struct iobref *iobref, dict_t *xattr, dict_t *xdata);
+
+call_stub_t *
+fop_put_cbk_stub(call_frame_t *frame, fop_put_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata);
+
+call_stub_t *
+fop_icreate_stub(call_frame_t *frame, fop_icreate_t fn, loc_t *loc, mode_t mode,
+ dict_t *xdata);
+
+call_stub_t *
+fop_namelink_stub(call_frame_t *frame, fop_namelink_t fn, loc_t *loc,
+ dict_t *xdata);
+
+call_stub_t *
+fop_icreate_cbk_stub(call_frame_t *frame, fop_icreate_cbk_t fn, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata);
+
+call_stub_t *
+fop_namelink_cbk_stub(call_frame_t *frame, fop_namelink_cbk_t fn,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata);
+
+call_stub_t *
+fop_copy_file_range_stub(call_frame_t *frame, fop_copy_file_range_t fn,
+ fd_t *fd_in, off64_t off_in, fd_t *fd_out,
+ off64_t off_out, size_t len, uint32_t flags,
+ dict_t *xdata);
+
+call_stub_t *
+fop_copy_file_range_cbk_stub(call_frame_t *frame, fop_copy_file_range_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *stbuf, struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, dict_t *xdata);
+
+void
+call_resume(call_stub_t *stub);
+void
+call_resume_keep_stub(call_stub_t *stub);
+void
+call_stub_destroy(call_stub_t *stub);
+void
+call_unwind_error(call_stub_t *stub, int op_ret, int op_errno);
+void
+call_unwind_error_keep_stub(call_stub_t *stub, int op_ret, int op_errno);
+
+/*
+ * Sometimes we might want to call just this, perhaps repeatedly, without
+ * having (or being able) to destroy and recreate it.
+ */
+void
+call_resume_wind(call_stub_t *stub);
+
+#endif
diff --git a/libglusterfs/src/checksum.h b/libglusterfs/src/glusterfs/checksum.h
index bf7eeede8fc..019bb14df71 100644
--- a/libglusterfs/src/checksum.h
+++ b/libglusterfs/src/glusterfs/checksum.h
@@ -12,9 +12,11 @@
#define __CHECKSUM_H__
uint32_t
-gf_rsync_weak_checksum (unsigned char *buf, size_t len);
+gf_rsync_weak_checksum(unsigned char *buf, size_t len);
void
-gf_rsync_strong_checksum (unsigned char *buf, size_t len, unsigned char *sum);
+gf_rsync_strong_checksum(unsigned char *buf, size_t len, unsigned char *sum);
+void
+gf_rsync_md5_checksum(unsigned char *data, size_t len, unsigned char *md5);
#endif /* __CHECKSUM_H__ */
diff --git a/libglusterfs/src/glusterfs/circ-buff.h b/libglusterfs/src/glusterfs/circ-buff.h
new file mode 100644
index 00000000000..822345b641b
--- /dev/null
+++ b/libglusterfs/src/glusterfs/circ-buff.h
@@ -0,0 +1,61 @@
+/*
+ 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 "glusterfs/common-utils.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;
+ void (*destroy_buffer_data)(void *data);
+ 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 (*destroy_data)(void *data));
+
+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/glusterfs/client_t.h b/libglusterfs/src/glusterfs/client_t.h
new file mode 100644
index 00000000000..a2c508e1d5c
--- /dev/null
+++ b/libglusterfs/src/glusterfs/client_t.h
@@ -0,0 +1,147 @@
+/*
+ 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 _CLIENT_T_H
+#define _CLIENT_T_H
+
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/locking.h" /* for gf_lock_t, not included by glusterfs.h */
+#include "glusterfs/atomic.h" /* for gf_atomic_t */
+
+/* auth_data structure is required by RPC layer. But as it is also used in
+ * client_t structure validation, comparision, it is critical that it is defined
+ * in the larger scope of libglusterfs, instead of libgfrpc. With this change,
+ * even RPC will use this structure */
+#define GF_CLIENTT_AUTH_BYTES 400
+typedef struct client_auth_data {
+ int flavour;
+ int datalen;
+ char authdata[GF_CLIENTT_AUTH_BYTES];
+} client_auth_data_t;
+
+struct client_ctx {
+ void *ctx_key;
+ void *ctx_value;
+};
+
+typedef struct _client {
+ struct {
+ /* e.g. protocol/server stashes its ctx here */
+ gf_lock_t lock;
+ unsigned short count;
+ struct client_ctx *ctx;
+ } scratch_ctx;
+ gf_atomic_t bind;
+ gf_atomic_t count;
+ xlator_t *bound_xl;
+ xlator_t *this;
+ int tbl_index;
+ char *client_uid;
+ char *client_name;
+ struct {
+ int flavour;
+ size_t len;
+ char *data;
+ char *username;
+ char *passwd;
+ } auth;
+
+ /* subdir_mount */
+ char *subdir_mount;
+ inode_t *subdir_inode;
+ uuid_t subdir_gfid;
+ int32_t opversion;
+ /* Variable to save fd_count for detach brick */
+ gf_atomic_t fd_cnt;
+} client_t;
+
+#define GF_CLIENTCTX_INITIAL_SIZE 8
+
+struct client_table_entry {
+ client_t *client;
+ int next_free;
+};
+typedef struct client_table_entry cliententry_t;
+
+struct clienttable {
+ unsigned int max_clients;
+ gf_lock_t lock;
+ cliententry_t *cliententries;
+ int first_free;
+ client_t *local;
+};
+typedef struct clienttable clienttable_t;
+
+#define GF_CLIENTTABLE_INITIAL_SIZE 128
+
+/* Signifies no more entries in the client table. */
+#define GF_CLIENTTABLE_END -1
+
+/* This is used to invalidate
+ * the next_free value in an cliententry that has been allocated
+ */
+#define GF_CLIENTENTRY_ALLOCATED -2
+
+void
+gf_client_put(client_t *client, gf_boolean_t *detached);
+
+clienttable_t *
+gf_clienttable_alloc(void);
+
+client_t *
+gf_client_ref(client_t *client);
+
+void
+gf_client_unref(client_t *client);
+
+int
+gf_client_dump_fdtable_to_dict(xlator_t *this, dict_t *dict);
+
+int
+gf_client_dump_fdtable(xlator_t *this);
+
+int
+gf_client_dump_inodes_to_dict(xlator_t *this, dict_t *dict);
+
+int
+gf_client_dump_inodes(xlator_t *this);
+
+void *
+client_ctx_set(client_t *client, void *key, void *value);
+
+int
+client_ctx_get(client_t *client, void *key, void **value);
+
+int
+client_ctx_del(client_t *client, void *key, void **value);
+
+void
+client_ctx_dump(client_t *client, char *prefix);
+
+int
+gf_client_dump_fdtables_to_dict(xlator_t *this, dict_t *dict);
+
+int
+gf_client_dump_fdtables(xlator_t *this);
+
+int
+gf_client_dump_inodes_to_dict(xlator_t *this, dict_t *dict);
+
+int
+gf_client_dump_inodes(xlator_t *this);
+
+int
+gf_client_disconnect(client_t *client);
+
+client_t *
+gf_client_get(xlator_t *this, client_auth_data_t *cred, char *client_uid,
+ char *subdir_mount);
+
+#endif /* _CLIENT_T_H */
diff --git a/libglusterfs/src/glusterfs/cluster-syncop.h b/libglusterfs/src/glusterfs/cluster-syncop.h
new file mode 100644
index 00000000000..d0ad5ed548c
--- /dev/null
+++ b/libglusterfs/src/glusterfs/cluster-syncop.h
@@ -0,0 +1,227 @@
+/*
+ Copyright (c) 2015 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 _CLUSTER_SYNCOP_H
+#define _CLUSTER_SYNCOP_H
+
+#include <sys/time.h>
+#include <pthread.h>
+#include <ucontext.h>
+
+#include "glusterfs/defaults.h"
+#include "glusterfs/default-args.h"
+#include "glusterfs/syncop.h"
+
+/*********************************************************************
+ *
+ * PARALLEL_FOP_ONLIST:
+ * Performs file operations in parallel on bricks.
+ * This macro expects a helper function(func) to implement the
+ * functionality.
+ *
+ ********************************************************************/
+#define PARALLEL_FOP_ONLIST(subvols, on, numsubvols, replies, frame, func, \
+ args...) \
+ do { \
+ int __i = 0; \
+ int __count = 0; \
+ cluster_local_t __local = { \
+ 0, \
+ }; \
+ void *__old_local = frame->local; \
+ \
+ __local.replies = replies; \
+ cluster_replies_wipe(replies, numsubvols); \
+ for (__i = 0; __i < numsubvols; __i++) \
+ INIT_LIST_HEAD(&replies[__i].entries.list); \
+ if (syncbarrier_init(&__local.barrier)) \
+ break; \
+ frame->local = &__local; \
+ for (__i = 0; __i < numsubvols; __i++) { \
+ if (on[__i]) { \
+ __count++; \
+ } \
+ } \
+ __local.barrier.waitfor = __count; \
+ for (__i = 0; __i < numsubvols; __i++) { \
+ if (on[__i]) { \
+ func(frame, subvols[__i], __i, ##args); \
+ } \
+ } \
+ syncbarrier_wait(&__local.barrier, __count); \
+ syncbarrier_destroy(&__local.barrier); \
+ frame->local = __old_local; \
+ STACK_RESET(frame->root); \
+ } while (0)
+
+typedef struct cluster_local_ {
+ default_args_cbk_t *replies;
+ syncbarrier_t barrier;
+} cluster_local_t;
+
+int32_t
+cluster_lookup(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata);
+int32_t
+cluster_setattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata);
+int32_t
+cluster_getxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata);
+int32_t
+cluster_setxattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata);
+
+int
+cluster_inodelk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom, inode_t *inode,
+ off_t off, size_t size);
+
+int
+cluster_uninodelk(xlator_t **subvols, unsigned char *locked_on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, off_t off, size_t size);
+
+int
+cluster_entrylk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom, inode_t *inode,
+ const char *name);
+
+int32_t
+cluster_rmdir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata);
+
+int32_t
+cluster_unlink(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
+ dict_t *xdata);
+
+int
+cluster_mkdir(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, dict_t *xdata);
+
+int32_t
+cluster_readlink(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
+ dict_t *xdata);
+
+int
+cluster_symlink(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc, mode_t umask, dict_t *xdata);
+
+int32_t
+cluster_link(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata);
+
+int
+cluster_mknod(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, mode_t umask, dict_t *xdata);
+
+int
+cluster_unentrylk(xlator_t **subvols, unsigned char *locked_on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, const char *name);
+
+int
+cluster_tryentrylk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, const char *name);
+
+int32_t
+cluster_fxattrop(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata);
+
+int32_t
+cluster_xattrop(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata);
+
+int32_t
+cluster_fstat(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata);
+
+int32_t
+cluster_ftruncate(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ dict_t *xdata);
+
+int32_t
+cluster_open(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, dict_t *xdata);
+
+int
+cluster_tryinodelk(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *locked_on,
+ call_frame_t *frame, xlator_t *this, char *dom,
+ inode_t *inode, off_t off, size_t size);
+
+int32_t
+cluster_fsetattr(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata);
+
+int32_t
+cluster_put(xlator_t **subvols, unsigned char *on, int numsubvols,
+ default_args_cbk_t *replies, unsigned char *output,
+ call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,
+ off_t offset, struct iobref *iobref, dict_t *xattr, dict_t *xdata);
+
+void
+cluster_replies_wipe(default_args_cbk_t *replies, int num_subvols);
+
+int32_t
+cluster_fop_success_fill(default_args_cbk_t *replies, int numsubvols,
+ unsigned char *success);
+
+int32_t
+cluster_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata);
+
+int
+cluster_tiebreaker_inodelk(xlator_t **subvols, unsigned char *on,
+ int numsubvols, default_args_cbk_t *replies,
+ unsigned char *locked_on, call_frame_t *frame,
+ xlator_t *this, char *dom, inode_t *inode, off_t off,
+ size_t size);
+#endif /* !_CLUSTER_SYNCOP_H */
diff --git a/libglusterfs/src/glusterfs/common-utils.h b/libglusterfs/src/glusterfs/common-utils.h
new file mode 100644
index 00000000000..f297fdab5c9
--- /dev/null
+++ b/libglusterfs/src/glusterfs/common-utils.h
@@ -0,0 +1,1256 @@
+/*
+ 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
+#define _COMMON_UTILS_H
+
+#include <stdint.h>
+#include <sys/uio.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <openssl/md5.h>
+#ifndef GF_BSD_HOST_OS
+#include <alloca.h>
+#endif
+#include <limits.h>
+#include <fnmatch.h>
+#include <uuid/uuid.h>
+
+/* FreeBSD, etc. */
+#ifndef __BITS_PER_LONG
+#define __BITS_PER_LONG (CHAR_BIT * (sizeof(long)))
+#endif
+
+#ifndef ffsll
+#define ffsll(x) __builtin_ffsll(x)
+#endif
+
+void
+trap(void);
+
+#define GF_UNIVERSAL_ANSWER 42 /* :O */
+
+/* To solve type punned error */
+#define VOID(ptr) ((void **)((void *)ptr))
+
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/compat-uuid.h"
+#include "glusterfs/iatt.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+#define STRINGIFY(val) #val
+#define TOSTRING(val) STRINGIFY(val)
+
+#define alloca0(size) \
+ ({ \
+ void *__ptr; \
+ __ptr = alloca(size); \
+ memset(__ptr, 0, size); \
+ __ptr; \
+ })
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define gf_roof(a, b) ((((a) + (b)-1) / ((b != 0) ? (b) : 1)) * (b))
+#define gf_floor(a, b) (((a) / ((b != 0) ? (b) : 1)) * (b))
+
+#define IPv4_ADDR_SIZE 32
+
+#define GF_UNIT_KB 1024ULL
+#define GF_UNIT_MB 1048576ULL
+#define GF_UNIT_GB 1073741824ULL
+#define GF_UNIT_TB 1099511627776ULL
+#define GF_UNIT_PB 1125899906842624ULL
+
+#define GF_UNIT_B_STRING "B"
+#define GF_UNIT_KB_STRING "KB"
+#define GF_UNIT_MB_STRING "MB"
+#define GF_UNIT_GB_STRING "GB"
+#define GF_UNIT_TB_STRING "TB"
+#define GF_UNIT_PB_STRING "PB"
+
+#define GF_UNIT_PERCENT_STRING "%"
+
+#define GEOREP "geo-replication"
+#define GLUSTERD_NAME "glusterd"
+
+#define GF_SELINUX_XATTR_KEY "security.selinux"
+
+#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"))
+
+/* process mode definitions */
+#define GF_SERVER_PROCESS 0
+#define GF_CLIENT_PROCESS 1
+#define GF_GLUSTERD_PROCESS 2
+
+/* Defining this here as it is needed by glusterd for setting
+ * nfs port in volume status.
+ */
+#define GF_NFS3_PORT 2049
+
+#define GF_CLIENT_PORT_CEILING 1024
+#define GF_IANA_PRIV_PORTS_START 49152 /* RFC 6335 */
+#define GF_CLNT_INSECURE_PORT_CEILING (GF_IANA_PRIV_PORTS_START - 1)
+#define GF_PORT_MAX 65535
+#define GF_PORT_ARRAY_SIZE ((GF_PORT_MAX + 7) / 8)
+#define GF_LOCK_TIMER 180
+#define GF_MINUTE_IN_SECONDS 60
+#define GF_HOUR_IN_SECONDS (60 * 60)
+#define GF_DAY_IN_SECONDS (24 * 60 * 60)
+#define GF_WEEK_IN_SECONDS (7 * 24 * 60 * 60)
+#define GF_SEC_IN_NS 1000000000
+#define GF_MS_IN_NS 1000000
+#define GF_US_IN_NS 1000
+
+/* Default timeout for both barrier and changelog translator */
+#define BARRIER_TIMEOUT "120"
+
+/* Default value of signing waiting time to sign a file for bitrot */
+#define SIGNING_TIMEOUT "120"
+#define BR_WORKERS "4"
+
+/* xxhash */
+#define GF_XXH64_DIGEST_LENGTH 8
+#define GF_XXHSUM64_DEFAULT_SEED 0
+
+/* Shard */
+#define GF_XATTR_SHARD_FILE_SIZE "trusted.glusterfs.shard.file-size"
+#define SHARD_ROOT_GFID "be318638-e8a0-4c6d-977d-7a937aa84806"
+#define DOT_SHARD_REMOVE_ME_GFID "77dd5a45-dbf5-4592-b31b-b440382302e9"
+
+/* Lease: buffer length for stringified lease id
+ * Format: 4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum
+ * Eg:6c69-6431-2d63-6c6e-7431-0000-0000-0000
+ */
+#define GF_LEASE_ID_BUF_SIZE ((LEASE_ID_SIZE * 2) + (LEASE_ID_SIZE / 2))
+
+#define GF_PERCENTAGE(val, total) (((val)*100) / (total))
+
+/* pthread related */
+/* as per the man page, thread-name should be at max 16 bytes */
+/* with prefix of 'glfs_' (5), we are left with 11 more bytes */
+#define GF_THREAD_NAME_LIMIT 16
+#define GF_THREAD_NAME_PREFIX "glfs_"
+
+/* Advisory buffer size for formatted timestamps (see gf_time_fmt) */
+#define GF_TIMESTR_SIZE 256
+
+/*
+ * 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 few clients that use this feature, it's okay.
+ */
+enum _gf_special_pid {
+ GF_CLIENT_PID_MAX = 0,
+ GF_CLIENT_PID_GSYNCD = -1,
+ GF_CLIENT_PID_HADOOP = -2,
+ GF_CLIENT_PID_DEFRAG = -3,
+ GF_CLIENT_PID_NO_ROOT_SQUASH = -4,
+ GF_CLIENT_PID_QUOTA_MOUNT = -5,
+ GF_CLIENT_PID_SELF_HEALD = -6,
+ GF_CLIENT_PID_GLFS_HEAL = -7,
+ GF_CLIENT_PID_BITD = -8,
+ GF_CLIENT_PID_SCRUB = -9,
+ GF_CLIENT_PID_TIER_DEFRAG = -10,
+ GF_SERVER_PID_TRASH = -11,
+ GF_CLIENT_PID_ADD_REPLICA_MOUNT = -12,
+ GF_CLIENT_PID_SET_UTIME = -13,
+};
+
+enum _gf_xlator_ipc_targets {
+ GF_IPC_TARGET_CHANGELOG = 0,
+ GF_IPC_TARGET_CTR = 1,
+ GF_IPC_TARGET_UPCALL = 2
+};
+
+typedef enum _gf_special_pid gf_special_pid_t;
+typedef enum _gf_xlator_ipc_targets _gf_xlator_ipc_targets_t;
+
+/* Array to hold custom xattr keys */
+extern char *xattrs_to_heal[];
+
+char **
+get_xattrs_to_heal();
+
+/* The DHT file rename operation is not a straightforward rename.
+ * It involves creating linkto and linkfiles, and can unlink or rename the
+ * source file depending on the hashed and cached subvols for the source
+ * and target files. this makes it difficult for geo-rep to figure out that
+ * a rename operation has taken place.
+ *
+ * We now send a special key and the values of the source and target pargfids
+ * and basenames to indicate to changelog that the operation in question
+ * should be treated as a rename. We are explicitly filling and sending this
+ * as a binary value in the dictionary as the unlink op will not have the
+ * source file information. The lengths of the src and target basenames
+ * are used to calculate where to start reading the names in the structure.
+ * XFS allows a max of 255 chars for filenames but other file systems might
+ * not have such restrictions
+ */
+typedef struct dht_changelog_rename_info {
+ uuid_t old_pargfid;
+ uuid_t new_pargfid;
+ int32_t oldname_len;
+ int32_t newname_len;
+ char buffer[1];
+} dht_changelog_rename_info_t;
+
+typedef int (*gf_cmp)(void *, void *);
+
+struct _dict;
+
+struct dnscache {
+ struct _dict *cache_dict;
+ time_t ttl;
+};
+
+struct dnscache_entry {
+ char *ip;
+ char *fqdn;
+ time_t timestamp;
+};
+
+struct dnscache6 {
+ struct addrinfo *first;
+ struct addrinfo *next;
+};
+
+struct list_node {
+ void *ptr;
+ struct list_head list;
+};
+
+extern char *vol_type_str[];
+
+struct list_node *
+list_node_add(void *ptr, struct list_head *list);
+struct list_node *
+list_node_add_order(void *ptr, struct list_head *list,
+ int (*compare)(struct list_head *, struct list_head *));
+void
+list_node_del(struct list_node *node);
+
+struct dnscache *
+gf_dnscache_init(time_t ttl);
+void
+gf_dnscache_deinit(struct dnscache *cache);
+struct dnscache_entry *
+gf_dnscache_entry_init(void);
+void
+gf_dnscache_entry_deinit(struct dnscache_entry *entry);
+char *
+gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache);
+
+char *
+gf_resolve_path_parent(const char *path);
+
+void
+gf_global_variable_init(void);
+
+int32_t
+gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache,
+ struct addrinfo **addr_info);
+
+void
+gf_log_dump_graph(FILE *specfp, glusterfs_graph_t *graph);
+void
+gf_print_trace(int32_t signal, glusterfs_ctx_t *ctx);
+int
+gf_set_log_file_path(cmd_args_t *cmd_args, glusterfs_ctx_t *ctx);
+int
+gf_set_log_ident(cmd_args_t *cmd_args);
+
+int
+gf_process_getspec_servers_list(cmd_args_t *cmd_args, const char *servers_list);
+int
+gf_set_volfile_server_common(cmd_args_t *cmd_args, const char *host,
+ const char *transport, int port);
+
+static inline void
+BIT_SET(unsigned char *array, unsigned int index)
+{
+ unsigned int offset = index / 8;
+ unsigned int shift = index % 8;
+
+ array[offset] |= (1 << shift);
+}
+
+static inline void
+BIT_CLEAR(unsigned char *array, unsigned int index)
+{
+ unsigned int offset = index / 8;
+ unsigned int shift = index % 8;
+
+ array[offset] &= ~(1 << shift);
+}
+
+static inline unsigned int
+BIT_VALUE(unsigned char *array, unsigned int index)
+{
+ unsigned int offset = index / 8;
+ unsigned int shift = index % 8;
+
+ return (array[offset] >> shift) & 0x1;
+}
+
+#define VECTORSIZE(count) (count * (sizeof(struct iovec)))
+
+#define STRLEN_0(str) (strlen(str) + 1)
+
+#define VALIDATE_OR_GOTO(arg, label) \
+ do { \
+ if (!arg) { \
+ errno = EINVAL; \
+ gf_msg_callingfn((this ? (this->name) : "(Govinda! Govinda!)"), \
+ GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, \
+ "invalid argument: " #arg); \
+ goto label; \
+ } \
+ } while (0)
+
+#define GF_VALIDATE_OR_GOTO(name, arg, label) \
+ do { \
+ if (!arg) { \
+ errno = EINVAL; \
+ gf_msg_callingfn(name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG, \
+ "invalid argument: " #arg); \
+ goto label; \
+ } \
+ } while (0)
+
+#define GF_VALIDATE_OR_GOTO_WITH_ERROR(name, arg, label, errno, error) \
+ do { \
+ if (!arg) { \
+ errno = error; \
+ gf_msg_callingfn(name, GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, \
+ "invalid argument: " #arg); \
+ goto label; \
+ } \
+ } while (0)
+
+#define GF_CHECK_ALLOC(arg, retval, label) \
+ do { \
+ if (!(arg)) { \
+ retval = -ENOMEM; \
+ goto label; \
+ } \
+ } while (0)
+
+#define GF_CHECK_ALLOC_AND_LOG(name, item, retval, msg, errlabel) \
+ do { \
+ if (!(item)) { \
+ (retval) = -ENOMEM; \
+ gf_msg(name, GF_LOG_CRITICAL, ENOMEM, LG_MSG_NO_MEMORY, (msg)); \
+ goto errlabel; \
+ } \
+ } 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 { \
+ GF_VALIDATE_OR_GOTO(name, arg, label); \
+ if ((arg[0]) != '/') { \
+ errno = EINVAL; \
+ gf_msg_callingfn(name, GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, \
+ "invalid argument: " #arg); \
+ goto label; \
+ } \
+ } 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_REMOVE_INTERNAL_XATTR(pattern, dict) \
+ do { \
+ if (!dict) { \
+ gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_DICT_NULL, \
+ "dict is null"); \
+ break; \
+ } \
+ dict_foreach_fnmatch(dict, pattern, dict_remove_foreach_fn, NULL); \
+ } while (0)
+
+#define GF_IF_INTERNAL_XATTR_GOTO(pattern, dict, op_errno, label) \
+ do { \
+ if (!dict) { \
+ gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_DICT_NULL, \
+ "setxattr dict is null"); \
+ goto label; \
+ } \
+ if (dict_foreach_fnmatch(dict, pattern, dict_null_foreach_fn, NULL) > \
+ 0) { \
+ op_errno = EPERM; \
+ gf_msg(this->name, GF_LOG_ERROR, op_errno, LG_MSG_NO_PERM, \
+ "attempt to set internal" \
+ " xattr: %s", \
+ pattern); \
+ goto label; \
+ } \
+ } while (0)
+
+#define GF_IF_NATIVE_XATTR_GOTO(pattern, key, op_errno, label) \
+ do { \
+ if (!key) { \
+ gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_NO_KEY, \
+ "no key for removexattr"); \
+ goto label; \
+ } \
+ if (!fnmatch(pattern, key, 0)) { \
+ op_errno = EPERM; \
+ gf_msg(this->name, GF_LOG_ERROR, op_errno, LG_MSG_NO_PERM, \
+ "attempt to remove internal " \
+ "xattr: %s", \
+ key); \
+ goto label; \
+ } \
+ } while (0)
+
+#ifdef DEBUG
+#define GF_ASSERT(x) assert(x);
+#else
+#define GF_ASSERT(x) \
+ do { \
+ if (!(x)) { \
+ gf_msg_callingfn("", GF_LOG_ERROR, 0, LG_MSG_ASSERTION_FAILED, \
+ "Assertion failed: " #x); \
+ } \
+ } while (0)
+#endif
+
+/* Compile-time assert, borrowed from Linux kernel. */
+#ifdef HAVE_STATIC_ASSERT
+#define GF_STATIC_ASSERT(expr, ...) \
+ __gf_static_assert(expr, ##__VA_ARGS__, #expr)
+#define __gf_static_assert(expr, msg, ...) _Static_assert(expr, msg)
+#else
+#define GF_STATIC_ASSERT(expr, ...)
+#endif
+
+#define GF_ABORT(msg...) \
+ do { \
+ gf_msg_callingfn("", GF_LOG_CRITICAL, 0, LG_MSG_ASSERTION_FAILED, \
+ "Assertion failed: " msg); \
+ abort(); \
+ } while (0)
+
+#define GF_UUID_ASSERT(u) \
+ if (gf_uuid_is_null(u)) \
+ GF_ASSERT(!"uuid null");
+
+#define GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, op_errno) \
+ (((frame->root->pid == GF_CLIENT_PID_GSYNCD) && \
+ (op_errno == EEXIST || op_errno == ENOENT)) \
+ ? 0 \
+ : 1)
+
+union gf_sock_union {
+ struct sockaddr_storage storage;
+ struct sockaddr_in6 sin6;
+ struct sockaddr_in sin;
+ struct sockaddr sa;
+};
+
+#define GF_HIDDEN_PATH ".glusterfs"
+#define GF_UNLINK_PATH GF_HIDDEN_PATH "/unlink"
+#define GF_LANDFILL_PATH GF_HIDDEN_PATH "/landfill"
+
+#define IOV_MIN(n) min(IOV_MAX, n)
+
+static inline gf_boolean_t
+gf_irrelevant_entry(struct dirent *entry)
+{
+ GF_ASSERT(entry);
+
+ return (!strcmp(entry->d_name, ".") ||
+ !fnmatch("*.tmp", entry->d_name, 0) ||
+ !strcmp(entry->d_name, ".."));
+}
+
+static inline void
+iov_free(struct iovec *vector, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ FREE(vector[i].iov_base);
+
+ GF_FREE(vector);
+}
+
+static inline int
+iov_length(const struct iovec *vector, int count)
+{
+ int i = 0;
+ size_t size = 0;
+
+ for (i = 0; i < count; i++)
+ size += vector[i].iov_len;
+
+ return size;
+}
+
+static inline struct iovec *
+iov_dup(const struct iovec *vector, int count)
+{
+ int bytecount = 0;
+ struct iovec *newvec = NULL;
+
+ bytecount = (count * sizeof(struct iovec));
+ newvec = GF_MALLOC(bytecount, gf_common_mt_iovec);
+ if (newvec != NULL) {
+ memcpy(newvec, vector, bytecount);
+ }
+
+ return newvec;
+}
+
+typedef struct _iov_iter {
+ const struct iovec *iovec;
+ void *ptr;
+ uint32_t len;
+ uint32_t count;
+} iov_iter_t;
+
+static inline bool
+iov_iter_init(iov_iter_t *iter, const struct iovec *iovec, uint32_t count,
+ uint32_t offset)
+{
+ uint32_t len;
+
+ while (count > 0) {
+ count--;
+ len = iovec->iov_len;
+ if (offset < len) {
+ iter->ptr = iovec->iov_base + offset;
+ iter->len = len - offset;
+ iter->iovec = iovec + 1;
+ iter->count = count;
+
+ return true;
+ }
+ offset -= len;
+ }
+
+ memset(iter, 0, sizeof(*iter));
+
+ return false;
+}
+
+static inline bool
+iov_iter_end(iov_iter_t *iter)
+{
+ return iter->count == 0;
+}
+
+static inline bool
+iov_iter_next(iov_iter_t *iter, uint32_t size)
+{
+ GF_ASSERT(size <= iter->len);
+
+ if (iter->len > size) {
+ iter->len -= size;
+ iter->ptr += size;
+
+ return true;
+ }
+ if (iter->count > 0) {
+ iter->count--;
+ iter->ptr = iter->iovec->iov_base;
+ iter->len = iter->iovec->iov_len;
+ iter->iovec++;
+
+ return true;
+ }
+
+ memset(iter, 0, sizeof(*iter));
+
+ return false;
+}
+
+static inline uint32_t
+iov_iter_copy(iov_iter_t *dst, iov_iter_t *src, uint32_t size)
+{
+ uint32_t len;
+
+ len = src->len;
+ if (len > dst->len) {
+ len = dst->len;
+ }
+ if (len > size) {
+ len = size;
+ }
+ memcpy(dst->ptr, src->ptr, len);
+
+ return len;
+}
+
+static inline uint32_t
+iov_iter_to_iovec(iov_iter_t *iter, struct iovec *iovec, int32_t idx,
+ uint32_t size)
+{
+ uint32_t len;
+
+ len = iter->len;
+ if (len > size) {
+ len = size;
+ }
+ iovec[idx].iov_base = iter->ptr;
+ iovec[idx].iov_len = len;
+
+ return len;
+}
+
+static inline int
+iov_subset(struct iovec *src, int src_count, uint32_t start, uint32_t size,
+ struct iovec **dst, int32_t dst_count)
+{
+ struct iovec iovec[src_count];
+ iov_iter_t iter;
+ uint32_t len;
+ int32_t idx;
+
+ if ((size == 0) || !iov_iter_init(&iter, src, src_count, start)) {
+ return 0;
+ }
+
+ idx = 0;
+ do {
+ len = iov_iter_to_iovec(&iter, iovec, idx, size);
+ idx++;
+ size -= len;
+ } while ((size > 0) && iov_iter_next(&iter, len));
+
+ if (*dst == NULL) {
+ *dst = iov_dup(iovec, idx);
+ if (*dst == NULL) {
+ return -1;
+ }
+ } else if (idx > dst_count) {
+ return -1;
+ } else {
+ memcpy(*dst, iovec, idx * sizeof(struct iovec));
+ }
+
+ return idx;
+}
+
+static inline int
+iov_skip(struct iovec *iovec, uint32_t count, uint32_t size)
+{
+ uint32_t len, idx;
+
+ idx = 0;
+ while ((size > 0) && (idx < count)) {
+ len = iovec[idx].iov_len;
+ if (len > size) {
+ iovec[idx].iov_len -= size;
+ iovec[idx].iov_base += size;
+ break;
+ }
+ idx++;
+ size -= len;
+ }
+
+ if (idx > 0) {
+ memmove(iovec, iovec + idx, (count - idx) * sizeof(struct iovec));
+ }
+
+ return count - idx;
+}
+
+static inline size_t
+iov_range_copy(const struct iovec *dst, uint32_t dst_count, uint32_t dst_offset,
+ const struct iovec *src, uint32_t src_count, uint32_t src_offset,
+ uint32_t size)
+{
+ iov_iter_t src_iter, dst_iter;
+ uint32_t len, total;
+
+ if ((size == 0) || !iov_iter_init(&src_iter, src, src_count, src_offset) ||
+ !iov_iter_init(&dst_iter, dst, dst_count, dst_offset)) {
+ return 0;
+ }
+
+ total = 0;
+ do {
+ len = iov_iter_copy(&dst_iter, &src_iter, size);
+ total += len;
+ size -= len;
+ } while ((size > 0) && iov_iter_next(&src_iter, len) &&
+ iov_iter_next(&dst_iter, len));
+
+ return total;
+}
+
+static inline void
+iov_unload(char *buf, const struct iovec *vector, int count)
+{
+ int i;
+ int copied = 0;
+
+ for (i = 0; i < count; i++) {
+ memcpy(buf + copied, vector[i].iov_base, vector[i].iov_len);
+ copied += vector[i].iov_len;
+ }
+}
+
+static inline size_t
+iov_load(const struct iovec *vector, int count, char *buf, int size)
+{
+ size_t left = size;
+ size_t cp = 0;
+ int ret = 0;
+ int i = 0;
+
+ while (left && i < count) {
+ cp = min(vector[i].iov_len, left);
+ if (vector[i].iov_base != buf + (size - left))
+ memcpy(vector[i].iov_base, buf + (size - left), cp);
+ ret += cp;
+ left -= cp;
+ if (left)
+ i++;
+ }
+
+ return ret;
+}
+
+static inline size_t
+iov_copy(const struct iovec *dst, int dcnt, const struct iovec *src, int scnt)
+{
+ return iov_range_copy(dst, dcnt, 0, src, scnt, 0, UINT32_MAX);
+}
+
+/* based on the amusing discussion @ https://rusty.ozlabs.org/?p=560 */
+static bool
+memeqzero(const void *data, size_t length)
+{
+ const unsigned char *p = data;
+ size_t len;
+
+ /* Check first 16 bytes manually */
+ for (len = 0; len < 16; len++) {
+ if (!length)
+ return true;
+ if (*p)
+ return false;
+ p++;
+ length--;
+ }
+
+ /* Now we know that's zero, memcmp with self. */
+ return memcmp(data, p, length) == 0;
+}
+
+static inline int
+mem_0filled(const char *buf, size_t size)
+{
+ return !memeqzero(buf, size);
+}
+
+static inline int
+iov_0filled(const struct iovec *vector, int count)
+{
+ int i = 0;
+ int ret = 0;
+
+ for (i = 0; i < count; i++) {
+ ret = mem_0filled(vector[i].iov_base, vector[i].iov_len);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+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, /* MMM DD hh:mm:ss */
+ gf_timefmt_F_HMS, /* YYYY-MM-DD hhmmss */
+ gf_timefmt_dirent,
+ gf_timefmt_s,
+ gf_timefmt_last
+} gf_timefmts;
+
+static inline char *
+gf_time_fmt_tv(char *dst, size_t sz_dst, struct timeval *tv, unsigned int fmt)
+{
+ extern void _gf_timestuff(const char ***, const char ***);
+ static gf_timefmts timefmt_last = (gf_timefmts)-1;
+ static const char **fmts;
+ static const char **zeros;
+ struct tm tm, *res;
+ int localtime = 0;
+ int len = 0;
+ int pos = 0;
+
+ if (timefmt_last == ((gf_timefmts)-1)) {
+ _gf_timestuff(&fmts, &zeros);
+ timefmt_last = gf_timefmt_last;
+ }
+ if (timefmt_last <= fmt) {
+ fmt = gf_timefmt_default;
+ }
+ localtime = gf_log_get_localtime();
+ res = localtime ? localtime_r(&tv->tv_sec, &tm)
+ : gmtime_r(&tv->tv_sec, &tm);
+ if (tv->tv_sec && (res != NULL)) {
+ len = strftime(dst, sz_dst, fmts[fmt], &tm);
+ if (len == 0)
+ return dst;
+ pos += len;
+ if (tv->tv_usec >= 0) {
+ len = snprintf(dst + pos, sz_dst - pos, ".%" GF_PRI_SUSECONDS,
+ tv->tv_usec);
+ if (len >= sz_dst - pos)
+ return dst;
+ pos += len;
+ }
+ strftime(dst + pos, sz_dst - pos, " %z", &tm);
+ } else {
+ strncpy(dst, "N/A", sz_dst);
+ }
+ return dst;
+}
+
+static inline char *
+gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt)
+{
+ struct timeval tv = {utime, -1};
+
+ return gf_time_fmt_tv(dst, sz_dst, &tv, fmt);
+}
+
+/* This function helps us use gfid (unique identity) to generate inode's unique
+ * number in glusterfs.
+ */
+ino_t
+gfid_to_ino(uuid_t gfid);
+
+int
+mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks);
+/*
+ * rounds up nr to power of two. If nr is already a power of two, just returns
+ * nr
+ */
+
+int
+gf_lstat_dir(const char *path, struct stat *stbuf_in);
+
+int32_t
+gf_roundup_power_of_two(int32_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(int32_t nr);
+
+char *
+gf_trim(char *string);
+int
+gf_volume_name_validate(const char *volume_name);
+
+int
+gf_string2long(const char *str, long *n);
+int
+gf_string2ulong(const char *str, unsigned long *n);
+int
+gf_string2int(const char *str, int *n);
+int
+gf_string2uint(const char *str, unsigned int *n);
+int
+gf_string2double(const char *str, double *n);
+int
+gf_string2longlong(const char *str, long long *n);
+int
+gf_string2ulonglong(const char *str, unsigned long long *n);
+
+int
+gf_string2int8(const char *str, int8_t *n);
+int
+gf_string2int16(const char *str, int16_t *n);
+int
+gf_string2int32(const char *str, int32_t *n);
+int
+gf_string2int64(const char *str, int64_t *n);
+int
+gf_string2uint8(const char *str, uint8_t *n);
+int
+gf_string2uint16(const char *str, uint16_t *n);
+int
+gf_string2uint32(const char *str, uint32_t *n);
+int
+gf_string2uint64(const char *str, uint64_t *n);
+
+int
+gf_strstr(const char *str, const char *delim, const char *match);
+
+int
+gf_string2ulong_base10(const char *str, unsigned long *n);
+int
+gf_string2uint_base10(const char *str, unsigned int *n);
+int
+gf_string2uint8_base10(const char *str, uint8_t *n);
+int
+gf_string2uint16_base10(const char *str, uint16_t *n);
+int
+gf_string2uint32_base10(const char *str, uint32_t *n);
+int
+gf_string2uint64_base10(const char *str, uint64_t *n);
+int
+gf_string2bytesize_uint64(const char *str, uint64_t *n);
+int
+gf_string2bytesize_int64(const char *str, int64_t *n);
+int
+gf_string2percent_or_bytesize(const char *str, double *n,
+ gf_boolean_t *is_percent);
+
+int
+gf_string2boolean(const char *str, gf_boolean_t *b);
+int
+gf_strn2boolean(const char *str, const int len, gf_boolean_t *b);
+int
+gf_string2percent(const char *str, double *n);
+int
+gf_string2time(const char *str, uint32_t *n);
+
+int
+gf_lockfd(int fd);
+int
+gf_unlockfd(int fd);
+
+int
+get_checksum_for_file(int fd, uint32_t *checksum, int op_version);
+int
+log_base2(unsigned long x);
+
+int
+get_checksum_for_path(char *path, uint32_t *checksum, int op_version);
+int
+get_file_mtime(const char *path, time_t *stamp);
+char *
+gf_resolve_path_parent(const char *path);
+
+char *
+strtail(char *str, const char *pattern);
+void
+skipwhite(char **s);
+char *
+nwstrtail(char *str, char *pattern);
+/* returns a new string with nth word of given string. n>=1 */
+
+typedef struct token_iter {
+ char *end;
+ char sep;
+} token_iter_t;
+char *
+token_iter_init(char *str, char sep, token_iter_t *tit);
+gf_boolean_t
+next_token(char **tokenp, token_iter_t *tit);
+void
+drop_token(char *token, token_iter_t *tit);
+
+gf_boolean_t
+mask_match(const uint32_t a, const uint32_t b, const uint32_t m);
+gf_boolean_t
+gf_is_ip_in_net(const char *network, const char *ip_str);
+char
+valid_host_name(char *address, int length);
+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,
+ gf_boolean_t cidr);
+gf_boolean_t
+valid_mount_auth_address(char *address);
+gf_boolean_t
+valid_ipv4_subnetwork(const char *address);
+gf_boolean_t
+gf_sock_union_equal_addr(union gf_sock_union *a, union gf_sock_union *b);
+char *
+gf_rev_dns_lookup(const char *ip);
+
+char *
+uuid_utoa(uuid_t uuid);
+char *
+uuid_utoa_r(uuid_t uuid, char *dst);
+char *
+lkowner_utoa(gf_lkowner_t *lkowner);
+char *
+lkowner_utoa_r(gf_lkowner_t *lkowner, char *dst, int len);
+char *
+leaseid_utoa(const char *lease_id);
+gf_boolean_t
+is_valid_lease_id(const char *lease_id);
+char *
+gf_leaseid_get(void);
+char *
+gf_existing_leaseid(void);
+
+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(void);
+int
+gf_strip_whitespace(char *str, int len);
+int
+gf_canonicalize_path(char *path);
+char *
+generate_glusterfs_ctx_id(void);
+char *
+gf_get_reserved_ports(void);
+int
+gf_process_reserved_ports(unsigned char *ports, uint32_t ceiling);
+gf_boolean_t
+gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling);
+int
+gf_get_hostname_from_ip(char *client_ip, char **hostname);
+gf_boolean_t
+gf_is_local_addr(char *hostname);
+gf_boolean_t
+gf_is_same_address(char *host1, char *host2);
+void
+gf_xxh64_wrapper(const unsigned char *data, size_t const len,
+ unsigned long long const seed, char *xxh64);
+int
+gf_gfid_generate_from_xxh64(uuid_t gfid, char *key);
+
+int
+gf_set_timestamp(const char *src, const char *dest);
+
+int
+gf_thread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg, const char *name,
+ ...) __attribute__((__format__(__printf__, 5, 6)));
+
+int
+gf_thread_vcreate(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg, const char *name,
+ va_list args);
+int
+gf_thread_create_detached(pthread_t *thread, void *(*start_routine)(void *),
+ void *arg, const char *name, ...)
+ __attribute__((__format__(__printf__, 4, 5)));
+
+void
+gf_thread_set_name(pthread_t thread, const char *name, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
+
+void
+gf_thread_set_vname(pthread_t thread, const char *name, va_list args);
+gf_boolean_t
+gf_is_pid_running(int pid);
+gf_boolean_t
+gf_is_service_running(char *pidfile, int *pid);
+gf_boolean_t
+gf_valid_pid(const char *pid, int length);
+int
+gf_skip_header_section(int fd, int header_len);
+
+struct iatt;
+struct _dict;
+
+gf_boolean_t
+dht_is_linkfile(struct iatt *buf, struct _dict *dict);
+
+int
+gf_check_log_format(const char *value);
+
+int
+gf_check_logger(const char *value);
+
+gf_boolean_t
+gf_compare_sockaddr(const struct sockaddr *addr1, const struct sockaddr *addr2);
+
+char *
+gf_backtrace_save(char *buf);
+
+void
+gf_backtrace_done(char *buf);
+
+gf_loglevel_t
+fop_log_level(glusterfs_fop_t fop, int op_errno);
+
+int32_t
+gf_build_absolute_path(char *current_path, char *relative_path, char **path);
+
+int
+recursive_rmdir(const char *delete_path);
+
+int
+gf_get_index_by_elem(char **array, char *elem);
+
+int
+glusterfs_is_local_pathinfo(char *pathinfo, gf_boolean_t *local);
+
+int
+gf_thread_cleanup_xint(pthread_t thread);
+
+ssize_t
+gf_nread(int fd, void *buf, size_t count);
+
+ssize_t
+gf_nwrite(int fd, const void *buf, size_t count);
+
+void
+_mask_cancellation(void);
+void
+_unmask_cancellation(void);
+
+gf_boolean_t
+gf_is_zero_filled_stat(struct iatt *buf);
+
+void
+gf_zero_fill_stat(struct iatt *buf);
+
+gf_boolean_t
+gf_is_valid_xattr_namespace(char *k);
+
+const char *
+gf_inode_type_to_str(ia_type_t type);
+
+int32_t
+gf_bits_count(uint64_t n);
+
+int32_t
+gf_bits_index(uint64_t n);
+
+const char *
+gf_fop_string(glusterfs_fop_t fop);
+
+int
+gf_fop_int(char *fop);
+
+char *
+get_ip_from_addrinfo(struct addrinfo *addr, char **ip);
+
+int
+close_fds_except(int *fdv, size_t count);
+
+int
+gf_getgrouplist(const char *user, gid_t group, gid_t **groups);
+
+int
+glusterfs_compute_sha256(const unsigned char *content, size_t size,
+ char *sha256_hash);
+
+char *
+gf_strncpy(char *dest, const char *src, const size_t dest_size);
+
+void
+gf_strTrim(char **s);
+
+int
+gf_replace_old_iatt_in_dict(struct _dict *);
+
+int
+gf_replace_new_iatt_in_dict(struct _dict *);
+
+xlator_cmdline_option_t *
+find_xlator_option_in_cmd_args_t(const char *option_name, cmd_args_t *args);
+
+int
+gf_d_type_from_ia_type(ia_type_t type);
+
+int
+gf_syncfs(int fd);
+
+int
+gf_nanosleep(uint64_t nsec);
+
+static inline time_t
+gf_time(void)
+{
+ return time(NULL);
+}
+
+/* Return delta value in microseconds. */
+
+static inline double
+gf_tvdiff(struct timeval *start, struct timeval *end)
+{
+ struct timeval t;
+
+ if (start->tv_usec > end->tv_usec)
+ t.tv_sec = end->tv_sec - 1, t.tv_usec = end->tv_usec + 1000000;
+ else
+ t.tv_sec = end->tv_sec, t.tv_usec = end->tv_usec;
+
+ return (double)(t.tv_sec - start->tv_sec) * 1e6 +
+ (double)(t.tv_usec - start->tv_usec);
+}
+
+/* Return delta value in nanoseconds. */
+
+static inline double
+gf_tsdiff(struct timespec *start, struct timespec *end)
+{
+ struct timespec t;
+
+ if (start->tv_nsec > end->tv_nsec)
+ t.tv_sec = end->tv_sec - 1, t.tv_nsec = end->tv_nsec + 1000000000;
+ else
+ t.tv_sec = end->tv_sec, t.tv_nsec = end->tv_nsec;
+
+ return (double)(t.tv_sec - start->tv_sec) * 1e9 +
+ (double)(t.tv_nsec - start->tv_nsec);
+}
+
+#endif /* _COMMON_UTILS_H */
diff --git a/libglusterfs/src/glusterfs/compat-errno.h b/libglusterfs/src/glusterfs/compat-errno.h
new file mode 100644
index 00000000000..c4ab09ab0d5
--- /dev/null
+++ b/libglusterfs/src/glusterfs/compat-errno.h
@@ -0,0 +1,238 @@
+/*
+ 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__
+#define __COMPAT_ERRNO_H__
+
+#include <errno.h>
+
+#define GF_ERROR_CODE_SUCCESS 0
+#define GF_ERROR_CODE_UNKNOWN 1024
+#define GF_ERRNO_UNKNOWN 1024
+
+#define GF_ERROR_CODE_PERM 1 /* Operation not permitted */
+#define GF_ERROR_CODE_NOENT 2 /* No such file or directory */
+#define GF_ERROR_CODE_SRCH 3 /* No such process */
+#define GF_ERROR_CODE_INTR 4 /* Interrupted system call */
+#define GF_ERROR_CODE_IO 5 /* I/O error */
+#define GF_ERROR_CODE_NXIO 6 /* No such device or address */
+#define GF_ERROR_CODE_2BIG 7 /* Argument list too long */
+#define GF_ERROR_CODE_NOEXEC 8 /* Exec format error */
+#define GF_ERROR_CODE_BADF 9 /* Bad file number */
+#define GF_ERROR_CODE_CHILD 10 /* No child processes */
+#define GF_ERROR_CODE_AGAIN 11 /* Try again */
+#define GF_ERROR_CODE_NOMEM 12 /* Out of memory */
+#define GF_ERROR_CODE_ACCES 13 /* Permission denied */
+#define GF_ERROR_CODE_FAULT 14 /* Bad address */
+#define GF_ERROR_CODE_NOTBLK 15 /* Block device required */
+#define GF_ERROR_CODE_BUSY 16 /* Device or resource busy */
+#define GF_ERROR_CODE_EXIST 17 /* File exists */
+#define GF_ERROR_CODE_XDEV 18 /* Cross-device link */
+#define GF_ERROR_CODE_NODEV 19 /* No such device */
+#define GF_ERROR_CODE_NOTDIR 20 /* Not a directory */
+#define GF_ERROR_CODE_ISDIR 21 /* Is a directory */
+#define GF_ERROR_CODE_INVAL 22 /* Invalid argument */
+#define GF_ERROR_CODE_NFILE 23 /* File table overflow */
+#define GF_ERROR_CODE_MFILE 24 /* Too many open files */
+#define GF_ERROR_CODE_NOTTY 25 /* Not a typewriter */
+#define GF_ERROR_CODE_TXTBSY 26 /* Text file busy */
+#define GF_ERROR_CODE_FBIG 27 /* File too large */
+#define GF_ERROR_CODE_NOSPC 28 /* No space left on device */
+#define GF_ERROR_CODE_SPIPE 29 /* Illegal seek */
+#define GF_ERROR_CODE_ROFS 30 /* Read-only file system */
+#define GF_ERROR_CODE_MLINK 31 /* Too many links */
+#define GF_ERROR_CODE_PIPE 32 /* Broken pipe */
+#define GF_ERROR_CODE_DOM 33 /* Math argument out of domain of func */
+#define GF_ERROR_CODE_RANGE 34 /* Math result not representable */
+#define GF_ERROR_CODE_DEADLK 35 /* Resource deadlock would occur */
+#define GF_ERROR_CODE_NAMETOOLONG 36 /* File name too long */
+#define GF_ERROR_CODE_NOLCK 37 /* No record locks available */
+#define GF_ERROR_CODE_NOSYS 38 /* Function not implemented */
+#define GF_ERROR_CODE_NOTEMPTY 39 /* Directory not empty */
+#define GF_ERROR_CODE_LOOP 40 /* Too many symbolic links encountered */
+
+#define GF_ERROR_CODE_NOMSG 42 /* No message of desired type */
+#define GF_ERROR_CODE_IDRM 43 /* Identifier removed */
+#define GF_ERROR_CODE_CHRNG 44 /* Channel number out of range */
+#define GF_ERROR_CODE_L2NSYNC 45 /* Level 2 not synchronized */
+#define GF_ERROR_CODE_L3HLT 46 /* Level 3 halted */
+#define GF_ERROR_CODE_L3RST 47 /* Level 3 reset */
+#define GF_ERROR_CODE_LNRNG 48 /* Link number out of range */
+#define GF_ERROR_CODE_UNATCH 49 /* Protocol driver not attached */
+#define GF_ERROR_CODE_NOCSI 50 /* No CSI structure available */
+#define GF_ERROR_CODE_L2HLT 51 /* Level 2 halted */
+#define GF_ERROR_CODE_BADE 52 /* Invalid exchange */
+#define GF_ERROR_CODE_BADR 53 /* Invalid request descriptor */
+#define GF_ERROR_CODE_XFULL 54 /* Exchange full */
+#define GF_ERROR_CODE_NOANO 55 /* No anode */
+#define GF_ERROR_CODE_BADRQC 56 /* Invalid request code */
+#define GF_ERROR_CODE_BADSLT 57 /* Invalid slot */
+#define GF_ERROR_CODE_BFONT 59 /* Bad font file format */
+#define GF_ERROR_CODE_NOSTR 60 /* Device not a stream */
+#define GF_ERROR_CODE_NODATA 61 /* No data available */
+#define GF_ERROR_CODE_TIME 62 /* Timer expired */
+#define GF_ERROR_CODE_NOSR 63 /* Out of streams resources */
+#define GF_ERROR_CODE_NONET 64 /* Machine is not on the network */
+#define GF_ERROR_CODE_NOPKG 65 /* Package not installed */
+#define GF_ERROR_CODE_REMOTE 66 /* Object is remote */
+#define GF_ERROR_CODE_NOLINK 67 /* Link has been severed */
+#define GF_ERROR_CODE_ADV 68 /* Advertise error */
+#define GF_ERROR_CODE_SRMNT 69 /* Srmount error */
+#define GF_ERROR_CODE_COMM 70 /* Communication error on send */
+#define GF_ERROR_CODE_PROTO 71 /* Protocol error */
+#define GF_ERROR_CODE_MULTIHOP 72 /* Multihop attempted */
+#define GF_ERROR_CODE_DOTDOT 73 /* RFS specific error */
+#define GF_ERROR_CODE_BADMSG 74 /* Not a data message */
+#define GF_ERROR_CODE_OVERFLOW 75 /* Value too large for defined data type */
+#define GF_ERROR_CODE_NOTUNIQ 76 /* Name not unique on network */
+#define GF_ERROR_CODE_BADFD 77 /* File descriptor in bad state */
+#define GF_ERROR_CODE_REMCHG 78 /* Remote address changed */
+#define GF_ERROR_CODE_LIBACC 79 /* Can not access a needed shared library */
+#define GF_ERROR_CODE_LIBBAD 80 /* Accessing a corrupted shared library */
+#define GF_ERROR_CODE_LIBSCN 81 /* .lib section in a.out corrupted */
+#define GF_ERROR_CODE_LIBMAX \
+ 82 /* Attempting to link in too many shared libraries */
+#define GF_ERROR_CODE_LIBEXEC 83 /* Cannot exec a shared library directly */
+#define GF_ERROR_CODE_ILSEQ 84 /* Illegal byte sequence */
+#define GF_ERROR_CODE_RESTART \
+ 85 /* Interrupted system call should be restarted */
+#define GF_ERROR_CODE_STRPIPE 86 /* Streams pipe error */
+#define GF_ERROR_CODE_USERS 87 /* Too many users */
+#define GF_ERROR_CODE_NOTSOCK 88 /* Socket operation on non-socket */
+#define GF_ERROR_CODE_DESTADDRREQ 89 /* Destination address required */
+#define GF_ERROR_CODE_MSGSIZE 90 /* Message too long */
+#define GF_ERROR_CODE_PROTOTYPE 91 /* Protocol wrong type for socket */
+#define GF_ERROR_CODE_NOPROTOOPT 92 /* Protocol not available */
+#define GF_ERROR_CODE_PROTONOSUPPORT 93 /* Protocol not supported */
+#define GF_ERROR_CODE_SOCKTNOSUPPORT 94 /* Socket type not supported */
+#define GF_ERROR_CODE_OPNOTSUPP \
+ 95 /* Operation not supported on transport endpoint */
+#define GF_ERROR_CODE_PFNOSUPPORT 96 /* Protocol family not supported */
+#define GF_ERROR_CODE_AFNOSUPPORT \
+ 97 /* Address family not supported by protocol */
+#define GF_ERROR_CODE_ADDRINUSE 98 /* Address already in use */
+#define GF_ERROR_CODE_ADDRNOTAVAIL 99 /* Cannot assign requested address */
+#define GF_ERROR_CODE_NETDOWN 100 /* Network is down */
+#define GF_ERROR_CODE_NETUNREACH 101 /* Network is unreachable */
+#define GF_ERROR_CODE_NETRESET \
+ 102 /* Network dropped connection because of reset */
+#define GF_ERROR_CODE_CONNABORTED 103 /* Software caused connection abort */
+#define GF_ERROR_CODE_CONNRESET 104 /* Connection reset by peer */
+#define GF_ERROR_CODE_NOBUFS 105 /* No buffer space available */
+#define GF_ERROR_CODE_ISCONN 106 /* Transport endpoint is already connected */
+#define GF_ERROR_CODE_NOTCONN 107 /* Transport endpoint is not connected */
+#define GF_ERROR_CODE_SHUTDOWN \
+ 108 /* Cannot send after transport endpoint shutdown */
+#define GF_ERROR_CODE_TOOMANYREFS 109 /* Too many references: cannot splice */
+#define GF_ERROR_CODE_TIMEDOUT 110 /* Connection timed out */
+#define GF_ERROR_CODE_CONNREFUSED 111 /* Connection refused */
+#define GF_ERROR_CODE_HOSTDOWN 112 /* Host is down */
+#define GF_ERROR_CODE_HOSTUNREACH 113 /* No route to host */
+#define GF_ERROR_CODE_ALREADY 114 /* Operation already in progress */
+#define GF_ERROR_CODE_INPROGRESS 115 /* Operation now in progress */
+#define GF_ERROR_CODE_ALREADY 114 /* Operation already in progress */
+#define GF_ERROR_CODE_INPROGRESS 115 /* Operation now in progress */
+#define GF_ERROR_CODE_STALE 116 /* Stale NFS file handle */
+#define GF_ERROR_CODE_UCLEAN 117 /* Structure needs cleaning */
+#define GF_ERROR_CODE_NOTNAM 118 /* Not a XENIX named type file */
+#define GF_ERROR_CODE_NAVAIL 119 /* No XENIX semaphores available */
+#define GF_ERROR_CODE_ISNAM 120 /* Is a named type file */
+#define GF_ERROR_CODE_REMOTEIO 121 /* Remote I/O error */
+#define GF_ERROR_CODE_DQUOT 122 /* Quota exceeded */
+#define GF_ERROR_CODE_NOMEDIUM 123 /* No medium found */
+#define GF_ERROR_CODE_MEDIUMTYPE 124 /* Wrong medium type */
+#define GF_ERROR_CODE_CANCELED 125 /* Operation Canceled */
+#define GF_ERROR_CODE_NOKEY 126 /* Required key not available */
+#define GF_ERROR_CODE_KEYEXPIRED 127 /* Key has expired */
+#define GF_ERROR_CODE_KEYREVOKED 128 /* Key has been revoked */
+#define GF_ERROR_CODE_KEYREJECTED 129 /* Key was rejected by service */
+
+/* for robust mutexes */
+#define GF_ERROR_CODE_OWNERDEAD 130 /* Owner died */
+#define GF_ERROR_CODE_NOTRECOVERABLE 131 /* State not recoverable */
+
+/* Should never be seen by user programs */
+#define GF_ERROR_CODE_RESTARTSYS 512
+#define GF_ERROR_CODE_RESTARTNOINTR 513
+#define GF_ERROR_CODE_RESTARTNOHAND 514 /* restart if no handler.. */
+#define GF_ERROR_CODE_NOIOCTLCMD 515 /* No ioctl command */
+#define GF_ERROR_CODE_RESTART_RESTARTBLOCK \
+ 516 /* restart by calling sys_restart_syscall */
+
+/* Defined for the NFSv3 protocol */
+#define GF_ERROR_CODE_BADHANDLE 521 /* Illegal NFS file handle */
+#define GF_ERROR_CODE_NOTSYNC 522 /* Update synchronization mismatch */
+#define GF_ERROR_CODE_BADCOOKIE 523 /* Cookie is stale */
+#define GF_ERROR_CODE_NOTSUPP 524 /* Operation is not supported */
+#define GF_ERROR_CODE_TOOSMALL 525 /* Buffer or request is too small */
+#define GF_ERROR_CODE_SERVERFAULT 526 /* An untranslatable error occurred */
+#define GF_ERROR_CODE_BADTYPE 527 /* Type not supported by server */
+#define GF_ERROR_CODE_JUKEBOX \
+ 528 /* Request initiated, but will not complete before timeout */
+#define GF_ERROR_CODE_IOCBQUEUED \
+ 529 /* iocb queued, will get completion event */
+#define GF_ERROR_CODE_IOCBRETRY 530 /* iocb queued, will trigger a retry */
+
+/* Darwin OS X */
+#define GF_ERROR_CODE_NOPOLICY 701
+#define GF_ERROR_CODE_BADMACHO 702
+#define GF_ERROR_CODE_PWROFF 703
+#define GF_ERROR_CODE_DEVERR 704
+#define GF_ERROR_CODE_BADARCH 705
+#define GF_ERROR_CODE_BADEXEC 706
+#define GF_ERROR_CODE_SHLIBVERS 707
+
+/* Solaris */
+/* ENOTACTIVE 73 / * Facility is not active */
+#define GF_ERROR_CODE_NOTACTIVE 801
+/* ELOCKUNMAPPED 72 / * locked lock was unmapped */
+#define GF_ERROR_CODE_LOCKUNMAPPED 802
+
+/* BSD system */
+#define GF_ERROR_CODE_PROCLIM 901 /* Too many processes */
+#define GF_ERROR_CODE_BADRPC 902 /* RPC struct is bad */
+#define GF_ERROR_CODE_RPCMISMATCH 903 /* RPC version wrong */
+#define GF_ERROR_CODE_PROGUNAVAIL 904 /* RPC prog. not avail */
+#define GF_ERROR_CODE_PROGMISMATCH 905 /* Program version wrong */
+#define GF_ERROR_CODE_PROCUNAVAIL 905 /* Bad procedure for program */
+#define GF_ERROR_CODE_FTYPE 906 /* Inappropriate file type or format */
+#define GF_ERROR_CODE_AUTH 907 /* Authentication error */
+#define GF_ERROR_CODE_NEEDAUTH 908 /* Need authenticator */
+#define GF_ERROR_CODE_DOOFUS 909 /* Programming error */
+
+#define GF_ERROR_CODE_NOATTR GF_ERROR_CODE_NODATA /* Attribute not found */
+
+/* Either one of enodata or enoattr will be there in system */
+#ifndef ENOATTR
+#define ENOATTR ENODATA
+#endif /* ENOATTR */
+
+#ifndef ENODATA
+#define ENODATA ENOATTR
+#endif /* ENODATA */
+
+#ifndef EBADFD
+#define EBADFD EBADRPC
+#endif /* EBADFD */
+
+#if !defined(ENODATA)
+/* This happens on FreeBSD. Value borrowed from Linux. */
+#define ENODATA 61
+#endif
+
+/* These functions are defined for all the OS flags, but content will
+ * be different for each OS flag.
+ */
+int32_t
+gf_errno_to_error(int32_t op_errno);
+int32_t
+gf_error_to_errno(int32_t error);
+
+#endif /* __COMPAT_ERRNO_H__ */
diff --git a/libglusterfs/src/compat-uuid.h b/libglusterfs/src/glusterfs/compat-uuid.h
index 4161b958508..6e7fdefbfab 100644
--- a/libglusterfs/src/compat-uuid.h
+++ b/libglusterfs/src/glusterfs/compat-uuid.h
@@ -11,54 +11,52 @@
#ifndef _GF_UUID_H
#define _GF_UUID_H
-#if defined(HAVE_LIBUUID) /* Linux like libuuid.so */
-
-#include <uuid.h>
+#include <uuid/uuid.h>
static inline void
-gf_uuid_clear (uuid_t uuid)
+gf_uuid_clear(uuid_t uuid)
{
- uuid_clear (uuid);
+ uuid_clear(uuid);
}
static inline int
-gf_uuid_compare (uuid_t u1, uuid_t u2)
+gf_uuid_compare(uuid_t u1, uuid_t u2)
{
- return uuid_compare (u1, u2);
+ return uuid_compare(u1, u2);
}
static inline void
-gf_uuid_copy (uuid_t dst, uuid_t src)
+gf_uuid_copy(uuid_t dst, const uuid_t src)
{
- uuid_copy (dst, src);
+ uuid_copy(dst, src);
}
static inline void
-gf_uuid_generate (uuid_t uuid)
+gf_uuid_generate(uuid_t uuid)
{
- uuid_generate (uuid);
+ uuid_generate(uuid);
}
static inline int
-gf_uuid_is_null (uuid_t uuid)
+gf_uuid_is_null(uuid_t uuid)
{
- return uuid_is_null (uuid);
+ return uuid_is_null(uuid);
}
static inline int
-gf_uuid_parse (const char *in, uuid_t uuid)
+gf_uuid_parse(const char *in, uuid_t uuid)
{
- return uuid_parse (in, uuid);
+ return uuid_parse(in, uuid);
}
static inline void
-gf_uuid_unparse (const uuid_t uuid, char *out)
+gf_uuid_unparse(const uuid_t uuid, char *out)
{
- uuid_unparse (uuid, out);
+ uuid_unparse(uuid, out);
}
/* TODO: add more uuid APIs, use constructs like this:
-#elif defined(__NetBSD__) * NetBSD libc *
+#if defined(__NetBSD__) * NetBSD libc *
#include <string.h>
@@ -67,12 +65,7 @@ gf_uuid_clear (uuid_t uuid)
{
memset (uuid, 0, sizeof (uuid_t));
}
-
+#endif
*/
-#else /* use bundled Linux like libuuid from contrib/uuid/ */
-
-#include "uuid.h"
-
-#endif /* HAVE_UUID */
#endif /* _GF_UUID_H */
diff --git a/libglusterfs/src/glusterfs/compat.h b/libglusterfs/src/glusterfs/compat.h
new file mode 100644
index 00000000000..bf00d903152
--- /dev/null
+++ b/libglusterfs/src/glusterfs/compat.h
@@ -0,0 +1,544 @@
+/*
+ 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__
+#define __COMPAT_H__
+
+#include <stdint.h>
+
+#ifndef LLONG_MAX
+#define LLONG_MAX __LONG_LONG_MAX__ /* compat with old gcc */
+#endif /* LLONG_MAX */
+
+#ifdef GF_LINUX_HOST_OS
+
+#define UNIX_PATH_MAX 108
+
+#include <sys/un.h>
+#include <linux/limits.h>
+#include <sys/xattr.h>
+#include <linux/xattr.h>
+#include <endian.h>
+#ifdef HAVE_LINUX_FALLOC_H
+#include <linux/falloc.h>
+#endif
+
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+
+#ifndef _PATH_UMOUNT
+#define _PATH_UMOUNT "/bin/umount"
+#endif
+#define GF_XATTR_NAME_MAX XATTR_NAME_MAX
+#endif /* GF_LINUX_HOST_OS */
+
+/*
+ * Define the fallocate flags in case we do not have the header. This also
+ * accounts for older systems that do not define FALLOC_FL_PUNCH_HOLE.
+ */
+
+#ifndef FALLOC_FL_KEEP_SIZE
+#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */
+#endif
+#ifndef FALLOC_FL_PUNCH_HOLE
+#define FALLOC_FL_PUNCH_HOLE 0x02 /* de-allocates range */
+#endif
+#ifndef FALLOC_FL_ZERO_RANGE
+#define FALLOC_FL_ZERO_RANGE 0x10 /* zeroes out range */
+#endif
+#ifndef FALLOC_FL_COLLAPSE_RANGE
+#define FALLOC_FL_COLLAPSE_RANGE 0x08 /* reduces the size */
+#endif
+#ifndef FALLOC_FL_INSERT_RANGE
+#define FALLOC_FL_INSERT_RANGE 0x20 /* expands the size */
+#endif
+
+#ifndef HAVE_LLISTXATTR
+
+/* This part is valid only in case of old glibc which doesn't support
+ * 'llistxattr()' system calls.
+ */
+
+#define lremovexattr(path, key) removexattr(path, key)
+#define llistxattr(path, key, size) listxattr(path, key, size)
+#define lgetxattr(path, key, value, size) getxattr(path, key, value, size)
+#define lsetxattr(path, key, value, size, flags) \
+ setxattr(path, key, value, size, flags)
+
+#endif /* HAVE_LLISTXATTR */
+
+#ifdef GF_DARWIN_HOST_OS
+#include <machine/endian.h>
+#include <libkern/OSByteOrder.h>
+#include <sys/xattr.h>
+
+#define htobe16(x) OSSwapHostToBigInt16(x)
+#define htole16(x) OSSwapHostToLittleInt16(x)
+#define be16toh(x) OSSwapBigToHostInt16(x)
+#define le16toh(x) OSSwapLittleToHostInt16(x)
+
+#define htobe32(x) OSSwapHostToBigInt32(x)
+#define htole32(x) OSSwapHostToLittleInt32(x)
+#define be32toh(x) OSSwapBigToHostInt32(x)
+#define le32toh(x) OSSwapLittleToHostInt32(x)
+
+#define htobe64(x) OSSwapHostToBigInt64(x)
+#define htole64(x) OSSwapHostToLittleInt64(x)
+#define be64toh(x) OSSwapBigToHostInt64(x)
+#define le64toh(x) OSSwapLittleToHostInt64(x)
+
+#endif
+
+#ifdef GF_BSD_HOST_OS
+/* In case of FreeBSD and NetBSD */
+
+#define UNIX_PATH_MAX 104
+#include <sys/types.h>
+
+#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>
+/*
+ * This is where things like off64_t are defined.
+ * So include it before declaring _OFF64_T_DECLARED.
+ * If the freebsd version has support for off64_t
+ * including stdio.h should be sufficient.
+ */
+#include <stdio.h>
+
+#ifndef _OFF64_T_DECLARED
+/*
+ * Including <stdio.h> (done above) should actually define
+ * _OFF64_T_DECLARED with off64_t data type being available
+ * for consumption. But, off64_t data type is not recognizable
+ * for FreeBSD versions less than 11. Hence, int64_t is typedefed
+ * to off64_t.
+ */
+#define _OFF64_T_DECLARED
+typedef int64_t off64_t;
+#endif /* _OFF64_T_DECLARED */
+
+#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
+#define sighandler_t sig_t
+#endif
+
+#ifdef __FreeBSD__
+#undef ino_t
+#define ino_t uint64_t
+#include <sys/types.h>
+#include <sys/extattr.h>
+/* Using NAME_MAX since EXTATTR_MAXNAMELEN is inside a preprocessor conditional
+ * for the kernel
+ */
+#define GF_XATTR_NAME_MAX NAME_MAX
+#endif /* __FreeBSD__ */
+
+#ifdef __NetBSD__
+#define GF_XATTR_NAME_MAX XATTR_NAME_MAX
+#endif
+
+#ifndef ino64_t
+#define ino64_t ino_t
+#endif
+
+#ifndef EUCLEAN
+#define EUCLEAN 0
+#endif
+
+#include <netinet/in.h>
+#ifndef s6_addr16
+#define s6_addr16 __u6_addr.__u6_addr16
+#endif
+#ifndef s6_addr32
+#define s6_addr32 __u6_addr.__u6_addr32
+#endif
+
+#ifndef LOGIN_NAME_MAX
+#define LOGIN_NAME_MAX 256
+#endif
+
+/* Posix dictates NAME_MAX to be used */
+#ifndef NAME_MAX
+#ifdef MAXNAMLEN
+#define NAME_MAX MAXNAMLEN
+#else
+#define NAME_MAX 255
+#endif
+#endif
+
+#define F_GETLK64 F_GETLK
+#define F_SETLK64 F_SETLK
+#define F_SETLKW64 F_SETLKW
+#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */
+#define FALLOC_FL_PUNCH_HOLE 0x02 /* de-allocates range */
+#define FALLOC_FL_ZERO_RANGE 0x10 /* zeroes out range */
+#define FALLOC_FL_INSERT_RANGE 0x20 /* Expands the size */
+#define FALLOC_FL_COLLAPSE_RANGE 0x08 /* Reduces the size */
+
+#ifndef _PATH_UMOUNT
+#define _PATH_UMOUNT "/sbin/umount"
+#endif
+
+void
+gf_extattr_list_reshape(char *list, ssize_t size);
+
+#endif /* GF_BSD_HOST_OS */
+
+#ifdef GF_DARWIN_HOST_OS
+#include <machine/endian.h>
+#include <libkern/OSByteOrder.h>
+
+#define htobe16(x) OSSwapHostToBigInt16(x)
+#define htole16(x) OSSwapHostToLittleInt16(x)
+#define be16toh(x) OSSwapBigToHostInt16(x)
+#define le16toh(x) OSSwapLittleToHostInt16(x)
+
+#define htobe32(x) OSSwapHostToBigInt32(x)
+#define htole32(x) OSSwapHostToLittleInt32(x)
+#define be32toh(x) OSSwapBigToHostInt32(x)
+#define le32toh(x) OSSwapLittleToHostInt32(x)
+
+#define htobe64(x) OSSwapHostToBigInt64(x)
+#define htole64(x) OSSwapHostToLittleInt64(x)
+#define be64toh(x) OSSwapBigToHostInt64(x)
+#define le64toh(x) OSSwapLittleToHostInt64(x)
+
+#define UNIX_PATH_MAX 104
+/* OSX Yosemite now has this defined */
+#ifndef AT_SYMLINK_NOFOLLOW
+#define AT_SYMLINK_NOFOLLOW 0x100
+#endif
+#include <sys/types.h>
+
+#include <sys/un.h>
+#include <sys/xattr.h>
+#include <limits.h>
+
+#include <libgen.h>
+
+#if __DARWIN_64_BIT_INO_T == 0
+#error '64 bit ino_t is must for GlusterFS to work, Compile with "CFLAGS=-D__DARWIN_64_BIT_INO_T"'
+#endif /* __DARWIN_64_BIT_INO_T */
+
+#if __DARWIN_64_BIT_INO_T == 0
+#error '64 bit ino_t is must for GlusterFS to work, Compile with "CFLAGS=-D__DARWIN_64_BIT_INO_T"'
+#endif /* __DARWIN_64_BIT_INO_T */
+
+#ifndef sighandler_t
+#define sighandler_t sig_t
+#endif
+
+#ifndef EUCLEAN
+#define EUCLEAN 0
+#endif
+
+#include <netinet/in.h>
+#ifndef s6_addr16
+#define s6_addr16 __u6_addr.__u6_addr16
+#endif
+#ifndef s6_addr32
+#define s6_addr32 __u6_addr.__u6_addr32
+#endif
+
+/* Posix dictates NAME_MAX to be used */
+#ifndef NAME_MAX
+#ifdef MAXNAMLEN
+#define NAME_MAX MAXNAMLEN
+#else
+#define NAME_MAX 255
+#endif
+#endif
+
+#define F_GETLK64 F_GETLK
+#define F_SETLK64 F_SETLK
+#define F_SETLKW64 F_SETLKW
+
+#ifndef FTW_CONTINUE
+#define FTW_CONTINUE 0
+#endif
+
+#ifndef _PATH_UMOUNT
+#define _PATH_UMOUNT "/sbin/umount"
+#endif
+#endif /* GF_DARWIN_HOST_OS */
+
+#ifdef GF_SOLARIS_HOST_OS
+
+#define UNIX_PATH_MAX 108
+#define EUCLEAN 117
+
+#include <sys/un.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/fcntl.h>
+#include <libgen.h>
+#include <sys/mkdev.h>
+
+#ifndef lchmod
+#define lchmod chmod
+#endif
+
+#define lgetxattr(path, key, value, size) \
+ solaris_getxattr(path, key, value, size)
+enum {
+ ATTR_CREATE = 1,
+#define XATTR_CREATE ATTR_CREATE
+ ATTR_REPLACE = 2
+#define XATTR_REPLACE ATTR_REPLACE
+};
+
+/* This patch is not present in Solaris 10 and before */
+#ifndef dirfd
+#define dirfd(dirp) ((dirp)->dd_fd)
+#endif
+
+/* Posix dictates NAME_MAX to be used */
+#ifndef NAME_MAX
+#ifdef MAXNAMLEN
+#define NAME_MAX MAXNAMLEN
+#else
+#define NAME_MAX 255
+#endif
+#endif
+
+#include <netinet/in.h>
+#ifndef s6_addr16
+#define S6_ADDR16(x) ((uint16_t *)((char *)&(x).s6_addr))
+#endif
+#ifndef s6_addr32
+#define s6_addr32 _S6_un._S6_u32
+#endif
+
+#define lutimes(filename, times) utimes(filename, times)
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+enum {
+ DT_UNKNOWN = 0,
+#define DT_UNKNOWN DT_UNKNOWN
+ DT_FIFO = 1,
+#define DT_FIFO DT_FIFO
+ DT_CHR = 2,
+#define DT_CHR DT_CHR
+ DT_DIR = 4,
+#define DT_DIR DT_DIR
+ DT_BLK = 6,
+#define DT_BLK DT_BLK
+ DT_REG = 8,
+#define DT_REG DT_REG
+ DT_LNK = 10,
+#define DT_LNK DT_LNK
+ DT_SOCK = 12,
+#define DT_SOCK DT_SOCK
+ DT_WHT = 14
+#define DT_WHT DT_WHT
+};
+
+#ifndef _PATH_MOUNTED
+#define _PATH_MOUNTED "/etc/mtab"
+#endif
+#ifndef _PATH_UMOUNT
+#define _PATH_UMOUNT "/sbin/umount"
+#endif
+
+#ifndef O_ASYNC
+#ifdef FASYNC
+#define O_ASYNC FASYNC
+#else
+#define O_ASYNC 0
+#endif
+#endif
+
+#ifndef FTW_CONTINUE
+#define FTW_CONTINUE 0
+#endif
+
+int
+asprintf(char **string_ptr, const char *format, ...);
+
+int
+vasprintf(char **result, const char *format, va_list args);
+char *
+strsep(char **str, const char *delims);
+int
+solaris_listxattr(const char *path, char *list, size_t size);
+int
+solaris_removexattr(const char *path, const char *key);
+int
+solaris_getxattr(const char *path, const char *key, char *value, size_t size);
+int
+solaris_setxattr(const char *path, const char *key, const char *value,
+ size_t size, int flags);
+int
+solaris_fgetxattr(int fd, const char *key, char *value, size_t size);
+int
+solaris_fsetxattr(int fd, const char *key, const char *value, size_t size,
+ int flags);
+int
+solaris_flistxattr(int fd, char *list, size_t size);
+
+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);
+
+#endif /* GF_SOLARIS_HOST_OS */
+
+#ifndef HAVE_ARGP
+#include "argp.h"
+#else
+#include <argp.h>
+#endif /* HAVE_ARGP */
+
+#ifndef HAVE_STRNLEN
+size_t
+strnlen(const char *string, size_t maxlen);
+#endif /* STRNLEN */
+
+#ifndef strdupa
+#define strdupa(s) \
+ (__extension__({ \
+ __const char *__old = (s); \
+ size_t __len = strlen(__old) + 1; \
+ char *__new = (char *)__builtin_alloca(__len); \
+ (char *)memcpy(__new, __old, __len); \
+ }))
+#endif
+
+#define GF_DIR_ALIGN(x) (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1))
+
+#include <sys/types.h>
+#include <dirent.h>
+
+static inline int32_t
+dirent_size(struct dirent *entry)
+{
+ int32_t size = -1;
+
+#ifdef GF_BSD_HOST_OS
+ size = GF_DIR_ALIGN(24 /* FIX MEEEE!!! */ + entry->d_namlen);
+#endif
+#ifdef GF_DARWIN_HOST_OS
+ size = GF_DIR_ALIGN(24 /* FIX MEEEE!!! */ + entry->d_namlen);
+#endif
+#ifdef GF_LINUX_HOST_OS
+ size = GF_DIR_ALIGN(24 /* FIX MEEEE!!! */ + entry->d_reclen);
+#endif
+#ifdef GF_SOLARIS_HOST_OS
+ size = GF_DIR_ALIGN(24 /* FIX MEEEE!!! */ + entry->d_reclen);
+#endif
+ 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 */
+
+#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+/* Linux, Solaris, Cygwin */
+#define ST_ATIM_SEC(stbuf) ((stbuf)->st_atim.tv_sec)
+#define ST_CTIM_SEC(stbuf) ((stbuf)->st_ctim.tv_sec)
+#define ST_MTIM_SEC(stbuf) ((stbuf)->st_mtim.tv_sec)
+#define ST_ATIM_SEC_SET(stbuf, val) ((stbuf)->st_atim.tv_sec = (val))
+#define ST_MTIM_SEC_SET(stbuf, val) ((stbuf)->st_mtim.tv_sec = (val))
+#define ST_CTIM_SEC_SET(stbuf, val) ((stbuf)->st_ctim.tv_sec = (val))
+#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec)
+#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec)
+#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.tv_nsec)
+#define ST_ATIM_NSEC_SET(stbuf, val) ((stbuf)->st_atim.tv_nsec = (val))
+#define ST_MTIM_NSEC_SET(stbuf, val) ((stbuf)->st_mtim.tv_nsec = (val))
+#define ST_CTIM_NSEC_SET(stbuf, val) ((stbuf)->st_ctim.tv_nsec = (val))
+#elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC)
+/* FreeBSD, NetBSD */
+#define ST_ATIM_SEC(stbuf) ((stbuf)->st_atimespec.tv_sec)
+#define ST_CTIM_SEC(stbuf) ((stbuf)->st_ctimespec.tv_sec)
+#define ST_MTIM_SEC(stbuf) ((stbuf)->st_mtimespec.tv_sec)
+#define ST_ATIM_SEC_SET(stbuf, val) ((stbuf)->st_atimespec.tv_sec = (val))
+#define ST_MTIM_SEC_SET(stbuf, val) ((stbuf)->st_mtimespec.tv_sec = (val))
+#define ST_CTIM_SEC_SET(stbuf, val) ((stbuf)->st_ctimespec.tv_sec = (val))
+#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec)
+#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec)
+#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.tv_nsec)
+#define ST_ATIM_NSEC_SET(stbuf, val) ((stbuf)->st_atimespec.tv_nsec = (val))
+#define ST_MTIM_NSEC_SET(stbuf, val) ((stbuf)->st_mtimespec.tv_nsec = (val))
+#define ST_CTIM_NSEC_SET(stbuf, val) ((stbuf)->st_ctimespec.tv_nsec = (val))
+#else
+#define ST_ATIM_NSEC(stbuf) (0)
+#define ST_CTIM_NSEC(stbuf) (0)
+#define ST_MTIM_NSEC(stbuf) (0)
+#define ST_ATIM_NSEC_SET(stbuf, val) \
+ do { \
+ } while (0);
+#define ST_MTIM_NSEC_SET(stbuf, val) \
+ do { \
+ } while (0);
+#define ST_CTIM_NSEC_SET(stbuf, val) \
+ do { \
+ } while (0);
+#endif
+
+#ifdef GF_BSD_HOST_OS
+#define CLOCK_REALTIME_COARSE CLOCK_REALTIME
+#endif
+
+#if defined(__GNUC__) && !defined(RELAX_POISONING)
+/* Use run API, see run.h */
+#include <stdlib.h> /* system(), mkostemp() */
+#include <stdio.h> /* popen() */
+#ifdef GF_LINUX_HOST_OS
+#include <sys/sysmacros.h>
+#endif
+#pragma GCC poison system mkostemp popen
+#endif
+
+int
+gf_umount_lazy(char *xlname, char *path, int rmdir);
+
+#ifndef GF_XATTR_NAME_MAX
+#error 'Please define GF_XATTR_NAME_MAX for your OS distribution.'
+#endif
+
+#endif /* __COMPAT_H__ */
diff --git a/libglusterfs/src/daemon.h b/libglusterfs/src/glusterfs/daemon.h
index 95e134b78b0..48850800b5e 100644
--- a/libglusterfs/src/daemon.h
+++ b/libglusterfs/src/glusterfs/daemon.h
@@ -13,6 +13,8 @@
#define DEVNULLPATH "/dev/null"
-int os_daemon_return(int nochdir, int noclose);
-int os_daemon(int nochdir, int noclose);
+int
+os_daemon_return(int nochdir, int noclose);
+int
+os_daemon(int nochdir, int noclose);
#endif /*_DAEMON_H */
diff --git a/libglusterfs/src/glusterfs/default-args.h b/libglusterfs/src/glusterfs/default-args.h
new file mode 100644
index 00000000000..ca7526fcab6
--- /dev/null
+++ b/libglusterfs/src/glusterfs/default-args.h
@@ -0,0 +1,455 @@
+/*
+ Copyright (c) 2008-2015 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:
+ This file contains definition of default fops and mops functions.
+*/
+
+#ifndef _DEFAULT_ARGS_H
+#define _DEFAULT_ARGS_H
+
+#include "glusterfs/xlator.h"
+
+int
+args_lookup_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xdata, struct iatt *postparent);
+
+int
+args_stat_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *buf, dict_t *xdata);
+
+int
+args_fstat_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *buf, dict_t *xdata);
+
+int
+args_truncate_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata);
+
+int
+args_ftruncate_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata);
+
+int
+args_access_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_readlink_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, const char *path, struct iatt *stbuf,
+ dict_t *xdata);
+
+int
+args_mknod_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+
+int
+args_mkdir_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+
+int
+args_unlink_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+
+int
+args_rmdir_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata);
+
+int
+args_symlink_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, inode_t *inode, struct iatt *buf,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata);
+
+int
+args_rename_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent,
+ dict_t *xdata);
+
+int
+args_link_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+
+int
+args_create_cbk_store(default_args_cbk_t *args, 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);
+
+int
+args_open_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ fd_t *fd, dict_t *xdata);
+
+int
+args_readv_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iovec *vector, int32_t count, struct iatt *stbuf,
+ struct iobref *iobref, dict_t *xdata);
+
+int
+args_writev_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata);
+
+int
+args_put_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+
+int
+args_flush_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata);
+
+int
+args_fsync_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata);
+
+int
+args_opendir_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, fd_t *fd, dict_t *xdata);
+
+int
+args_fsyncdir_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_statfs_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct statvfs *buf, dict_t *xdata);
+
+int
+args_setxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_getxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *dict, dict_t *xdata);
+
+int
+args_fsetxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_fgetxattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *dict, dict_t *xdata);
+
+int
+args_removexattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_fremovexattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_lk_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct gf_flock *lock, dict_t *xdata);
+
+int
+args_inodelk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_finodelk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_entrylk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_fentrylk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xdata);
+
+int
+args_readdirp_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, gf_dirent_t *entries, dict_t *xdata);
+
+int
+args_readdir_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, gf_dirent_t *entries, dict_t *xdata);
+
+int
+args_rchecksum_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, uint32_t weak_checksum,
+ uint8_t *strong_checksum, dict_t *xdata);
+
+int
+args_xattrop_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xattr, dict_t *xdata);
+
+int
+args_fxattrop_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, dict_t *xattr, dict_t *xdata);
+
+int
+args_setattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata);
+
+int
+args_fsetattr_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata);
+
+int
+args_fallocate_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata);
+
+int
+args_discard_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata);
+
+int
+args_zerofill_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost, dict_t *xdata);
+
+int
+args_ipc_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata);
+
+int
+args_seek_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ off_t offset, dict_t *xdata);
+
+void
+args_lease_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,
+ struct gf_lease *lease, dict_t *xdata);
+
+int
+args_copy_file_range_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, struct iatt *stbuf,
+ struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, dict_t *xdata);
+
+void
+args_cbk_wipe(default_args_cbk_t *args_cbk);
+
+void
+args_wipe(default_args_t *args);
+
+int
+args_lookup_store(default_args_t *args, loc_t *loc, dict_t *xdata);
+
+int
+args_stat_store(default_args_t *args, loc_t *loc, dict_t *xdata);
+
+int
+args_fstat_store(default_args_t *args, fd_t *fd, dict_t *xdata);
+
+int
+args_truncate_store(default_args_t *args, loc_t *loc, off_t off, dict_t *xdata);
+int
+args_ftruncate_store(default_args_t *args, fd_t *fd, off_t off, dict_t *xdata);
+
+int
+args_access_store(default_args_t *args, loc_t *loc, int32_t mask,
+ dict_t *xdata);
+
+int
+args_readlink_store(default_args_t *args, loc_t *loc, size_t size,
+ dict_t *xdata);
+
+int
+args_mknod_store(default_args_t *args, loc_t *loc, mode_t mode, dev_t rdev,
+ mode_t umask, dict_t *xdata);
+
+int
+args_mkdir_store(default_args_t *args, loc_t *loc, mode_t mode, mode_t umask,
+ dict_t *xdata);
+
+int
+args_unlink_store(default_args_t *args, loc_t *loc, int xflag, dict_t *xdata);
+
+int
+args_rmdir_store(default_args_t *args, loc_t *loc, int flags, dict_t *xdata);
+
+int
+args_symlink_store(default_args_t *args, const char *linkname, loc_t *loc,
+ mode_t umask, dict_t *xdata);
+
+int
+args_rename_store(default_args_t *args, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata);
+
+int
+args_link_store(default_args_t *args, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata);
+
+int
+args_create_store(default_args_t *args, loc_t *loc, int32_t flags, mode_t mode,
+ mode_t umask, fd_t *fd, dict_t *xdata);
+
+int
+args_open_store(default_args_t *args, loc_t *loc, int32_t flags, fd_t *fd,
+ dict_t *xdata);
+
+int
+args_readv_store(default_args_t *args, fd_t *fd, size_t size, off_t off,
+ uint32_t flags, dict_t *xdata);
+
+int
+args_writev_store(default_args_t *args, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t off, uint32_t flags,
+ struct iobref *iobref, dict_t *xdata);
+
+int
+args_put_store(default_args_t *args, loc_t *loc, mode_t mode, mode_t umask,
+ uint32_t flags, struct iovec *vector, int32_t count, off_t off,
+ struct iobref *iobref, dict_t *xattr, dict_t *xdata);
+
+int
+args_flush_store(default_args_t *args, fd_t *fd, dict_t *xdata);
+
+int
+args_fsync_store(default_args_t *args, fd_t *fd, int32_t datasync,
+ dict_t *xdata);
+
+int
+args_opendir_store(default_args_t *args, loc_t *loc, fd_t *fd, dict_t *xdata);
+
+int
+args_fsyncdir_store(default_args_t *args, fd_t *fd, int32_t datasync,
+ dict_t *xdata);
+
+int
+args_statfs_store(default_args_t *args, loc_t *loc, dict_t *xdata);
+
+int
+args_setxattr_store(default_args_t *args, loc_t *loc, dict_t *dict,
+ int32_t flags, dict_t *xdata);
+
+int
+args_getxattr_store(default_args_t *args, loc_t *loc, const char *name,
+ dict_t *xdata);
+
+int
+args_fsetxattr_store(default_args_t *args, fd_t *fd, dict_t *dict,
+ int32_t flags, dict_t *xdata);
+
+int
+args_fgetxattr_store(default_args_t *args, fd_t *fd, const char *name,
+ dict_t *xdata);
+
+int
+args_removexattr_store(default_args_t *args, loc_t *loc, const char *name,
+ dict_t *xdata);
+
+int
+args_fremovexattr_store(default_args_t *args, fd_t *fd, const char *name,
+ dict_t *xdata);
+
+int
+args_lk_store(default_args_t *args, fd_t *fd, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata);
+
+int
+args_inodelk_store(default_args_t *args, const char *volume, loc_t *loc,
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata);
+
+int
+args_finodelk_store(default_args_t *args, const char *volume, fd_t *fd,
+ int32_t cmd, struct gf_flock *lock, dict_t *xdata);
+
+int
+args_entrylk_store(default_args_t *args, const char *volume, loc_t *loc,
+ const char *name, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata);
+
+int
+args_fentrylk_store(default_args_t *args, const char *volume, fd_t *fd,
+ const char *name, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata);
+int
+args_readdirp_store(default_args_t *args, fd_t *fd, size_t size, off_t off,
+ dict_t *xdata);
+
+int
+args_readdir_store(default_args_t *args, fd_t *fd, size_t size, off_t off,
+ dict_t *xdata);
+
+int
+args_rchecksum_store(default_args_t *args, fd_t *fd, off_t offset, int32_t len,
+ dict_t *xdata);
+
+int
+args_xattrop_store(default_args_t *args, loc_t *loc, gf_xattrop_flags_t optype,
+ dict_t *xattr, dict_t *xdata);
+
+int
+args_fxattrop_store(default_args_t *args, fd_t *fd, gf_xattrop_flags_t optype,
+ dict_t *xattr, dict_t *xdata);
+
+int
+args_setattr_store(default_args_t *args, loc_t *loc, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata);
+
+int
+args_fsetattr_store(default_args_t *args, fd_t *fd, struct iatt *stbuf,
+ int32_t valid, dict_t *xdata);
+
+int
+args_fallocate_store(default_args_t *args, fd_t *fd, int32_t mode, off_t offset,
+ size_t len, dict_t *xdata);
+
+int
+args_discard_store(default_args_t *args, fd_t *fd, off_t offset, size_t len,
+ dict_t *xdata);
+
+int
+args_zerofill_store(default_args_t *args, fd_t *fd, off_t offset, off_t len,
+ dict_t *xdata);
+
+int
+args_ipc_store(default_args_t *args, int32_t op, dict_t *xdata);
+
+int
+args_seek_store(default_args_t *args, fd_t *fd, off_t offset,
+ gf_seek_what_t what, dict_t *xdata);
+
+void
+args_lease_store(default_args_t *args, loc_t *loc, struct gf_lease *lease,
+ dict_t *xdata);
+
+int
+args_getactivelk_cbk_store(default_args_cbk_t *args, int32_t op_ret,
+ int32_t op_errno, lock_migration_info_t *locklist,
+ dict_t *xdata);
+
+int
+args_setactivelk_store(default_args_t *args, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata);
+
+int
+args_icreate_store(default_args_t *args, loc_t *loc, mode_t mode,
+ dict_t *xdata);
+
+int
+args_namelink_store(default_args_t *args, loc_t *loc, dict_t *xdata);
+
+int
+args_copy_file_range_store(default_args_t *args, fd_t *fd_in, off64_t off_in,
+ fd_t *fd_out, off_t off64_out, size_t len,
+ uint32_t flags, dict_t *xdata);
+
+void
+args_cbk_init(default_args_cbk_t *args_cbk);
+#endif /* _DEFAULT_ARGS_H */
diff --git a/libglusterfs/src/glusterfs/defaults.h b/libglusterfs/src/glusterfs/defaults.h
new file mode 100644
index 00000000000..5a818eeb91a
--- /dev/null
+++ b/libglusterfs/src/glusterfs/defaults.h
@@ -0,0 +1,1275 @@
+/*
+ Copyright (c) 2008-2015 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:
+ This file contains definition of default fops and mops functions.
+*/
+
+#ifndef _DEFAULTS_H
+#define _DEFAULTS_H
+
+#include "glusterfs/xlator.h"
+
+typedef struct {
+ int op_ret;
+ int op_errno;
+ inode_t *inode;
+ struct iatt stat;
+ struct iatt prestat;
+ struct iatt poststat;
+ struct iatt preparent; /* @preoldparent in rename_cbk */
+ struct iatt postparent; /* @postoldparent in rename_cbk */
+ struct iatt preparent2; /* @prenewparent in rename_cbk */
+ struct iatt postparent2; /* @postnewparent in rename_cbk */
+ const char *buf;
+ struct iovec *vector;
+ int count;
+ struct iobref *iobref;
+ fd_t *fd;
+ struct statvfs statvfs;
+ dict_t *xattr;
+ struct gf_flock lock;
+ uint32_t weak_checksum;
+ uint8_t *strong_checksum;
+ dict_t *xdata;
+ gf_dirent_t entries;
+ off_t offset; /* seek hole/data */
+ int valid; /* If the response is valid or not. For call-stub it is
+ always valid irrespective of this */
+ struct gf_lease lease;
+ lock_migration_info_t locklist;
+} default_args_cbk_t;
+
+typedef struct {
+ loc_t loc; /* @old in rename(), link() */
+ loc_t loc2; /* @new in rename(), link() */
+ fd_t *fd; /* for all the fd based ops */
+ fd_t *fd_dst; /* Only for copy_file_range destination */
+ off_t offset;
+ /*
+ * According to the man page of copy_file_range,
+ * the offsets for source and destination file
+ * are of type loff_t. But the type loff_t is
+ * linux specific and is actual a typedef of
+ * off64_t.
+ */
+ off64_t off_in; /* For copy_file_range source fd */
+ off64_t off_out; /* For copy_file_range destination fd only */
+ int mask;
+ size_t size;
+ mode_t mode;
+ dev_t rdev;
+ mode_t umask;
+ int xflag;
+ int flags;
+ const char *linkname;
+ struct iovec *vector;
+ int count;
+ struct iobref *iobref;
+ int datasync;
+ dict_t *xattr;
+ const char *name;
+ int cmd;
+ struct gf_flock lock;
+ const char *volume;
+ entrylk_cmd entrylkcmd;
+ entrylk_type entrylktype;
+ gf_xattrop_flags_t optype;
+ int valid;
+ struct iatt stat;
+ gf_seek_what_t what;
+ dict_t *xdata;
+ struct gf_lease lease;
+ lock_migration_info_t locklist;
+} default_args_t;
+
+typedef struct {
+ int fop_enum;
+ unsigned int fop_length;
+ int *enum_list;
+ default_args_t *req_list;
+ dict_t *xdata;
+} compound_args_t;
+
+typedef struct {
+ int fop_enum;
+ unsigned int fop_length;
+ int *enum_list;
+ default_args_cbk_t *rsp_list;
+ dict_t *xdata;
+} compound_args_cbk_t;
+
+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);
+
+extern struct xlator_fops *default_fops;
+
+/* Management Operations */
+
+int32_t
+default_getspec(call_frame_t *frame, xlator_t *this, const char *key,
+ int32_t flag);
+
+int32_t
+default_rchecksum(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ int32_t len, dict_t *xdata);
+
+/* FileSystem operations */
+int32_t
+default_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata);
+
+int32_t
+default_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata);
+
+int32_t
+default_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata);
+
+int32_t
+default_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
+ dict_t *xdata);
+
+int32_t
+default_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ dict_t *xdata);
+
+int32_t
+default_access(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
+ dict_t *xdata);
+
+int32_t
+default_readlink(call_frame_t *frame, xlator_t *this, loc_t *loc, 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, mode_t umask, dict_t *xdata);
+
+int32_t
+default_mkdir(call_frame_t *frame, xlator_t *this, 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, int xflag,
+ dict_t *xdata);
+
+int32_t
+default_rmdir(call_frame_t *frame, xlator_t *this, 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, mode_t umask, dict_t *xdata);
+
+int32_t
+default_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata);
+
+int32_t
+default_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, 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, 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, dict_t *xdata);
+
+int32_t
+default_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset, uint32_t flags, dict_t *xdata);
+
+int32_t
+default_writev(call_frame_t *frame, 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(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata);
+
+int32_t
+default_fsync(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
+ dict_t *xdata);
+
+int32_t
+default_opendir(call_frame_t *frame, xlator_t *this, 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, dict_t *xdata);
+
+int32_t
+default_statfs(call_frame_t *frame, xlator_t *this, 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, dict_t *xdata);
+
+int32_t
+default_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ 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, dict_t *xdata);
+
+int32_t
+default_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata);
+
+int32_t
+default_removexattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ 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, 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, 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, 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, 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, dict_t *xdata);
+
+int32_t
+default_readdir(call_frame_t *frame, xlator_t *this, fd_t *fd, 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, 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 *xdata);
+
+int32_t
+default_fxattrop(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, 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, dict_t *xdata);
+
+int32_t
+default_fsetattr(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata);
+
+int32_t
+default_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t keep_size, off_t offset, size_t len, dict_t *xdata);
+
+int32_t
+default_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ size_t len, dict_t *xdata);
+
+int32_t
+default_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ off_t len, dict_t *xdata);
+
+int32_t
+default_ipc(call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata);
+
+int32_t
+default_seek(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ gf_seek_what_t what, dict_t *xdata);
+
+int32_t
+default_lease(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct gf_lease *lease, dict_t *xdata);
+
+int32_t
+default_getactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata);
+
+int32_t
+default_setactivelk(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata);
+
+int32_t
+default_put(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,
+ off_t off, struct iobref *iobref, dict_t *xattr, dict_t *xdata);
+
+int32_t
+default_icreate(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dict_t *xdata);
+
+int32_t
+default_namelink(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata);
+
+int32_t
+default_copy_file_range(call_frame_t *frame, xlator_t *this, fd_t *fd_in,
+ off64_t off_in, fd_t *fd_out, off64_t off_out,
+ size_t len, uint32_t flags, dict_t *xdata);
+
+/* Resume */
+int32_t
+default_getspec_resume(call_frame_t *frame, xlator_t *this, const char *key,
+ int32_t flag);
+
+int32_t
+default_rchecksum_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, 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 *xdata);
+
+int32_t
+default_stat_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata);
+
+int32_t
+default_fstat_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *xdata);
+
+int32_t
+default_truncate_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ off_t offset, dict_t *xdata);
+
+int32_t
+default_ftruncate_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, dict_t *xdata);
+
+int32_t
+default_access_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t mask, dict_t *xdata);
+
+int32_t
+default_readlink_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ 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, mode_t umask, dict_t *xdata);
+
+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,
+ int xflag, dict_t *xdata);
+
+int32_t
+default_rmdir_resume(call_frame_t *frame, xlator_t *this, 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, mode_t umask,
+ dict_t *xdata);
+
+int32_t
+default_rename_resume(call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc, dict_t *xdata);
+
+int32_t
+default_link_resume(call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ 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, 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, dict_t *xdata);
+
+int32_t
+default_readv_resume(call_frame_t *frame, 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,
+ uint32_t flags, struct iobref *iobref, dict_t *xdata);
+
+int32_t
+default_flush_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *xdata);
+
+int32_t
+default_fsync_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t datasync, dict_t *xdata);
+
+int32_t
+default_opendir_resume(call_frame_t *frame, xlator_t *this, 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, dict_t *xdata);
+
+int32_t
+default_statfs_resume(call_frame_t *frame, xlator_t *this, 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, dict_t *xdata);
+
+int32_t
+default_getxattr_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ 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, dict_t *xdata);
+
+int32_t
+default_fgetxattr_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata);
+
+int32_t
+default_removexattr_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ 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, 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,
+ 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,
+ 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, 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, dict_t *xdata);
+
+int32_t
+default_readdir_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ 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, 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 *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 *xdata);
+int32_t
+default_rchecksum_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, 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, dict_t *xdata);
+
+int32_t
+default_fsetattr_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid, dict_t *xdata);
+
+int32_t
+default_fallocate_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t keep_size, off_t offset, size_t len,
+ dict_t *xdata);
+
+int32_t
+default_discard_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata);
+
+int32_t
+default_zerofill_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, off_t len, dict_t *xdata);
+
+int32_t
+default_ipc_resume(call_frame_t *frame, xlator_t *this, int32_t op,
+ dict_t *xdata);
+
+int32_t
+default_seek_resume(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ gf_seek_what_t what, dict_t *xdata);
+
+int32_t
+default_lease_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct gf_lease *lease, dict_t *xdata);
+
+int32_t
+default_getactivelk_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata);
+
+int32_t
+default_setactivelk_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata);
+
+int32_t
+default_put_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, uint32_t flags, struct iovec *vector,
+ int32_t count, off_t off, struct iobref *iobref,
+ dict_t *xattr, dict_t *xdata);
+
+int32_t
+default_copy_file_range_resume(call_frame_t *frame, xlator_t *this, fd_t *fd_in,
+ off_t off64_in, fd_t *fd_out, off64_t off_out,
+ size_t len, uint32_t flags, dict_t *xdata);
+
+/* _cbk_resume */
+
+int32_t
+default_lookup_cbk_resume(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 *xdata,
+ struct iatt *postparent);
+
+int32_t
+default_stat_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata);
+
+int32_t
+default_truncate_cbk_resume(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);
+
+int32_t
+default_ftruncate_cbk_resume(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);
+
+int32_t
+default_access_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_readlink_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, const char *path,
+ struct iatt *buf, dict_t *xdata);
+
+int32_t
+default_mknod_cbk_resume(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);
+
+int32_t
+default_mkdir_cbk_resume(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);
+
+int32_t
+default_unlink_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata);
+
+int32_t
+default_rmdir_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *preparent, struct iatt *postparent,
+ dict_t *xdata);
+
+int32_t
+default_symlink_cbk_resume(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);
+
+int32_t
+default_rename_cbk_resume(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,
+ dict_t *xdata);
+
+int32_t
+default_link_cbk_resume(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);
+
+int32_t
+default_create_cbk_resume(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);
+
+int32_t
+default_open_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd,
+ dict_t *xdata);
+
+int32_t
+default_readv_cbk_resume(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);
+
+int32_t
+default_writev_cbk_resume(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);
+
+int32_t
+default_flush_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_fsync_cbk_resume(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);
+
+int32_t
+default_fstat_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ dict_t *xdata);
+
+int32_t
+default_opendir_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd,
+ dict_t *xdata);
+
+int32_t
+default_fsyncdir_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_statfs_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf,
+ dict_t *xdata);
+
+int32_t
+default_setxattr_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_fsetxattr_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_fgetxattr_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata);
+
+int32_t
+default_getxattr_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata);
+
+int32_t
+default_xattrop_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata);
+
+int32_t
+default_fxattrop_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata);
+
+int32_t
+default_removexattr_cbk_resume(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata);
+
+int32_t
+default_fremovexattr_cbk_resume(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_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
+ dict_t *xdata);
+
+int32_t
+default_inodelk_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_finodelk_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_entrylk_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_fentrylk_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_rchecksum_cbk_resume(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,
+ dict_t *xdata);
+
+int32_t
+default_readdir_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ gf_dirent_t *entries, dict_t *xdata);
+
+int32_t
+default_readdirp_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ gf_dirent_t *entries, dict_t *xdata);
+
+int32_t
+default_setattr_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost,
+ dict_t *xdata);
+
+int32_t
+default_fsetattr_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost,
+ dict_t *xdata);
+
+int32_t
+default_fallocate_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
+
+int32_t
+default_discard_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
+
+int32_t
+default_zerofill_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
+int32_t
+default_ipc_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_seek_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, off_t offset,
+ dict_t *xdata);
+
+int32_t
+default_getspec_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, char *spec_data);
+
+int32_t
+default_lease_cbk_resume(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct gf_lease *lease, dict_t *xdata);
+
+int32_t
+default_getactivelk_cbk_resume(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ lock_migration_info_t *locklist, dict_t *xdata);
+
+int32_t
+default_setactivelk_cbk_resume(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *xdata);
+
+int32_t
+default_put_cbk_resume(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);
+
+int32_t
+default_icreate_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, dict_t *xdata);
+
+int32_t
+default_namelink_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata);
+
+int32_t
+default_copy_file_range_cbk_resume(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iatt *stbuf,
+ struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, 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 *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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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,
+ 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, 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, 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,
+ 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,
+ 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,
+ 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,
+ 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, 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,
+ 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, 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, 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, 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, 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, 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,
+ 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,
+ 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, 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, dict_t *xdata);
+
+int32_t
+default_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
+
+int32_t
+default_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
+
+int32_t
+default_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
+
+int32_t
+default_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, off_t offset, dict_t *xdata);
+
+int32_t
+default_getspec_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, char *spec_data);
+
+int32_t
+default_lease_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_lease *lease,
+ dict_t *xdata);
+
+int32_t
+default_getactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ lock_migration_info_t *locklist, dict_t *xdata);
+
+int32_t
+default_setactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int32_t
+default_put_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);
+
+int32_t
+default_icreate_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 *xdata);
+
+int32_t
+default_namelink_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);
+
+int32_t
+default_copy_file_range_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *stbuf, struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, dict_t *xdata);
+
+int32_t
+default_lookup_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_stat_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_truncate_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_ftruncate_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_access_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_readlink_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_mknod_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_mkdir_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_unlink_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_rmdir_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_symlink_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_rename_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_link_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_create_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_open_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_readv_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_writev_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_flush_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fsync_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fstat_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_opendir_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fsyncdir_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_statfs_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_setxattr_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fsetxattr_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fgetxattr_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_getxattr_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_xattrop_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fxattrop_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_removexattr_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fremovexattr_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_lk_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_inodelk_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_finodelk_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_entrylk_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fentrylk_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_rchecksum_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_readdir_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_readdirp_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_setattr_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fsetattr_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_fallocate_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_discard_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_zerofill_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_getspec_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_ipc_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_seek_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_lease_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_getactivelk_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_setactivelk_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_put_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_icreate_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_namelink_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_copy_file_range_failure_cbk(call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_mem_acct_init(xlator_t *this);
+
+void
+default_fini(xlator_t *this);
+
+#endif /* _DEFAULTS_H */
diff --git a/libglusterfs/src/glusterfs/dict.h b/libglusterfs/src/glusterfs/dict.h
new file mode 100644
index 00000000000..d0467c6dfb6
--- /dev/null
+++ b/libglusterfs/src/glusterfs/dict.h
@@ -0,0 +1,420 @@
+/*
+ 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
+#define _DICT_H
+
+#include <inttypes.h>
+#include <sys/uio.h>
+#include <pthread.h>
+
+#include "glusterfs/common-utils.h"
+
+typedef struct _data data_t;
+typedef struct _dict dict_t;
+typedef struct _data_pair data_pair_t;
+
+#define dict_set_sizen(this, key, value) dict_setn(this, key, SLEN(key), value)
+
+#define dict_add_sizen(this, key, value) dict_addn(this, key, SLEN(key), value)
+
+#define dict_get_sizen(this, key) dict_getn(this, key, SLEN(key))
+
+#define dict_del_sizen(this, key) dict_deln(this, key, SLEN(key))
+
+#define dict_set_str_sizen(this, key, str) \
+ dict_set_strn(this, key, SLEN(key), str)
+
+#define dict_set_sizen_str_sizen(this, key, str) \
+ dict_set_nstrn(this, key, SLEN(key), str, SLEN(str))
+
+#define dict_set_dynstr_sizen(this, key, str) \
+ dict_set_dynstrn(this, key, SLEN(key), str)
+
+#define dict_get_str_sizen(this, key, str) \
+ dict_get_strn(this, key, SLEN(key), str)
+
+#define dict_get_int32_sizen(this, key, val) \
+ dict_get_int32n(this, key, SLEN(key), val)
+
+#define dict_set_int32_sizen(this, key, val) \
+ dict_set_int32n(this, key, SLEN(key), val)
+
+#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_msg(this->name, GF_LOG_WARNING, 0, LG_MSG_DICT_SERIAL_FAILED, \
+ "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 { \
+ if (!len) \
+ break; \
+ to = dict_new(); \
+ GF_VALIDATE_OR_GOTO(xl->name, to, labl); \
+ \
+ ret = dict_unserialize(buff, len, &to); \
+ if (ret < 0) { \
+ gf_msg(xl->name, GF_LOG_WARNING, 0, LG_MSG_DICT_UNSERIAL_FAILED, \
+ "failed to unserialize dictionary (%s)", (#to)); \
+ \
+ ope = EINVAL; \
+ goto labl; \
+ } \
+ \
+ } while (0)
+
+#define dict_foreach_inline(d, c) for (c = d->members_list; c; c = c->next)
+
+#define DICT_KEY_VALUE_MAX_SIZE 1048576
+#define DICT_MAX_FLAGS 256
+#define DICT_FLAG_SET 1
+#define DICT_FLAG_CLEAR 0
+#define DICT_HDR_LEN 4
+#define DICT_DATA_HDR_KEY_LEN 4
+#define DICT_DATA_HDR_VAL_LEN 4
+
+struct _data {
+ char *data;
+ gf_atomic_t refcount;
+ gf_dict_data_type_t data_type;
+ uint32_t len;
+ gf_boolean_t is_static;
+};
+
+struct _data_pair {
+ struct _data_pair *hash_next;
+ struct _data_pair *prev;
+ struct _data_pair *next;
+ data_t *value;
+ char *key;
+ uint32_t key_hash;
+};
+
+struct _dict {
+ uint64_t max_count;
+ int32_t hash_size;
+ int32_t count;
+ gf_atomic_t refcount;
+ data_pair_t **members;
+ data_pair_t *members_list;
+ char *extra_stdfree;
+ gf_lock_t lock;
+ data_pair_t *members_internal;
+ data_pair_t free_pair;
+ /* Variable to store total keylen + value->len */
+ uint32_t totkvlen;
+};
+
+typedef gf_boolean_t (*dict_match_t)(dict_t *d, char *k, data_t *v, void *data);
+
+int32_t
+is_data_equal(data_t *one, data_t *two);
+void
+data_destroy(data_t *data);
+
+/* function to set a key/value pair (overwrite existing if matches the key */
+int32_t
+dict_set(dict_t *this, char *key, data_t *value);
+int32_t
+dict_setn(dict_t *this, char *key, const int keylen, data_t *value);
+
+/* function to set a new key/value pair (without checking for duplicate) */
+int32_t
+dict_add(dict_t *this, char *key, data_t *value);
+int32_t
+dict_addn(dict_t *this, char *key, const int keylen, data_t *value);
+int
+dict_get_with_ref(dict_t *this, char *key, data_t **data);
+data_t *
+dict_get(dict_t *this, char *key);
+data_t *
+dict_getn(dict_t *this, char *key, const int keylen);
+void
+dict_del(dict_t *this, char *key);
+void
+dict_deln(dict_t *this, char *key, const int keylen);
+int
+dict_reset(dict_t *dict);
+
+int
+dict_key_count(dict_t *this);
+
+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, u_int *length);
+
+void
+dict_unref(dict_t *dict);
+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_t **data);
+/*
+ TODO: provide converts for different byte sizes, signedness, and void *
+ */
+data_t *
+int_to_data(int64_t value);
+data_t *
+str_to_data(char *value);
+data_t *
+strn_to_data(char *value, const int vallen);
+data_t *
+data_from_dynptr(void *value, int32_t len);
+data_t *
+bin_to_data(void *value, int32_t len);
+data_t *
+static_str_to_data(char *value);
+data_t *
+static_bin_to_data(void *value);
+
+int64_t
+data_to_int64(data_t *data);
+int32_t
+data_to_int32(data_t *data);
+int16_t
+data_to_int16(data_t *data);
+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_int64(int64_t value);
+data_t *
+data_from_int32(int32_t value);
+data_t *
+data_from_int16(int16_t value);
+data_t *
+data_from_int8(int8_t value);
+
+data_t *
+data_from_uint64(uint64_t value);
+data_t *
+data_from_uint32(uint32_t value);
+data_t *
+data_from_uint16(uint16_t value);
+
+char *
+data_to_str(data_t *data);
+void *
+data_to_bin(data_t *data);
+void *
+data_to_ptr(data_t *data);
+data_t *
+data_copy(data_t *old);
+struct iatt *
+data_to_iatt(data_t *data, char *key);
+
+int
+dict_foreach(dict_t *this,
+ int (*fn)(dict_t *this, char *key, data_t *value, void *data),
+ void *data);
+
+int
+dict_foreach_fnmatch(dict_t *dict, char *pattern,
+ int (*fn)(dict_t *this, char *key, data_t *value,
+ void *data),
+ void *data);
+
+int
+dict_foreach_match(dict_t *dict,
+ gf_boolean_t (*match)(dict_t *this, char *key, data_t *value,
+ void *mdata),
+ void *match_data,
+ int (*action)(dict_t *this, char *key, data_t *value,
+ void *adata),
+ void *action_data);
+
+int
+dict_null_foreach_fn(dict_t *d, char *k, data_t *v, void *tmp);
+int
+dict_remove_foreach_fn(dict_t *d, char *k, data_t *v, void *tmp);
+dict_t *
+dict_copy(dict_t *this, dict_t *new);
+int
+dict_keys_join(void *value, int size, dict_t *dict,
+ int (*filter_fn)(char *key));
+
+/* CLEANED UP FUNCTIONS DECLARATIONS */
+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);
+
+GF_MUST_CHECK int
+dict_get_int16(dict_t *this, char *key, int16_t *val);
+GF_MUST_CHECK int
+dict_set_int16(dict_t *this, char *key, int16_t val);
+
+GF_MUST_CHECK int
+dict_get_int32(dict_t *this, char *key, int32_t *val);
+GF_MUST_CHECK int
+dict_get_int32n(dict_t *this, char *key, const int keylen, int32_t *val);
+GF_MUST_CHECK int
+dict_set_int32(dict_t *this, char *key, int32_t val);
+GF_MUST_CHECK int
+dict_set_int32n(dict_t *this, char *key, const int keylen, int32_t val);
+
+GF_MUST_CHECK int
+dict_get_int64(dict_t *this, char *key, int64_t *val);
+GF_MUST_CHECK int
+dict_set_int64(dict_t *this, char *key, int64_t val);
+
+GF_MUST_CHECK int
+dict_get_uint16(dict_t *this, char *key, uint16_t *val);
+GF_MUST_CHECK int
+dict_set_uint16(dict_t *this, char *key, uint16_t val);
+
+GF_MUST_CHECK int
+dict_get_uint32(dict_t *this, char *key, uint32_t *val);
+GF_MUST_CHECK int
+dict_set_uint32(dict_t *this, char *key, uint32_t val);
+
+GF_MUST_CHECK int
+dict_get_uint64(dict_t *this, char *key, uint64_t *val);
+GF_MUST_CHECK int
+dict_set_uint64(dict_t *this, char *key, uint64_t val);
+
+GF_MUST_CHECK int
+dict_check_flag(dict_t *this, char *key, int flag);
+GF_MUST_CHECK int
+dict_set_flag(dict_t *this, char *key, int flag);
+GF_MUST_CHECK int
+dict_clear_flag(dict_t *this, char *key, int flag);
+
+GF_MUST_CHECK int
+dict_get_double(dict_t *this, char *key, double *val);
+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_dynptr(dict_t *this, char *key, void *ptr, size_t size);
+
+GF_MUST_CHECK int
+dict_get_bin(dict_t *this, char *key, void **ptr);
+GF_MUST_CHECK int
+dict_set_bin(dict_t *this, char *key, void *ptr, size_t size);
+GF_MUST_CHECK int
+dict_set_static_bin(dict_t *this, char *key, void *ptr, size_t size);
+
+GF_MUST_CHECK int
+dict_set_option(dict_t *this, char *key, char *str);
+GF_MUST_CHECK int
+dict_set_str(dict_t *this, char *key, char *str);
+GF_MUST_CHECK int
+dict_set_strn(dict_t *this, char *key, const int keylen, char *str);
+GF_MUST_CHECK int
+dict_set_nstrn(dict_t *this, char *key, const int keylen, char *str,
+ const int vallen);
+GF_MUST_CHECK int
+dict_set_dynstr(dict_t *this, char *key, char *str);
+GF_MUST_CHECK int
+dict_set_dynstrn(dict_t *this, char *key, const int keylen, char *str);
+GF_MUST_CHECK int
+dict_set_dynstr_with_alloc(dict_t *this, char *key, const char *str);
+GF_MUST_CHECK int
+dict_add_dynstr_with_alloc(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_strn(dict_t *this, char *key, const int keylen, char **str);
+
+GF_MUST_CHECK int
+dict_get_str_boolean(dict_t *this, char *key, int default_val);
+GF_MUST_CHECK int
+dict_rename_key(dict_t *this, char *key, char *replace_key);
+GF_MUST_CHECK int
+dict_serialize_value_with_delim(dict_t *this, char *buf, int32_t *serz_len,
+ char delimiter);
+
+GF_MUST_CHECK int
+dict_set_gfuuid(dict_t *this, char *key, uuid_t uuid, bool is_static);
+GF_MUST_CHECK int
+dict_get_gfuuid(dict_t *this, char *key, uuid_t *uuid);
+
+GF_MUST_CHECK int
+dict_set_iatt(dict_t *this, char *key, struct iatt *iatt, bool is_static);
+GF_MUST_CHECK int
+dict_get_iatt(dict_t *this, char *key, struct iatt *iatt);
+GF_MUST_CHECK int
+dict_set_mdata(dict_t *this, char *key, struct mdata_iatt *mdata,
+ bool is_static);
+GF_MUST_CHECK int
+dict_get_mdata(dict_t *this, char *key, struct mdata_iatt *mdata);
+
+void
+dict_dump_to_statedump(dict_t *dict, char *dict_name, char *domain);
+
+void
+dict_dump_to_log(dict_t *dict);
+
+int
+dict_dump_to_str(dict_t *dict, char *dump, int dumpsize, char *format);
+gf_boolean_t
+dict_match_everything(dict_t *d, char *k, data_t *v, void *data);
+
+dict_t *
+dict_for_key_value(const char *name, const char *value, size_t size,
+ gf_boolean_t is_static);
+
+gf_boolean_t
+are_dicts_equal(dict_t *one, dict_t *two,
+ gf_boolean_t (*match)(dict_t *d, char *k, data_t *v,
+ void *data),
+ gf_boolean_t (*value_ignore)(char *k));
+int
+dict_has_key_from_array(dict_t *dict, char **strings, gf_boolean_t *result);
+
+int
+dict_serialized_length_lk(dict_t *this);
+#endif
diff --git a/libglusterfs/src/glusterfs/event-history.h b/libglusterfs/src/glusterfs/event-history.h
new file mode 100644
index 00000000000..f0e0422418e
--- /dev/null
+++ b/libglusterfs/src/glusterfs/event-history.h
@@ -0,0 +1,40 @@
+/*
+ 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
+
+#include <pthread.h> // for pthread_mutex_t
+#include <stddef.h> // for size_t
+#include "glusterfs/circ-buff.h" // for buffer_t, circular_buffer_t
+#include "glusterfs/glusterfs.h" // for gf_boolean_t
+
+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,
+ void (*destroy_data)(void *data));
+
+int
+eh_save_history(eh_t *history, void *string);
+
+int
+eh_destroy(eh_t *history);
+
+#endif /* _EH_H */
diff --git a/libglusterfs/src/glusterfs/events.h b/libglusterfs/src/glusterfs/events.h
new file mode 100644
index 00000000000..74c5326427b
--- /dev/null
+++ b/libglusterfs/src/glusterfs/events.h
@@ -0,0 +1,34 @@
+/*
+ Copyright (c) 2016 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 __EVENTS_H__
+#define __EVENTS_H__
+
+#include "eventtypes.h"
+
+#ifdef USE_EVENTS
+int
+_gf_event(eventtypes_t event, const char *fmt, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
+#else
+__attribute__((__format__(__printf__, 2, 3))) static inline int
+_gf_event(eventtypes_t event, const char *fmt, ...)
+{
+ return 0;
+}
+#endif /* USE_EVENTS */
+
+#define gf_event(event, fmt...) \
+ do { \
+ FMT_WARN(fmt); \
+ _gf_event(event, ##fmt); \
+ } while (0)
+
+#endif /* __EVENTS_H__ */
diff --git a/libglusterfs/src/glusterfs/fd-lk.h b/libglusterfs/src/glusterfs/fd-lk.h
new file mode 100644
index 00000000000..76cc680306a
--- /dev/null
+++ b/libglusterfs/src/glusterfs/fd-lk.h
@@ -0,0 +1,59 @@
+/*
+ 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 "glusterfs/fd.h"
+#include "glusterfs/locking.h"
+#include "glusterfs/list.h"
+#include "glusterfs/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;
+ gf_atomic_t 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_create(void);
+
+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);
+
+gf_boolean_t
+fd_lk_ctx_empty(fd_lk_ctx_t *lk_ctx);
+
+#endif /* _FD_LK_H */
diff --git a/libglusterfs/src/glusterfs/fd.h b/libglusterfs/src/glusterfs/fd.h
new file mode 100644
index 00000000000..3ffaaa60504
--- /dev/null
+++ b/libglusterfs/src/glusterfs/fd.h
@@ -0,0 +1,169 @@
+/*
+ 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_H
+#define _FD_H
+
+#include "glusterfs/list.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/locking.h"
+#include "glusterfs/fd-lk.h"
+
+#define GF_ANON_FD_NO -2
+#define GF_ANON_FD_FLAGS (O_RDWR | O_LARGEFILE)
+
+struct _inode;
+struct _dict;
+struct fd_lk_ctx;
+
+struct _fd_ctx {
+ union {
+ uint64_t key;
+ void *xl_key;
+ };
+ union {
+ uint64_t value1;
+ void *ptr1;
+ };
+};
+
+struct _fd {
+ uint64_t pid;
+ int32_t flags;
+ gf_atomic_t refcount;
+ struct list_head inode_list;
+ struct _inode *inode;
+ gf_lock_t lock; /* used ONLY for manipulating
+ '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; /* fd which does not have counterpart open
+ fd on backend (server for client, posix
+ for server). */
+};
+typedef struct _fd fd_t;
+
+struct fd_table_entry {
+ fd_t *fd;
+ int next_free;
+};
+typedef struct fd_table_entry fdentry_t;
+
+struct _fdtable {
+ int refcount;
+ uint32_t max_fds;
+ pthread_rwlock_t lock;
+ fdentry_t *fdentries;
+ int first_free;
+};
+typedef struct _fdtable fdtable_t;
+
+/* Signifies no more entries in the fd table. */
+#define GF_FDTABLE_END -1
+
+/* This is used to invalidated
+ * the next_free value in an fdentry that has been allocated
+ */
+#define GF_FDENTRY_ALLOCATED -2
+
+#include "glusterfs/logging.h"
+#include "glusterfs/xlator.h"
+
+void
+gf_fd_put(fdtable_t *fdtable, int32_t fd);
+
+fd_t *
+gf_fd_fdptr_get(fdtable_t *fdtable, int64_t fd);
+
+fdtable_t *
+gf_fd_fdtable_alloc(void);
+
+int
+gf_fd_unused_get(fdtable_t *fdtable, fd_t *fdptr);
+
+fdentry_t *
+gf_fd_fdtable_get_all_fds(fdtable_t *fdtable, uint32_t *count);
+
+void
+gf_fd_fdtable_destroy(fdtable_t *fdtable);
+
+fd_t *
+__fd_ref(fd_t *fd);
+
+fd_t *
+fd_ref(fd_t *fd);
+
+void
+fd_unref(fd_t *fd);
+
+void
+fd_close(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_lookup_anonymous(inode_t *inode, int32_t flags);
+
+fd_t *
+fd_anonymous(inode_t *inode);
+
+fd_t *
+fd_anonymous_with_flags(inode_t *inode, int32_t flags);
+
+gf_boolean_t
+fd_is_anonymous(fd_t *fd);
+
+uint8_t
+fd_list_empty(struct _inode *inode);
+
+fd_t *
+fd_bind(fd_t *fd);
+
+int
+fd_ctx_set(fd_t *fd, xlator_t *xlator, uint64_t value);
+
+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);
+
+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);
+
+int
+__fd_ctx_get(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);
+
+void
+gf_fdptr_put(fdtable_t *fdtable, fd_t *fd);
+
+#endif /* _FD_H */
diff --git a/libglusterfs/src/glusterfs/gf-dirent.h b/libglusterfs/src/glusterfs/gf-dirent.h
new file mode 100644
index 00000000000..e358da30f58
--- /dev/null
+++ b/libglusterfs/src/glusterfs/gf-dirent.h
@@ -0,0 +1,71 @@
+/*
+ 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 _GF_DIRENT_H
+#define _GF_DIRENT_H
+
+#include "glusterfs/iatt.h"
+#include "glusterfs/inode.h"
+
+#define gf_dirent_size(name) (sizeof(gf_dirent_t) + strlen(name) + 1)
+
+int
+gf_deitransform(xlator_t *this, uint64_t y);
+
+int
+gf_itransform(xlator_t *this, uint64_t x, uint64_t *y_p, int client_id);
+
+uint64_t
+gf_dirent_orig_offset(xlator_t *this, uint64_t offset);
+
+struct _dir_entry {
+ struct _dir_entry *next;
+ char *name;
+ char *link;
+ struct iatt buf;
+};
+
+struct _gf_dirent {
+ union {
+ struct list_head list;
+ struct {
+ struct _gf_dirent *next;
+ struct _gf_dirent *prev;
+ };
+ };
+ uint64_t d_ino;
+ uint64_t d_off;
+ uint32_t d_len;
+ uint32_t d_type;
+ struct iatt d_stat;
+ dict_t *dict;
+ inode_t *inode;
+ char d_name[];
+};
+
+#define DT_ISDIR(mode) (mode == DT_DIR)
+
+gf_dirent_t *
+gf_dirent_for_name(const char *name);
+gf_dirent_t *
+entry_copy(gf_dirent_t *source);
+void
+gf_dirent_entry_free(gf_dirent_t *entry);
+void
+gf_dirent_free(gf_dirent_t *entries);
+int
+gf_link_inodes_from_dirent(xlator_t *this, inode_t *parent,
+ gf_dirent_t *entries);
+int
+gf_fill_iatt_for_dirent(gf_dirent_t *entry, inode_t *parent, xlator_t *subvol);
+
+void
+gf_link_inode_from_dirent(xlator_t *this, inode_t *parent, gf_dirent_t *entry);
+#endif /* _GF_DIRENT_H */
diff --git a/libglusterfs/src/glusterfs/gf-event.h b/libglusterfs/src/glusterfs/gf-event.h
new file mode 100644
index 00000000000..40f8fbdf10a
--- /dev/null
+++ b/libglusterfs/src/glusterfs/gf-event.h
@@ -0,0 +1,140 @@
+/*
+ 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 _GF_EVENT_H_
+#define _GF_EVENT_H_
+
+#include <pthread.h>
+#include "common-utils.h"
+#include "list.h"
+
+struct event_pool;
+struct event_ops;
+struct event_slot_poll;
+struct event_slot_epoll;
+struct event_data {
+ int idx;
+ int gen;
+} __attribute__((__packed__, __may_alias__));
+
+typedef void (*event_handler_t)(int fd, int idx, int gen, void *data,
+ int poll_in, int poll_out, int poll_err,
+ char event_thread_exit);
+
+#define EVENT_EPOLL_TABLES 1024
+#define EVENT_EPOLL_SLOTS 1024
+#define EVENT_MAX_THREADS 1024
+
+/* See rpcsvc.h to check why. */
+GF_STATIC_ASSERT(EVENT_MAX_THREADS % __BITS_PER_LONG == 0);
+
+struct event_pool {
+ struct event_ops *ops;
+
+ int fd;
+ int breaker[2];
+
+ int count;
+ struct event_slot_poll *reg;
+ struct event_slot_epoll *ereg[EVENT_EPOLL_TABLES];
+ int slots_used[EVENT_EPOLL_TABLES];
+
+ struct list_head poller_death;
+ int poller_death_sliced; /* track whether the list of fds interested
+ * poller_death is sliced. If yes, new thread death
+ * notification has to wait till the list is added
+ * back
+ */
+ int poller_gen;
+ int used;
+ int changed;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+
+ void *evcache;
+ int evcache_size;
+
+ /* NOTE: Currently used only when event processing is done using
+ * epoll. */
+ int eventthreadcount; /* number of event threads to execute. */
+ pthread_t pollers[EVENT_MAX_THREADS]; /* poller thread_id store, and live
+ status */
+ int destroy;
+ int activethreadcount;
+
+ /*
+ * Number of threads created by auto-scaling, *in addition to* the
+ * configured number of threads. This is only applicable on the
+ * server, where we try to keep the number of threads around the number
+ * of bricks. In that case, the configured number is just "extra"
+ * threads to handle requests in excess of one per brick (including
+ * requests on the GlusterD connection). For clients or GlusterD, this
+ * number will always be zero, so the "extra" is all we have.
+ *
+ * TBD: consider auto-scaling for clients as well
+ */
+ int auto_thread_count;
+};
+
+struct event_destroy_data {
+ int readfd;
+ struct event_pool *pool;
+};
+
+struct event_ops {
+ struct event_pool *(*new)(int count, int eventthreadcount);
+
+ int (*event_register)(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death);
+
+ int (*event_select_on)(struct event_pool *event_pool, int fd, int idx,
+ int poll_in, int poll_out);
+
+ int (*event_unregister)(struct event_pool *event_pool, int fd, int idx);
+
+ int (*event_unregister_close)(struct event_pool *event_pool, int fd,
+ int idx);
+
+ int (*event_dispatch)(struct event_pool *event_pool);
+
+ int (*event_reconfigure_threads)(struct event_pool *event_pool,
+ int newcount);
+ int (*event_pool_destroy)(struct event_pool *event_pool);
+ int (*event_handled)(struct event_pool *event_pool, int fd, int idx,
+ int gen);
+};
+
+struct event_pool *
+gf_event_pool_new(int count, int eventthreadcount);
+int
+gf_event_select_on(struct event_pool *event_pool, int fd, int idx, int poll_in,
+ int poll_out);
+int
+gf_event_register(struct event_pool *event_pool, int fd,
+ event_handler_t handler, void *data, int poll_in,
+ int poll_out, char notify_poller_death);
+int
+gf_event_unregister(struct event_pool *event_pool, int fd, int idx);
+int
+gf_event_unregister_close(struct event_pool *event_pool, int fd, int idx);
+int
+gf_event_dispatch(struct event_pool *event_pool);
+int
+gf_event_reconfigure_threads(struct event_pool *event_pool, int value);
+int
+gf_event_pool_destroy(struct event_pool *event_pool);
+int
+gf_event_dispatch_destroy(struct event_pool *event_pool);
+int
+gf_event_handled(struct event_pool *event_pool, int fd, int idx, int gen);
+
+#endif /* _GF_EVENT_H_ */
diff --git a/libglusterfs/src/gidcache.h b/libglusterfs/src/glusterfs/gidcache.h
index 886721e719f..ddaabd765b5 100644
--- a/libglusterfs/src/gidcache.h
+++ b/libglusterfs/src/glusterfs/gidcache.h
@@ -11,8 +11,8 @@
#ifndef __GIDCACHE_H__
#define __GIDCACHE_H__
-#include "glusterfs.h"
-#include "locking.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/locking.h"
/*
* TBD: make the cache size tunable
@@ -26,30 +26,35 @@
* to scan more entries with every lookup/update.
*/
-#define AUX_GID_CACHE_ASSOC 4
-#define AUX_GID_CACHE_BUCKETS 256
-#define AUX_GID_CACHE_SIZE (AUX_GID_CACHE_ASSOC * AUX_GID_CACHE_BUCKETS)
+#define AUX_GID_CACHE_ASSOC 4
+#define AUX_GID_CACHE_BUCKETS 256
+#define AUX_GID_CACHE_SIZE (AUX_GID_CACHE_ASSOC * AUX_GID_CACHE_BUCKETS)
typedef struct {
- uint64_t gl_id;
- uint64_t gl_uid;
- uint64_t gl_gid;
- int gl_count;
- gid_t *gl_list;
- time_t gl_deadline;
+ uint64_t gl_id;
+ uint64_t gl_uid;
+ uint64_t gl_gid;
+ int gl_count;
+ gid_t *gl_list;
+ time_t gl_deadline;
} gid_list_t;
typedef struct {
- gf_lock_t gc_lock;
- uint32_t gc_max_age;
- unsigned int gc_nbuckets;
- gid_list_t gc_cache[AUX_GID_CACHE_SIZE];
+ gf_lock_t gc_lock;
+ uint32_t gc_max_age;
+ unsigned int gc_nbuckets;
+ gid_list_t gc_cache[AUX_GID_CACHE_SIZE];
} gid_cache_t;
-int gid_cache_init(gid_cache_t *, uint32_t);
-int gid_cache_reconf(gid_cache_t *, uint32_t);
-const gid_list_t *gid_cache_lookup(gid_cache_t *, uint64_t, uint64_t, uint64_t);
-void gid_cache_release(gid_cache_t *, const gid_list_t *);
-int gid_cache_add(gid_cache_t *, gid_list_t *);
+int
+gid_cache_init(gid_cache_t *, uint32_t);
+int
+gid_cache_reconf(gid_cache_t *, uint32_t);
+const gid_list_t *
+gid_cache_lookup(gid_cache_t *, uint64_t, uint64_t, uint64_t);
+void
+gid_cache_release(gid_cache_t *, const gid_list_t *);
+int
+gid_cache_add(gid_cache_t *, gid_list_t *);
#endif /* __GIDCACHE_H__ */
diff --git a/libglusterfs/src/glusterfs/glfs-message-id.h b/libglusterfs/src/glusterfs/glfs-message-id.h
new file mode 100644
index 00000000000..a1a16ca1efb
--- /dev/null
+++ b/libglusterfs/src/glusterfs/glfs-message-id.h
@@ -0,0 +1,102 @@
+/*
+ Copyright (c) 2015-2016 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _GLFS_MESSAGE_ID_H_
+#define _GLFS_MESSAGE_ID_H_
+
+/* Base of all message IDs, all message IDs would be
+ * greater than this */
+#define GLFS_MSGID_BASE 100000
+
+/* Segment size of allocated range. Any component needing more than this
+ * segment size should take multiple segments (at times non contiguous,
+ * if extensions are being made post the next segment already allocated) */
+#define GLFS_MSGID_SEGMENT 1000
+
+/* Macro to define a range of messages for a component. The first argument is
+ * the name of the component. The second argument is the number of segments
+ * to allocate. The defined values will be GLFS_MSGID_COMP_<name> and
+ * GLFS_MSGID_COMP_<name>_END. */
+#define GLFS_MSGID_COMP(_name, _blocks) \
+ GLFS_MSGID_COMP_##_name, \
+ GLFS_MSGID_COMP_##_name##_END = (GLFS_MSGID_COMP_##_name + \
+ (GLFS_MSGID_SEGMENT * (_blocks)) - 1)
+
+#define GLFS_MSGID(_name, _msgs...) \
+ enum _msgid_table_##_name \
+ { \
+ GLFS_##_name##_COMP_BASE = GLFS_MSGID_COMP_##_name, ##_msgs, \
+ GLGS_##_name##_COMP_END \
+ }
+
+/* Per module message segments allocated */
+/* NOTE: For any new module add to the end the modules */
+enum _msgid_comp {
+ GLFS_MSGID_RESERVED = GLFS_MSGID_BASE - 1,
+
+ GLFS_MSGID_COMP(GLUSTERFSD, 1),
+ GLFS_MSGID_COMP(LIBGLUSTERFS, 1),
+ GLFS_MSGID_COMP(RPC_LIB, 1),
+ GLFS_MSGID_COMP(RPC_TRANS_RDMA, 1),
+ GLFS_MSGID_COMP(API, 1),
+ GLFS_MSGID_COMP(CLI, 1),
+ /* glusterd has a lot of messages, taking 2 segments for the same */
+ GLFS_MSGID_COMP(GLUSTERD, 2),
+ GLFS_MSGID_COMP(AFR, 1),
+ GLFS_MSGID_COMP(DHT, 1),
+ /* there is no component called 'common', however reserving this segment
+ * for common actions/errors like dict_{get/set}, memory accounting*/
+ GLFS_MSGID_COMP(COMMON, 1),
+ GLFS_MSGID_COMP(UPCALL, 1),
+ GLFS_MSGID_COMP(NFS, 1),
+ GLFS_MSGID_COMP(POSIX, 1),
+ GLFS_MSGID_COMP(PC, 1),
+ GLFS_MSGID_COMP(PS, 1),
+ GLFS_MSGID_COMP(BITROT_STUB, 1),
+ GLFS_MSGID_COMP(CHANGELOG, 1),
+ GLFS_MSGID_COMP(BITROT_BITD, 1),
+ GLFS_MSGID_COMP(RPC_TRANS_SOCKET, 1),
+ GLFS_MSGID_COMP(QUOTA, 1),
+ GLFS_MSGID_COMP(CTR, 1),
+ GLFS_MSGID_COMP(EC, 1),
+ GLFS_MSGID_COMP(IO_CACHE, 1),
+ GLFS_MSGID_COMP(IO_THREADS, 1),
+ GLFS_MSGID_COMP(MD_CACHE, 1),
+ GLFS_MSGID_COMP(OPEN_BEHIND, 1),
+ GLFS_MSGID_COMP(QUICK_READ, 1),
+ GLFS_MSGID_COMP(READ_AHEAD, 1),
+ GLFS_MSGID_COMP(READDIR_AHEAD, 1),
+ GLFS_MSGID_COMP(SYMLINK_CACHE, 1),
+ GLFS_MSGID_COMP(WRITE_BEHIND, 1),
+ GLFS_MSGID_COMP(CHANGELOG_LIB, 1),
+ GLFS_MSGID_COMP(SHARD, 1),
+ GLFS_MSGID_COMP(JBR, 1),
+ GLFS_MSGID_COMP(PL, 1),
+ GLFS_MSGID_COMP(DC, 1),
+ GLFS_MSGID_COMP(LEASES, 1),
+ GLFS_MSGID_COMP(INDEX, 1),
+ GLFS_MSGID_COMP(POSIX_ACL, 1),
+ GLFS_MSGID_COMP(NLC, 1),
+ GLFS_MSGID_COMP(SL, 1),
+ GLFS_MSGID_COMP(HAM, 1),
+ GLFS_MSGID_COMP(SDFS, 1),
+ GLFS_MSGID_COMP(QUIESCE, 1),
+ GLFS_MSGID_COMP(TA, 1),
+ GLFS_MSGID_COMP(SNAPVIEW_CLIENT, 1),
+ GLFS_MSGID_COMP(TEMPLATE, 1),
+ GLFS_MSGID_COMP(UTIME, 1),
+ GLFS_MSGID_COMP(SNAPVIEW_SERVER, 1),
+ GLFS_MSGID_COMP(CVLT, 1),
+ /* --- new segments for messages goes above this line --- */
+
+ GLFS_MSGID_END
+};
+
+#endif /* !_GLFS_MESSAGE_ID_H_ */
diff --git a/libglusterfs/src/glusterfs/globals.h b/libglusterfs/src/glusterfs/globals.h
new file mode 100644
index 00000000000..b22eaae6c2f
--- /dev/null
+++ b/libglusterfs/src/glusterfs/globals.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 _GLOBALS_H
+#define _GLOBALS_H
+
+#define GF_DEFAULT_BASE_PORT 24007
+#define GF_DEFAULT_VOLFILE_TRANSPORT "tcp"
+
+#define GF_GLOBAL_XLATOR_NAME "global"
+#define GD_OP_VERSION_KEY "operating-version"
+#define GD_MIN_OP_VERSION_KEY "minimum-operating-version"
+#define GD_MAX_OP_VERSION_KEY "maximum-operating-version"
+
+#define GF_PROTECT_FROM_EXTERNAL_WRITES "trusted.glusterfs.protect.writes"
+#define GF_AVOID_OVERWRITE "glusterfs.avoid.overwrite"
+#define GF_CLEAN_WRITE_PROTECTION "glusterfs.clean.writexattr"
+
+/* Gluster versions - OP-VERSION mapping
+ *
+ * 3.3.x - 1
+ * 3.4.x - 2
+ * 3.5.0 - 3
+ * 3.5.1 - 30501
+ * 3.6.0 - 30600
+ * 3.7.0 - 30700
+ * 3.7.1 - 30701
+ * 3.7.2 - 30702
+ *
+ * Starting with Gluster v3.6, the op-version will be multi-digit integer values
+ * based on the Glusterfs version, instead of a simply incrementing integer
+ * value. The op-version for a given X.Y.Z release will be an integer XYZ, with
+ * Y and Z 2 digit always 2 digits wide and padded with 0 when needed. This
+ * should allow for some gaps between two Y releases for backports of features
+ * in Z releases.
+ */
+#define GD_OP_VERSION_MIN \
+ 1 /* MIN is the fresh start op-version, mostly \
+ should not change */
+#define GD_OP_VERSION_MAX \
+ GD_OP_VERSION_9_0 /* MAX VERSION is the maximum \
+ count in VME table, should \
+ keep changing with \
+ introduction of newer \
+ versions */
+
+#define GD_OP_VERSION_3_6_0 30600 /* Op-Version for GlusterFS 3.6.0 */
+
+#define GD_OP_VERSION_3_7_0 30700 /* Op-version for GlusterFS 3.7.0 */
+
+#define GD_OP_VERSION_3_7_1 30701 /* Op-version for GlusterFS 3.7.1 */
+
+#define GD_OP_VERSION_3_7_2 30702 /* Op-version for GlusterFS 3.7.2 */
+
+#define GD_OP_VERSION_3_7_3 30703 /* Op-version for GlusterFS 3.7.3 */
+
+#define GD_OP_VERSION_3_7_4 30704 /* Op-version for GlusterFS 3.7.4 */
+
+#define GD_OP_VERSION_3_7_5 30705 /* Op-version for GlusterFS 3.7.5 */
+
+#define GD_OP_VERSION_3_7_6 30706 /* Op-version for GlusterFS 3.7.6 */
+
+#define GD_OP_VERSION_3_7_7 30707 /* Op-version for GlusterFS 3.7.7 */
+
+#define GD_OP_VERSION_3_7_10 30710 /* Op-version for GlusterFS 3.7.10 */
+
+#define GD_OP_VERSION_3_7_12 30712 /* Op-version for GlusterFS 3.7.12 */
+
+#define GD_OP_VERSION_3_8_0 30800 /* Op-version for GlusterFS 3.8.0 */
+
+#define GD_OP_VERSION_3_8_3 30803 /* Op-version for GlusterFS 3.8.3 */
+
+#define GD_OP_VERSION_3_8_4 30804 /* Op-version for GlusterFS 3.8.4 */
+
+#define GD_OP_VERSION_3_9_0 30900 /* Op-version for GlusterFS 3.9.0 */
+
+#define GD_OP_VERSION_3_9_1 30901 /* Op-version for GlusterFS 3.9.1 */
+
+#define GD_OP_VERSION_3_10_0 31000 /* Op-version for GlusterFS 3.10.0 */
+
+#define GD_OP_VERSION_3_10_1 31001 /* Op-version for GlusterFS 3.10.1 */
+
+#define GD_OP_VERSION_3_10_2 31002 /* Op-version for GlusterFS 3.10.2 */
+
+#define GD_OP_VERSION_3_11_0 31100 /* Op-version for GlusterFS 3.11.0 */
+
+#define GD_OP_VERSION_3_11_1 31101 /* Op-version for GlusterFS 3.11.1 */
+
+#define GD_OP_VERSION_3_12_0 31200 /* Op-version for GlusterFS 3.12.0 */
+
+#define GD_OP_VERSION_3_12_2 31202 /* Op-version for GlusterFS 3.12.2 */
+
+#define GD_OP_VERSION_3_12_3 31203 /* Op-version for GlusterFS 3.12.3 */
+
+#define GD_OP_VERSION_3_13_0 31300 /* Op-version for GlusterFS 3.13.0 */
+
+#define GD_OP_VERSION_3_13_1 31301 /* Op-version for GlusterFS 3.13.1 */
+
+#define GD_OP_VERSION_3_13_2 31302 /* Op-version for GlusterFS 3.13.2 */
+
+#define GD_OP_VERSION_4_0_0 40000 /* Op-version for GlusterFS 4.0.0 */
+
+#define GD_OP_VERSION_4_1_0 40100 /* Op-version for GlusterFS 4.1.0 */
+
+#define GD_OP_VERSION_5_0 50000 /* Op-version for GlusterFS 5.0 */
+
+#define GD_OP_VERSION_5_4 50400 /* Op-version for GlusterFS 5.4 */
+
+#define GD_OP_VERSION_6_0 60000 /* Op-version for GlusterFS 6.0 */
+
+#define GD_OP_VERSION_7_0 70000 /* Op-version for GlusterFS 7.0 */
+#define GD_OP_VERSION_7_1 70100 /* Op-version for GlusterFS 7.1 */
+#define GD_OP_VERSION_7_2 70200 /* Op-version for GlusterFS 7.2 */
+#define GD_OP_VERSION_7_3 70300 /* Op-version for GlusterFS 7.3 */
+
+#define GD_OP_VERSION_8_0 80000 /* Op-version for GlusterFS 8.0 */
+
+#define GD_OP_VERSION_9_0 90000 /* Op-version for GlusterFS 9.0 */
+
+#define GD_OP_VER_PERSISTENT_AFR_XATTRS GD_OP_VERSION_3_6_0
+
+#include "glusterfs/xlator.h"
+#include "glusterfs/options.h"
+
+/* THIS */
+#define THIS (*__glusterfs_this_location())
+#define DECLARE_OLD_THIS xlator_t *old_THIS = THIS
+
+xlator_t **
+__glusterfs_this_location(void);
+xlator_t *
+glusterfs_this_get(void);
+void
+glusterfs_this_set(xlator_t *);
+
+extern xlator_t global_xlator;
+extern struct volume_options global_xl_options[];
+
+/* syncopctx */
+void *
+syncopctx_getctx(void);
+
+/* task */
+void *
+synctask_get(void);
+void
+synctask_set(void *);
+
+/* uuid_buf */
+char *
+glusterfs_uuid_buf_get(void);
+/* lkowner_buf */
+char *
+glusterfs_lkowner_buf_get(void);
+/* leaseid buf */
+char *
+glusterfs_leaseid_buf_get(void);
+char *
+glusterfs_leaseid_exist(void);
+
+/* init */
+int
+glusterfs_globals_init(glusterfs_ctx_t *ctx);
+
+void
+gf_thread_needs_cleanup(void);
+
+struct tvec_base *
+glusterfs_ctx_tw_get(glusterfs_ctx_t *ctx);
+void
+glusterfs_ctx_tw_put(glusterfs_ctx_t *ctx);
+
+extern const char *gf_fop_list[];
+extern const char *gf_upcall_list[];
+
+/* mem acct enable/disable */
+int
+gf_global_mem_acct_enable_get(void);
+int
+gf_global_mem_acct_enable_set(int val);
+#endif /* !_GLOBALS_H */
diff --git a/libglusterfs/src/glusterfs/glusterfs-acl.h b/libglusterfs/src/glusterfs/glusterfs-acl.h
new file mode 100644
index 00000000000..987bf5fab0b
--- /dev/null
+++ b/libglusterfs/src/glusterfs/glusterfs-acl.h
@@ -0,0 +1,162 @@
+/*
+ Copyright (c) 2013 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_ACL_H
+#define _GLUSTERFS_ACL_H
+
+/* WARNING: Much if this code is restricted to Linux usage.
+ *
+ * It would be much cleaner to replace the code with something that is based on
+ * libacl (or its libc implementation on *BSD).
+ *
+ * Initial work for replacing this Linux specific implementation has been
+ * started as part of the "Improve POSIX ACLs" feature. Functionality for this
+ * feature has been added to the end of this file.
+ */
+
+#include <stdint.h>
+#include <sys/types.h> /* For uid_t */
+
+#include "glusterfs/locking.h" /* For gf_lock_t in struct posix_acl_conf */
+
+#define ACL_PROGRAM 100227
+#define ACLV3_VERSION 3
+
+#define POSIX_ACL_MINIMAL_ACE_COUNT 3
+
+#define POSIX_ACL_READ (0x04)
+#define POSIX_ACL_WRITE (0x02)
+#define POSIX_ACL_EXECUTE (0x01)
+
+#define POSIX_ACL_UNDEFINED_TAG (0x00)
+#define POSIX_ACL_USER_OBJ (0x01)
+#define POSIX_ACL_USER (0x02)
+#define POSIX_ACL_GROUP_OBJ (0x04)
+#define POSIX_ACL_GROUP (0x08)
+#define POSIX_ACL_MASK (0x10)
+#define POSIX_ACL_OTHER (0x20)
+
+#define POSIX_ACL_UNDEFINED_ID (-1)
+
+#define POSIX_ACL_XATTR_VERSION (0x02)
+
+#define POSIX_ACL_ACCESS_XATTR "system.posix_acl_access"
+#define POSIX_ACL_DEFAULT_XATTR "system.posix_acl_default"
+
+struct posix_acl_xattr_entry {
+ uint16_t tag;
+ uint16_t perm;
+ uint32_t id;
+};
+
+struct posix_acl_xattr_header {
+ uint32_t version;
+ struct posix_acl_xattr_entry entries[];
+};
+
+typedef struct posix_acl_xattr_entry posix_acl_xattr_entry;
+typedef struct posix_acl_xattr_header posix_acl_xattr_header;
+
+static inline size_t
+posix_acl_xattr_size(unsigned int count)
+{
+ return (sizeof(posix_acl_xattr_header) +
+ (count * sizeof(posix_acl_xattr_entry)));
+}
+
+static inline ssize_t
+posix_acl_xattr_count(size_t size)
+{
+ if (size < sizeof(posix_acl_xattr_header))
+ return (-1);
+ size -= sizeof(posix_acl_xattr_header);
+ if (size % sizeof(posix_acl_xattr_entry))
+ return (-1);
+ return (size / sizeof(posix_acl_xattr_entry));
+}
+
+struct posix_ace {
+ uint16_t tag;
+ uint16_t perm;
+ uint32_t id;
+};
+
+struct posix_acl {
+ int refcnt;
+ int count;
+ struct posix_ace entries[];
+};
+
+struct posix_acl_ctx {
+ uid_t uid;
+ gid_t gid;
+ mode_t perm;
+ glusterfs_fop_t fop;
+ struct posix_acl *acl_access;
+ struct posix_acl *acl_default;
+};
+
+struct posix_acl_conf {
+ gf_lock_t acl_lock;
+ uid_t super_uid;
+ struct posix_acl *minimal_acl;
+};
+
+/* Above this comment, the legacy POSIX ACL support is kept until it is not
+ * used anymore. Below you will find the more portable version to support POSIX
+ * ACls based on the implementation of libacl (see sys/acl.h). */
+
+/* virtual xattrs passed over RPC, not stored on disk */
+#define GF_POSIX_ACL_ACCESS "glusterfs.posix.acl"
+#define GF_POSIX_ACL_DEFAULT "glusterfs.posix.default_acl"
+#define GF_POSIX_ACL_REQUEST(key) \
+ (!strncmp(key, GF_POSIX_ACL_ACCESS, SLEN(GF_POSIX_ACL_ACCESS)) || \
+ !strncmp(key, GF_POSIX_ACL_DEFAULT, SLEN(GF_POSIX_ACL_DEFAULT)))
+
+#ifdef HAVE_SYS_ACL_H /* only NetBSD does not support POSIX ACLs */
+
+#include <sys/acl.h>
+
+static inline const char *
+gf_posix_acl_get_key(const acl_type_t type)
+{
+ char *acl_key = NULL;
+
+ switch (type) {
+ case ACL_TYPE_ACCESS:
+ acl_key = GF_POSIX_ACL_ACCESS;
+ break;
+ case ACL_TYPE_DEFAULT:
+ acl_key = GF_POSIX_ACL_DEFAULT;
+ break;
+ default:
+ errno = EINVAL;
+ }
+
+ return acl_key;
+}
+
+static inline acl_type_t
+gf_posix_acl_get_type(const char *key)
+{
+ acl_type_t type = 0;
+
+ if (!strncmp(key, GF_POSIX_ACL_ACCESS, SLEN(GF_POSIX_ACL_ACCESS)))
+ type = ACL_TYPE_ACCESS;
+ else if (!strncmp(key, GF_POSIX_ACL_DEFAULT, SLEN(GF_POSIX_ACL_DEFAULT)))
+ type = ACL_TYPE_DEFAULT;
+ else
+ errno = EINVAL;
+
+ return type;
+}
+
+#endif /* HAVE_SYS_ACL_H */
+#endif /* _GLUSTERFS_ACL_H */
diff --git a/libglusterfs/src/glusterfs/glusterfs-fops.h b/libglusterfs/src/glusterfs/glusterfs-fops.h
new file mode 100644
index 00000000000..030b2701608
--- /dev/null
+++ b/libglusterfs/src/glusterfs/glusterfs-fops.h
@@ -0,0 +1,241 @@
+/*
+ Copyright (c) 2008-2019 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_FOPS_H_
+#define _GLUSTERFS_FOPS_H_
+
+#include <glusterfs/compat.h>
+
+enum glusterfs_fop_t {
+ GF_FOP_NULL = 0,
+ GF_FOP_STAT = 0 + 1,
+ GF_FOP_READLINK = 0 + 2,
+ GF_FOP_MKNOD = 0 + 3,
+ GF_FOP_MKDIR = 0 + 4,
+ GF_FOP_UNLINK = 0 + 5,
+ GF_FOP_RMDIR = 0 + 6,
+ GF_FOP_SYMLINK = 0 + 7,
+ GF_FOP_RENAME = 0 + 8,
+ GF_FOP_LINK = 0 + 9,
+ GF_FOP_TRUNCATE = 0 + 10,
+ GF_FOP_OPEN = 0 + 11,
+ GF_FOP_READ = 0 + 12,
+ GF_FOP_WRITE = 0 + 13,
+ GF_FOP_STATFS = 0 + 14,
+ GF_FOP_FLUSH = 0 + 15,
+ GF_FOP_FSYNC = 0 + 16,
+ GF_FOP_SETXATTR = 0 + 17,
+ GF_FOP_GETXATTR = 0 + 18,
+ GF_FOP_REMOVEXATTR = 0 + 19,
+ GF_FOP_OPENDIR = 0 + 20,
+ GF_FOP_FSYNCDIR = 0 + 21,
+ GF_FOP_ACCESS = 0 + 22,
+ GF_FOP_CREATE = 0 + 23,
+ GF_FOP_FTRUNCATE = 0 + 24,
+ GF_FOP_FSTAT = 0 + 25,
+ GF_FOP_LK = 0 + 26,
+ GF_FOP_LOOKUP = 0 + 27,
+ GF_FOP_READDIR = 0 + 28,
+ GF_FOP_INODELK = 0 + 29,
+ GF_FOP_FINODELK = 0 + 30,
+ GF_FOP_ENTRYLK = 0 + 31,
+ GF_FOP_FENTRYLK = 0 + 32,
+ GF_FOP_XATTROP = 0 + 33,
+ GF_FOP_FXATTROP = 0 + 34,
+ GF_FOP_FGETXATTR = 0 + 35,
+ GF_FOP_FSETXATTR = 0 + 36,
+ GF_FOP_RCHECKSUM = 0 + 37,
+ GF_FOP_SETATTR = 0 + 38,
+ GF_FOP_FSETATTR = 0 + 39,
+ GF_FOP_READDIRP = 0 + 40,
+ GF_FOP_FORGET = 0 + 41,
+ GF_FOP_RELEASE = 0 + 42,
+ GF_FOP_RELEASEDIR = 0 + 43,
+ GF_FOP_GETSPEC = 0 + 44,
+ GF_FOP_FREMOVEXATTR = 0 + 45,
+ GF_FOP_FALLOCATE = 0 + 46,
+ GF_FOP_DISCARD = 0 + 47,
+ GF_FOP_ZEROFILL = 0 + 48,
+ GF_FOP_IPC = 0 + 49,
+ GF_FOP_SEEK = 0 + 50,
+ GF_FOP_LEASE = 0 + 51,
+ GF_FOP_COMPOUND = 0 + 52,
+ GF_FOP_GETACTIVELK = 0 + 53,
+ GF_FOP_SETACTIVELK = 0 + 54,
+ GF_FOP_PUT = 0 + 55,
+ GF_FOP_ICREATE = 0 + 56,
+ GF_FOP_NAMELINK = 0 + 57,
+ GF_FOP_COPY_FILE_RANGE = 0 + 58,
+ GF_FOP_MAXVALUE = 0 + 59,
+};
+typedef enum glusterfs_fop_t glusterfs_fop_t;
+
+enum glusterfs_event_t {
+ GF_EVENT_PARENT_UP = 1,
+ GF_EVENT_POLLIN = 1 + 1,
+ GF_EVENT_POLLOUT = 1 + 2,
+ GF_EVENT_POLLERR = 1 + 3,
+ GF_EVENT_CHILD_UP = 1 + 4,
+ GF_EVENT_CHILD_DOWN = 1 + 5,
+ GF_EVENT_CHILD_CONNECTING = 1 + 6,
+ GF_EVENT_CLEANUP = 9,
+ GF_EVENT_TRANSPORT_CONNECTED = 9 + 1,
+ GF_EVENT_VOLFILE_MODIFIED = 9 + 2,
+ GF_EVENT_GRAPH_NEW = 9 + 3,
+ GF_EVENT_TRANSLATOR_INFO = 9 + 4,
+ GF_EVENT_TRANSLATOR_OP = 9 + 5,
+ GF_EVENT_AUTH_FAILED = 9 + 6,
+ GF_EVENT_VOLUME_DEFRAG = 9 + 7,
+ GF_EVENT_PARENT_DOWN = 9 + 8,
+ GF_EVENT_VOLUME_BARRIER_OP = 9 + 9,
+ GF_EVENT_UPCALL = 9 + 10,
+ GF_EVENT_SCRUB_STATUS = 9 + 11,
+ GF_EVENT_SOME_DESCENDENT_DOWN = 9 + 12,
+ GF_EVENT_SCRUB_ONDEMAND = 9 + 13,
+ GF_EVENT_SOME_DESCENDENT_UP = 9 + 14,
+ GF_EVENT_CHILD_PING = 9 + 15,
+ GF_EVENT_MAXVAL = 9 + 16,
+};
+typedef enum glusterfs_event_t glusterfs_event_t;
+
+enum gf_op_type_t {
+ GF_OP_TYPE_NULL = 0,
+ GF_OP_TYPE_FOP = 0 + 1,
+ GF_OP_TYPE_MGMT = 0 + 2,
+ GF_OP_TYPE_MAX = 0 + 3,
+};
+typedef enum gf_op_type_t gf_op_type_t;
+
+enum glusterfs_lk_cmds_t {
+ GF_LK_GETLK = 0,
+ GF_LK_SETLK = 0 + 1,
+ GF_LK_SETLKW = 0 + 2,
+ GF_LK_RESLK_LCK = 0 + 3,
+ GF_LK_RESLK_LCKW = 0 + 4,
+ GF_LK_RESLK_UNLCK = 0 + 5,
+ GF_LK_GETLK_FD = 0 + 6,
+};
+typedef enum glusterfs_lk_cmds_t glusterfs_lk_cmds_t;
+
+enum glusterfs_lk_types_t {
+ GF_LK_F_RDLCK = 0,
+ GF_LK_F_WRLCK = 0 + 1,
+ GF_LK_F_UNLCK = 0 + 2,
+ GF_LK_EOL = 0 + 3,
+};
+typedef enum glusterfs_lk_types_t glusterfs_lk_types_t;
+
+enum gf_lease_types_t {
+ NONE = 0,
+ GF_RD_LEASE = 1,
+ GF_RW_LEASE = 2,
+ GF_LEASE_MAX_TYPE = 2 + 1,
+};
+typedef enum gf_lease_types_t gf_lease_types_t;
+
+enum gf_lease_cmds_t {
+ GF_GET_LEASE = 1,
+ GF_SET_LEASE = 2,
+ GF_UNLK_LEASE = 3,
+};
+typedef enum gf_lease_cmds_t gf_lease_cmds_t;
+
+#define LEASE_ID_SIZE 16 /* 128bits */
+
+struct gf_lease {
+ gf_lease_cmds_t cmd;
+ gf_lease_types_t lease_type;
+ char lease_id[LEASE_ID_SIZE];
+ u_int lease_flags;
+};
+typedef struct gf_lease gf_lease;
+
+enum glusterfs_lk_recovery_cmds_t {
+ F_RESLK_LCK = 200,
+ F_RESLK_LCKW = 200 + 1,
+ F_RESLK_UNLCK = 200 + 2,
+ F_GETLK_FD = 200 + 3,
+};
+typedef enum glusterfs_lk_recovery_cmds_t glusterfs_lk_recovery_cmds_t;
+
+enum gf_lk_domain_t {
+ GF_LOCK_POSIX = 0,
+ GF_LOCK_INTERNAL = 1,
+};
+typedef enum gf_lk_domain_t gf_lk_domain_t;
+
+enum entrylk_cmd {
+ ENTRYLK_LOCK = 0,
+ ENTRYLK_UNLOCK = 1,
+ ENTRYLK_LOCK_NB = 2,
+};
+typedef enum entrylk_cmd entrylk_cmd;
+
+enum entrylk_type {
+ ENTRYLK_RDLCK = 0,
+ ENTRYLK_WRLCK = 1,
+};
+typedef enum entrylk_type entrylk_type;
+#define GF_MAX_LOCK_OWNER_LEN 1024 /* 1kB as per NLM */
+#define GF_LKOWNER_BUF_SIZE \
+ ((GF_MAX_LOCK_OWNER_LEN * 2) + (GF_MAX_LOCK_OWNER_LEN / 8))
+
+struct gf_lkowner_t {
+ int len;
+ char data[GF_MAX_LOCK_OWNER_LEN];
+};
+typedef struct gf_lkowner_t gf_lkowner_t;
+
+enum gf_xattrop_flags_t {
+ GF_XATTROP_ADD_ARRAY = 0,
+ GF_XATTROP_ADD_ARRAY64 = 1,
+ GF_XATTROP_OR_ARRAY = 2,
+ GF_XATTROP_AND_ARRAY = 3,
+ GF_XATTROP_GET_AND_SET = 4,
+ GF_XATTROP_ADD_ARRAY_WITH_DEFAULT = 5,
+ GF_XATTROP_ADD_ARRAY64_WITH_DEFAULT = 6,
+};
+typedef enum gf_xattrop_flags_t gf_xattrop_flags_t;
+
+enum gf_seek_what_t {
+ GF_SEEK_DATA = 0,
+ GF_SEEK_HOLE = 1,
+};
+typedef enum gf_seek_what_t gf_seek_what_t;
+
+enum gf_upcall_flags_t {
+ GF_UPCALL_NULL = 0,
+ GF_UPCALL = 1,
+ GF_UPCALL_CI_STAT = 2,
+ GF_UPCALL_CI_XATTR = 3,
+ GF_UPCALL_CI_RENAME = 4,
+ GF_UPCALL_CI_NLINK = 5,
+ GF_UPCALL_CI_FORGET = 6,
+ GF_UPCALL_LEASE_RECALL = 7,
+ GF_UPCALL_FLAGS_MAXVALUE = 8,
+};
+typedef enum gf_upcall_flags_t gf_upcall_flags_t;
+
+enum gf_dict_data_type_t {
+ GF_DATA_TYPE_UNKNOWN = 0,
+ GF_DATA_TYPE_STR_OLD = 1,
+ GF_DATA_TYPE_INT = 2,
+ GF_DATA_TYPE_UINT = 3,
+ GF_DATA_TYPE_DOUBLE = 4,
+ GF_DATA_TYPE_STR = 5,
+ GF_DATA_TYPE_PTR = 6,
+ GF_DATA_TYPE_GFUUID = 7,
+ GF_DATA_TYPE_IATT = 8,
+ GF_DATA_TYPE_MDATA = 9,
+ GF_DATA_TYPE_MAX = 10,
+};
+typedef enum gf_dict_data_type_t gf_dict_data_type_t;
+
+#endif /* !_GLUSTERFS_FOPS_H */
diff --git a/libglusterfs/src/glusterfs/glusterfs.h b/libglusterfs/src/glusterfs/glusterfs.h
new file mode 100644
index 00000000000..e6425618b7f
--- /dev/null
+++ b/libglusterfs/src/glusterfs/glusterfs.h
@@ -0,0 +1,838 @@
+/*
+ Copyright (c) 2008-2016 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
+#define _GLUSTERFS_H
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <netdb.h>
+#include <errno.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <sys/poll.h>
+#include <pthread.h>
+#include <limits.h> /* For PATH_MAX */
+#include <openssl/sha.h>
+
+#include "glusterfs/glusterfs-fops.h"
+#include "glusterfs/list.h"
+#include "glusterfs/locking.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/lkowner.h"
+#include "glusterfs/compat-uuid.h"
+#include "glusterfs/refcount.h"
+#include "glusterfs/atomic.h"
+
+#define GF_YES 1
+#define GF_NO 0
+
+#define IS_ERROR(ret) ((ret) < 0)
+#define IS_SUCCESS(ret) ((ret) >= 0)
+
+#ifndef O_LARGEFILE
+/* savannah bug #20053, patch for compiling on darwin */
+#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
+/* savannah bug #20050, #20052 */
+#define O_DIRECT 0 /* From asm/fcntl.h */
+#endif
+
+#ifndef O_DIRECTORY
+/* FreeBSD does not need O_DIRECTORY */
+#define O_DIRECTORY 0
+#endif
+
+#ifndef EBADFD
+/* Mac OS X does not have EBADFD */
+#define EBADFD EBADF
+#endif
+
+#ifndef FNM_EXTMATCH
+#define FNM_EXTMATCH 0
+#endif
+
+/*gets max-offset on all architectures correctly*/
+#define GF_OFF_MAX ((1ULL << (sizeof(off_t) * 8 - 1)) - 1ULL)
+
+#define GLUSTERD_MAX_SNAP_NAME 255
+#define GLUSTERFS_SOCKET_LISTEN_BACKLOG 1024
+#define GLUSTERD_BRICK_SERVERS "cluster.brick-vol-servers"
+#define SLEN(str) (sizeof(str) - 1)
+
+#define ZR_MOUNTPOINT_OPT "mountpoint"
+#define ZR_ATTR_TIMEOUT_OPT "attribute-timeout"
+#define ZR_ENTRY_TIMEOUT_OPT "entry-timeout"
+#define ZR_NEGATIVE_TIMEOUT_OPT "negative-timeout"
+#define ZR_DIRECT_IO_OPT "direct-io-mode"
+#define ZR_STRICT_VOLFILE_CHECK "strict-volfile-check"
+#define ZR_DUMP_FUSE "dump-fuse"
+#define ZR_FUSE_MOUNTOPTS "fuse-mountopts"
+#define IO_THREADS_QUEUE_SIZE_KEY "io-thread-queue-size"
+
+#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_LIST_NODE_UUIDS_KEY "trusted.glusterfs.list-node-uuids"
+#define GF_REBAL_FIND_LOCAL_SUBVOL "glusterfs.find-local-subvol"
+#define GF_REBAL_OLD_FIND_LOCAL_SUBVOL "glusterfs.old-find-local-subvol"
+#define GF_XATTR_VOL_ID_KEY "trusted.glusterfs.volume-id"
+#define GF_XATTR_LOCKINFO_KEY "trusted.glusterfs.lockinfo"
+#define GF_META_LOCK_KEY "glusterfs.lock-migration-meta-lock"
+#define GF_META_UNLOCK_KEY "glusterfs.lock-migration-meta-unlock"
+#define GF_XATTR_GET_REAL_FILENAME_KEY "glusterfs.get_real_filename:"
+#define GF_XATTR_USER_PATHINFO_KEY "glusterfs.pathinfo"
+#define GF_INTERNAL_IGNORE_DEEM_STATFS "ignore-deem-statfs"
+#define GF_XATTR_IOSTATS_DUMP_KEY "trusted.io-stats-dump"
+
+#define GF_READDIR_SKIP_DIRS "readdir-filter-directories"
+#define GF_MDC_LOADED_KEY_NAMES "glusterfs.mdc.loaded.key.names"
+
+#define BD_XATTR_KEY "user.glusterfs"
+#define GF_PREOP_PARENT_KEY "glusterfs.preop.parent.key"
+#define GF_PREOP_CHECK_FAILED "glusterfs.preop.check.failed"
+
+#define XATTR_IS_PATHINFO(x) \
+ ((strncmp(x, GF_XATTR_PATHINFO_KEY, strlen(x)) == 0) || \
+ (strncmp(x, GF_XATTR_USER_PATHINFO_KEY, strlen(x)) == 0))
+#define XATTR_IS_NODE_UUID(x) \
+ (strncmp(x, GF_XATTR_NODE_UUID_KEY, SLEN(GF_XATTR_NODE_UUID_KEY)) == 0)
+#define XATTR_IS_NODE_UUID_LIST(x) \
+ (strncmp(x, GF_XATTR_LIST_NODE_UUIDS_KEY, \
+ SLEN(GF_XATTR_LIST_NODE_UUIDS_KEY)) == 0)
+#define XATTR_IS_LOCKINFO(x) \
+ (strncmp(x, GF_XATTR_LOCKINFO_KEY, SLEN(GF_XATTR_LOCKINFO_KEY)) == 0)
+
+#define XATTR_IS_BD(x) (strncmp(x, BD_XATTR_KEY, SLEN(BD_XATTR_KEY)) == 0)
+
+#define GF_XATTR_LINKINFO_KEY "trusted.distribute.linkinfo"
+#define GFID_XATTR_KEY "trusted.gfid"
+#define PGFID_XATTR_KEY_PREFIX "trusted.pgfid."
+#define GFID2PATH_VIRT_XATTR_KEY "glusterfs.gfidtopath"
+#define GFID2PATH_XATTR_KEY_PREFIX "trusted.gfid2path."
+#define GFID2PATH_XATTR_KEY_PREFIX_LENGTH 18
+#define VIRTUAL_GFID_XATTR_KEY_STR "glusterfs.gfid.string"
+#define VIRTUAL_GFID_XATTR_KEY "glusterfs.gfid"
+#define GF_XATTR_MDATA_KEY "trusted.glusterfs.mdata"
+#define UUID_CANONICAL_FORM_LEN 36
+
+#define GET_ANCESTRY_PATH_KEY "glusterfs.ancestry.path"
+#define GET_ANCESTRY_DENTRY_KEY "glusterfs.ancestry.dentry"
+
+#define BITROT_DEFAULT_CURRENT_VERSION (unsigned long)1
+#define BITROT_DEFAULT_SIGNING_VERSION (unsigned long)0
+
+/* on-disk object signature keys */
+#define BITROT_OBJECT_BAD_KEY "trusted.bit-rot.bad-file"
+#define BITROT_CURRENT_VERSION_KEY "trusted.bit-rot.version"
+#define BITROT_SIGNING_VERSION_KEY "trusted.bit-rot.signature"
+
+/* globally usable bad file marker */
+#define GLUSTERFS_BAD_INODE "glusterfs.bad-inode"
+
+/* on-disk size of signing xattr (not the signature itself) */
+#define BITROT_SIGNING_XATTR_SIZE_KEY "trusted.glusterfs.bit-rot.size"
+
+/* GET/SET object signature */
+#define GLUSTERFS_GET_OBJECT_SIGNATURE "trusted.glusterfs.get-signature"
+#define GLUSTERFS_SET_OBJECT_SIGNATURE "trusted.glusterfs.set-signature"
+
+/* operation needs to be durable on-disk */
+#define GLUSTERFS_DURABLE_OP "trusted.glusterfs.durable-op"
+
+/* key for version exchange b/w bitrot stub and changelog */
+#define GLUSTERFS_VERSION_XCHG_KEY "glusterfs.version.xchg"
+
+#define GLUSTERFS_INTERNAL_FOP_KEY "glusterfs-internal-fop"
+
+#define GF_ENFORCE_MANDATORY_LOCK "trusted.glusterfs.enforce-mandatory-lock"
+
+/* GlusterFS Internal FOP Indicator flags
+ * (To pass information on the context in which a paritcular
+ * fop is performed between translators)
+ * The presence of a particular flag must be treated as an
+ * indicator of the context, however the flag is added only in
+ * a scenario where there is a need for such context across translators.
+ * So it cannot be an absolute information on context.
+ */
+#define GF_INTERNAL_CTX_KEY "glusterfs.internal-ctx"
+
+/*
+ * Always append entries to end of the enum, do not delete entries.
+ * Currently dict_set_flag allows to set up to 256 flag, if the enum
+ * needs to grow beyond this dict_set_flag has to be changed accordingly
+ */
+enum gf_internal_fop_indicator {
+ GF_DHT_HEAL_DIR /* Index 0 in bit array*/
+};
+
+/* Todo:
+ * Add GF_FOP_LINK_FILE 0x2ULL
+ * address GLUSTERFS_MARKER_DONT_ACCOUNT_KEY and
+ * GLUSTERFS_INTERNAL_FOP_KEY with this flag
+ */
+
+#define DHT_CHANGELOG_RENAME_OP_KEY "changelog.rename-op"
+
+#define GLUSTERFS_WRITE_IS_APPEND "glusterfs.write-is-append"
+#define GLUSTERFS_WRITE_UPDATE_ATOMIC "glusterfs.write-update-atomic"
+#define GLUSTERFS_OPEN_FD_COUNT "glusterfs.open-fd-count"
+#define GLUSTERFS_ACTIVE_FD_COUNT "glusterfs.open-active-fd-count"
+#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 GLUSTERFS_INODELK_DOM_COUNT "glusterfs.inodelk-dom-count"
+#define GLUSTERFS_INODELK_DOM_PREFIX "glusterfs.inodelk-dom-prefix"
+#define GLUSTERFS_MULTIPLE_DOM_LK_CNT_REQUESTS "glusterfs.multi-dom-lk-cnt-req"
+#define GFID_TO_PATH_KEY "glusterfs.gfid2path"
+#define GF_XATTR_STIME_PATTERN "trusted.glusterfs.*.stime"
+#define GF_XATTR_XTIME_PATTERN "trusted.glusterfs.*.xtime"
+#define GF_XATTR_TRIGGER_SYNC "glusterfs.geo-rep.trigger-sync"
+
+/* quota xattrs */
+#define QUOTA_SIZE_KEY "trusted.glusterfs.quota.size"
+#define QUOTA_LIMIT_KEY "trusted.glusterfs.quota.limit-set"
+#define QUOTA_LIMIT_OBJECTS_KEY "trusted.glusterfs.quota.limit-objects"
+#define VIRTUAL_QUOTA_XATTR_CLEANUP_KEY "glusterfs.quota-xattr-cleanup"
+#define QUOTA_READ_ONLY_KEY "trusted.glusterfs.quota.read-only"
+
+/* ctime related */
+#define CTIME_MDATA_XDATA_KEY "set-ctime-mdata"
+
+/* afr related */
+#define AFR_XATTR_PREFIX "trusted.afr"
+
+/* Index xlator related */
+#define GF_XATTROP_INDEX_GFID "glusterfs.xattrop_index_gfid"
+#define GF_XATTROP_ENTRY_CHANGES_GFID "glusterfs.xattrop_entry_changes_gfid"
+#define GF_XATTROP_INDEX_COUNT "glusterfs.xattrop_index_count"
+#define GF_XATTROP_DIRTY_GFID "glusterfs.xattrop_dirty_gfid"
+#define GF_XATTROP_DIRTY_COUNT "glusterfs.xattrop_dirty_count"
+#define GF_XATTROP_ENTRY_IN_KEY "glusterfs.xattrop-entry-create"
+#define GF_XATTROP_ENTRY_OUT_KEY "glusterfs.xattrop-entry-delete"
+#define GF_INDEX_IA_TYPE_GET_REQ "glusterfs.index-ia-type-get-req"
+#define GF_INDEX_IA_TYPE_GET_RSP "glusterfs.index-ia-type-get-rsp"
+
+#define GF_HEAL_INFO "glusterfs.heal-info"
+#define GF_AFR_HEAL_SBRAIN "glusterfs.heal-sbrain"
+#define GF_AFR_SBRAIN_STATUS "replica.split-brain-status"
+#define GF_AFR_SBRAIN_CHOICE "replica.split-brain-choice"
+#define GF_AFR_SPB_CHOICE_TIMEOUT "replica.split-brain-choice-timeout"
+#define GF_AFR_SBRAIN_RESOLVE "replica.split-brain-heal-finalize"
+#define GF_AFR_ADD_BRICK "trusted.add-brick"
+#define GF_AFR_REPLACE_BRICK "trusted.replace-brick"
+#define GF_AFR_DIRTY "trusted.afr.dirty"
+#define GF_XATTROP_ENTRY_OUT "glusterfs.xattrop-entry-delete"
+#define GF_XATTROP_PURGE_INDEX "glusterfs.xattrop-purge-index"
+
+#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 GLUSTERFS_MARKER_DONT_ACCOUNT_KEY "glusters.marker.dont-account"
+#define GLUSTERFS_RDMA_INLINE_THRESHOLD (2048)
+#define GLUSTERFS_RDMA_MAX_HEADER_SIZE \
+ (228) /* (sizeof (rdma_header_t) \
+ + RDMA_MAX_SEGMENTS \
+ * sizeof (rdma_read_chunk_t)) \
+ */
+
+#define GLUSTERFS_RPC_REPLY_SIZE 24
+
+#define STARTING_EVENT_THREADS 2
+
+#define DEFAULT_VAR_RUN_DIRECTORY DATADIR "/run/gluster"
+#define DEFAULT_GLUSTERFSD_MISC_DIRETORY DATADIR "/lib/misc/glusterfsd"
+#ifdef GF_LINUX_HOST_OS
+#define GLUSTERD_DEFAULT_WORKDIR DATADIR "/lib/glusterd"
+#else
+#define GLUSTERD_DEFAULT_WORKDIR DATADIR "/db/glusterd"
+#endif
+#define GF_REPLICATE_TRASH_DIR ".landfill"
+
+/* GlusterFS's maximum supported Auxiliary GIDs */
+#define GF_MAX_AUX_GROUPS 65535
+
+#define GF_UUID_BUF_SIZE 37 /* UUID_CANONICAL_FORM_LEN + NULL */
+#define GF_UUID_BNAME_BUF_SIZE (320) /* (64 + 256) */
+
+#define GF_REBALANCE_TID_KEY "rebalance-id"
+#define GF_REMOVE_BRICK_TID_KEY "remove-brick-id"
+#define GF_TIER_TID_KEY "tier-id"
+#define GF_TIER_ENABLED "tier-enabled"
+
+#define UUID_CANONICAL_FORM_LEN 36
+
+/* Adding this here instead of any glusterd*.h files as it is also required by
+ * cli
+ */
+#define DEFAULT_GLUSTERD_SOCKFILE DATADIR "/run/glusterd.socket"
+
+/* features/marker-quota also needs to have knowledge of link-files so as to
+ * exclude them from accounting.
+ */
+#define DHT_LINKFILE_MODE (S_ISVTX)
+
+#define IS_DHT_LINKFILE_MODE(iabuf) \
+ ((st_mode_from_ia((iabuf)->ia_prot, (iabuf)->ia_type) & ~S_IFMT) == \
+ DHT_LINKFILE_MODE)
+#define DHT_LINKFILE_STR "linkto"
+#define DHT_COMMITHASH_STR "commithash"
+
+#define DHT_SKIP_NON_LINKTO_UNLINK "unlink-only-if-dht-linkto-file"
+#define TIER_SKIP_NON_LINKTO_UNLINK "unlink-only-if-tier-linkto-file"
+#define DHT_SKIP_OPEN_FD_UNLINK "dont-unlink-for-open-fd"
+#define DHT_IATT_IN_XDATA_KEY "dht-get-iatt-in-xattr"
+#define DHT_MODE_IN_XDATA_KEY "dht-get-mode-in-xattr"
+#define GET_LINK_COUNT "get-link-count"
+#define GF_GET_SIZE "get-size"
+#define GF_PRESTAT "virt-gf-prestat"
+#define GF_POSTSTAT "virt-gf-poststat"
+
+/*CTR and Marker requires inode dentry link count from posix*/
+#define GF_RESPONSE_LINK_COUNT_XDATA "gf_response_link_count"
+#define GF_REQUEST_LINK_COUNT_XDATA "gf_request_link_count"
+
+#define GF_GET_FILE_BLOCK_COUNT "gf_get_file_block_count"
+
+#define CTR_ATTACH_TIER_LOOKUP "ctr_attach_tier_lookup"
+
+#define CLIENT_CMD_CONNECT "trusted.glusterfs.client-connect"
+#define CLIENT_CMD_DISCONNECT "trusted.glusterfs.client-disconnect"
+
+#define GF_LOG_LRU_BUFSIZE_DEFAULT 5
+#define GF_LOG_LRU_BUFSIZE_MIN 0
+#define GF_LOG_LRU_BUFSIZE_MAX 20
+#define GF_LOG_LRU_BUFSIZE_MIN_STR "0"
+#define GF_LOG_LRU_BUFSIZE_MAX_STR "20"
+
+#define GF_LOG_FLUSH_TIMEOUT_DEFAULT 120
+#define GF_LOG_FLUSH_TIMEOUT_MIN 30
+#define GF_LOG_FLUSH_TIMEOUT_MAX 300
+#define GF_LOG_FLUSH_TIMEOUT_MIN_STR "30"
+#define GF_LOG_FLUSH_TIMEOUT_MAX_STR "300"
+#define GF_LOG_LOCALTIME_DEFAULT 0
+
+#define GF_NETWORK_TIMEOUT 42
+
+#define GF_BACKTRACE_LEN 4096
+#define GF_BACKTRACE_FRAME_COUNT 7
+
+#define GF_LK_ADVISORY 0 /* maps to GLFS_LK_ADVISORY from libgfapi*/
+#define GF_LK_MANDATORY 1 /* maps to GLFS_LK_MANDATORY from libgfapi*/
+#define GF_LOCK_MODE "glusterfs.lk.lkmode"
+
+#define GF_CHECK_XATTR_KEY_AND_GOTO(key, cmpkey, errval, lbl) \
+ do { \
+ if (key && strcmp(key, cmpkey) == 0) { \
+ errval = -EINVAL; \
+ goto lbl; \
+ } \
+ } while (0)
+
+#define GF_CS_OBJECT_SIZE "trusted.glusterfs.cs.object_size"
+#define GF_CS_BLOCK_SIZE "trusted.glusterfs.cs.block_size"
+#define GF_CS_NUM_BLOCKS "trusted.glusterfs.cs.num_blocks"
+
+#define GF_CS_XATTR_ARCHIVE_UUID "trusted.cloudsync.uuid"
+
+#define GF_CS_OBJECT_UPLOAD_COMPLETE "trusted.glusterfs.csou.complete"
+#define GF_CS_OBJECT_REMOTE "trusted.glusterfs.cs.remote"
+#define GF_CS_OBJECT_DOWNLOADING "trusted.glusterfs.cs.downloading"
+#define GF_CS_OBJECT_DOWNLOADED "trusted.glusterfs.cs.downloaded"
+#define GF_CS_OBJECT_STATUS "trusted.glusterfs.cs.status"
+#define GF_CS_OBJECT_REPAIR "trusted.glusterfs.cs.repair"
+
+#define gf_boolean_t bool
+#define _gf_false false
+#define _gf_true true
+
+typedef enum {
+ GF_CS_LOCAL = 1,
+ GF_CS_REMOTE = 2,
+ GF_CS_REPAIR = 4,
+ GF_CS_DOWNLOADING = 8,
+ GF_CS_ERROR = 16,
+} gf_cs_obj_state;
+
+typedef enum {
+ GF_FOP_PRI_UNSPEC = -1, /* Priority not specified */
+ GF_FOP_PRI_HI = 0, /* low latency */
+ GF_FOP_PRI_NORMAL, /* normal */
+ GF_FOP_PRI_LO, /* bulk */
+ GF_FOP_PRI_LEAST, /* least */
+ GF_FOP_PRI_MAX, /* Highest */
+} gf_fop_pri_t;
+
+typedef enum {
+ /* The 'component' (xlator / option) is not yet setting the flag */
+ GF_UNCLASSIFIED = 0,
+ /* The 'component' is experimental, should not be recommened
+ in production mode */
+ GF_EXPERIMENTAL,
+ /* The 'component' is tech preview, ie, it is 'mostly' working as
+ expected, but can have some of the corner cases, which is not
+ handled. */
+ GF_TECH_PREVIEW,
+ /* The 'component' is good to run. Has good enough test and
+ documentation coverage. */
+ GF_MAINTAINED,
+ /* The component is:
+ - no more a focus
+ - no more solving a valid use case
+ - no more maintained, no volunteers to maintain
+ - there is 'maintained' or 'tech-preview' feature,
+ which does the same thing, better.
+ */
+ GF_DEPRECATED,
+ /* The 'component' is no more 'built'. */
+ GF_OBSOLETE,
+ /* The 'component' exist for Documentation purposes.
+ No real usecase */
+ GF_DOCUMENT_PURPOSE,
+} gf_category_t;
+
+static const char *const FOP_PRI_STRINGS[] = {"HIGH", "NORMAL", "LOW", "LEAST"};
+
+static inline const char *
+fop_pri_to_string(gf_fop_pri_t pri)
+{
+ if (IS_ERROR(pri))
+ return "UNSPEC";
+
+ if (pri >= GF_FOP_PRI_MAX)
+ return "INVALID";
+
+ return FOP_PRI_STRINGS[pri];
+}
+
+const char *
+fop_enum_to_pri_string(glusterfs_fop_t fop);
+
+#define GF_SET_IF_NOT_PRESENT 0x1 /* default behaviour */
+#define GF_SET_OVERWRITE 0x2 /* Overwrite with the buf given */
+#define GF_SET_DIR_ONLY 0x4
+#define GF_SET_EPOCH_TIME 0x8 /* used by afr dir lookup selfheal */
+#define GF_AUXILLARY_PARGFID 0xd /* RIO dummy parent gfid */
+
+/* key value which quick read uses to get small files in lookup cbk */
+#define GF_CONTENT_KEY "glusterfs.content"
+
+struct _xlator_cmdline_option {
+ struct list_head cmd_args;
+ char *volume;
+ char *key;
+ char *value;
+};
+typedef struct _xlator_cmdline_option xlator_cmdline_option_t;
+
+struct _server_cmdline {
+ struct list_head list;
+ char *volfile_server;
+ char *transport;
+ int port;
+};
+typedef struct _server_cmdline server_cmdline_t;
+
+#define GF_OPTION_ENABLE _gf_true
+#define GF_OPTION_DISABLE _gf_false
+#define GF_OPTION_DEFERRED 2
+
+typedef enum { _gf_none, _gf_memcheck, _gf_drd } gf_valgrind_tool;
+
+struct _cmd_args {
+ /* basic options */
+ char *volfile_server;
+ server_cmdline_t *curr_server;
+ /* List of backup volfile servers, including original */
+ struct list_head volfile_servers;
+ char *volfile;
+ char *log_server;
+ gf_loglevel_t log_level;
+ char *log_file;
+ char *log_ident;
+ gf_log_logger_t logger;
+ gf_log_format_t log_format;
+ uint32_t log_buf_size;
+ uint32_t log_flush_timeout;
+ int32_t max_connect_attempts;
+ char *print_exports;
+ char *print_netgroups;
+ int print_xlatordir;
+ int print_statedumpdir;
+ int print_logdir;
+ int print_libexecdir;
+ /* advanced options */
+ uint32_t volfile_server_port;
+ char *volfile_server_transport;
+ uint32_t log_server_port;
+ char *pid_file;
+ char *sock_file;
+ int no_daemon_mode;
+ char *run_id;
+ int debug_mode;
+ int read_only;
+ int acl;
+ int selinux;
+ int capability;
+ int enable_ino32;
+ int worm;
+ int mac_compat;
+ int fopen_keep_cache;
+ int gid_timeout;
+ char gid_timeout_set;
+ int aux_gfid_mount;
+
+ /* need a process wide timer-wheel? */
+ int global_timer_wheel;
+
+ /* list of xlator_option_t */
+ struct list_head xlator_options;
+
+ /* fuse options */
+ int fuse_direct_io_mode;
+ char *use_readdirp;
+ int no_root_squash;
+ int volfile_check;
+ double fuse_entry_timeout;
+ double fuse_negative_timeout;
+ double fuse_attribute_timeout;
+ char *volume_name;
+ int fuse_nodev;
+ int fuse_nosuid;
+ char *dump_fuse;
+ pid_t client_pid;
+ int client_pid_set;
+ unsigned uid_map_root;
+ int32_t lru_limit;
+ int32_t invalidate_limit;
+ int background_qlen;
+ int congestion_threshold;
+ char *fuse_mountopts;
+ int mem_acct;
+ int resolve_gids;
+
+ /* key args */
+ char *mount_point;
+ char *volfile_id;
+
+ /* required for portmap */
+ int brick_port;
+ char *brick_name;
+ int brick_port2;
+
+ /* Should management connections use SSL? */
+ int secure_mgmt;
+
+ /* Linux-only OOM killer adjustment */
+#ifdef GF_LINUX_HOST_OS
+ char *oom_score_adj;
+#endif
+
+ /* Run this process with valgrind? Might want to prevent calling
+ * functions that prevent valgrind from working correctly, like
+ * dlclose(). */
+ gf_valgrind_tool vgtool;
+
+ int localtime_logging;
+
+ /* For the subdir mount */
+ char *subdir_mount;
+
+ char *process_name;
+ char *event_history;
+ int thin_client;
+ uint32_t reader_thread_count;
+
+ /* FUSE writeback cache support */
+ int kernel_writeback_cache;
+ uint32_t attr_times_granularity;
+
+ int fuse_flush_handle_interrupt;
+ int fuse_auto_inval;
+
+ bool global_threading;
+ bool brick_mux;
+
+ uint32_t fuse_dev_eperm_ratelimit_ns;
+};
+typedef struct _cmd_args cmd_args_t;
+
+struct _glusterfs_graph {
+ struct list_head list;
+ struct timeval dob;
+ void *first;
+ void *top; /* selected by -n */
+ int xl_count;
+ int id; /* Used in logging */
+ int used; /* Should be set when fuse gets
+ first CHILD_UP */
+ uint32_t volfile_checksum;
+ uint32_t leaf_count;
+ void *last_xl; /* Stores the last xl of the graph, as of now only populated
+ in client multiplexed code path */
+ pthread_mutex_t mutex;
+ pthread_cond_t child_down_cond; /* for broadcasting CHILD_DOWN */
+ int parent_down;
+ char graph_uuid[128];
+ char volume_id[GF_UUID_BUF_SIZE];
+};
+typedef struct _glusterfs_graph glusterfs_graph_t;
+
+typedef int32_t (*glusterfsd_mgmt_event_notify_fn_t)(int32_t event, void *data,
+ ...);
+
+typedef enum {
+ MGMT_SSL_NEVER = 0,
+ MGMT_SSL_COPY_IO,
+ MGMT_SSL_ALWAYS
+} mgmt_ssl_t;
+
+struct tvec_base;
+
+/* reference counting for the global (per ctx) timer-wheel */
+struct gf_ctx_tw {
+ GF_REF_DECL;
+ struct tvec_base *timer_wheel; /* global timer-wheel instance */
+};
+
+struct _glusterfs_ctx {
+ cmd_args_t cmd_args;
+ char *process_uuid;
+ FILE *pidfp;
+ char fin;
+ void *timer;
+ void *ib;
+ struct call_pool *pool;
+ void *event_pool;
+ void *iobuf_pool;
+ void *logbuf_pool;
+ gf_lock_t lock;
+ size_t page_size;
+
+ /* one per volfile parse */
+ struct list_head graphs;
+
+ /* the latest graph in use */
+ glusterfs_graph_t *active;
+
+ /* fuse or nfs (but not protocol/server) */
+ void *master;
+
+ /* xlator implementing MOPs for centralized logging, volfile server */
+ void *mgmt;
+
+ /* listener of the commands from glusterd */
+ void *listener;
+
+ /* toggle switch for latency measurement */
+ unsigned char measure_latency;
+ pthread_t sigwaiter;
+ char *cmdlinestr;
+ struct mem_pool *stub_mem_pool;
+ unsigned char cleanup_started;
+ 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;
+
+ glusterfsd_mgmt_event_notify_fn_t notify; /* Used for xlators to make
+ call to fsd-mgmt */
+ gf_log_handle_t log; /* all logging related variables */
+
+ int mem_acct_enable;
+
+ int daemon_pipe[2];
+
+ struct clienttable *clienttable;
+
+ /*
+ * Should management connections use SSL? This is the only place we
+ * can put it where both daemon-startup and socket code will see it.
+ *
+ * Why is it an int? Because we're included before common-utils.h,
+ * which defines gf_boolean_t (what we really want). It doesn't make
+ * any sense, but it's not worth turning the codebase upside-down to
+ * fix it. Thus, an int.
+ */
+ int secure_mgmt;
+
+ /* The option is use to set cert_depth while management connection
+ use SSL
+ */
+ int ssl_cert_depth;
+
+ /*
+ * Should *our* server/inbound connections use SSL? This is only true
+ * if we're glusterd and secure_mgmt is set, or if we're glusterfsd
+ * and SSL is set on the I/O path. It should never be set e.g. for
+ * NFS.
+ */
+ mgmt_ssl_t secure_srvr;
+ /* Buffer to 'save' backtrace even under OOM-kill like situations*/
+ char btbuf[GF_BACKTRACE_LEN];
+
+ pthread_mutex_t notify_lock;
+ pthread_mutex_t cleanup_lock;
+ pthread_cond_t notify_cond;
+ int notifying;
+
+ struct gf_ctx_tw *tw; /* refcounted timer_wheel */
+
+ gf_lock_t volfile_lock;
+
+ /* configuration related elements, which gets changed
+ from global xlator */
+ struct {
+ char *metrics_dumppath;
+ } config;
+
+ struct {
+ gf_atomic_t max_dict_pairs;
+ gf_atomic_t total_pairs_used;
+ gf_atomic_t total_dicts_used;
+ } stats;
+
+ struct list_head volfile_list;
+ /* Add members to manage janitor threads for cleanup fd */
+ struct list_head janitor_fds;
+ pthread_cond_t fd_cond;
+ pthread_mutex_t fd_lock;
+ pthread_t janitor;
+ /* The variable is use to save total posix xlator count */
+ uint32_t pxl_count;
+
+ char volume_id[GF_UUID_BUF_SIZE]; /* Used only in protocol/client */
+};
+typedef struct _glusterfs_ctx glusterfs_ctx_t;
+
+typedef struct {
+ char volfile_checksum[SHA256_DIGEST_LENGTH];
+ char vol_id[NAME_MAX + 1];
+ struct list_head volfile_list;
+ glusterfs_graph_t *graph;
+ FILE *pidfp;
+} gf_volfile_t;
+
+glusterfs_ctx_t *
+glusterfs_ctx_new(void);
+
+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;
+};
+
+typedef struct lock_migration_info {
+ struct list_head list;
+ struct gf_flock flock;
+ char *client_uid;
+ uint32_t lk_flags;
+} lock_migration_info_t;
+
+#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))
+
+/*
+ * If present, this has the following effects:
+ *
+ * glusterd enables privileged commands over TCP
+ *
+ * all code enables SSL for outbound connections to management port
+ *
+ * glusterd enables SSL for inbound connections
+ *
+ * Servers and clients enable/disable SSL among themselves by other means.
+ * Making secure management connections conditional on a file is a bit of a
+ * hack, but we don't have any other place for such global settings across
+ * all of the affected components. Making it a compile-time option would
+ * reduce functionality, both for users and for testing (which can now be
+ * done using secure connections for all tests without change elsewhere).
+ *
+ */
+#define SECURE_ACCESS_FILE GLUSTERD_DEFAULT_WORKDIR "/secure-access"
+
+int
+glusterfs_graph_prepare(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx,
+ char *volume_name);
+int
+glusterfs_graph_destroy_residual(glusterfs_graph_t *graph);
+int
+glusterfs_graph_deactivate(glusterfs_graph_t *graph);
+int
+glusterfs_graph_destroy(glusterfs_graph_t *graph);
+int
+glusterfs_get_leaf_count(glusterfs_graph_t *graph);
+int
+glusterfs_graph_activate(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx);
+glusterfs_graph_t *
+glusterfs_graph_construct(FILE *fp);
+int
+glusterfs_graph_init(glusterfs_graph_t *graph);
+glusterfs_graph_t *
+glusterfs_graph_new(void);
+int
+glusterfs_graph_reconfigure(glusterfs_graph_t *oldgraph,
+ glusterfs_graph_t *newgraph);
+int
+glusterfs_graph_attach(glusterfs_graph_t *orig_graph, char *path,
+ glusterfs_graph_t **newgraph);
+int
+glusterfs_graph_parent_up(glusterfs_graph_t *graph);
+
+void
+gf_free_mig_locks(lock_migration_info_t *locks);
+
+int
+glusterfs_read_secure_access_file(void);
+int
+glusterfs_graph_fini(glusterfs_graph_t *graph);
+#endif /* _GLUSTERFS_H */
diff --git a/libglusterfs/src/graph-utils.h b/libglusterfs/src/glusterfs/graph-utils.h
index 207664fdb1f..247f1a55d5a 100644
--- a/libglusterfs/src/graph-utils.h
+++ b/libglusterfs/src/glusterfs/graph-utils.h
@@ -11,10 +11,10 @@
#ifndef _GRAPH_H_
#define _GRAPH_H_
-int glusterfs_graph_print_file (FILE *file, glusterfs_graph_t *graph);
-
-char *glusterfs_graph_print_buf (glusterfs_graph_t *graph);
-
-int glusterfs_xlator_link (xlator_t *pxl, xlator_t *cxl);
-void glusterfs_graph_set_first (glusterfs_graph_t *graph, xlator_t *xl);
+int
+glusterfs_graph_print_file(FILE *file, glusterfs_graph_t *graph);
+int
+glusterfs_xlator_link(xlator_t *pxl, xlator_t *cxl);
+void
+glusterfs_graph_set_first(glusterfs_graph_t *graph, xlator_t *xl);
#endif
diff --git a/libglusterfs/src/hashfn.h b/libglusterfs/src/glusterfs/hashfn.h
index fed464e11cd..6e92e706d8c 100644
--- a/libglusterfs/src/hashfn.h
+++ b/libglusterfs/src/glusterfs/hashfn.h
@@ -14,9 +14,10 @@
#include <sys/types.h>
#include <stdint.h>
-uint32_t SuperFastHash (const char * data, int32_t len);
+uint32_t
+SuperFastHash(const char *data, int32_t len);
-uint32_t gf_dm_hashfn (const char *msg, int len);
+uint32_t
+gf_dm_hashfn(const char *msg, int len);
-uint32_t ReallySimpleHash (char *path, int len);
#endif /* __HASHFN_H__ */
diff --git a/libglusterfs/src/glusterfs/iatt.h b/libglusterfs/src/glusterfs/iatt.h
new file mode 100644
index 00000000000..f03d68b02f0
--- /dev/null
+++ b/libglusterfs/src/glusterfs/iatt.h
@@ -0,0 +1,489 @@
+/*
+ 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 _IATT_H
+#define _IATT_H
+
+#if defined(GF_LINUX_HOST_OS)
+#include <sys/sysmacros.h> /* for makedev(3), major(3), minor(3) */
+#endif
+#include <sys/types.h>
+#include <sys/stat.h> /* for iatt <--> stat conversions */
+#include <unistd.h>
+
+#include "glusterfs/compat.h"
+#include "glusterfs/compat-uuid.h"
+
+typedef enum {
+ IA_INVAL = 0,
+ IA_IFREG,
+ IA_IFDIR,
+ IA_IFLNK,
+ IA_IFBLK,
+ IA_IFCHR,
+ IA_IFIFO,
+ IA_IFSOCK
+} ia_type_t;
+
+typedef struct {
+ uint8_t suid : 1;
+ uint8_t sgid : 1;
+ uint8_t sticky : 1;
+ struct {
+ uint8_t read : 1;
+ uint8_t write : 1;
+ uint8_t exec : 1;
+ } owner, group, other;
+} ia_prot_t;
+
+struct iatt {
+ uint64_t ia_flags;
+ uint64_t ia_ino; /* inode number */
+ uint64_t ia_dev; /* backing device ID */
+ uint64_t ia_rdev; /* device ID (if special file) */
+ uint64_t ia_size; /* file size in bytes */
+ uint32_t ia_nlink; /* Link count */
+ uint32_t ia_uid; /* user ID of owner */
+ uint32_t ia_gid; /* group ID of owner */
+ uint32_t ia_blksize; /* blocksize for filesystem I/O */
+ uint64_t ia_blocks; /* number of 512B blocks allocated */
+ int64_t ia_atime; /* last access time */
+ int64_t ia_mtime; /* last modification time */
+ int64_t ia_ctime; /* last status change time */
+ int64_t ia_btime; /* creation time. Fill using statx */
+ uint32_t ia_atime_nsec;
+ uint32_t ia_mtime_nsec;
+ uint32_t ia_ctime_nsec;
+ uint32_t ia_btime_nsec;
+ uint64_t ia_attributes; /* chattr related:compressed, immutable,
+ * append only, encrypted etc.*/
+ uint64_t ia_attributes_mask; /* Mask for the attributes */
+
+ uuid_t ia_gfid;
+ ia_type_t ia_type; /* type of file */
+ ia_prot_t ia_prot; /* protection */
+};
+
+struct old_iatt {
+ uint64_t ia_ino; /* inode number */
+ uuid_t ia_gfid;
+ uint64_t ia_dev; /* backing device ID */
+ ia_type_t ia_type; /* type of file */
+ ia_prot_t ia_prot; /* protection */
+ uint32_t ia_nlink; /* Link count */
+ uint32_t ia_uid; /* user ID of owner */
+ uint32_t ia_gid; /* group ID of owner */
+ uint64_t ia_rdev; /* device ID (if special file) */
+ uint64_t ia_size; /* file size in bytes */
+ uint32_t ia_blksize; /* blocksize for filesystem I/O */
+ uint64_t ia_blocks; /* number of 512B blocks allocated */
+ uint32_t ia_atime; /* last access time */
+ uint32_t ia_atime_nsec;
+ uint32_t ia_mtime; /* last modification time */
+ uint32_t ia_mtime_nsec;
+ uint32_t ia_ctime; /* last status change time */
+ uint32_t ia_ctime_nsec;
+};
+
+struct mdata_iatt {
+ int64_t ia_atime; /* last access time */
+ int64_t ia_mtime; /* last modification time */
+ int64_t ia_ctime; /* last status change time */
+ uint32_t ia_atime_nsec;
+ uint32_t ia_mtime_nsec;
+ uint32_t ia_ctime_nsec;
+};
+
+/* 64-bit mask for valid members in struct iatt. */
+#define IATT_TYPE 0x0000000000000001U
+#define IATT_MODE 0x0000000000000002U
+#define IATT_NLINK 0x0000000000000004U
+#define IATT_UID 0x0000000000000008U
+#define IATT_GID 0x0000000000000010U
+#define IATT_ATIME 0x0000000000000020U
+#define IATT_MTIME 0x0000000000000040U
+#define IATT_CTIME 0x0000000000000080U
+#define IATT_INO 0x0000000000000100U
+#define IATT_SIZE 0x0000000000000200U
+#define IATT_BLOCKS 0x0000000000000400U
+#define IATT_BTIME 0x0000000000000800U
+#define IATT_GFID 0x0000000000001000U
+
+/* Macros for checking validity of struct iatt members.*/
+#define IATT_TYPE_VALID(iaflags) (iaflags & IATT_TYPE)
+#define IATT_MODE_VALID(iaflags) (iaflags & IATT_MODE)
+#define IATT_NLINK_VALID(iaflags) (iaflags & IATT_NLINK)
+#define IATT_UID_VALID(iaflags) (iaflags & IATT_UID)
+#define IATT_GID_VALID(iaflags) (iaflags & IATT_GID)
+#define IATT_ATIME_VALID(iaflags) (iaflags & IATT_ATIME)
+#define IATT_MTIME_VALID(iaflags) (iaflags & IATT_MTIME)
+#define IATT_CTIME_VALID(iaflags) (iaflags & IATT_CTIME)
+#define IATT_INO_VALID(iaflags) (iaflags & IATT_INO)
+#define IATT_SIZE_VALID(iaflags) (iaflags & IATT_SIZE)
+#define IATT_BLOCKS_VALID(iaflags) (iaflags & IATT_BLOCKS)
+#define IATT_BTIME_VALID(iaflags) (iaflags & IATT_BTIME)
+#define IATT_GFID_VALID(iaflags) (iaflags & IATT_GFID)
+
+#define IA_ISREG(t) (t == IA_IFREG)
+#define IA_ISDIR(t) (t == IA_IFDIR)
+#define IA_ISLNK(t) (t == IA_IFLNK)
+#define IA_ISBLK(t) (t == IA_IFBLK)
+#define IA_ISCHR(t) (t == IA_IFCHR)
+#define IA_ISFIFO(t) (t == IA_IFIFO)
+#define IA_ISSOCK(t) (t == IA_IFSOCK)
+#define IA_ISINVAL(t) (t == IA_INVAL)
+
+#define IA_PROT_RUSR(prot) ((prot).owner.read == 1)
+#define IA_PROT_WUSR(prot) ((prot).owner.write == 1)
+#define IA_PROT_XUSR(prot) ((prot).owner.exec == 1)
+
+#define IA_PROT_RGRP(prot) ((prot).group.read == 1)
+#define IA_PROT_WGRP(prot) ((prot).group.write == 1)
+#define IA_PROT_XGRP(prot) ((prot).group.exec == 1)
+
+#define IA_PROT_ROTH(prot) ((prot).other.read == 1)
+#define IA_PROT_WOTH(prot) ((prot).other.write == 1)
+#define IA_PROT_XOTH(prot) ((prot).other.exec == 1)
+
+#define IA_PROT_SUID(prot) ((prot).suid == 1)
+#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)
+{
+ return (uint32_t)(ia_dev >> 32);
+}
+
+static inline uint32_t
+ia_minor(uint64_t ia_dev)
+{
+ return (uint32_t)(ia_dev & 0xffffffff);
+}
+
+static inline uint64_t
+ia_makedev(uint32_t ia_maj, uint32_t ia_min)
+{
+ return ((((uint64_t)ia_maj) << 32) | ia_min);
+}
+
+static inline ia_prot_t
+ia_prot_from_st_mode(mode_t mode)
+{
+ ia_prot_t ia_prot = {
+ 0,
+ };
+
+ if (mode & S_ISUID)
+ ia_prot.suid = 1;
+ if (mode & S_ISGID)
+ ia_prot.sgid = 1;
+ if (mode & S_ISVTX)
+ ia_prot.sticky = 1;
+
+ if (mode & S_IRUSR)
+ ia_prot.owner.read = 1;
+ if (mode & S_IWUSR)
+ ia_prot.owner.write = 1;
+ if (mode & S_IXUSR)
+ ia_prot.owner.exec = 1;
+
+ if (mode & S_IRGRP)
+ ia_prot.group.read = 1;
+ if (mode & S_IWGRP)
+ ia_prot.group.write = 1;
+ if (mode & S_IXGRP)
+ ia_prot.group.exec = 1;
+
+ if (mode & S_IROTH)
+ ia_prot.other.read = 1;
+ if (mode & S_IWOTH)
+ ia_prot.other.write = 1;
+ if (mode & S_IXOTH)
+ ia_prot.other.exec = 1;
+
+ return ia_prot;
+}
+
+static inline ia_type_t
+ia_type_from_st_mode(mode_t mode)
+{
+ ia_type_t type = IA_INVAL;
+
+ if (S_ISREG(mode))
+ type = IA_IFREG;
+ if (S_ISDIR(mode))
+ type = IA_IFDIR;
+ if (S_ISLNK(mode))
+ type = IA_IFLNK;
+ if (S_ISBLK(mode))
+ type = IA_IFBLK;
+ if (S_ISCHR(mode))
+ type = IA_IFCHR;
+ if (S_ISFIFO(mode))
+ type = IA_IFIFO;
+ if (S_ISSOCK(mode))
+ type = IA_IFSOCK;
+
+ return type;
+}
+
+static inline uint32_t
+st_mode_prot_from_ia(ia_prot_t prot)
+{
+ uint32_t prot_bit = 0;
+
+ if (prot.suid)
+ prot_bit |= S_ISUID;
+ if (prot.sgid)
+ prot_bit |= S_ISGID;
+ if (prot.sticky)
+ prot_bit |= S_ISVTX;
+
+ if (prot.owner.read)
+ prot_bit |= S_IRUSR;
+ if (prot.owner.write)
+ prot_bit |= S_IWUSR;
+ if (prot.owner.exec)
+ prot_bit |= S_IXUSR;
+
+ if (prot.group.read)
+ prot_bit |= S_IRGRP;
+ if (prot.group.write)
+ prot_bit |= S_IWGRP;
+ if (prot.group.exec)
+ prot_bit |= S_IXGRP;
+
+ if (prot.other.read)
+ prot_bit |= S_IROTH;
+ if (prot.other.write)
+ prot_bit |= S_IWOTH;
+ if (prot.other.exec)
+ prot_bit |= S_IXOTH;
+
+ return prot_bit;
+}
+
+static inline uint32_t
+st_mode_type_from_ia(ia_type_t type)
+{
+ uint32_t type_bit = 0;
+
+ switch (type) {
+ case IA_IFREG:
+ type_bit = S_IFREG;
+ break;
+ case IA_IFDIR:
+ type_bit = S_IFDIR;
+ break;
+ case IA_IFLNK:
+ type_bit = S_IFLNK;
+ break;
+ case IA_IFBLK:
+ type_bit = S_IFBLK;
+ break;
+ case IA_IFCHR:
+ type_bit = S_IFCHR;
+ break;
+ case IA_IFIFO:
+ type_bit = S_IFIFO;
+ break;
+ case IA_IFSOCK:
+ type_bit = S_IFSOCK;
+ break;
+ case IA_INVAL:
+ break;
+ }
+
+ return type_bit;
+}
+
+static inline mode_t
+st_mode_from_ia(ia_prot_t prot, ia_type_t type)
+{
+ mode_t st_mode = 0;
+ uint32_t type_bit = 0;
+ uint32_t prot_bit = 0;
+
+ type_bit = st_mode_type_from_ia(type);
+ prot_bit = st_mode_prot_from_ia(prot);
+
+ st_mode = (type_bit | prot_bit);
+
+ return st_mode;
+}
+
+static inline void
+iatt_to_mdata(struct mdata_iatt *mdata, struct iatt *iatt)
+{
+ mdata->ia_atime = iatt->ia_atime;
+ mdata->ia_atime_nsec = iatt->ia_atime_nsec;
+ mdata->ia_mtime = iatt->ia_mtime;
+ mdata->ia_mtime_nsec = iatt->ia_mtime_nsec;
+ mdata->ia_ctime = iatt->ia_ctime;
+ mdata->ia_ctime_nsec = iatt->ia_ctime_nsec;
+}
+
+static inline int
+iatt_from_stat(struct iatt *iatt, struct stat *stat)
+{
+ iatt->ia_dev = stat->st_dev;
+ iatt->ia_ino = stat->st_ino;
+
+ iatt->ia_type = ia_type_from_st_mode(stat->st_mode);
+ iatt->ia_prot = ia_prot_from_st_mode(stat->st_mode);
+
+ iatt->ia_nlink = stat->st_nlink;
+ iatt->ia_uid = stat->st_uid;
+ iatt->ia_gid = stat->st_gid;
+
+ iatt->ia_rdev = ia_makedev(major(stat->st_rdev), minor(stat->st_rdev));
+
+ iatt->ia_size = stat->st_size;
+ 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);
+
+ iatt->ia_mtime = stat->st_mtime;
+ iatt->ia_mtime_nsec = ST_MTIM_NSEC(stat);
+
+ iatt->ia_ctime = stat->st_ctime;
+ iatt->ia_ctime_nsec = ST_CTIM_NSEC(stat);
+
+ /* Setting IATT_INO in ia_flags is done in posix_fill_ino_from_gfid. */
+ iatt->ia_flags = iatt->ia_flags | IATT_TYPE | IATT_MODE | IATT_NLINK |
+ IATT_UID | IATT_GID | IATT_SIZE | IATT_BLOCKS |
+ IATT_ATIME | IATT_MTIME | IATT_CTIME;
+
+ return 0;
+}
+
+static inline int
+iatt_to_stat(struct iatt *iatt, struct stat *stat)
+{
+ stat->st_dev = iatt->ia_dev;
+ stat->st_ino = iatt->ia_ino;
+
+ stat->st_mode = st_mode_from_ia(iatt->ia_prot, iatt->ia_type);
+
+ stat->st_nlink = iatt->ia_nlink;
+ stat->st_uid = iatt->ia_uid;
+ stat->st_gid = iatt->ia_gid;
+
+ stat->st_rdev = makedev(ia_major(iatt->ia_rdev), ia_minor(iatt->ia_rdev));
+
+ stat->st_size = iatt->ia_size;
+ stat->st_blksize = iatt->ia_blksize;
+ stat->st_blocks = iatt->ia_blocks;
+
+ stat->st_atime = iatt->ia_atime;
+ ST_ATIM_NSEC_SET(stat, iatt->ia_atime_nsec);
+
+ stat->st_mtime = iatt->ia_mtime;
+ ST_MTIM_NSEC_SET(stat, iatt->ia_mtime_nsec);
+
+ stat->st_ctime = iatt->ia_ctime;
+ ST_CTIM_NSEC_SET(stat, iatt->ia_ctime_nsec);
+
+ return 0;
+}
+
+static inline void
+oldiatt_from_iatt(struct old_iatt *o_iatt, struct iatt *c_iatt)
+{
+ o_iatt->ia_dev = c_iatt->ia_dev;
+ o_iatt->ia_ino = c_iatt->ia_ino;
+ o_iatt->ia_type = c_iatt->ia_type;
+ o_iatt->ia_prot = c_iatt->ia_prot;
+ o_iatt->ia_nlink = c_iatt->ia_nlink;
+ o_iatt->ia_uid = c_iatt->ia_uid;
+ o_iatt->ia_gid = c_iatt->ia_gid;
+ o_iatt->ia_rdev = c_iatt->ia_rdev;
+ o_iatt->ia_size = c_iatt->ia_size;
+ o_iatt->ia_blksize = c_iatt->ia_blksize;
+ o_iatt->ia_blocks = c_iatt->ia_blocks;
+ o_iatt->ia_atime = c_iatt->ia_atime;
+ o_iatt->ia_atime_nsec = c_iatt->ia_atime_nsec;
+ o_iatt->ia_mtime = c_iatt->ia_mtime;
+ o_iatt->ia_mtime_nsec = c_iatt->ia_mtime_nsec;
+ o_iatt->ia_ctime = c_iatt->ia_ctime;
+ o_iatt->ia_ctime_nsec = c_iatt->ia_ctime_nsec;
+
+ gf_uuid_copy(o_iatt->ia_gfid, c_iatt->ia_gfid);
+
+ return;
+}
+
+static inline void
+iatt_from_oldiatt(struct iatt *c_iatt, struct old_iatt *o_iatt)
+{
+ c_iatt->ia_dev = o_iatt->ia_dev;
+ c_iatt->ia_ino = o_iatt->ia_ino;
+ c_iatt->ia_type = o_iatt->ia_type;
+ c_iatt->ia_prot = o_iatt->ia_prot;
+ c_iatt->ia_nlink = o_iatt->ia_nlink;
+ c_iatt->ia_uid = o_iatt->ia_uid;
+ c_iatt->ia_gid = o_iatt->ia_gid;
+ c_iatt->ia_rdev = o_iatt->ia_rdev;
+ c_iatt->ia_size = o_iatt->ia_size;
+ c_iatt->ia_blksize = o_iatt->ia_blksize;
+ c_iatt->ia_blocks = o_iatt->ia_blocks;
+ c_iatt->ia_atime = o_iatt->ia_atime;
+ c_iatt->ia_atime_nsec = o_iatt->ia_atime_nsec;
+ c_iatt->ia_mtime = o_iatt->ia_mtime;
+ c_iatt->ia_mtime_nsec = o_iatt->ia_mtime_nsec;
+ c_iatt->ia_ctime = o_iatt->ia_ctime;
+ c_iatt->ia_ctime_nsec = o_iatt->ia_ctime_nsec;
+
+ gf_uuid_copy(c_iatt->ia_gfid, o_iatt->ia_gfid);
+
+ c_iatt->ia_attributes = 0;
+
+ c_iatt->ia_flags = IATT_TYPE | IATT_MODE | IATT_NLINK | IATT_INO |
+ IATT_UID | IATT_GID | IATT_SIZE | IATT_BLOCKS |
+ IATT_ATIME | IATT_MTIME | IATT_CTIME | IATT_GFID;
+
+ return;
+}
+
+static inline int
+is_same_mode(ia_prot_t prot1, ia_prot_t prot2)
+{
+ int ret = 0;
+
+ if (st_mode_prot_from_ia(prot1) != st_mode_prot_from_ia(prot2))
+ ret = -1;
+
+ return ret;
+}
+
+#endif /* _IATT_H */
diff --git a/libglusterfs/src/glusterfs/inode.h b/libglusterfs/src/glusterfs/inode.h
new file mode 100644
index 00000000000..4b28da510c7
--- /dev/null
+++ b/libglusterfs/src/glusterfs/inode.h
@@ -0,0 +1,306 @@
+/*
+ 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
+#define _INODE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define LOOKUP_NEEDED 1
+#define LOOKUP_NOT_NEEDED 2
+
+#define DEFAULT_INODE_MEMPOOL_ENTRIES 32 * 1024
+#define INODE_PATH_FMT "<gfid:%s>"
+struct _inode_table;
+typedef struct _inode_table inode_table_t;
+
+struct _inode;
+typedef struct _inode inode_t;
+
+struct _dentry;
+typedef struct _dentry dentry_t;
+
+#include "glusterfs/list.h"
+#include "glusterfs/iatt.h"
+#include "glusterfs/compat-uuid.h"
+#include "glusterfs/fd.h"
+
+struct _inode_table {
+ pthread_mutex_t lock;
+ size_t hashsize; /* bucket size of inode hash and dentry hash */
+ char *name; /* name of the inode table, just for gf_log() */
+ inode_t *root; /* root directory inode, with number 1 */
+ xlator_t *xl; /* xlator to be called to do purge */
+ uint32_t lru_limit; /* maximum LRU cache size */
+ struct list_head *inode_hash; /* buckets for inode hash table */
+ struct list_head *name_hash; /* buckets for dentry hash table */
+ struct list_head active; /* list of inodes currently active (in an fop) */
+ uint32_t active_size; /* count of inodes in active list */
+ struct list_head lru; /* list of inodes recently used.
+ lru.next most recent */
+ uint32_t lru_size; /* count of inodes in lru list */
+ struct list_head purge; /* list of inodes to be purged soon */
+ uint32_t purge_size; /* count of inodes in purge list */
+
+ struct mem_pool *inode_pool; /* memory pool for inodes */
+ struct mem_pool *dentry_pool; /* memory pool for dentrys */
+ struct mem_pool *fd_mem_pool; /* memory pool for fd_t */
+ int ctxcount; /* number of slots in inode->ctx */
+
+ /* This is required for 'invalidation' when 'nlookup' would be used,
+ specially in case of fuse-bridge */
+ int32_t (*invalidator_fn)(xlator_t *, inode_t *);
+ xlator_t *invalidator_xl;
+ struct list_head invalidate; /* inodes which are in invalidation queue */
+ uint32_t invalidate_size; /* count of inodes in invalidation list */
+
+ /* flag to indicate whether the cleanup of the inode
+ table started or not */
+ gf_boolean_t cleanup_started;
+};
+
+struct _dentry {
+ struct list_head inode_list; /* list of dentries of inode */
+ struct list_head hash; /* hash table pointers */
+ inode_t *inode; /* inode of this directory entry */
+ char *name; /* name of the directory entry */
+ inode_t *parent; /* directory of the entry */
+};
+
+struct _inode_ctx {
+ union {
+ uint64_t key;
+ xlator_t *xl_key;
+ };
+ /* if value1 is 0, then field is not set.. */
+ union {
+ uint64_t value1;
+ void *ptr1;
+ };
+ /* if value2 is 0, then field is not set.. */
+ union {
+ uint64_t value2;
+ void *ptr2;
+ };
+ int ref; /* This is for debugging inode ref leaks,
+ basically helps in identifying the xlator
+ causing th ref leak, it is printed in
+ statedump */
+};
+
+struct _inode {
+ inode_table_t *table; /* the table this inode belongs to */
+ uuid_t gfid;
+ gf_lock_t lock;
+ gf_atomic_t nlookup;
+ uint32_t fd_count; /* Open fd count */
+ uint32_t active_fd_count; /* Active open fd count */
+ uint32_t ref; /* reference count on this inode */
+ 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 */
+ struct list_head hash; /* hash table pointers */
+ struct list_head list; /* active/lru/purge */
+
+ struct _inode_ctx *_ctx; /* replacement for dict_t *(inode->ctx) */
+ bool in_invalidate_list; /* Set if inode is in table invalidate list */
+ bool invalidate_sent; /* Set it if invalidator_fn is called for 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(uint32_t lru_limit, xlator_t *xl);
+
+inode_table_t *
+inode_table_with_invalidator(uint32_t lru_limit, xlator_t *xl,
+ int32_t (*invalidator_fn)(xlator_t *, inode_t *),
+ xlator_t *invalidator_xl);
+
+void
+inode_table_destroy_all(glusterfs_ctx_t *ctx);
+
+void
+inode_table_destroy(inode_table_t *inode_table);
+
+inode_t *
+inode_new(inode_table_t *table);
+
+inode_t *
+inode_link(inode_t *inode, inode_t *parent, const char *name,
+ struct iatt *stbuf);
+
+void
+inode_unlink(inode_t *inode, inode_t *parent, const char *name);
+
+inode_t *
+inode_parent(inode_t *inode, uuid_t pargfid, const char *name);
+
+inode_t *
+inode_ref(inode_t *inode);
+
+inode_t *
+inode_unref(inode_t *inode);
+
+int
+inode_lookup(inode_t *inode);
+
+int
+inode_forget(inode_t *inode, uint64_t nlookup);
+int
+inode_forget_with_unref(inode_t *inode, uint64_t nlookup);
+
+int
+inode_ref_reduce_by_n(inode_t *inode, uint64_t nref);
+
+int
+inode_invalidate(inode_t *inode);
+
+int
+inode_rename(inode_table_t *table, inode_t *olddir, const char *oldname,
+ inode_t *newdir, const char *newname, inode_t *inode,
+ struct iatt *stbuf);
+
+inode_t *
+inode_grep(inode_table_t *table, inode_t *parent, const char *name);
+
+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);
+
+int
+inode_path(inode_t *inode, const char *name, char **bufp);
+
+int
+__inode_path(inode_t *inode, const char *name, char **bufp);
+
+inode_t *
+inode_from_path(inode_table_t *table, const char *path);
+
+inode_t *
+inode_resolve(inode_table_t *table, char *path);
+
+/* deal with inode ctx's both values */
+
+int
+inode_ctx_set2(inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
+int
+__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_ctx_reset2(inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
+
+/* deal with inode ctx's 1st value */
+
+int
+inode_ctx_set0(inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+int
+__inode_ctx_set0(inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+int
+inode_ctx_get0(inode_t *inode, xlator_t *xlator, uint64_t *value1);
+int
+__inode_ctx_get0(inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+int
+inode_ctx_reset0(inode_t *inode, xlator_t *xlator, uint64_t *value1);
+
+/* deal with inode ctx's 2st value */
+
+int
+inode_ctx_set1(inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+int
+__inode_ctx_set1(inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+int
+inode_ctx_get1(inode_t *inode, xlator_t *xlator, uint64_t *value2);
+int
+__inode_ctx_get1(inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+int
+inode_ctx_reset1(inode_t *inode, xlator_t *xlator, uint64_t *value2);
+
+static inline int
+__inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
+{
+ return __inode_ctx_set0(inode, this, &v);
+}
+
+static inline int
+inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
+{
+ return inode_ctx_set0(inode, this, &v);
+}
+
+#define __inode_ctx_set(i, x, v_p) __inode_ctx_set0(i, x, v_p)
+
+#define inode_ctx_set(i, x, v_p) inode_ctx_set0(i, x, v_p)
+
+#define inode_ctx_reset(i, x, v) inode_ctx_reset0(i, x, v)
+
+#define __inode_ctx_get(i, x, v) __inode_ctx_get0(i, x, v)
+
+#define inode_ctx_get(i, x, v) inode_ctx_get0(i, x, v)
+
+#define inode_ctx_del(i, x, v) inode_ctx_del2(i, x, v, 0)
+#define inode_ctx_del1(i, x, v) inode_ctx_del2(i, x, 0, v)
+
+gf_boolean_t
+__is_root_gfid(uuid_t gfid);
+
+void
+__inode_table_set_lru_limit(inode_table_t *table, uint32_t lru_limit);
+
+void
+inode_table_set_lru_limit(inode_table_t *table, uint32_t lru_limit);
+
+void
+inode_ctx_merge(fd_t *fd, inode_t *inode, inode_t *linked_inode);
+
+int
+inode_is_linked(inode_t *inode);
+
+void
+inode_set_need_lookup(inode_t *inode, xlator_t *this);
+
+gf_boolean_t
+inode_needs_lookup(inode_t *inode, xlator_t *this);
+
+int
+inode_has_dentry(inode_t *inode);
+
+size_t
+inode_ctx_size(inode_t *inode);
+
+void
+inode_find_directory_name(inode_t *inode, const char **name);
+#endif /* _INODE_H */
diff --git a/libglusterfs/src/glusterfs/iobuf.h b/libglusterfs/src/glusterfs/iobuf.h
new file mode 100644
index 00000000000..4bd443efd5e
--- /dev/null
+++ b/libglusterfs/src/glusterfs/iobuf.h
@@ -0,0 +1,194 @@
+/*
+ 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_
+#define _IOBUF_H_
+
+#include <stddef.h> // for size_t
+#include <sys/mman.h>
+#include "glusterfs/atomic.h" // for gf_atomic_t
+#include <sys/uio.h> // for struct iovec
+#include "glusterfs/locking.h" // for gf_lock_t
+#include "glusterfs/list.h"
+
+#define GF_VARIABLE_IOBUF_COUNT 32
+
+#define GF_RDMA_DEVICE_COUNT 8
+
+/* Lets try to define the new anonymous mapping
+ * flag, in case the system is still using the
+ * now deprecated MAP_ANON flag.
+ *
+ * Also, this should ideally be in a centralized/common
+ * header which can be used by other source files also.
+ */
+#ifndef MAP_ANONYMOUS
+#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;
+
+/* one region of memory mapped from the operating system */
+/* each region MMAPs @arena_size bytes of memory */
+/* each arena hosts @arena_size / @page_size IOBUFs */
+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 {
+ struct list_head list;
+ struct {
+ struct iobuf *next;
+ struct iobuf *prev;
+ };
+ };
+ struct iobuf_arena *iobuf_arena;
+
+ gf_lock_t lock; /* for ->ptr and ->ref */
+ gf_atomic_t 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 */
+};
+
+struct iobuf_arena {
+ union {
+ struct list_head list;
+ struct {
+ struct iobuf_arena *next;
+ struct iobuf_arena *prev;
+ };
+ };
+
+ struct list_head all_list;
+ size_t page_size; /* size of all iobufs in this arena */
+ size_t arena_size;
+ /* this is equal to rounded_size * num_iobufs.
+ (rounded_size comes with gf_iobuf_get_pagesize().) */
+ size_t page_count;
+
+ struct iobuf_pool *iobuf_pool;
+
+ void *mem_base;
+ struct iobuf *iobufs; /* allocated iobufs list */
+
+ struct iobuf active; /* head node iobuf
+ (unused by itself) */
+ struct iobuf passive; /* head node iobuf
+ (unused by itself) */
+ uint64_t alloc_cnt; /* total allocs in this pool */
+ int active_cnt;
+ int passive_cnt;
+ int max_active; /* max active buffers at a given time */
+};
+
+struct iobuf_pool {
+ pthread_mutex_t mutex;
+ size_t arena_size; /* size of memory region in
+ arena */
+ size_t default_page_size; /* default size of iobuf */
+
+ struct list_head all_arenas;
+ 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 */
+ int arena_cnt;
+ int rdma_device_count;
+ struct list_head *mr_list[GF_RDMA_DEVICE_COUNT];
+ void *device[GF_RDMA_DEVICE_COUNT];
+ int (*rdma_registration)(void **, void *);
+ int (*rdma_deregistration)(struct list_head **, struct iobuf_arena *);
+};
+
+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);
+struct iobuf *
+iobuf_ref(struct iobuf *iobuf);
+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_default_pagesize(iobpool) ((iobpool)->default_page_size)
+#define iobuf_pagesize(iob) (iob->iobuf_arena->page_size)
+
+struct iobref {
+ gf_lock_t lock;
+ gf_atomic_t ref;
+ struct iobuf **iobrefs;
+ int allocated;
+ int used;
+};
+
+struct iobref *
+iobref_new(void);
+struct iobref *
+iobref_ref(struct iobref *iobref);
+void
+iobref_unref(struct iobref *iobref);
+int
+iobref_add(struct iobref *iobref, struct iobuf *iobuf);
+int
+iobref_merge(struct iobref *to, struct iobref *from);
+void
+iobref_clear(struct iobref *iobref);
+
+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);
+
+struct iobuf *
+iobuf_get_page_aligned(struct iobuf_pool *iobuf_pool, size_t page_size,
+ size_t align_size);
+
+int
+iobuf_copy(struct iobuf_pool *iobuf_pool, const struct iovec *iovec_src,
+ int iovcnt, struct iobref **iobref, struct iobuf **iobuf,
+ struct iovec *iov_dst);
+
+#endif /* !_IOBUF_H_ */
diff --git a/libglusterfs/src/glusterfs/latency.h b/libglusterfs/src/glusterfs/latency.h
new file mode 100644
index 00000000000..4d601bbcbd6
--- /dev/null
+++ b/libglusterfs/src/glusterfs/latency.h
@@ -0,0 +1,33 @@
+/*
+ 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 __LATENCY_H__
+#define __LATENCY_H__
+
+#include <inttypes.h>
+#include <time.h>
+
+typedef struct _gf_latency {
+ uint64_t min; /* min time for the call (nanoseconds) */
+ uint64_t max; /* max time for the call (nanoseconds) */
+ uint64_t total; /* total time (nanoseconds) */
+ uint64_t count;
+} gf_latency_t;
+
+gf_latency_t *
+gf_latency_new(size_t n);
+
+void
+gf_latency_reset(gf_latency_t *lat);
+
+void
+gf_latency_update(gf_latency_t *lat, struct timespec *begin,
+ struct timespec *end);
+#endif /* __LATENCY_H__ */
diff --git a/libglusterfs/src/glusterfs/libglusterfs-messages.h b/libglusterfs/src/glusterfs/libglusterfs-messages.h
new file mode 100644
index 00000000000..cb31dd7614b
--- /dev/null
+++ b/libglusterfs/src/glusterfs/libglusterfs-messages.h
@@ -0,0 +1,245 @@
+/*
+ Copyright (c) 2015 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 _LG_MESSAGES_H_
+#define _LG_MESSAGES_H_
+
+#include "glusterfs/glfs-message-id.h"
+
+/* To add new message IDs, append new identifiers at the end of the list.
+ *
+ * Never remove a message ID. If it's not used anymore, you can rename it or
+ * leave it as it is, but not delete it. This is to prevent reutilization of
+ * IDs by other messages.
+ *
+ * The component name must match one of the entries defined in
+ * glfs-message-id.h.
+ */
+
+GLFS_MSGID(
+ LIBGLUSTERFS, LG_MSG_ASPRINTF_FAILED, LG_MSG_INVALID_ENTRY,
+ LG_MSG_COUNT_LESS_THAN_ZERO, LG_MSG_COUNT_LESS_THAN_DATA_PAIRS,
+ LG_MSG_VALUE_LENGTH_LESS_THAN_ZERO, LG_MSG_PAIRS_LESS_THAN_COUNT,
+ LG_MSG_KEY_OR_VALUE_NULL, LG_MSG_FAILED_TO_LOG_DICT,
+ LG_MSG_NULL_VALUE_IN_DICT, LG_MSG_DIR_OP_FAILED,
+ LG_MSG_STORE_HANDLE_CREATE_FAILED, LG_MSG_FILE_OP_FAILED,
+ LG_MSG_FILE_STAT_FAILED, LG_MSG_LOCK_FAILED, LG_MSG_UNLOCK_FAILED,
+ LG_MSG_DICT_SERIAL_FAILED, LG_MSG_DICT_UNSERIAL_FAILED, LG_MSG_NO_MEMORY,
+ LG_MSG_VOLUME_ERROR, LG_MSG_SUB_VOLUME_ERROR, LG_MSG_SYNTAX_ERROR,
+ LG_MSG_BACKTICK_PARSE_FAILED, LG_MSG_BUFFER_ERROR, LG_MSG_STRDUP_ERROR,
+ LG_MSG_HASH_FUNC_ERROR, LG_MSG_GET_BUCKET_FAILED, LG_MSG_INSERT_FAILED,
+ LG_MSG_OUT_OF_RANGE, LG_MSG_VALIDATE_RETURNS, LG_MSG_VALIDATE_REC_FAILED,
+ LG_MSG_RB_TABLE_CREATE_FAILED, LG_MSG_PATH_NOT_FOUND,
+ LG_MSG_EXPAND_FD_TABLE_FAILED, LG_MSG_MAPPING_FAILED,
+ LG_MSG_INIT_IOBUF_FAILED, LG_MSG_PAGE_SIZE_EXCEEDED, LG_MSG_ARENA_NOT_FOUND,
+ LG_MSG_IOBUF_NOT_FOUND, LG_MSG_POOL_NOT_FOUND, LG_MSG_SET_ATTRIBUTE_FAILED,
+ LG_MSG_READ_ATTRIBUTE_FAILED, LG_MSG_UNMOUNT_FAILED,
+ LG_MSG_LATENCY_MEASUREMENT_STATE, LG_MSG_NO_PERM, LG_MSG_NO_KEY,
+ LG_MSG_DICT_NULL, LG_MSG_INIT_TIMER_FAILED, LG_MSG_FD_ANONYMOUS_FAILED,
+ LG_MSG_FD_CREATE_FAILED, LG_MSG_BUFFER_FULL, LG_MSG_FWRITE_FAILED,
+ LG_MSG_PRINT_FAILED, LG_MSG_MEM_POOL_DESTROY,
+ LG_MSG_EXPAND_CLIENT_TABLE_FAILED, LG_MSG_DISCONNECT_CLIENT,
+ LG_MSG_PIPE_CREATE_FAILED, LG_MSG_SET_PIPE_FAILED,
+ LG_MSG_REGISTER_PIPE_FAILED, LG_MSG_POLL_IGNORE_MULTIPLE_THREADS,
+ LG_MSG_INDEX_NOT_FOUND, LG_MSG_EPOLL_FD_CREATE_FAILED,
+ LG_MSG_SLOT_NOT_FOUND, LG_MSG_STALE_FD_FOUND, LG_MSG_GENERATION_MISMATCH,
+ LG_MSG_PTHREAD_KEY_CREATE_FAILED, LG_MSG_TRANSLATOR_INIT_FAILED,
+ LG_MSG_UUID_BUF_INIT_FAILED, LG_MSG_LKOWNER_BUF_INIT_FAILED,
+ LG_MSG_SYNCTASK_INIT_FAILED, LG_MSG_SYNCOPCTX_INIT_FAILED,
+ LG_MSG_GLOBAL_INIT_FAILED, LG_MSG_PTHREAD_FAILED, LG_MSG_DIR_IS_SYMLINK,
+ LG_MSG_RESOLVE_HOSTNAME_FAILED, LG_MSG_GETADDRINFO_FAILED,
+ LG_MSG_GETNAMEINFO_FAILED, LG_MSG_PATH_ERROR, LG_MSG_INET_PTON_FAILED,
+ LG_MSG_NEGATIVE_NUM_PASSED, LG_MSG_GETHOSTNAME_FAILED,
+ LG_MSG_RESERVED_PORTS_ERROR, LG_MSG_INVALID_PORT, LG_MSG_INVALID_FAMILY,
+ LG_MSG_CONVERSION_FAILED, LG_MSG_SKIP_HEADER_FAILED, LG_MSG_INVALID_LOG,
+ LG_MSG_UTIMES_FAILED, LG_MSG_BACKTRACE_SAVE_FAILED, LG_MSG_INIT_FAILED,
+ LG_MSG_VALIDATION_FAILED, LG_MSG_GRAPH_ERROR, LG_MSG_UNKNOWN_OPTIONS_FAILED,
+ LG_MSG_CTX_NULL, LG_MSG_TMPFILE_CREATE_FAILED, LG_MSG_DLOPEN_FAILED,
+ LG_MSG_LOAD_FAILED, LG_MSG_DLSYM_ERROR, LG_MSG_TREE_NOT_FOUND,
+ LG_MSG_PER_DENTRY, LG_MSG_DENTRY, LG_MSG_GETIFADDRS_FAILED,
+ LG_MSG_REGEX_OP_FAILED, LG_MSG_FRAME_ERROR, LG_MSG_SET_PARAM_FAILED,
+ LG_MSG_GET_PARAM_FAILED, LG_MSG_PREPARE_FAILED, LG_MSG_EXEC_FAILED,
+ LG_MSG_BINDING_FAILED, LG_MSG_DELETE_FAILED, LG_MSG_GET_ID_FAILED,
+ LG_MSG_CREATE_FAILED, LG_MSG_PARSE_FAILED, LG_MSG_GETCONTEXT_FAILED,
+ LG_MSG_UPDATE_FAILED, LG_MSG_QUERY_CALL_BACK_FAILED,
+ LG_MSG_GET_RECORD_FAILED, LG_MSG_DB_ERROR, LG_MSG_CONNECTION_ERROR,
+ LG_MSG_NOT_MULTITHREAD_MODE, LG_MSG_SKIP_PATH, LG_MSG_INVALID_FOP,
+ LG_MSG_QUERY_FAILED, LG_MSG_CLEAR_COUNTER_FAILED, LG_MSG_LOCK_LIST_FAILED,
+ LG_MSG_UNLOCK_LIST_FAILED, LG_MSG_ADD_TO_LIST_FAILED, LG_MSG_INIT_DB_FAILED,
+ LG_MSG_DELETE_FROM_LIST_FAILED, LG_MSG_CLOSE_CONNECTION_FAILED,
+ LG_MSG_INSERT_OR_UPDATE_FAILED, LG_MSG_FIND_OP_FAILED,
+ LG_MSG_CONNECTION_INIT_FAILED, LG_MSG_COMPLETED_TASK, LG_MSG_WAKE_UP_ZOMBIE,
+ LG_MSG_REWAITING_TASK, LG_MSG_SLEEP_ZOMBIE, LG_MSG_SWAPCONTEXT_FAILED,
+ LG_MSG_UNSUPPORTED_PLUGIN, LG_MSG_INVALID_DB_TYPE, LG_MSG_UNDERSIZED_BUF,
+ LG_MSG_DATA_CONVERSION_ERROR, LG_MSG_DICT_ERROR, LG_MSG_IOBUFS_NOT_FOUND,
+ LG_MSG_ENTRIES_NULL, LG_MSG_FD_NOT_FOUND_IN_FDTABLE,
+ LG_MSG_REALLOC_FOR_FD_PTR_FAILED, LG_MSG_DICT_SET_FAILED, LG_MSG_NULL_PTR,
+ LG_MSG_RBTHASH_INIT_BUCKET_FAILED, LG_MSG_ASSERTION_FAILED,
+ LG_MSG_HOSTNAME_NULL, LG_MSG_INVALID_IPV4_FORMAT,
+ LG_MSG_CTX_CLEANUP_STARTED, LG_MSG_TIMER_REGISTER_ERROR,
+ LG_MSG_PTR_HEADER_CORRUPTED, LG_MSG_INVALID_UPLINK, LG_MSG_CLIENT_NULL,
+ LG_MSG_XLATOR_DOES_NOT_IMPLEMENT, LG_MSG_DENTRY_NOT_FOUND,
+ LG_MSG_INODE_NOT_FOUND, LG_MSG_INODE_TABLE_NOT_FOUND,
+ LG_MSG_DENTRY_CREATE_FAILED, LG_MSG_INODE_CONTEXT_FREED,
+ LG_MSG_UNKNOWN_LOCK_TYPE, LG_MSG_UNLOCK_BEFORE_LOCK,
+ LG_MSG_LOCK_OWNER_ERROR, LG_MSG_MEMPOOL_PTR_NULL,
+ LG_MSG_QUOTA_XATTRS_MISSING, LG_MSG_INVALID_STRING, LG_MSG_BIND_REF,
+ LG_MSG_REF_COUNT, LG_MSG_INVALID_ARG, LG_MSG_VOL_OPTION_ADD,
+ LG_MSG_XLATOR_OPTION_INVALID, LG_MSG_GETTIMEOFDAY_FAILED,
+ LG_MSG_GRAPH_INIT_FAILED, LG_MSG_EVENT_NOTIFY_FAILED,
+ LG_MSG_ACTIVE_GRAPH_NULL, LG_MSG_VOLFILE_PARSE_ERROR, LG_MSG_FD_INODE_NULL,
+ LG_MSG_INVALID_VOLFILE_ENTRY, LG_MSG_PER_DENTRY_FAILED,
+ LG_MSG_PARENT_DENTRY_NOT_FOUND, LG_MSG_DENTRY_CYCLIC_LOOP,
+ LG_MSG_INVALID_POLL_IN, LG_MSG_INVALID_POLL_OUT, LG_MSG_EPOLL_FD_ADD_FAILED,
+ LG_MSG_EPOLL_FD_DEL_FAILED, LG_MSG_EPOLL_FD_MODIFY_FAILED,
+ LG_MSG_STARTED_EPOLL_THREAD, LG_MSG_EXITED_EPOLL_THREAD,
+ LG_MSG_START_EPOLL_THREAD_FAILED, LG_MSG_FALLBACK_TO_POLL,
+ LG_MSG_QUOTA_CONF_ERROR, LG_MSG_RBTHASH_GET_ENTRY_FAILED,
+ LG_MSG_RBTHASH_GET_BUCKET_FAILED, LG_MSG_RBTHASH_INSERT_FAILED,
+ LG_MSG_RBTHASH_INIT_ENTRY_FAILED, LG_MSG_TMPFILE_DELETE_FAILED,
+ LG_MSG_MEMPOOL_INVALID_FREE, LG_MSG_LOCK_FAILURE, LG_MSG_SET_LOG_LEVEL,
+ LG_MSG_VERIFY_PLATFORM, LG_MSG_RUNNER_LOG, LG_MSG_LEASEID_BUF_INIT_FAILED,
+ LG_MSG_PTHREAD_ATTR_INIT_FAILED, LG_MSG_INVALID_INODE_LIST,
+ LG_MSG_COMPACT_FAILED, LG_MSG_COMPACT_STATUS, LG_MSG_UTIMENSAT_FAILED,
+ LG_MSG_PTHREAD_NAMING_FAILED, LG_MSG_SYSCALL_RETURNS_WRONG,
+ LG_MSG_XXH64_TO_GFID_FAILED, LG_MSG_ASYNC_WARNING, LG_MSG_ASYNC_FAILURE,
+ LG_MSG_GRAPH_CLEANUP_FAILED, LG_MSG_GRAPH_SETUP_FAILED,
+ LG_MSG_GRAPH_DETACH_STARTED, LG_MSG_GRAPH_ATTACH_FAILED,
+ LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED, LG_MSG_DUPLICATE_ENTRY,
+ LG_MSG_THREAD_NAME_TOO_LONG, LG_MSG_SET_THREAD_FAILED,
+ LG_MSG_THREAD_CREATE_FAILED, LG_MSG_FILE_DELETE_FAILED, LG_MSG_WRONG_VALUE,
+ LG_MSG_PATH_OPEN_FAILED, LG_MSG_DISPATCH_HANDLER_FAILED,
+ LG_MSG_READ_FILE_FAILED, LG_MSG_ENTRIES_NOT_PROVIDED,
+ LG_MSG_ENTRIES_PROVIDED, LG_MSG_UNKNOWN_OPTION_TYPE,
+ LG_MSG_OPTION_DEPRECATED, LG_MSG_INVALID_INIT, LG_MSG_OBJECT_NULL,
+ LG_MSG_GRAPH_NOT_SET, LG_MSG_FILENAME_NOT_SPECIFIED, LG_MSG_STRUCT_MISS,
+ LG_MSG_METHOD_MISS, LG_MSG_INPUT_DATA_NULL, LG_MSG_OPEN_LOGFILE_FAILED);
+
+#define LG_MSG_EPOLL_FD_CREATE_FAILED_STR "epoll fd creation failed"
+#define LG_MSG_INVALID_POLL_IN_STR "invalid poll_in value"
+#define LG_MSG_INVALID_POLL_OUT_STR "invalid poll_out value"
+#define LG_MSG_SLOT_NOT_FOUND_STR "could not find slot"
+#define LG_MSG_EPOLL_FD_ADD_FAILED_STR "failed to add fd to epoll"
+#define LG_MSG_EPOLL_FD_DEL_FAILED_STR "fail to delete fd to epoll"
+#define LG_MSG_EPOLL_FD_MODIFY_FAILED_STR "failed to modify fd events"
+#define LG_MSG_STALE_FD_FOUND_STR "stale fd found"
+#define LG_MSG_GENERATION_MISMATCH_STR "generation mismatch"
+#define LG_MSG_STARTED_EPOLL_THREAD_STR "Started thread with index"
+#define LG_MSG_EXITED_EPOLL_THREAD_STR "Exited thread"
+#define LG_MSG_DISPATCH_HANDLER_FAILED_STR "Failed to dispatch handler"
+#define LG_MSG_START_EPOLL_THREAD_FAILED_STR "Failed to start thread"
+#define LG_MSG_PIPE_CREATE_FAILED_STR "pipe creation failed"
+#define LG_MSG_SET_PIPE_FAILED_STR "could not set pipe to non blocking mode"
+#define LG_MSG_REGISTER_PIPE_FAILED_STR \
+ "could not register pipe fd with poll event loop"
+#define LG_MSG_POLL_IGNORE_MULTIPLE_THREADS_STR \
+ "Currently poll does not use multiple event processing threads, count " \
+ "ignored"
+#define LG_MSG_INDEX_NOT_FOUND_STR "index not found"
+#define LG_MSG_READ_FILE_FAILED_STR "read on file returned error"
+#define LG_MSG_RB_TABLE_CREATE_FAILED_STR "Failed to create rb table bucket"
+#define LG_MSG_HASH_FUNC_ERROR_STR "Hash function not given"
+#define LG_MSG_ENTRIES_NOT_PROVIDED_STR \
+ "Both mem-pool and expected entries not provided"
+#define LG_MSG_ENTRIES_PROVIDED_STR \
+ "Both mem-pool and expected entries are provided"
+#define LG_MSG_RBTHASH_INIT_BUCKET_FAILED_STR "failed to init buckets"
+#define LG_MSG_RBTHASH_GET_ENTRY_FAILED_STR "Failed to get entry from mem-pool"
+#define LG_MSG_RBTHASH_GET_BUCKET_FAILED_STR "Failed to get bucket"
+#define LG_MSG_RBTHASH_INSERT_FAILED_STR "Failed to insert entry"
+#define LG_MSG_RBTHASH_INIT_ENTRY_FAILED_STR "Failed to init entry"
+#define LG_MSG_FILE_STAT_FAILED_STR "failed to stat"
+#define LG_MSG_INET_PTON_FAILED_STR "inet_pton() failed"
+#define LG_MSG_INVALID_ENTRY_STR "Invalid arguments"
+#define LG_MSG_NEGATIVE_NUM_PASSED_STR "negative number passed"
+#define LG_MSG_PATH_ERROR_STR "Path manipulation failed"
+#define LG_MSG_FILE_OP_FAILED_STR "could not open/read file, getting ports info"
+#define LG_MSG_RESERVED_PORTS_ERROR_STR \
+ "Not able to get reserved ports, hence there is a possibility that " \
+ "glusterfs may consume reserved port"
+#define LG_MSG_INVALID_PORT_STR "invalid port"
+#define LG_MSG_GETNAMEINFO_FAILED_STR "Could not lookup hostname"
+#define LG_MSG_GETIFADDRS_FAILED_STR "getifaddrs() failed"
+#define LG_MSG_INVALID_FAMILY_STR "Invalid family"
+#define LG_MSG_CONVERSION_FAILED_STR "String conversion failed"
+#define LG_MSG_GETADDRINFO_FAILED_STR "error in getaddrinfo"
+#define LG_MSG_DUPLICATE_ENTRY_STR "duplicate entry for volfile-server"
+#define LG_MSG_PTHREAD_NAMING_FAILED_STR "Failed to compose thread name"
+#define LG_MSG_THREAD_NAME_TOO_LONG_STR \
+ "Thread name is too long. It has been truncated"
+#define LG_MSG_SET_THREAD_FAILED_STR "Could not set thread name"
+#define LG_MSG_THREAD_CREATE_FAILED_STR "Thread creation failed"
+#define LG_MSG_PTHREAD_ATTR_INIT_FAILED_STR \
+ "Thread attribute initialization failed"
+#define LG_MSG_SKIP_HEADER_FAILED_STR "Failed to skip header section"
+#define LG_MSG_INVALID_LOG_STR "Invalid log-format"
+#define LG_MSG_UTIMENSAT_FAILED_STR "utimenstat failed"
+#define LG_MSG_UTIMES_FAILED_STR "utimes failed"
+#define LG_MSG_FILE_DELETE_FAILED_STR "Unable to delete file"
+#define LG_MSG_BACKTRACE_SAVE_FAILED_STR "Failed to save the backtrace"
+#define LG_MSG_WRONG_VALUE_STR "wrong value"
+#define LG_MSG_DIR_OP_FAILED_STR "Failed to create directory"
+#define LG_MSG_DIR_IS_SYMLINK_STR "dir is symlink"
+#define LG_MSG_RESOLVE_HOSTNAME_FAILED_STR "couldnot resolve hostname"
+#define LG_MSG_PATH_OPEN_FAILED_STR "Unable to open path"
+#define LG_MSG_NO_MEMORY_STR "Error allocating memory"
+#define LG_MSG_EVENT_NOTIFY_FAILED_STR "notification failed"
+#define LG_MSG_PER_DENTRY_FAILED_STR "per dentry fn returned"
+#define LG_MSG_PARENT_DENTRY_NOT_FOUND_STR "parent not found"
+#define LG_MSG_DENTRY_CYCLIC_LOOP_STR \
+ "detected cyclic loop formation during inode linkage"
+#define LG_MSG_CTX_NULL_STR "_ctx not found"
+#define LG_MSG_DENTRY_NOT_FOUND_STR "dentry not found"
+#define LG_MSG_OUT_OF_RANGE_STR "out of range"
+#define LG_MSG_UNKNOWN_OPTION_TYPE_STR "unknown option type"
+#define LG_MSG_VALIDATE_RETURNS_STR "validate of returned"
+#define LG_MSG_OPTION_DEPRECATED_STR \
+ "option is deprecated, continuing with correction"
+#define LG_MSG_VALIDATE_REC_FAILED_STR "validate_rec failed"
+#define LG_MSG_MAPPING_FAILED_STR "mapping failed"
+#define LG_MSG_INIT_IOBUF_FAILED_STR "init failed"
+#define LG_MSG_ARENA_NOT_FOUND_STR "arena not found"
+#define LG_MSG_PAGE_SIZE_EXCEEDED_STR \
+ "page_size of iobufs in arena being added is greater than max available"
+#define LG_MSG_POOL_NOT_FOUND_STR "pool not found"
+#define LG_MSG_IOBUF_NOT_FOUND_STR "iobuf not found"
+#define LG_MSG_DLOPEN_FAILED_STR "DL open failed"
+#define LG_MSG_DLSYM_ERROR_STR "dlsym missing"
+#define LG_MSG_LOAD_FAILED_STR "Failed to load xlator options table"
+#define LG_MSG_INPUT_DATA_NULL_STR \
+ "input data is null. cannot update the lru limit of the inode table. " \
+ "continuing with older value."
+#define LG_MSG_INIT_FAILED_STR "No init() found"
+#define LG_MSG_VOLUME_ERROR_STR \
+ "Initialization of volume failed. review your volfile again."
+#define LG_MSG_TREE_NOT_FOUND_STR "Translator tree not found"
+#define LG_MSG_SET_LOG_LEVEL_STR "setting log level"
+#define LG_MSG_INVALID_INIT_STR \
+ "Invalid log-level. possible values are DEBUG|WARNING|ERROR|NONE|TRACE"
+#define LG_MSG_OBJECT_NULL_STR "object is null, returning false."
+#define LG_MSG_GRAPH_NOT_SET_STR "Graph is not set for xlator"
+#define LG_MSG_OPEN_LOGFILE_FAILED_STR "failed to open logfile"
+#define LG_MSG_STRDUP_ERROR_STR "failed to create metrics dir"
+#define LG_MSG_FILENAME_NOT_SPECIFIED_STR "no filename specified"
+#define LG_MSG_UNDERSIZED_BUF_STR "data value is smaller than expected"
+#define LG_MSG_DICT_SET_FAILED_STR "unable to set dict"
+#define LG_MSG_COUNT_LESS_THAN_ZERO_STR "count < 0!"
+#define LG_MSG_PAIRS_LESS_THAN_COUNT_STR "less than count data pairs found"
+#define LG_MSG_NULL_PTR_STR "pair->key is null!"
+#define LG_MSG_VALUE_LENGTH_LESS_THAN_ZERO_STR "value->len < 0"
+#define LG_MSG_INVALID_ARG_STR "buf is null"
+#define LG_MSG_KEY_OR_VALUE_NULL_STR "key or value is null"
+#define LG_MSG_NULL_VALUE_IN_DICT_STR "null value found in dict"
+#define LG_MSG_FAILED_TO_LOG_DICT_STR "Failed to log dictionary"
+#define LG_MSG_DICT_ERROR_STR "dict error"
+#define LG_MSG_STRUCT_MISS_STR "struct missing"
+#define LG_MSG_METHOD_MISS_STR "method missing(init)"
+
+#endif /* !_LG_MESSAGES_H_ */
diff --git a/libglusterfs/src/glusterfs/list.h b/libglusterfs/src/glusterfs/list.h
new file mode 100644
index 00000000000..221a710ca30
--- /dev/null
+++ b/libglusterfs/src/glusterfs/list.h
@@ -0,0 +1,273 @@
+/*
+ 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
+#define _LLIST_H
+
+struct list_head {
+ struct list_head *next;
+ struct list_head *prev;
+};
+
+#define INIT_LIST_HEAD(head) \
+ do { \
+ (head)->next = (head)->prev = head; \
+ } while (0)
+
+static inline void
+list_add(struct list_head *new, struct list_head *head)
+{
+ new->prev = head;
+ new->next = head->next;
+
+ new->prev->next = new;
+ new->next->prev = new;
+}
+
+static inline void
+list_add_tail(struct list_head *new, struct list_head *head)
+{
+ new->next = head;
+ new->prev = head->prev;
+
+ new->prev->next = new;
+ new->next->prev = new;
+}
+
+/* This function will insert the element to the list in a order.
+ Order will be based on the compare function provided as a input.
+ If element to be inserted in ascending order compare should return:
+ 0: if both the arguments are equal
+ >0: if first argument is greater than second argument
+ <0: if first argument is less than second argument */
+static inline void
+list_add_order(struct list_head *new, struct list_head *head,
+ int (*compare)(struct list_head *, struct list_head *))
+{
+ struct list_head *pos = head->prev;
+
+ while (pos != head) {
+ if (compare(new, pos) >= 0)
+ break;
+
+ /* Iterate the list in the reverse order. This will have
+ better efficiency if the elements are inserted in the
+ ascending order */
+ pos = pos->prev;
+ }
+
+ list_add(new, pos);
+}
+
+static inline void
+list_del(struct list_head *old)
+{
+ old->prev->next = old->next;
+ old->next->prev = old->prev;
+
+ old->next = (void *)0xbabebabe;
+ old->prev = (void *)0xcafecafe;
+}
+
+static inline void
+list_del_init(struct list_head *old)
+{
+ old->prev->next = old->next;
+ old->next->prev = old->prev;
+
+ old->next = old;
+ old->prev = old;
+}
+
+static inline void
+list_move(struct list_head *list, struct list_head *head)
+{
+ list_del(list);
+ list_add(list, head);
+}
+
+static inline void
+list_move_tail(struct list_head *list, struct list_head *head)
+{
+ list_del(list);
+ list_add_tail(list, head);
+}
+
+static inline int
+list_empty(struct list_head *head)
+{
+ return (head->next == head);
+}
+
+static inline void
+__list_splice(struct list_head *list, struct list_head *head)
+{
+ (list->prev)->next = (head->next);
+ (head->next)->prev = (list->prev);
+
+ (head)->next = (list->next);
+ (list->next)->prev = (head);
+}
+
+static inline void
+list_splice(struct list_head *list, struct list_head *head)
+{
+ if (list_empty(list))
+ return;
+
+ __list_splice(list, head);
+}
+
+/* Splice moves @list to the head of the list at @head. */
+static inline void
+list_splice_init(struct list_head *list, struct list_head *head)
+{
+ if (list_empty(list))
+ return;
+
+ __list_splice(list, head);
+ INIT_LIST_HEAD(list);
+}
+
+static inline void
+__list_append(struct list_head *list, struct list_head *head)
+{
+ (head->prev)->next = (list->next);
+ (list->next)->prev = (head->prev);
+ (head->prev) = (list->prev);
+ (list->prev)->next = head;
+}
+
+static inline void
+list_append(struct list_head *list, struct list_head *head)
+{
+ if (list_empty(list))
+ return;
+
+ __list_append(list, head);
+}
+
+/* Append moves @list to the end of @head */
+static inline void
+list_append_init(struct list_head *list, struct list_head *head)
+{
+ if (list_empty(list))
+ return;
+
+ __list_append(list, head);
+ INIT_LIST_HEAD(list);
+}
+
+static inline int
+list_is_last(struct list_head *list, struct list_head *head)
+{
+ return (list->next == head);
+}
+
+static inline int
+list_is_singular(struct list_head *head)
+{
+ return !list_empty(head) && (head->next == head->prev);
+}
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void
+list_replace(struct list_head *old, struct list_head *new)
+{
+ new->next = old->next;
+ new->next->prev = new;
+ new->prev = old->prev;
+ new->prev->next = new;
+}
+
+static inline void
+list_replace_init(struct list_head *old, struct list_head *new)
+{
+ list_replace(old, new);
+ INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_rotate_left - rotate the list to the left
+ * @head: the head of the list
+ */
+static inline void
+list_rotate_left(struct list_head *head)
+{
+ struct list_head *first;
+
+ if (!list_empty(head)) {
+ first = head->next;
+ list_move_tail(first, head);
+ }
+}
+
+#define list_entry(ptr, type, member) \
+ ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
+
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
+
+#define list_next_entry(pos, member) \
+ list_entry((pos)->member.next, typeof(*(pos)), member)
+
+#define list_prev_entry(pos, member) \
+ list_entry((pos)->member.prev, typeof(*(pos)), member)
+
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+#define list_for_each_entry_safe_reverse(pos, n, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+/*
+ * This list implementation has some advantages, but one disadvantage: you
+ * can't use NULL to check whether you're at the head or tail. Thus, the
+ * address of the head has to be an argument for these macros.
+ */
+
+#define list_next(ptr, head, type, member) \
+ (((ptr)->member.next == head) \
+ ? NULL \
+ : list_entry((ptr)->member.next, type, member))
+
+#define list_prev(ptr, head, type, member) \
+ (((ptr)->member.prev == head) \
+ ? NULL \
+ : list_entry((ptr)->member.prev, type, member))
+
+#endif /* _LLIST_H */
diff --git a/libglusterfs/src/glusterfs/lkowner.h b/libglusterfs/src/glusterfs/lkowner.h
new file mode 100644
index 00000000000..692de34bc7a
--- /dev/null
+++ b/libglusterfs/src/glusterfs/lkowner.h
@@ -0,0 +1,93 @@
+/*
+ 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
+
+#include "glusterfs/glusterfs-fops.h"
+
+/* 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));
+}
+
+static inline int
+is_lk_owner_null(gf_lkowner_t *lkowner)
+{
+ int is_null = 1;
+ int i = 0;
+
+ if (lkowner == NULL || lkowner->len == 0)
+ goto out;
+
+ for (i = 0; i < lkowner->len; i++) {
+ if (lkowner->data[i] != 0) {
+ is_null = 0;
+ break;
+ }
+ }
+out:
+ return is_null;
+}
+
+static inline void
+lk_owner_copy(gf_lkowner_t *dst, gf_lkowner_t *src)
+{
+ dst->len = src->len;
+ memcpy(dst->data, src->data, src->len);
+}
+#endif /* _LK_OWNER_H */
diff --git a/libglusterfs/src/glusterfs/locking.h b/libglusterfs/src/glusterfs/locking.h
new file mode 100644
index 00000000000..43cc87735d1
--- /dev/null
+++ b/libglusterfs/src/glusterfs/locking.h
@@ -0,0 +1,84 @@
+/*
+ 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 _LOCKING_H
+#define _LOCKING_H
+
+#include <pthread.h>
+
+#if defined(GF_DARWIN_HOST_OS)
+#include <libkern/OSAtomic.h>
+#define pthread_spinlock_t OSSpinLock
+#define pthread_spin_lock(l) OSSpinLockLock(l)
+#define pthread_spin_unlock(l) OSSpinLockUnlock(l)
+#define pthread_spin_destroy(l) 0
+#define pthread_spin_init(l, v) (*l = v)
+#endif
+
+#if defined(HAVE_SPINLOCK)
+
+typedef union {
+ pthread_spinlock_t spinlock;
+ pthread_mutex_t mutex;
+} gf_lock_t;
+
+#if !defined(LOCKING_IMPL)
+extern int use_spinlocks;
+
+/*
+ * Using a dispatch table would be unpleasant because we're dealing with two
+ * different types. If the dispatch contains direct pointers to pthread_xx
+ * or mutex_xxx then we have to hope that every possible union alternative
+ * starts at the same address as the union itself. I'm old enough to remember
+ * compilers where this was not the case (for alignment reasons) so I'm a bit
+ * paranoid about that. Also, I don't like casting arguments through "void *"
+ * which we'd also have to do to avoid type errors. The other alternative would
+ * be to define actual functions which pick out the right union member, and put
+ * those in the dispatch tables. Now we have a pointer dereference through the
+ * dispatch table plus a function call, which is likely to be worse than the
+ * branching here from the ?: construct. If it were a clear win it might be
+ * worth the extra complexity, but for now this way seems preferable.
+ */
+
+#define LOCK_INIT(x) \
+ (use_spinlocks ? pthread_spin_init(&((x)->spinlock), 0) \
+ : pthread_mutex_init(&((x)->mutex), 0))
+
+#define LOCK(x) \
+ (use_spinlocks ? pthread_spin_lock(&((x)->spinlock)) \
+ : pthread_mutex_lock(&((x)->mutex)))
+
+#define TRY_LOCK(x) \
+ (use_spinlocks ? pthread_spin_trylock(&((x)->spinlock)) \
+ : pthread_mutex_trylock(&((x)->mutex)))
+
+#define UNLOCK(x) \
+ (use_spinlocks ? pthread_spin_unlock(&((x)->spinlock)) \
+ : pthread_mutex_unlock(&((x)->mutex)))
+
+#define LOCK_DESTROY(x) \
+ (use_spinlocks ? pthread_spin_destroy(&((x)->spinlock)) \
+ : pthread_mutex_destroy(&((x)->mutex)))
+
+#endif
+
+#else
+
+typedef pthread_mutex_t gf_lock_t;
+
+#define LOCK_INIT(x) pthread_mutex_init(x, 0)
+#define LOCK(x) pthread_mutex_lock(x)
+#define TRY_LOCK(x) pthread_mutex_trylock(x)
+#define UNLOCK(x) pthread_mutex_unlock(x)
+#define LOCK_DESTROY(x) pthread_mutex_destroy(x)
+
+#endif /* HAVE_SPINLOCK */
+
+#endif /* _LOCKING_H */
diff --git a/libglusterfs/src/glusterfs/logging.h b/libglusterfs/src/glusterfs/logging.h
new file mode 100644
index 00000000000..b3a6ac191f0
--- /dev/null
+++ b/libglusterfs/src/glusterfs/logging.h
@@ -0,0 +1,383 @@
+/*
+ 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__
+#define __LOGGING_H__
+
+#include <sys/time.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include "glusterfs/list.h"
+
+#ifdef GF_DARWIN_HOST_OS
+#define GF_PRI_FSBLK "u"
+#define GF_PRI_DEV PRId32
+#define GF_PRI_INODE PRIu64
+#define GF_PRI_NLINK PRIu32
+#define GF_PRI_SECOND "ld"
+#define GF_PRI_SUSECONDS "06d"
+#define GF_PRI_SNSECONDS "09ld"
+#define GF_PRI_USEC "d"
+#else
+#define GF_PRI_FSBLK PRIu64
+#define GF_PRI_DEV PRIu64
+#define GF_PRI_INODE PRIu64
+#define GF_PRI_NLINK PRIu32
+#define GF_PRI_SECOND "lu"
+#define GF_PRI_SUSECONDS "06ld"
+#define GF_PRI_SNSECONDS "09ld"
+#define GF_PRI_USEC "ld"
+#endif
+#define GF_PRI_BLKSIZE PRId32
+#define GF_PRI_SIZET "zu"
+#define GF_PRI_ATOMIC PRIu64
+
+#ifdef GF_DARWIN_HOST_OS
+#define GF_PRI_TIME "ld"
+#else
+#define GF_PRI_TIME PRIu64
+#endif
+
+#if 0
+/* Syslog definitions :-) */
+#define LOG_EMERG 0 /* system is unusable */
+#define LOG_ALERT 1 /* action must be taken immediately */
+#define LOG_CRIT 2 /* critical conditions */
+#define LOG_ERR 3 /* error conditions */
+#define LOG_WARNING 4 /* warning conditions */
+#define LOG_NOTICE 5 /* normal but significant condition */
+#define LOG_INFO 6 /* informational */
+#define LOG_DEBUG 7 /* debug-level messages */
+#endif
+
+#define GF_LOG_FORMAT_NO_MSG_ID "no-msg-id"
+#define GF_LOG_FORMAT_WITH_MSG_ID "with-msg-id"
+
+#define GF_LOGGER_GLUSTER_LOG "gluster-log"
+#define GF_LOGGER_SYSLOG "syslog"
+
+typedef enum {
+ GF_LOG_NONE,
+ GF_LOG_EMERG,
+ GF_LOG_ALERT,
+ GF_LOG_CRITICAL, /* fatal errors */
+ GF_LOG_ERROR, /* major failures (not necessarily fatal) */
+ GF_LOG_WARNING, /* info about normal operation */
+ GF_LOG_NOTICE,
+ GF_LOG_INFO, /* Normal information */
+ GF_LOG_DEBUG, /* internal errors */
+ GF_LOG_TRACE, /* full trace of operation */
+} gf_loglevel_t;
+
+/* format for the logs */
+typedef enum {
+ gf_logformat_traditional = 0, /* Format as in gluster 3.5 */
+ gf_logformat_withmsgid, /* Format enhanced with MsgID, ident, errstr */
+ gf_logformat_cee /* log enhanced format in cee */
+} gf_log_format_t;
+
+/* log infrastructure to log to */
+typedef enum {
+ gf_logger_glusterlog = 0, /* locations and files as in gluster 3.5 */
+ gf_logger_syslog /* log to (r)syslog, based on (r)syslog conf */
+ /* NOTE: In the future journald, lumberjack, next new thing here */
+} gf_log_logger_t;
+
+#define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
+#define DEFAULT_QUOTA_CRAWL_LOG_DIRECTORY DATADIR "/log/glusterfs/quota_crawl"
+#define DEFAULT_LOG_LEVEL GF_LOG_INFO
+
+typedef struct gf_log_handle_ {
+ pthread_mutex_t logfile_mutex;
+ gf_loglevel_t loglevel;
+ gf_loglevel_t sys_log_level;
+ int gf_log_syslog;
+ char *filename;
+ FILE *logfile;
+ FILE *gf_log_logfile;
+ char *cmd_log_filename;
+ FILE *cmdlogfile;
+ gf_log_logger_t logger;
+ gf_log_format_t logformat;
+ char *ident;
+ int log_control_file_found;
+ struct list_head lru_queue;
+ pthread_mutex_t log_buf_lock;
+ struct _gf_timer *log_flush_timer;
+ int localtime;
+ uint32_t lru_size;
+ uint32_t lru_cur_size;
+ uint32_t timeout;
+ uint8_t logrotate;
+ uint8_t cmd_history_logrotate;
+} gf_log_handle_t;
+
+typedef struct log_buf_ {
+ char *msg;
+ uint64_t msg_id;
+ int errnum;
+ struct timeval oldest;
+ struct timeval latest;
+ char *domain;
+ char *file;
+ char *function;
+ int32_t line;
+ gf_loglevel_t level;
+ int refcount;
+ int graph_id;
+ struct list_head msg_list;
+} log_buf_t;
+
+void
+gf_log_globals_init(void *ctx, gf_loglevel_t level);
+int
+gf_log_init(void *data, const char *filename, const char *ident);
+
+void
+gf_log_logrotate(int signum);
+
+void
+gf_log_cleanup(void);
+
+/* Internal interfaces to log messages with message IDs */
+int
+_gf_msg(const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum, int trace,
+ uint64_t msgid, const char *fmt, ...)
+ __attribute__((__format__(__printf__, 9, 10)));
+
+void
+_gf_msg_backtrace_nomem(gf_loglevel_t level, int stacksize);
+
+int
+_gf_msg_plain(gf_loglevel_t level, const char *fmt, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
+
+int
+_gf_msg_plain_nomem(gf_loglevel_t level, const char *msg);
+
+int
+_gf_msg_vplain(gf_loglevel_t level, const char *fmt, va_list ap);
+
+int
+_gf_msg_nomem(const char *domain, const char *file, const char *function,
+ int line, gf_loglevel_t level, size_t size);
+
+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_eh(const char *function, const char *fmt, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
+
+/* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
+ * other level as is */
+#define SET_LOG_PRIO(level, priority) \
+ do { \
+ if (GF_LOG_TRACE == (level) || GF_LOG_NONE == (level)) { \
+ priority = LOG_DEBUG; \
+ } else { \
+ priority = (level)-1; \
+ } \
+ } while (0)
+
+/* extract just the file name from the path */
+#define GET_FILE_NAME_TO_LOG(file, basename) \
+ do { \
+ basename = strrchr((file), '/'); \
+ if (basename) \
+ basename++; \
+ else \
+ basename = (file); \
+ } while (0)
+
+#define PRINT_SIZE_CHECK(ret, label, strsize) \
+ do { \
+ if (ret < 0) \
+ goto label; \
+ if ((strsize - ret) > 0) { \
+ strsize -= ret; \
+ } else { \
+ ret = 0; \
+ goto label; \
+ } \
+ } while (0)
+
+#define FMT_WARN(fmt...) \
+ do { \
+ if (0) \
+ printf(fmt); \
+ } while (0)
+
+/* Interface to log messages with message IDs */
+#define gf_msg(dom, level, errnum, msgid, fmt...) \
+ do { \
+ _gf_msg(dom, __FILE__, __FUNCTION__, __LINE__, level, errnum, 0, \
+ msgid, ##fmt); \
+ } while (0)
+
+/* no frills, no thrills, just a vanilla message, used to print the graph */
+#define gf_msg_plain(level, fmt...) \
+ do { \
+ _gf_msg_plain(level, ##fmt); \
+ } while (0)
+
+#define gf_msg_plain_nomem(level, msg) \
+ do { \
+ _gf_msg_plain_nomem(level, msg); \
+ } while (0)
+
+#define gf_msg_vplain(level, fmt, va) \
+ do { \
+ _gf_msg_vplain(level, fmt, va); \
+ } while (0)
+
+#define gf_msg_backtrace_nomem(level, stacksize) \
+ do { \
+ _gf_msg_backtrace_nomem(level, stacksize); \
+ } while (0)
+
+#define gf_msg_callingfn(dom, level, errnum, msgid, fmt...) \
+ do { \
+ _gf_msg(dom, __FILE__, __FUNCTION__, __LINE__, level, errnum, 1, \
+ msgid, ##fmt); \
+ } while (0)
+
+/* No malloc or calloc should be called in this function */
+#define gf_msg_nomem(dom, level, size) \
+ do { \
+ _gf_msg_nomem(dom, __FILE__, __FUNCTION__, __LINE__, level, size); \
+ } while (0)
+
+/* Debug or trace messages do not need message IDs as these are more developer
+ * related. Hence, the following abstractions are provided for the same */
+#define gf_msg_debug(dom, errnum, fmt...) \
+ do { \
+ _gf_msg(dom, __FILE__, __FUNCTION__, __LINE__, GF_LOG_DEBUG, errnum, \
+ 0, 0, ##fmt); \
+ } while (0)
+
+#define gf_msg_trace(dom, errnum, fmt...) \
+ do { \
+ _gf_msg(dom, __FILE__, __FUNCTION__, __LINE__, GF_LOG_TRACE, errnum, \
+ 0, 0, ##fmt); \
+ } while (0)
+
+#define gf_log(dom, level, fmt...) \
+ do { \
+ FMT_WARN(fmt); \
+ _gf_log(dom, __FILE__, __FUNCTION__, __LINE__, level, ##fmt); \
+ } while (0)
+
+#define gf_log_eh(fmt...) \
+ do { \
+ FMT_WARN(fmt); \
+ _gf_log_eh(__FUNCTION__, ##fmt); \
+ } while (0)
+
+#define gf_log_callingfn(dom, level, fmt...) \
+ do { \
+ FMT_WARN(fmt); \
+ _gf_log_callingfn(dom, __FILE__, __FUNCTION__, __LINE__, level, \
+ ##fmt); \
+ } while (0)
+
+/* Log once in GF_UNIVERSAL_ANSWER times */
+#define GF_LOG_OCCASIONALLY(var, args...) \
+ if (var++ == 0 || !((var - 1) % GF_UNIVERSAL_ANSWER)) { \
+ gf_log(args); \
+ }
+
+struct _glusterfs_ctx;
+
+void
+gf_log_disable_syslog(void);
+void
+gf_log_enable_syslog(void);
+gf_loglevel_t
+gf_log_get_loglevel(void);
+void
+gf_log_set_loglevel(struct _glusterfs_ctx *ctx, gf_loglevel_t level);
+int
+gf_log_get_localtime(void);
+void
+gf_log_set_localtime(int);
+void
+gf_log_flush(void);
+gf_loglevel_t
+gf_log_get_xl_loglevel(void *xl);
+void
+gf_log_set_xl_loglevel(void *xl, gf_loglevel_t level);
+
+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);
+
+int
+gf_log_fini(void *data);
+
+void
+gf_log_set_logger(gf_log_logger_t logger);
+
+void
+gf_log_set_logformat(gf_log_format_t format);
+
+void
+gf_log_set_log_buf_size(uint32_t buf_size);
+
+void
+gf_log_set_log_flush_timeout(uint32_t timeout);
+
+void
+gf_log_flush_msgs(struct _glusterfs_ctx *ctx);
+
+int
+gf_log_inject_timer_event(struct _glusterfs_ctx *ctx);
+
+void
+gf_log_disable_suppression_before_exit(struct _glusterfs_ctx *ctx);
+
+#define GF_DEBUG(xl, format, args...) \
+ gf_log((xl)->name, GF_LOG_DEBUG, format, ##args)
+#define GF_INFO(xl, format, args...) \
+ gf_log((xl)->name, GF_LOG_INFO, format, ##args)
+#define GF_WARNING(xl, format, args...) \
+ gf_log((xl)->name, GF_LOG_WARNING, format, ##args)
+#define GF_ERROR(xl, format, args...) \
+ gf_log((xl)->name, GF_LOG_ERROR, format, ##args)
+
+int
+_gf_smsg(const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum, int trace,
+ uint64_t msgid, const char *event, ...);
+
+/* Interface to log messages with message IDs */
+#define gf_smsg(dom, level, errnum, msgid, event...) \
+ do { \
+ _gf_smsg(dom, __FILE__, __FUNCTION__, __LINE__, level, errnum, 0, \
+ msgid, msgid##_STR, ##event); \
+ } while (0)
+
+#endif /* __LOGGING_H__ */
diff --git a/libglusterfs/src/lvm-defaults.h b/libglusterfs/src/glusterfs/lvm-defaults.h
index 32feebf3f6e..32feebf3f6e 100644
--- a/libglusterfs/src/lvm-defaults.h
+++ b/libglusterfs/src/glusterfs/lvm-defaults.h
diff --git a/libglusterfs/src/glusterfs/mem-pool.h b/libglusterfs/src/glusterfs/mem-pool.h
new file mode 100644
index 00000000000..e5b3276d047
--- /dev/null
+++ b/libglusterfs/src/glusterfs/mem-pool.h
@@ -0,0 +1,336 @@
+/*
+ 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_
+#define _MEM_POOL_H_
+
+#include "glusterfs/list.h"
+#include "glusterfs/atomic.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/mem-types.h"
+#include "glusterfs/glusterfs.h" /* for glusterfs_ctx_t */
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdarg.h>
+
+/*
+ * Need this for unit tests since inline functions
+ * access memory allocation and need to use the
+ * unit test versions
+ */
+#ifdef UNIT_TESTING
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#endif
+
+#define GF_MEM_TRAILER_SIZE 8
+#define GF_MEM_HEADER_MAGIC 0xCAFEBABE
+#define GF_MEM_TRAILER_MAGIC 0xBAADF00D
+#define GF_MEM_INVALID_MAGIC 0xDEADC0DE
+
+#define POOL_SMALLEST 7 /* i.e. 128 */
+#define POOL_LARGEST 20 /* i.e. 1048576 */
+#define NPOOLS (POOL_LARGEST - POOL_SMALLEST + 1)
+
+struct mem_acct_rec {
+ const char *typestr;
+ uint64_t size;
+ uint64_t max_size;
+ uint64_t total_allocs;
+ uint32_t num_allocs;
+ uint32_t max_num_allocs;
+ gf_lock_t lock;
+#ifdef DEBUG
+ struct list_head obj_list;
+#endif
+};
+
+struct mem_acct {
+ uint32_t num_types;
+ gf_atomic_t refcnt;
+ struct mem_acct_rec rec[0];
+};
+
+struct mem_header {
+ uint32_t type;
+ size_t size;
+ struct mem_acct *mem_acct;
+ uint32_t magic;
+#ifdef DEBUG
+ struct list_head acct_list;
+#endif
+ int padding[8];
+};
+
+#define GF_MEM_HEADER_SIZE (sizeof(struct mem_header))
+
+#ifdef DEBUG
+struct mem_invalid {
+ uint32_t magic;
+ void *mem_acct;
+ uint32_t type;
+ size_t size;
+ void *baseaddr;
+};
+#endif
+
+void *
+__gf_calloc(size_t cnt, size_t size, uint32_t type, const char *typestr);
+
+void *
+__gf_malloc(size_t size, uint32_t type, const char *typestr);
+
+void *
+__gf_realloc(void *ptr, size_t size);
+
+int
+gf_vasprintf(char **string_ptr, const char *format, va_list arg);
+
+int
+gf_asprintf(char **string_ptr, const char *format, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
+
+void
+__gf_free(void *ptr);
+
+static inline void *
+__gf_default_malloc(size_t size)
+{
+ void *ptr = NULL;
+
+ ptr = malloc(size);
+ if (!ptr)
+ gf_msg_nomem("", GF_LOG_ALERT, size);
+
+ return ptr;
+}
+
+static inline void *
+__gf_default_calloc(int cnt, size_t size)
+{
+ void *ptr = NULL;
+
+ ptr = calloc(cnt, size);
+ if (!ptr)
+ gf_msg_nomem("", GF_LOG_ALERT, (cnt * size));
+
+ return ptr;
+}
+
+static inline void *
+__gf_default_realloc(void *oldptr, size_t size)
+{
+ void *ptr = NULL;
+
+ ptr = realloc(oldptr, size);
+ if (!ptr)
+ gf_msg_nomem("", GF_LOG_ALERT, size);
+
+ return ptr;
+}
+
+#define MALLOC(size) __gf_default_malloc(size)
+#define CALLOC(cnt, size) __gf_default_calloc(cnt, size)
+#define REALLOC(ptr, size) __gf_default_realloc(ptr, size)
+
+#define FREE(ptr) \
+ do { \
+ if (ptr != NULL) { \
+ free((void *)ptr); \
+ ptr = (void *)0xeeeeeeee; \
+ } \
+ } while (0)
+
+#define GF_CALLOC(nmemb, size, type) __gf_calloc(nmemb, size, type, #type)
+
+#define GF_MALLOC(size, type) __gf_malloc(size, type, #type)
+
+#define GF_REALLOC(ptr, size) __gf_realloc(ptr, size)
+
+#define GF_FREE(free_ptr) __gf_free(free_ptr)
+
+static inline char *
+gf_strndup(const char *src, size_t len)
+{
+ char *dup_str = NULL;
+
+ if (!src) {
+ goto out;
+ }
+
+ dup_str = GF_MALLOC(len + 1, gf_common_mt_strdup);
+ if (!dup_str) {
+ goto out;
+ }
+
+ memcpy(dup_str, src, len);
+ dup_str[len] = '\0';
+out:
+ return dup_str;
+}
+
+static inline char *
+gf_strdup(const char *src)
+{
+ if (!src)
+ return NULL;
+
+ return gf_strndup(src, strlen(src));
+}
+
+static inline void *
+gf_memdup(const void *src, size_t size)
+{
+ void *dup_mem = NULL;
+
+ dup_mem = GF_MALLOC(size, gf_common_mt_memdup);
+ if (!dup_mem)
+ goto out;
+
+ memcpy(dup_mem, src, size);
+
+out:
+ return dup_mem;
+}
+
+#ifdef GF_DISABLE_MEMPOOL
+
+/* No-op memory pool enough to fit current API without massive redesign. */
+
+struct mem_pool {
+ unsigned long sizeof_type;
+};
+
+#define mem_pools_init() \
+ do { \
+ } while (0)
+#define mem_pools_fini() \
+ do { \
+ } while (0)
+#define mem_pool_thread_destructor(pool_list) (void)pool_list
+
+#else /* !GF_DISABLE_MEMPOOL */
+
+/* kind of 'header' for the actual mem_pool_shared structure, this might make
+ * it possible to dump some more details in a statedump */
+struct mem_pool {
+ /* object size, without pooled_obj_hdr_t */
+ unsigned long sizeof_type;
+ unsigned long count; /* requested pool size (unused) */
+ char *name;
+ char *xl_name;
+ gf_atomic_t active; /* current allocations */
+#ifdef DEBUG
+ gf_atomic_t hit; /* number of allocations served from pt_pool */
+ gf_atomic_t miss; /* number of std allocs due to miss */
+#endif
+ struct list_head owner; /* glusterfs_ctx_t->mempool_list */
+ glusterfs_ctx_t *ctx; /* take ctx->lock when updating owner */
+
+ struct mem_pool_shared *pool; /* the initial pool that was returned */
+};
+
+typedef struct pooled_obj_hdr {
+ unsigned long magic;
+ struct pooled_obj_hdr *next;
+ struct per_thread_pool_list *pool_list;
+ unsigned int power_of_two;
+
+ /* track the pool that was used to request this object */
+ struct mem_pool *pool;
+} pooled_obj_hdr_t;
+
+/* Each memory block inside a pool has a fixed size that is a power of two.
+ * However each object will have a header that will reduce the available
+ * space. */
+#define AVAILABLE_SIZE(p2) ((1UL << (p2)) - sizeof(pooled_obj_hdr_t))
+
+typedef struct per_thread_pool {
+ /* the pool that was used to request this allocation */
+ struct mem_pool_shared *parent;
+ /* Everything else is protected by our own lock. */
+ pooled_obj_hdr_t *hot_list;
+ pooled_obj_hdr_t *cold_list;
+} per_thread_pool_t;
+
+typedef struct per_thread_pool_list {
+ /* thr_list is used to place the TLS pool_list into the active global list
+ * (pool_threads) or the inactive global list (pool_free_threads). It's
+ * protected by the global pool_lock. */
+ struct list_head thr_list;
+
+ /* This lock is used to update poison and the hot/cold lists of members
+ * of 'pools' array. */
+ pthread_spinlock_t lock;
+
+ /* This field is used to mark a pool_list as not being owned by any thread.
+ * This means that the sweeper thread won't be cleaning objects stored in
+ * its pools. mem_put() uses it to decide if the object being released is
+ * placed into its original pool_list or directly destroyed. */
+ bool poison;
+
+ /*
+ * There's really more than one pool, but the actual number is hidden
+ * in the implementation code so we just make it a single-element array
+ * here.
+ */
+ per_thread_pool_t pools[1];
+} per_thread_pool_list_t;
+
+/* actual pool structure, shared between different mem_pools */
+struct mem_pool_shared {
+ unsigned int power_of_two;
+ /*
+ * Updates to these are *not* protected by a global lock, so races
+ * could occur and the numbers might be slightly off. Don't expect
+ * them to line up exactly. It's the general trends that matter, and
+ * it's not worth the locked-bus-cycle overhead to make these precise.
+ */
+ gf_atomic_t allocs_hot;
+ gf_atomic_t allocs_cold;
+ gf_atomic_t allocs_stdc;
+ gf_atomic_t frees_to_list;
+};
+
+void
+mem_pools_init(void); /* start the pool_sweeper thread */
+void
+mem_pools_fini(void); /* cleanup memory pools */
+void
+mem_pool_thread_destructor(per_thread_pool_list_t *pool_list);
+
+#endif /* GF_DISABLE_MEMPOOL */
+
+struct mem_pool *
+mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type,
+ unsigned long count, char *name);
+
+#define mem_pool_new(type, count) \
+ mem_pool_new_fn(THIS->ctx, sizeof(type), count, #type)
+
+#define mem_pool_new_ctx(ctx, type, count) \
+ mem_pool_new_fn(ctx, sizeof(type), count, #type)
+
+void
+mem_put(void *ptr);
+void *
+mem_get(struct mem_pool *pool);
+void *
+mem_get0(struct mem_pool *pool);
+
+void
+mem_pool_destroy(struct mem_pool *pool);
+
+void
+gf_mem_acct_enable_set(void *ctx);
+
+#endif /* _MEM_POOL_H */
diff --git a/libglusterfs/src/glusterfs/mem-types.h b/libglusterfs/src/glusterfs/mem-types.h
new file mode 100644
index 00000000000..d45d5b68c91
--- /dev/null
+++ b/libglusterfs/src/glusterfs/mem-types.h
@@ -0,0 +1,139 @@
+/*
+ Copyright (c) 2008-2016 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_TYPES_H__
+#define __MEM_TYPES_H__
+
+enum gf_common_mem_types_ {
+ gf_common_mt_dnscache6, /* used only in one location */
+ gf_common_mt_event_pool,
+ gf_common_mt_reg,
+ gf_common_mt_pollfd, /* used only in one location */
+ gf_common_mt_fdentry_t, /* used only in one location */
+ gf_common_mt_fdtable_t, /* used only in one location */
+ gf_common_mt_fd_ctx, /* used only in one location */
+ gf_common_mt_gf_dirent_t,
+ gf_common_mt_inode_t, /* used only in one location */
+ gf_common_mt_inode_ctx, /* used only in one location */
+ gf_common_mt_list_head,
+ gf_common_mt_inode_table_t, /* used only in one location */
+ gf_common_mt_xlator_t,
+ gf_common_mt_xlator_list_t, /* used only in one location */
+ gf_common_mt_volume_opt_list_t,
+ gf_common_mt_gf_timer_t, /* used only in one location */
+ gf_common_mt_gf_timer_registry_t, /* used only in one location */
+ gf_common_mt_auth_handle_t, /* used only in one location */
+ gf_common_mt_iobuf, /* used only in one location */
+ gf_common_mt_iobuf_arena, /* used only in one location */
+ gf_common_mt_iobref, /* used only in one location */
+ gf_common_mt_iobuf_pool, /* used only in one location */
+ gf_common_mt_iovec,
+ gf_common_mt_memdup, /* used only in one location */
+ gf_common_mt_asprintf, /* used only in one location */
+ gf_common_mt_strdup,
+ gf_common_mt_socket_private_t, /* used only in one location */
+ gf_common_mt_ioq, /* used only in one location */
+ gf_common_mt_char,
+ gf_common_mt_rbthash_table_t, /* used only in one location */
+ gf_common_mt_rbthash_bucket, /* used only in one location */
+ gf_common_mt_mem_pool, /* used only in one location */
+ gf_common_mt_rpcsvc_auth_list, /* used only in one location */
+ gf_common_mt_rpcsvc_t, /* used only in one location */
+ gf_common_mt_rpcsvc_program_t, /* used only in one location */
+ gf_common_mt_rpcsvc_listener_t, /* used only in one location */
+ gf_common_mt_rpcsvc_wrapper_t, /* used only in one location */
+ gf_common_mt_rpcclnt_t, /* used only in one location */
+ gf_common_mt_rpcclnt_savedframe_t, /* used only in one location */
+ gf_common_mt_rpc_trans_t,
+ gf_common_mt_rpc_trans_pollin_t, /* used only in one location */
+ gf_common_mt_rpc_trans_reqinfo_t, /* used only in one location */
+ gf_common_mt_glusterfs_graph_t,
+ gf_common_mt_rdma_private_t, /* used only in one location */
+ gf_common_mt_rpc_transport_t, /* used only in one location */
+ gf_common_mt_rdma_post_t, /* used only in one location */
+ gf_common_mt_qpent, /* used only in one location */
+ gf_common_mt_rdma_device_t, /* used only in one location */
+ gf_common_mt_rdma_arena_mr, /* used only in one location */
+ gf_common_mt_sge, /* used only in one location */
+ gf_common_mt_rpcclnt_cb_program_t, /* used only in one location */
+ gf_common_mt_libxl_marker_local, /* used only in one location */
+ gf_common_mt_graph_buf, /* used only in one location */
+ gf_common_mt_trie_trie, /* used only in one location */
+ gf_common_mt_trie_data, /* used only in one location */
+ gf_common_mt_trie_node, /* used only in one location */
+ gf_common_mt_trie_buf, /* used only in one location */
+ gf_common_mt_run_argv, /* used only in one location */
+ gf_common_mt_run_logbuf, /* used only in one location */
+ gf_common_mt_fd_lk_ctx_t, /* used only in one location */
+ gf_common_mt_fd_lk_ctx_node_t, /* used only in one location */
+ gf_common_mt_buffer_t, /* used only in one location */
+ gf_common_mt_circular_buffer_t, /* used only in one location */
+ gf_common_mt_eh_t,
+ gf_common_mt_store_handle_t, /* used only in one location */
+ gf_common_mt_store_iter_t, /* used only in one location */
+ gf_common_mt_drc_client_t, /* used only in one location */
+ gf_common_mt_drc_globals_t, /* used only in one location */
+ gf_common_mt_groups_t,
+ gf_common_mt_cliententry_t, /* used only in one location */
+ gf_common_mt_clienttable_t, /* used only in one location */
+ gf_common_mt_client_t, /* used only in one location */
+ gf_common_mt_client_ctx, /* used only in one location */
+ gf_common_mt_auxgids, /* used only in one location */
+ gf_common_mt_syncopctx, /* used only in one location */
+ gf_common_mt_iobrefs, /* used only in one location */
+ gf_common_mt_gsync_status_t,
+ gf_common_mt_uuid_t,
+ gf_common_mt_mgmt_v3_lock_obj_t, /* used only in one location */
+ gf_common_mt_txn_opinfo_obj_t, /* used only in one location */
+ gf_common_mt_strfd_t, /* used only in one location */
+ gf_common_mt_strfd_data_t, /* used only in one location */
+ gf_common_mt_regex_t, /* used only in one location */
+ gf_common_mt_ereg, /* used only in one location */
+ gf_common_mt_wr, /* used only in one location */
+ gf_common_mt_dnscache, /* used only in one location */
+ gf_common_mt_dnscache_entry, /* used only in one location */
+ gf_common_mt_parser_t, /* used only in one location */
+ gf_common_quota_meta_t,
+ gf_common_mt_rbuf_t, /* used only in one location */
+ gf_common_mt_rlist_t, /* used only in one location */
+ gf_common_mt_rvec_t, /* used only in one location */
+ /* glusterd can load the nfs-xlator dynamically and needs these two */
+ gf_common_mt_nfs_netgroups, /* used only in one location */
+ gf_common_mt_nfs_exports, /* used only in one location */
+ gf_common_mt_gf_brick_spec_t, /* used only in one location */
+ gf_common_mt_int,
+ gf_common_mt_pointer,
+ gf_common_mt_synctask, /* used only in one location */
+ gf_common_mt_syncstack, /* used only in one location */
+ gf_common_mt_syncenv, /* used only in one location */
+ gf_common_mt_scan_data, /* used only in one location */
+ gf_common_list_node,
+ gf_mt_default_args_t, /* used only in one location */
+ gf_mt_default_args_cbk_t, /* used only in one location */
+ /*used for compound fops*/
+ gf_mt_compound_req_t, /* used only in one location */
+ gf_mt_compound_rsp_t, /* used only in one location */
+ gf_common_mt_tw_ctx, /* used only in one location */
+ gf_common_mt_tw_timer_list,
+ /*lock migration*/
+ gf_common_mt_lock_mig,
+ /* throttle */
+ gf_common_mt_tbf_t, /* used only in one location */
+ gf_common_mt_tbf_bucket_t, /* used only in one location */
+ gf_common_mt_tbf_throttle_t, /* used only in one location */
+ gf_common_mt_pthread_t, /* used only in one location */
+ gf_common_ping_local_t, /* used only in one location */
+ gf_common_volfile_t,
+ gf_common_mt_mgmt_v3_lock_timer_t, /* used only in one location */
+ gf_common_mt_server_cmdline_t, /* used only in one location */
+ gf_common_mt_latency_t,
+ gf_common_mt_end
+};
+#endif
diff --git a/libglusterfs/src/glusterfs/monitoring.h b/libglusterfs/src/glusterfs/monitoring.h
new file mode 100644
index 00000000000..09d9f54e734
--- /dev/null
+++ b/libglusterfs/src/glusterfs/monitoring.h
@@ -0,0 +1,21 @@
+/*
+ Copyright (c) 2017 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 __MONITORING_H__
+#define __MONITORING_H__
+
+#include "glusterfs/glusterfs.h"
+
+#define GLUSTER_METRICS_DIR "/var/run/gluster/metrics"
+
+char *
+gf_monitor_metrics(glusterfs_ctx_t *ctx);
+
+#endif /* __MONITORING_H__ */
diff --git a/libglusterfs/src/glusterfs/options.h b/libglusterfs/src/glusterfs/options.h
new file mode 100644
index 00000000000..747b13ba375
--- /dev/null
+++ b/libglusterfs/src/glusterfs/options.h
@@ -0,0 +1,327 @@
+/*
+ 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
+
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "glusterfs/xlator.h"
+#include "glusterfs/libglusterfs-messages.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_CLIENT_AUTH_ADDR,
+ GF_OPTION_TYPE_MAX,
+} volume_option_type_t;
+
+typedef enum {
+ GF_OPT_VALIDATE_BOTH = 0,
+ GF_OPT_VALIDATE_MIN,
+ GF_OPT_VALIDATE_MAX,
+} opt_validate_type_t;
+
+typedef enum {
+ OPT_FLAG_NONE = 0,
+ OPT_FLAG_SETTABLE = 1 << 0, /* can be set using volume set */
+ OPT_FLAG_CLIENT_OPT = 1 << 1, /* affects clients */
+ OPT_FLAG_GLOBAL = 1
+ << 2, /* affects all instances of the particular xlator */
+ OPT_FLAG_FORCE = 1 << 3, /* needs force to be reset */
+ OPT_FLAG_NEVER_RESET = 1 << 4, /* which should not be reset */
+ OPT_FLAG_DOC = 1 << 5, /* can be shown in volume set help */
+} opt_flags_t;
+
+typedef enum {
+ OPT_STATUS_ADVANCED = 0,
+ OPT_STATUS_BASIC = 1,
+ OPT_STATUS_EXPERIMENTAL = 2,
+ OPT_STATUS_DEPRECATED = 3,
+} opt_level_t;
+
+#define ZR_VOLUME_MAX_NUM_KEY 4
+#define ZR_OPTION_MAX_ARRAY_SIZE 64
+/* The maximum number of releases that an option could be backported to
+ * based on the release schedule as in August 2017 (3), plus one more
+ * Refer comment on volume_options.op_version for more information.
+ */
+#define GF_MAX_RELEASES 4
+
+/* Custom validation functoins for options
+ * TODO: Need to check what sorts of validation is being done, and decide if
+ * passing the volinfo is actually required. If it is, then we should possibly
+ * try a solution in GD2 for this.
+ */
+/* typedef int (*option_validation_fn) (glusterd_volinfo_t *volinfo, dict_t
+ *dict, char *key, char *value, char **op_errstr);
+ */
+
+/* Each translator should define this structure */
+/* XXX: This structure is in use by GD2, and SHOULD NOT be modified.
+ * If there is a need to add new members, add them to the end of the structure.
+ * If the struct must be modified, GD2 MUST be updated as well
+ */
+typedef struct volume_options {
+ char *key[ZR_VOLUME_MAX_NUM_KEY];
+ /* different key, same meaning */
+ volume_option_type_t type;
+ double min; /* 0 means no range */
+ double 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 */
+ /* Required for int options where only the min value
+ * is given and is 0. This will cause validation not to
+ * happen
+ */
+ opt_validate_type_t validate;
+
+ /* The op-version at which this option was introduced.
+ * This is an array to support options that get backported to supported
+ * releases.
+ * Normally, an option introduced for a major release just has a single
+ * entry in the array, with op-version of the major release
+ * For an option that is backported, the op-versions of the all the
+ * releases it was ported to should be added, starting from the newest,
+ * to the oldest.
+ */
+ uint32_t op_version[GF_MAX_RELEASES];
+ /* The op-version at which this option was deprecated.
+ * Follows the same rules as above.
+ */
+ uint32_t deprecated[GF_MAX_RELEASES];
+ /* Additional flags for an option
+ * Check the OPT_FLAG_* enums for available flags
+ */
+ uint32_t flags;
+ /* Tags applicable to this option, which can be used to group similar
+ * options
+ */
+ char *tags[ZR_OPTION_MAX_ARRAY_SIZE];
+ /* A custom validation function if required
+ * TODO: See todo above for option_validation_fn
+ */
+ /* option_validation_fn validate_fn; */
+ /* This is actual key that should be set in the options dict. Can
+ * contain varstrings
+ */
+ char *setkey;
+
+ /* A 'level' is about the technical depth / understanding one
+ needs to handle the option. 'category' is based on
+ quality (ie, tests, people behind it, documentation available) */
+
+ /* The level at which the option is classified */
+ opt_level_t level;
+
+ /* Flag to understand how this option is categorized */
+ gf_category_t category;
+} 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);
+
+int
+xlator_option_validate_addr_list(xlator_t *xl, const char *key,
+ const char *value, volume_option_t *opt,
+ char **op_errstr);
+
+volume_option_t *
+xlator_volume_option_get(xlator_t *xl, const char *key);
+
+volume_option_t *
+xlator_volume_option_get_list(volume_opt_list_t *vol_list, 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(uint64_t, size_uint64);
+DECLARE_INIT_OPT(double, percent);
+DECLARE_INIT_OPT(double, percent_or_size);
+DECLARE_INIT_OPT(gf_boolean_t, bool);
+DECLARE_INIT_OPT(xlator_t *, xlator);
+DECLARE_INIT_OPT(char *, path);
+DECLARE_INIT_OPT(double, double);
+DECLARE_INIT_OPT(uint32_t, time);
+
+#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_msg(this->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ENTRY, \
+ "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_msg_trace(this->name, 0, "option %s not set", key); \
+ *val_p = (type_t)0; \
+ return 0; \
+ } \
+ if (value == def_value) { \
+ gf_msg_trace(this->name, 0, \
+ "option %s using default" \
+ " value %s", \
+ key, value); \
+ } else { \
+ gf_msg_debug(this->name, 0, \
+ "option %s using set" \
+ " value %s", \
+ key, value); \
+ } \
+ old_THIS = THIS; \
+ THIS = this; \
+ ret = conv(value, val_p); \
+ THIS = old_THIS; \
+ if (ret) { \
+ gf_msg(this->name, GF_LOG_INFO, 0, LG_MSG_CONVERSION_FAILED, \
+ "option %s conversion failed value %s", key, value); \
+ 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, int keylen, 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(uint64_t, size_uint64);
+DECLARE_RECONF_OPT(double, percent);
+DECLARE_RECONF_OPT(double, percent_or_size);
+DECLARE_RECONF_OPT(gf_boolean_t, bool);
+DECLARE_RECONF_OPT(xlator_t *, xlator);
+DECLARE_RECONF_OPT(char *, path);
+DECLARE_RECONF_OPT(double, double);
+DECLARE_RECONF_OPT(uint32_t, time);
+
+#define DEFINE_RECONF_OPT(type_t, type, conv) \
+ int xlator_option_reconf_##type(xlator_t *this, dict_t *options, \
+ char *key, int keylen, type_t *val_p) \
+ { \
+ int ret = 0; \
+ char *value = NULL; \
+ xlator_t *old_THIS = NULL; \
+ \
+ volume_option_t *opt = xlator_volume_option_get(this, key); \
+ if (!opt) { \
+ gf_msg(this->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ENTRY, \
+ "unknown option: %s", key); \
+ return -1; \
+ } \
+ ret = dict_get_strn(options, key, keylen, &value); \
+ if (ret == 0 && value) { \
+ gf_msg(this->name, GF_LOG_INFO, 0, 0, \
+ "option %s using set value %s", key, value); \
+ } else if (opt->default_value) { \
+ value = opt->default_value; \
+ gf_msg_trace(this->name, 0, "option %s using default value %s", \
+ key, value); \
+ } else { \
+ gf_msg_trace(this->name, 0, "option %s not set", key); \
+ *val_p = (type_t)0; \
+ return 0; \
+ } \
+ \
+ old_THIS = THIS; \
+ THIS = this; \
+ ret = conv(value, val_p); \
+ THIS = old_THIS; \
+ if (ret) \
+ return ret; \
+ return xlator_option_validate(this, key, value, opt, NULL); \
+ }
+
+#define GF_OPTION_RECONF(key, val, opt, type, err_label) \
+ do { \
+ if (xlator_option_reconf_##type(THIS, opt, key, SLEN(key), &(val))) \
+ goto err_label; \
+ } while (0)
+
+#endif /* !_OPTIONS_H */
diff --git a/libglusterfs/src/parse-utils.h b/libglusterfs/src/glusterfs/parse-utils.h
index 275ccf3153b..8653b9dd180 100644
--- a/libglusterfs/src/parse-utils.h
+++ b/libglusterfs/src/glusterfs/parse-utils.h
@@ -20,31 +20,31 @@
#define GF_PARSE "parse-utils"
struct parser {
- regex_t preg; /* Compiled regex */
- regmatch_t pmatch[1]; /* The match */
- char *complete_str; /* The string we are parsing */
- char *regex; /* Regex used to parse the string */
- char *_rstr; /* Temp string to hold offsets */
+ regex_t preg; /* Compiled regex */
+ regmatch_t pmatch[1]; /* The match */
+ char *complete_str; /* The string we are parsing */
+ char *regex; /* Regex used to parse the string */
+ char *_rstr; /* Temp string to hold offsets */
};
/* Initializes some of the parsers variables */
struct parser *
-parser_init (const char *regex);
+parser_init(const char *regex);
/* Sets the string to parse */
int
-parser_set_string (struct parser *parser, const char *complete_str);
+parser_set_string(struct parser *parser, const char *complete_str);
/* Frees memory used by the string after all matches are found */
int
-parser_unset_string (struct parser *parser);
+parser_unset_string(struct parser *parser);
/* Free memory used by the parser */
void
-parser_deinit (struct parser *ptr);
+parser_deinit(struct parser *ptr);
/* Get the next matching string */
char *
-parser_get_next_match (struct parser *parser);
+parser_get_next_match(struct parser *parser);
#endif /* _PARSE_UTILS_H */
diff --git a/libglusterfs/src/glusterfs/quota-common-utils.h b/libglusterfs/src/glusterfs/quota-common-utils.h
new file mode 100644
index 00000000000..0096e340756
--- /dev/null
+++ b/libglusterfs/src/glusterfs/quota-common-utils.h
@@ -0,0 +1,68 @@
+/*
+ Copyright (c) 2015 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 _QUOTA_COMMON_UTILS_H
+#define _QUOTA_COMMON_UTILS_H
+
+#include "glusterfs/iatt.h"
+
+#define GF_QUOTA_CONF_VERSION 1.2
+#define QUOTA_CONF_HEADER "GlusterFS Quota conf | version: v1.2\n"
+#define QUOTA_CONF_HEADER_1_1 "GlusterFS Quota conf | version: v1.1\n"
+
+typedef enum {
+ GF_QUOTA_CONF_TYPE_USAGE = 1,
+ GF_QUOTA_CONF_TYPE_OBJECTS
+} gf_quota_conf_type_t;
+
+struct _quota_limits {
+ int64_t hl;
+ int64_t sl;
+} __attribute__((__packed__));
+typedef struct _quota_limits quota_limits_t;
+
+struct _quota_meta {
+ int64_t size;
+ int64_t file_count;
+ int64_t dir_count;
+} __attribute__((__packed__));
+typedef struct _quota_meta quota_meta_t;
+
+gf_boolean_t
+quota_meta_is_null(const quota_meta_t *meta);
+
+int32_t
+quota_data_to_meta(data_t *data, quota_meta_t *meta);
+
+int32_t
+quota_dict_get_inode_meta(dict_t *dict, char *key, const int keylen,
+ quota_meta_t *meta);
+
+int32_t
+quota_dict_get_meta(dict_t *dict, char *key, const int keylen,
+ quota_meta_t *meta);
+
+int32_t
+quota_dict_set_meta(dict_t *dict, char *key, const quota_meta_t *meta,
+ ia_type_t ia_type);
+
+int32_t
+quota_conf_read_header(int fd, char *buf);
+
+int32_t
+quota_conf_read_version(int fd, float *version);
+
+int32_t
+quota_conf_read_gfid(int fd, void *buf, char *type, float version);
+
+int32_t
+quota_conf_skip_header(int fd);
+
+#endif /* _QUOTA_COMMON_UTILS_H */
diff --git a/libglusterfs/src/glusterfs/rbthash.h b/libglusterfs/src/glusterfs/rbthash.h
new file mode 100644
index 00000000000..4c731de69c2
--- /dev/null
+++ b/libglusterfs/src/glusterfs/rbthash.h
@@ -0,0 +1,75 @@
+/*
+ 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 __RBTHASH_TABLE_H_
+#define __RBTHASH_TABLE_H_
+
+#include <stdint.h> // for uint32_t
+#include "glusterfs/glusterfs.h" // for gf_boolean_t, glusterfs_ctx_t
+#include "glusterfs/list.h" // for list_head
+#include "glusterfs/locking.h" // for gf_lock_t
+struct mem_pool;
+
+#define GF_RBTHASH_MEMPOOL 16384 // 1048576
+#define GF_RBTHASH "rbthash"
+
+struct rbthash_bucket {
+ struct rb_table *bucket;
+ gf_lock_t bucketlock;
+};
+
+typedef struct rbthash_entry {
+ void *data;
+ void *key;
+ 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;
+ int numbuckets;
+ struct mem_pool *entrypool;
+ gf_lock_t tablelock;
+ struct rbthash_bucket *buckets;
+ 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 *
+rbthash_table_init(glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc,
+ rbt_data_destroyer_t dfunc, unsigned long expected_entries,
+ struct mem_pool *entrypool);
+
+extern int
+rbthash_insert(rbthash_table_t *tbl, void *data, void *key, int keylen);
+
+extern void *
+rbthash_get(rbthash_table_t *tbl, void *key, int keylen);
+
+extern void *
+rbthash_remove(rbthash_table_t *tbl, void *key, int keylen);
+
+extern void *
+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/refcount.h b/libglusterfs/src/glusterfs/refcount.h
index e850e6389ae..cf922dabb05 100644
--- a/libglusterfs/src/refcount.h
+++ b/libglusterfs/src/glusterfs/refcount.h
@@ -17,33 +17,33 @@
* http://lists.iptel.org/pipermail/semsdev/2010-October/005075.html
* this is sufficient for RHEL5 i386 builds
*/
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && !defined(__i386__)
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && \
+ !defined(__i386__)
#undef REFCOUNT_NEEDS_LOCK
#else
#define REFCOUNT_NEEDS_LOCK
-#include "locking.h"
+#include "glusterfs/locking.h"
#endif /* compiler support for __sync_*_and_fetch() */
typedef void (*gf_ref_release_t)(void *data);
-struct _gf_ref_t {
+struct _gf_ref {
#ifdef REFCOUNT_NEEDS_LOCK
- gf_lock_t lk; /* lock for atomically adjust cnt */
+ gf_lock_t lk; /* lock for atomically adjust cnt */
#endif
- unsigned int cnt; /* number of users, free on 0 */
+ unsigned int cnt; /* number of users, free on 0 */
- gf_ref_release_t release; /* cleanup when cnt == 0 */
- void *data; /* parameter passed to release() */
+ gf_ref_release_t release; /* cleanup when cnt == 0 */
+ void *data; /* parameter passed to release() */
};
-typedef struct _gf_ref_t gf_ref_t;
-
+typedef struct _gf_ref gf_ref_t;
/* _gf_ref_get -- increase the refcount
*
* @return: greater then 0 when a reference was taken, 0 when not
*/
-unsigned int
-_gf_ref_get (gf_ref_t *ref);
+void *
+_gf_ref_get(gf_ref_t *ref);
/* _gf_ref_put -- decrease the refcount
*
@@ -51,16 +51,15 @@ _gf_ref_get (gf_ref_t *ref);
* should be done, gf_ref_release_t is called on cleanup
*/
unsigned int
-_gf_ref_put (gf_ref_t *ref);
+_gf_ref_put(gf_ref_t *ref);
-/* _gf_ref_init -- initalize an embedded refcount object
+/* _gf_ref_init -- initialize an embedded refcount object
*
* @release: function to call when the refcount == 0
* @data: parameter to be passed to @release
*/
void
-_gf_ref_init (gf_ref_t *ref, gf_ref_release_t release, void *data);
-
+_gf_ref_init(gf_ref_t *ref, gf_ref_release_t release, void *data);
/*
* Strong suggestion to use the simplified GF_REF_* API.
@@ -75,7 +74,7 @@ _gf_ref_init (gf_ref_t *ref, gf_ref_release_t release, void *data);
* ... // additional members
* };
*/
-#define GF_REF_DECL gf_ref_t _ref
+#define GF_REF_DECL gf_ref_t _ref
/* GF_REF_INIT -- initialize a GF_REF_DECL structure
*
@@ -84,20 +83,19 @@ _gf_ref_init (gf_ref_t *ref, gf_ref_release_t release, void *data);
*
* Sets the refcount to 1.
*/
-#define GF_REF_INIT(p, d) _gf_ref_init (&p->_ref, d, p)
+#define GF_REF_INIT(p, d) _gf_ref_init(&(p)->_ref, (gf_ref_release_t)d, p)
/* GF_REF_GET -- increase the refcount of a GF_REF_DECL structure
*
* @return: greater then 0 when a reference was taken, 0 when not
*/
-#define GF_REF_GET(p) _gf_ref_get (&p->_ref)
+#define GF_REF_GET(p) _gf_ref_get(&(p)->_ref)
/* GF_REF_PUT -- decrease the refcount of a GF_REF_DECL structure
*
* @return: greater then 0 when there are still references, 0 when cleanup
* should be done, gf_ref_release_t is called on cleanup
*/
-#define GF_REF_PUT(p) _gf_ref_put (&p->_ref)
-
+#define GF_REF_PUT(p) _gf_ref_put(&(p)->_ref)
#endif /* _REFCOUNT_H */
diff --git a/libglusterfs/src/glusterfs/revision.h b/libglusterfs/src/glusterfs/revision.h
new file mode 100644
index 00000000000..3c404d30e78
--- /dev/null
+++ b/libglusterfs/src/glusterfs/revision.h
@@ -0,0 +1 @@
+#define GLUSTERFS_REPOSITORY_REVISION "git://git.gluster.org/glusterfs.git"
diff --git a/libglusterfs/src/glusterfs/rot-buffs.h b/libglusterfs/src/glusterfs/rot-buffs.h
new file mode 100644
index 00000000000..9dc227d58b8
--- /dev/null
+++ b/libglusterfs/src/glusterfs/rot-buffs.h
@@ -0,0 +1,125 @@
+/*
+ Copyright (c) 2008-2015 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 __ROT_BUFFS_H
+#define __ROT_BUFFS_H
+
+#include "glusterfs/list.h"
+#include "glusterfs/locking.h"
+#include "glusterfs/common-utils.h"
+
+typedef struct rbuf_iovec {
+ struct iovec iov;
+
+ struct list_head list;
+} rbuf_iovec_t;
+
+#define RBUF_IOVEC_SIZE (sizeof(rbuf_iovec_t))
+
+typedef struct rbuf_list {
+ gf_lock_t c_lock;
+
+ pthread_mutex_t b_lock; /* protects this structure */
+ pthread_cond_t b_cond; /* signal for writer completion */
+
+ gf_boolean_t awaiting;
+
+ unsigned long long pending; /* pending writers */
+ unsigned long long completed; /* completed writers */
+
+ rbuf_iovec_t *rvec; /* currently used IO vector */
+
+ struct list_head veclist; /* list of attached rbuf_iov */
+
+ unsigned long long used; /* consumable entries
+ attached in ->veclist */
+ unsigned long long total; /* total entries in ->veclist (used
+ during deallocation) */
+
+ unsigned long seq[2]; /* if interested, this whould store
+ the start sequence number and the
+ range */
+
+ struct list_head list; /* attachment to rbuf_t */
+} rbuf_list_t;
+
+struct rlist_iter {
+ struct list_head veclist;
+
+ unsigned long long iter;
+};
+
+#define RLIST_ENTRY_COUNT(rlist) rlist->used
+
+#define rlist_iter_init(riter, rlist) \
+ do { \
+ (riter)->iter = rlist->used; \
+ (riter)->veclist = rlist->veclist; \
+ } while (0)
+
+#define rvec_for_each_entry(pos, riter) \
+ for (pos = list_entry((riter)->veclist.next, typeof(*pos), list); \
+ (riter)->iter > 0; \
+ pos = list_entry(pos->list.next, typeof(*pos), list), \
+ --((riter)->iter))
+
+/**
+ * Sequence number assignment routine is called during buffer
+ * switch under rbuff ->lock.
+ */
+typedef void(sequence_fn)(rbuf_list_t *, void *);
+
+#define RLIST_STORE_SEQ(rlist, start, range) \
+ do { \
+ rlist->seq[0] = start; \
+ rlist->seq[1] = range; \
+ } while (0)
+
+#define RLIST_GET_SEQ(rlist, start, range) \
+ do { \
+ start = rlist->seq[0]; \
+ range = rlist->seq[1]; \
+ } while (0)
+
+typedef struct rbuf {
+ gf_lock_t lock; /* protects "current" rlist */
+
+ rbuf_list_t *current; /* cached pointer to first free rlist */
+
+ struct list_head freelist;
+} rbuf_t;
+
+typedef enum {
+ RBUF_CONSUMABLE = 1,
+ RBUF_BUSY,
+ RBUF_EMPTY,
+ RBUF_WOULD_STARVE,
+} rlist_retval_t;
+
+/* Initialization/Destruction */
+rbuf_t *
+rbuf_init(int);
+void
+rbuf_dtor(rbuf_t *);
+
+/* Producer API */
+char *
+rbuf_reserve_write_area(rbuf_t *, size_t, void **);
+int
+rbuf_write_complete(void *);
+
+/* Consumer API */
+int
+rbuf_get_buffer(rbuf_t *, void **, sequence_fn *, void *);
+int
+rbuf_wait_for_completion(rbuf_t *, void *, void (*)(rbuf_list_t *, void *),
+ void *);
+
+#endif
diff --git a/libglusterfs/src/run.h b/libglusterfs/src/glusterfs/run.h
index 1dc4bf9f1b0..76af95fd27f 100644
--- a/libglusterfs/src/run.h
+++ b/libglusterfs/src/glusterfs/run.h
@@ -14,12 +14,12 @@
#define RUN_PIPE -1
struct runner {
- char **argv;
- unsigned argvlen;
- int runerr;
- pid_t chpid;
- int chfd[3];
- FILE *chio[3];
+ char **argv;
+ unsigned argvlen;
+ int runerr;
+ pid_t chpid;
+ int chfd[3];
+ FILE *chio[3];
};
typedef struct runner runner_t;
@@ -29,7 +29,8 @@ typedef struct runner runner_t;
*
* @param runner pointer to runner_t instance
*/
-void runinit (runner_t *runner);
+void
+runinit(runner_t *runner);
/**
* get FILE pointer to which child's stdio is redirected.
@@ -40,7 +41,8 @@ void runinit (runner_t *runner);
*
* @see runner_redir()
*/
-FILE *runner_chio (runner_t *runner, int fd);
+FILE *
+runner_chio(runner_t *runner, int fd);
/**
* add an argument.
@@ -52,7 +54,8 @@ FILE *runner_chio (runner_t *runner, int fd);
* @param runner pointer to runner_t instance
* @param arg command line argument
*/
-void runner_add_arg (runner_t *runner, const char *arg);
+void
+runner_add_arg(runner_t *runner, const char *arg);
/**
* add a sequence of arguments.
@@ -66,7 +69,8 @@ void runner_add_arg (runner_t *runner, const char *arg);
*
* @see runner_add_arg()
*/
-void runner_add_args (runner_t *runner, ...);
+void
+runner_add_args(runner_t *runner, ...);
/**
* add an argument with printf style formatting.
@@ -76,8 +80,9 @@ void runner_add_args (runner_t *runner, ...);
* @param runner pointer to runner_t instance
* @param format printf style format specifier
*/
-void runner_argprintf (runner_t *runner, const char *format, ...);
-
+void
+runner_argprintf(runner_t *runner, const char *format, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
/**
* log a message about the command to be run.
*
@@ -89,8 +94,9 @@ void runner_argprintf (runner_t *runner, const char *format, ...);
*
* @see gf_log()
*/
-void runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
- const char *msg);
+void
+runner_log(runner_t *runner, const char *dom, gf_loglevel_t lvl,
+ const char *msg);
/**
* set up redirection for child.
@@ -111,7 +117,7 @@ void runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
* @see runner_start(), dup(2), runner_chio(), runner_start()
*/
void
-runner_redir (runner_t *runner, int fd, int tgt_fd);
+runner_redir(runner_t *runner, int fd, int tgt_fd);
/**
* spawn child with accumulated arg list.
@@ -123,7 +129,8 @@ runner_redir (runner_t *runner, int fd, int tgt_fd);
*
* @see runner_cout()
*/
-int runner_start (runner_t *runner);
+int
+runner_start(runner_t *runner);
/**
* complete operation and free resources.
@@ -140,7 +147,8 @@ int runner_start (runner_t *runner);
*
* @see waitpid(2)
*/
-int runner_end (runner_t *runner);
+int
+runner_end(runner_t *runner);
/**
* variant of runner_end() which does not free internal data
@@ -148,7 +156,8 @@ int runner_end (runner_t *runner);
*
* @see runner_end()
*/
-int runner_end_reuse (runner_t *runner);
+int
+runner_end_reuse(runner_t *runner);
/**
* spawn and child, take it to completion and free resources.
@@ -163,13 +172,15 @@ int runner_end_reuse (runner_t *runner);
*
* @see runner_start(), runner_end()
*/
-int runner_run (runner_t *runner);
+int
+runner_run(runner_t *runner);
/**
* variant for runner_run() which does not wait for acknowledgement
* from child, and always assumes it succeeds.
*/
-int runner_run_nowait (runner_t *runner);
+int
+runner_run_nowait(runner_t *runner);
/**
* variant of runner_run() which does not free internal data
@@ -177,7 +188,8 @@ int runner_run_nowait (runner_t *runner);
*
* @see runner_run()
*/
-int runner_run_reuse (runner_t *runner);
+int
+runner_run_reuse(runner_t *runner);
/**
* run a command with args.
@@ -189,6 +201,7 @@ int runner_run_reuse (runner_t *runner);
* @return 0 on success
* -1 on failure
*/
-int runcmd (const char *arg, ...);
+int
+runcmd(const char *arg, ...);
#endif
diff --git a/libglusterfs/src/glusterfs/stack.h b/libglusterfs/src/glusterfs/stack.h
new file mode 100644
index 00000000000..536a330d38b
--- /dev/null
+++ b/libglusterfs/src/glusterfs/stack.h
@@ -0,0 +1,555 @@
+/*
+ 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.
+*/
+
+/*
+ This file defines MACROS and static inlines used to emulate a function
+ call over asynchronous communication with remote server
+*/
+
+#ifndef _STACK_H
+#define _STACK_H
+
+struct _call_stack;
+typedef struct _call_stack call_stack_t;
+struct _call_frame;
+typedef struct _call_frame call_frame_t;
+struct call_pool;
+typedef struct call_pool call_pool_t;
+
+#include <sys/time.h>
+
+#include "glusterfs/xlator.h"
+#include "glusterfs/dict.h"
+#include "glusterfs/list.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/lkowner.h"
+#include "glusterfs/client_t.h"
+#include "glusterfs/libglusterfs-messages.h"
+#include "glusterfs/timespec.h"
+
+#define NFS_PID 1
+#define LOW_PRIO_PROC_PID -1
+
+#define STACK_ERR_XL_NAME(stack) (stack->err_xl ? stack->err_xl->name : "-")
+#define STACK_CLIENT_NAME(stack) \
+ (stack->client ? stack->client->client_uid : "-")
+
+typedef int32_t (*ret_fn_t)(call_frame_t *frame, call_frame_t *prev_frame,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ ...);
+
+void
+gf_frame_latency_update(call_frame_t *frame);
+
+struct call_pool {
+ union {
+ struct list_head all_frames;
+ struct {
+ call_stack_t *next_call;
+ call_stack_t *prev_call;
+ } all_stacks;
+ };
+ int64_t cnt;
+ gf_atomic_t total_count;
+ gf_lock_t lock;
+ struct mem_pool *frame_mem_pool;
+ struct mem_pool *stack_mem_pool;
+};
+
+struct _call_frame {
+ call_stack_t *root; /* stack root */
+ call_frame_t *parent; /* previous BP */
+ struct list_head frames;
+ void *local; /* local variables */
+ xlator_t *this; /* implicit object */
+ ret_fn_t ret; /* op_return address */
+ int32_t ref_count;
+ gf_lock_t lock;
+ void *cookie; /* unique cookie */
+ gf_boolean_t complete;
+
+ glusterfs_fop_t op;
+ struct timespec begin; /* when this frame was created */
+ struct timespec end; /* when this frame completed */
+ const char *wind_from;
+ const char *wind_to;
+ const char *unwind_from;
+ const char *unwind_to;
+};
+
+struct _ns_info {
+ uint32_t hash; /* Hash of the namespace from SuperFastHash */
+ gf_boolean_t found; /* Set to true if we found a namespace */
+};
+
+typedef struct _ns_info ns_info_t;
+
+#define SMALL_GROUP_COUNT 128
+
+struct _call_stack {
+ union {
+ struct list_head all_frames;
+ struct {
+ call_stack_t *next_call;
+ call_stack_t *prev_call;
+ };
+ };
+ call_pool_t *pool;
+ gf_lock_t stack_lock;
+ client_t *client;
+ uint64_t unique;
+ void *state; /* pointer to request state */
+ uid_t uid;
+ gid_t gid;
+ pid_t pid;
+ char identifier[UNIX_PATH_MAX];
+ uint16_t ngrps;
+ uint32_t groups_small[SMALL_GROUP_COUNT];
+ uint32_t *groups_large;
+ uint32_t *groups;
+ gf_lkowner_t lk_owner;
+ glusterfs_ctx_t *ctx;
+
+ struct list_head myframes; /* List of call_frame_t that go
+ to make the call stack */
+
+ int32_t op;
+ int8_t type;
+ struct timespec tv;
+ xlator_t *err_xl;
+ int32_t error;
+
+ uint32_t flags; /* use it wisely, think of it as a mechanism to
+ send information over the wire too */
+ struct timespec ctime; /* timestamp, most probably set at
+ creation of stack. */
+
+ ns_info_t ns_info;
+};
+
+/* call_stack flags field users */
+#define MDATA_CTIME (1 << 0)
+#define MDATA_MTIME (1 << 1)
+#define MDATA_ATIME (1 << 2)
+#define MDATA_PAR_CTIME (1 << 3)
+#define MDATA_PAR_MTIME (1 << 4)
+#define MDATA_PAR_ATIME (1 << 5)
+
+#define frame_set_uid_gid(frm, u, g) \
+ do { \
+ if (frm) { \
+ (frm)->root->uid = u; \
+ (frm)->root->gid = g; \
+ (frm)->root->ngrps = 0; \
+ } \
+ } while (0);
+
+struct xlator_fops;
+
+static inline void
+FRAME_DESTROY(call_frame_t *frame)
+{
+ void *local = NULL;
+
+ if (frame->root->ctx->measure_latency)
+ gf_frame_latency_update(frame);
+
+ list_del_init(&frame->frames);
+ if (frame->local) {
+ local = frame->local;
+ frame->local = NULL;
+ }
+
+ LOCK_DESTROY(&frame->lock);
+ mem_put(frame);
+
+ if (local)
+ mem_put(local);
+}
+
+static inline void
+STACK_DESTROY(call_stack_t *stack)
+{
+ call_frame_t *frame = NULL;
+ call_frame_t *tmp = NULL;
+
+ LOCK(&stack->pool->lock);
+ {
+ list_del_init(&stack->all_frames);
+ stack->pool->cnt--;
+ }
+ UNLOCK(&stack->pool->lock);
+
+ LOCK_DESTROY(&stack->stack_lock);
+
+ list_for_each_entry_safe(frame, tmp, &stack->myframes, frames)
+ {
+ FRAME_DESTROY(frame);
+ }
+
+ GF_FREE(stack->groups_large);
+
+ mem_put(stack);
+}
+
+static inline void
+STACK_RESET(call_stack_t *stack)
+{
+ call_frame_t *frame = NULL;
+ call_frame_t *tmp = NULL;
+ call_frame_t *last = NULL;
+ struct list_head toreset = {0};
+
+ INIT_LIST_HEAD(&toreset);
+
+ /* We acquire call_pool->lock only to remove the frames from this stack
+ * to preserve atomicity. This synchronizes across concurrent requests
+ * like statedump, STACK_DESTROY etc. */
+
+ LOCK(&stack->pool->lock);
+ {
+ last = list_last_entry(&stack->myframes, call_frame_t, frames);
+ list_del_init(&last->frames);
+ list_splice_init(&stack->myframes, &toreset);
+ list_add(&last->frames, &stack->myframes);
+ }
+ UNLOCK(&stack->pool->lock);
+
+ list_for_each_entry_safe(frame, tmp, &toreset, frames)
+ {
+ FRAME_DESTROY(frame);
+ }
+}
+
+#define FRAME_SU_DO(frm, local_type) \
+ do { \
+ local_type *__local = (frm)->local; \
+ __local->uid = frm->root->uid; \
+ __local->gid = frm->root->gid; \
+ __local->pid = frm->root->pid; \
+ frm->root->uid = 0; \
+ frm->root->gid = 0; \
+ frm->root->pid = GF_CLIENT_PID_NO_ROOT_SQUASH; \
+ } while (0);
+
+#define FRAME_SU_UNDO(frm, local_type) \
+ do { \
+ local_type *__local = (frm)->local; \
+ frm->root->uid = __local->uid; \
+ frm->root->gid = __local->gid; \
+ frm->root->pid = __local->pid; \
+ } while (0);
+
+/* NOTE: make sure to keep this as an macro, mainly because, we need 'fn'
+ field here to be the proper fn ptr, so its address is valid entry in
+ 'xlator_fops' struct.
+ To understand this, check the `xlator.h:struct xlator_fops`, and then
+ see a STACK_WIND call, which generally calls `subvol->fops->fop`, so
+ the address offset should give the index */
+
+/* +1 is required as 0 means NULL fop, and we don't have a variable for it */
+#define get_fop_index_from_fn(xl, fn) \
+ (1 + (((long)&(fn) - (long)&((xl)->fops->stat)) / sizeof(void *)))
+
+/* NOTE: the above reason holds good here too. But notice that we are getting
+ the base address of the 'stat' fop, which is the first entry in the fop
+ structure. All we need to do is move as much as 'idx' fields, and get the
+ actual pointer from that field. */
+
+static inline void *
+get_the_pt_fop(void *base_fop, int fop_idx)
+{
+ void *target_addr = (base_fop + ((fop_idx - 1) * sizeof(void *)));
+ /* all below type casting is for not getting warning. */
+ return (void *)*(unsigned long *)target_addr;
+}
+
+/* make a call without switching frames */
+#define STACK_WIND_TAIL(frame, obj, fn, params...) \
+ do { \
+ xlator_t *old_THIS = NULL; \
+ xlator_t *next_xl = obj; \
+ typeof(fn) next_xl_fn = fn; \
+ int opn = get_fop_index_from_fn((next_xl), (fn)); \
+ \
+ frame->this = next_xl; \
+ frame->wind_to = #fn; \
+ old_THIS = THIS; \
+ THIS = next_xl; \
+ gf_msg_trace("stack-trace", 0, \
+ "stack-address: %p, " \
+ "winding from %s to %s", \
+ frame->root, old_THIS->name, THIS->name); \
+ /* Need to capture counts at leaf node */ \
+ if (!next_xl->pass_through && !next_xl->children) { \
+ GF_ATOMIC_INC(next_xl->stats.total.metrics[opn].fop); \
+ GF_ATOMIC_INC(next_xl->stats.interval.metrics[opn].fop); \
+ GF_ATOMIC_INC(next_xl->stats.total.count); \
+ GF_ATOMIC_INC(next_xl->stats.interval.count); \
+ } \
+ \
+ if (next_xl->pass_through) { \
+ next_xl_fn = get_the_pt_fop(&next_xl->pass_through_fops->stat, \
+ opn); \
+ } \
+ next_xl_fn(frame, next_xl, params); \
+ THIS = old_THIS; \
+ } while (0)
+
+/* make a call */
+#define STACK_WIND(frame, rfn, obj, fn, params...) \
+ STACK_WIND_COMMON(frame, rfn, 0, NULL, obj, fn, params)
+
+/* make a call with a cookie */
+#define STACK_WIND_COOKIE(frame, rfn, cky, obj, fn, params...) \
+ STACK_WIND_COMMON(frame, rfn, 1, cky, obj, fn, params)
+
+/* Cookie passed as the argument can be NULL (ptr) or 0 (int). Hence we
+ have to have a mechanism to separate out the two STACK_WIND formats.
+ Needed a common macro, as other than for cookie, all the other code
+ is common across.
+ */
+#define STACK_WIND_COMMON(frame, rfn, has_cookie, cky, obj, fn, params...) \
+ do { \
+ call_frame_t *_new = NULL; \
+ xlator_t *old_THIS = NULL; \
+ typeof(fn) next_xl_fn = fn; \
+ \
+ _new = mem_get0(frame->root->pool->frame_mem_pool); \
+ if (!_new) { \
+ break; \
+ } \
+ typeof(fn##_cbk) tmp_cbk = rfn; \
+ _new->root = frame->root; \
+ _new->this = obj; \
+ _new->ret = (ret_fn_t)tmp_cbk; \
+ _new->parent = frame; \
+ /* (void *) is required for avoiding gcc warning */ \
+ _new->cookie = ((has_cookie == 1) ? (void *)(cky) : (void *)_new); \
+ _new->wind_from = __FUNCTION__; \
+ _new->wind_to = #fn; \
+ _new->unwind_to = #rfn; \
+ LOCK_INIT(&_new->lock); \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ list_add(&_new->frames, &frame->root->myframes); \
+ frame->ref_count++; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
+ fn##_cbk = rfn; \
+ old_THIS = THIS; \
+ THIS = obj; \
+ gf_msg_trace("stack-trace", 0, \
+ "stack-address: %p, " \
+ "winding from %s to %s", \
+ frame->root, old_THIS->name, THIS->name); \
+ if (obj->ctx->measure_latency) \
+ timespec_now(&_new->begin); \
+ _new->op = get_fop_index_from_fn((_new->this), (fn)); \
+ if (!obj->pass_through) { \
+ GF_ATOMIC_INC(obj->stats.total.metrics[_new->op].fop); \
+ GF_ATOMIC_INC(obj->stats.interval.metrics[_new->op].fop); \
+ GF_ATOMIC_INC(obj->stats.total.count); \
+ GF_ATOMIC_INC(obj->stats.interval.count); \
+ } else { \
+ /* we want to get to the actual fop to call */ \
+ next_xl_fn = get_the_pt_fop(&obj->pass_through_fops->stat, \
+ _new->op); \
+ } \
+ next_xl_fn(_new, obj, params); \
+ THIS = old_THIS; \
+ } while (0)
+
+#define STACK_UNWIND STACK_UNWIND_STRICT
+
+/* return from function in type-safe way */
+#define STACK_UNWIND_STRICT(fop, frame, op_ret, op_errno, params...) \
+ do { \
+ fop_##fop##_cbk_t fn = NULL; \
+ call_frame_t *_parent = NULL; \
+ xlator_t *old_THIS = NULL; \
+ \
+ if (!frame) { \
+ gf_msg("stack", GF_LOG_CRITICAL, 0, LG_MSG_FRAME_ERROR, "!frame"); \
+ break; \
+ } \
+ if ((op_ret) < 0) { \
+ gf_msg_debug("stack-trace", op_errno, \
+ "stack-address: %p, " \
+ "%s returned %d error: %s", \
+ frame->root, THIS->name, (int32_t)(op_ret), \
+ strerror(op_errno)); \
+ } else { \
+ gf_msg_trace("stack-trace", 0, \
+ "stack-address: %p, " \
+ "%s returned %d", \
+ frame->root, THIS->name, (int32_t)(op_ret)); \
+ } \
+ fn = (fop_##fop##_cbk_t)frame->ret; \
+ _parent = frame->parent; \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _parent->ref_count--; \
+ if ((op_ret) < 0 && (op_errno) != frame->root->error) { \
+ frame->root->err_xl = frame->this; \
+ frame->root->error = (op_errno); \
+ } else if ((op_ret) == 0) { \
+ frame->root->err_xl = NULL; \
+ frame->root->error = 0; \
+ } \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
+ old_THIS = THIS; \
+ THIS = _parent->this; \
+ frame->complete = _gf_true; \
+ frame->unwind_from = __FUNCTION__; \
+ if (frame->this->ctx->measure_latency) { \
+ timespec_now(&frame->end); \
+ /* required for top most xlator */ \
+ if (_parent->ret == NULL) \
+ timespec_now(&_parent->end); \
+ } \
+ if (op_ret < 0) { \
+ GF_ATOMIC_INC(THIS->stats.total.metrics[frame->op].cbk); \
+ GF_ATOMIC_INC(THIS->stats.interval.metrics[frame->op].cbk); \
+ } \
+ fn(_parent, frame->cookie, _parent->this, op_ret, op_errno, params); \
+ THIS = old_THIS; \
+ } while (0)
+
+static inline int
+call_stack_alloc_groups(call_stack_t *stack, int ngrps)
+{
+ if (ngrps <= SMALL_GROUP_COUNT) {
+ stack->groups = stack->groups_small;
+ } else {
+ GF_FREE(stack->groups_large);
+ stack->groups_large = GF_CALLOC(ngrps, sizeof(gid_t),
+ gf_common_mt_groups_t);
+ if (!stack->groups_large)
+ return -1;
+ stack->groups = stack->groups_large;
+ }
+
+ stack->ngrps = ngrps;
+
+ return 0;
+}
+
+static inline int
+call_stack_groups_capacity(call_stack_t *stack)
+{
+ return max(stack->ngrps, SMALL_GROUP_COUNT);
+}
+
+static inline int
+call_frames_count(call_stack_t *call_stack)
+{
+ call_frame_t *pos;
+ int32_t count = 0;
+
+ if (!call_stack)
+ return count;
+
+ list_for_each_entry(pos, &call_stack->myframes, frames) count++;
+
+ return count;
+}
+
+static inline call_frame_t *
+copy_frame(call_frame_t *frame)
+{
+ call_stack_t *newstack = NULL;
+ call_stack_t *oldstack = NULL;
+ call_frame_t *newframe = NULL;
+
+ if (!frame) {
+ return NULL;
+ }
+
+ newstack = mem_get0(frame->root->pool->stack_mem_pool);
+ if (newstack == NULL) {
+ return NULL;
+ }
+
+ INIT_LIST_HEAD(&newstack->myframes);
+
+ newframe = mem_get0(frame->root->pool->frame_mem_pool);
+ if (!newframe) {
+ mem_put(newstack);
+ return NULL;
+ }
+
+ newframe->this = frame->this;
+ newframe->root = newstack;
+ INIT_LIST_HEAD(&newframe->frames);
+ list_add(&newframe->frames, &newstack->myframes);
+
+ oldstack = frame->root;
+
+ newstack->uid = oldstack->uid;
+ newstack->gid = oldstack->gid;
+ newstack->pid = oldstack->pid;
+ newstack->op = oldstack->op;
+ newstack->type = oldstack->type;
+ newstack->ctime = oldstack->ctime;
+ newstack->flags = oldstack->flags;
+ if (call_stack_alloc_groups(newstack, oldstack->ngrps) != 0) {
+ mem_put(newstack);
+ return NULL;
+ }
+ if (!oldstack->groups) {
+ gf_msg_debug("stack", EINVAL, "groups is null (ngrps: %d)",
+ oldstack->ngrps);
+ /* Considering 'groups' is NULL, set ngrps to 0 */
+ oldstack->ngrps = 0;
+
+ if (oldstack->groups_large)
+ oldstack->groups = oldstack->groups_large;
+ else
+ oldstack->groups = oldstack->groups_small;
+ }
+ newstack->ngrps = oldstack->ngrps;
+ memcpy(newstack->groups, oldstack->groups, sizeof(gid_t) * oldstack->ngrps);
+ newstack->unique = oldstack->unique;
+ newstack->pool = oldstack->pool;
+ newstack->lk_owner = oldstack->lk_owner;
+ newstack->ctx = oldstack->ctx;
+
+ if (newstack->ctx->measure_latency) {
+ timespec_now(&newstack->tv);
+ memcpy(&newframe->begin, &newstack->tv, sizeof(newstack->tv));
+ }
+
+ LOCK_INIT(&newframe->lock);
+ LOCK_INIT(&newstack->stack_lock);
+
+ LOCK(&oldstack->pool->lock);
+ {
+ list_add(&newstack->all_frames, &oldstack->all_frames);
+ newstack->pool->cnt++;
+ }
+ UNLOCK(&oldstack->pool->lock);
+ GF_ATOMIC_INC(newstack->pool->total_count);
+
+ return newframe;
+}
+
+void
+call_stack_set_groups(call_stack_t *stack, int ngrps, gid_t **groupbuf_p);
+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);
+call_frame_t *
+create_frame(xlator_t *xl, call_pool_t *pool);
+gf_boolean_t
+__is_fuse_call(call_frame_t *frame);
+#endif /* _STACK_H */
diff --git a/libglusterfs/src/glusterfs/statedump.h b/libglusterfs/src/glusterfs/statedump.h
new file mode 100644
index 00000000000..ce082706bdf
--- /dev/null
+++ b/libglusterfs/src/glusterfs/statedump.h
@@ -0,0 +1,132 @@
+/*
+ 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 STATEDUMP_H
+#define STATEDUMP_H
+
+#include <stdarg.h>
+#include "glusterfs/inode.h"
+#include "glusterfs/strfd.h"
+
+#define GF_DUMP_MAX_BUF_LEN 4096
+
+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_ {
+ gf_boolean_t dump_mem;
+ gf_boolean_t dump_iobuf;
+ gf_boolean_t dump_callpool;
+ gf_dump_xl_options_t xl_options; // options for all xlators
+ char *dump_path;
+} gf_dump_options_t;
+
+extern gf_dump_options_t dump_options;
+
+__attribute__((__format__(__printf__, 3, 4))) static inline void
+_gf_proc_dump_build_key(char *key, const char *prefix, const char *fmt, ...)
+{
+ va_list ap;
+ int32_t len;
+
+ len = snprintf(key, GF_DUMP_MAX_BUF_LEN, "%s.", prefix);
+ if (len >= 0) {
+ va_start(ap, fmt);
+ len = vsnprintf(key + len, GF_DUMP_MAX_BUF_LEN - len, fmt, ap);
+ va_end(ap);
+ }
+ if (len < 0) {
+ *key = 0;
+ }
+}
+
+#define gf_proc_dump_build_key(key, key_prefix, fmt...) \
+ { \
+ _gf_proc_dump_build_key(key, key_prefix, ##fmt); \
+ }
+
+#define GF_PROC_DUMP_SET_OPTION(opt, val) opt = val
+
+#define GF_CHECK_DUMP_OPTION_ENABLED(option_dump, var, label) \
+ do { \
+ if (option_dump == _gf_true) { \
+ var = _gf_false; \
+ goto label; \
+ } \
+ } while (0);
+
+void
+gf_proc_dump_init();
+
+void
+gf_proc_dump_fini(void);
+
+void
+gf_proc_dump_cleanup(void);
+
+void
+gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx);
+
+int
+gf_proc_dump_add_section(char *key, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
+
+int
+gf_proc_dump_write(char *key, char *value, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
+
+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);
+
+void
+gf_proc_dump_xlator_private(xlator_t *this, strfd_t *strfd);
+
+void
+gf_proc_dump_mallinfo(strfd_t *strfd);
+
+void
+gf_proc_dump_xlator_history(xlator_t *this, strfd_t *strfd);
+
+void
+gf_proc_dump_xlator_meminfo(xlator_t *this, strfd_t *strfd);
+
+void
+gf_proc_dump_xlator_profile(xlator_t *this, strfd_t *strfd);
+
+void
+gf_latency_statedump_and_reset(char *key, gf_latency_t *lat);
+#endif /* STATEDUMP_H */
diff --git a/libglusterfs/src/glusterfs/store.h b/libglusterfs/src/glusterfs/store.h
new file mode 100644
index 00000000000..a1f70c7b840
--- /dev/null
+++ b/libglusterfs/src/glusterfs/store.h
@@ -0,0 +1,112 @@
+/*
+ Copyright (c) 2013 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 _GLUSTERD_STORE_H_
+#define _GLUSTERD_STORE_H_
+
+#include "glusterfs/compat.h"
+#include "glusterfs/glusterfs.h"
+
+struct gf_store_handle_ {
+ char *path;
+ int fd;
+ int tmp_fd;
+ FILE *read;
+ int locked; /* state of lockf() */
+};
+
+typedef struct gf_store_handle_ gf_store_handle_t;
+
+struct gf_store_iter_ {
+ FILE *file;
+ char filepath[PATH_MAX];
+};
+
+typedef struct gf_store_iter_ gf_store_iter_t;
+
+typedef enum {
+ GD_STORE_SUCCESS,
+ GD_STORE_KEY_NULL,
+ GD_STORE_VALUE_NULL,
+ GD_STORE_KEY_VALUE_NULL,
+ GD_STORE_EOF,
+ GD_STORE_ENOMEM,
+ GD_STORE_STAT_FAILED
+} gf_store_op_errno_t;
+
+int32_t
+gf_store_mkdir(char *path);
+
+int32_t
+gf_store_handle_create_on_absence(gf_store_handle_t **shandle, char *path);
+
+int32_t
+gf_store_mkstemp(gf_store_handle_t *shandle);
+
+int
+gf_store_sync_direntry(char *path);
+
+int32_t
+gf_store_rename_tmppath(gf_store_handle_t *shandle);
+
+int32_t
+gf_store_unlink_tmppath(gf_store_handle_t *shandle);
+
+int
+gf_store_read_and_tokenize(FILE *file, char **iter_key, char **iter_val,
+ gf_store_op_errno_t *store_errno);
+
+int32_t
+gf_store_retrieve_value(gf_store_handle_t *handle, char *key, char **value);
+
+int32_t
+gf_store_save_value(int fd, char *key, char *value);
+
+int32_t
+gf_store_save_items(int fd, char *items);
+
+int32_t
+gf_store_handle_new(const char *path, gf_store_handle_t **handle);
+
+int
+gf_store_handle_retrieve(char *path, gf_store_handle_t **handle);
+
+int32_t
+gf_store_handle_destroy(gf_store_handle_t *handle);
+
+int32_t
+gf_store_iter_new(gf_store_handle_t *shandle, gf_store_iter_t **iter);
+
+int32_t
+gf_store_validate_key_value(char *storepath, char *key, char *val,
+ gf_store_op_errno_t *op_errno);
+
+int32_t
+gf_store_iter_get_next(gf_store_iter_t *iter, char **key, char **value,
+ gf_store_op_errno_t *op_errno);
+
+int32_t
+gf_store_iter_get_matching(gf_store_iter_t *iter, char *key, char **value);
+
+int32_t
+gf_store_iter_destroy(gf_store_iter_t **iter);
+
+char *
+gf_store_strerror(gf_store_op_errno_t op_errno);
+
+int
+gf_store_lock(gf_store_handle_t *sh);
+
+void
+gf_store_unlock(gf_store_handle_t *sh);
+
+int
+gf_store_locked_local(gf_store_handle_t *sh);
+
+#endif
diff --git a/libglusterfs/src/strfd.h b/libglusterfs/src/glusterfs/strfd.h
index 9084e235eef..861cd02e005 100644
--- a/libglusterfs/src/strfd.h
+++ b/libglusterfs/src/glusterfs/strfd.h
@@ -12,19 +12,23 @@
#define _STRFD_H
typedef struct {
- void *data;
- size_t alloc_size;
- size_t size;
- off_t pos;
+ void *data;
+ size_t alloc_size;
+ size_t size;
+ off_t pos;
} strfd_t;
-strfd_t *strfd_open();
+strfd_t *
+strfd_open();
-int strprintf(strfd_t *strfd, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
+int
+strprintf(strfd_t *strfd, const char *fmt, ...)
+ __attribute__((__format__(__printf__, 2, 3)));
-int strvprintf(strfd_t *strfd, const char *fmt, va_list ap);
+int
+strvprintf(strfd_t *strfd, const char *fmt, va_list ap);
-int strfd_close(strfd_t *strfd);
+int
+strfd_close(strfd_t *strfd);
#endif
diff --git a/libglusterfs/src/glusterfs/syncop-utils.h b/libglusterfs/src/glusterfs/syncop-utils.h
new file mode 100644
index 00000000000..1f3ee403edc
--- /dev/null
+++ b/libglusterfs/src/glusterfs/syncop-utils.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (c) 2015, 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 _SYNCOP_UTILS_H
+#define _SYNCOP_UTILS_H
+
+typedef int (*syncop_dir_scan_fn_t)(xlator_t *subvol, gf_dirent_t *entry,
+ loc_t *parent, void *data);
+int
+syncop_ftw(xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn)(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data));
+
+int
+syncop_mt_dir_scan(call_frame_t *frame, xlator_t *subvol, loc_t *loc, int pid,
+ void *data, syncop_dir_scan_fn_t fn, dict_t *xdata,
+ uint32_t max_jobs, uint32_t max_qlen);
+
+int
+syncop_dir_scan(xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn)(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data));
+
+int
+syncop_dirfd(xlator_t *subvol, loc_t *loc, fd_t **fd, int pid);
+
+int
+syncop_is_subvol_local(xlator_t *this, loc_t *loc, gf_boolean_t *is_local);
+
+int
+syncop_gfid_to_path(inode_table_t *itable, xlator_t *subvol, uuid_t gfid,
+ char **path_p);
+
+int
+syncop_ftw_throttle(xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn)(xlator_t *subvol, gf_dirent_t *entry,
+ loc_t *parent, void *data),
+ int count, int sleep_time);
+int
+syncop_inode_find(xlator_t *this, xlator_t *subvol, uuid_t gfid,
+ inode_t **inode, dict_t *xdata, dict_t **rsp_dict);
+
+int
+syncop_gfid_to_path_hard(inode_table_t *itable, xlator_t *subvol, uuid_t gfid,
+ inode_t *inode, char **path_p,
+ gf_boolean_t hard_resolve);
+#endif /* _SYNCOP_H */
diff --git a/libglusterfs/src/glusterfs/syncop.h b/libglusterfs/src/glusterfs/syncop.h
new file mode 100644
index 00000000000..4e9241a32fc
--- /dev/null
+++ b/libglusterfs/src/glusterfs/syncop.h
@@ -0,0 +1,718 @@
+/*
+ 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 _SYNCOP_H
+#define _SYNCOP_H
+
+#include <sys/time.h>
+#include <pthread.h>
+#include <ucontext.h>
+#include "glusterfs/dict.h" // for dict_t
+#include "glusterfs/stack.h" // for call_frame_t, STACK_DESTROY, STACK_...
+#include "glusterfs/timer.h"
+
+#define SYNCENV_PROC_MAX 16
+#define SYNCENV_PROC_MIN 2
+#define SYNCPROC_IDLE_TIME 600
+
+/*
+ * Flags for syncopctx valid elements
+ */
+#define SYNCOPCTX_UID 0x00000001
+#define SYNCOPCTX_GID 0x00000002
+#define SYNCOPCTX_GROUPS 0x00000004
+#define SYNCOPCTX_PID 0x00000008
+#define SYNCOPCTX_LKOWNER 0x00000010
+
+#ifdef HAVE_TSAN_API
+/* Currently hardcoded within thread context maintained by the sanitizer. */
+#define TSAN_THREAD_NAMELEN 64
+#endif
+
+struct synctask;
+struct syncproc;
+struct syncenv;
+struct synccond;
+
+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_ZOMBIE,
+} 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;
+ struct timespec *delta;
+ gf_timer_t *timer;
+ struct synccond *synccond;
+ void *opaque;
+ void *stack;
+ synctask_state_t state;
+ int woken;
+ int slept;
+ int ret;
+
+ uid_t uid;
+ gid_t gid;
+
+#ifdef HAVE_TSAN_API
+ struct {
+ void *fiber;
+ char name[TSAN_THREAD_NAMELEN];
+ } tsan;
+#endif
+
+ ucontext_t ctx;
+ struct syncproc *proc;
+
+ pthread_mutex_t mutex; /* for synchronous spawning of synctask */
+ pthread_cond_t cond;
+ int done;
+
+ struct list_head waitq; /* can wait only "once" at a time */
+};
+
+struct syncproc {
+ pthread_t processor;
+
+#ifdef HAVE_TSAN_API
+ struct {
+ void *fiber;
+ char name[TSAN_THREAD_NAMELEN];
+ } tsan;
+#endif
+
+ 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];
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+
+ struct list_head runq;
+ struct list_head waitq;
+
+ int procs;
+ int procs_idle;
+
+ int runcount;
+
+ int procmin;
+ int procmax;
+
+ size_t stacksize;
+
+ int destroy; /* FLAG to mark syncenv is in destroy mode
+ so that no more synctasks are accepted*/
+};
+
+typedef enum { LOCK_NULL = 0, LOCK_TASK, LOCK_THREAD } lock_type_t;
+
+typedef enum {
+ SYNC_LOCK_DEFAULT = 0,
+ SYNC_LOCK_RECURSIVE, /*it allows recursive locking*/
+} lock_attr_t;
+
+struct synclock {
+ pthread_mutex_t guard; /* guard the remaining members, pair @cond */
+ pthread_cond_t cond; /* waiting non-synctasks */
+ struct list_head waitq; /* waiting synctasks */
+ volatile int lock; /* true(non zero) or false(zero), lock status */
+ lock_attr_t attr;
+ struct synctask *owner; /* NULL if current owner is not a synctask */
+ pthread_t owner_tid;
+ lock_type_t type;
+};
+typedef struct synclock synclock_t;
+
+struct synccond {
+ pthread_mutex_t pmutex;
+ pthread_cond_t pcond;
+ struct list_head waitq;
+};
+typedef struct synccond synccond_t;
+
+struct syncbarrier {
+ gf_boolean_t initialized; /*Set on successful initialization*/
+ pthread_mutex_t guard; /* guard the remaining members, pair @cond */
+ pthread_cond_t cond; /* waiting non-synctasks */
+ struct list_head waitq; /* waiting synctasks */
+ int count; /* count the number of wakes */
+ int waitfor; /* no. of wakes until which task can be in
+ waitq before being woken up. */
+};
+typedef struct syncbarrier syncbarrier_t;
+
+struct syncargs {
+ int op_ret;
+ int op_errno;
+
+ /*
+ * The below 3 iatt structures are used in the fops
+ * whose callbacks get struct iatt as one of the
+ * a return arguments. Currently, the maximum number
+ * of iatt structures returned is 3 for some fops
+ * such as mknod, copy_file_range, mkdir etc. So
+ * all the following 3 iatt structures would be used
+ * for those fops.
+ */
+ struct iatt iatt1;
+ struct iatt iatt2;
+ struct iatt iatt3;
+ dict_t *xattr;
+ struct statvfs statvfs_buf;
+ struct iovec *vector;
+ int count;
+ struct iobref *iobref;
+ char *buffer;
+ dict_t *xdata;
+ struct gf_flock flock;
+ struct gf_lease lease;
+ dict_t *dict_out;
+
+ /* some more _cbk needs */
+ uuid_t uuid;
+ char *errstr;
+ dict_t *dict;
+ pthread_mutex_t lock_dict;
+
+ syncbarrier_t barrier;
+
+ /* do not touch */
+ struct synctask *task;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int done;
+
+ gf_dirent_t entries;
+ off_t offset;
+
+ lock_migration_info_t locklist;
+};
+
+struct syncopctx {
+ unsigned int valid; /* valid flags for elements that are set */
+ uid_t uid;
+ gid_t gid;
+ int grpsize;
+ int ngrps;
+ gid_t *groups;
+ pid_t pid;
+ gf_lkowner_t lk_owner;
+};
+
+#define __yawn(args) \
+ do { \
+ args->task = synctask_get(); \
+ if (args->task) \
+ break; \
+ pthread_mutex_init(&args->mutex, NULL); \
+ pthread_cond_init(&args->cond, NULL); \
+ args->done = 0; \
+ } while (0)
+
+#define __wake(args) \
+ do { \
+ if (args->task) { \
+ synctask_wake(args->task); \
+ } else { \
+ pthread_mutex_lock(&args->mutex); \
+ { \
+ args->done = 1; \
+ pthread_cond_signal(&args->cond); \
+ } \
+ pthread_mutex_unlock(&args->mutex); \
+ } \
+ } while (0)
+
+#define __yield(args) \
+ do { \
+ if (args->task) { \
+ synctask_yield(args->task, NULL); \
+ } else { \
+ pthread_mutex_lock(&args->mutex); \
+ { \
+ while (!args->done) \
+ 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 SYNCOP(subvol, stb, cbk, fn_op, params...) \
+ do { \
+ struct synctask *task = NULL; \
+ call_frame_t *frame = NULL; \
+ \
+ task = synctask_get(); \
+ stb->task = task; \
+ if (task) \
+ frame = copy_frame(task->opframe); \
+ else \
+ frame = syncop_create_frame(THIS); \
+ \
+ if (!frame) { \
+ stb->op_ret = -1; \
+ stb->op_errno = errno; \
+ break; \
+ } \
+ \
+ if (task) { \
+ frame->root->uid = task->uid; \
+ frame->root->gid = task->gid; \
+ } \
+ \
+ __yawn(stb); \
+ \
+ frame->op = get_fop_index_from_fn(subvol, fn_op); \
+ STACK_WIND_COOKIE(frame, cbk, (void *)stb, subvol, fn_op, params); \
+ \
+ __yield(stb); \
+ STACK_DESTROY(frame->root); \
+ } while (0)
+
+/*
+ * syncop_xxx() calls are executed in two ways, one is inside a synctask where
+ * the executing function will do 'swapcontext' and the other is without
+ * synctask where the executing thread is made to wait using pthread_cond_wait.
+ * Executing thread may change when syncop_xxx() is executed inside a synctask.
+ * This leads to errno_location change i.e. errno may give errno of
+ * non-executing thread. So errno is not touched inside a synctask execution.
+ * All gfapi calls are executed using the second way of executing syncop_xxx()
+ * where the executing thread waits using pthread_cond_wait so it is ok to set
+ * errno in these cases. The following macro makes syncop_xxx() behave just
+ * like a system call, where -1 is returned and errno is set when a failure
+ * occurs.
+ */
+#define DECODE_SYNCOP_ERR(ret) \
+ do { \
+ if (ret < 0) { \
+ errno = -ret; \
+ ret = -1; \
+ } else { \
+ errno = 0; \
+ } \
+ } while (0)
+
+#define SYNCENV_DEFAULT_STACKSIZE (2 * 1024 * 1024)
+
+struct syncenv *
+syncenv_new(size_t stacksize, int procmin, int procmax);
+void
+syncenv_destroy(struct syncenv *);
+void
+syncenv_scale(struct syncenv *env);
+
+int
+synctask_new1(struct syncenv *, size_t stacksize, synctask_fn_t, synctask_cbk_t,
+ call_frame_t *frame, void *);
+int
+synctask_new(struct syncenv *, synctask_fn_t, synctask_cbk_t,
+ call_frame_t *frame, void *);
+struct synctask *
+synctask_create(struct syncenv *, size_t stacksize, synctask_fn_t,
+ synctask_cbk_t, call_frame_t *, void *);
+int
+synctask_join(struct synctask *task);
+void
+synctask_wake(struct synctask *task);
+void
+synctask_yield(struct synctask *task, struct timespec *delta);
+void
+synctask_sleep(int32_t secs);
+void
+synctask_waitfor(struct synctask *task, int count);
+
+#define synctask_barrier_init(args) syncbarrier_init(&args->barrier)
+#define synctask_barrier_wait(args, n) syncbarrier_wait(&args->barrier, n)
+#define synctask_barrier_wake(args) syncbarrier_wake(&args->barrier)
+
+int
+synctask_setid(struct synctask *task, uid_t uid, gid_t gid);
+#define SYNCTASK_SETID(uid, gid) synctask_setid(synctask_get(), uid, gid);
+
+int
+syncopctx_setfsuid(void *uid);
+int
+syncopctx_setfsgid(void *gid);
+int
+syncopctx_setfsgroups(int count, const void *groups);
+int
+syncopctx_setfspid(void *pid);
+int
+syncopctx_setfslkowner(gf_lkowner_t *lk_owner);
+
+static inline call_frame_t *
+syncop_create_frame(xlator_t *this)
+{
+ call_frame_t *frame = NULL;
+ int ngrps = -1;
+ struct syncopctx *opctx = NULL;
+
+ frame = create_frame(this, this->ctx->pool);
+ if (!frame)
+ return NULL;
+
+ frame->root->type = GF_OP_TYPE_FOP;
+ opctx = syncopctx_getctx();
+
+ if (opctx && (opctx->valid & SYNCOPCTX_PID))
+ frame->root->pid = opctx->pid;
+ else
+ frame->root->pid = getpid();
+
+ if (opctx && (opctx->valid & SYNCOPCTX_UID))
+ frame->root->uid = opctx->uid;
+ else
+ frame->root->uid = geteuid();
+
+ if (opctx && (opctx->valid & SYNCOPCTX_GID))
+ frame->root->gid = opctx->gid;
+ else
+ frame->root->gid = getegid();
+
+ if (opctx && (opctx->valid & SYNCOPCTX_GROUPS)) {
+ ngrps = opctx->ngrps;
+
+ if (ngrps != 0 && opctx->groups != NULL) {
+ if (call_stack_alloc_groups(frame->root, ngrps) != 0) {
+ STACK_DESTROY(frame->root);
+ return NULL;
+ }
+
+ memcpy(frame->root->groups, opctx->groups, (sizeof(gid_t) * ngrps));
+ }
+ } else {
+ ngrps = getgroups(0, 0);
+ if (ngrps < 0) {
+ STACK_DESTROY(frame->root);
+ return NULL;
+ }
+
+ if (call_stack_alloc_groups(frame->root, ngrps) != 0) {
+ STACK_DESTROY(frame->root);
+ return NULL;
+ }
+
+ if (getgroups(ngrps, frame->root->groups) < 0) {
+ STACK_DESTROY(frame->root);
+ return NULL;
+ }
+ }
+
+ if (opctx && (opctx->valid & SYNCOPCTX_LKOWNER))
+ frame->root->lk_owner = opctx->lk_owner;
+
+ return frame;
+}
+
+int
+synclock_init(synclock_t *lock, lock_attr_t attr);
+int
+synclock_destroy(synclock_t *lock);
+int
+synclock_lock(synclock_t *lock);
+int
+synclock_trylock(synclock_t *lock);
+int
+synclock_unlock(synclock_t *lock);
+
+int32_t
+synccond_init(synccond_t *cond);
+
+void
+synccond_destroy(synccond_t *cond);
+
+int
+synccond_wait(synccond_t *cond, synclock_t *lock);
+
+int
+synccond_timedwait(synccond_t *cond, synclock_t *lock, struct timespec *delta);
+
+void
+synccond_signal(synccond_t *cond);
+
+void
+synccond_broadcast(synccond_t *cond);
+
+int
+syncbarrier_init(syncbarrier_t *barrier);
+int
+syncbarrier_wait(syncbarrier_t *barrier, int waitfor);
+int
+syncbarrier_wake(syncbarrier_t *barrier);
+int
+syncbarrier_destroy(syncbarrier_t *barrier);
+
+int
+syncop_lookup(xlator_t *subvol, loc_t *loc,
+ /* out */
+ struct iatt *iatt, struct iatt *parent,
+ /* xdata */
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_readdirp(xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ /* out */
+ gf_dirent_t *entries, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_readdir(xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ gf_dirent_t *entries, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_opendir(xlator_t *subvol, loc_t *loc, fd_t *fd, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_setattr(xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
+ /* out */
+ struct iatt *preop, struct iatt *postop, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_fsetattr(xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid,
+ /* out */
+ struct iatt *preop, struct iatt *postop, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_statfs(xlator_t *subvol, loc_t *loc,
+ /* out */
+ struct statvfs *buf, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_setxattr(xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_fsetxattr(xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_listxattr(xlator_t *subvol, loc_t *loc, dict_t **dict, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_getxattr(xlator_t *xl, loc_t *loc, dict_t **dict, const char *key,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_fgetxattr(xlator_t *xl, fd_t *fd, dict_t **dict, const char *key,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_removexattr(xlator_t *subvol, loc_t *loc, const char *name,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_fremovexattr(xlator_t *subvol, fd_t *fd, const char *name,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_create(xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
+ fd_t *fd, struct iatt *iatt, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_open(xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+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,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_writev(xlator_t *subvol, fd_t *fd, const struct iovec *vector,
+ int32_t count, off_t offset, struct iobref *iobref,
+ uint32_t flags, struct iatt *preiatt, struct iatt *postiatt,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+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,
+ struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_ftruncate(xlator_t *subvol, fd_t *fd, off_t offset, struct iatt *preiatt,
+ struct iatt *postiatt, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_truncate(xlator_t *subvol, loc_t *loc, off_t offset, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_unlink(xlator_t *subvol, loc_t *loc, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_rmdir(xlator_t *subvol, loc_t *loc, int flags, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_fsync(xlator_t *subvol, fd_t *fd, int dataonly, struct iatt *preiatt,
+ struct iatt *postiatt, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_flush(xlator_t *subvol, fd_t *fd, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_fstat(xlator_t *subvol, fd_t *fd, struct iatt *stbuf, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_stat(xlator_t *subvol, loc_t *loc, struct iatt *stbuf, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_symlink(xlator_t *subvol, loc_t *loc, const char *newpath,
+ struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_readlink(xlator_t *subvol, loc_t *loc, char **buffer, size_t size,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_mknod(xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev,
+ struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_mkdir(xlator_t *subvol, loc_t *loc, mode_t mode, struct iatt *iatt,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_link(xlator_t *subvol, loc_t *oldloc, loc_t *newloc, struct iatt *iatt,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_fsyncdir(xlator_t *subvol, fd_t *fd, int datasync, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_access(xlator_t *subvol, loc_t *loc, int32_t mask, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_fallocate(xlator_t *subvol, fd_t *fd, int32_t keep_size, off_t offset,
+ size_t len, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_discard(xlator_t *subvol, fd_t *fd, off_t offset, size_t len,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_zerofill(xlator_t *subvol, fd_t *fd, off_t offset, off_t len,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_rename(xlator_t *subvol, loc_t *oldloc, loc_t *newloc, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_lk(xlator_t *subvol, fd_t *fd, int cmd, struct gf_flock *flock,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_inodelk(xlator_t *subvol, const char *volume, loc_t *loc, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_lease(xlator_t *subvol, loc_t *loc, struct gf_lease *lease,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_ipc(xlator_t *subvol, int op, dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_xattrop(xlator_t *subvol, loc_t *loc, gf_xattrop_flags_t flags,
+ dict_t *dict, dict_t *xdata_in, dict_t **dict_out,
+ dict_t **xdata_out);
+
+int
+syncop_fxattrop(xlator_t *subvol, fd_t *fd, gf_xattrop_flags_t flags,
+ dict_t *dict, dict_t *xdata_in, dict_t **dict_out,
+ dict_t **xdata_out);
+
+int
+syncop_seek(xlator_t *subvol, fd_t *fd, off_t offset, gf_seek_what_t what,
+ dict_t *xdata_in, off_t *off);
+
+int
+syncop_getactivelk(xlator_t *subvol, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_setactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int
+syncop_setactivelk(xlator_t *subvol, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata_in,
+ dict_t **xdata_out);
+
+int
+syncop_put(xlator_t *subvol, loc_t *loc, mode_t mode, mode_t umask,
+ uint32_t flags, struct iovec *vector, int32_t count, off_t offset,
+ struct iobref *iobref, dict_t *xattr, struct iatt *iatt,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_setactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int
+syncop_icreate(xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *xdata_out);
+
+int
+syncop_entrylk(xlator_t *subvol, const char *volume, loc_t *loc,
+ const char *basename, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_copy_file_range(xlator_t *subvol, fd_t *fd_in, off64_t off_in,
+ fd_t *fd_out, off64_t off_out, size_t len,
+ uint32_t flags, struct iatt *stbuf,
+ struct iatt *preiatt_dst, struct iatt *postiatt_dst,
+ dict_t *xdata_in, dict_t **xdata_out);
+
+int
+syncop_copy_file_range_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *stbuf,
+ struct iatt *prebuf_dst, struct iatt *postbuf_dst,
+ dict_t *xdata);
+
+#endif /* _SYNCOP_H */
diff --git a/libglusterfs/src/glusterfs/syscall.h b/libglusterfs/src/glusterfs/syscall.h
new file mode 100644
index 00000000000..b6d3ab4f2ad
--- /dev/null
+++ b/libglusterfs/src/glusterfs/syscall.h
@@ -0,0 +1,278 @@
+/*
+ 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 __SYSCALL_H__
+#define __SYSCALL_H__
+
+#include <dirent.h>
+#include <sys/uio.h>
+#include <sys/statvfs.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <stdio.h>
+
+/* GF follows the Linux XATTR definition, which differs in Darwin. */
+#define GF_XATTR_CREATE 0x1 /* set value, fail if attr already exists */
+#define GF_XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
+
+/* Linux kernel version 2.6.x don't have these defined
+ define if not defined */
+
+#ifndef XATTR_SECURITY_PREFIX
+#define XATTR_SECURITY_PREFIX "security."
+#define XATTR_SECURITY_PREFIX_LEN (sizeof(XATTR_SECURITY_PREFIX) - 1)
+#endif
+
+#ifndef XATTR_SYSTEM_PREFIX
+#define XATTR_SYSTEM_PREFIX "system."
+#define XATTR_SYSTEM_PREFIX_LEN (sizeof(XATTR_SYSTEM_PREFIX) - 1)
+#endif
+
+#ifndef XATTR_TRUSTED_PREFIX
+#define XATTR_TRUSTED_PREFIX "trusted."
+#define XATTR_TRUSTED_PREFIX_LEN (sizeof(XATTR_TRUSTED_PREFIX) - 1)
+#endif
+
+#ifndef XATTR_USER_PREFIX
+#define XATTR_USER_PREFIX "user."
+#define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1)
+#endif
+
+#if defined(GF_DARWIN_HOST_OS)
+#include <sys/xattr.h>
+#define XATTR_DARWIN_NOSECURITY XATTR_NOSECURITY
+#define XATTR_DARWIN_NODEFAULT XATTR_NODEFAULT
+#define XATTR_DARWIN_SHOWCOMPRESSION XATTR_SHOWCOMPRESSION
+#endif
+
+int
+sys_lstat(const char *path, struct stat *buf);
+
+int
+sys_stat(const char *path, struct stat *buf);
+
+int
+sys_fstat(int fd, struct stat *buf);
+
+int
+sys_fstatat(int dirfd, const char *pathname, struct stat *buf, int flags);
+
+int
+sys_open(const char *pathname, int flags, int mode);
+
+int
+sys_openat(int dirfd, const char *pathname, int flags, int mode);
+
+DIR *
+sys_opendir(const char *name);
+
+struct dirent *
+sys_readdir(DIR *dir, struct dirent *de);
+
+ssize_t
+sys_readlink(const char *path, char *buf, size_t bufsiz);
+
+int
+sys_closedir(DIR *dir);
+
+int
+sys_mknod(const char *pathname, mode_t mode, dev_t dev);
+
+int
+sys_mkdir(const char *pathname, mode_t mode);
+
+int
+sys_mkdirat(int dirfd, const char *pathname, mode_t mode);
+
+int
+sys_unlink(const char *pathname);
+
+int
+sys_unlinkat(int dfd, const char *pathname);
+
+int
+sys_rmdir(const char *pathname);
+
+int
+sys_symlink(const char *oldpath, const char *newpath);
+
+int
+sys_symlinkat(const char *oldpath, int dirfd, const char *newpath);
+
+int
+sys_rename(const char *oldpath, const char *newpath);
+
+int
+sys_link(const char *oldpath, const char *newpath);
+
+int
+sys_linkat(int oldfd, const char *oldpath, int newfd, const char *newpath);
+
+int
+sys_chmod(const char *path, mode_t mode);
+
+int
+sys_fchmod(int fd, mode_t mode);
+
+int
+sys_chown(const char *path, uid_t owner, gid_t group);
+
+int
+sys_fchown(int fd, uid_t owner, gid_t group);
+
+int
+sys_lchown(const char *path, uid_t owner, gid_t group);
+
+int
+sys_truncate(const char *path, off_t length);
+
+int
+sys_ftruncate(int fd, off_t length);
+
+int
+sys_utimes(const char *filename, const struct timeval times[2]);
+
+#if defined(HAVE_UTIMENSAT)
+int
+sys_utimensat(int dirfd, const char *filename, const struct timespec times[2],
+ int flags);
+#endif
+
+int
+sys_futimes(int fd, const struct timeval times[2]);
+
+int
+sys_creat(const char *pathname, mode_t mode);
+
+ssize_t
+sys_readv(int fd, const struct iovec *iov, int iovcnt);
+
+ssize_t
+sys_writev(int fd, const struct iovec *iov, int iovcnt);
+
+ssize_t
+sys_read(int fd, void *buf, size_t count);
+
+ssize_t
+sys_write(int fd, const void *buf, size_t count);
+
+off_t
+sys_lseek(int fd, off_t offset, int whence);
+
+int
+sys_statvfs(const char *path, struct statvfs *buf);
+
+int
+sys_fstatvfs(int fd, struct statvfs *buf);
+
+int
+sys_close(int fd);
+
+int
+sys_fsync(int fd);
+
+int
+sys_fdatasync(int fd);
+
+void
+gf_add_prefix(const char *ns, const char *key, char **newkey);
+
+void
+gf_remove_prefix(const char *ns, const char *key, char **newkey);
+
+int
+sys_lsetxattr(const char *path, const char *name, const void *value,
+ size_t size, int flags);
+
+ssize_t
+sys_llistxattr(const char *path, char *list, size_t size);
+
+ssize_t
+sys_lgetxattr(const char *path, const char *name, void *value, size_t size);
+
+ssize_t
+sys_fgetxattr(int filedes, const char *name, void *value, size_t size);
+
+int
+sys_fsetxattr(int filedes, const char *name, const void *value, size_t size,
+ int flags);
+
+ssize_t
+sys_flistxattr(int filedes, char *list, size_t size);
+
+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
+sys_fallocate(int fd, int mode, off_t offset, off_t len);
+
+ssize_t
+sys_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+
+ssize_t
+sys_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+
+ssize_t
+sys_pread(int fd, void *buf, size_t count, off_t offset);
+
+ssize_t
+sys_pwrite(int fd, const void *buf, size_t count, off_t offset);
+
+int
+sys_socket(int domain, int type, int protocol);
+
+int
+sys_accept(int sock, struct sockaddr *sockaddr, socklen_t *socklen, int flags);
+
+#ifdef GF_BSD_HOST_OS
+#ifndef _OFF64_T_DECLARED
+/*
+ * Including <stdio.h> (done above) should actually define
+ * _OFF64_T_DECLARED with off64_t data type being available
+ * for consumption. But, off64_t data type is not recognizable
+ * for FreeBSD versions less than 11. Hence, int64_t is typedefed
+ * to off64_t.
+ */
+#define _OFF64_T_DECLARED
+typedef int64_t off64_t;
+#endif /* _OFF64_T_DECLARED */
+#endif /* GF_BSD_HOST_OS */
+
+/*
+ * According to the man page of copy_file_range, both off_in and off_out are
+ * pointers to the data type loff_t (i.e. loff_t *). But, freebsd does not
+ * have (and recognize) loff_t. Since loff_t is 64 bits, use off64_t
+ * instead. Since it's a pointer type it should be okay. It just needs
+ * to be a pointer-to-64-bit pointer for both 32- and 64-bit platforms.
+ * off64_t is recognized by freebsd.
+ * TODO: In future, when freebsd can recognize loff_t, probably revisit this
+ * and change the off_in and off_out to (loff_t *).
+ */
+ssize_t
+sys_copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out,
+ size_t len, unsigned int flags);
+
+int
+sys_kill(pid_t pid, int sig);
+
+#ifdef __FreeBSD__
+int
+sys_sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
+ const void *newp, size_t newlen);
+#endif
+
+#endif /* __SYSCALL_H__ */
diff --git a/libglusterfs/src/glusterfs/template-component-messages.h b/libglusterfs/src/glusterfs/template-component-messages.h
new file mode 100644
index 00000000000..aa7ad3d1baa
--- /dev/null
+++ b/libglusterfs/src/glusterfs/template-component-messages.h
@@ -0,0 +1,28 @@
+/*
+ Copyright (c) 2013 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 _component_MESSAGES_H_
+#define _component_MESSAGES_H_
+
+#include "glusterfs/glfs-message-id.h"
+
+/* To add new message IDs, append new identifiers at the end of the list.
+ *
+ * Never remove a message ID. If it's not used anymore, you can rename it or
+ * leave it as it is, but not delete it. This is to prevent reutilization of
+ * IDs by other messages.
+ *
+ * The component name must match one of the entries defined in
+ * glfs-message-id.h.
+ */
+
+GLFS_MSGID(component, message id, message id, ...);
+
+#endif /* !_component_MESSAGES_H_ */
diff --git a/libglusterfs/src/glusterfs/throttle-tbf.h b/libglusterfs/src/glusterfs/throttle-tbf.h
new file mode 100644
index 00000000000..cccb13c83d9
--- /dev/null
+++ b/libglusterfs/src/glusterfs/throttle-tbf.h
@@ -0,0 +1,74 @@
+/*
+ Copyright (c) 2015 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 "glusterfs/list.h"
+#include "glusterfs/xlator.h"
+#include "glusterfs/locking.h"
+
+#ifndef THROTTLE_TBF_H__
+#define THROTTLE_TBF_H__
+
+typedef enum tbf_ops {
+ TBF_OP_MIN = -1,
+ TBF_OP_HASH = 0, /* checksum calculation */
+ TBF_OP_READ = 1, /* inode read(s) */
+ TBF_OP_READDIR = 2, /* dentry read(s) */
+ TBF_OP_MAX = 3,
+} tbf_ops_t;
+
+/**
+ * Operation rate specification
+ */
+typedef struct tbf_opspec {
+ tbf_ops_t op;
+
+ unsigned long rate;
+
+ unsigned long maxlimit;
+
+ unsigned long token_gen_interval; /* Token generation interval in usec */
+} tbf_opspec_t;
+
+/**
+ * Token bucket for each operation type
+ */
+typedef struct tbf_bucket {
+ gf_lock_t lock;
+
+ pthread_t tokener; /* token generator thread */
+
+ unsigned long tokenrate; /* token generation rate */
+
+ unsigned long tokens; /* number of current tokens */
+
+ unsigned long maxtokens; /* maximum token in the bucket */
+
+ struct list_head queued; /* list of non-conformant requests */
+
+ unsigned long token_gen_interval; /* Token generation interval in usec */
+} tbf_bucket_t;
+
+typedef struct tbf {
+ tbf_bucket_t **bucket;
+} tbf_t;
+
+tbf_t *
+tbf_init(tbf_opspec_t *, unsigned int);
+
+int
+tbf_mod(tbf_t *, tbf_opspec_t *);
+
+void
+tbf_throttle(tbf_t *, tbf_ops_t, unsigned long);
+
+#define TBF_THROTTLE_BEGIN(tbf, op, tokens) (tbf_throttle(tbf, op, tokens))
+#define TBF_THROTTLE_END(tbf, op, tokens)
+
+#endif /** THROTTLE_TBF_H__ */
diff --git a/libglusterfs/src/glusterfs/timer.h b/libglusterfs/src/glusterfs/timer.h
new file mode 100644
index 00000000000..ae5b2edf451
--- /dev/null
+++ b/libglusterfs/src/glusterfs/timer.h
@@ -0,0 +1,56 @@
+/*
+ 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 _TIMER_H
+#define _TIMER_H
+
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/xlator.h"
+#include <sys/time.h>
+#include <pthread.h>
+
+typedef void (*gf_timer_cbk_t)(void *);
+
+struct _gf_timer {
+ union {
+ struct list_head list;
+ struct {
+ struct _gf_timer *next;
+ struct _gf_timer *prev;
+ };
+ };
+ struct timespec at;
+ gf_timer_cbk_t callbk;
+ void *data;
+ xlator_t *xl;
+ gf_boolean_t fired;
+};
+
+struct _gf_timer_registry {
+ struct list_head active;
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+ pthread_t th;
+ char fin;
+};
+
+typedef struct _gf_timer gf_timer_t;
+typedef struct _gf_timer_registry gf_timer_registry_t;
+
+gf_timer_t *
+gf_timer_call_after(glusterfs_ctx_t *ctx, struct timespec delta,
+ gf_timer_cbk_t cbk, void *data);
+
+int32_t
+gf_timer_call_cancel(glusterfs_ctx_t *ctx, gf_timer_t *event);
+
+void
+gf_timer_registry_destroy(glusterfs_ctx_t *ctx);
+#endif /* _TIMER_H */
diff --git a/libglusterfs/src/timespec.h b/libglusterfs/src/glusterfs/timespec.h
index f37194b97cf..bb9ab446a5f 100644
--- a/libglusterfs/src/timespec.h
+++ b/libglusterfs/src/glusterfs/timespec.h
@@ -14,11 +14,20 @@
#include <stdint.h>
#include <sys/time.h>
-#define TS(ts) ((ts.tv_sec * 1000000000LL) + ts.tv_nsec)
+#define TS(ts) ((ts.tv_sec * 1000000000LL) + ts.tv_nsec)
#define NANO (+1.0E-9)
#define GIGA UINT64_C(1000000000)
-void timespec_now (struct timespec *ts);
-void timespec_adjust_delta (struct timespec *ts, struct timespec delta);
+void
+timespec_now(struct timespec *ts);
+void
+timespec_now_realtime(struct timespec *ts);
+void
+timespec_adjust_delta(struct timespec *ts, struct timespec delta);
+void
+timespec_sub(const struct timespec *begin, const struct timespec *end,
+ struct timespec *res);
+int
+timespec_cmp(const struct timespec *lhs_ts, const struct timespec *rhs_ts);
#endif /* __INCLUDE_TIMESPEC_H__ */
diff --git a/libglusterfs/src/glusterfs/trie.h b/libglusterfs/src/glusterfs/trie.h
new file mode 100644
index 00000000000..6d2d8015964
--- /dev/null
+++ b/libglusterfs/src/glusterfs/trie.h
@@ -0,0 +1,52 @@
+/*
+ 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 _TRIE_H_
+#define _TRIE_H_
+
+struct trienode;
+typedef struct trienode trienode_t;
+
+struct trie;
+typedef struct trie trie_t;
+
+struct trienodevec {
+ trienode_t **nodes;
+ unsigned cnt;
+};
+
+trie_t *
+trie_new();
+
+int
+trie_add(trie_t *trie, const char *word);
+
+void
+trie_destroy(trie_t *trie);
+
+void
+trie_destroy_bynode(trienode_t *node);
+
+int
+trie_measure(trie_t *trie, const char *word, trienode_t **nodes, int nodecnt);
+
+int
+trie_measure_vec(trie_t *trie, const char *word, struct trienodevec *nodevec);
+
+void
+trie_reset_search(trie_t *trie);
+
+int
+trienode_get_dist(trienode_t *node);
+
+int
+trienode_get_word(trienode_t *node, char **buf);
+
+#endif
diff --git a/libglusterfs/src/glusterfs/upcall-utils.h b/libglusterfs/src/glusterfs/upcall-utils.h
new file mode 100644
index 00000000000..0de8428c5fc
--- /dev/null
+++ b/libglusterfs/src/glusterfs/upcall-utils.h
@@ -0,0 +1,110 @@
+/*
+ Copyright (c) 2015, 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 _UPCALL_UTILS_H
+#define _UPCALL_UTILS_H
+
+#include "glusterfs/iatt.h"
+#include "glusterfs/compat-uuid.h"
+#include "glusterfs/compat.h"
+
+/* Flags sent for cache_invalidation */
+#define UP_NLINK 0x00000001 /* update nlink */
+#define UP_MODE 0x00000002 /* update mode and ctime */
+#define UP_OWN 0x00000004 /* update mode,uid,gid and ctime */
+#define UP_SIZE 0x00000008 /* update fsize */
+#define UP_TIMES 0x00000010 /* update all times */
+#define UP_ATIME 0x00000020 /* update atime only */
+#define UP_PERM \
+ 0x00000040 /* update fields needed for permission \
+ checking */
+#define UP_RENAME \
+ 0x00000080 /* this is a rename op - delete the cache \
+ entry */
+#define UP_FORGET \
+ 0x00000100 /* inode_forget on server side - \
+ invalidate the cache entry */
+#define UP_PARENT_TIMES 0x00000200 /* update parent dir times */
+
+#define UP_XATTR 0x00000400 /* update the xattrs and ctime */
+#define UP_XATTR_RM 0x00000800 /* Remove the xattrs and update ctime */
+
+#define UP_EXPLICIT_LOOKUP 0x00001000 /* Request an explicit lookup */
+
+#define UP_INVAL_ATTR 0x00002000 /* Request to invalidate iatt and xatt */
+
+/* for fops - open, read, lk, */
+#define UP_UPDATE_CLIENT (UP_ATIME)
+
+/* for fop - write, truncate */
+#define UP_WRITE_FLAGS (UP_SIZE | UP_TIMES)
+
+/* for fop - setattr */
+#define UP_ATTR_FLAGS (UP_SIZE | UP_TIMES | UP_OWN | UP_MODE | UP_PERM)
+/* for fop - rename */
+#define UP_RENAME_FLAGS (UP_RENAME)
+
+/* to invalidate parent directory entries for fops -rename, unlink, rmdir,
+ * mkdir, create */
+#define UP_PARENT_DENTRY_FLAGS (UP_PARENT_TIMES)
+
+/* for fop - unlink, link, rmdir, mkdir */
+#define UP_NLINK_FLAGS (UP_NLINK | UP_TIMES)
+
+#define IATT_UPDATE_FLAGS \
+ (UP_NLINK | UP_MODE | UP_OWN | UP_SIZE | UP_TIMES | UP_ATIME | UP_PERM)
+
+typedef enum {
+ GF_UPCALL_EVENT_NULL,
+ GF_UPCALL_CACHE_INVALIDATION,
+ GF_UPCALL_RECALL_LEASE,
+ GF_UPCALL_INODELK_CONTENTION,
+ GF_UPCALL_ENTRYLK_CONTENTION,
+} gf_upcall_event_t;
+
+struct gf_upcall {
+ char *client_uid;
+ uuid_t gfid;
+ uint32_t event_type;
+ void *data;
+};
+
+struct gf_upcall_cache_invalidation {
+ uint32_t flags;
+ uint32_t expire_time_attr;
+ struct iatt stat;
+ struct iatt p_stat; /* parent dir stat */
+ struct iatt oldp_stat; /* oldparent dir stat */
+ dict_t *dict; /* For xattrs */
+};
+
+struct gf_upcall_recall_lease {
+ uint32_t lease_type; /* Lease type to which client can downgrade to*/
+ uuid_t tid; /* transaction id of the fop that caused
+ the recall */
+ dict_t *dict;
+};
+
+struct gf_upcall_inodelk_contention {
+ struct gf_flock flock;
+ pid_t pid;
+ const char *domain;
+ dict_t *xdata;
+};
+
+struct gf_upcall_entrylk_contention {
+ uint32_t type;
+ pid_t pid;
+ const char *name;
+ const char *domain;
+ dict_t *xdata;
+};
+
+#endif /* _UPCALL_UTILS_H */
diff --git a/libglusterfs/src/glusterfs/xlator.h b/libglusterfs/src/glusterfs/xlator.h
new file mode 100644
index 00000000000..4fd3abdaeff
--- /dev/null
+++ b/libglusterfs/src/glusterfs/xlator.h
@@ -0,0 +1,1106 @@
+/*
+ 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 _XLATOR_H
+#define _XLATOR_H
+
+#include <stdint.h> // for int32_t
+#include <sys/types.h> // for off_t, mode_t, off64_t, dev_t
+#include "glusterfs/glusterfs-fops.h" // for GF_FOP_MAXVALUE, entrylk_cmd
+#include "glusterfs/atomic.h" // for gf_atomic_t
+#include "glusterfs/glusterfs.h" // for gf_boolean_t, glusterfs_ctx_t
+#include "glusterfs/compat-uuid.h" // for uuid_t
+#include "glusterfs/compat.h"
+#include "glusterfs/event-history.h"
+#include "glusterfs/dict.h"
+#include "glusterfs/latency.h"
+
+#define FIRST_CHILD(xl) (xl->children->xlator)
+#define SECOND_CHILD(xl) (xl->children->next->xlator)
+
+#define GF_SET_ATTR_MODE 0x1
+#define GF_SET_ATTR_UID 0x2
+#define GF_SET_ATTR_GID 0x4
+#define GF_SET_ATTR_SIZE 0x8
+#define GF_SET_ATTR_ATIME 0x10
+#define GF_SET_ATTR_MTIME 0x20
+#define GF_SET_ATTR_CTIME 0x40
+#define GF_ATTR_ATIME_NOW 0x80
+#define GF_ATTR_MTIME_NOW 0x100
+
+#define gf_attr_mode_set(mode) ((mode)&GF_SET_ATTR_MODE)
+#define gf_attr_uid_set(mode) ((mode)&GF_SET_ATTR_UID)
+#define gf_attr_gid_set(mode) ((mode)&GF_SET_ATTR_GID)
+#define gf_attr_size_set(mode) ((mode)&GF_SET_ATTR_SIZE)
+#define gf_attr_atime_set(mode) ((mode)&GF_SET_ATTR_ATIME)
+#define gf_attr_mtime_set(mode) ((mode)&GF_SET_ATTR_MTIME)
+
+struct _xlator;
+typedef struct _xlator xlator_t;
+struct _dir_entry;
+typedef struct _dir_entry dir_entry_t;
+struct _gf_dirent;
+typedef struct _gf_dirent gf_dirent_t;
+struct _loc;
+typedef struct _loc loc_t;
+
+typedef int32_t (*event_notify_fn_t)(xlator_t *this, int32_t event, void *data,
+ ...);
+
+#include "glusterfs/list.h"
+#include "glusterfs/gf-dirent.h"
+#include "glusterfs/stack.h"
+#include "glusterfs/iobuf.h"
+#include "glusterfs/globals.h"
+#include "glusterfs/iatt.h"
+#include "glusterfs/options.h"
+#include "glusterfs/client_t.h"
+
+struct _loc {
+ const char *path;
+ const char *name;
+ 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;
+};
+
+typedef int32_t (*fop_getspec_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, char *spec_data);
+
+typedef int32_t (*fop_rchecksum_cbk_t)(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, dict_t *xdata);
+
+typedef int32_t (*fop_getspec_t)(call_frame_t *frame, xlator_t *this,
+ const char *key, int32_t flag);
+
+typedef int32_t (*fop_rchecksum_t)(call_frame_t *frame, xlator_t *this,
+ fd_t *fd, off_t offset, int32_t len,
+ dict_t *xdata);
+
+typedef int32_t (*fop_lookup_cbk_t)(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 *xdata,
+ struct iatt *postparent);
+
+typedef int32_t (*fop_stat_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, 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,
+ dict_t *xdata);
+
+typedef int32_t (*fop_truncate_cbk_t)(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);
+
+typedef int32_t (*fop_ftruncate_cbk_t)(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);
+
+typedef int32_t (*fop_access_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_readlink_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, const char *path,
+ struct iatt *buf, dict_t *xdata);
+
+typedef int32_t (*fop_mknod_cbk_t)(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);
+
+typedef int32_t (*fop_mkdir_cbk_t)(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);
+
+typedef int32_t (*fop_unlink_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+
+typedef int32_t (*fop_rmdir_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent, dict_t *xdata);
+
+typedef int32_t (*fop_symlink_cbk_t)(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);
+
+typedef int32_t (*fop_rename_cbk_t)(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, dict_t *xdata);
+
+typedef int32_t (*fop_link_cbk_t)(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);
+
+typedef int32_t (*fop_create_cbk_t)(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);
+
+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, dict_t *xdata);
+
+typedef int32_t (*fop_readv_cbk_t)(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);
+
+typedef int32_t (*fop_writev_cbk_t)(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);
+
+typedef int32_t (*fop_flush_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_fsync_cbk_t)(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);
+
+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, 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, 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,
+ 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, 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 *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, 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 *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, 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,
+ 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, 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, 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, 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, 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,
+ 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,
+ 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 *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 *xdata);
+
+typedef int32_t (*fop_setattr_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf, dict_t *xdata);
+
+typedef int32_t (*fop_fsetattr_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf, dict_t *xdata);
+
+typedef int32_t (*fop_fallocate_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf,
+ dict_t *xdata);
+
+typedef int32_t (*fop_discard_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf, dict_t *xdata);
+
+typedef int32_t (*fop_zerofill_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf, dict_t *xdata);
+
+typedef int32_t (*fop_ipc_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_seek_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, off_t offset,
+ dict_t *xdata);
+
+typedef int32_t (*fop_lease_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct gf_lease *lease,
+ dict_t *xdata);
+typedef int32_t (*fop_compound_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, void *data,
+ dict_t *xdata);
+
+typedef int32_t (*fop_getactivelk_cbk_t)(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno,
+ lock_migration_info_t *locklist,
+ dict_t *xdata);
+
+typedef int32_t (*fop_setactivelk_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_put_cbk_t)(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);
+
+typedef int32_t (*fop_icreate_cbk_t)(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 *xdata);
+
+typedef int32_t (*fop_namelink_cbk_t)(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);
+
+typedef int32_t (*fop_copy_file_range_cbk_t)(
+ call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iatt *stbuf, struct iatt *prebuf_dst,
+ struct iatt *postbuf_dst, dict_t *xdata);
+
+typedef int32_t (*fop_lookup_t)(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata);
+
+typedef int32_t (*fop_stat_t)(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xdata);
+
+typedef int32_t (*fop_fstat_t)(call_frame_t *frame, xlator_t *this, 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, dict_t *xdata);
+
+typedef int32_t (*fop_ftruncate_t)(call_frame_t *frame, xlator_t *this,
+ fd_t *fd, 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, dict_t *xdata);
+
+typedef int32_t (*fop_readlink_t)(call_frame_t *frame, xlator_t *this,
+ loc_t *loc, 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, 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, mode_t umask, dict_t *xdata);
+
+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 xflags, dict_t *xdata);
+
+typedef int32_t (*fop_symlink_t)(call_frame_t *frame, xlator_t *this,
+ const char *linkname, loc_t *loc, 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, dict_t *xdata);
+
+typedef int32_t (*fop_link_t)(call_frame_t *frame, xlator_t *this,
+ loc_t *oldloc, 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, 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.
+ */
+#define GF_OPEN_FSYNC 0x01
+
+/* Tell write-behind to disable writing behind despite O_SYNC not being set.
+ */
+#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, 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, uint32_t flags,
+ dict_t *xdata);
+
+typedef int32_t (*fop_writev_t)(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count,
+ off_t offset, 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,
+ dict_t *xdata);
+
+typedef int32_t (*fop_fsync_t)(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ 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, dict_t *xdata);
+
+typedef int32_t (*fop_fsyncdir_t)(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t datasync, dict_t *xdata);
+
+typedef int32_t (*fop_statfs_t)(call_frame_t *frame, xlator_t *this, 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,
+ dict_t *xdata);
+
+typedef int32_t (*fop_getxattr_t)(call_frame_t *frame, xlator_t *this,
+ loc_t *loc, 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,
+ dict_t *xdata);
+
+typedef int32_t (*fop_fgetxattr_t)(call_frame_t *frame, xlator_t *this,
+ fd_t *fd, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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 *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 *xdata);
+
+typedef int32_t (*fop_setattr_t)(call_frame_t *frame, xlator_t *this,
+ loc_t *loc, struct iatt *stbuf, 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,
+ dict_t *xdata);
+
+typedef int32_t (*fop_fallocate_t)(call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int32_t keep_size, off_t offset,
+ size_t len, dict_t *xdata);
+
+typedef int32_t (*fop_discard_t)(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, size_t len, dict_t *xdata);
+
+typedef int32_t (*fop_zerofill_t)(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, off_t len, dict_t *xdata);
+
+typedef int32_t (*fop_ipc_t)(call_frame_t *frame, xlator_t *this, int32_t op,
+ dict_t *xdata);
+
+typedef int32_t (*fop_seek_t)(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset, gf_seek_what_t what, dict_t *xdata);
+
+typedef int32_t (*fop_lease_t)(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct gf_lease *lease, dict_t *xdata);
+
+typedef int32_t (*fop_compound_t)(call_frame_t *frame, xlator_t *this,
+ void *args, dict_t *xdata);
+
+typedef int32_t (*fop_getactivelk_t)(call_frame_t *frame, xlator_t *this,
+ loc_t *loc, dict_t *xdata);
+
+typedef int32_t (*fop_setactivelk_t)(call_frame_t *frame, xlator_t *this,
+ loc_t *loc,
+ lock_migration_info_t *locklist,
+ dict_t *xdata);
+
+typedef int32_t (*fop_put_t)(call_frame_t *frame, xlator_t *this, loc_t *loc,
+ mode_t mode, mode_t umask, uint32_t flags,
+ struct iovec *vector, int32_t count, off_t offset,
+ struct iobref *iobref, dict_t *xattr,
+ dict_t *xdata);
+
+typedef int32_t (*fop_icreate_t)(call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, dict_t *xdata);
+
+typedef int32_t (*fop_namelink_t)(call_frame_t *frame, xlator_t *this,
+ loc_t *loc, dict_t *xdata);
+typedef int32_t (*fop_copy_file_range_t)(call_frame_t *frame, xlator_t *this,
+ fd_t *fd_in, off64_t off_in,
+ fd_t *fd_out, off64_t off_out,
+ size_t len, uint32_t flags,
+ dict_t *xdata);
+
+/* WARNING: make sure the list is in order with FOP definition in
+ `rpc/xdr/src/glusterfs-fops.x`.
+ If it is not in order, mainly the metrics related feature would be broken */
+struct xlator_fops {
+ fop_stat_t stat;
+ fop_readlink_t readlink;
+ fop_mknod_t mknod;
+ fop_mkdir_t mkdir;
+ fop_unlink_t unlink;
+ fop_rmdir_t rmdir;
+ fop_symlink_t symlink;
+ fop_rename_t rename;
+ fop_link_t link;
+ fop_truncate_t truncate;
+ fop_open_t open;
+ fop_readv_t readv;
+ fop_writev_t writev;
+ fop_statfs_t statfs;
+ fop_flush_t flush;
+ fop_fsync_t fsync;
+ fop_setxattr_t setxattr;
+ fop_getxattr_t getxattr;
+ fop_removexattr_t removexattr;
+ fop_opendir_t opendir;
+ fop_fsyncdir_t fsyncdir;
+ fop_access_t access;
+ fop_create_t create;
+ fop_ftruncate_t ftruncate;
+ fop_fstat_t fstat;
+ fop_lk_t lk;
+ fop_lookup_t lookup;
+ fop_readdir_t readdir;
+ fop_inodelk_t inodelk;
+ fop_finodelk_t finodelk;
+ fop_entrylk_t entrylk;
+ fop_fentrylk_t fentrylk;
+ fop_xattrop_t xattrop;
+ fop_fxattrop_t fxattrop;
+ fop_fgetxattr_t fgetxattr;
+ fop_fsetxattr_t fsetxattr;
+ fop_rchecksum_t rchecksum;
+ fop_setattr_t setattr;
+ fop_fsetattr_t fsetattr;
+ fop_readdirp_t readdirp;
+
+ /* These 3 are required to keep the index same as GF_FOP_##FOP */
+ void *forget_placeholder;
+ void *release_placeholder;
+ void *releasedir_placeholder;
+
+ fop_getspec_t getspec;
+ fop_fremovexattr_t fremovexattr;
+ fop_fallocate_t fallocate;
+ fop_discard_t discard;
+ fop_zerofill_t zerofill;
+ fop_ipc_t ipc;
+ fop_seek_t seek;
+ fop_lease_t lease;
+ fop_compound_t compound;
+ fop_getactivelk_t getactivelk;
+ fop_setactivelk_t setactivelk;
+ fop_put_t put;
+ fop_icreate_t icreate;
+ fop_namelink_t namelink;
+ fop_copy_file_range_t copy_file_range;
+
+ /* these entries are used for a typechecking hack in STACK_WIND _only_ */
+ /* make sure to add _cbk variables only after defining regular fops as
+ its relative position is used to get the index */
+ fop_stat_cbk_t stat_cbk;
+ fop_readlink_cbk_t readlink_cbk;
+ fop_mknod_cbk_t mknod_cbk;
+ fop_mkdir_cbk_t mkdir_cbk;
+ fop_unlink_cbk_t unlink_cbk;
+ fop_rmdir_cbk_t rmdir_cbk;
+ fop_symlink_cbk_t symlink_cbk;
+ fop_rename_cbk_t rename_cbk;
+ fop_link_cbk_t link_cbk;
+ fop_truncate_cbk_t truncate_cbk;
+ fop_open_cbk_t open_cbk;
+ fop_readv_cbk_t readv_cbk;
+ fop_writev_cbk_t writev_cbk;
+ fop_statfs_cbk_t statfs_cbk;
+ fop_flush_cbk_t flush_cbk;
+ fop_fsync_cbk_t fsync_cbk;
+ fop_setxattr_cbk_t setxattr_cbk;
+ fop_getxattr_cbk_t getxattr_cbk;
+ fop_removexattr_cbk_t removexattr_cbk;
+ fop_opendir_cbk_t opendir_cbk;
+ fop_fsyncdir_cbk_t fsyncdir_cbk;
+ fop_access_cbk_t access_cbk;
+ fop_create_cbk_t create_cbk;
+ fop_ftruncate_cbk_t ftruncate_cbk;
+ fop_fstat_cbk_t fstat_cbk;
+ fop_lk_cbk_t lk_cbk;
+ fop_lookup_cbk_t lookup_cbk;
+ fop_readdir_cbk_t readdir_cbk;
+ fop_inodelk_cbk_t inodelk_cbk;
+ fop_finodelk_cbk_t finodelk_cbk;
+ fop_entrylk_cbk_t entrylk_cbk;
+ fop_fentrylk_cbk_t fentrylk_cbk;
+ fop_xattrop_cbk_t xattrop_cbk;
+ fop_fxattrop_cbk_t fxattrop_cbk;
+ fop_fgetxattr_cbk_t fgetxattr_cbk;
+ fop_fsetxattr_cbk_t fsetxattr_cbk;
+ fop_rchecksum_cbk_t rchecksum_cbk;
+ fop_setattr_cbk_t setattr_cbk;
+ fop_fsetattr_cbk_t fsetattr_cbk;
+ fop_readdirp_cbk_t readdirp_cbk;
+
+ /* These 3 are required to keep the index same as GF_FOP_##FOP */
+ void *forget_placeholder_cbk;
+ void *release_placeholder_cbk;
+ void *releasedir_placeholder_cbk;
+
+ fop_getspec_cbk_t getspec_cbk;
+ fop_fremovexattr_cbk_t fremovexattr_cbk;
+ fop_fallocate_cbk_t fallocate_cbk;
+ fop_discard_cbk_t discard_cbk;
+ fop_zerofill_cbk_t zerofill_cbk;
+ fop_ipc_cbk_t ipc_cbk;
+ fop_seek_cbk_t seek_cbk;
+ fop_lease_cbk_t lease_cbk;
+ fop_compound_cbk_t compound_cbk;
+ fop_getactivelk_cbk_t getactivelk_cbk;
+ fop_setactivelk_cbk_t setactivelk_cbk;
+ fop_put_cbk_t put_cbk;
+ fop_icreate_cbk_t icreate_cbk;
+ fop_namelink_cbk_t namelink_cbk;
+ fop_copy_file_range_cbk_t copy_file_range_cbk;
+};
+
+typedef int32_t (*cbk_forget_t)(xlator_t *this, inode_t *inode);
+
+typedef int32_t (*cbk_release_t)(xlator_t *this, fd_t *fd);
+
+typedef int32_t (*cbk_invalidate_t)(xlator_t *this, inode_t *inode);
+
+typedef int32_t (*cbk_client_t)(xlator_t *this, client_t *client);
+
+typedef void (*cbk_ictxmerge_t)(xlator_t *this, fd_t *fd, inode_t *inode,
+ inode_t *linked_inode);
+
+typedef size_t (*cbk_inodectx_size_t)(xlator_t *this, inode_t *inode);
+
+typedef size_t (*cbk_fdctx_size_t)(xlator_t *this, fd_t *fd);
+
+typedef void (*cbk_fdclose_t)(xlator_t *this, fd_t *fd);
+
+struct xlator_cbks {
+ cbk_forget_t forget;
+ cbk_release_t release;
+ cbk_release_t releasedir;
+ cbk_invalidate_t invalidate;
+ cbk_client_t client_destroy;
+ cbk_client_t client_disconnect;
+ cbk_ictxmerge_t ictxmerge;
+ cbk_inodectx_size_t ictxsize;
+ cbk_fdctx_size_t fdctxsize;
+ cbk_fdclose_t fdclose;
+ cbk_fdclose_t fdclosedir;
+};
+
+typedef int32_t (*dumpop_priv_t)(xlator_t *this);
+
+typedef int32_t (*dumpop_inode_t)(xlator_t *this);
+
+typedef int32_t (*dumpop_fd_t)(xlator_t *this);
+
+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,
+ char *brickname);
+
+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_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 {
+ xlator_t *xlator;
+ struct xlator_list *next;
+} xlator_list_t;
+
+typedef struct fop_metrics {
+ gf_atomic_t fop;
+ gf_atomic_t cbk; /* only updaed when there is failure */
+} fop_metrics_t;
+
+struct _xlator {
+ /* Built during parsing */
+ char *name;
+ char *type;
+ char *instance_name; /* Used for multi NFSd */
+ xlator_t *next;
+ xlator_t *prev;
+ xlator_list_t *parents;
+ xlator_list_t *children;
+ dict_t *options;
+
+ /* Set after doing dlopen() */
+ void *dlhandle;
+ struct xlator_fops *fops;
+ struct xlator_cbks *cbks;
+ struct xlator_dumpops *dumpops;
+ struct list_head volume_options; /* list of volume_option_t */
+
+ void (*fini)(xlator_t *this);
+ 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 (*dump_metrics)(xlator_t *this, int fd);
+
+ event_notify_fn_t notify;
+
+ gf_loglevel_t loglevel; /* Log level for translator */
+
+ struct {
+ struct {
+ /* for latency measurement */
+ fop_metrics_t metrics[GF_FOP_MAXVALUE];
+
+ gf_atomic_t count;
+ } total;
+
+ struct {
+ /* for latency measurement */
+ gf_latency_t latencies[GF_FOP_MAXVALUE];
+ /* for latency measurement */
+ fop_metrics_t metrics[GF_FOP_MAXVALUE];
+
+ gf_atomic_t count;
+ } interval;
+ } stats;
+
+ /* 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;
+ gf_boolean_t is_autoloaded;
+
+ /* Saved volfile ID (used for multiplexing) */
+ char *volfile_id;
+
+ /* Its used as an index to inode_ctx*/
+ uint32_t xl_id;
+
+ /* op_version: initialized in xlator code itself */
+ uint32_t op_version[GF_MAX_RELEASES];
+
+ /* flags: initialized in xlator code itself */
+ uint32_t flags;
+
+ /* id: unique, initialized in xlator code itself */
+ uint32_t id;
+
+ /* identifier: a full string which can unique identify the xlator */
+ char *identifier;
+
+ /* Is this pass_through? */
+ gf_boolean_t pass_through;
+ struct xlator_fops *pass_through_fops;
+
+ /* cleanup flag to avoid races during xlator cleanup */
+ uint32_t cleanup_starting;
+
+ /* flag to avoid recall of xlator_mem_cleanup for xame xlator */
+ uint32_t call_cleanup;
+
+ /* Flag to understand how this xlator is categorized */
+ gf_category_t category;
+
+ /* Variable to save xprt associated for detach brick */
+ gf_atomic_t xprtrefcnt;
+
+ /* Flag to notify got CHILD_DOWN event for detach brick */
+ uint32_t notify_down;
+
+ /* Flag to avoid throw duplicate PARENT_DOWN event */
+ uint32_t parent_down;
+};
+
+/* This would be the only structure which needs to be exported by
+ the translators. For the backward compatibility, in 4.x series
+ even the old exported fields will be supported */
+/* XXX: This struct is in use by GD2, and hence SHOULD NOT be modified.
+ * If the struct must be modified, see instructions at the comment with
+ * GD2MARKER below.
+ */
+typedef struct {
+ /* op_version: will be used by volume generation logic to figure
+ out whether to insert it in graph or no, based on cluster's
+ operating version.
+ default value: 0, which means good to insert always */
+ uint32_t op_version[GF_MAX_RELEASES];
+
+ /* flags: will be used by volume generation logic to optimize the
+ placements etc.
+ default value: 0, which means don't treat it specially */
+ uint32_t flags;
+
+ /* xlator_id: unique per xlator. make sure to have no collission
+ in this ID */
+ uint32_t xlator_id;
+
+ /* identifier: a string constant */
+ char *identifier;
+
+ /* struct options: if the translator takes any 'options' from the
+ volume file, then that should be defined here. optional. */
+ volume_option_t *options;
+
+ /* Flag to understand how this xlator is categorized */
+ gf_category_t category;
+
+ /* XXX: GD2MARKER
+ * If a new member that needs to be visible to GD2 is introduced,
+ * add it above this comment.
+ * Any other new members need to be added below this comment, or at the
+ * end of the struct
+ */
+
+ /* init(): mandatory method, will be called during the
+ graph initialization */
+ int32_t (*init)(xlator_t *this);
+
+ /* fini(): optional method, will be initialized to default
+ method which would just free the 'xlator->private' variable.
+ This method is called when the graph is no more in use, and
+ is being destroyed. Also when SIGTERM is received */
+ void (*fini)(xlator_t *this);
+
+ /* reconfigure(): optional method, will be initialized to default
+ method in case not provided by xlator. This method is called
+ when there are only option changes in xlator, and no graph change.
+ eg., a 'gluster volume set' command */
+ int32_t (*reconfigure)(xlator_t *this, dict_t *options);
+
+ /* mem_acct_init(): used for memory accounting inside of the xlator.
+ optional. called during translator initialization */
+ int32_t (*mem_acct_init)(xlator_t *this);
+
+ /* dump_metrics(): used for providing internal metrics. optional */
+ int32_t (*dump_metrics)(xlator_t *this, int fd);
+
+ /* notify(): used for handling the notification of events from either
+ the parent or child in the graph. optional. */
+ event_notify_fn_t notify;
+
+ /* struct fops: mandatory. provides all the filesystem operations
+ methods of the xlator */
+ struct xlator_fops *fops;
+ /* struct cbks: optional. provides methods to handle
+ inode forgets, and fd releases */
+ struct xlator_cbks *cbks;
+
+ /* dumpops: a structure again, with methods to dump the details.
+ optional. */
+ struct xlator_dumpops *dumpops;
+
+ /* struct pass_through_fops: optional. provides all the filesystem
+ operations which should be used if the xlator is marked as pass_through
+ */
+ /* by default, the default_fops would be used */
+ struct xlator_fops *pass_through_fops;
+} xlator_api_t;
+
+#define xlator_has_parent(xl) (xl->parents != NULL)
+
+#define XLATOR_NOTIFY(ret, _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);
+
+int32_t
+xlator_set_type(xlator_t *xl, const char *type);
+
+int32_t
+xlator_dynload(xlator_t *xl);
+
+xlator_t *
+file_to_xlator_tree(glusterfs_ctx_t *ctx, FILE *fp);
+
+int
+xlator_notify(xlator_t *this, int32_t event, void *data, ...);
+int
+xlator_init(xlator_t *this);
+int
+xlator_destroy(xlator_t *xl);
+
+int32_t
+xlator_tree_init(xlator_t *xl);
+int32_t
+xlator_tree_free_members(xlator_t *xl);
+int32_t
+xlator_tree_free_memacct(xlator_t *xl);
+
+void
+xlator_tree_fini(xlator_t *xl);
+
+void
+xlator_foreach(xlator_t *this, void (*fn)(xlator_t *each, void *data),
+ void *data);
+
+void
+xlator_foreach_depth_first(xlator_t *this,
+ void (*fn)(xlator_t *each, void *data), void *data);
+
+xlator_t *
+xlator_search_by_name(xlator_t *any, const char *name);
+xlator_t *
+get_xlator_by_name(xlator_t *this, char *target);
+xlator_t *
+get_xlator_by_type(xlator_t *this, char *target);
+
+void
+xlator_set_inode_lru_limit(xlator_t *this, void *data);
+
+void
+inode_destroy_notify(inode_t *inode, const char *xlname);
+
+int
+loc_copy(loc_t *dst, loc_t *src);
+int
+loc_copy_overload_parent(loc_t *dst, loc_t *src, inode_t *parent);
+#define loc_dup(src, dst) loc_copy(dst, src)
+void
+loc_wipe(loc_t *loc);
+int
+loc_path(loc_t *loc, const char *bname);
+void
+loc_gfid(loc_t *loc, uuid_t gfid);
+void
+loc_pargfid(loc_t *loc, uuid_t pargfid);
+char *
+loc_gfid_utoa(loc_t *loc);
+gf_boolean_t
+loc_is_root(loc_t *loc);
+int32_t
+loc_build_child(loc_t *child, loc_t *parent, char *name);
+gf_boolean_t
+loc_is_nameless(loc_t *loc);
+int
+xlator_mem_acct_init(xlator_t *xl, int num_types);
+void
+xlator_mem_acct_unref(struct mem_acct *mem_acct);
+int
+is_gf_log_command(xlator_t *trans, const char *name, char *value, size_t size);
+int
+glusterd_check_log_level(const char *value);
+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,
+};
+gf_boolean_t
+is_graph_topology_equal(glusterfs_graph_t *graph1, glusterfs_graph_t *graph2);
+int
+glusterfs_volfile_reconfigure(FILE *newvolfile_fp, glusterfs_ctx_t *ctx);
+
+int
+gf_volfile_reconfigure(int oldvollen, FILE *newvolfile_fp, glusterfs_ctx_t *ctx,
+ const char *oldvolfile);
+
+int
+loc_touchup(loc_t *loc, const char *name);
+
+int
+glusterfs_leaf_position(xlator_t *tgt);
+
+int
+glusterfs_reachable_leaves(xlator_t *base, dict_t *leaves);
+
+int
+xlator_subvolume_count(xlator_t *this);
+
+void
+xlator_init_lock(void);
+void
+xlator_init_unlock(void);
+int
+copy_opts_to_child(xlator_t *src, xlator_t *dst, char *glob);
+
+int
+glusterfs_delete_volfile_checksum(glusterfs_ctx_t *ctx, const char *volfile_id);
+int
+xlator_memrec_free(xlator_t *xl);
+
+void
+xlator_mem_cleanup(xlator_t *this);
+
+void
+handle_default_options(xlator_t *xl, dict_t *options);
+
+void
+gluster_graph_take_reference(xlator_t *tree);
+
+gf_boolean_t
+mgmt_is_multiplexed_daemon(char *name);
+
+gf_boolean_t
+xlator_is_cleanup_starting(xlator_t *this);
+int
+graph_total_client_xlator(glusterfs_graph_t *graph);
+#endif /* _XLATOR_H */
diff --git a/libglusterfs/src/graph-print.c b/libglusterfs/src/graph-print.c
index 676167b17d2..595d74330a1 100644
--- a/libglusterfs/src/graph-print.c
+++ b/libglusterfs/src/graph-print.c
@@ -10,188 +10,126 @@
#include <sys/uio.h>
-#include "common-utils.h"
-#include "xlator.h"
-#include "graph-utils.h"
-#include "libglusterfs-messages.h"
-
+#include "glusterfs/common-utils.h"
+#include "glusterfs/xlator.h"
+#include "glusterfs/graph-utils.h"
+#include "glusterfs/libglusterfs-messages.h"
struct gf_printer {
- ssize_t (*write) (struct gf_printer *gp, char *buf, size_t len);
- void *priv;
- int len;
+ ssize_t (*write)(struct gf_printer *gp, char *buf, size_t len);
+ void *priv;
+ int len;
};
static ssize_t
-gp_write_file (struct gf_printer *gp, char *buf, size_t len)
+gp_write_file(struct gf_printer *gp, char *buf, size_t len)
{
- FILE *f = gp->priv;
-
- if (fwrite (buf, len, 1, f) != 1) {
- gf_msg ("graph-print", GF_LOG_ERROR, errno,
- LG_MSG_FWRITE_FAILED, "fwrite failed");
-
- return -1;
- }
+ FILE *f = gp->priv;
- return len;
-}
-
-static ssize_t
-gp_write_buf (struct gf_printer *gp, char *buf, size_t len)
-{
- struct iovec *iov = gp->priv;
+ if (fwrite(buf, len, 1, f) != 1) {
+ gf_msg("graph-print", GF_LOG_ERROR, errno, LG_MSG_FWRITE_FAILED,
+ "fwrite failed");
- if (iov->iov_len < len) {
- gf_msg ("graph-print", GF_LOG_ERROR, 0, LG_MSG_BUFFER_FULL,
- "buffer full");
-
- return -1;
- }
-
- memcpy (iov->iov_base, buf, len);
- iov->iov_base += len;
- iov->iov_len -= len;
+ return -1;
+ }
- return len;
+ return len;
}
static int
-gpprintf (struct gf_printer *gp, const char *format, ...)
+gpprintf(struct gf_printer *gp, const char *format, ...)
{
- va_list arg;
- char *str = NULL;
- int ret = 0;
+ va_list arg;
+ char *str = NULL;
+ int ret = 0;
- va_start (arg, format);
- ret = gf_vasprintf (&str, format, arg);
- va_end (arg);
+ va_start(arg, format);
+ ret = gf_vasprintf(&str, format, arg);
+ va_end(arg);
- if (ret < 0)
- return ret;
+ if (ret < 0)
+ return ret;
- ret = gp->write (gp, str, ret);
+ ret = gp->write(gp, str, ret);
- GF_FREE (str);
+ GF_FREE(str);
- return ret;
+ return ret;
}
-#define GPPRINTF(gp, fmt, ...) do { \
- ret = gpprintf (gp, fmt, ## __VA_ARGS__); \
- if (ret == -1) \
- goto out; \
- else \
- gp->len += ret; \
- } while (0)
+#define GPPRINTF(gp, fmt, ...) \
+ do { \
+ ret = gpprintf(gp, fmt, ##__VA_ARGS__); \
+ if (ret == -1) \
+ goto out; \
+ else \
+ gp->len += ret; \
+ } while (0)
static int
-_print_volume_options (dict_t *d, char *k, data_t *v,
- void *tmp)
+_print_volume_options(dict_t *d, char *k, data_t *v, void *tmp)
{
- struct gf_printer *gp = tmp;
- int ret = 0;
- GPPRINTF (gp, " option %s %s\n", k, v->data);
- return 0;
+ struct gf_printer *gp = tmp;
+ int ret = 0;
+ GPPRINTF(gp, " option %s %s\n", k, v->data);
+ return 0;
out:
- /* means, it is a failure */
- return -1;
+ /* means, it is a failure */
+ return -1;
}
static int
-glusterfs_graph_print (struct gf_printer *gp, glusterfs_graph_t *graph)
+glusterfs_graph_print(struct gf_printer *gp, glusterfs_graph_t *graph)
{
- xlator_t *trav = NULL;
- xlator_list_t *xch = NULL;
- int ret = 0;
- ssize_t len = 0;
-
- if (!graph->first)
- return 0;
+ xlator_t *trav = NULL;
+ xlator_list_t *xch = NULL;
+ int ret = 0;
+ ssize_t len = 0;
- for (trav = graph->first; trav->next; trav = trav->next);
- for (; trav; trav = trav->prev) {
- GPPRINTF (gp, "volume %s\n type %s\n", trav->name,
- trav->type);
+ if (!graph->first)
+ return 0;
- ret = dict_foreach (trav->options, _print_volume_options, gp);
- if (ret)
- goto out;
+ for (trav = graph->first; trav->next; trav = trav->next)
+ ;
+ for (; trav; trav = trav->prev) {
+ GPPRINTF(gp, "volume %s\n type %s\n", trav->name, trav->type);
- if (trav->children) {
- GPPRINTF (gp, " subvolumes");
+ ret = dict_foreach(trav->options, _print_volume_options, gp);
+ if (ret)
+ goto out;
- for (xch = trav->children; xch; xch = xch->next)
- GPPRINTF (gp, " %s", xch->xlator->name);
+ if (trav->children) {
+ GPPRINTF(gp, " subvolumes");
- GPPRINTF (gp, "\n");
- }
+ for (xch = trav->children; xch; xch = xch->next)
+ GPPRINTF(gp, " %s", xch->xlator->name);
- GPPRINTF (gp, "end-volume\n");
- if (trav != graph->first)
- GPPRINTF (gp, "\n");
+ GPPRINTF(gp, "\n");
}
+ GPPRINTF(gp, "end-volume\n");
+ if (trav != graph->first)
+ GPPRINTF(gp, "\n");
+ }
+
out:
- len = gp->len;
- if (ret == -1) {
- gf_msg ("graph-print", GF_LOG_ERROR, 0, LG_MSG_PRINT_FAILED,
- "printing failed");
+ len = gp->len;
+ if (ret == -1) {
+ gf_msg("graph-print", GF_LOG_ERROR, 0, LG_MSG_PRINT_FAILED,
+ "printing failed");
- return -1;
- }
+ return -1;
+ }
- return len;
+ return len;
#undef GPPRINTF
}
int
-glusterfs_graph_print_file (FILE *file, glusterfs_graph_t *graph)
+glusterfs_graph_print_file(FILE *file, glusterfs_graph_t *graph)
{
- struct gf_printer gp = { .write = gp_write_file,
- .priv = file
- };
-
- return glusterfs_graph_print (&gp, graph);
-}
-
-char *
-glusterfs_graph_print_buf (glusterfs_graph_t *graph)
-{
- FILE *f = NULL;
- struct iovec iov = {0,};
- int len = 0;
- char *buf = NULL;
- struct gf_printer gp = { .write = gp_write_buf,
- .priv = &iov
- };
-
- f = fopen ("/dev/null", "a");
- if (!f) {
- gf_msg ("graph-print", GF_LOG_ERROR, errno,
- LG_MSG_DIR_OP_FAILED, "cannot open /dev/null");
-
- return NULL;
- }
- len = glusterfs_graph_print_file (f, graph);
- fclose (f);
- if (len == -1)
- return NULL;
-
- buf = GF_CALLOC (1, len + 1, gf_common_mt_graph_buf);
- if (!buf) {
- return NULL;
- }
- iov.iov_base = buf;
- iov.iov_len = len;
-
- len = glusterfs_graph_print (&gp, graph);
- if (len == -1) {
- GF_FREE (buf);
-
- return NULL;
- }
+ struct gf_printer gp = {.write = gp_write_file, .priv = file};
- return buf;
+ return glusterfs_graph_print(&gp, graph);
}
diff --git a/libglusterfs/src/graph.c b/libglusterfs/src/graph.c
index ed12b1c0e7f..13f298eb3bd 100644
--- a/libglusterfs/src/graph.c
+++ b/libglusterfs/src/graph.c
@@ -8,15 +8,32 @@
cases as published by the Free Software Foundation.
*/
-#include "xlator.h"
-#include <dlfcn.h>
-#include <netdb.h>
-#include <fnmatch.h>
-#include <stdlib.h>
-#include "defaults.h"
-#include <unistd.h>
-
-#include "libglusterfs-messages.h"
+#include <stdint.h> // for uint32_t
+#include <sys/time.h> // for timeval
+#include <errno.h> // for EIO, errno, EINVAL, ENOMEM
+#include <fnmatch.h> // for fnmatch, FNM_NOESCAPE
+#include <openssl/sha.h> // for SHA256_DIGEST_LENGTH
+#include <regex.h> // for regmatch_t, regcomp
+#include <stdio.h> // for fclose, fopen, snprintf
+#include <stdlib.h> // for NULL, atoi, mkstemp
+#include <string.h> // for strcmp, strerror, memcpy
+#include <strings.h> // for rindex
+#include <sys/stat.h> // for stat
+#include <sys/time.h> // for gettimeofday
+#include <unistd.h> // for gethostname, getpid
+#include "glusterfs/common-utils.h" // for gf_strncpy, gf_time_fmt
+#include "glusterfs/defaults.h"
+#include "glusterfs/dict.h" // for dict_foreach, dict_set_...
+#include "glusterfs/globals.h" // for xlator_t, xlator_list_t
+#include "glusterfs/glusterfs.h" // for glusterfs_graph_t, glus...
+#include "glusterfs/glusterfs-fops.h" // for GF_EVENT_GRAPH_NEW, GF_...
+#include "glusterfs/libglusterfs-messages.h" // for LG_MSG_GRAPH_ERROR, LG_...
+#include "glusterfs/list.h" // for list_add, list_del_init
+#include "glusterfs/logging.h" // for gf_msg, GF_LOG_ERROR
+#include "glusterfs/mem-pool.h" // for GF_FREE, gf_strdup, GF_...
+#include "glusterfs/mem-types.h" // for gf_common_mt_xlator_list_t
+#include "glusterfs/options.h" // for xlator_tree_reconfigure
+#include "glusterfs/syscall.h" // for sys_close, sys_stat
#if 0
static void
@@ -24,7 +41,7 @@ _gf_dump_details (int argc, char **argv)
{
extern FILE *gf_log_logfile;
int i = 0;
- char timestr[64];
+ char timestr[GF_TIMESTR_SIZE];
time_t utime = 0;
pid_t mypid = 0;
struct utsname uname_buf = {{0, }, };
@@ -67,556 +84,648 @@ _gf_dump_details (int argc, char **argv)
}
#endif
+int
+glusterfs_read_secure_access_file(void)
+{
+ FILE *fp = NULL;
+ char line[100] = {
+ 0,
+ };
+ int cert_depth = 1; /* Default SSL CERT DEPTH */
+ regex_t regcmpl;
+ char *key = {"^option transport.socket.ssl-cert-depth"};
+ char keyval[50] = {
+ 0,
+ };
+ int start = 0, end = 0, copy_len = 0;
+ regmatch_t result[1] = {{0}};
+
+ fp = fopen(SECURE_ACCESS_FILE, "r");
+ if (!fp)
+ goto out;
+
+ /* Check if any line matches with key */
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ if (regcomp(&regcmpl, key, REG_EXTENDED)) {
+ goto out;
+ }
+ if (!regexec(&regcmpl, line, 1, result, 0)) {
+ start = result[0].rm_so;
+ end = result[0].rm_eo;
+ copy_len = end - start;
+ gf_strncpy(keyval, line + copy_len, sizeof(keyval));
+ if (keyval[0]) {
+ cert_depth = atoi(keyval);
+ if (cert_depth == 0)
+ cert_depth = 1; /* Default SSL CERT DEPTH */
+ break;
+ }
+ }
+ regfree(&regcmpl);
+ }
+out:
+ if (fp)
+ fclose(fp);
+ return cert_depth;
+}
-int
-glusterfs_xlator_link (xlator_t *pxl, xlator_t *cxl)
+xlator_t *
+glusterfs_get_last_xlator(glusterfs_graph_t *graph)
{
- xlator_list_t *xlchild = NULL;
- xlator_list_t *xlparent = NULL;
- xlator_list_t **tmp = NULL;
+ xlator_t *trav = graph->first;
+ if (!trav)
+ return NULL;
- xlparent = (void *) GF_CALLOC (1, sizeof (*xlparent),
- gf_common_mt_xlator_list_t);
- if (!xlparent)
- return -1;
+ while (trav->next)
+ trav = trav->next;
- xlchild = (void *) GF_CALLOC (1, sizeof (*xlchild),
- gf_common_mt_xlator_list_t);
- if (!xlchild) {
- GF_FREE (xlparent);
+ return trav;
+}
- return -1;
+xlator_t *
+glusterfs_mux_xlator_unlink(xlator_t *pxl, xlator_t *cxl)
+{
+ xlator_list_t *unlink = NULL;
+ xlator_list_t *prev = NULL;
+ xlator_list_t **tmp = NULL;
+ xlator_t *next_child = NULL;
+ xlator_t *xl = NULL;
+
+ for (tmp = &pxl->children; *tmp; tmp = &(*tmp)->next) {
+ if ((*tmp)->xlator == cxl) {
+ unlink = *tmp;
+ *tmp = (*tmp)->next;
+ if (*tmp)
+ next_child = (*tmp)->xlator;
+ break;
}
+ prev = *tmp;
+ }
- xlparent->xlator = pxl;
- for (tmp = &cxl->parents; *tmp; tmp = &(*tmp)->next);
- *tmp = xlparent;
+ if (!prev)
+ xl = pxl;
+ else if (prev->xlator)
+ xl = prev->xlator->graph->last_xl;
- xlchild->xlator = cxl;
- for (tmp = &pxl->children; *tmp; tmp = &(*tmp)->next);
- *tmp = xlchild;
+ if (xl)
+ xl->next = next_child;
+ if (next_child)
+ next_child->prev = xl;
- return 0;
+ GF_FREE(unlink);
+ return next_child;
}
+int
+glusterfs_xlator_link(xlator_t *pxl, xlator_t *cxl)
+{
+ xlator_list_t *xlchild = NULL;
+ xlator_list_t *xlparent = NULL;
+ xlator_list_t **tmp = NULL;
+
+ xlparent = (void *)GF_CALLOC(1, sizeof(*xlparent),
+ gf_common_mt_xlator_list_t);
+ if (!xlparent)
+ return -1;
+
+ xlchild = (void *)GF_CALLOC(1, sizeof(*xlchild),
+ gf_common_mt_xlator_list_t);
+ if (!xlchild) {
+ GF_FREE(xlparent);
+
+ return -1;
+ }
+
+ xlparent->xlator = pxl;
+ for (tmp = &cxl->parents; *tmp; tmp = &(*tmp)->next)
+ ;
+ *tmp = xlparent;
+
+ xlchild->xlator = cxl;
+ for (tmp = &pxl->children; *tmp; tmp = &(*tmp)->next)
+ ;
+ *tmp = xlchild;
+
+ return 0;
+}
void
-glusterfs_graph_set_first (glusterfs_graph_t *graph, xlator_t *xl)
+glusterfs_graph_set_first(glusterfs_graph_t *graph, xlator_t *xl)
{
- xl->next = graph->first;
- if (graph->first)
- ((xlator_t *)graph->first)->prev = xl;
- graph->first = xl;
+ xl->next = graph->first;
+ if (graph->first)
+ ((xlator_t *)graph->first)->prev = xl;
+ graph->first = xl;
- graph->xl_count++;
+ graph->xl_count++;
+ xl->xl_id = graph->xl_count;
}
-
int
-glusterfs_graph_insert (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx,
- const char *type, const char *name,
- gf_boolean_t autoload)
+glusterfs_graph_insert(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx,
+ const char *type, const char *name,
+ gf_boolean_t autoload)
{
- xlator_t *ixl = NULL;
+ xlator_t *ixl = NULL;
- if (!ctx->master) {
- gf_msg ("glusterfs", GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR,
- "volume \"%s\" can be added from command line only "
- "on client side", type);
+ if (!ctx->master) {
+ gf_msg("glusterfs", GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR,
+ "volume \"%s\" can be added from command line only "
+ "on client side",
+ type);
- return -1;
- }
+ return -1;
+ }
- ixl = GF_CALLOC (1, sizeof (*ixl), gf_common_mt_xlator_t);
- if (!ixl)
- return -1;
+ ixl = GF_CALLOC(1, sizeof(*ixl), gf_common_mt_xlator_t);
+ if (!ixl)
+ return -1;
- ixl->ctx = ctx;
- ixl->graph = graph;
- ixl->options = get_new_dict ();
- if (!ixl->options)
- goto err;
+ ixl->ctx = ctx;
+ ixl->graph = graph;
+ ixl->options = dict_new();
+ if (!ixl->options)
+ goto err;
- ixl->name = gf_strdup (name);
- if (!ixl->name)
- goto err;
+ ixl->name = gf_strdup(name);
+ if (!ixl->name)
+ goto err;
- ixl->is_autoloaded = autoload;
+ ixl->is_autoloaded = autoload;
- if (xlator_set_type (ixl, type) == -1) {
- gf_msg ("glusterfs", GF_LOG_ERROR, 0, LG_MSG_INIT_FAILED,
- "%s (%s) initialization failed",
- name, type);
- return -1;
- }
+ if (xlator_set_type(ixl, type) == -1) {
+ gf_msg("glusterfs", GF_LOG_ERROR, 0, LG_MSG_INIT_FAILED,
+ "%s (%s) initialization failed", name, type);
+ return -1;
+ }
- if (glusterfs_xlator_link (ixl, graph->top) == -1)
- goto err;
- glusterfs_graph_set_first (graph, ixl);
- graph->top = ixl;
+ if (glusterfs_xlator_link(ixl, graph->top) == -1)
+ goto err;
+ glusterfs_graph_set_first(graph, ixl);
+ graph->top = ixl;
- return 0;
+ return 0;
err:
- xlator_destroy (ixl);
- return -1;
+ xlator_destroy(ixl);
+ return -1;
}
int
-glusterfs_graph_acl (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;
+ int ret = 0;
+ cmd_args_t *cmd_args = NULL;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- if (!cmd_args->acl)
- return 0;
+ if (!cmd_args->acl)
+ return 0;
- ret = glusterfs_graph_insert (graph, ctx, "system/posix-acl",
- "posix-acl-autoload", 1);
- return ret;
+ ret = glusterfs_graph_insert(graph, ctx, "system/posix-acl",
+ "posix-acl-autoload", 1);
+ return ret;
}
int
-glusterfs_graph_worm (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+glusterfs_graph_worm(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
{
- int ret = 0;
- cmd_args_t *cmd_args = NULL;
+ int ret = 0;
+ cmd_args_t *cmd_args = NULL;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- if (!cmd_args->worm)
- return 0;
+ if (!cmd_args->worm)
+ return 0;
- ret = glusterfs_graph_insert (graph, ctx, "features/worm",
- "worm-autoload", 1);
- return ret;
+ ret = glusterfs_graph_insert(graph, ctx, "features/worm", "worm-autoload",
+ 1);
+ return ret;
}
-
int
-glusterfs_graph_meta (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+glusterfs_graph_meta(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
{
- int ret = 0;
+ int ret = 0;
- if (!ctx->master)
- return 0;
+ if (!ctx->master)
+ return 0;
- ret = glusterfs_graph_insert (graph, ctx, "meta",
- "meta-autoload", 1);
- return ret;
+ ret = glusterfs_graph_insert(graph, ctx, "meta", "meta-autoload", 1);
+ return ret;
}
-
int
-glusterfs_graph_mac_compat (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+glusterfs_graph_mac_compat(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
{
- int ret = 0;
- cmd_args_t *cmd_args = NULL;
+ int ret = 0;
+ cmd_args_t *cmd_args = NULL;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- if (cmd_args->mac_compat == GF_OPTION_DISABLE)
- return 0;
+ if (cmd_args->mac_compat == GF_OPTION_DISABLE)
+ return 0;
- ret = glusterfs_graph_insert (graph, ctx, "features/mac-compat",
- "mac-compat-autoload", 1);
+ ret = glusterfs_graph_insert(graph, ctx, "features/mac-compat",
+ "mac-compat-autoload", 1);
- return ret;
+ return ret;
}
int
-glusterfs_graph_gfid_access (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+glusterfs_graph_gfid_access(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
{
- int ret = 0;
- cmd_args_t *cmd_args = NULL;
+ int ret = 0;
+ cmd_args_t *cmd_args = NULL;
- cmd_args = &ctx->cmd_args;
+ cmd_args = &ctx->cmd_args;
- if (!cmd_args->aux_gfid_mount)
- return 0;
+ if (!cmd_args->aux_gfid_mount)
+ return 0;
- ret = glusterfs_graph_insert (graph, ctx, "features/gfid-access",
- "gfid-access-autoload", 1);
- return ret;
+ ret = glusterfs_graph_insert(graph, ctx, "features/gfid-access",
+ "gfid-access-autoload", 1);
+ return ret;
}
static void
-gf_add_cmdline_options (glusterfs_graph_t *graph, cmd_args_t *cmd_args)
-{
- int ret = 0;
- xlator_t *trav = NULL;
- xlator_cmdline_option_t *cmd_option = NULL;
-
- trav = graph->first;
-
- while (trav) {
- list_for_each_entry (cmd_option,
- &cmd_args->xlator_options, cmd_args) {
- if (!fnmatch (cmd_option->volume,
- trav->name, FNM_NOESCAPE)) {
- ret = dict_set_str (trav->options,
- cmd_option->key,
- cmd_option->value);
- if (ret == 0) {
- gf_msg (trav->name, GF_LOG_INFO, 0,
- LG_MSG_VOL_OPTION_ADD,
- "adding option '%s' for "
- "volume '%s' with value '%s'",
- cmd_option->key, trav->name,
- cmd_option->value);
- } else {
- gf_msg (trav->name, GF_LOG_WARNING,
- -ret, LG_MSG_VOL_OPTION_ADD,
- "adding option '%s' for "
- "volume '%s' failed",
- cmd_option->key, trav->name);
- }
- }
+gf_add_cmdline_options(glusterfs_graph_t *graph, cmd_args_t *cmd_args)
+{
+ int ret = 0;
+ xlator_t *trav = NULL;
+ xlator_cmdline_option_t *cmd_option = NULL;
+
+ trav = graph->first;
+
+ while (trav) {
+ list_for_each_entry(cmd_option, &cmd_args->xlator_options, cmd_args)
+ {
+ if (!fnmatch(cmd_option->volume, trav->name, FNM_NOESCAPE)) {
+ ret = dict_set_str(trav->options, cmd_option->key,
+ cmd_option->value);
+ if (ret == 0) {
+ gf_msg(trav->name, GF_LOG_TRACE, 0, LG_MSG_VOL_OPTION_ADD,
+ "adding option '%s' for "
+ "volume '%s' with value '%s'",
+ cmd_option->key, trav->name, cmd_option->value);
+ } else {
+ gf_msg(trav->name, GF_LOG_WARNING, -ret,
+ LG_MSG_VOL_OPTION_ADD,
+ "adding option '%s' for "
+ "volume '%s' failed",
+ cmd_option->key, trav->name);
}
- trav = trav->next;
+ }
}
+ trav = trav->next;
+ }
}
-
int
-glusterfs_graph_validate_options (glusterfs_graph_t *graph)
+glusterfs_graph_validate_options(glusterfs_graph_t *graph)
{
- xlator_t *trav = NULL;
- int ret = -1;
- char *errstr = NULL;
+ xlator_t *trav = NULL;
+ int ret = -1;
+ char *errstr = NULL;
- trav = graph->first;
+ trav = graph->first;
- while (trav) {
- if (list_empty (&trav->volume_options))
- continue;
+ while (trav) {
+ if (list_empty(&trav->volume_options)) {
+ trav = trav->next;
+ continue;
+ }
- ret = xlator_options_validate (trav, trav->options, &errstr);
- if (ret) {
- gf_msg (trav->name, GF_LOG_ERROR, 0,
- LG_MSG_VALIDATION_FAILED, "validation failed: "
- "%s", errstr);
- return ret;
- }
- trav = trav->next;
+ ret = xlator_options_validate(trav, trav->options, &errstr);
+ if (ret) {
+ gf_msg(trav->name, GF_LOG_ERROR, 0, LG_MSG_VALIDATION_FAILED,
+ "validation failed: "
+ "%s",
+ errstr);
+ return ret;
}
+ trav = trav->next;
+ }
- return 0;
+ return 0;
}
-
int
-glusterfs_graph_init (glusterfs_graph_t *graph)
+glusterfs_graph_init(glusterfs_graph_t *graph)
{
- xlator_t *trav = NULL;
- int ret = -1;
+ xlator_t *trav = NULL;
+ int ret = -1;
- trav = graph->first;
+ trav = graph->first;
- while (trav) {
- ret = xlator_init (trav);
- if (ret) {
- gf_msg (trav->name, GF_LOG_ERROR, 0,
- LG_MSG_TRANSLATOR_INIT_FAILED,
- "initializing translator failed");
- return ret;
- }
- trav = trav->next;
+ while (trav) {
+ ret = xlator_init(trav);
+ if (ret) {
+ gf_msg(trav->name, GF_LOG_ERROR, 0, LG_MSG_TRANSLATOR_INIT_FAILED,
+ "initializing translator failed");
+ return ret;
}
+ trav = trav->next;
+ }
- return 0;
+ return 0;
}
int
-glusterfs_graph_deactivate (glusterfs_graph_t *graph)
+glusterfs_graph_deactivate(glusterfs_graph_t *graph)
{
- xlator_t *top = NULL;
+ xlator_t *top = NULL;
- if (graph == NULL)
- goto out;
+ if (graph == NULL)
+ goto out;
- top = graph->top;
- xlator_tree_fini (top);
- out:
- return 0;
+ top = graph->top;
+ xlator_tree_fini(top);
+out:
+ return 0;
}
static int
-_log_if_unknown_option (dict_t *dict, char *key, data_t *value, void *data)
+_log_if_unknown_option(dict_t *dict, char *key, data_t *value, void *data)
{
- volume_option_t *found = NULL;
- xlator_t *xl = NULL;
+ volume_option_t *found = NULL;
+ xlator_t *xl = NULL;
- xl = data;
+ xl = data;
- found = xlator_volume_option_get (xl, key);
+ found = xlator_volume_option_get(xl, key);
- if (!found) {
- gf_msg (xl->name, GF_LOG_WARNING, 0,
- LG_MSG_XLATOR_OPTION_INVALID,
- "option '%s' is not recognized", key);
- }
+ if (!found) {
+ gf_msg(xl->name, GF_LOG_DEBUG, 0, LG_MSG_XLATOR_OPTION_INVALID,
+ "option '%s' is not recognized", key);
+ }
- return 0;
+ return 0;
}
-
static void
-_xlator_check_unknown_options (xlator_t *xl, void *data)
+_xlator_check_unknown_options(xlator_t *xl, void *data)
{
- dict_foreach (xl->options, _log_if_unknown_option, xl);
+ dict_foreach(xl->options, _log_if_unknown_option, xl);
}
-
-int
-glusterfs_graph_unknown_options (glusterfs_graph_t *graph)
+static int
+glusterfs_graph_unknown_options(glusterfs_graph_t *graph)
{
- xlator_foreach (graph->first, _xlator_check_unknown_options, NULL);
- return 0;
+ xlator_foreach(graph->first, _xlator_check_unknown_options, NULL);
+ return 0;
}
-
-void
-fill_uuid (char *uuid, int size)
+static void
+fill_uuid(char *uuid, int size, struct timeval tv)
{
- char hostname[256] = {0,};
- struct timeval tv = {0,};
- char now_str[64];
+ char hostname[50] = {
+ 0,
+ };
+ char now_str[GF_TIMESTR_SIZE];
- if (gettimeofday (&tv, NULL) == -1) {
- gf_msg ("graph", GF_LOG_ERROR, errno,
- LG_MSG_GETTIMEOFDAY_FAILED, "gettimeofday: "
- "failed");
- }
-
- if (gethostname (hostname, 256) == -1) {
- gf_msg ("graph", GF_LOG_ERROR, errno,
- LG_MSG_GETHOSTNAME_FAILED, "gethostname: "
- "failed");
- }
+ if (gethostname(hostname, sizeof(hostname) - 1) != 0) {
+ gf_msg("graph", GF_LOG_ERROR, errno, LG_MSG_GETHOSTNAME_FAILED,
+ "gethostname failed");
+ hostname[sizeof(hostname) - 1] = '\0';
+ }
- gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_dirent);
- snprintf (uuid, size, "%s-%d-%s:%"GF_PRI_SUSECONDS,
- hostname, getpid(), now_str, tv.tv_usec);
+ gf_time_fmt_tv(now_str, sizeof now_str, &tv, gf_timefmt_dirent);
+ snprintf(uuid, size, "%s-%d-%s", hostname, getpid(), now_str);
- return;
+ return;
}
-
-int
-glusterfs_graph_settop (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+static int
+glusterfs_graph_settop(glusterfs_graph_t *graph, char *volume_name,
+ gf_boolean_t exact_match)
{
- const char *volume_name = NULL;
- xlator_t *trav = NULL;
-
- volume_name = ctx->cmd_args.volume_name;
-
- if (!volume_name) {
- graph->top = graph->first;
- return 0;
- }
+ int ret = -1;
+ xlator_t *trav = NULL;
+ if (!volume_name || !exact_match) {
+ graph->top = graph->first;
+ ret = 0;
+ } else {
for (trav = graph->first; trav; trav = trav->next) {
- if (strcmp (trav->name, volume_name) == 0) {
- graph->top = trav;
- return 0;
- }
+ if (strcmp(trav->name, volume_name) == 0) {
+ graph->top = trav;
+ ret = 0;
+ break;
+ }
}
+ }
- return -1;
+ return ret;
}
-
int
-glusterfs_graph_parent_up (glusterfs_graph_t *graph)
+glusterfs_graph_parent_up(glusterfs_graph_t *graph)
{
- xlator_t *trav = NULL;
- int ret = -1;
+ xlator_t *trav = NULL;
+ int ret = -1;
- trav = graph->first;
+ trav = graph->first;
- while (trav) {
- if (!xlator_has_parent (trav)) {
- ret = xlator_notify (trav, GF_EVENT_PARENT_UP, trav);
- }
+ while (trav) {
+ if (!xlator_has_parent(trav)) {
+ ret = xlator_notify(trav, GF_EVENT_PARENT_UP, trav);
+ }
- if (ret)
- break;
+ if (ret)
+ break;
- trav = trav->next;
- }
+ trav = trav->next;
+ }
- return ret;
+ return ret;
}
-
int
-glusterfs_graph_prepare (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+glusterfs_graph_prepare(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx,
+ char *volume_name)
{
- xlator_t *trav = NULL;
- int ret = 0;
-
- /* XXX: CHECKSUM */
-
- /* XXX: attach to -n volname */
- ret = glusterfs_graph_settop (graph, ctx);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
- "glusterfs graph settop failed");
- return -1;
- }
+ xlator_t *trav = NULL;
+ int ret = 0;
+
+ /* XXX: CHECKSUM */
+
+ /* XXX: attach to -n volname */
+ /* A '/' in the volume name suggests brick multiplexing is used, find
+ * the top of the (sub)graph. The volname MUST match the subvol in this
+ * case. In other cases (like for gfapi) the default top for the
+ * (sub)graph is ok. */
+ if (!volume_name) {
+ /* GlusterD does not pass a volume_name */
+ ret = glusterfs_graph_settop(graph, volume_name, _gf_false);
+ } else if (strncmp(volume_name, "/snaps/", 7) == 0) {
+ /* snap shots have their top xlator named like "/snaps/..." */
+ ret = glusterfs_graph_settop(graph, volume_name, _gf_false);
+ } else if (volume_name[0] == '/') {
+ /* brick multiplexing passes the brick path */
+ ret = glusterfs_graph_settop(graph, volume_name, _gf_true);
+ } else {
+ ret = glusterfs_graph_settop(graph, volume_name, _gf_false);
+ }
+
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, EINVAL, LG_MSG_GRAPH_ERROR,
+ "glusterfs graph settop failed");
+ errno = EINVAL;
+ return -1;
+ }
- /* XXX: WORM VOLUME */
- ret = glusterfs_graph_worm (graph, ctx);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
- "glusterfs graph worm failed");
- return -1;
- }
- ret = glusterfs_graph_acl (graph, ctx);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
- "glusterfs graph ACL failed");
- return -1;
- }
+ /* XXX: WORM VOLUME */
+ ret = glusterfs_graph_worm(graph, ctx);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
+ "glusterfs graph worm failed");
+ return -1;
+ }
+ ret = glusterfs_graph_acl(graph, ctx);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
+ "glusterfs graph ACL failed");
+ return -1;
+ }
- /* XXX: MAC COMPAT */
- ret = glusterfs_graph_mac_compat (graph, ctx);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
- "glusterfs graph mac compat failed");
- return -1;
- }
+ /* XXX: MAC COMPAT */
+ ret = glusterfs_graph_mac_compat(graph, ctx);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
+ "glusterfs graph mac compat failed");
+ return -1;
+ }
- /* XXX: gfid-access */
- ret = glusterfs_graph_gfid_access (graph, ctx);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
- "glusterfs graph 'gfid-access' failed");
- return -1;
- }
+ /* XXX: gfid-access */
+ ret = glusterfs_graph_gfid_access(graph, ctx);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
+ "glusterfs graph 'gfid-access' failed");
+ return -1;
+ }
- /* XXX: topmost xlator */
- ret = glusterfs_graph_meta (graph, ctx);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
- "glusterfs graph meta failed");
- return -1;
- }
+ /* XXX: topmost xlator */
+ ret = glusterfs_graph_meta(graph, ctx);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_ERROR,
+ "glusterfs graph meta failed");
+ return -1;
+ }
- /* XXX: this->ctx setting */
- for (trav = graph->first; trav; trav = trav->next) {
- trav->ctx = ctx;
- }
+ /* XXX: this->ctx setting */
+ for (trav = graph->first; trav; trav = trav->next) {
+ trav->ctx = ctx;
+ }
- /* XXX: DOB setting */
- gettimeofday (&graph->dob, NULL);
+ /* XXX: DOB setting */
+ gettimeofday(&graph->dob, NULL);
- fill_uuid (graph->graph_uuid, 128);
+ fill_uuid(graph->graph_uuid, sizeof(graph->graph_uuid), graph->dob);
- graph->id = ctx->graph_id++;
+ graph->id = ctx->graph_id++;
- /* XXX: --xlator-option additions */
- gf_add_cmdline_options (graph, &ctx->cmd_args);
+ /* XXX: --xlator-option additions */
+ gf_add_cmdline_options(graph, &ctx->cmd_args);
- return 0;
+ return 0;
}
-static
-xlator_t *glusterfs_root(glusterfs_graph_t *graph)
+static xlator_t *
+glusterfs_root(glusterfs_graph_t *graph)
{
- return graph->first;
+ return graph->first;
}
-static
-int glusterfs_is_leaf(xlator_t *xl)
+static int
+glusterfs_is_leaf(xlator_t *xl)
{
- int ret = 0;
+ int ret = 0;
- if (!xl->children)
- ret = 1;
+ if (!xl->children)
+ ret = 1;
- return ret;
+ return ret;
}
-static
-uint32_t glusterfs_count_leaves(xlator_t *xl)
+static uint32_t
+glusterfs_count_leaves(xlator_t *xl)
{
- int n = 0;
- xlator_list_t *list = NULL;
+ int n = 0;
+ xlator_list_t *list = NULL;
- if (glusterfs_is_leaf(xl))
- n = 1;
- else
- for (list = xl->children; list; list = list->next)
- n += glusterfs_count_leaves(list->xlator);
+ if (glusterfs_is_leaf(xl))
+ n = 1;
+ else
+ for (list = xl->children; list; list = list->next)
+ n += glusterfs_count_leaves(list->xlator);
- return n;
+ return n;
}
-int glusterfs_get_leaf_count(glusterfs_graph_t *graph)
+int
+glusterfs_get_leaf_count(glusterfs_graph_t *graph)
{
- return graph->leaf_count;
+ return graph->leaf_count;
}
-static
-int _glusterfs_leaf_position(xlator_t *tgt, int *id, xlator_t *xl)
+static int
+_glusterfs_leaf_position(xlator_t *tgt, int *id, xlator_t *xl)
{
- xlator_list_t *list = NULL;
- int found = 0;
-
- if (xl == tgt)
- found = 1;
- else if (glusterfs_is_leaf(xl))
- *id += 1;
- else
- for (list = xl->children; !found && list; list = list->next)
- found = _glusterfs_leaf_position(tgt, id, list->xlator);
-
- return found;
+ xlator_list_t *list = NULL;
+ int found = 0;
+
+ if (xl == tgt)
+ found = 1;
+ else if (glusterfs_is_leaf(xl))
+ *id += 1;
+ else
+ for (list = xl->children; !found && list; list = list->next)
+ found = _glusterfs_leaf_position(tgt, id, list->xlator);
+
+ return found;
}
-int glusterfs_leaf_position(xlator_t *tgt)
+int
+glusterfs_leaf_position(xlator_t *tgt)
{
- xlator_t *root = NULL;
- int pos = 0;
+ xlator_t *root = NULL;
+ int pos = 0;
- root = glusterfs_root(tgt->graph);
+ root = glusterfs_root(tgt->graph);
- if (!_glusterfs_leaf_position(tgt, &pos, root))
- pos = -1;
+ if (!_glusterfs_leaf_position(tgt, &pos, root))
+ pos = -1;
- return pos;
+ return pos;
}
static int
_glusterfs_reachable_leaves(xlator_t *base, xlator_t *xl, dict_t *leaves)
{
- xlator_list_t *list = NULL;
- int err = 1;
- int pos = 0;
- char strpos[6];
-
- if (glusterfs_is_leaf(xl)) {
- pos = glusterfs_leaf_position(xl);
- if (pos < 0)
- goto out;
- sprintf(strpos, "%d", pos);
-
- err = dict_set_static_ptr(leaves, strpos, base);
-
- } else {
- for (err = 0, list = xl->children;
- !err && list;
- list = list->next)
- err = _glusterfs_reachable_leaves(base, list->xlator,
- leaves);
+ xlator_list_t *list = NULL;
+ int err = 1;
+ int pos = 0;
+ char *strpos = NULL;
+
+ if (glusterfs_is_leaf(xl)) {
+ pos = glusterfs_leaf_position(xl);
+ if (pos < 0)
+ goto out;
+
+ err = gf_asprintf(&strpos, "%d", pos);
+
+ if (err >= 0) {
+ err = dict_set_static_ptr(leaves, strpos, base);
+ GF_FREE(strpos);
}
+ } else {
+ for (err = 0, list = xl->children; !err && list; list = list->next)
+ err = _glusterfs_reachable_leaves(base, list->xlator, leaves);
+ }
out:
- return err;
+ return err;
}
/*
@@ -634,318 +743,412 @@ out:
int
glusterfs_reachable_leaves(xlator_t *base, dict_t *leaves)
{
- xlator_list_t *list = NULL;
- int err = 0;
+ xlator_list_t *list = NULL;
+ int err = 0;
- for (list = base->children; !err && list; list = list->next)
- err = _glusterfs_reachable_leaves(list->xlator,
- list->xlator, leaves);
+ for (list = base->children; !err && list; list = list->next)
+ err = _glusterfs_reachable_leaves(list->xlator, list->xlator, leaves);
- return err;
+ return err;
}
int
-glusterfs_graph_activate (glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
+glusterfs_graph_activate(glusterfs_graph_t *graph, glusterfs_ctx_t *ctx)
{
- int ret = 0;
- xlator_t *root = NULL;
-
- root = glusterfs_root(graph);
+ int ret = 0;
+ xlator_t *root = NULL;
- graph->leaf_count = glusterfs_count_leaves(root);
+ root = glusterfs_root(graph);
- /* XXX: all xlator options validation */
- ret = glusterfs_graph_validate_options (graph);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_VALIDATION_FAILED,
- "validate options failed");
- return ret;
- }
+ graph->leaf_count = glusterfs_count_leaves(root);
- /* XXX: perform init () */
- ret = glusterfs_graph_init (graph);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_INIT_FAILED,
- "init failed");
- return ret;
- }
+ /* XXX: all xlator options validation */
+ ret = glusterfs_graph_validate_options(graph);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_VALIDATION_FAILED,
+ "validate options failed");
+ return ret;
+ }
- ret = glusterfs_graph_unknown_options (graph);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0,
- LG_MSG_UNKNOWN_OPTIONS_FAILED, "unknown options "
- "failed");
- return ret;
- }
+ /* XXX: perform init () */
+ ret = glusterfs_graph_init(graph);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_GRAPH_INIT_FAILED,
+ "init failed");
+ return ret;
+ }
- /* XXX: log full graph (_gf_dump_details) */
+ ret = glusterfs_graph_unknown_options(graph);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_UNKNOWN_OPTIONS_FAILED,
+ "unknown options "
+ "failed");
+ return ret;
+ }
- list_add (&graph->list, &ctx->graphs);
- ctx->active = graph;
+ /* XXX: log full graph (_gf_dump_details) */
- /* XXX: attach to master and set active pointer */
- if (ctx->master) {
- ret = xlator_notify (ctx->master, GF_EVENT_GRAPH_NEW, graph);
- if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0,
- LG_MSG_EVENT_NOTIFY_FAILED,
- "graph new notification failed");
- return ret;
- }
- ((xlator_t *)ctx->master)->next = graph->top;
- }
+ list_add(&graph->list, &ctx->graphs);
+ ctx->active = graph;
- /* XXX: perform parent up */
- ret = glusterfs_graph_parent_up (graph);
+ /* XXX: attach to master and set active pointer */
+ if (ctx->master) {
+ ret = xlator_notify(ctx->master, GF_EVENT_GRAPH_NEW, graph);
if (ret) {
- gf_msg ("graph", GF_LOG_ERROR, 0, LG_MSG_EVENT_NOTIFY_FAILED,
- "parent up notification failed");
- return ret;
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_EVENT_NOTIFY_FAILED,
+ "graph new notification failed");
+ return ret;
}
+ ((xlator_t *)ctx->master)->next = graph->top;
+ }
+
+ /* XXX: perform parent up */
+ ret = glusterfs_graph_parent_up(graph);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_EVENT_NOTIFY_FAILED,
+ "parent up notification failed");
+ return ret;
+ }
- return 0;
+ return 0;
}
-
int
-xlator_equal_rec (xlator_t *xl1, xlator_t *xl2)
+xlator_equal_rec(xlator_t *xl1, xlator_t *xl2)
{
- xlator_list_t *trav1 = NULL;
- xlator_list_t *trav2 = NULL;
- int ret = 0;
+ xlator_list_t *trav1 = NULL;
+ xlator_list_t *trav2 = NULL;
+ int ret = 0;
- if (xl1 == NULL || xl2 == NULL) {
- gf_msg_debug ("xlator", 0, "invalid argument");
- return -1;
- }
-
- trav1 = xl1->children;
- trav2 = xl2->children;
-
- while (trav1 && trav2) {
- ret = xlator_equal_rec (trav1->xlator, trav2->xlator);
- if (ret) {
- gf_msg_debug ("glusterfsd-mgmt", 0, "xlators children "
- "not equal");
- goto out;
- }
-
- trav1 = trav1->next;
- trav2 = trav2->next;
- }
+ if (xl1 == NULL || xl2 == NULL) {
+ gf_msg_debug("xlator", 0, "invalid argument");
+ return -1;
+ }
- if (trav1 || trav2) {
- ret = -1;
- goto out;
- }
+ trav1 = xl1->children;
+ trav2 = xl2->children;
- if (strcmp (xl1->name, xl2->name)) {
- ret = -1;
- goto out;
+ while (trav1 && trav2) {
+ ret = xlator_equal_rec(trav1->xlator, trav2->xlator);
+ if (ret) {
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "xlators children "
+ "not equal");
+ goto out;
}
- /* type could have changed even if xlator names match,
- e.g cluster/distrubte and cluster/nufa share the same
- xlator name
- */
- if (strcmp (xl1->type, xl2->type)) {
- ret = -1;
- goto out;
- }
-out :
- return ret;
+ trav1 = trav1->next;
+ trav2 = trav2->next;
+ }
+
+ if (trav1 || trav2) {
+ ret = -1;
+ goto out;
+ }
+
+ if (strcmp(xl1->name, xl2->name)) {
+ ret = -1;
+ goto out;
+ }
+
+ /* type could have changed even if xlator names match,
+ e.g cluster/distribute and cluster/nufa share the same
+ xlator name
+ */
+ if (strcmp(xl1->type, xl2->type)) {
+ ret = -1;
+ goto out;
+ }
+out:
+ return ret;
}
-
gf_boolean_t
-is_graph_topology_equal (glusterfs_graph_t *graph1, glusterfs_graph_t *graph2)
+is_graph_topology_equal(glusterfs_graph_t *graph1, glusterfs_graph_t *graph2)
{
- xlator_t *trav1 = NULL;
- xlator_t *trav2 = NULL;
- gf_boolean_t ret = _gf_true;
+ xlator_t *trav1 = NULL;
+ xlator_t *trav2 = NULL;
+ gf_boolean_t ret = _gf_true;
+ xlator_list_t *ltrav;
+
+ trav1 = graph1->first;
+ trav2 = graph2->first;
+
+ if (strcmp(trav2->type, "protocol/server") == 0) {
+ trav2 = trav2->children->xlator;
+ for (ltrav = trav1->children; ltrav; ltrav = ltrav->next) {
+ trav1 = ltrav->xlator;
+ if (!trav1->cleanup_starting && !strcmp(trav1->name, trav2->name)) {
+ break;
+ }
+ }
+ if (!ltrav) {
+ return _gf_false;
+ }
+ }
- trav1 = graph1->first;
- trav2 = graph2->first;
+ ret = xlator_equal_rec(trav1, trav2);
- ret = xlator_equal_rec (trav1, trav2);
+ if (ret) {
+ gf_msg_debug("glusterfsd-mgmt", 0, "graphs are not equal");
+ ret = _gf_false;
+ goto out;
+ }
- if (ret) {
- gf_msg_debug ("glusterfsd-mgmt", 0, "graphs are not equal");
- ret = _gf_false;
- goto out;
- }
-
- ret = _gf_true;
- gf_msg_debug ("glusterfsd-mgmt", 0, "graphs are equal");
+ ret = _gf_true;
+ gf_msg_debug("glusterfsd-mgmt", 0, "graphs are equal");
out:
- return ret;
+ return ret;
}
-
/* Function has 3types of return value 0, -ve , 1
* return 0 =======> reconfiguration of options has succeeded
- * return 1 =======> the graph has to be reconstructed and all the xlators should be inited
- * return -1(or -ve) =======> Some Internal Error occurred during the operation
+ * return 1 =======> the graph has to be reconstructed and all the
+ * xlators should be inited return -1(or -ve) =======> Some Internal Error
+ * occurred during the operation
*/
int
-glusterfs_volfile_reconfigure (int oldvollen, FILE *newvolfile_fp,
- glusterfs_ctx_t *ctx, const char *oldvolfile)
+glusterfs_volfile_reconfigure(FILE *newvolfile_fp, glusterfs_ctx_t *ctx)
{
- glusterfs_graph_t *oldvolfile_graph = NULL;
- glusterfs_graph_t *newvolfile_graph = NULL;
- FILE *oldvolfile_fp = NULL;
- /*Since the function mkstemp() replaces XXXXXX,
- * assigning it to a variable
- */
- char temp_file[] = "/tmp/temp_vol_file_XXXXXX";
- gf_boolean_t active_graph_found = _gf_true;
-
- int ret = -1;
- int u_ret = -1;
- int file_desc = -1;
-
- if (!oldvollen) {
- ret = 1; // Has to call INIT for the whole graph
- goto out;
- }
-
- if (!ctx) {
- gf_msg ("glusterfsd-mgmt", GF_LOG_ERROR, 0, LG_MSG_CTX_NULL,
- "ctx is NULL");
- goto out;
- }
-
- oldvolfile_graph = ctx->active;
- if (!oldvolfile_graph) {
- active_graph_found = _gf_false;
- gf_msg ("glusterfsd-mgmt", GF_LOG_ERROR, 0,
- LG_MSG_ACTIVE_GRAPH_NULL,
- "glusterfs_ctx->active is NULL");
-
- file_desc = mkstemp(temp_file);
- if (file_desc < 0) {
- gf_msg ("glusterfsd-mgmt", GF_LOG_ERROR, errno,
- LG_MSG_TMPFILE_CREATE_FAILED, "Unable to "
- "create temporary volfile");
- goto out;
- }
-
- /*Calling unlink so that when the file is closed or program
- *terminates the tempfile is deleted.
- */
- u_ret = unlink(temp_file);
-
- if (u_ret < 0) {
- gf_msg ("glusterfsd-mgmt", GF_LOG_ERROR, errno,
- LG_MSG_TMPFILE_DELETE_FAILED, "Temporary file"
- " delete failed.");
- close (file_desc);
- goto out;
- }
-
+ glusterfs_graph_t *oldvolfile_graph = NULL;
+ glusterfs_graph_t *newvolfile_graph = NULL;
+
+ int ret = -1;
+
+ if (!ctx) {
+ gf_msg("glusterfsd-mgmt", GF_LOG_ERROR, 0, LG_MSG_CTX_NULL,
+ "ctx is NULL");
+ goto out;
+ }
+
+ oldvolfile_graph = ctx->active;
+ if (!oldvolfile_graph) {
+ ret = 1;
+ goto out;
+ }
+
+ newvolfile_graph = glusterfs_graph_construct(newvolfile_fp);
+
+ if (!newvolfile_graph) {
+ goto out;
+ }
+
+ glusterfs_graph_prepare(newvolfile_graph, ctx, ctx->cmd_args.volume_name);
+
+ if (!is_graph_topology_equal(oldvolfile_graph, newvolfile_graph)) {
+ ret = 1;
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "Graph topology not "
+ "equal(should call INIT)");
+ goto out;
+ }
+
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "Only options have changed in the"
+ " new graph");
+
+ ret = glusterfs_graph_reconfigure(oldvolfile_graph, newvolfile_graph);
+ if (ret) {
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "Could not reconfigure "
+ "new options in old graph");
+ goto out;
+ }
+
+ ret = 0;
+out:
- oldvolfile_fp = fdopen (file_desc, "w+b");
- if (!oldvolfile_fp)
- goto out;
+ if (newvolfile_graph)
+ glusterfs_graph_destroy(newvolfile_graph);
- fwrite (oldvolfile, oldvollen, 1, oldvolfile_fp);
- fflush (oldvolfile_fp);
- if (ferror (oldvolfile_fp)) {
- goto out;
- }
+ return ret;
+}
- oldvolfile_graph = glusterfs_graph_construct (oldvolfile_fp);
- if (!oldvolfile_graph)
- goto out;
- }
+/* This function need to remove. This added to support gfapi volfile
+ * reconfigure.
+ */
- newvolfile_graph = glusterfs_graph_construct (newvolfile_fp);
- if (!newvolfile_graph) {
- goto out;
+int
+gf_volfile_reconfigure(int oldvollen, FILE *newvolfile_fp, glusterfs_ctx_t *ctx,
+ const char *oldvolfile)
+{
+ glusterfs_graph_t *oldvolfile_graph = NULL;
+ glusterfs_graph_t *newvolfile_graph = NULL;
+ FILE *oldvolfile_fp = NULL;
+ /*Since the function mkstemp() replaces XXXXXX,
+ * assigning it to a variable
+ */
+ char temp_file[] = "/tmp/temp_vol_file_XXXXXX";
+ gf_boolean_t active_graph_found = _gf_true;
+
+ int ret = -1;
+ int u_ret = -1;
+ int file_desc = -1;
+
+ if (!oldvollen) {
+ ret = 1; // Has to call INIT for the whole graph
+ goto out;
+ }
+
+ if (!ctx) {
+ gf_msg("glusterfsd-mgmt", GF_LOG_ERROR, 0, LG_MSG_CTX_NULL,
+ "ctx is NULL");
+ goto out;
+ }
+
+ oldvolfile_graph = ctx->active;
+ if (!oldvolfile_graph) {
+ active_graph_found = _gf_false;
+ gf_msg("glusterfsd-mgmt", GF_LOG_ERROR, 0, LG_MSG_ACTIVE_GRAPH_NULL,
+ "glusterfs_ctx->active is NULL");
+
+ /* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
+ file_desc = mkstemp(temp_file);
+ if (file_desc < 0) {
+ gf_msg("glusterfsd-mgmt", GF_LOG_ERROR, errno,
+ LG_MSG_TMPFILE_CREATE_FAILED,
+ "Unable to "
+ "create temporary volfile");
+ goto out;
}
- glusterfs_graph_prepare (newvolfile_graph, ctx);
-
- if (!is_graph_topology_equal (oldvolfile_graph,
- newvolfile_graph)) {
-
- ret = 1;
- gf_msg_debug ("glusterfsd-mgmt", 0, "Graph topology not "
- "equal(should call INIT)");
- goto out;
+ /*Calling unlink so that when the file is closed or program
+ *terminates the tempfile is deleted.
+ */
+ u_ret = sys_unlink(temp_file);
+
+ if (u_ret < 0) {
+ gf_msg("glusterfsd-mgmt", GF_LOG_ERROR, errno,
+ LG_MSG_TMPFILE_DELETE_FAILED,
+ "Temporary file"
+ " delete failed.");
+ sys_close(file_desc);
+ goto out;
}
- gf_msg_debug ("glusterfsd-mgmt", 0, "Only options have changed in the"
- " new graph");
+ oldvolfile_fp = fdopen(file_desc, "w+b");
+ if (!oldvolfile_fp)
+ goto out;
- /* */
- ret = glusterfs_graph_reconfigure (oldvolfile_graph,
- newvolfile_graph);
- if (ret) {
- gf_msg_debug ("glusterfsd-mgmt", 0, "Could not reconfigure "
- "new options in old graph");
- goto out;
+ fwrite(oldvolfile, oldvollen, 1, oldvolfile_fp);
+ fflush(oldvolfile_fp);
+ if (ferror(oldvolfile_fp)) {
+ goto out;
}
- ret = 0;
+ oldvolfile_graph = glusterfs_graph_construct(oldvolfile_fp);
+ if (!oldvolfile_graph)
+ goto out;
+ }
+
+ newvolfile_graph = glusterfs_graph_construct(newvolfile_fp);
+ if (!newvolfile_graph) {
+ goto out;
+ }
+
+ glusterfs_graph_prepare(newvolfile_graph, ctx, ctx->cmd_args.volume_name);
+
+ if (!is_graph_topology_equal(oldvolfile_graph, newvolfile_graph)) {
+ ret = 1;
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "Graph topology not "
+ "equal(should call INIT)");
+ goto out;
+ }
+
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "Only options have changed in the"
+ " new graph");
+
+ /* */
+ ret = glusterfs_graph_reconfigure(oldvolfile_graph, newvolfile_graph);
+ if (ret) {
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "Could not reconfigure "
+ "new options in old graph");
+ goto out;
+ }
+
+ ret = 0;
out:
- if (oldvolfile_fp)
- fclose (oldvolfile_fp);
-
- /* Do not simply destroy the old graph here. If the oldgraph
- is constructed here in this function itself instead of getting
- it from ctx->active (which happens only of ctx->active is NULL),
- then destroy the old graph. If some i/o is still happening in
- the old graph and the old graph is obtained from ctx->active,
- then destroying the graph will cause problems.
- */
- if (!active_graph_found && oldvolfile_graph)
- glusterfs_graph_destroy (oldvolfile_graph);
- if (newvolfile_graph)
- glusterfs_graph_destroy (newvolfile_graph);
-
- return ret;
+ if (oldvolfile_fp)
+ fclose(oldvolfile_fp);
+
+ /* Do not simply destroy the old graph here. If the oldgraph
+ is constructed here in this function itself instead of getting
+ it from ctx->active (which happens only of ctx->active is NULL),
+ then destroy the old graph. If some i/o is still happening in
+ the old graph and the old graph is obtained from ctx->active,
+ then destroying the graph will cause problems.
+ */
+ if (!active_graph_found && oldvolfile_graph)
+ glusterfs_graph_destroy(oldvolfile_graph);
+ if (newvolfile_graph)
+ glusterfs_graph_destroy(newvolfile_graph);
+
+ return ret;
}
-
int
-glusterfs_graph_reconfigure (glusterfs_graph_t *oldgraph,
- glusterfs_graph_t *newgraph)
+glusterfs_graph_reconfigure(glusterfs_graph_t *oldgraph,
+ glusterfs_graph_t *newgraph)
{
- xlator_t *old_xl = NULL;
- xlator_t *new_xl = NULL;
-
- GF_ASSERT (oldgraph);
- GF_ASSERT (newgraph);
-
- old_xl = oldgraph->first;
- while (old_xl->is_autoloaded) {
- old_xl = old_xl->children->xlator;
- }
-
- new_xl = newgraph->first;
- while (new_xl->is_autoloaded) {
- new_xl = new_xl->children->xlator;
+ xlator_t *old_xl = NULL;
+ xlator_t *new_xl = NULL;
+ xlator_list_t *trav;
+
+ GF_ASSERT(oldgraph);
+ GF_ASSERT(newgraph);
+
+ old_xl = oldgraph->first;
+ while (old_xl->is_autoloaded) {
+ old_xl = old_xl->children->xlator;
+ }
+
+ new_xl = newgraph->first;
+ while (new_xl->is_autoloaded) {
+ new_xl = new_xl->children->xlator;
+ }
+
+ if (strcmp(old_xl->type, "protocol/server") != 0) {
+ return xlator_tree_reconfigure(old_xl, new_xl);
+ }
+
+ /* Some options still need to be handled by the server translator. */
+ if (old_xl->reconfigure) {
+ old_xl->reconfigure(old_xl, new_xl->options);
+ }
+
+ (void)copy_opts_to_child(new_xl, FIRST_CHILD(new_xl), "*auth*");
+ new_xl = FIRST_CHILD(new_xl);
+
+ for (trav = old_xl->children; trav; trav = trav->next) {
+ if (!trav->xlator->cleanup_starting &&
+ !strcmp(trav->xlator->name, new_xl->name)) {
+ return xlator_tree_reconfigure(trav->xlator, new_xl);
}
+ }
- return xlator_tree_reconfigure (old_xl, new_xl);
+ return -1;
}
int
-glusterfs_graph_destroy_residual (glusterfs_graph_t *graph)
+glusterfs_graph_destroy_residual(glusterfs_graph_t *graph)
{
- int ret = -1;
+ int ret = -1;
- if (graph == NULL)
- return ret;
+ if (graph == NULL)
+ return ret;
- ret = xlator_tree_free_memacct (graph->first);
+ ret = xlator_tree_free_memacct(graph->first);
- list_del_init (&graph->list);
- GF_FREE (graph);
+ list_del_init(&graph->list);
+ pthread_mutex_destroy(&graph->mutex);
+ pthread_cond_destroy(&graph->child_down_cond);
+ GF_FREE(graph);
- return ret;
+ return ret;
}
/* This function destroys all the xlator members except for the
@@ -971,15 +1174,707 @@ glusterfs_graph_destroy_residual (glusterfs_graph_t *graph)
* object itself.
*/
int
-glusterfs_graph_destroy (glusterfs_graph_t *graph)
+glusterfs_graph_destroy(glusterfs_graph_t *graph)
{
- int ret = 0;
+ int ret = 0;
- GF_VALIDATE_OR_GOTO ("graph", graph, out);
+ GF_VALIDATE_OR_GOTO("graph", graph, out);
- ret = xlator_tree_free_members (graph->first);
+ ret = xlator_tree_free_members(graph->first);
- ret = glusterfs_graph_destroy_residual (graph);
+ ret = glusterfs_graph_destroy_residual(graph);
out:
- return ret;
+ return ret;
+}
+
+int
+glusterfs_graph_fini(glusterfs_graph_t *graph)
+{
+ xlator_t *trav = NULL;
+
+ trav = graph->first;
+
+ while (trav) {
+ if (trav->init_succeeded) {
+ trav->cleanup_starting = 1;
+ trav->fini(trav);
+ if (trav->local_pool) {
+ mem_pool_destroy(trav->local_pool);
+ trav->local_pool = NULL;
+ }
+ if (trav->itable) {
+ inode_table_destroy(trav->itable);
+ trav->itable = NULL;
+ }
+ trav->init_succeeded = 0;
+ }
+ trav = trav->next;
+ }
+
+ return 0;
+}
+
+int
+glusterfs_graph_attach(glusterfs_graph_t *orig_graph, char *path,
+ glusterfs_graph_t **newgraph)
+{
+ xlator_t *this = THIS;
+ FILE *fp;
+ glusterfs_graph_t *graph;
+ xlator_t *xl;
+ char *volfile_id = NULL;
+ char *volfile_content = NULL;
+ struct stat stbuf = {
+ 0,
+ };
+ size_t file_len = -1;
+ gf_volfile_t *volfile_obj = NULL;
+ int ret = -1;
+ char sha256_hash[SHA256_DIGEST_LENGTH] = {
+ 0,
+ };
+
+ if (!orig_graph) {
+ return -EINVAL;
+ }
+
+ ret = sys_stat(path, &stbuf);
+ if (ret < 0) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Unable to stat %s (%s)", path,
+ strerror(errno));
+ return -EINVAL;
+ }
+
+ file_len = stbuf.st_size;
+ volfile_content = GF_MALLOC(file_len + 1, gf_common_mt_char);
+ if (!volfile_content)
+ return -ENOMEM;
+
+ fp = fopen(path, "r");
+ if (!fp) {
+ gf_log(THIS->name, GF_LOG_WARNING, "oops, %s disappeared on us", path);
+ GF_FREE(volfile_content);
+ return -EIO;
+ }
+
+ ret = fread(volfile_content, sizeof(char), file_len, fp);
+ if (ret == file_len) {
+ glusterfs_compute_sha256((const unsigned char *)volfile_content,
+ file_len, sha256_hash);
+ } else {
+ gf_log(THIS->name, GF_LOG_ERROR,
+ "read failed on path %s. File size=%" GF_PRI_SIZET
+ "read size=%d",
+ path, file_len, ret);
+ GF_FREE(volfile_content);
+ fclose(fp);
+ return -EIO;
+ }
+
+ GF_FREE(volfile_content);
+
+ graph = glusterfs_graph_construct(fp);
+ fclose(fp);
+ if (!graph) {
+ gf_log(this->name, GF_LOG_WARNING, "could not create graph from %s",
+ path);
+ return -EIO;
+ }
+
+ /*
+ * If there's a server translator on top, we want whatever's below
+ * that.
+ */
+ xl = graph->first;
+ if (strcmp(xl->type, "protocol/server") == 0) {
+ (void)copy_opts_to_child(xl, FIRST_CHILD(xl), "*auth*");
+ xl = FIRST_CHILD(xl);
+ }
+ graph->first = xl;
+ *newgraph = graph;
+
+ volfile_id = strstr(path, "/snaps/");
+ if (!volfile_id) {
+ volfile_id = rindex(path, '/');
+ if (volfile_id) {
+ ++volfile_id;
+ }
+ }
+ if (volfile_id) {
+ xl->volfile_id = gf_strdup(volfile_id);
+ /* There's a stray ".vol" at the end. */
+ xl->volfile_id[strlen(xl->volfile_id) - 4] = '\0';
+ }
+
+ /* TODO memory leaks everywhere need to free graph in case of error */
+ if (glusterfs_graph_prepare(graph, this->ctx, xl->name)) {
+ gf_log(this->name, GF_LOG_WARNING,
+ "failed to prepare graph for xlator %s", xl->name);
+ return -EIO;
+ } else if (glusterfs_graph_init(graph)) {
+ gf_log(this->name, GF_LOG_WARNING,
+ "failed to initialize graph for xlator %s", xl->name);
+ return -EIO;
+ } else if (glusterfs_xlator_link(orig_graph->top, graph->top)) {
+ gf_log(this->name, GF_LOG_WARNING,
+ "failed to link the graphs for xlator %s ", xl->name);
+ return -EIO;
+ }
+
+ if (!volfile_obj) {
+ volfile_obj = GF_CALLOC(1, sizeof(gf_volfile_t), gf_common_volfile_t);
+ if (!volfile_obj) {
+ return -EIO;
+ }
+ }
+
+ INIT_LIST_HEAD(&volfile_obj->volfile_list);
+ snprintf(volfile_obj->vol_id, sizeof(volfile_obj->vol_id), "%s",
+ xl->volfile_id);
+ memcpy(volfile_obj->volfile_checksum, sha256_hash,
+ sizeof(volfile_obj->volfile_checksum));
+ list_add(&volfile_obj->volfile_list, &this->ctx->volfile_list);
+
+ return 0;
+}
+int
+glusterfs_muxsvc_cleanup_parent(glusterfs_ctx_t *ctx,
+ glusterfs_graph_t *parent_graph)
+{
+ if (parent_graph) {
+ if (parent_graph->first) {
+ xlator_destroy(parent_graph->first);
+ }
+ ctx->active = NULL;
+ GF_FREE(parent_graph);
+ parent_graph = NULL;
+ }
+ return 0;
+}
+
+void *
+glusterfs_graph_cleanup(void *arg)
+{
+ glusterfs_graph_t *graph = NULL;
+ glusterfs_ctx_t *ctx = THIS->ctx;
+ int ret = -1;
+ graph = arg;
+
+ if (!graph)
+ return NULL;
+
+ /* To destroy the graph, fitst sent a GF_EVENT_PARENT_DOWN
+ * Then wait for GF_EVENT_CHILD_DOWN to get on the top
+ * xl. Once we have GF_EVENT_CHILD_DOWN event, then proceed
+ * to fini.
+ *
+ * During fini call, this will take a last unref on rpc and
+ * rpc_transport_object.
+ */
+ if (graph->first)
+ default_notify(graph->first, GF_EVENT_PARENT_DOWN, graph->first);
+
+ ret = pthread_mutex_lock(&graph->mutex);
+ if (ret != 0) {
+ gf_msg("glusterfs", GF_LOG_ERROR, EAGAIN, LG_MSG_GRAPH_CLEANUP_FAILED,
+ "Failed to acquire a lock");
+ goto out;
+ }
+ /* check and wait for CHILD_DOWN for top xlator*/
+ while (graph->used) {
+ ret = pthread_cond_wait(&graph->child_down_cond, &graph->mutex);
+ if (ret != 0)
+ gf_msg("glusterfs", GF_LOG_INFO, 0, LG_MSG_GRAPH_CLEANUP_FAILED,
+ "cond wait failed ");
+ }
+
+ ret = pthread_mutex_unlock(&graph->mutex);
+ if (ret != 0) {
+ gf_msg("glusterfs", GF_LOG_ERROR, EAGAIN, LG_MSG_GRAPH_CLEANUP_FAILED,
+ "Failed to release a lock");
+ }
+
+ /* Though we got a child down on top xlator, we have to wait until
+ * all the notifier to exit. Because there should not be any threads
+ * that access xl variables.
+ */
+ pthread_mutex_lock(&ctx->notify_lock);
+ {
+ while (ctx->notifying)
+ pthread_cond_wait(&ctx->notify_cond, &ctx->notify_lock);
+ }
+ pthread_mutex_unlock(&ctx->notify_lock);
+
+ pthread_mutex_lock(&ctx->cleanup_lock);
+ {
+ glusterfs_graph_fini(graph);
+ glusterfs_graph_destroy(graph);
+ }
+ pthread_mutex_unlock(&ctx->cleanup_lock);
+out:
+ return NULL;
+}
+
+glusterfs_graph_t *
+glusterfs_muxsvc_setup_parent_graph(glusterfs_ctx_t *ctx, char *name,
+ char *type)
+{
+ glusterfs_graph_t *parent_graph = NULL;
+ xlator_t *ixl = NULL;
+ int ret = -1;
+ parent_graph = GF_CALLOC(1, sizeof(*parent_graph),
+ gf_common_mt_glusterfs_graph_t);
+ if (!parent_graph)
+ goto out;
+
+ INIT_LIST_HEAD(&parent_graph->list);
+
+ ctx->active = parent_graph;
+ ixl = GF_CALLOC(1, sizeof(*ixl), gf_common_mt_xlator_t);
+ if (!ixl)
+ goto out;
+
+ ixl->ctx = ctx;
+ ixl->graph = parent_graph;
+ ixl->options = dict_new();
+ if (!ixl->options)
+ goto out;
+
+ ixl->name = gf_strdup(name);
+ if (!ixl->name)
+ goto out;
+
+ ixl->is_autoloaded = 1;
+
+ if (xlator_set_type(ixl, type) == -1) {
+ gf_msg("glusterfs", GF_LOG_ERROR, EINVAL, LG_MSG_GRAPH_SETUP_FAILED,
+ "%s (%s) set type failed", name, type);
+ goto out;
+ }
+
+ glusterfs_graph_set_first(parent_graph, ixl);
+ parent_graph->top = ixl;
+ ixl = NULL;
+
+ gettimeofday(&parent_graph->dob, NULL);
+ fill_uuid(parent_graph->graph_uuid, 128, parent_graph->dob);
+ parent_graph->id = ctx->graph_id++;
+ ret = 0;
+out:
+ if (ixl)
+ xlator_destroy(ixl);
+
+ if (ret) {
+ glusterfs_muxsvc_cleanup_parent(ctx, parent_graph);
+ parent_graph = NULL;
+ }
+ return parent_graph;
+}
+
+int
+glusterfs_svc_mux_pidfile_cleanup(gf_volfile_t *volfile_obj)
+{
+ if (!volfile_obj || !volfile_obj->pidfp)
+ return 0;
+
+ gf_msg_trace("glusterfsd", 0, "pidfile %s cleanup", volfile_obj->vol_id);
+
+ lockf(fileno(volfile_obj->pidfp), F_ULOCK, 0);
+ fclose(volfile_obj->pidfp);
+ volfile_obj->pidfp = NULL;
+
+ return 0;
+}
+
+int
+glusterfs_process_svc_detach(glusterfs_ctx_t *ctx, gf_volfile_t *volfile_obj)
+{
+ xlator_t *last_xl = NULL;
+ glusterfs_graph_t *graph = NULL;
+ glusterfs_graph_t *parent_graph = NULL;
+ pthread_t clean_graph = {
+ 0,
+ };
+ int ret = -1;
+ xlator_t *xl = NULL;
+
+ if (!ctx || !ctx->active || !volfile_obj)
+ goto out;
+
+ pthread_mutex_lock(&ctx->cleanup_lock);
+ {
+ parent_graph = ctx->active;
+ graph = volfile_obj->graph;
+ if (!graph)
+ goto unlock;
+ if (graph->first)
+ xl = graph->first;
+
+ last_xl = graph->last_xl;
+ if (last_xl)
+ last_xl->next = NULL;
+ if (!xl || xl->cleanup_starting)
+ goto unlock;
+
+ xl->cleanup_starting = 1;
+ gf_msg("mgmt", GF_LOG_INFO, 0, LG_MSG_GRAPH_DETACH_STARTED,
+ "detaching child %s", volfile_obj->vol_id);
+
+ list_del_init(&volfile_obj->volfile_list);
+ glusterfs_mux_xlator_unlink(parent_graph->top, xl);
+ glusterfs_svc_mux_pidfile_cleanup(volfile_obj);
+ parent_graph->last_xl = glusterfs_get_last_xlator(parent_graph);
+ parent_graph->xl_count -= graph->xl_count;
+ parent_graph->leaf_count -= graph->leaf_count;
+ parent_graph->id++;
+ ret = 0;
+ }
+unlock:
+ pthread_mutex_unlock(&ctx->cleanup_lock);
+out:
+ if (!ret) {
+ list_del_init(&volfile_obj->volfile_list);
+ if (graph) {
+ ret = gf_thread_create_detached(
+ &clean_graph, glusterfs_graph_cleanup, graph, "graph_clean");
+ if (ret) {
+ gf_msg("glusterfs", GF_LOG_ERROR, EINVAL,
+ LG_MSG_GRAPH_CLEANUP_FAILED,
+ "%s failed to create clean "
+ "up thread",
+ volfile_obj->vol_id);
+ ret = 0;
+ }
+ }
+ GF_FREE(volfile_obj);
+ }
+ return ret;
+}
+
+int
+glusterfs_svc_mux_pidfile_setup(gf_volfile_t *volfile_obj, const char *pid_file)
+{
+ int ret = -1;
+ FILE *pidfp = NULL;
+
+ if (!pid_file || !volfile_obj)
+ goto out;
+
+ if (volfile_obj->pidfp) {
+ ret = 0;
+ goto out;
+ }
+ pidfp = fopen(pid_file, "a+");
+ if (!pidfp) {
+ goto out;
+ }
+ volfile_obj->pidfp = pidfp;
+
+ ret = lockf(fileno(pidfp), F_TLOCK, 0);
+ if (ret) {
+ ret = 0;
+ goto out;
+ }
+out:
+ return ret;
+}
+
+int
+glusterfs_svc_mux_pidfile_update(gf_volfile_t *volfile_obj,
+ const char *pid_file, pid_t pid)
+{
+ int ret = 0;
+ FILE *pidfp = NULL;
+ int old_pid;
+
+ if (!volfile_obj->pidfp) {
+ ret = glusterfs_svc_mux_pidfile_setup(volfile_obj, pid_file);
+ if (ret == -1)
+ goto out;
+ }
+ pidfp = volfile_obj->pidfp;
+ ret = fscanf(pidfp, "%d", &old_pid);
+ if (ret <= 0) {
+ goto update;
+ }
+ if (old_pid == pid) {
+ ret = 0;
+ goto out;
+ } else {
+ gf_msg("mgmt", GF_LOG_INFO, 0, LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED,
+ "Old pid=%d found in pidfile %s. Cleaning the old pid and "
+ "Updating new pid=%d",
+ old_pid, pid_file, pid);
+ }
+update:
+ ret = sys_ftruncate(fileno(pidfp), 0);
+ if (ret) {
+ gf_msg("glusterfsd", GF_LOG_ERROR, errno,
+ LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED,
+ "pidfile %s truncation failed", pid_file);
+ goto out;
+ }
+
+ ret = fprintf(pidfp, "%d\n", pid);
+ if (ret <= 0) {
+ gf_msg("glusterfsd", GF_LOG_ERROR, errno,
+ LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED, "pidfile %s write failed",
+ pid_file);
+ goto out;
+ }
+
+ ret = fflush(pidfp);
+ if (ret) {
+ gf_msg("glusterfsd", GF_LOG_ERROR, errno,
+ LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED, "pidfile %s write failed",
+ pid_file);
+ goto out;
+ }
+out:
+ return ret;
+}
+
+int
+glusterfs_update_mux_pid(dict_t *dict, gf_volfile_t *volfile_obj)
+{
+ char *file = NULL;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO("graph", dict, out);
+ GF_VALIDATE_OR_GOTO("graph", volfile_obj, out);
+
+ ret = dict_get_str(dict, "pidfile", &file);
+ if (ret < 0) {
+ gf_msg("mgmt", GF_LOG_ERROR, EINVAL, LG_MSG_GRAPH_SETUP_FAILED,
+ "Failed to get pidfile from dict for volfile_id=%s",
+ volfile_obj->vol_id);
+ }
+
+ ret = glusterfs_svc_mux_pidfile_update(volfile_obj, file, getpid());
+ if (ret < 0) {
+ ret = -1;
+ gf_msg("mgmt", GF_LOG_ERROR, EINVAL, LG_MSG_GRAPH_SETUP_FAILED,
+ "Failed to update "
+ "the pidfile for volfile_id=%s",
+ volfile_obj->vol_id);
+
+ goto out;
+ }
+
+ if (ret == 1)
+ gf_msg("mgmt", GF_LOG_INFO, 0, LG_MSG_GRAPH_ATTACH_PID_FILE_UPDATED,
+ "PID %d updated in pidfile=%s", getpid(), file);
+ ret = 0;
+out:
+ return ret;
+}
+int
+glusterfs_process_svc_attach_volfp(glusterfs_ctx_t *ctx, FILE *fp,
+ char *volfile_id, char *checksum,
+ dict_t *dict)
+{
+ glusterfs_graph_t *graph = NULL;
+ glusterfs_graph_t *parent_graph = NULL;
+ glusterfs_graph_t *clean_graph = NULL;
+ int ret = -1;
+ xlator_t *xl = NULL;
+ xlator_t *last_xl = NULL;
+ gf_volfile_t *volfile_obj = NULL;
+ pthread_t thread_id = {
+ 0,
+ };
+
+ if (!ctx)
+ goto out;
+ parent_graph = ctx->active;
+ graph = glusterfs_graph_construct(fp);
+ if (!graph) {
+ gf_msg("glusterfsd", GF_LOG_ERROR, EINVAL, LG_MSG_GRAPH_ATTACH_FAILED,
+ "failed to construct the graph");
+ goto out;
+ }
+ graph->parent_down = 0;
+ graph->last_xl = glusterfs_get_last_xlator(graph);
+
+ for (xl = graph->first; xl; xl = xl->next) {
+ if (strcmp(xl->type, "mount/fuse") == 0) {
+ gf_msg("glusterfsd", GF_LOG_ERROR, EINVAL,
+ LG_MSG_GRAPH_ATTACH_FAILED,
+ "fuse xlator cannot be specified in volume file");
+ goto out;
+ }
+ }
+
+ graph->leaf_count = glusterfs_count_leaves(glusterfs_root(graph));
+ xl = graph->first;
+ /* TODO memory leaks everywhere need to free graph in case of error */
+ if (glusterfs_graph_prepare(graph, ctx, xl->name)) {
+ gf_msg("glusterfsd", GF_LOG_WARNING, EINVAL, LG_MSG_GRAPH_ATTACH_FAILED,
+ "failed to prepare graph for xlator %s", xl->name);
+ ret = -1;
+ goto out;
+ } else if (glusterfs_graph_init(graph)) {
+ gf_msg("glusterfsd", GF_LOG_WARNING, EINVAL, LG_MSG_GRAPH_ATTACH_FAILED,
+ "failed to initialize graph for xlator %s", xl->name);
+ ret = -1;
+ goto out;
+ } else if (glusterfs_graph_parent_up(graph)) {
+ gf_msg("glusterfsd", GF_LOG_WARNING, EINVAL, LG_MSG_GRAPH_ATTACH_FAILED,
+ "failed to link the graphs for xlator %s ", xl->name);
+ ret = -1;
+ goto out;
+ }
+
+ if (!parent_graph) {
+ parent_graph = glusterfs_muxsvc_setup_parent_graph(ctx, "glustershd",
+ "debug/io-stats");
+ if (!parent_graph)
+ goto out;
+ ((xlator_t *)parent_graph->top)->next = xl;
+ clean_graph = parent_graph;
+ } else {
+ last_xl = parent_graph->last_xl;
+ if (last_xl)
+ last_xl->next = xl;
+ xl->prev = last_xl;
+ }
+ parent_graph->last_xl = graph->last_xl;
+
+ ret = glusterfs_xlator_link(parent_graph->top, xl);
+ if (ret) {
+ gf_msg("graph", GF_LOG_ERROR, 0, LG_MSG_EVENT_NOTIFY_FAILED,
+ "parent up notification failed");
+ goto out;
+ }
+ parent_graph->xl_count += graph->xl_count;
+ parent_graph->leaf_count += graph->leaf_count;
+ parent_graph->id++;
+
+ volfile_obj = GF_CALLOC(1, sizeof(gf_volfile_t), gf_common_volfile_t);
+ if (!volfile_obj) {
+ ret = -1;
+ goto out;
+ }
+ volfile_obj->pidfp = NULL;
+ snprintf(volfile_obj->vol_id, sizeof(volfile_obj->vol_id), "%s",
+ volfile_id);
+
+ if (strcmp(ctx->cmd_args.process_name, "glustershd") == 0) {
+ ret = glusterfs_update_mux_pid(dict, volfile_obj);
+ if (ret == -1) {
+ GF_FREE(volfile_obj);
+ goto out;
+ }
+ }
+
+ graph->used = 1;
+ parent_graph->id++;
+ list_add(&graph->list, &ctx->graphs);
+ INIT_LIST_HEAD(&volfile_obj->volfile_list);
+ volfile_obj->graph = graph;
+ memcpy(volfile_obj->volfile_checksum, checksum,
+ sizeof(volfile_obj->volfile_checksum));
+ list_add_tail(&volfile_obj->volfile_list, &ctx->volfile_list);
+ gf_log_dump_graph(fp, graph);
+ graph = NULL;
+
+ ret = 0;
+out:
+ if (ret) {
+ if (graph) {
+ gluster_graph_take_reference(graph->first);
+ ret = gf_thread_create_detached(&thread_id, glusterfs_graph_cleanup,
+ graph, "graph_clean");
+ if (ret) {
+ gf_msg("glusterfs", GF_LOG_ERROR, EINVAL,
+ LG_MSG_GRAPH_CLEANUP_FAILED,
+ "%s failed to create clean "
+ "up thread",
+ volfile_id);
+ ret = 0;
+ }
+ }
+ if (clean_graph)
+ glusterfs_muxsvc_cleanup_parent(ctx, clean_graph);
+ }
+ return ret;
+}
+
+int
+glusterfs_mux_volfile_reconfigure(FILE *newvolfile_fp, glusterfs_ctx_t *ctx,
+ gf_volfile_t *volfile_obj, char *checksum,
+ dict_t *dict)
+{
+ glusterfs_graph_t *oldvolfile_graph = NULL;
+ glusterfs_graph_t *newvolfile_graph = NULL;
+ char vol_id[NAME_MAX + 1];
+
+ int ret = -1;
+
+ if (!ctx) {
+ gf_msg("glusterfsd-mgmt", GF_LOG_ERROR, 0, LG_MSG_CTX_NULL,
+ "ctx is NULL");
+ goto out;
+ }
+
+ /* Change the message id */
+ if (!volfile_obj) {
+ gf_msg("glusterfsd-mgmt", GF_LOG_ERROR, 0, LG_MSG_CTX_NULL,
+ "failed to get volfile object");
+ goto out;
+ }
+
+ oldvolfile_graph = volfile_obj->graph;
+ if (!oldvolfile_graph) {
+ goto out;
+ }
+
+ newvolfile_graph = glusterfs_graph_construct(newvolfile_fp);
+
+ if (!newvolfile_graph) {
+ goto out;
+ }
+ newvolfile_graph->last_xl = glusterfs_get_last_xlator(newvolfile_graph);
+
+ glusterfs_graph_prepare(newvolfile_graph, ctx, newvolfile_graph->first);
+
+ if (!is_graph_topology_equal(oldvolfile_graph, newvolfile_graph)) {
+ ret = snprintf(vol_id, sizeof(vol_id), "%s", volfile_obj->vol_id);
+ if (ret < 0)
+ goto out;
+ ret = glusterfs_process_svc_detach(ctx, volfile_obj);
+ if (ret) {
+ gf_msg("glusterfsd-mgmt", GF_LOG_ERROR, EINVAL,
+ LG_MSG_GRAPH_CLEANUP_FAILED,
+ "Could not detach "
+ "old graph. Aborting the reconfiguration operation");
+ goto out;
+ }
+ volfile_obj = NULL;
+ ret = glusterfs_process_svc_attach_volfp(ctx, newvolfile_fp, vol_id,
+ checksum, dict);
+ goto out;
+ }
+
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "Only options have changed in the"
+ " new graph");
+
+ ret = glusterfs_graph_reconfigure(oldvolfile_graph, newvolfile_graph);
+ if (ret) {
+ gf_msg_debug("glusterfsd-mgmt", 0,
+ "Could not reconfigure "
+ "new options in old graph");
+ goto out;
+ }
+ memcpy(volfile_obj->volfile_checksum, checksum,
+ sizeof(volfile_obj->volfile_checksum));
+
+ ret = 0;
+out:
+
+ if (newvolfile_graph)
+ glusterfs_graph_destroy(newvolfile_graph);
+
+ return ret;
}
diff --git a/libglusterfs/src/graph.l b/libglusterfs/src/graph.l
index 8af28a43539..b9d4b2b6828 100644
--- a/libglusterfs/src/graph.l
+++ b/libglusterfs/src/graph.l
@@ -14,35 +14,27 @@
%{
#define YYSTYPE char *
-#include "xlator.h"
+#include "glusterfs/xlator.h"
#include "y.tab.h"
#include <string.h>
-#define START_STRSIZE 32
static char *text;
-static int text_asize;
static int text_size;
void append_string(const char *str, int size)
{
- int new_size = text_size + size + 1;
- if (new_size > text_asize) {
- new_size += START_STRSIZE - 1;
- new_size &= -START_STRSIZE;
- if (!text) {
- text = GF_CALLOC (1, new_size,
- gf_common_mt_char);
- } else {
- text = GF_REALLOC (text, new_size);
- }
- if (!text) {
- return;
- }
- text_asize = new_size;
- }
- memcpy(text + text_size, str, size);
- text_size += size;
- text[text_size] = 0;
+ int new_size = text_size + size + 1;
+ if (!text) {
+ text = GF_CALLOC (1, new_size, gf_common_mt_char);
+ } else {
+ text = GF_REALLOC (text, new_size);
+ }
+ if (!text) {
+ return;
+ }
+ memcpy(text + text_size, str, size);
+ text_size += size;
+ text[text_size] = 0;
}
%}
@@ -65,12 +57,14 @@ TYPE [t][y][p][e]
\\. { append_string (yytext + 1, yyleng - 1); }
\" {
if (0) {
- yyunput (0, NULL);
+ yyunput (0, NULL);
}
BEGIN (INITIAL);
graphyylval = text;
+ text = NULL;
+ text_size = 0;
return STRING_TOK;
- }
+ }
}
[^ \t\r\n\"\\]+ { graphyylval = gf_strdup (yytext) ; return ID; }
[ \t\r\n]+ ;
diff --git a/libglusterfs/src/graph.y b/libglusterfs/src/graph.y
index 9fd02823a6c..e63febdc08b 100644
--- a/libglusterfs/src/graph.y
+++ b/libglusterfs/src/graph.y
@@ -22,10 +22,11 @@
#define RELAX_POISONING
-#include "xlator.h"
-#include "graph-utils.h"
-#include "logging.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/xlator.h"
+#include "glusterfs/graph-utils.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/libglusterfs-messages.h"
static int new_volume (char *name);
static int volume_type (char *type);
@@ -122,7 +123,7 @@ new_volume (char *name)
int ret = 0;
if (!name) {
- gf_msg_debug ("parser", 0,"Invalid argument name: '%s'", name);
+ gf_msg_debug ("parser", 0,"Invalid argument name");
ret = -1;
goto out;
}
@@ -163,7 +164,8 @@ new_volume (char *name)
goto out;
}
- curr->options = get_new_dict ();
+ INIT_LIST_HEAD(&curr->volume_options);
+ curr->options = dict_new ();
if (!curr->options) {
GF_FREE (curr->name);
@@ -181,6 +183,7 @@ new_volume (char *name)
construct->first = curr;
construct->xl_count++;
+ curr->xl_id = construct->xl_count;
gf_msg_trace ("parser", 0, "New node for '%s'", name);
@@ -237,7 +240,7 @@ volume_option (char *key, char *value)
}
set_value = gf_strdup (value);
- ret = dict_set_dynstr (curr->options, key, set_value);
+ ret = dict_set_option (curr->options, key, set_value);
if (ret == 1) {
gf_msg ("parser", GF_LOG_ERROR, 0,
@@ -510,7 +513,7 @@ preprocess (FILE *srcfp, FILE *dstfp)
if (in_backtick) {
gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_VOLUME_ERROR,
- "Unterminated backtick in volume specfication file at "
+ "Unterminated backtick in volume specification file at "
"line (%d), column (%d).", line, column);
ret = -1;
}
@@ -540,6 +543,9 @@ glusterfs_graph_new ()
INIT_LIST_HEAD (&graph->list);
+ pthread_mutex_init(&graph->mutex, NULL);
+ pthread_cond_init(&graph->child_down_cond, NULL);
+
gettimeofday (&graph->dob, NULL);
return graph;
@@ -553,19 +559,19 @@ glusterfs_graph_construct (FILE *fp)
int tmp_fd = -1;
glusterfs_graph_t *graph = NULL;
FILE *tmp_file = NULL;
- char template[PATH_MAX] = {0};
+ char template[] = "/tmp/tmp.XXXXXX";
static pthread_mutex_t graph_mutex = PTHREAD_MUTEX_INITIALIZER;
graph = glusterfs_graph_new ();
if (!graph)
goto err;
- strcpy (template, "/tmp/tmp.XXXXXX");
+ /* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
tmp_fd = mkstemp (template);
if (-1 == tmp_fd)
goto err;
- ret = unlink (template);
+ ret = sys_unlink (template);
if (ret < 0) {
gf_msg ("parser", GF_LOG_WARNING, 0, LG_MSG_FILE_OP_FAILED,
"Unable to delete file: %s", template);
@@ -606,7 +612,7 @@ err:
gf_msg ("parser", GF_LOG_ERROR, 0, LG_MSG_FILE_OP_FAILED,
"cannot create temporary file");
if (-1 != tmp_fd)
- close (tmp_fd);
+ sys_close (tmp_fd);
}
glusterfs_graph_destroy (graph);
diff --git a/libglusterfs/src/hashfn.c b/libglusterfs/src/hashfn.c
index 62f7ab87800..d2237e99f83 100644
--- a/libglusterfs/src/hashfn.c
+++ b/libglusterfs/src/hashfn.c
@@ -11,24 +11,11 @@
#include <stdint.h>
#include <stdlib.h>
-#include "hashfn.h"
-
-#define get16bits(d) (*((const uint16_t *) (d)))
+#define get16bits(d) (*((const uint16_t *)(d)))
#define DM_DELTA 0x9E3779B9
-#define DM_FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
-#define DM_PARTROUNDS 6 /* 6 gets complete mixing */
-
-
-uint32_t
-ReallySimpleHash (char *path, int len)
-{
- uint32_t hash = 0;
- for (;len > 0; len--)
- hash ^= (char)path[len];
-
- return hash;
-}
+#define DM_FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
+#define DM_PARTROUNDS 6 /* 6 gets complete mixing */
/*
This is apparently the "fastest hash function for strings".
@@ -37,146 +24,145 @@ ReallySimpleHash (char *path, int len)
/* In any case make sure, you return 1 */
-uint32_t SuperFastHash (const char * data, int32_t len) {
- uint32_t hash = len, tmp;
- int32_t rem;
-
- if (len <= 1 || data == NULL) return 1;
-
- rem = len & 3;
- len >>= 2;
-
- /* Main loop */
- for (;len > 0; len--) {
- hash += get16bits (data);
- tmp = (get16bits (data+2) << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2*sizeof (uint16_t);
- hash += hash >> 11;
- }
-
- /* Handle end cases */
- switch (rem) {
- case 3: hash += get16bits (data);
- hash ^= hash << 16;
- hash ^= data[sizeof (uint16_t)] << 18;
- hash += hash >> 11;
- break;
- case 2: hash += get16bits (data);
- hash ^= hash << 11;
- hash += hash >> 17;
- break;
- case 1: hash += *data;
- hash ^= hash << 10;
- hash += hash >> 1;
- }
-
- /* Force "avalanching" of final 127 bits */
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 4;
- hash += hash >> 17;
- hash ^= hash << 25;
- hash += hash >> 6;
-
- return hash;
+uint32_t
+SuperFastHash(const char *data, int32_t len)
+{
+ uint32_t hash = len, tmp;
+ int32_t rem;
+
+ if (len <= 1 || data == NULL)
+ return 1;
+
+ rem = len & 3;
+ len >>= 2;
+
+ /* Main loop */
+ for (; len > 0; len--) {
+ hash += get16bits(data);
+ tmp = (get16bits(data + 2) << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ data += 2 * sizeof(uint16_t);
+ hash += hash >> 11;
+ }
+
+ /* Handle end cases */
+ switch (rem) {
+ case 3:
+ hash += get16bits(data);
+ hash ^= hash << 16;
+ hash ^= data[sizeof(uint16_t)] << 18;
+ hash += hash >> 11;
+ break;
+ case 2:
+ hash += get16bits(data);
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ break;
+ case 1:
+ hash += *data;
+ hash ^= hash << 10;
+ hash += hash >> 1;
+ }
+
+ /* Force "avalanching" of final 127 bits */
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 4;
+ hash += hash >> 17;
+ hash ^= hash << 25;
+ hash += hash >> 6;
+
+ return hash;
}
-
/* Davies-Meyer hashing function implementation
*/
static int
-dm_round (int rounds, uint32_t *array, uint32_t *h0, uint32_t *h1)
+dm_round(int rounds, uint32_t *array, uint32_t *h0, uint32_t *h1)
{
- uint32_t sum = 0;
- int n = 0;
- uint32_t b0 = 0;
- uint32_t b1 = 0;
-
- b0 = *h0;
- b1 = *h1;
-
- n = rounds;
-
- do {
- sum += DM_DELTA;
- b0 += ((b1 << 4) + array[0])
- ^ (b1 + sum)
- ^ ((b1 >> 5) + array[1]);
- b1 += ((b0 << 4) + array[2])
- ^ (b0 + sum)
- ^ ((b0 >> 5) + array[3]);
- } while (--n);
-
- *h0 += b0;
- *h1 += b1;
-
- return 0;
-}
+ uint32_t sum = 0;
+ int n = 0;
+ uint32_t b0 = 0;
+ uint32_t b1 = 0;
+
+ b0 = *h0;
+ b1 = *h1;
+
+ n = rounds;
+ do {
+ sum += DM_DELTA;
+ b0 += ((b1 << 4) + array[0]) ^ (b1 + sum) ^ ((b1 >> 5) + array[1]);
+ b1 += ((b0 << 4) + array[2]) ^ (b0 + sum) ^ ((b0 >> 5) + array[3]);
+ } while (--n);
+
+ *h0 += b0;
+ *h1 += b1;
+
+ return 0;
+}
uint32_t
-__pad (int len)
+__pad(int len)
{
- uint32_t pad = 0;
+ uint32_t pad = 0;
- pad = (uint32_t) len | ((uint32_t) len << 8);
- pad |= pad << 16;
+ pad = (uint32_t)len | ((uint32_t)len << 8);
+ pad |= pad << 16;
- return pad;
+ return pad;
}
uint32_t
-gf_dm_hashfn (const char *msg, int len)
+gf_dm_hashfn(const char *msg, int len)
{
- uint32_t h0 = 0x9464a485;
- uint32_t h1 = 0x542e1a94;
- uint32_t array[4];
- uint32_t pad = 0;
- int i = 0;
- int j = 0;
- int full_quads = 0;
- int full_words = 0;
- int full_bytes = 0;
- uint32_t *intmsg = NULL;
- int word = 0;
-
-
- intmsg = (uint32_t *) msg;
- pad = __pad (len);
-
- full_bytes = len;
- full_words = len / 4;
- full_quads = len / 16;
-
- for (i = 0; i < full_quads; i++) {
- for (j = 0; j < 4; j++) {
- word = *intmsg;
- array[j] = word;
- intmsg++;
- full_words--;
- full_bytes -= 4;
- }
- dm_round (DM_PARTROUNDS, &array[0], &h0, &h1);
- }
-
+ uint32_t h0 = 0x9464a485;
+ uint32_t h1 = 0x542e1a94;
+ uint32_t array[4];
+ uint32_t pad = 0;
+ int i = 0;
+ int j = 0;
+ int full_quads = 0;
+ int full_words = 0;
+ int full_bytes = 0;
+ uint32_t *intmsg = NULL;
+ int word = 0;
+
+ intmsg = (uint32_t *)msg;
+ pad = __pad(len);
+
+ full_bytes = len;
+ full_words = len / 4;
+ full_quads = len / 16;
+
+ for (i = 0; i < full_quads; i++) {
for (j = 0; j < 4; j++) {
- if (full_words) {
- word = *intmsg;
- array[j] = word;
- intmsg++;
- full_words--;
- full_bytes -= 4;
- } else {
- array[j] = pad;
- while (full_bytes) {
- array[j] <<= 8;
- array[j] |= msg[len - full_bytes];
- full_bytes--;
- }
- }
+ word = *intmsg;
+ array[j] = word;
+ intmsg++;
+ full_words--;
+ full_bytes -= 4;
+ }
+ dm_round(DM_PARTROUNDS, &array[0], &h0, &h1);
+ }
+
+ for (j = 0; j < 4; j++) {
+ if (full_words) {
+ word = *intmsg;
+ array[j] = word;
+ intmsg++;
+ full_words--;
+ full_bytes -= 4;
+ } else {
+ array[j] = pad;
+ while (full_bytes) {
+ array[j] <<= 8;
+ array[j] |= msg[len - full_bytes];
+ full_bytes--;
+ }
}
- dm_round (DM_FULLROUNDS, &array[0], &h0, &h1);
+ }
+ dm_round(DM_FULLROUNDS, &array[0], &h0, &h1);
- return h0 ^ h1;
+ return h0 ^ h1;
}
diff --git a/libglusterfs/src/iatt.h b/libglusterfs/src/iatt.h
deleted file mode 100644
index e89f94662aa..00000000000
--- a/libglusterfs/src/iatt.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- 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 _IATT_H
-#define _IATT_H
-
-#include <sys/types.h>
-#include <sys/stat.h> /* for iatt <--> stat conversions */
-#include <unistd.h>
-
-#include "compat.h"
-#include "compat-uuid.h"
-
-typedef enum {
- IA_INVAL = 0,
- IA_IFREG,
- IA_IFDIR,
- IA_IFLNK,
- IA_IFBLK,
- IA_IFCHR,
- IA_IFIFO,
- IA_IFSOCK
-} ia_type_t;
-
-
-typedef struct {
- uint8_t suid:1;
- uint8_t sgid:1;
- uint8_t sticky:1;
- struct {
- uint8_t read:1;
- uint8_t write:1;
- uint8_t exec:1;
- } owner, group, other;
-} ia_prot_t;
-
-
-struct iatt {
- uint64_t ia_ino; /* inode number */
- uuid_t ia_gfid;
- uint64_t ia_dev; /* backing device ID */
- ia_type_t ia_type; /* type of file */
- ia_prot_t ia_prot; /* protection */
- uint32_t ia_nlink; /* Link count */
- uint32_t ia_uid; /* user ID of owner */
- uint32_t ia_gid; /* group ID of owner */
- uint64_t ia_rdev; /* device ID (if special file) */
- uint64_t ia_size; /* file size in bytes */
- uint32_t ia_blksize; /* blocksize for filesystem I/O */
- uint64_t ia_blocks; /* number of 512B blocks allocated */
- uint32_t ia_atime; /* last access time */
- uint32_t ia_atime_nsec;
- uint32_t ia_mtime; /* last modification time */
- uint32_t ia_mtime_nsec;
- uint32_t ia_ctime; /* last status change time */
- uint32_t ia_ctime_nsec;
-};
-
-
-#define IA_ISREG(t) (t == IA_IFREG)
-#define IA_ISDIR(t) (t == IA_IFDIR)
-#define IA_ISLNK(t) (t == IA_IFLNK)
-#define IA_ISBLK(t) (t == IA_IFBLK)
-#define IA_ISCHR(t) (t == IA_IFCHR)
-#define IA_ISFIFO(t) (t == IA_IFIFO)
-#define IA_ISSOCK(t) (t == IA_IFSOCK)
-#define IA_ISINVAL(t) (t == IA_INVAL)
-
-#define IA_PROT_RUSR(prot) ((prot).owner.read == 1)
-#define IA_PROT_WUSR(prot) ((prot).owner.write == 1)
-#define IA_PROT_XUSR(prot) ((prot).owner.exec == 1)
-
-#define IA_PROT_RGRP(prot) ((prot).group.read == 1)
-#define IA_PROT_WGRP(prot) ((prot).group.write == 1)
-#define IA_PROT_XGRP(prot) ((prot).group.exec == 1)
-
-#define IA_PROT_ROTH(prot) ((prot).other.read == 1)
-#define IA_PROT_WOTH(prot) ((prot).other.write == 1)
-#define IA_PROT_XOTH(prot) ((prot).other.exec == 1)
-
-#define IA_PROT_SUID(prot) ((prot).suid == 1)
-#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)
-{
- return (uint32_t) (ia_dev >> 32);
-}
-
-
-static inline uint32_t
-ia_minor (uint64_t ia_dev)
-{
- return (uint32_t) (ia_dev & 0xffffffff);
-}
-
-
-static inline uint64_t
-ia_makedev (uint32_t ia_maj, uint32_t ia_min)
-{
- return ((((uint64_t) ia_maj) << 32) | ia_min);
-}
-
-
-static inline ia_prot_t
-ia_prot_from_st_mode (mode_t mode)
-{
- ia_prot_t ia_prot = {0, };
-
- if (mode & S_ISUID)
- ia_prot.suid = 1;
- if (mode & S_ISGID)
- ia_prot.sgid = 1;
- if (mode & S_ISVTX)
- ia_prot.sticky = 1;
-
- if (mode & S_IRUSR)
- ia_prot.owner.read = 1;
- if (mode & S_IWUSR)
- ia_prot.owner.write = 1;
- if (mode & S_IXUSR)
- ia_prot.owner.exec = 1;
-
- if (mode & S_IRGRP)
- ia_prot.group.read = 1;
- if (mode & S_IWGRP)
- ia_prot.group.write = 1;
- if (mode & S_IXGRP)
- ia_prot.group.exec = 1;
-
- if (mode & S_IROTH)
- ia_prot.other.read = 1;
- if (mode & S_IWOTH)
- ia_prot.other.write = 1;
- if (mode & S_IXOTH)
- ia_prot.other.exec = 1;
-
- return ia_prot;
-}
-
-
-static inline ia_type_t
-ia_type_from_st_mode (mode_t mode)
-{
- ia_type_t type = IA_INVAL;
-
- if (S_ISREG (mode))
- type = IA_IFREG;
- if (S_ISDIR (mode))
- type = IA_IFDIR;
- if (S_ISLNK (mode))
- type = IA_IFLNK;
- if (S_ISBLK (mode))
- type = IA_IFBLK;
- if (S_ISCHR (mode))
- type = IA_IFCHR;
- if (S_ISFIFO (mode))
- type = IA_IFIFO;
- if (S_ISSOCK (mode))
- type = IA_IFSOCK;
-
- return type;
-}
-
-
-static inline mode_t
-st_mode_from_ia (ia_prot_t prot, ia_type_t type)
-{
- mode_t st_mode = 0;
- uint32_t type_bit = 0;
- uint32_t prot_bit = 0;
-
- switch (type) {
- case IA_IFREG:
- type_bit = S_IFREG;
- break;
- case IA_IFDIR:
- type_bit = S_IFDIR;
- break;
- case IA_IFLNK:
- type_bit = S_IFLNK;
- break;
- case IA_IFBLK:
- type_bit = S_IFBLK;
- break;
- case IA_IFCHR:
- type_bit = S_IFCHR;
- break;
- case IA_IFIFO:
- type_bit = S_IFIFO;
- break;
- case IA_IFSOCK:
- type_bit = S_IFSOCK;
- break;
- case IA_INVAL:
- break;
- }
-
- if (prot.suid)
- prot_bit |= S_ISUID;
- if (prot.sgid)
- prot_bit |= S_ISGID;
- if (prot.sticky)
- prot_bit |= S_ISVTX;
-
- if (prot.owner.read)
- prot_bit |= S_IRUSR;
- if (prot.owner.write)
- prot_bit |= S_IWUSR;
- if (prot.owner.exec)
- prot_bit |= S_IXUSR;
-
- if (prot.group.read)
- prot_bit |= S_IRGRP;
- if (prot.group.write)
- prot_bit |= S_IWGRP;
- if (prot.group.exec)
- prot_bit |= S_IXGRP;
-
- if (prot.other.read)
- prot_bit |= S_IROTH;
- if (prot.other.write)
- prot_bit |= S_IWOTH;
- if (prot.other.exec)
- prot_bit |= S_IXOTH;
-
- st_mode = (type_bit | prot_bit);
-
- return st_mode;
-}
-
-
-static inline int
-iatt_from_stat (struct iatt *iatt, struct stat *stat)
-{
- iatt->ia_dev = stat->st_dev;
- iatt->ia_ino = stat->st_ino;
-
- iatt->ia_type = ia_type_from_st_mode (stat->st_mode);
- iatt->ia_prot = ia_prot_from_st_mode (stat->st_mode);
-
- iatt->ia_nlink = stat->st_nlink;
- iatt->ia_uid = stat->st_uid;
- iatt->ia_gid = stat->st_gid;
-
- iatt->ia_rdev = ia_makedev (major (stat->st_rdev),
- minor (stat->st_rdev));
-
- iatt->ia_size = stat->st_size;
- 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);
-
- iatt->ia_mtime = stat->st_mtime;
- iatt->ia_mtime_nsec = ST_MTIM_NSEC (stat);
-
- iatt->ia_ctime = stat->st_ctime;
- iatt->ia_ctime_nsec = ST_CTIM_NSEC (stat);
-
- return 0;
-}
-
-
-static inline int
-iatt_to_stat (struct iatt *iatt, struct stat *stat)
-{
- stat->st_dev = iatt->ia_dev;
- stat->st_ino = iatt->ia_ino;
-
- stat->st_mode = st_mode_from_ia (iatt->ia_prot, iatt->ia_type);
-
- stat->st_nlink = iatt->ia_nlink;
- stat->st_uid = iatt->ia_uid;
- stat->st_gid = iatt->ia_gid;
-
- stat->st_rdev = makedev (ia_major (iatt->ia_rdev),
- ia_minor (iatt->ia_rdev));
-
- stat->st_size = iatt->ia_size;
- stat->st_blksize = iatt->ia_blksize;
- stat->st_blocks = iatt->ia_blocks;
-
- stat->st_atime = iatt->ia_atime;
- ST_ATIM_NSEC_SET (stat, iatt->ia_atime_nsec);
-
- stat->st_mtime = iatt->ia_mtime;
- ST_MTIM_NSEC_SET (stat, iatt->ia_mtime_nsec);
-
- stat->st_ctime = iatt->ia_ctime;
- ST_CTIM_NSEC_SET (stat, iatt->ia_ctime_nsec);
-
- return 0;
-}
-
-
-#endif /* _IATT_H */
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index 50ef98fba20..dbadf77442d 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -8,653 +8,707 @@
cases as published by the Free Software Foundation.
*/
-#include "inode.h"
-#include "fd.h"
-#include "common-utils.h"
-#include "statedump.h"
+#include "glusterfs/inode.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/statedump.h"
#include <pthread.h>
#include <sys/types.h>
#include <stdint.h>
-#include "list.h"
-#include <time.h>
+#include "glusterfs/list.h"
#include <assert.h>
-#include "libglusterfs-messages.h"
+#include "glusterfs/libglusterfs-messages.h"
/* TODO:
move latest accessed dentry to list_head of inode
*/
-#define INODE_DUMP_LIST(head, key_buf, key_prefix, list_type) \
- { \
- int i = 1; \
- inode_t *inode = NULL; \
- list_for_each_entry (inode, head, list) { \
- gf_proc_dump_build_key(key_buf, key_prefix, \
- "%s.%d",list_type, i++); \
- gf_proc_dump_add_section(key_buf); \
- inode_dump(inode, key); \
- } \
- }
+// clang-format off
+/*
+
+Details as per Xavi:
+
+ I think we should have 3 lists: active, lru and invalidate.
+
+We'll need 3 things: refs, nlookups and invalidate_sent flag. Any change of
+refs, invalidate_sent flag and moving from one list to another must be done
+atomically.
+
+With this information, these are the states that cause a transition:
+
+ refs nlookups inv_sent op
+ 1 0 0 unref -> refs = 0, active--->destroy
+ 1 1 0 unref -> refs = 0, active--->lru
+ 1 1 0 forget -> nlookups = 0, active--->active
+ *0 1 0 forget -> nlookups = 0, lru--->destroy
+ *0 1 1 forget -> nlookups = 0, invalidate--->destroy
+ 0 1 0 ref -> refs = 1, lru--->active
+ 0 1 1 ref -> refs = 1, inv_sent = 0, invalidate--->active
+ 0 1 0 overflow -> refs = 1, inv_sent = 1, lru--->invalidate
+ 1 1 1 unref -> refs = 0, invalidate--->invalidate
+ 1 1 1 forget -> nlookups = 0, inv_sent = 0, invalidate--->active
+
+(*) technically these combinations cannot happen because a forget sent by the
+kernel first calls ref() and then unref(). However it's equivalent.
+
+overflow means that lru list has grown beyond the limit and the inode needs to
+be invalidated. All other combinations do not cause a change in state or are not
+possible.
+
+Based on this, the code could be similar to this:
+
+ ref(inode, inv)
+ {
+ if (refs == 0) {
+ if (inv_sent) {
+ invalidate_count--;
+ inv_sent = 0;
+ } else {
+ lru_count--;
+ }
+ if (inv) {
+ inv_sent = 1;
+ invalidate_count++;
+ list_move(inode, invalidate);
+ } else {
+ active_count++;
+ list_move(inode, active);
+ }
+ }
+ refs++;
+ }
+
+ unref(inode, clear)
+ {
+ if (clear && inv_sent) {
+ // there is a case of fuse itself sending forget, without
+ // invalidate, after entry delete, like unlink(), rmdir().
+ inv_sent = 0;
+ invalidate_count--;
+ active_count++;
+ list_move(inode, active);
+ }
+ refs--;
+ if ((refs == 0) && !inv_sent) {
+ active_count--;
+ if (nlookups == 0) {
+ destroy(inode);
+ } else {
+ lru_count++;
+ list_move(inode, lru);
+ }
+ }
+ }
+
+ forget(inode)
+ {
+ ref(inode, false);
+ nlookups--;
+ unref(inode, true);
+ }
+
+ overflow(inode)
+ {
+ ref(inode, true);
+ invalidator(inode);
+ unref(inode, false);
+ }
+
+*/
+// clang-format on
+
+#define INODE_DUMP_LIST(head, key_buf, key_prefix, list_type) \
+ { \
+ int i = 1; \
+ inode_t *inode = NULL; \
+ list_for_each_entry(inode, head, list) \
+ { \
+ gf_proc_dump_build_key(key_buf, key_prefix, "%s.%d", list_type, \
+ i++); \
+ gf_proc_dump_add_section("%s", key_buf); \
+ inode_dump(inode, key); \
+ } \
+ }
static inode_t *
-__inode_unref (inode_t *inode);
+__inode_unref(inode_t *inode, bool clear);
static int
-inode_table_prune (inode_table_t *table);
+inode_table_prune(inode_table_t *table);
void
-fd_dump (struct list_head *head, char *prefix);
+fd_dump(struct list_head *head, char *prefix);
static int
-hash_dentry (inode_t *parent, const char *name, int mod)
+hash_dentry(inode_t *parent, const char *name, int mod)
{
- int hash = 0;
- int ret = 0;
+ int hash = 0;
+ int ret = 0;
- hash = *name;
- if (hash) {
- for (name += 1; *name != '\0'; name++) {
- hash = (hash << 5) - hash + *name;
- }
+ hash = *name;
+ if (hash) {
+ for (name += 1; *name != '\0'; name++) {
+ hash = (hash << 5) - hash + *name;
}
- ret = (hash + (unsigned long)parent) % mod;
+ }
+ ret = (hash + (unsigned long)parent) % mod;
- return ret;
+ return ret;
}
-
static int
-hash_gfid (uuid_t uuid, int mod)
+hash_gfid(uuid_t uuid, int mod)
{
- int ret = 0;
-
- ret = uuid[15] + (uuid[14] << 8);
-
- return ret;
+ return ((uuid[15] + (uuid[14] << 8)) % mod);
}
-
static void
-__dentry_hash (dentry_t *dentry)
+__dentry_hash(dentry_t *dentry, const int hash)
{
- inode_table_t *table = NULL;
- int hash = 0;
-
- if (!dentry) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_DENTRY_NOT_FOUND, "dentry not found");
- return;
- }
+ inode_table_t *table = NULL;
- table = dentry->inode->table;
- hash = hash_dentry (dentry->parent, dentry->name,
- table->hashsize);
+ table = dentry->inode->table;
- list_del_init (&dentry->hash);
- list_add (&dentry->hash, &table->name_hash[hash]);
+ list_del_init(&dentry->hash);
+ list_add(&dentry->hash, &table->name_hash[hash]);
}
-
static int
-__is_dentry_hashed (dentry_t *dentry)
+__is_dentry_hashed(dentry_t *dentry)
{
- if (!dentry) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_DENTRY_NOT_FOUND, "dentry not found");
- return 0;
- }
-
- return !list_empty (&dentry->hash);
+ return !list_empty(&dentry->hash);
}
-
static void
-__dentry_unhash (dentry_t *dentry)
+__dentry_unhash(dentry_t *dentry)
{
- if (!dentry) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_DENTRY_NOT_FOUND, "dentry not found");
- return;
- }
-
- list_del_init (&dentry->hash);
+ list_del_init(&dentry->hash);
}
-
static void
-__dentry_unset (dentry_t *dentry)
+dentry_destroy(dentry_t *dentry)
{
- if (!dentry) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_DENTRY_NOT_FOUND, "dentry not found");
- return;
- }
-
- __dentry_unhash (dentry);
+ if (!dentry)
+ return;
- list_del_init (&dentry->inode_list);
+ GF_FREE(dentry->name);
+ dentry->name = NULL;
+ mem_put(dentry);
- GF_FREE (dentry->name);
- dentry->name = NULL;
+ return;
+}
- if (dentry->parent) {
- __inode_unref (dentry->parent);
- dentry->parent = NULL;
- }
+static dentry_t *
+__dentry_unset(dentry_t *dentry)
+{
+ if (!dentry)
+ return NULL;
- mem_put (dentry);
-}
+ __dentry_unhash(dentry);
+ list_del_init(&dentry->inode_list);
-static int
-__foreach_ancestor_dentry (dentry_t *dentry,
- int (per_dentry_fn) (dentry_t *dentry,
- void *data),
- void *data)
-{
- inode_t *parent = NULL;
- dentry_t *each = NULL;
- int ret = 0;
-
- if (!dentry) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_DENTRY_NOT_FOUND, "dentry not found");
- return 0;
- }
+ if (dentry->parent) {
+ __inode_unref(dentry->parent, false);
+ dentry->parent = NULL;
+ }
- ret = per_dentry_fn (dentry, data);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_PER_DENTRY_FAILED, "per dentry fn returned %d",
- ret);
- goto out;
- }
+ return dentry;
+}
- parent = dentry->parent;
- if (!parent) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_PARENT_DENTRY_NOT_FOUND,
- "parent not found");
- goto out;
- }
+static int
+__foreach_ancestor_dentry(dentry_t *dentry,
+ int(per_dentry_fn)(dentry_t *dentry, void *data),
+ void *data)
+{
+ inode_t *parent = NULL;
+ dentry_t *each = NULL;
+ int ret = 0;
- list_for_each_entry (each, &parent->dentry_list, inode_list) {
- ret = __foreach_ancestor_dentry (each, per_dentry_fn, data);
- if (ret)
- goto out;
- }
+ if (!dentry) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND,
+ "dentry not found");
+ return 0;
+ }
+
+ ret = per_dentry_fn(dentry, data);
+ if (ret) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PER_DENTRY_FAILED,
+ "ret=%d", ret, NULL);
+ goto out;
+ }
+
+ parent = dentry->parent;
+ if (!parent) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PARENT_DENTRY_NOT_FOUND,
+ NULL);
+ goto out;
+ }
+
+ list_for_each_entry(each, &parent->dentry_list, inode_list)
+ {
+ ret = __foreach_ancestor_dentry(each, per_dentry_fn, data);
+ if (ret)
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
-
static int
-__check_cycle (dentry_t *a_dentry, void *data)
+__check_cycle(dentry_t *a_dentry, void *data)
{
- inode_t *link_inode = NULL;
+ inode_t *link_inode = NULL;
- link_inode = data;
+ link_inode = data;
- if (a_dentry->parent == link_inode)
- return 1;
+ if (a_dentry->parent == link_inode)
+ return 1;
- return 0;
+ return 0;
}
-
static int
-__is_dentry_cyclic (dentry_t *dentry)
+__is_dentry_cyclic(dentry_t *dentry)
{
- int ret = 0;
- inode_t *inode = NULL;
- char *name = "<nul>";
-
- ret = __foreach_ancestor_dentry (dentry, __check_cycle,
- dentry->inode);
- if (ret) {
- inode = dentry->inode;
+ int ret = 0;
- if (dentry->name)
- name = dentry->name;
-
- gf_msg (dentry->inode->table->name, GF_LOG_CRITICAL, 0,
- LG_MSG_DENTRY_CYCLIC_LOOP, "detected cyclic loop "
- "formation during inode linkage. inode (%s) linking "
- "under itself as %s", uuid_utoa (inode->gfid), name);
- }
+ ret = __foreach_ancestor_dentry(dentry, __check_cycle, dentry->inode);
+ if (ret) {
+ gf_smsg(dentry->inode->table->name, GF_LOG_CRITICAL, 0,
+ LG_MSG_DENTRY_CYCLIC_LOOP, "gfid=%s name=-%s",
+ uuid_utoa(dentry->inode->gfid), dentry->name, NULL);
+ }
- return ret;
+ return ret;
}
-
static void
-__inode_unhash (inode_t *inode)
+__inode_unhash(inode_t *inode)
{
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return;
- }
-
- list_del_init (&inode->hash);
+ list_del_init(&inode->hash);
}
-
static int
-__is_inode_hashed (inode_t *inode)
+__is_inode_hashed(inode_t *inode)
{
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return 0;
- }
-
- return !list_empty (&inode->hash);
+ return !list_empty(&inode->hash);
}
-
static void
-__inode_hash (inode_t *inode)
+__inode_hash(inode_t *inode, const int hash)
{
- inode_table_t *table = NULL;
- int hash = 0;
+ inode_table_t *table = inode->table;
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return;
- }
-
- table = inode->table;
- hash = hash_gfid (inode->gfid, 65536);
-
- list_del_init (&inode->hash);
- list_add (&inode->hash, &table->inode_hash[hash]);
+ list_del_init(&inode->hash);
+ list_add(&inode->hash, &table->inode_hash[hash]);
}
-
static dentry_t *
-__dentry_search_for_inode (inode_t *inode, uuid_t pargfid, const char *name)
+__dentry_search_for_inode(inode_t *inode, uuid_t pargfid, const char *name)
{
- dentry_t *dentry = NULL;
- dentry_t *tmp = NULL;
+ dentry_t *dentry = NULL;
+ dentry_t *tmp = NULL;
- if (!inode || !name) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG,
- "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 || gf_uuid_is_null (pargfid))
- 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 || gf_uuid_is_null(pargfid))
+ return NULL;
- list_for_each_entry (tmp, &inode->dentry_list, inode_list) {
- if ((gf_uuid_compare (tmp->parent->gfid, pargfid) == 0) &&
- !strcmp (tmp->name, name)) {
- dentry = tmp;
- break;
- }
+ list_for_each_entry(tmp, &inode->dentry_list, inode_list)
+ {
+ if ((gf_uuid_compare(tmp->parent->gfid, pargfid) == 0) &&
+ !strcmp(tmp->name, name)) {
+ dentry = tmp;
+ break;
}
+ }
- return dentry;
+ return dentry;
}
-
static void
-__inode_ctx_free (inode_t *inode)
+__inode_ctx_free(inode_t *inode)
{
- int index = 0;
- xlator_t *xl = NULL;
- xlator_t *old_THIS = NULL;
-
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return;
- }
+ int index = 0;
+ xlator_t *xl = NULL;
+ xlator_t *old_THIS = NULL;
- if (!inode->_ctx) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0, LG_MSG_CTX_NULL,
- "_ctx not found");
- goto noctx;
- }
+ if (!inode->_ctx) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_CTX_NULL, NULL);
+ goto noctx;
+ }
- 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;
- old_THIS = THIS;
- THIS = xl;
- if (xl->cbks->forget)
- xl->cbks->forget (xl, inode);
- THIS = old_THIS;
- }
+ for (index = 0; index < inode->table->ctxcount; index++) {
+ if (inode->_ctx[index].value1 || inode->_ctx[index].value2) {
+ xl = (xlator_t *)(long)inode->_ctx[index].xl_key;
+ if (xl && !xl->call_cleanup && xl->cbks->forget) {
+ old_THIS = THIS;
+ THIS = xl;
+ xl->cbks->forget(xl, inode);
+ THIS = old_THIS;
+ }
}
+ }
- GF_FREE (inode->_ctx);
- inode->_ctx = NULL;
+ GF_FREE(inode->_ctx);
+ inode->_ctx = NULL;
noctx:
- return;
+ return;
}
static void
-__inode_destroy (inode_t *inode)
+__inode_destroy(inode_t *inode)
{
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return;
- }
-
- __inode_ctx_free (inode);
+ __inode_ctx_free(inode);
- LOCK_DESTROY (&inode->lock);
- // memset (inode, 0xb, sizeof (*inode));
- mem_put (inode);
+ LOCK_DESTROY(&inode->lock);
+ // memset (inode, 0xb, sizeof (*inode));
+ mem_put(inode);
}
void
-inode_ctx_merge (fd_t *fd, inode_t *inode, inode_t *linked_inode)
+inode_ctx_merge(fd_t *fd, inode_t *inode, inode_t *linked_inode)
{
- int index = 0;
- xlator_t *xl = NULL;
- xlator_t *old_THIS = NULL;
+ int index = 0;
+ xlator_t *xl = NULL;
+ xlator_t *old_THIS = NULL;
- if (!fd || !inode || !linked_inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "invalid inode");
- return;
- }
+ if (!fd || !inode || !linked_inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid inode");
+ return;
+ }
- if (!inode->_ctx || !linked_inode->_ctx) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG,
- "invalid inode context");
- return;
- }
+ if (!inode->_ctx || !linked_inode->_ctx) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid inode context");
+ return;
+ }
- for (; index < inode->table->ctxcount; index++) {
- if (inode->_ctx[index].xl_key) {
- xl = (xlator_t *)(long) inode->_ctx[index].xl_key;
+ for (; index < inode->table->ctxcount; index++) {
+ if (inode->_ctx[index].xl_key) {
+ xl = (xlator_t *)(long)inode->_ctx[index].xl_key;
- old_THIS = THIS;
- THIS = xl;
- if (xl->cbks->ictxmerge)
- xl->cbks->ictxmerge (xl, fd,
- inode, linked_inode);
- THIS = old_THIS;
- }
+ old_THIS = THIS;
+ THIS = xl;
+ if (xl->cbks->ictxmerge)
+ xl->cbks->ictxmerge(xl, fd, inode, linked_inode);
+ THIS = old_THIS;
}
+ }
}
static void
-__inode_activate (inode_t *inode)
+__inode_activate(inode_t *inode)
{
- if (!inode)
- return;
-
- list_move (&inode->list, &inode->table->active);
- inode->table->active_size++;
+ list_move(&inode->list, &inode->table->active);
+ inode->table->active_size++;
}
-
static void
-__inode_passivate (inode_t *inode)
+__inode_passivate(inode_t *inode)
{
- dentry_t *dentry = NULL;
- dentry_t *t = NULL;
-
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return;
- }
+ dentry_t *dentry = NULL;
+ dentry_t *t = NULL;
- list_move_tail (&inode->list, &inode->table->lru);
- inode->table->lru_size++;
+ list_move_tail(&inode->list, &inode->table->lru);
+ inode->table->lru_size++;
- list_for_each_entry_safe (dentry, t, &inode->dentry_list, inode_list) {
- if (!__is_dentry_hashed (dentry))
- __dentry_unset (dentry);
- }
+ list_for_each_entry_safe(dentry, t, &inode->dentry_list, inode_list)
+ {
+ if (!__is_dentry_hashed(dentry))
+ dentry_destroy(__dentry_unset(dentry));
+ }
}
-
static void
-__inode_retire (inode_t *inode)
+__inode_retire(inode_t *inode)
{
- dentry_t *dentry = NULL;
- dentry_t *t = NULL;
+ dentry_t *dentry = NULL;
+ dentry_t *t = NULL;
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return;
- }
+ list_move_tail(&inode->list, &inode->table->purge);
+ inode->table->purge_size++;
- list_move_tail (&inode->list, &inode->table->purge);
- inode->table->purge_size++;
+ __inode_unhash(inode);
- __inode_unhash (inode);
-
- list_for_each_entry_safe (dentry, t, &inode->dentry_list, inode_list) {
- __dentry_unset (dentry);
- }
+ list_for_each_entry_safe(dentry, t, &inode->dentry_list, inode_list)
+ {
+ dentry_destroy(__dentry_unset(dentry));
+ }
}
+static int
+__inode_get_xl_index(inode_t *inode, xlator_t *xlator)
+{
+ int set_idx = -1;
+
+ if ((inode->_ctx[xlator->xl_id].xl_key != NULL) &&
+ (inode->_ctx[xlator->xl_id].xl_key != xlator))
+ goto out;
+
+ set_idx = xlator->xl_id;
+ inode->_ctx[set_idx].xl_key = xlator;
+
+out:
+ return set_idx;
+}
static inode_t *
-__inode_unref (inode_t *inode)
+__inode_unref(inode_t *inode, bool clear)
{
- if (!inode)
- return NULL;
+ int index = 0;
+ xlator_t *this = NULL;
+ uint64_t nlookup = 0;
+
+ /*
+ * Root inode should always be in active list of inode table. So unrefs
+ * on root inode are no-ops.
+ */
+ if (__is_root_gfid(inode->gfid))
+ return inode;
+ /*
+ * No need to acquire inode table's lock
+ * as __inode_unref is called after acquiding
+ * the inode table's lock.
+ */
+ if (inode->table->cleanup_started && !inode->ref)
/*
- * Root inode should always be in active list of inode table. So unrefs
- * on root inode are no-ops.
+ * There is a good chance that, the inode
+ * on which unref came has already been
+ * zero refed and added to the purge list.
+ * This can happen when inode table is
+ * being destroyed (glfs_fini is something
+ * which destroys the inode table).
+ *
+ * Consider a directory 'a' which has a file
+ * 'b'. Now as part of inode table destruction
+ * zero refing of inodes does not happen from
+ * leaf to the root. It happens in the order
+ * inodes are present in the list. So, in this
+ * example, the dentry of 'b' would have its
+ * parent set to the inode of 'a'. So if
+ * 'a' gets zero refed first (as part of
+ * inode table cleanup) and then 'b' has to
+ * zero refed, then dentry_unset is called on
+ * the dentry of 'b' and it further goes on to
+ * call inode_unref on b's parent which is 'a'.
+ * In this situation, GF_ASSERT would be called
+ * below as the refcount of 'a' has been already set
+ * to zero.
+ *
+ * So return the inode if the inode table cleanup
+ * has already started and inode refcount is 0.
*/
- if (__is_root_gfid(inode->gfid))
- return inode;
+ return inode;
- GF_ASSERT (inode->ref);
+ this = THIS;
- --inode->ref;
+ if (clear && inode->in_invalidate_list) {
+ inode->in_invalidate_list = false;
+ inode->table->invalidate_size--;
+ __inode_activate(inode);
+ }
+ GF_ASSERT(inode->ref);
- if (!inode->ref) {
- inode->table->active_size--;
+ --inode->ref;
- if (inode->nlookup)
- __inode_passivate (inode);
- else
- __inode_retire (inode);
- }
+ index = __inode_get_xl_index(inode, this);
+ if (index >= 0) {
+ inode->_ctx[index].xl_key = this;
+ inode->_ctx[index].ref--;
+ }
- return inode;
-}
+ if (!inode->ref && !inode->in_invalidate_list) {
+ inode->table->active_size--;
+ nlookup = GF_ATOMIC_GET(inode->nlookup);
+ if (nlookup)
+ __inode_passivate(inode);
+ else
+ __inode_retire(inode);
+ }
+
+ return inode;
+}
static inode_t *
-__inode_ref (inode_t *inode)
+__inode_ref(inode_t *inode, bool is_invalidate)
{
- if (!inode)
- return NULL;
+ int index = 0;
+ xlator_t *this = NULL;
+
+ if (!inode)
+ return NULL;
+
+ this = THIS;
+
+ /*
+ * Root inode should always be in active list of inode table. So unrefs
+ * on root inode are no-ops. If we do not allow unrefs but allow refs,
+ * it leads to refcount overflows and deleting and adding the inode
+ * to active-list, which is ugly. active_size (check __inode_activate)
+ * in inode table increases which is wrong. So just keep the ref
+ * count as 1 always
+ */
+ if (__is_root_gfid(inode->gfid) && inode->ref)
+ return inode;
- if (!inode->ref) {
- inode->table->lru_size--;
- __inode_activate (inode);
+ if (!inode->ref) {
+ if (inode->in_invalidate_list) {
+ inode->in_invalidate_list = false;
+ inode->table->invalidate_size--;
+ } else {
+ inode->table->lru_size--;
+ }
+ if (is_invalidate) {
+ inode->in_invalidate_list = true;
+ inode->table->invalidate_size++;
+ list_move_tail(&inode->list, &inode->table->invalidate);
+ } else {
+ __inode_activate(inode);
}
+ }
- /*
- * Root inode should always be in active list of inode table. So unrefs
- * on root inode are no-ops. If we do not allow unrefs but allow refs,
- * it leads to refcount overflows and deleting and adding the inode
- * to active-list, which is ugly. active_size (check __inode_activate)
- * in inode table increases which is wrong. So just keep the ref
- * count as 1 always
- */
- if (__is_root_gfid(inode->gfid) && inode->ref)
- return inode;
+ inode->ref++;
- inode->ref++;
+ index = __inode_get_xl_index(inode, this);
+ if (index >= 0) {
+ inode->_ctx[index].xl_key = this;
+ inode->_ctx[index].ref++;
+ }
- return inode;
+ return inode;
}
-
inode_t *
-inode_unref (inode_t *inode)
+inode_unref(inode_t *inode)
{
- inode_table_t *table = NULL;
+ inode_table_t *table = NULL;
- if (!inode)
- return NULL;
+ if (!inode)
+ return NULL;
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- inode = __inode_unref (inode);
- }
- pthread_mutex_unlock (&table->lock);
+ pthread_mutex_lock(&table->lock);
+ {
+ inode = __inode_unref(inode, false);
+ }
+ pthread_mutex_unlock(&table->lock);
- inode_table_prune (table);
+ inode_table_prune(table);
- return inode;
+ return inode;
}
-
inode_t *
-inode_ref (inode_t *inode)
+inode_ref(inode_t *inode)
{
- inode_table_t *table = NULL;
+ inode_table_t *table = NULL;
- if (!inode)
- return NULL;
+ if (!inode)
+ return NULL;
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- inode = __inode_ref (inode);
- }
- pthread_mutex_unlock (&table->lock);
+ pthread_mutex_lock(&table->lock);
+ {
+ inode = __inode_ref(inode, false);
+ }
+ pthread_mutex_unlock(&table->lock);
- return inode;
+ return inode;
}
-
static dentry_t *
-__dentry_create (inode_t *inode, inode_t *parent, const char *name)
+dentry_create(inode_t *inode, inode_t *parent, const char *name)
{
- dentry_t *newd = NULL;
-
- if (!inode || !parent || !name) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG,
- "inode || parent || name not found");
- return NULL;
- }
+ dentry_t *newd = NULL;
- newd = mem_get0 (parent->table->dentry_pool);
- if (newd == NULL) {
- goto out;
- }
-
- INIT_LIST_HEAD (&newd->inode_list);
- INIT_LIST_HEAD (&newd->hash);
+ newd = mem_get0(parent->table->dentry_pool);
+ if (newd == NULL) {
+ goto out;
+ }
- newd->name = gf_strdup (name);
- if (newd->name == NULL) {
- mem_put (newd);
- newd = NULL;
- goto out;
- }
+ INIT_LIST_HEAD(&newd->inode_list);
+ INIT_LIST_HEAD(&newd->hash);
- if (parent)
- newd->parent = __inode_ref (parent);
+ newd->name = gf_strdup(name);
+ if (newd->name == NULL) {
+ mem_put(newd);
+ newd = NULL;
+ goto out;
+ }
- list_add (&newd->inode_list, &inode->dentry_list);
- newd->inode = inode;
+ newd->inode = inode;
out:
- return newd;
+ return newd;
}
-
static inode_t *
-__inode_create (inode_table_t *table)
+inode_create(inode_table_t *table)
{
- inode_t *newi = NULL;
+ inode_t *newi = NULL;
- if (!table) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_TABLE_NOT_FOUND, "table not "
- "found");
- return NULL;
- }
+ newi = mem_get0(table->inode_pool);
+ if (!newi) {
+ goto out;
+ }
- newi = mem_get0 (table->inode_pool);
- if (!newi) {
- goto out;
- }
+ newi->table = table;
- newi->table = table;
+ LOCK_INIT(&newi->lock);
- LOCK_INIT (&newi->lock);
+ INIT_LIST_HEAD(&newi->fd_list);
+ INIT_LIST_HEAD(&newi->list);
+ INIT_LIST_HEAD(&newi->hash);
+ INIT_LIST_HEAD(&newi->dentry_list);
- INIT_LIST_HEAD (&newi->fd_list);
- INIT_LIST_HEAD (&newi->list);
- INIT_LIST_HEAD (&newi->hash);
- INIT_LIST_HEAD (&newi->dentry_list);
-
- newi->_ctx = GF_CALLOC (1,
- (sizeof (struct _inode_ctx) * table->ctxcount),
- gf_common_mt_inode_ctx);
- if (newi->_ctx == NULL) {
- LOCK_DESTROY (&newi->lock);
- mem_put (newi);
- newi = NULL;
- goto out;
- }
-
- list_add (&newi->list, &table->lru);
- table->lru_size++;
+ newi->_ctx = GF_CALLOC(1, (sizeof(struct _inode_ctx) * table->ctxcount),
+ gf_common_mt_inode_ctx);
+ if (newi->_ctx == NULL) {
+ LOCK_DESTROY(&newi->lock);
+ mem_put(newi);
+ newi = NULL;
+ goto out;
+ }
out:
-
- return newi;
+ return newi;
}
-
inode_t *
-inode_new (inode_table_t *table)
+inode_new(inode_table_t *table)
{
- inode_t *inode = NULL;
+ inode_t *inode = NULL;
- if (!table) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_TABLE_NOT_FOUND, "inode not "
- "found");
- return NULL;
- }
+ if (!table) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_INODE_TABLE_NOT_FOUND,
+ "inode not "
+ "found");
+ return NULL;
+ }
- pthread_mutex_lock (&table->lock);
+ inode = inode_create(table);
+ if (inode) {
+ pthread_mutex_lock(&table->lock);
{
- inode = __inode_create (table);
- if (inode != NULL) {
- __inode_ref (inode);
- }
+ list_add(&inode->list, &table->lru);
+ table->lru_size++;
+ __inode_ref(inode, false);
}
- pthread_mutex_unlock (&table->lock);
+ pthread_mutex_unlock(&table->lock);
+ }
- return inode;
+ return inode;
}
-
/* Reduce the ref count by value 'nref'
* Args:
* inode - address of the inode to operate on
@@ -665,1474 +719,1560 @@ inode_new (inode_table_t *table)
* hence to be used only in destructor functions and not otherwise.
*/
static inode_t *
-__inode_ref_reduce_by_n (inode_t *inode, uint64_t nref)
+__inode_ref_reduce_by_n(inode_t *inode, uint64_t nref)
{
- if (!inode)
- return NULL;
+ uint64_t nlookup = 0;
- GF_ASSERT (inode->ref >= nref);
+ GF_ASSERT(inode->ref >= nref);
- inode->ref -= nref;
+ inode->ref -= nref;
- if (!nref)
- inode->ref = 0;
+ if (!nref)
+ inode->ref = 0;
- if (!inode->ref) {
- inode->table->active_size--;
+ if (!inode->ref) {
+ inode->table->active_size--;
- if (inode->nlookup)
- __inode_passivate (inode);
- else
- __inode_retire (inode);
- }
+ nlookup = GF_ATOMIC_GET(inode->nlookup);
+ if (nlookup)
+ __inode_passivate(inode);
+ else
+ __inode_retire(inode);
+ }
- return inode;
+ return inode;
}
-
-static inode_t *
-__inode_lookup (inode_t *inode)
-{
- if (!inode)
- return NULL;
-
- inode->nlookup++;
-
- return inode;
-}
-
-
static inode_t *
-__inode_forget (inode_t *inode, uint64_t nlookup)
+inode_forget_atomic(inode_t *inode, uint64_t nlookup)
{
- if (!inode)
- return NULL;
-
- GF_ASSERT (inode->nlookup >= nlookup);
+ uint64_t inode_lookup = 0;
- inode->nlookup -= nlookup;
+ if (!inode)
+ return NULL;
- if (!nlookup)
- inode->nlookup = 0;
+ if (nlookup == 0) {
+ GF_ATOMIC_INIT(inode->nlookup, 0);
+ } else {
+ inode_lookup = GF_ATOMIC_FETCH_SUB(inode->nlookup, nlookup);
+ GF_ASSERT(inode_lookup >= nlookup);
+ }
- return inode;
+ return inode;
}
-
dentry_t *
-__dentry_grep (inode_table_t *table, inode_t *parent, const char *name)
+__dentry_grep(inode_table_t *table, inode_t *parent, const char *name,
+ const int hash)
{
- int hash = 0;
- dentry_t *dentry = NULL;
- dentry_t *tmp = NULL;
-
- if (!table || !name || !parent)
- return NULL;
+ dentry_t *dentry = NULL;
+ dentry_t *tmp = NULL;
- hash = hash_dentry (parent, name, table->hashsize);
-
- list_for_each_entry (tmp, &table->name_hash[hash], hash) {
- if (tmp->parent == parent && !strcmp (tmp->name, name)) {
- dentry = tmp;
- break;
- }
+ list_for_each_entry(tmp, &table->name_hash[hash], hash)
+ {
+ if (tmp->parent == parent && !strcmp(tmp->name, name)) {
+ dentry = tmp;
+ break;
}
+ }
- return dentry;
+ return dentry;
}
-
inode_t *
-inode_grep (inode_table_t *table, inode_t *parent, const char *name)
+inode_grep(inode_table_t *table, inode_t *parent, const char *name)
{
- inode_t *inode = NULL;
- dentry_t *dentry = NULL;
+ inode_t *inode = NULL;
+ dentry_t *dentry = NULL;
- if (!table || !parent || !name) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "table || parent || name"
- " not found");
- return NULL;
- }
+ if (!table || !parent || !name) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "table || parent || name"
+ " not found");
+ return NULL;
+ }
- pthread_mutex_lock (&table->lock);
- {
- dentry = __dentry_grep (table, parent, name);
-
- if (dentry)
- inode = dentry->inode;
+ int hash = hash_dentry(parent, name, table->hashsize);
- if (inode)
- __inode_ref (inode);
+ pthread_mutex_lock(&table->lock);
+ {
+ dentry = __dentry_grep(table, parent, name, hash);
+ if (dentry) {
+ inode = dentry->inode;
+ if (inode)
+ __inode_ref(inode, false);
}
- pthread_mutex_unlock (&table->lock);
+ }
+ pthread_mutex_unlock(&table->lock);
- return inode;
+ return inode;
}
-
inode_t *
-inode_resolve (inode_table_t *table, char *path)
+inode_resolve(inode_table_t *table, char *path)
{
- char *tmp = NULL, *bname = NULL, *str = NULL, *saveptr = NULL;
- inode_t *inode = NULL, *parent = NULL;
-
- if ((path == NULL) || (table == NULL)) {
- goto out;
- }
+ char *tmp = NULL, *bname = NULL, *str = NULL, *saveptr = NULL;
+ inode_t *inode = NULL, *parent = NULL;
- parent = inode_ref (table->root);
- str = tmp = gf_strdup (path);
+ if ((path == NULL) || (table == NULL)) {
+ goto out;
+ }
- while (1) {
- bname = strtok_r (str, "/", &saveptr);
- if (bname == NULL) {
- break;
- }
+ parent = inode_ref(table->root);
+ str = tmp = gf_strdup(path);
+ if (str == NULL) {
+ goto out;
+ }
- if (inode != NULL) {
- inode_unref (inode);
- }
+ while (1) {
+ bname = strtok_r(str, "/", &saveptr);
+ if (bname == NULL) {
+ break;
+ }
- inode = inode_grep (table, parent, bname);
- if (inode == NULL) {
- break;
- }
+ if (inode != NULL) {
+ inode_unref(inode);
+ }
- if (parent != NULL) {
- inode_unref (parent);
- }
+ inode = inode_grep(table, parent, bname);
+ if (inode == NULL) {
+ break;
+ }
- parent = inode_ref (inode);
- str = NULL;
+ if (parent != NULL) {
+ inode_unref(parent);
}
- inode_unref (parent);
- GF_FREE (tmp);
+ parent = inode_ref(inode);
+ str = NULL;
+ }
+
+ inode_unref(parent);
+ GF_FREE(tmp);
out:
- return inode;
+ 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_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "table || parent || name"
- " not found");
- return ret;
- }
+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;
- pthread_mutex_lock (&table->lock);
- {
- dentry = __dentry_grep (table, parent, name);
+ if (!table || !parent || !name) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "table || parent || name"
+ " not found");
+ return ret;
+ }
- if (dentry)
- inode = dentry->inode;
+ int hash = hash_dentry(parent, name, table->hashsize);
- if (inode) {
- gf_uuid_copy (gfid, inode->gfid);
- *type = inode->ia_type;
- ret = 0;
- }
+ pthread_mutex_lock(&table->lock);
+ {
+ dentry = __dentry_grep(table, parent, name, hash);
+ if (dentry) {
+ inode = dentry->inode;
+ if (inode) {
+ gf_uuid_copy(gfid, inode->gfid);
+ *type = inode->ia_type;
+ ret = 0;
+ }
}
- pthread_mutex_unlock (&table->lock);
+ }
+ pthread_mutex_unlock(&table->lock);
- return ret;
+ return ret;
}
-
/* return 1 if gfid is of root, 0 if not */
gf_boolean_t
-__is_root_gfid (uuid_t gfid)
+__is_root_gfid(uuid_t gfid)
{
- uuid_t root;
-
- memset (root, 0, 16);
- root[15] = 1;
+ static uuid_t root = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
- if (gf_uuid_compare (gfid, root) == 0)
- return _gf_true;
+ if (gf_uuid_compare(gfid, root) == 0)
+ return _gf_true;
- return _gf_false;
+ return _gf_false;
}
-
inode_t *
-__inode_find (inode_table_t *table, uuid_t gfid)
+__inode_find(inode_table_t *table, uuid_t gfid, const int hash)
{
- inode_t *inode = NULL;
- inode_t *tmp = NULL;
- int hash = 0;
+ inode_t *inode = NULL;
+ inode_t *tmp = NULL;
- if (!table) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_TABLE_NOT_FOUND, "table not "
- "found");
- goto out;
- }
+ if (__is_root_gfid(gfid))
+ return table->root;
- if (__is_root_gfid (gfid))
- return table->root;
-
- hash = hash_gfid (gfid, 65536);
-
- list_for_each_entry (tmp, &table->inode_hash[hash], hash) {
- if (gf_uuid_compare (tmp->gfid, gfid) == 0) {
- inode = tmp;
- break;
- }
+ list_for_each_entry(tmp, &table->inode_hash[hash], hash)
+ {
+ if (gf_uuid_compare(tmp->gfid, gfid) == 0) {
+ inode = tmp;
+ break;
}
+ }
-out:
- return inode;
+ return inode;
}
-
inode_t *
-inode_find (inode_table_t *table, uuid_t gfid)
+inode_find(inode_table_t *table, uuid_t gfid)
{
- inode_t *inode = NULL;
+ inode_t *inode = NULL;
- if (!table) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_TABLE_NOT_FOUND, "table not "
- "found");
- return NULL;
- }
+ if (!table) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_INODE_TABLE_NOT_FOUND,
+ "table not "
+ "found");
+ return NULL;
+ }
- pthread_mutex_lock (&table->lock);
- {
- inode = __inode_find (table, gfid);
- if (inode)
- __inode_ref (inode);
- }
- pthread_mutex_unlock (&table->lock);
+ int hash = hash_gfid(gfid, 65536);
- return inode;
-}
+ pthread_mutex_lock(&table->lock);
+ {
+ inode = __inode_find(table, gfid, hash);
+ if (inode)
+ __inode_ref(inode, false);
+ }
+ pthread_mutex_unlock(&table->lock);
+ return inode;
+}
static inode_t *
-__inode_link (inode_t *inode, inode_t *parent, const char *name,
- struct iatt *iatt)
+__inode_link(inode_t *inode, inode_t *parent, const char *name,
+ struct iatt *iatt, const int dhash)
{
- dentry_t *dentry = NULL;
- dentry_t *old_dentry = NULL;
- inode_t *old_inode = NULL;
- inode_table_t *table = NULL;
- inode_t *link_inode = NULL;
+ dentry_t *dentry = NULL;
+ dentry_t *old_dentry = NULL;
+ inode_t *old_inode = NULL;
+ inode_table_t *table = NULL;
+ inode_t *link_inode = NULL;
+ char link_uuid_str[64] = {0}, parent_uuid_str[64] = {0};
- if (!inode)
- return NULL;
-
- table = inode->table;
- if (!table)
- return NULL;
+ table = inode->table;
- 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");
- }
+ 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) {
+ errno = EINVAL;
+ GF_ASSERT(!"link attempted b/w inodes of diff table");
+ }
- if (parent->ia_type != IA_IFDIR) {
- GF_ASSERT (!"link attempted on non-directory parent");
- return NULL;
- }
+ if (parent->ia_type != IA_IFDIR) {
+ errno = EINVAL;
+ GF_ASSERT(!"link attempted on non-directory parent");
+ return NULL;
+ }
- if (!name || strlen (name) == 0) {
- GF_ASSERT (!"link attempted with no basename on "
+ if (!name || strlen(name) == 0) {
+ errno = EINVAL;
+ GF_ASSERT (!"link attempted with no basename on "
"parent");
- return NULL;
- }
+ return NULL;
}
+ }
- link_inode = inode;
+ link_inode = inode;
- if (!__is_inode_hashed (inode)) {
- if (!iatt)
- return NULL;
+ if (!__is_inode_hashed(inode)) {
+ if (!iatt) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (gf_uuid_is_null(iatt->ia_gfid)) {
+ errno = EINVAL;
+ return NULL;
+ }
- if (gf_uuid_is_null (iatt->ia_gfid))
- return NULL;
+ int ihash = hash_gfid(iatt->ia_gfid, 65536);
- old_inode = __inode_find (table, iatt->ia_gfid);
+ old_inode = __inode_find(table, iatt->ia_gfid, ihash);
- if (old_inode) {
- link_inode = old_inode;
- } else {
- gf_uuid_copy (inode->gfid, iatt->ia_gfid);
- inode->ia_type = iatt->ia_type;
- __inode_hash (inode);
- }
+ if (old_inode) {
+ link_inode = old_inode;
} else {
- /* @old_inode serves another important purpose - it indicates
- to the code further below whether a dentry cycle check is
- required or not (a new inode linkage can never result in
- creation of a loop.)
-
- if the given @inode is already hashed, it actually means
- it is an "old" inode and deserves to undergo the cyclic
- check.
- */
- old_inode = inode;
- }
+ gf_uuid_copy(inode->gfid, iatt->ia_gfid);
+ inode->ia_type = iatt->ia_type;
+ __inode_hash(inode, ihash);
+ }
+ } else {
+ /* @old_inode serves another important purpose - it indicates
+ to the code further below whether a dentry cycle check is
+ required or not (a new inode linkage can never result in
+ creation of a loop.)
+
+ if the given @inode is already hashed, it actually means
+ it is an "old" inode and deserves to undergo the cyclic
+ check.
+ */
+ old_inode = inode;
+ }
+
+ if (name && (!strcmp(name, ".") || !strcmp(name, ".."))) {
+ return link_inode;
+ }
+
+ /* use only link_inode beyond this point */
+ if (parent) {
+ old_dentry = __dentry_grep(table, parent, name, dhash);
+
+ if (!old_dentry || old_dentry->inode != link_inode) {
+ dentry = dentry_create(link_inode, parent, name);
+ if (!dentry) {
+ gf_msg_callingfn(THIS->name, GF_LOG_ERROR, 0,
+ LG_MSG_DENTRY_CREATE_FAILED,
+ "dentry create failed on "
+ "inode %s with parent %s",
+ uuid_utoa_r(link_inode->gfid, link_uuid_str),
+ uuid_utoa_r(parent->gfid, parent_uuid_str));
+ errno = ENOMEM;
+ return NULL;
+ }
- if (name) {
- if (!strcmp(name, ".") || !strcmp(name, ".."))
- return link_inode;
+ /* dentry linking needs to happen inside lock */
+ dentry->parent = __inode_ref(parent, false);
+ list_add(&dentry->inode_list, &link_inode->dentry_list);
- if (strchr (name, '/')) {
- GF_ASSERT (!"inode link attempted with '/' in name");
- return NULL;
- }
- }
+ if (old_inode && __is_dentry_cyclic(dentry)) {
+ errno = ELOOP;
+ dentry_destroy(__dentry_unset(dentry));
+ return NULL;
+ }
+ __dentry_hash(dentry, dhash);
- /* 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_msg_callingfn (THIS->name, GF_LOG_ERROR, 0,
- LG_MSG_DENTRY_CREATE_FAILED,
- "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;
- }
- __dentry_hash (dentry);
-
- if (old_dentry)
- __dentry_unset (old_dentry);
- }
+ if (old_dentry)
+ dentry_destroy(__dentry_unset(old_dentry));
}
+ }
- return link_inode;
+ return link_inode;
}
-
inode_t *
-inode_link (inode_t *inode, inode_t *parent, const char *name,
- struct iatt *iatt)
+inode_link(inode_t *inode, inode_t *parent, const char *name, struct iatt *iatt)
{
- inode_table_t *table = NULL;
- inode_t *linked_inode = NULL;
+ int hash = 0;
+ inode_table_t *table = NULL;
+ inode_t *linked_inode = NULL;
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return NULL;
- }
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return NULL;
+ }
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- linked_inode = __inode_link (inode, parent, name, iatt);
+ if (parent && name) {
+ hash = hash_dentry(parent, name, table->hashsize);
+ }
- if (linked_inode)
- __inode_ref (linked_inode);
- }
- pthread_mutex_unlock (&table->lock);
+ if (name && strchr(name, '/')) {
+ GF_ASSERT(!"inode link attempted with '/' in name");
+ return NULL;
+ }
+
+ pthread_mutex_lock(&table->lock);
+ {
+ linked_inode = __inode_link(inode, parent, name, iatt, hash);
+ if (linked_inode)
+ __inode_ref(linked_inode, false);
+ }
+ pthread_mutex_unlock(&table->lock);
- inode_table_prune (table);
+ inode_table_prune(table);
- return linked_inode;
+ return linked_inode;
}
+int
+inode_lookup(inode_t *inode)
+{
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return -1;
+ }
+
+ GF_ATOMIC_INC(inode->nlookup);
+
+ return 0;
+}
int
-inode_lookup (inode_t *inode)
+inode_ref_reduce_by_n(inode_t *inode, uint64_t nref)
{
- inode_table_t *table = NULL;
+ inode_table_t *table = NULL;
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return -1;
- }
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return -1;
+ }
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- __inode_lookup (inode);
- }
- pthread_mutex_unlock (&table->lock);
+ pthread_mutex_lock(&table->lock);
+ {
+ __inode_ref_reduce_by_n(inode, nref);
+ }
+ pthread_mutex_unlock(&table->lock);
- return 0;
-}
+ inode_table_prune(table);
+ return 0;
+}
int
-inode_ref_reduce_by_n (inode_t *inode, uint64_t nref)
+inode_forget(inode_t *inode, uint64_t nlookup)
{
- inode_table_t *table = NULL;
+ inode_table_t *table = NULL;
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return -1;
- }
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return -1;
+ }
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- __inode_ref_reduce_by_n (inode, nref);
- }
- pthread_mutex_unlock (&table->lock);
+ inode_forget_atomic(inode, nlookup);
- inode_table_prune (table);
+ inode_table_prune(table);
- return 0;
+ return 0;
}
-
int
-inode_forget (inode_t *inode, uint64_t nlookup)
+inode_forget_with_unref(inode_t *inode, uint64_t nlookup)
{
- inode_table_t *table = NULL;
+ inode_table_t *table = NULL;
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return -1;
- }
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return -1;
+ }
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- __inode_forget (inode, nlookup);
- }
- pthread_mutex_unlock (&table->lock);
+ pthread_mutex_lock(&table->lock);
+ {
+ inode_forget_atomic(inode, nlookup);
+ __inode_unref(inode, true);
+ }
+ pthread_mutex_unlock(&table->lock);
- inode_table_prune (table);
+ inode_table_prune(table);
- return 0;
+ return 0;
}
/*
- * Invalidate an inode. This is invoked when a translator decides that an inode's
- * cache is no longer valid. Any translator interested in taking action in this
- * situation can define the invalidate callback.
+ * Invalidate an inode. This is invoked when a translator decides that an
+ * inode's cache is no longer valid. Any translator interested in taking action
+ * in this situation can define the invalidate callback.
*/
int
inode_invalidate(inode_t *inode)
{
- int ret = 0;
- xlator_t *xl = NULL;
- xlator_t *old_THIS = NULL;
-
- if (!inode) {
- gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return -1;
- }
-
- /*
- * The master xlator is not in the graph but it can define an invalidate
- * handler.
- */
- xl = inode->table->xl->ctx->master;
- if (xl && xl->cbks->invalidate) {
- old_THIS = THIS;
- THIS = xl;
- ret = xl->cbks->invalidate(xl, inode);
- THIS = old_THIS;
- if (ret)
- return ret;
- }
+ int ret = 0;
+ xlator_t *xl = NULL;
+ xlator_t *old_THIS = NULL;
+
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return -1;
+ }
+
+ /*
+ * The master xlator is not in the graph but it can define an invalidate
+ * handler.
+ */
+ xl = inode->table->xl->ctx->master;
+ if (xl && xl->cbks->invalidate) {
+ old_THIS = THIS;
+ THIS = xl;
+ ret = xl->cbks->invalidate(xl, inode);
+ THIS = old_THIS;
+ if (ret)
+ return ret;
+ }
- xl = inode->table->xl->graph->first;
- while (xl) {
- old_THIS = THIS;
- THIS = xl;
- if (xl->cbks->invalidate)
- ret = xl->cbks->invalidate(xl, inode);
- THIS = old_THIS;
+ xl = inode->table->xl->graph->first;
+ while (xl) {
+ old_THIS = THIS;
+ THIS = xl;
+ if (xl->cbks->invalidate)
+ ret = xl->cbks->invalidate(xl, inode);
+ THIS = old_THIS;
- if (ret)
- break;
+ if (ret)
+ break;
- xl = xl->next;
- }
+ xl = xl->next;
+ }
- return ret;
+ return ret;
}
-
-static void
-__inode_unlink (inode_t *inode, inode_t *parent, const char *name)
+static dentry_t *
+__inode_unlink(inode_t *inode, inode_t *parent, const char *name)
{
- dentry_t *dentry = NULL;
- char pgfid[64] = {0};
- char gfid[64] = {0};
-
- if (!inode || !parent || !name)
- return;
+ dentry_t *dentry = NULL;
+ char pgfid[64] = {0};
+ char gfid[64] = {0};
- dentry = __dentry_search_for_inode (inode, parent->gfid, name);
+ dentry = __dentry_search_for_inode(inode, parent->gfid, name);
- /* dentry NULL for corrupted backend */
- if (dentry) {
- __dentry_unset (dentry);
- } else {
- gf_msg ("inode", GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND,
- "%s/%s: dentry not found in %s",
- uuid_utoa_r (parent->gfid, pgfid), name,
- uuid_utoa_r (inode->gfid, gfid));
- }
+ /* dentry NULL for corrupted backend */
+ if (dentry) {
+ dentry = __dentry_unset(dentry);
+ } else {
+ gf_smsg("inode", GF_LOG_WARNING, 0, LG_MSG_DENTRY_NOT_FOUND,
+ "parent-gfid=%s name=%s gfid%s",
+ uuid_utoa_r(parent->gfid, pgfid), name,
+ uuid_utoa_r(inode->gfid, gfid), NULL);
+ }
+ return dentry;
}
-
void
-inode_unlink (inode_t *inode, inode_t *parent, const char *name)
+inode_unlink(inode_t *inode, inode_t *parent, const char *name)
{
- inode_table_t *table = NULL;
+ inode_table_t *table;
+ dentry_t *dentry;
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return;
- }
+ if (!inode || !parent || !name)
+ return;
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- __inode_unlink (inode, parent, name);
- }
- pthread_mutex_unlock (&table->lock);
+ pthread_mutex_lock(&table->lock);
+ {
+ dentry = __inode_unlink(inode, parent, name);
+ }
+ pthread_mutex_unlock(&table->lock);
- inode_table_prune (table);
-}
+ dentry_destroy(dentry);
+ inode_table_prune(table);
+}
int
-inode_rename (inode_table_t *table, inode_t *srcdir, const char *srcname,
- inode_t *dstdir, const char *dstname, inode_t *inode,
- struct iatt *iatt)
-{
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return -1;
- }
+inode_rename(inode_table_t *table, inode_t *srcdir, const char *srcname,
+ inode_t *dstdir, const char *dstname, inode_t *inode,
+ struct iatt *iatt)
+{
+ int hash = 0;
+ dentry_t *dentry = NULL;
- table = inode->table;
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return -1;
+ }
- pthread_mutex_lock (&table->lock);
- {
- __inode_link (inode, dstdir, dstname, iatt);
- __inode_unlink (inode, srcdir, srcname);
- }
- pthread_mutex_unlock (&table->lock);
+ table = inode->table;
- inode_table_prune (table);
+ if (dstname && strchr(dstname, '/')) {
+ GF_ASSERT(!"inode link attempted with '/' in name");
+ return -1;
+ }
- return 0;
-}
+ if (dstdir && dstname) {
+ hash = hash_dentry(dstdir, dstname, table->hashsize);
+ }
+
+ pthread_mutex_lock(&table->lock);
+ {
+ __inode_link(inode, dstdir, dstname, iatt, hash);
+ /* pick the old dentry */
+ dentry = __inode_unlink(inode, srcdir, srcname);
+ }
+ pthread_mutex_unlock(&table->lock);
+
+ /* free the old dentry */
+ dentry_destroy(dentry);
+
+ inode_table_prune(table);
+ return 0;
+}
static dentry_t *
-__dentry_search_arbit (inode_t *inode)
+__dentry_search_arbit(inode_t *inode)
{
- dentry_t *dentry = NULL;
- dentry_t *trav = NULL;
+ dentry_t *dentry = NULL;
+ dentry_t *trav = NULL;
- if (!inode)
- return NULL;
+ if (!inode)
+ return NULL;
- list_for_each_entry (trav, &inode->dentry_list, inode_list) {
- if (__is_dentry_hashed (trav)) {
- dentry = trav;
- break;
- }
+ list_for_each_entry(trav, &inode->dentry_list, inode_list)
+ {
+ if (__is_dentry_hashed(trav)) {
+ dentry = trav;
+ break;
}
+ }
- if (!dentry) {
- list_for_each_entry (trav, &inode->dentry_list, inode_list) {
- dentry = trav;
- break;
- }
+ if (!dentry) {
+ list_for_each_entry(trav, &inode->dentry_list, inode_list)
+ {
+ dentry = trav;
+ break;
}
+ }
- return dentry;
+ return dentry;
}
-
inode_t *
-inode_parent (inode_t *inode, uuid_t pargfid, 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;
+ inode_t *parent = NULL;
+ inode_table_t *table = NULL;
+ dentry_t *dentry = NULL;
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return NULL;
- }
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return NULL;
+ }
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- if (pargfid && !gf_uuid_is_null (pargfid) && name) {
- dentry = __dentry_search_for_inode (inode, pargfid, name);
- } else {
- dentry = __dentry_search_arbit (inode);
- }
+ pthread_mutex_lock(&table->lock);
+ {
+ if (pargfid && !gf_uuid_is_null(pargfid) && name) {
+ dentry = __dentry_search_for_inode(inode, pargfid, name);
+ } else {
+ dentry = __dentry_search_arbit(inode);
+ }
- if (dentry)
- parent = dentry->parent;
+ if (dentry)
+ parent = dentry->parent;
- if (parent)
- __inode_ref (parent);
- }
- pthread_mutex_unlock (&table->lock);
+ if (parent)
+ __inode_ref(parent, false);
+ }
+ pthread_mutex_unlock(&table->lock);
- return parent;
+ return parent;
}
static int
-__inode_has_dentry (inode_t *inode)
+__inode_has_dentry(inode_t *inode)
{
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return 0;
- }
-
- return !list_empty (&inode->dentry_list);
+ return !list_empty(&inode->dentry_list);
}
int
-inode_has_dentry (inode_t *inode)
+inode_has_dentry(inode_t *inode)
{
+ int dentry_present = 0;
- int dentry_present = 0;
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return 0;
+ }
- LOCK (&inode->lock);
- {
- dentry_present = __inode_has_dentry (inode);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ dentry_present = __inode_has_dentry(inode);
+ }
+ UNLOCK(&inode->lock);
- return dentry_present;
+ return dentry_present;
}
int
-__inode_path (inode_t *inode, const char *name, char **bufp)
-{
- inode_table_t *table = NULL;
- 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 || gf_uuid_is_null (inode->gfid)) {
- GF_ASSERT (0);
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, EINVAL,
- LG_MSG_INVALID_ARG, "invalid inode");
- return -EINVAL;
- }
+__inode_path(inode_t *inode, const char *name, char **bufp)
+{
+ inode_table_t *table = NULL;
+ 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 || gf_uuid_is_null(inode->gfid)) {
+ GF_ASSERT(0);
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid inode");
+ return -EINVAL;
+ }
+
+ table = inode->table;
+
+ 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_smsg(table->name, GF_LOG_CRITICAL, 0, LG_MSG_DENTRY_CYCLIC_LOOP,
+ "name=%s", name, NULL);
+ ret = -ENOENT;
+ goto out;
+ }
+ }
+
+ if (!__is_root_gfid(itrav->gfid)) {
+ /* "<gfid:00000000-0000-0000-0000-000000000000>"/path */
+ i += GFID_STR_PFX_LEN;
+ }
+
+ if (name) {
+ i++;
+ i += strlen(name);
+ }
+
+ ret = i;
+ size = i + 1;
+ buf = GF_CALLOC(size, sizeof(char), gf_common_mt_char);
+ if (buf) {
+ buf[size - 1] = 0;
- table = inode->table;
+ if (name) {
+ len = strlen(name);
+ memcpy(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;
- i ++; /* "/" */
- i += strlen (trav->name);
- if (i > PATH_MAX) {
- gf_msg (table->name, GF_LOG_CRITICAL, 0,
- LG_MSG_DENTRY_CYCLIC_LOOP, "possible infinite "
- "loop detected, forcing break. name=(%s)",
- name);
- ret = -ENOENT;
- goto out;
- }
+ for (trav = __dentry_search_arbit(itrav); trav;
+ trav = __dentry_search_arbit(itrav)) {
+ itrav = trav->parent;
+ len = strlen(trav->name);
+ memcpy(buf + (i - len), trav->name, len);
+ buf[i - len - 1] = '/';
+ i -= (len + 1);
}
- if (!__is_root_gfid (itrav->gfid)) {
- /* "<gfid:00000000-0000-0000-0000-000000000000>"/path */
- i += GFID_STR_PFX_LEN;
+ 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] = '>';
}
- if (name) {
- i++;
- i += strlen (name);
- }
+ *bufp = buf;
+ } else {
+ ret = -ENOMEM;
+ }
- ret = i;
- size = i + 1;
- buf = GF_CALLOC (size, sizeof (char), gf_common_mt_char);
+out:
+ if (__is_root_gfid(inode->gfid) && !name) {
+ ret = 1;
+ GF_FREE(buf);
+ buf = GF_CALLOC(ret + 1, sizeof(char), gf_common_mt_char);
if (buf) {
-
- buf[size - 1] = 0;
-
- 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;
+ strcpy(buf, "/");
+ *bufp = buf;
} else {
- ret = -ENOMEM;
- }
-
-out:
- if (__is_root_gfid (inode->gfid) && !name) {
- ret = 1;
- GF_FREE (buf);
- buf = GF_CALLOC (ret + 1, sizeof (char), gf_common_mt_char);
- if (buf) {
- strcpy (buf, "/");
- *bufp = buf;
- } else {
- ret = -ENOMEM;
- }
+ ret = -ENOMEM;
}
+ }
- if (ret < 0)
- *bufp = NULL;
- return ret;
+ if (ret < 0)
+ *bufp = NULL;
+ return ret;
}
-
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;
- int ret = -1;
+ inode_table_t *table = NULL;
+ int ret = -1;
- if (!inode)
- return -EINVAL;
+ if (!inode)
+ return -EINVAL;
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- ret = __inode_path (inode, name, bufp);
- }
- pthread_mutex_unlock (&table->lock);
+ pthread_mutex_lock(&table->lock);
+ {
+ ret = __inode_path(inode, name, bufp);
+ }
+ pthread_mutex_unlock(&table->lock);
- return ret;
+ return ret;
}
void
-__inode_table_set_lru_limit (inode_table_t *table, uint32_t lru_limit)
+__inode_table_set_lru_limit(inode_table_t *table, uint32_t lru_limit)
{
- table->lru_limit = lru_limit;
- return;
+ table->lru_limit = lru_limit;
+ return;
}
-
void
-inode_table_set_lru_limit (inode_table_t *table, uint32_t lru_limit)
+inode_table_set_lru_limit(inode_table_t *table, uint32_t lru_limit)
{
- pthread_mutex_lock (&table->lock);
- {
- __inode_table_set_lru_limit (table, lru_limit);
- }
- pthread_mutex_unlock (&table->lock);
+ pthread_mutex_lock(&table->lock);
+ {
+ __inode_table_set_lru_limit(table, lru_limit);
+ }
+ pthread_mutex_unlock(&table->lock);
- inode_table_prune (table);
+ inode_table_prune(table);
- return;
+ return;
}
static int
-inode_table_prune (inode_table_t *table)
-{
- int ret = 0;
- struct list_head purge = {0, };
- inode_t *del = NULL;
- inode_t *tmp = NULL;
- inode_t *entry = NULL;
-
- if (!table)
- return -1;
-
- INIT_LIST_HEAD (&purge);
-
- pthread_mutex_lock (&table->lock);
- {
- while (table->lru_limit
- && table->lru_size > (table->lru_limit)) {
-
- entry = list_entry (table->lru.next, inode_t, list);
-
- table->lru_size--;
- __inode_retire (entry);
-
- ret++;
+inode_table_prune(inode_table_t *table)
+{
+ int ret = 0;
+ int ret1 = 0;
+ struct list_head purge = {
+ 0,
+ };
+ inode_t *del = NULL;
+ inode_t *tmp = NULL;
+ inode_t *entry = NULL;
+ uint64_t nlookup = 0;
+ int64_t lru_size = 0;
+
+ if (!table)
+ return -1;
+
+ INIT_LIST_HEAD(&purge);
+
+ pthread_mutex_lock(&table->lock);
+ {
+ if (!table->lru_limit)
+ goto purge_list;
+
+ lru_size = table->lru_size;
+ while (lru_size > (table->lru_limit)) {
+ if (list_empty(&table->lru)) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_INVALID_INODE_LIST,
+ "Empty inode lru list found"
+ " but with (%d) lru_size",
+ table->lru_size);
+ break;
+ }
+
+ lru_size--;
+ entry = list_entry(table->lru.next, inode_t, list);
+ /* The logic of invalidation is required only if invalidator_fn
+ is present */
+ if (table->invalidator_fn) {
+ /* check for valid inode with 'nlookup' */
+ nlookup = GF_ATOMIC_GET(entry->nlookup);
+ if (nlookup) {
+ if (entry->invalidate_sent) {
+ list_move_tail(&entry->list, &table->lru);
+ continue;
+ }
+ __inode_ref(entry, true);
+ tmp = entry;
+ break;
}
-
- list_splice_init (&table->purge, &purge);
- table->purge_size = 0;
- }
- pthread_mutex_unlock (&table->lock);
-
+ }
+
+ table->lru_size--;
+ __inode_retire(entry);
+ ret++;
+ }
+
+ purge_list:
+ list_splice_init(&table->purge, &purge);
+ table->purge_size = 0;
+ }
+ pthread_mutex_unlock(&table->lock);
+
+ /* Pick 1 inode for invalidation */
+ if (tmp) {
+ xlator_t *old_THIS = THIS;
+ THIS = table->invalidator_xl;
+ ret1 = table->invalidator_fn(table->invalidator_xl, tmp);
+ THIS = old_THIS;
+ pthread_mutex_lock(&table->lock);
{
- list_for_each_entry_safe (del, tmp, &purge, list) {
- list_del_init (&del->list);
- __inode_forget (del, 0);
- __inode_destroy (del);
- }
+ if (!ret1) {
+ tmp->invalidate_sent = true;
+ __inode_unref(tmp, false);
+ } else {
+ /* Move this back to the lru list*/
+ __inode_unref(tmp, true);
+ }
}
+ pthread_mutex_unlock(&table->lock);
+ }
- return ret;
-}
+ /* Just so that if purge list is handled too, then clear it off */
+ list_for_each_entry_safe(del, tmp, &purge, list)
+ {
+ list_del_init(&del->list);
+ inode_forget_atomic(del, 0);
+ __inode_destroy(del);
+ }
+ return ret;
+}
static void
-__inode_table_init_root (inode_table_t *table)
+__inode_table_init_root(inode_table_t *table)
{
- inode_t *root = NULL;
- struct iatt iatt = {0, };
+ inode_t *root = NULL;
+ struct iatt iatt = {
+ 0,
+ };
+
+ if (!table)
+ return;
- if (!table)
- return;
+ root = inode_create(table);
- root = __inode_create (table);
+ list_add(&root->list, &table->lru);
+ table->lru_size++;
- iatt.ia_gfid[15] = 1;
- iatt.ia_ino = 1;
- iatt.ia_type = IA_IFDIR;
+ iatt.ia_gfid[15] = 1;
+ iatt.ia_ino = 1;
+ iatt.ia_type = IA_IFDIR;
- __inode_link (root, NULL, NULL, &iatt);
- table->root = root;
+ __inode_link(root, NULL, NULL, &iatt, 0);
+ table->root = root;
}
-
inode_table_t *
-inode_table_new (size_t lru_limit, xlator_t *xl)
+inode_table_with_invalidator(uint32_t lru_limit, xlator_t *xl,
+ int32_t (*invalidator_fn)(xlator_t *, inode_t *),
+ xlator_t *invalidator_xl)
{
- inode_table_t *new = NULL;
- int ret = -1;
- int i = 0;
+ inode_table_t *new = NULL;
+ uint32_t mem_pool_size = lru_limit;
+ int ret = -1;
+ int i = 0;
- new = (void *)GF_CALLOC(1, sizeof (*new), gf_common_mt_inode_table_t);
- if (!new)
- return NULL;
-
- new->xl = xl;
- new->ctxcount = xl->graph->xl_count + 1;
+ new = (void *)GF_CALLOC(1, sizeof(*new), gf_common_mt_inode_table_t);
+ if (!new)
+ return NULL;
- new->lru_limit = lru_limit;
+ new->xl = xl;
+ new->ctxcount = xl->graph->xl_count + 1;
- new->hashsize = 14057; /* TODO: Random Number?? */
+ new->lru_limit = lru_limit;
+ new->invalidator_fn = invalidator_fn;
+ new->invalidator_xl = invalidator_xl;
- /* In case FUSE is initing the inode table. */
- if (lru_limit == 0)
- lru_limit = DEFAULT_INODE_MEMPOOL_ENTRIES;
+ new->hashsize = 14057; /* TODO: Random Number?? */
- new->inode_pool = mem_pool_new (inode_t, lru_limit);
+ /* In case FUSE is initing the inode table. */
+ if (!mem_pool_size || (mem_pool_size > DEFAULT_INODE_MEMPOOL_ENTRIES))
+ mem_pool_size = DEFAULT_INODE_MEMPOOL_ENTRIES;
- if (!new->inode_pool)
- goto out;
+ new->inode_pool = mem_pool_new(inode_t, mem_pool_size);
+ if (!new->inode_pool)
+ goto out;
- new->dentry_pool = mem_pool_new (dentry_t, lru_limit);
+ new->dentry_pool = mem_pool_new(dentry_t, mem_pool_size);
+ if (!new->dentry_pool)
+ goto out;
- 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)
+ goto out;
- new->inode_hash = (void *)GF_CALLOC (65536,
- sizeof (struct list_head),
- gf_common_mt_list_head);
- 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)
+ goto out;
- new->name_hash = (void *)GF_CALLOC (new->hashsize,
- sizeof (struct list_head),
- gf_common_mt_list_head);
- if (!new->name_hash)
- goto out;
+ /* 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 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)
+ goto out;
- if (!new->fd_mem_pool)
- goto out;
-
- for (i = 0; i < 65536; i++) {
- INIT_LIST_HEAD (&new->inode_hash[i]);
- }
+ for (i = 0; i < 65536; i++) {
+ INIT_LIST_HEAD(&new->inode_hash[i]);
+ }
+ for (i = 0; i < new->hashsize; i++) {
+ INIT_LIST_HEAD(&new->name_hash[i]);
+ }
- for (i = 0; i < new->hashsize; i++) {
- INIT_LIST_HEAD (&new->name_hash[i]);
- }
+ INIT_LIST_HEAD(&new->active);
+ INIT_LIST_HEAD(&new->lru);
+ INIT_LIST_HEAD(&new->purge);
+ INIT_LIST_HEAD(&new->invalidate);
- INIT_LIST_HEAD (&new->active);
- INIT_LIST_HEAD (&new->lru);
- INIT_LIST_HEAD (&new->purge);
+ ret = gf_asprintf(&new->name, "%s/inode", xl->name);
+ if (-1 == ret) {
+ /* TODO: This should be ok to continue, check with avati */
+ ;
+ }
- ret = gf_asprintf (&new->name, "%s/inode", xl->name);
- if (-1 == ret) {
- /* TODO: This should be ok to continue, check with avati */
- ;
- }
+ new->cleanup_started = _gf_false;
- __inode_table_init_root (new);
+ __inode_table_init_root(new);
- pthread_mutex_init (&new->lock, NULL);
+ pthread_mutex_init(&new->lock, NULL);
- ret = 0;
+ ret = 0;
out:
- if (ret) {
- if (new) {
- GF_FREE (new->inode_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;
- }
+ if (ret) {
+ if (new) {
+ GF_FREE(new->inode_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;
+}
- return new;
+inode_table_t *
+inode_table_new(uint32_t lru_limit, xlator_t *xl)
+{
+ /* Only fuse for now requires the inode table with invalidator */
+ return inode_table_with_invalidator(lru_limit, xl, NULL, NULL);
}
int
-inode_table_ctx_free (inode_table_t *table)
+inode_table_ctx_free(inode_table_t *table)
{
- int ret = 0;
- inode_t *del = NULL;
- inode_t *tmp = NULL;
- int purge_count = 0;
- int lru_count = 0;
- int active_count = 0;
- xlator_t *this = NULL;
- int itable_size = 0;
+ int ret = 0;
+ inode_t *del = NULL;
+ inode_t *tmp = NULL;
+ int purge_count = 0;
+ int lru_count = 0;
+ int active_count = 0;
+ xlator_t *this = NULL;
+ int itable_size = 0;
- if (!table)
- return -1;
+ if (!table)
+ return -1;
- this = THIS;
+ this = THIS;
- pthread_mutex_lock (&table->lock);
+ pthread_mutex_lock(&table->lock);
+ {
+ list_for_each_entry_safe(del, tmp, &table->purge, list)
{
- list_for_each_entry_safe (del, tmp, &table->purge, list) {
- if (del->_ctx) {
- __inode_ctx_free (del);
- purge_count++;
- }
- }
-
- list_for_each_entry_safe (del, tmp, &table->lru, list) {
- if (del->_ctx) {
- __inode_ctx_free (del);
- lru_count++;
- }
- }
+ if (del->_ctx) {
+ __inode_ctx_free(del);
+ purge_count++;
+ }
+ }
- /* should the contexts of active inodes be freed?
- * Since before this function being called fds would have
- * been migrated and would have held the ref on the new
- * inode from the new inode table, the older inode would not
- * be used.
- */
- list_for_each_entry_safe (del, tmp, &table->active, list) {
- if (del->_ctx) {
- __inode_ctx_free (del);
- active_count++;
- }
- }
+ list_for_each_entry_safe(del, tmp, &table->lru, list)
+ {
+ if (del->_ctx) {
+ __inode_ctx_free(del);
+ lru_count++;
+ }
}
- pthread_mutex_unlock (&table->lock);
-
- ret = purge_count + lru_count + active_count;
- itable_size = table->active_size + table->lru_size + table->purge_size;
- gf_msg_callingfn (this->name, GF_LOG_INFO, 0,
- LG_MSG_INODE_CONTEXT_FREED, "total %d (itable size: "
- "%d) inode contexts have been freed (active: %d, ("
- "active size: %d), lru: %d, (lru size: %d), purge: "
- "%d, (purge size: %d))", ret, itable_size,
- active_count, table->active_size, lru_count,
- table->lru_size, purge_count, table->purge_size);
- return ret;
+
+ /* should the contexts of active inodes be freed?
+ * Since before this function being called fds would have
+ * been migrated and would have held the ref on the new
+ * inode from the new inode table, the older inode would not
+ * be used.
+ */
+ list_for_each_entry_safe(del, tmp, &table->active, list)
+ {
+ if (del->_ctx) {
+ __inode_ctx_free(del);
+ active_count++;
+ }
+ }
+ }
+ pthread_mutex_unlock(&table->lock);
+
+ ret = purge_count + lru_count + active_count;
+ itable_size = table->active_size + table->lru_size + table->purge_size;
+ gf_msg_callingfn(this->name, GF_LOG_INFO, 0, LG_MSG_INODE_CONTEXT_FREED,
+ "total %d (itable size: "
+ "%d) inode contexts have been freed (active: %d, ("
+ "active size: %d), lru: %d, (lru size: %d), purge: "
+ "%d, (purge size: %d))",
+ ret, itable_size, active_count, table->active_size,
+ lru_count, table->lru_size, purge_count,
+ table->purge_size);
+ return ret;
}
void
-inode_table_destroy_all (glusterfs_ctx_t *ctx) {
-
- glusterfs_graph_t *trav_graph = NULL, *tmp = NULL;
- xlator_t *tree = NULL;
- inode_table_t *inode_table = NULL;
+inode_table_destroy_all(glusterfs_ctx_t *ctx)
+{
+ glusterfs_graph_t *trav_graph = NULL, *tmp = NULL;
+ xlator_t *tree = NULL;
+ inode_table_t *inode_table = NULL;
+
+ if (ctx == NULL)
+ goto out;
+
+ /* TODO: Traverse ctx->graphs with in ctx->lock and also the other
+ * graph additions and traversals in ctx->lock.
+ */
+ list_for_each_entry_safe(trav_graph, tmp, &ctx->graphs, list)
+ {
+ tree = trav_graph->first;
+ inode_table = tree->itable;
+ tree->itable = NULL;
+ if (inode_table)
+ inode_table_destroy(inode_table);
+ }
+out:
+ return;
+}
- if (ctx == NULL)
- goto out;
+void
+inode_table_destroy(inode_table_t *inode_table)
+{
+ inode_t *trav = NULL;
- /* TODO: Traverse ctx->graphs with in ctx->lock and also the other
- * graph additions and traversals in ctx->lock.
- */
- list_for_each_entry_safe (trav_graph, tmp, &ctx->graphs, list) {
- tree = trav_graph->first;
- inode_table = tree->itable;
- tree->itable = NULL;
- if (inode_table)
- inode_table_destroy (inode_table);
- }
- out:
+ if (inode_table == NULL)
return;
-}
-void
-inode_table_destroy (inode_table_t *inode_table) {
-
- inode_t *tmp = NULL, *trav = NULL;
-
- if (inode_table == NULL)
- return;
-
- /* Ideally at this point in time, there should be no inodes with
- * refs remaining. But there are quite a few chances where the inodes
- * leak. So we can take three approaches for cleaning up the inode table:
- * 1. Assume there are no leaks and then send a forget on all the inodes
- * in lru list.(If no leaks there should be no inodes in active list)
- * 2. Knowing there could be leaks and not freeing those inodes will
- * also not free its inode context and this could leak a lot of
- * memory, force free the inodes by changing the ref to 0.
- * The problem with this is that any reference to inode after this
- * calling this funtion will lead to a crash.
- * 3. Knowing there could be leakes, just free the inode contexts of
- * all the inodes. and let the inodes be alive. This way the major
- * memory consumed by the inode contexts are freed, but there can
- * be errors when any inode contexts are accessed after destroying
- * this table.
+ /* Ideally at this point in time, there should be no inodes with
+ * refs remaining. But there are quite a few chances where the inodes
+ * leak. So we can take three approaches for cleaning up the inode table:
+ * 1. Assume there are no leaks and then send a forget on all the inodes
+ * in lru list.(If no leaks there should be no inodes in active list)
+ * 2. Knowing there could be leaks and not freeing those inodes will
+ * also not free its inode context and this could leak a lot of
+ * memory, force free the inodes by changing the ref to 0.
+ * The problem with this is that any reference to inode after this
+ * calling this function will lead to a crash.
+ * 3. Knowing there could be leakes, just free the inode contexts of
+ * all the inodes. and let the inodes be alive. This way the major
+ * memory consumed by the inode contexts are freed, but there can
+ * be errors when any inode contexts are accessed after destroying
+ * this table.
+ *
+ * Not sure which is the approach to be taken, going by approach 2.
+ */
+
+ /* Approach 3:
+ * ret = inode_table_ctx_free (inode_table);
+ */
+ pthread_mutex_lock(&inode_table->lock);
+ {
+ inode_table->cleanup_started = _gf_true;
+ /* Process lru list first as we need to unset their dentry
+ * entries (the ones which may not be unset during
+ * '__inode_passivate' as they were hashed) which in turn
+ * shall unref their parent
*
- * Not sure which is the approach to be taken, going by approach 2.
- */
-
- /* Approach 3:
- * ret = inode_table_ctx_free (inode_table);
+ * These parent inodes when unref'ed may well again fall
+ * into lru list and if we are at the end of traversing
+ * the list, we may miss to delete/retire that entry. Hence
+ * traverse the lru list till it gets empty.
*/
- pthread_mutex_lock (&inode_table->lock);
- {
- list_for_each_entry_safe (trav, tmp, &inode_table->active, list) {
- __inode_ref_reduce_by_n (trav, 0);
- }
-
- list_for_each_entry_safe (trav, tmp, &inode_table->lru, list) {
- __inode_forget (trav, 0);
- }
- }
- pthread_mutex_unlock (&inode_table->lock);
-
- inode_table_prune (inode_table);
-
- GF_FREE (inode_table->inode_hash);
- GF_FREE (inode_table->name_hash);
- if (inode_table->dentry_pool)
- mem_pool_destroy (inode_table->dentry_pool);
- if (inode_table->inode_pool)
- mem_pool_destroy (inode_table->inode_pool);
- if (inode_table->fd_mem_pool)
- mem_pool_destroy (inode_table->fd_mem_pool);
-
- pthread_mutex_destroy (&inode_table->lock);
-
- GF_FREE (inode_table->name);
- GF_FREE (inode_table);
-
- return;
+ while (!list_empty(&inode_table->lru)) {
+ trav = list_first_entry(&inode_table->lru, inode_t, list);
+ inode_forget_atomic(trav, 0);
+ __inode_retire(trav);
+ inode_table->lru_size--;
+ }
+
+ /* Same logic for invalidate list */
+ while (!list_empty(&inode_table->invalidate)) {
+ trav = list_first_entry(&inode_table->invalidate, inode_t, list);
+ inode_forget_atomic(trav, 0);
+ __inode_retire(trav);
+ inode_table->invalidate_size--;
+ }
+
+ while (!list_empty(&inode_table->active)) {
+ trav = list_first_entry(&inode_table->active, inode_t, list);
+ /* forget and unref the inode to retire and add it to
+ * purge list. By this time there should not be any
+ * inodes present in the active list except for root
+ * inode. Its a ref_leak otherwise. */
+ if (trav && (trav != inode_table->root))
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_REF_COUNT,
+ "Active inode(%p) with refcount"
+ "(%d) found during cleanup",
+ trav, trav->ref);
+ inode_forget_atomic(trav, 0);
+ __inode_ref_reduce_by_n(trav, 0);
+ }
+ }
+ pthread_mutex_unlock(&inode_table->lock);
+
+ inode_table_prune(inode_table);
+
+ GF_FREE(inode_table->inode_hash);
+ GF_FREE(inode_table->name_hash);
+ if (inode_table->dentry_pool)
+ mem_pool_destroy(inode_table->dentry_pool);
+ if (inode_table->inode_pool)
+ mem_pool_destroy(inode_table->inode_pool);
+ if (inode_table->fd_mem_pool)
+ mem_pool_destroy(inode_table->fd_mem_pool);
+
+ pthread_mutex_destroy(&inode_table->lock);
+
+ GF_FREE(inode_table->name);
+ GF_FREE(inode_table);
+
+ return;
}
inode_t *
-inode_from_path (inode_table_t *itable, const char *path)
+inode_from_path(inode_table_t *itable, const char *path)
{
- inode_t *inode = NULL;
- inode_t *parent = NULL;
- inode_t *root = NULL;
- inode_t *curr = NULL;
- char *pathname = NULL;
- char *component = NULL, *next_component = NULL;
- char *strtokptr = NULL;
+ inode_t *inode = NULL;
+ inode_t *parent = NULL;
+ inode_t *root = NULL;
+ inode_t *curr = NULL;
+ char *pathname = NULL;
+ char *component = NULL, *next_component = NULL;
+ char *strtokptr = NULL;
- if (!itable || !path)
- return NULL;
+ if (!itable || !path)
+ return NULL;
- /* top-down approach */
- pathname = gf_strdup (path);
- if (pathname == NULL) {
- goto out;
- }
+ /* top-down approach */
+ pathname = gf_strdup(path);
+ if (pathname == NULL) {
+ goto out;
+ }
- root = itable->root;
- parent = inode_ref (root);
- component = strtok_r (pathname, "/", &strtokptr);
+ root = itable->root;
+ parent = inode_ref(root);
+ component = strtok_r(pathname, "/", &strtokptr);
- if (component == NULL)
- /* root inode */
- inode = inode_ref (parent);
+ if (component == NULL)
+ /* root inode */
+ inode = inode_ref(parent);
- while (component) {
- curr = inode_grep (itable, parent, component);
+ while (component) {
+ curr = inode_grep(itable, parent, component);
- if (curr == NULL) {
- strtok_r (NULL, "/", &strtokptr);
- break;
- }
+ if (curr == NULL) {
+ strtok_r(NULL, "/", &strtokptr);
+ break;
+ }
- next_component = strtok_r (NULL, "/", &strtokptr);
+ next_component = strtok_r(NULL, "/", &strtokptr);
- if (next_component) {
- inode_unref (parent);
- parent = curr;
- curr = NULL;
- } else {
- inode = curr;
- }
-
- component = next_component;
+ if (next_component) {
+ inode_unref(parent);
+ parent = curr;
+ curr = NULL;
+ } else {
+ inode = curr;
}
- if (parent)
- inode_unref (parent);
+ component = next_component;
+ }
+
+ if (parent)
+ inode_unref(parent);
- GF_FREE (pathname);
+ GF_FREE(pathname);
out:
- return inode;
+ return inode;
}
void
-inode_set_need_lookup (inode_t *inode, xlator_t *this)
+inode_set_need_lookup(inode_t *inode, xlator_t *this)
{
- uint64_t need_lookup = 1;
+ uint64_t need_lookup = LOOKUP_NEEDED;
- if (!inode | !this)
- return;
+ if (!inode || !this)
+ return;
- inode_ctx_set (inode, this, &need_lookup);
+ inode_ctx_set(inode, this, &need_lookup);
- return;
+ return;
}
+/* Function behaviour:
+ * Function return true if inode_ctx is not present,
+ * or value stored in inode_ctx is LOOKUP_NEEDED.
+ * If inode_ctx value is LOOKUP_NOT_NEEDED, which means
+ * inode_ctx is present for xlator this, but no lookup
+ * needed.
+ */
gf_boolean_t
-inode_needs_lookup (inode_t *inode, xlator_t *this)
+inode_needs_lookup(inode_t *inode, xlator_t *this)
{
- uint64_t need_lookup = 0;
- gf_boolean_t ret = _gf_false;
+ uint64_t need_lookup = 0;
+ gf_boolean_t ret = _gf_false;
+ int op_ret = -1;
- if (!inode || !this)
- return ret;
+ if (!inode || !this)
+ return ret;
- inode_ctx_get (inode, this, &need_lookup);
- if (need_lookup) {
- ret = _gf_true;
- need_lookup = 0;
- inode_ctx_set (inode, this, &need_lookup);
- }
+ op_ret = inode_ctx_get(inode, this, &need_lookup);
+ if (op_ret == -1) {
+ ret = _gf_true;
+ } else if (need_lookup == LOOKUP_NEEDED) {
+ ret = _gf_true;
+ need_lookup = LOOKUP_NOT_NEEDED;
+ inode_ctx_set(inode, this, &need_lookup);
+ }
- return ret;
+ return ret;
}
int
-__inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
- uint64_t *value2_p)
-{
- int ret = 0;
- int index = 0;
- int set_idx = -1;
-
- if (!inode || !xlator || !inode->_ctx)
- return -1;
-
- for (index = 0; index < inode->table->ctxcount; index++) {
- if (!inode->_ctx[index].xl_key) {
- if (set_idx == -1)
- set_idx = index;
- /* dont break, to check if key already exists
- further on */
- }
- if (inode->_ctx[index].xl_key == xlator) {
- set_idx = index;
- break;
- }
- }
-
- if (set_idx == -1) {
- ret = -1;
- goto out;;
- }
-
- 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;
+__inode_ctx_set2(inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
+{
+ int ret = 0;
+ int set_idx = -1;
+
+ if (!inode || !xlator || !inode->_ctx)
+ return -1;
+
+ set_idx = __inode_get_xl_index(inode, xlator);
+ if (set_idx == -1) {
+ ret = -1;
+ goto out;
+ ;
+ }
+
+ 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;
+ return ret;
}
int
-__inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
+__inode_ctx_set0(inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
{
- return __inode_ctx_set2 (inode, xlator, value1_p, NULL);
+ return __inode_ctx_set2(inode, xlator, value1_p, NULL);
}
int
-__inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
+__inode_ctx_set1(inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
{
- return __inode_ctx_set2 (inode, xlator, NULL, value2_p);
+ return __inode_ctx_set2(inode, xlator, NULL, value2_p);
}
-
int
-inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
- uint64_t *value2_p)
+inode_ctx_set2(inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
{
- int ret = 0;
+ int ret = 0;
- if (!inode || !xlator)
- return -1;
+ if (!inode || !xlator)
+ return -1;
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_set2 (inode, xlator, value1_p, value2_p);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ ret = __inode_ctx_set2(inode, xlator, value1_p, value2_p);
+ }
+ UNLOCK(&inode->lock);
- return ret;
+ return ret;
}
int
-inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
+inode_ctx_set1(inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
{
- int ret = 0;
+ int ret = 0;
- if (!inode || !xlator)
- return -1;
+ if (!inode || !xlator)
+ return -1;
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_set1 (inode, xlator, value2_p);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ ret = __inode_ctx_set1(inode, xlator, value2_p);
+ }
+ UNLOCK(&inode->lock);
- return ret;
+ return ret;
}
int
-inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
+inode_ctx_set0(inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
{
- int ret = 0;
+ int ret = 0;
- if (!inode || !xlator)
- return -1;
+ if (!inode || !xlator)
+ return -1;
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_set0 (inode, xlator, value1_p);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ ret = __inode_ctx_set0(inode, xlator, value1_p);
+ }
+ UNLOCK(&inode->lock);
- return ret;
+ return ret;
}
-
int
-__inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
- uint64_t *value2)
+__inode_ctx_get2(inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2)
{
- int index = 0;
- int ret = -1;
-
- if (!inode || !xlator || !inode->_ctx)
- goto out;
+ int index = 0;
+ int ret = -1;
- for (index = 0; index < inode->table->ctxcount; index++) {
- if (inode->_ctx[index].xl_key == xlator)
- break;
- }
+ if (!inode || !xlator || !inode->_ctx)
+ goto out;
- if (index == inode->table->ctxcount)
- goto out;
+ index = xlator->xl_id;
+ if (inode->_ctx[index].xl_key != xlator)
+ goto out;
- if (inode->_ctx[index].value1) {
- if (value1) {
- *value1 = inode->_ctx[index].value1;
- ret = 0;
- }
+ if (inode->_ctx[index].value1) {
+ if (value1) {
+ *value1 = inode->_ctx[index].value1;
+ ret = 0;
}
- if (inode->_ctx[index].value2) {
- if (value2) {
- *value2 = inode->_ctx[index].value2;
- ret = 0;
- }
+ }
+ if (inode->_ctx[index].value2) {
+ if (value2) {
+ *value2 = inode->_ctx[index].value2;
+ ret = 0;
}
+ }
out:
- return ret;
+ return ret;
}
-
-
int
-__inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1)
+__inode_ctx_get0(inode_t *inode, xlator_t *xlator, uint64_t *value1)
{
- uint64_t tmp_value = 0;
- int ret = 0;
+ uint64_t tmp_value = 0;
+ int ret = 0;
- ret = __inode_ctx_get2 (inode, xlator, &tmp_value, NULL);
- if (!ret && value1)
- *value1 = tmp_value;
+ ret = __inode_ctx_get2(inode, xlator, &tmp_value, NULL);
+ if (!ret && value1)
+ *value1 = tmp_value;
- return ret;
+ return ret;
}
int
-__inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2)
+__inode_ctx_get1(inode_t *inode, xlator_t *xlator, uint64_t *value2)
{
- uint64_t tmp_value = 0;
- int ret = 0;
+ uint64_t tmp_value = 0;
+ int ret = 0;
- ret = __inode_ctx_get2 (inode, xlator, NULL, &tmp_value);
- if (!ret && value2)
- *value2 = tmp_value;
+ ret = __inode_ctx_get2(inode, xlator, NULL, &tmp_value);
+ if (!ret && value2)
+ *value2 = tmp_value;
- return ret;
+ return ret;
}
-
int
-inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
- uint64_t *value2)
+inode_ctx_get2(inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2)
{
- int ret = 0;
+ int ret = 0;
- if (!inode || !xlator)
- return -1;
+ if (!inode || !xlator)
+ return -1;
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get2 (inode, xlator, value1, value2);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ ret = __inode_ctx_get2(inode, xlator, value1, value2);
+ }
+ UNLOCK(&inode->lock);
- return ret;
+ return ret;
}
int
-inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2)
+inode_ctx_get1(inode_t *inode, xlator_t *xlator, uint64_t *value2)
{
- int ret = 0;
+ int ret = 0;
- if (!inode || !xlator)
- return -1;
+ if (!inode || !xlator)
+ return -1;
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get1 (inode, xlator, value2);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ ret = __inode_ctx_get1(inode, xlator, value2);
+ }
+ UNLOCK(&inode->lock);
- return ret;
+ return ret;
}
int
-inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1)
+inode_ctx_get0(inode_t *inode, xlator_t *xlator, uint64_t *value1)
{
- int ret = 0;
+ int ret = 0;
- if (!inode || !xlator)
- return -1;
+ if (!inode || !xlator)
+ return -1;
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get0 (inode, xlator, value1);
- }
- UNLOCK (&inode->lock);
+ LOCK(&inode->lock);
+ {
+ ret = __inode_ctx_get0(inode, xlator, value1);
+ }
+ UNLOCK(&inode->lock);
- return ret;
+ return ret;
}
-
int
-inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
- uint64_t *value2)
+inode_ctx_del2(inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2)
{
- int index = 0;
- int ret = 0;
+ int index = 0;
+ int ret = 0;
- if (!inode || !xlator)
- return -1;
+ if (!inode || !xlator)
+ return -1;
- LOCK (&inode->lock);
- {
- if (!inode->_ctx)
- goto unlock;
-
- for (index = 0; index < inode->table->ctxcount;
- index++) {
- if (inode->_ctx[index].xl_key == xlator)
- break;
- }
+ LOCK(&inode->lock);
+ {
+ if (!inode->_ctx)
+ goto unlock;
- if (index == inode->table->ctxcount) {
- ret = -1;
- goto unlock;
- }
+ index = xlator->xl_id;
+ if (inode->_ctx[index].xl_key != xlator) {
+ ret = -1;
+ goto unlock;
+ }
- if (inode->_ctx[index].value1 && value1)
- *value1 = inode->_ctx[index].value1;
- if (inode->_ctx[index].value2 && value2)
- *value2 = inode->_ctx[index].value2;
+ if (inode->_ctx[index].value1 && value1)
+ *value1 = inode->_ctx[index].value1;
+ if (inode->_ctx[index].value2 && value2)
+ *value2 = inode->_ctx[index].value2;
- inode->_ctx[index].key = 0;
- inode->_ctx[index].xl_key = NULL;
- inode->_ctx[index].value1 = 0;
- inode->_ctx[index].value2 = 0;
- }
+ inode->_ctx[index].key = 0;
+ inode->_ctx[index].xl_key = NULL;
+ inode->_ctx[index].value1 = 0;
+ inode->_ctx[index].value2 = 0;
+ }
unlock:
- UNLOCK (&inode->lock);
+ UNLOCK(&inode->lock);
- return ret;
+ return ret;
}
/* function behavior:
@@ -2143,308 +2283,395 @@ unlock:
- if both are set, both fields are reset.
*/
static int
-__inode_ctx_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
- uint64_t *value2)
+__inode_ctx_reset2(inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2)
{
- int index = 0;
- int ret = 0;
-
- if (!inode || !xlator)
- return -1;
+ int index = 0;
+ int ret = 0;
- LOCK (&inode->lock);
- {
- for (index = 0; index < inode->table->ctxcount;
- index++) {
- if (inode->_ctx[index].xl_key == xlator)
- break;
- }
+ if (!inode || !xlator)
+ return -1;
- if (index == inode->table->ctxcount) {
- ret = -1;
- goto unlock;
- }
+ LOCK(&inode->lock);
+ {
+ index = xlator->xl_id;
+ if (inode->_ctx[index].xl_key != xlator) {
+ ret = -1;
+ goto unlock;
+ }
- if (inode->_ctx[index].value1 && value1) {
- *value1 = inode->_ctx[index].value1;
- inode->_ctx[index].value1 = 0;
- }
- if (inode->_ctx[index].value2 && value2) {
- *value2 = inode->_ctx[index].value2;
- inode->_ctx[index].value2 = 0;
- }
+ if (inode->_ctx[index].value1 && value1) {
+ *value1 = inode->_ctx[index].value1;
+ inode->_ctx[index].value1 = 0;
+ }
+ if (inode->_ctx[index].value2 && value2) {
+ *value2 = inode->_ctx[index].value2;
+ inode->_ctx[index].value2 = 0;
}
+ }
unlock:
- UNLOCK (&inode->lock);
+ UNLOCK(&inode->lock);
- return ret;
+ return ret;
}
int
-inode_ctx_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
- uint64_t *value2_p)
-{
- uint64_t tmp_value1 = 0;
- uint64_t tmp_value2 = 0;
- int ret = 0;
-
- ret = __inode_ctx_reset2 (inode, xlator, &tmp_value1, &tmp_value2);
- if (!ret) {
- if (value1_p)
- *value1_p = tmp_value1;
- if (value2_p)
- *value2_p = tmp_value2;
- }
- return ret;
+inode_ctx_reset2(inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
+{
+ uint64_t tmp_value1 = 0;
+ uint64_t tmp_value2 = 0;
+ int ret = 0;
+
+ ret = __inode_ctx_reset2(inode, xlator, &tmp_value1, &tmp_value2);
+ if (!ret) {
+ if (value1_p)
+ *value1_p = tmp_value1;
+ if (value2_p)
+ *value2_p = tmp_value2;
+ }
+ return ret;
}
int
-inode_ctx_reset1 (inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
+inode_ctx_reset1(inode_t *inode, xlator_t *xlator, uint64_t *value2_p)
{
- uint64_t tmp_value2 = 0;
- int ret = 0;
-
- ret = __inode_ctx_reset2 (inode, xlator, NULL, &tmp_value2);
+ uint64_t tmp_value2 = 0;
+ int ret = 0;
- if (!ret && value2_p)
- *value2_p = tmp_value2;
+ ret = __inode_ctx_reset2(inode, xlator, NULL, &tmp_value2);
- return ret;
+ if (!ret && value2_p)
+ *value2_p = tmp_value2;
+ return ret;
}
int
-inode_ctx_reset0 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
+inode_ctx_reset0(inode_t *inode, xlator_t *xlator, uint64_t *value1_p)
{
- uint64_t tmp_value1 = 0;
- int ret = 0;
+ uint64_t tmp_value1 = 0;
+ int ret = 0;
- ret = __inode_ctx_reset2 (inode, xlator, &tmp_value1, NULL);
+ ret = __inode_ctx_reset2(inode, xlator, &tmp_value1, NULL);
- if (!ret && value1_p)
- *value1_p = tmp_value1;
+ if (!ret && value1_p)
+ *value1_p = tmp_value1;
- return ret;
+ return ret;
}
int
-inode_is_linked (inode_t *inode)
+inode_is_linked(inode_t *inode)
{
- int ret = 0;
- inode_table_t *table = NULL;
+ int ret = 0;
+ inode_table_t *table = NULL;
- if (!inode) {
- gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INODE_NOT_FOUND, "inode not found");
- return 0;
- }
+ if (!inode) {
+ gf_msg_callingfn(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INODE_NOT_FOUND,
+ "inode not found");
+ return 0;
+ }
- table = inode->table;
+ table = inode->table;
- pthread_mutex_lock (&table->lock);
- {
- ret = __is_inode_hashed (inode);
- }
- pthread_mutex_unlock (&table->lock);
+ pthread_mutex_lock(&table->lock);
+ {
+ ret = __is_inode_hashed(inode);
+ }
+ pthread_mutex_unlock(&table->lock);
- return ret;
+ return ret;
}
void
-inode_dump (inode_t *inode, char *prefix)
-{
- int ret = -1;
- xlator_t *xl = NULL;
- int i = 0;
- fd_t *fd = NULL;
- struct _inode_ctx *inode_ctx = NULL;
- struct list_head fd_list;
-
- if (!inode)
- return;
-
- INIT_LIST_HEAD (&fd_list);
+inode_dump(inode_t *inode, char *prefix)
+{
+ int ret = -1;
+ xlator_t *xl = NULL;
+ int i = 0;
+ fd_t *fd = NULL;
+ struct _inode_ctx *inode_ctx = NULL;
+ struct list_head fd_list;
+ int ref = 0;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ uint64_t nlookup = 0;
+
+ if (!inode)
+ return;
- ret = TRY_LOCK(&inode->lock);
- if (ret != 0) {
- return;
- }
+ INIT_LIST_HEAD(&fd_list);
- {
- gf_proc_dump_write("gfid", "%s", uuid_utoa (inode->gfid));
- gf_proc_dump_write("nlookup", "%ld", inode->nlookup);
- gf_proc_dump_write("fd-count", "%u", inode->fd_count);
- 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->ctxcount,
- sizeof (*inode_ctx),
- gf_common_mt_inode_ctx);
- if (inode_ctx == NULL) {
- goto unlock;
- }
-
- for (i = 0; i < inode->table->ctxcount;
- i++) {
- inode_ctx[i] = inode->_ctx[i];
- }
+ ret = TRY_LOCK(&inode->lock);
+ if (ret != 0) {
+ return;
+ }
+
+ {
+ nlookup = GF_ATOMIC_GET(inode->nlookup);
+ gf_proc_dump_write("gfid", "%s", uuid_utoa(inode->gfid));
+ gf_proc_dump_write("nlookup", "%" PRIu64, nlookup);
+ gf_proc_dump_write("fd-count", "%u", inode->fd_count);
+ gf_proc_dump_write("active-fd-count", "%u", inode->active_fd_count);
+ gf_proc_dump_write("ref", "%u", inode->ref);
+ gf_proc_dump_write("invalidate-sent", "%d", inode->invalidate_sent);
+ gf_proc_dump_write("ia_type", "%d", inode->ia_type);
+ if (inode->_ctx) {
+ inode_ctx = GF_CALLOC(inode->table->ctxcount, sizeof(*inode_ctx),
+ gf_common_mt_inode_ctx);
+ if (inode_ctx == NULL) {
+ goto unlock;
+ }
+
+ for (i = 0; i < inode->table->ctxcount; i++) {
+ inode_ctx[i] = inode->_ctx[i];
+ xl = inode_ctx[i].xl_key;
+ ref = inode_ctx[i].ref;
+ if (ref != 0 && xl) {
+ gf_proc_dump_build_key(key, "ref_by_xl:", "%s", xl->name);
+ gf_proc_dump_write(key, "%d", ref);
}
+ }
+ }
- if (dump_options.xl_options.dump_fdctx != _gf_true)
- goto unlock;
-
+ if (dump_options.xl_options.dump_fdctx != _gf_true)
+ goto unlock;
- list_for_each_entry (fd, &inode->fd_list, inode_list) {
- fd_ctx_dump (fd, prefix);
- }
+ list_for_each_entry(fd, &inode->fd_list, inode_list)
+ {
+ fd_ctx_dump(fd, prefix);
}
+ }
unlock:
- UNLOCK(&inode->lock);
-
- if (inode_ctx && (dump_options.xl_options.dump_inodectx == _gf_true)) {
- for (i = 0; i < inode->table->ctxcount; i++) {
- if (inode_ctx[i].xl_key) {
- xl = (xlator_t *)(long)inode_ctx[i].xl_key;
- if (xl->dumpops && xl->dumpops->inodectx)
- xl->dumpops->inodectx (xl, inode);
- }
- }
+ UNLOCK(&inode->lock);
+
+ if (inode_ctx && (dump_options.xl_options.dump_inodectx == _gf_true)) {
+ for (i = 0; i < inode->table->ctxcount; i++) {
+ if (inode_ctx[i].xl_key) {
+ xl = (xlator_t *)(long)inode_ctx[i].xl_key;
+ if (xl->dumpops && xl->dumpops->inodectx)
+ xl->dumpops->inodectx(xl, inode);
+ }
}
+ }
- GF_FREE (inode_ctx);
+ GF_FREE(inode_ctx);
- return;
+ return;
}
void
-inode_table_dump (inode_table_t *itable, char *prefix)
+inode_table_dump(inode_table_t *itable, char *prefix)
{
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int ret = 0;
- char key[GF_DUMP_MAX_BUF_LEN];
- int ret = 0;
-
- if (!itable)
- return;
+ if (!itable)
+ return;
- memset(key, 0, sizeof(key));
- ret = pthread_mutex_trylock(&itable->lock);
+ ret = pthread_mutex_trylock(&itable->lock);
- if (ret != 0) {
- return;
- }
+ if (ret != 0) {
+ return;
+ }
- gf_proc_dump_build_key(key, prefix, "hashsize");
- gf_proc_dump_write(key, "%d", itable->hashsize);
- gf_proc_dump_build_key(key, prefix, "name");
- gf_proc_dump_write(key, "%s", itable->name);
+ gf_proc_dump_build_key(key, prefix, "hashsize");
+ gf_proc_dump_write(key, "%" GF_PRI_SIZET, itable->hashsize);
+ gf_proc_dump_build_key(key, prefix, "name");
+ gf_proc_dump_write(key, "%s", itable->name);
- gf_proc_dump_build_key(key, prefix, "lru_limit");
- gf_proc_dump_write(key, "%d", itable->lru_limit);
- gf_proc_dump_build_key(key, prefix, "active_size");
- gf_proc_dump_write(key, "%d", itable->active_size);
- gf_proc_dump_build_key(key, prefix, "lru_size");
- gf_proc_dump_write(key, "%d", itable->lru_size);
- gf_proc_dump_build_key(key, prefix, "purge_size");
- gf_proc_dump_write(key, "%d", itable->purge_size);
+ gf_proc_dump_build_key(key, prefix, "lru_limit");
+ gf_proc_dump_write(key, "%d", itable->lru_limit);
+ gf_proc_dump_build_key(key, prefix, "active_size");
+ gf_proc_dump_write(key, "%d", itable->active_size);
+ gf_proc_dump_build_key(key, prefix, "lru_size");
+ gf_proc_dump_write(key, "%d", itable->lru_size);
+ gf_proc_dump_build_key(key, prefix, "purge_size");
+ gf_proc_dump_write(key, "%d", itable->purge_size);
+ gf_proc_dump_build_key(key, prefix, "invalidate_size");
+ gf_proc_dump_write(key, "%d", itable->invalidate_size);
- INODE_DUMP_LIST(&itable->active, key, prefix, "active");
- INODE_DUMP_LIST(&itable->lru, key, prefix, "lru");
- INODE_DUMP_LIST(&itable->purge, key, prefix, "purge");
+ INODE_DUMP_LIST(&itable->active, key, prefix, "active");
+ INODE_DUMP_LIST(&itable->lru, key, prefix, "lru");
+ INODE_DUMP_LIST(&itable->purge, key, prefix, "purge");
+ INODE_DUMP_LIST(&itable->invalidate, key, prefix, "invalidate");
- pthread_mutex_unlock(&itable->lock);
+ pthread_mutex_unlock(&itable->lock);
}
void
-inode_dump_to_dict (inode_t *inode, char *prefix, dict_t *dict)
+inode_dump_to_dict(inode_t *inode, char *prefix, dict_t *dict)
{
- int ret = -1;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+ uint64_t nlookup = 0;
- ret = TRY_LOCK (&inode->lock);
- if (ret)
- return;
+ 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;
+ 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;
+ snprintf(key, sizeof(key), "%s.nlookup", prefix);
+ nlookup = GF_ATOMIC_GET(inode->nlookup);
+ ret = dict_set_uint64(dict, key, 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;
+ 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);
+ snprintf(key, sizeof(key), "%s.ia_type", prefix);
+ ret = dict_set_int32(dict, key, inode->ia_type);
+ if (ret)
+ goto out;
out:
- UNLOCK (&inode->lock);
- return;
+ 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;
+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;
+#ifdef DEBUG
+ inode_t *inode = NULL;
+ int count = 0;
+#endif
+ ret = pthread_mutex_trylock(&itable->lock);
+ if (ret)
+ return;
- ret = pthread_mutex_trylock (&itable->lock);
- if (ret)
- return;
+ snprintf(key, sizeof(key), "%s.itable.lru_limit", prefix);
+ ret = dict_set_uint32(dict, key, itable->lru_limit);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%s.itable.active_size", prefix);
+ ret = dict_set_uint32(dict, key, itable->active_size);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%s.itable.lru_size", prefix);
+ ret = dict_set_uint32(dict, key, itable->lru_size);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "%s.itable.purge_size", prefix);
+ ret = dict_set_uint32(dict, key, itable->purge_size);
+ if (ret)
+ goto out;
+
+#ifdef DEBUG
+ /* Dumping inode details in dictionary and sending it to CLI is not
+ required as when a developer (or support team) asks for this command
+ output, they just want to get top level detail of inode table.
+ If one wants to debug, let them take statedump and debug, this
+ wouldn't be available in CLI during production setup.
+ */
+ list_for_each_entry(inode, &itable->active, list)
+ {
+ 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)
+ {
+ 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)
+ {
+ snprintf(key, sizeof(key), "%s.itable.purge%d", prefix, count++);
+ inode_dump_to_dict(inode, key, dict);
+ }
+#endif
- 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;
+out:
+ pthread_mutex_unlock(&itable->lock);
- 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;
+ return;
+}
- 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;
+size_t
+inode_ctx_size(inode_t *inode)
+{
+ int i = 0;
+ size_t size = 0;
+ xlator_t *xl = NULL, *old_THIS = NULL;
- 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;
+ if (!inode)
+ goto out;
- 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;
+ LOCK(&inode->lock);
+ {
+ for (i = 0; i < inode->table->ctxcount; i++) {
+ if (!inode->_ctx[i].xl_key)
+ continue;
- 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);
+ xl = (xlator_t *)(long)inode->_ctx[i].xl_key;
+ old_THIS = THIS;
+ THIS = xl;
+
+ /* If inode ref is taken when THIS is global xlator,
+ * the ctx xl_key is set, but the value is NULL.
+ * For global xlator the cbks can be NULL, hence check
+ * for the same */
+ if (!xl->cbks) {
+ THIS = old_THIS;
+ continue;
+ }
+
+ if (xl->cbks->ictxsize)
+ size += xl->cbks->ictxsize(xl, inode);
+
+ THIS = old_THIS;
}
+ }
+ UNLOCK(&inode->lock);
out:
- pthread_mutex_unlock (&itable->lock);
+ return size;
+}
+/* *
+ * This function finds name of the inode, if it has dentry. The dentry will be
+ * created only if inode_link happens with valid parent and name. And this
+ * function is only applicable for directories because multiple dentries are
+ * not possible(no hardlinks)
+ * */
+void
+inode_find_directory_name(inode_t *inode, const char **name)
+{
+ dentry_t *dentry = NULL;
+
+ GF_VALIDATE_OR_GOTO("inode", inode, out);
+ GF_VALIDATE_OR_GOTO("inode", name, out);
+
+ if (!IA_ISDIR(inode->ia_type))
return;
+
+ pthread_mutex_lock(&inode->table->lock);
+ {
+ dentry = __dentry_search_arbit(inode);
+ if (dentry) {
+ *name = dentry->name;
+ }
+ }
+ pthread_mutex_unlock(&inode->table->lock);
+out:
+ return;
}
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
deleted file mode 100644
index 46fe8f6ac80..00000000000
--- a/libglusterfs/src/inode.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- 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
-#define _INODE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#define DEFAULT_INODE_MEMPOOL_ENTRIES 32 * 1024
-#define INODE_PATH_FMT "<gfid:%s>"
-struct _inode_table;
-typedef struct _inode_table inode_table_t;
-
-struct _inode;
-typedef struct _inode inode_t;
-
-struct _dentry;
-typedef struct _dentry dentry_t;
-
-#include "list.h"
-#include "xlator.h"
-#include "iatt.h"
-#include "compat-uuid.h"
-#include "fd.h"
-
-struct _inode_table {
- pthread_mutex_t lock;
- size_t hashsize; /* bucket size of inode hash and dentry hash */
- char *name; /* name of the inode table, just for gf_log() */
- inode_t *root; /* root directory inode, with number 1 */
- xlator_t *xl; /* xlator to be called to do purge */
- uint32_t lru_limit; /* maximum LRU cache size */
- struct list_head *inode_hash; /* buckets for inode hash table */
- struct list_head *name_hash; /* buckets for dentry hash table */
- struct list_head active; /* list of inodes currently active (in an fop) */
- uint32_t active_size; /* count of inodes in active list */
- struct list_head lru; /* list of inodes recently used.
- lru.next most recent */
- uint32_t lru_size; /* count of inodes in lru list */
- struct list_head purge; /* list of inodes to be purged soon */
- uint32_t purge_size; /* count of inodes in purge list */
-
- struct mem_pool *inode_pool; /* memory pool for inodes */
- struct mem_pool *dentry_pool; /* memory pool for dentrys */
- struct mem_pool *fd_mem_pool; /* memory pool for fd_t */
- int ctxcount; /* number of slots in inode->ctx */
-};
-
-
-struct _dentry {
- struct list_head inode_list; /* list of dentries of inode */
- struct list_head hash; /* hash table pointers */
- inode_t *inode; /* inode of this directory entry */
- char *name; /* name of the directory entry */
- inode_t *parent; /* directory of the entry */
-};
-
-struct _inode_ctx {
- union {
- uint64_t key;
- xlator_t *xl_key;
- };
- /* if value1 is 0, then field is not set.. */
- union {
- uint64_t value1;
- void *ptr1;
- };
- /* if value2 is 0, then field is not set.. */
- union {
- uint64_t value2;
- void *ptr2;
- };
-};
-
-struct _inode {
- inode_table_t *table; /* the table this inode belongs to */
- uuid_t gfid;
- gf_lock_t lock;
- uint64_t nlookup;
- uint32_t fd_count; /* Open fd count */
- uint32_t ref; /* reference count on this inode */
- 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 */
- struct list_head hash; /* hash table pointers */
- struct list_head list; /* active/lru/purge */
-
- struct _inode_ctx *_ctx; /* replacement for dict_t *(inode->ctx) */
-};
-
-
-#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);
-
-void
-inode_table_destroy_all (glusterfs_ctx_t *ctx);
-
-void
-inode_table_destroy (inode_table_t *inode_table);
-
-inode_t *
-inode_new (inode_table_t *table);
-
-inode_t *
-inode_link (inode_t *inode, inode_t *parent,
- const char *name, struct iatt *stbuf);
-
-void
-inode_unlink (inode_t *inode, inode_t *parent, const char *name);
-
-inode_t *
-inode_parent (inode_t *inode, uuid_t pargfid, const char *name);
-
-inode_t *
-inode_ref (inode_t *inode);
-
-inode_t *
-inode_unref (inode_t *inode);
-
-int
-inode_lookup (inode_t *inode);
-
-int
-inode_forget (inode_t *inode, uint64_t nlookup);
-
-int
-inode_ref_reduce_by_n (inode_t *inode, uint64_t nref);
-
-int
-inode_invalidate(inode_t *inode);
-
-int
-inode_rename (inode_table_t *table, inode_t *olddir, const char *oldname,
- inode_t *newdir, const char *newname,
- inode_t *inode, struct iatt *stbuf);
-
-dentry_t *
-__dentry_grep (inode_table_t *table, inode_t *parent, const char *name);
-
-inode_t *
-inode_grep (inode_table_t *table, inode_t *parent, const char *name);
-
-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);
-
-int
-inode_path (inode_t *inode, const char *name, char **bufp);
-
-int
-__inode_path (inode_t *inode, const char *name, char **bufp);
-
-inode_t *
-inode_from_path (inode_table_t *table, const char *path);
-
-inode_t *
-inode_resolve (inode_table_t *table, char *path);
-
-/* deal with inode ctx's both values */
-
-int
-inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
- uint64_t *value2);
-int
-__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_ctx_reset2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
- uint64_t *value2);
-
-/* deal with inode ctx's 1st value */
-
-int
-inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
-
-int
-__inode_ctx_set0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
-
-int
-inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
-int
-__inode_ctx_get0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
-
-int
-inode_ctx_reset0 (inode_t *inode, xlator_t *xlator, uint64_t *value1);
-
-/* deal with inode ctx's 2st value */
-
-int
-inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
-
-int
-__inode_ctx_set1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
-
-int
-inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
-int
-__inode_ctx_get1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
-
-int
-inode_ctx_reset1 (inode_t *inode, xlator_t *xlator, uint64_t *value2);
-
-
-static inline int
-__inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
-{
- return __inode_ctx_set0 (inode, this, &v);
-}
-
-static inline int
-inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
-{
- return inode_ctx_set0 (inode, this, &v);
-}
-
-#define __inode_ctx_set(i,x,v_p) __inode_ctx_set0(i,x,v_p)
-
-#define inode_ctx_set(i,x,v_p) inode_ctx_set0(i,x,v_p)
-
-#define inode_ctx_reset(i,x,v) inode_ctx_reset0(i,x,v)
-
-#define __inode_ctx_get(i,x,v) __inode_ctx_get0(i,x,v)
-
-#define inode_ctx_get(i,x,v) inode_ctx_get0(i,x,v)
-
-#define inode_ctx_del(i,x,v) inode_ctx_del2(i,x,v,0)
-
-gf_boolean_t
-__is_root_gfid (uuid_t gfid);
-
-void
-__inode_table_set_lru_limit (inode_table_t *table, uint32_t lru_limit);
-
-void
-inode_table_set_lru_limit (inode_table_t *table, uint32_t lru_limit);
-
-void
-inode_ctx_merge (fd_t *fd, inode_t *inode, inode_t *linked_inode);
-
-int
-inode_is_linked (inode_t *inode);
-
-void
-inode_set_need_lookup (inode_t *inode, xlator_t *this);
-
-gf_boolean_t
-inode_needs_lookup (inode_t *inode, xlator_t *this);
-
-int
-inode_has_dentry (inode_t *inode);
-
-#endif /* _INODE_H */
diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c
index a4d36691cd0..4e7d2958764 100644
--- a/libglusterfs/src/iobuf.c
+++ b/libglusterfs/src/iobuf.c
@@ -8,1213 +8,1139 @@
cases as published by the Free Software Foundation.
*/
-
-#include "iobuf.h"
-#include "statedump.h"
+#include "glusterfs/iobuf.h"
+#include "glusterfs/statedump.h"
#include <stdio.h>
-#include "libglusterfs-messages.h"
+#include "glusterfs/libglusterfs-messages.h"
/*
TODO: implement destroy margins and prefetching of arenas
*/
-#define IOBUF_ARENA_MAX_INDEX (sizeof (gf_iobuf_init_config) / \
- (sizeof (struct iobuf_init_config)))
+#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},
+static const 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)
+static int
+gf_iobuf_get_arena_index(const 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;
- }
+ int i;
- if (i >= IOBUF_ARENA_MAX_INDEX)
- i = -1;
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ if (page_size <= gf_iobuf_init_config[i].pagesize)
+ return i;
+ }
- return i;
+ return -1;
}
-
-size_t
-gf_iobuf_get_pagesize (size_t page_size)
+static size_t
+gf_iobuf_get_pagesize(const size_t page_size, int *index)
{
- 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;
+ int i;
+ size_t size = 0;
+
+ for (i = 0; i < IOBUF_ARENA_MAX_INDEX; i++) {
+ size = gf_iobuf_init_config[i].pagesize;
+ if (page_size <= size) {
+ if (index != NULL)
+ *index = i;
+ return size;
}
+ }
- if (i >= IOBUF_ARENA_MAX_INDEX)
- size = -1;
-
- return size;
+ return -1;
}
-void
-__iobuf_arena_init_iobufs (struct iobuf_arena *iobuf_arena)
+static void
+__iobuf_arena_init_iobufs(struct iobuf_arena *iobuf_arena)
{
- int iobuf_cnt = 0;
- struct iobuf *iobuf = NULL;
- int offset = 0;
- int i = 0;
-
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
-
- iobuf_cnt = iobuf_arena->page_count;
-
- iobuf_arena->iobufs = GF_CALLOC (sizeof (*iobuf), iobuf_cnt,
- gf_common_mt_iobuf);
- if (!iobuf_arena->iobufs)
- return;
+ const int iobuf_cnt = iobuf_arena->page_count;
+ struct iobuf *iobuf = NULL;
+ int offset = 0;
+ int i = 0;
+
+ iobuf_arena->iobufs = GF_CALLOC(sizeof(*iobuf), iobuf_cnt,
+ gf_common_mt_iobuf);
+ if (!iobuf_arena->iobufs)
+ return;
- iobuf = iobuf_arena->iobufs;
- for (i = 0; i < iobuf_cnt; i++) {
- INIT_LIST_HEAD (&iobuf->list);
- LOCK_INIT (&iobuf->lock);
+ iobuf = iobuf_arena->iobufs;
+ for (i = 0; i < iobuf_cnt; i++) {
+ INIT_LIST_HEAD(&iobuf->list);
+ LOCK_INIT(&iobuf->lock);
- iobuf->iobuf_arena = iobuf_arena;
+ iobuf->iobuf_arena = iobuf_arena;
- iobuf->ptr = iobuf_arena->mem_base + offset;
+ iobuf->ptr = iobuf_arena->mem_base + offset;
- list_add (&iobuf->list, &iobuf_arena->passive.list);
- iobuf_arena->passive_cnt++;
+ list_add(&iobuf->list, &iobuf_arena->passive.list);
+ iobuf_arena->passive_cnt++;
- offset += iobuf_arena->page_size;
- iobuf++;
- }
+ offset += iobuf_arena->page_size;
+ iobuf++;
+ }
-out:
- return;
+ return;
}
-
-void
-__iobuf_arena_destroy_iobufs (struct iobuf_arena *iobuf_arena)
+static void
+__iobuf_arena_destroy_iobufs(struct iobuf_arena *iobuf_arena)
{
- int iobuf_cnt = 0;
- struct iobuf *iobuf = NULL;
- int i = 0;
-
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
+ int iobuf_cnt = 0;
+ struct iobuf *iobuf = NULL;
+ int i = 0;
- iobuf_cnt = iobuf_arena->page_count;
-
- if (!iobuf_arena->iobufs) {
- gf_msg_callingfn (THIS->name, GF_LOG_ERROR, 0,
- LG_MSG_IOBUFS_NOT_FOUND, "iobufs not found");
- return;
- }
+ if (!iobuf_arena->iobufs) {
+ gf_msg_callingfn(THIS->name, GF_LOG_ERROR, 0, LG_MSG_IOBUFS_NOT_FOUND,
+ "iobufs not found");
+ return;
+ }
- iobuf = iobuf_arena->iobufs;
- for (i = 0; i < iobuf_cnt; i++) {
- GF_ASSERT (iobuf->ref == 0);
+ iobuf_cnt = iobuf_arena->page_count;
+ iobuf = iobuf_arena->iobufs;
+ for (i = 0; i < iobuf_cnt; i++) {
+ GF_ASSERT(GF_ATOMIC_GET(iobuf->ref) == 0);
- LOCK_DESTROY (&iobuf->lock);
- list_del_init (&iobuf->list);
- iobuf++;
- }
+ LOCK_DESTROY(&iobuf->lock);
+ list_del_init(&iobuf->list);
+ iobuf++;
+ }
- GF_FREE (iobuf_arena->iobufs);
+ GF_FREE(iobuf_arena->iobufs);
-out:
- return;
+ return;
}
-
-void
-__iobuf_arena_destroy (struct iobuf_pool *iobuf_pool,
- struct iobuf_arena *iobuf_arena)
+static void
+__iobuf_arena_destroy(struct iobuf_pool *iobuf_pool,
+ struct iobuf_arena *iobuf_arena)
{
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_arena, out);
- if (iobuf_pool->rdma_deregistration)
- iobuf_pool->rdma_deregistration (iobuf_pool->mr_list,
- iobuf_arena);
+ if (iobuf_pool->rdma_deregistration)
+ iobuf_pool->rdma_deregistration(iobuf_pool->mr_list, iobuf_arena);
- __iobuf_arena_destroy_iobufs (iobuf_arena);
+ __iobuf_arena_destroy_iobufs(iobuf_arena);
- if (iobuf_arena->mem_base
- && iobuf_arena->mem_base != MAP_FAILED)
- munmap (iobuf_arena->mem_base, iobuf_arena->arena_size);
+ if (iobuf_arena->mem_base && iobuf_arena->mem_base != MAP_FAILED)
+ munmap(iobuf_arena->mem_base, iobuf_arena->arena_size);
- GF_FREE (iobuf_arena);
+ GF_FREE(iobuf_arena);
out:
- return;
+ return;
}
-
-struct iobuf_arena *
-__iobuf_arena_alloc (struct iobuf_pool *iobuf_pool, size_t page_size,
- int32_t num_iobufs)
+static struct iobuf_arena *
+__iobuf_arena_alloc(struct iobuf_pool *iobuf_pool, size_t page_size,
+ int32_t num_iobufs)
{
- struct iobuf_arena *iobuf_arena = NULL;
- size_t rounded_size = 0;
+ struct iobuf_arena *iobuf_arena = NULL;
+ size_t rounded_size = 0;
+ int index = 0; /* unused */
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
- iobuf_arena = GF_CALLOC (sizeof (*iobuf_arena), 1,
- gf_common_mt_iobuf_arena);
- if (!iobuf_arena)
- goto err;
+ 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->all_list);
- INIT_LIST_HEAD (&iobuf_arena->active.list);
- INIT_LIST_HEAD (&iobuf_arena->passive.list);
- iobuf_arena->iobuf_pool = iobuf_pool;
+ INIT_LIST_HEAD(&iobuf_arena->list);
+ INIT_LIST_HEAD(&iobuf_arena->all_list);
+ INIT_LIST_HEAD(&iobuf_arena->active.list);
+ INIT_LIST_HEAD(&iobuf_arena->passive.list);
+ iobuf_arena->iobuf_pool = iobuf_pool;
- rounded_size = gf_iobuf_get_pagesize (page_size);
+ rounded_size = gf_iobuf_get_pagesize(page_size, &index);
- iobuf_arena->page_size = rounded_size;
- iobuf_arena->page_count = num_iobufs;
+ iobuf_arena->page_size = rounded_size;
+ iobuf_arena->page_count = num_iobufs;
- iobuf_arena->arena_size = rounded_size * 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_msg (THIS->name, GF_LOG_WARNING, 0, LG_MSG_MAPPING_FAILED,
- "mapping failed");
- goto err;
- }
+ 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_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_MAPPING_FAILED, NULL);
+ goto err;
+ }
- if (iobuf_pool->rdma_registration) {
- iobuf_pool->rdma_registration (iobuf_pool->device,
- iobuf_arena);
- }
+ if (iobuf_pool->rdma_registration) {
+ iobuf_pool->rdma_registration(iobuf_pool->device, iobuf_arena);
+ }
- list_add_tail (&iobuf_arena->all_list, &iobuf_pool->all_arenas);
+ list_add_tail(&iobuf_arena->all_list, &iobuf_pool->all_arenas);
- __iobuf_arena_init_iobufs (iobuf_arena);
- if (!iobuf_arena->iobufs) {
- gf_msg (THIS->name, GF_LOG_ERROR, 0, LG_MSG_INIT_IOBUF_FAILED,
- "init failed");
- goto err;
- }
+ __iobuf_arena_init_iobufs(iobuf_arena);
+ if (!iobuf_arena->iobufs) {
+ gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INIT_IOBUF_FAILED, NULL);
+ goto err;
+ }
- iobuf_pool->arena_cnt++;
+ iobuf_pool->arena_cnt++;
- return iobuf_arena;
+ return iobuf_arena;
err:
- __iobuf_arena_destroy (iobuf_pool, iobuf_arena);
+ __iobuf_arena_destroy(iobuf_pool, iobuf_arena);
out:
- return NULL;
+ return NULL;
}
-
-struct iobuf_arena *
-__iobuf_arena_unprune (struct iobuf_pool *iobuf_pool, size_t page_size)
+static struct iobuf_arena *
+__iobuf_arena_unprune(struct iobuf_pool *iobuf_pool, const size_t page_size,
+ const int index)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
- int index = 0;
-
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
-
- index = gf_iobuf_get_arena_index (page_size);
- if (index == -1) {
- gf_msg ("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of iobufs in arena being added is "
- "greater than max available", page_size);
- return NULL;
- }
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *tmp = NULL;
- list_for_each_entry (tmp, &iobuf_pool->purge[index], list) {
- list_del_init (&tmp->list);
- iobuf_arena = tmp;
- break;
- }
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
+
+ list_for_each_entry(tmp, &iobuf_pool->purge[index], list)
+ {
+ list_del_init(&tmp->list);
+ iobuf_arena = tmp;
+ break;
+ }
out:
- return iobuf_arena;
+ return iobuf_arena;
}
-
-struct iobuf_arena *
-__iobuf_pool_add_arena (struct iobuf_pool *iobuf_pool, size_t page_size,
- int32_t num_pages)
+static struct iobuf_arena *
+__iobuf_pool_add_arena(struct iobuf_pool *iobuf_pool, const size_t page_size,
+ const int32_t num_pages, const int index)
{
- struct iobuf_arena *iobuf_arena = NULL;
- int index = 0;
-
- index = gf_iobuf_get_arena_index (page_size);
- if (index == -1) {
- gf_msg ("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of iobufs in arena being added is "
- "greater than max available", page_size);
- return NULL;
- }
+ struct iobuf_arena *iobuf_arena = NULL;
- iobuf_arena = __iobuf_arena_unprune (iobuf_pool, page_size);
-
- if (!iobuf_arena)
- iobuf_arena = __iobuf_arena_alloc (iobuf_pool, page_size,
- num_pages);
+ iobuf_arena = __iobuf_arena_unprune(iobuf_pool, page_size, index);
+ if (!iobuf_arena) {
+ iobuf_arena = __iobuf_arena_alloc(iobuf_pool, page_size, num_pages);
if (!iobuf_arena) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND,
- "arena not found");
- return NULL;
- }
- list_add (&iobuf_arena->list, &iobuf_pool->arenas[index]);
-
-
- return iobuf_arena;
-}
-
-
-struct iobuf_arena *
-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);
-
- pthread_mutex_lock (&iobuf_pool->mutex);
- {
- iobuf_arena = __iobuf_pool_add_arena (iobuf_pool, page_size,
- num_pages);
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND,
+ NULL);
+ return NULL;
}
- pthread_mutex_unlock (&iobuf_pool->mutex);
+ }
+ list_add(&iobuf_arena->list, &iobuf_pool->arenas[index]);
-out:
- return iobuf_arena;
+ return iobuf_arena;
}
-
/* This function destroys all the iobufs and the iobuf_pool */
void
-iobuf_pool_destroy (struct iobuf_pool *iobuf_pool)
+iobuf_pool_destroy(struct iobuf_pool *iobuf_pool)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
- int i = 0;
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *tmp = NULL;
+ int i = 0;
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
- pthread_mutex_lock (&iobuf_pool->mutex);
- {
- 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_pool, iobuf_arena);
- }
- list_for_each_entry_safe (iobuf_arena, tmp,
- &iobuf_pool->purge[i], list) {
- list_del_init (&iobuf_arena->list);
- iobuf_pool->arena_cnt--;
- __iobuf_arena_destroy (iobuf_pool, iobuf_arena);
- }
- /* If there are no iobuf leaks, there should be no
- * arenas in the filled list. If at all there are any
- * arenas in the filled list, the below function will
- * assert.
- */
- list_for_each_entry_safe (iobuf_arena, tmp,
- &iobuf_pool->filled[i], list) {
- list_del_init (&iobuf_arena->list);
- iobuf_pool->arena_cnt--;
- __iobuf_arena_destroy (iobuf_pool, iobuf_arena);
- }
- /* If there are no iobuf leaks, there shoould be
- * no standard alloced arenas, iobuf_put will free such
- * arenas.
- * TODO: Free the stdalloc arenas forcefully if present?
- */
- }
+ pthread_mutex_lock(&iobuf_pool->mutex);
+ {
+ 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_pool, iobuf_arena);
+ }
+ list_for_each_entry_safe(iobuf_arena, tmp, &iobuf_pool->purge[i],
+ list)
+ {
+ list_del_init(&iobuf_arena->list);
+ iobuf_pool->arena_cnt--;
+ __iobuf_arena_destroy(iobuf_pool, iobuf_arena);
+ }
+ /* If there are no iobuf leaks, there should be no
+ * arenas in the filled list. If at all there are any
+ * arenas in the filled list, the below function will
+ * assert.
+ */
+ list_for_each_entry_safe(iobuf_arena, tmp, &iobuf_pool->filled[i],
+ list)
+ {
+ list_del_init(&iobuf_arena->list);
+ iobuf_pool->arena_cnt--;
+ __iobuf_arena_destroy(iobuf_pool, iobuf_arena);
+ }
+ /* If there are no iobuf leaks, there shoould be
+ * no standard allocated arenas, iobuf_put will free
+ * such arenas.
+ * TODO: Free the stdalloc arenas forcefully if present?
+ */
}
- pthread_mutex_unlock (&iobuf_pool->mutex);
+ }
+ pthread_mutex_unlock(&iobuf_pool->mutex);
- pthread_mutex_destroy (&iobuf_pool->mutex);
+ pthread_mutex_destroy(&iobuf_pool->mutex);
- GF_FREE (iobuf_pool);
+ GF_FREE(iobuf_pool);
out:
- return;
+ return;
}
static void
-iobuf_create_stdalloc_arena (struct iobuf_pool *iobuf_pool)
+iobuf_create_stdalloc_arena(struct iobuf_pool *iobuf_pool)
{
- struct iobuf_arena *iobuf_arena = NULL;
+ 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;
+ /* 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);
+ 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->iobuf_pool = iobuf_pool;
- iobuf_arena->page_size = 0x7fffffff;
+ iobuf_arena->page_size = 0x7fffffff;
- list_add_tail (&iobuf_arena->list,
- &iobuf_pool->arenas[IOBUF_ARENA_MAX_INDEX]);
+ list_add_tail(&iobuf_arena->list,
+ &iobuf_pool->arenas[IOBUF_ARENA_MAX_INDEX]);
err:
- return;
+ return;
}
struct iobuf_pool *
-iobuf_pool_new (void)
+iobuf_pool_new(void)
{
- struct iobuf_pool *iobuf_pool = 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)
- goto out;
- INIT_LIST_HEAD (&iobuf_pool->all_arenas);
- pthread_mutex_init (&iobuf_pool->mutex, NULL);
- 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->default_page_size = 128 * GF_UNIT_KB;
-
- iobuf_pool->rdma_registration = NULL;
- iobuf_pool->rdma_deregistration = NULL;
-
- for (i = 0; i < GF_RDMA_DEVICE_COUNT; i++) {
-
- iobuf_pool->device[i] = NULL;
- iobuf_pool->mr_list[i] = NULL;
-
- }
-
- 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;
- }
-
- /* Need an arena to handle all the bigger iobuf requests */
- iobuf_create_stdalloc_arena (iobuf_pool);
-
- iobuf_pool->arena_size = arena_size;
+ struct iobuf_pool *iobuf_pool = 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)
+ goto out;
+ INIT_LIST_HEAD(&iobuf_pool->all_arenas);
+ pthread_mutex_init(&iobuf_pool->mutex, NULL);
+ 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->default_page_size = 128 * GF_UNIT_KB;
+
+ iobuf_pool->rdma_registration = NULL;
+ iobuf_pool->rdma_deregistration = NULL;
+
+ for (i = 0; i < GF_RDMA_DEVICE_COUNT; i++) {
+ iobuf_pool->device[i] = NULL;
+ iobuf_pool->mr_list[i] = NULL;
+ }
+
+ /* No locking required here
+ * as no one else can use this pool yet
+ */
+ 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;
+
+ if (__iobuf_pool_add_arena(iobuf_pool, page_size, num_pages, i) != NULL)
+ arena_size += page_size * num_pages;
+ }
+
+ /* 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;
+ return iobuf_pool;
}
-
-void
-__iobuf_arena_prune (struct iobuf_pool *iobuf_pool,
- struct iobuf_arena *iobuf_arena, int index)
+static void
+__iobuf_arena_prune(struct iobuf_pool *iobuf_pool,
+ struct iobuf_arena *iobuf_arena, const int index)
{
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
-
- /* 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;
+ /* code flow comes here only if the arena is in purge list and we can
+ * free the arena only if we have at least 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;
- /* All cases matched, destroy */
- list_del_init (&iobuf_arena->list);
- list_del_init (&iobuf_arena->all_list);
- iobuf_pool->arena_cnt--;
+ /* All cases matched, destroy */
+ list_del_init(&iobuf_arena->list);
+ list_del_init(&iobuf_arena->all_list);
+ iobuf_pool->arena_cnt--;
- __iobuf_arena_destroy (iobuf_pool, iobuf_arena);
+ __iobuf_arena_destroy(iobuf_pool, iobuf_arena);
out:
- return;
+ return;
}
-
void
-iobuf_pool_prune (struct iobuf_pool *iobuf_pool)
+iobuf_pool_prune(struct iobuf_pool *iobuf_pool)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_arena *tmp = NULL;
- int i = 0;
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *tmp = NULL;
+ int i = 0;
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
- pthread_mutex_lock (&iobuf_pool->mutex);
- {
- 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_lock(&iobuf_pool->mutex);
+ {
+ 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);
+ }
+ pthread_mutex_unlock(&iobuf_pool->mutex);
out:
- return;
+ return;
}
-
-struct iobuf_arena *
-__iobuf_select_arena (struct iobuf_pool *iobuf_pool, size_t page_size)
+/* Always called under the iobuf_pool mutex lock */
+static struct iobuf_arena *
+__iobuf_select_arena(struct iobuf_pool *iobuf_pool, const size_t page_size,
+ const int index)
{
- 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_msg ("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
- "page_size (%zu) of iobufs in arena being added is "
- "greater than max available", page_size);
- return NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_arena *trav = NULL;
+
+ /* look for unused iobuf from the head-most arena */
+ list_for_each_entry(trav, &iobuf_pool->arenas[index], list)
+ {
+ if (trav->passive_cnt) {
+ iobuf_arena = trav;
+ break;
}
+ }
- /* look for unused iobuf from the head-most arena */
- list_for_each_entry (trav, &iobuf_pool->arenas[index], list) {
- if (trav->passive_cnt) {
- iobuf_arena = trav;
- break;
- }
- }
+ if (!iobuf_arena) {
+ /* 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,
+ index);
+ }
- if (!iobuf_arena) {
- /* 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:
- return iobuf_arena;
+ return iobuf_arena;
}
-
-struct iobuf *
-__iobuf_ref (struct iobuf *iobuf)
+/* Always called under the iobuf_pool mutex lock */
+static struct iobuf *
+__iobuf_get(struct iobuf_pool *iobuf_pool, const size_t page_size,
+ const int index)
{
- iobuf->ref++;
+ struct iobuf *iobuf = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
- return iobuf;
-}
-
-
-struct iobuf *
-__iobuf_unref (struct iobuf *iobuf)
-{
- iobuf->ref--;
-
- return iobuf;
-}
-
-struct iobuf *
-__iobuf_get (struct iobuf_arena *iobuf_arena, size_t page_size)
-{
- struct iobuf *iobuf = NULL;
- struct iobuf_pool *iobuf_pool = NULL;
- int index = 0;
-
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
-
- iobuf_pool = iobuf_arena->iobuf_pool;
-
- list_for_each_entry (iobuf, &iobuf_arena->passive.list, list)
- break;
+ /* most eligible arena for picking an iobuf */
+ iobuf_arena = __iobuf_select_arena(iobuf_pool, page_size, index);
+ if (!iobuf_arena)
+ return NULL;
- list_del (&iobuf->list);
- iobuf_arena->passive_cnt--;
+ list_for_each_entry(iobuf, &iobuf_arena->passive.list, list) break;
- list_add (&iobuf->list, &iobuf_arena->active.list);
- iobuf_arena->active_cnt++;
+ list_del(&iobuf->list);
+ iobuf_arena->passive_cnt--;
- /* no resetting requied for this element */
- iobuf_arena->alloc_cnt++;
+ list_add(&iobuf->list, &iobuf_arena->active.list);
+ iobuf_arena->active_cnt++;
- if (iobuf_arena->max_active < iobuf_arena->active_cnt)
- iobuf_arena->max_active = iobuf_arena->active_cnt;
+ /* no resetting requied for this element */
+ iobuf_arena->alloc_cnt++;
- if (iobuf_arena->passive_cnt == 0) {
- index = gf_iobuf_get_arena_index (page_size);
- if (index == -1) {
- gf_msg ("iobuf", GF_LOG_ERROR, 0,
- LG_MSG_PAGE_SIZE_EXCEEDED, "page_size (%zu) of"
- " iobufs in arena being added is greater "
- "than max available", page_size);
- goto out;
- }
+ if (iobuf_arena->max_active < iobuf_arena->active_cnt)
+ iobuf_arena->max_active = iobuf_arena->active_cnt;
- list_del (&iobuf_arena->list);
- list_add (&iobuf_arena->list, &iobuf_pool->filled[index]);
- }
+ if (iobuf_arena->passive_cnt == 0) {
+ list_del(&iobuf_arena->list);
+ list_add(&iobuf_arena->list, &iobuf_pool->filled[index]);
+ }
-out:
- return iobuf;
+ return iobuf;
}
-struct iobuf *
-iobuf_get_from_stdalloc (struct iobuf_pool *iobuf_pool, size_t page_size)
+static struct iobuf *
+iobuf_get_from_stdalloc(struct iobuf_pool *iobuf_pool, const 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;
+ 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 */
+ GF_ATOMIC_INIT(iobuf->ref, 1);
+
+ ret = 0;
out:
- if (ret && iobuf) {
- GF_FREE (iobuf->free_ptr);
- GF_FREE (iobuf);
- iobuf = NULL;
- }
+ if (ret && iobuf) {
+ GF_FREE(iobuf->free_ptr);
+ GF_FREE(iobuf);
+ iobuf = NULL;
+ }
- return iobuf;
+ return iobuf;
}
-
struct iobuf *
-iobuf_get2 (struct iobuf_pool *iobuf_pool, size_t page_size)
+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_msg_debug ("iobuf", 0, "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;
+ struct iobuf *iobuf = NULL;
+ size_t rounded_size = 0;
+ int index = 0;
+
+ if (page_size == 0) {
+ page_size = iobuf_pool->default_page_size;
+ }
+
+ rounded_size = gf_iobuf_get_pagesize(page_size, &index);
+ 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_msg_debug("iobuf", 0,
+ "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;
+ } else if (index == -1) {
+ gf_smsg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
+ "page_size=%zu", page_size, NULL);
+ return NULL;
+ }
+
+ pthread_mutex_lock(&iobuf_pool->mutex);
+ {
+ iobuf = __iobuf_get(iobuf_pool, rounded_size, index);
+ if (!iobuf) {
+ pthread_mutex_unlock(&iobuf_pool->mutex);
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND,
+ NULL);
+ goto post_unlock;
}
- 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;
+ iobuf_ref(iobuf);
+ }
+ pthread_mutex_unlock(&iobuf_pool->mutex);
+post_unlock:
+ return iobuf;
}
struct iobuf *
-iobuf_get (struct iobuf_pool *iobuf_pool)
+iobuf_get_page_aligned(struct iobuf_pool *iobuf_pool, size_t page_size,
+ size_t align_size)
{
- struct iobuf *iobuf = NULL;
- struct iobuf_arena *iobuf_arena = NULL;
+ size_t req_size = 0;
+ struct iobuf *iobuf = NULL;
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_pool, out);
+ req_size = page_size;
- pthread_mutex_lock (&iobuf_pool->mutex);
- {
- /* most eligible arena for picking an iobuf */
- iobuf_arena = __iobuf_select_arena (iobuf_pool,
- iobuf_pool->default_page_size);
- if (!iobuf_arena) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_ARENA_NOT_FOUND, "arena not found");
- goto unlock;
- }
-
- iobuf = __iobuf_get (iobuf_arena,
- iobuf_pool->default_page_size);
- if (!iobuf) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_IOBUF_NOT_FOUND, "iobuf not found");
- goto unlock;
- }
-
- iobuf_ref (iobuf);
- }
-unlock:
- pthread_mutex_unlock (&iobuf_pool->mutex);
+ if (req_size == 0) {
+ req_size = iobuf_pool->default_page_size;
+ }
-out:
- return iobuf;
+ iobuf = iobuf_get2(iobuf_pool, req_size + align_size);
+ if (!iobuf)
+ return NULL;
+ /* If std allocation was used, then free_ptr will be non-NULL. In this
+ * case, we do not want to modify the original free_ptr.
+ * On the other hand, if the buf was gotten through the available
+ * arenas, then we use iobuf->free_ptr to store the original
+ * pointer to the offset into the mmap'd block of memory and in turn
+ * reuse iobuf->ptr to hold the page-aligned address. And finally, in
+ * iobuf_put(), we copy iobuf->free_ptr into iobuf->ptr - back to where
+ * it was originally when __iobuf_get() returned this iobuf.
+ */
+ if (!iobuf->free_ptr)
+ iobuf->free_ptr = iobuf->ptr;
+ iobuf->ptr = GF_ALIGN_BUF(iobuf->ptr, align_size);
+
+ return iobuf;
}
-void
-__iobuf_put (struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)
+struct iobuf *
+iobuf_get(struct iobuf_pool *iobuf_pool)
{
- 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;
+ struct iobuf *iobuf = NULL;
+ int index = 0;
- index = gf_iobuf_get_arena_index (iobuf_arena->page_size);
- if (index == -1) {
- gf_msg_debug ("iobuf", 0, "freeing the iobuf (%p) "
- "allocated with standard calloc()", iobuf);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
- /* 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[index]);
+ index = gf_iobuf_get_arena_index(iobuf_pool->default_page_size);
+ if (index == -1) {
+ gf_smsg("iobuf", GF_LOG_ERROR, 0, LG_MSG_PAGE_SIZE_EXCEEDED,
+ "page_size=%zu", iobuf_pool->default_page_size, NULL);
+ return NULL;
+ }
+
+ pthread_mutex_lock(&iobuf_pool->mutex);
+ {
+ iobuf = __iobuf_get(iobuf_pool, iobuf_pool->default_page_size, index);
+ if (!iobuf) {
+ pthread_mutex_unlock(&iobuf_pool->mutex);
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_IOBUF_NOT_FOUND,
+ NULL);
+ goto out;
}
- list_del_init (&iobuf->list);
- iobuf_arena->active_cnt--;
-
- list_add (&iobuf->list, &iobuf_arena->passive.list);
- iobuf_arena->passive_cnt++;
+ iobuf_ref(iobuf);
+ }
+ pthread_mutex_unlock(&iobuf_pool->mutex);
- if (iobuf_arena->active_cnt == 0) {
- list_del (&iobuf_arena->list);
- list_add_tail (&iobuf_arena->list, &iobuf_pool->purge[index]);
- __iobuf_arena_prune (iobuf_pool, iobuf_arena, index);
- }
out:
- return;
+ return iobuf;
}
+static void
+__iobuf_put(struct iobuf *iobuf, struct iobuf_arena *iobuf_arena)
+{
+ struct iobuf_pool *iobuf_pool = NULL;
+ int index = 0;
+
+ iobuf_pool = iobuf_arena->iobuf_pool;
+
+ index = gf_iobuf_get_arena_index(iobuf_arena->page_size);
+ if (index == -1) {
+ gf_msg_debug("iobuf", 0,
+ "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[index]);
+ }
+
+ list_del_init(&iobuf->list);
+ iobuf_arena->active_cnt--;
+
+ if (iobuf->free_ptr) {
+ iobuf->ptr = iobuf->free_ptr;
+ iobuf->free_ptr = NULL;
+ }
+
+ list_add(&iobuf->list, &iobuf_arena->passive.list);
+ iobuf_arena->passive_cnt++;
+
+ if (iobuf_arena->active_cnt == 0) {
+ list_del(&iobuf_arena->list);
+ list_add_tail(&iobuf_arena->list, &iobuf_pool->purge[index]);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
+ __iobuf_arena_prune(iobuf_pool, iobuf_arena, index);
+ }
+out:
+ return;
+}
void
-iobuf_put (struct iobuf *iobuf)
+iobuf_put(struct iobuf *iobuf)
{
- struct iobuf_arena *iobuf_arena = NULL;
- struct iobuf_pool *iobuf_pool = NULL;
+ struct iobuf_arena *iobuf_arena = NULL;
+ struct iobuf_pool *iobuf_pool = NULL;
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
- iobuf_arena = iobuf->iobuf_arena;
- if (!iobuf_arena) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND,
- "arena not found");
- return;
- }
+ iobuf_arena = iobuf->iobuf_arena;
+ if (!iobuf_arena) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, NULL);
+ return;
+ }
- iobuf_pool = iobuf_arena->iobuf_pool;
- if (!iobuf_pool) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_POOL_NOT_FOUND, "iobuf pool not found");
- return;
- }
+ iobuf_pool = iobuf_arena->iobuf_pool;
+ if (!iobuf_pool) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND, "iobuf",
+ NULL);
+ return;
+ }
- pthread_mutex_lock (&iobuf_pool->mutex);
- {
- __iobuf_put (iobuf, iobuf_arena);
- }
- pthread_mutex_unlock (&iobuf_pool->mutex);
+ pthread_mutex_lock(&iobuf_pool->mutex);
+ {
+ __iobuf_put(iobuf, iobuf_arena);
+ }
+ pthread_mutex_unlock(&iobuf_pool->mutex);
out:
- return;
+ return;
}
-
void
-iobuf_unref (struct iobuf *iobuf)
+iobuf_unref(struct iobuf *iobuf)
{
- int ref = 0;
+ int ref = 0;
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
- LOCK (&iobuf->lock);
- {
- __iobuf_unref (iobuf);
- ref = iobuf->ref;
- }
- UNLOCK (&iobuf->lock);
+ ref = GF_ATOMIC_DEC(iobuf->ref);
- if (!ref)
- iobuf_put (iobuf);
+ if (!ref)
+ iobuf_put(iobuf);
out:
- return;
+ return;
}
-
struct iobuf *
-iobuf_ref (struct iobuf *iobuf)
+iobuf_ref(struct iobuf *iobuf)
{
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
-
- LOCK (&iobuf->lock);
- {
- __iobuf_ref (iobuf);
- }
- UNLOCK (&iobuf->lock);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
+ GF_ATOMIC_INC(iobuf->ref);
out:
- return iobuf;
+ return iobuf;
}
-
struct iobref *
-iobref_new ()
+iobref_new()
{
- struct iobref *iobref = NULL;
-
- iobref = GF_CALLOC (sizeof (*iobref), 1,
- gf_common_mt_iobref);
- if (!iobref)
- return NULL;
+ struct iobref *iobref = NULL;
- iobref->iobrefs = GF_CALLOC (sizeof (*iobref->iobrefs),
- 16, gf_common_mt_iobrefs);
- if (!iobref->iobrefs) {
- GF_FREE (iobref);
- return NULL;
- }
+ iobref = GF_MALLOC(sizeof(*iobref), gf_common_mt_iobref);
+ if (!iobref)
+ return NULL;
- iobref->alloced = 16;
- iobref->used = 0;
+ iobref->iobrefs = GF_CALLOC(sizeof(*iobref->iobrefs), 16,
+ gf_common_mt_iobrefs);
+ if (!iobref->iobrefs) {
+ GF_FREE(iobref);
+ return NULL;
+ }
- LOCK_INIT (&iobref->lock);
+ iobref->allocated = 16;
+ iobref->used = 0;
- iobref->ref++;
+ LOCK_INIT(&iobref->lock);
- return iobref;
+ GF_ATOMIC_INIT(iobref->ref, 1);
+ return iobref;
}
-
struct iobref *
-iobref_ref (struct iobref *iobref)
+iobref_ref(struct iobref *iobref)
{
- GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
-
- LOCK (&iobref->lock);
- {
- iobref->ref++;
- }
- UNLOCK (&iobref->lock);
+ GF_VALIDATE_OR_GOTO("iobuf", iobref, out);
+ GF_ATOMIC_INC(iobref->ref);
out:
- return iobref;
+ return iobref;
}
-
void
-iobref_destroy (struct iobref *iobref)
+iobref_destroy(struct iobref *iobref)
{
- int i = 0;
- struct iobuf *iobuf = NULL;
+ int i = 0;
+ struct iobuf *iobuf = NULL;
- GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobref, out);
- for (i = 0; i < iobref->alloced; i++) {
- iobuf = iobref->iobrefs[i];
+ for (i = 0; i < iobref->allocated; i++) {
+ iobuf = iobref->iobrefs[i];
- iobref->iobrefs[i] = NULL;
- if (iobuf)
- iobuf_unref (iobuf);
- }
+ iobref->iobrefs[i] = NULL;
+ if (iobuf)
+ iobuf_unref(iobuf);
+ }
- GF_FREE (iobref->iobrefs);
- GF_FREE (iobref);
+ GF_FREE(iobref->iobrefs);
+ GF_FREE(iobref);
out:
- return;
+ return;
}
-
void
-iobref_unref (struct iobref *iobref)
+iobref_unref(struct iobref *iobref)
{
- int ref = 0;
+ int ref = 0;
- GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
-
- LOCK (&iobref->lock);
- {
- ref = (--iobref->ref);
- }
- UNLOCK (&iobref->lock);
+ GF_VALIDATE_OR_GOTO("iobuf", iobref, out);
+ ref = GF_ATOMIC_DEC(iobref->ref);
- if (!ref)
- iobref_destroy (iobref);
+ if (!ref)
+ iobref_destroy(iobref);
out:
- return;
+ return;
}
-
void
-iobref_clear (struct iobref *iobref)
+iobref_clear(struct iobref *iobref)
{
- int i = 0;
+ int i = 0;
- GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobref, out);
- for (; i < iobref->alloced; i++) {
- if (iobref->iobrefs[i] != NULL) {
- iobuf_unref (iobref->iobrefs[i]);
- } else {
- /** iobuf's are attched serially */
- break;
- }
+ for (; i < iobref->allocated; i++) {
+ if (iobref->iobrefs[i] != NULL) {
+ iobuf_unref(iobref->iobrefs[i]);
+ } else {
+ /** iobuf's are attached serially */
+ break;
}
+ }
- iobref_unref (iobref);
+ iobref_unref(iobref);
- out:
- return;
+out:
+ return;
}
-
static void
-__iobref_grow (struct iobref *iobref)
+__iobref_grow(struct iobref *iobref)
{
- void *newptr = NULL;
- int i = 0;
-
- newptr = GF_REALLOC (iobref->iobrefs,
- iobref->alloced * 2 * (sizeof (*iobref->iobrefs)));
- if (newptr) {
- iobref->iobrefs = newptr;
- iobref->alloced *= 2;
-
- for (i = iobref->used; i < iobref->alloced; i++)
- iobref->iobrefs[i] = NULL;
- }
+ void *newptr = NULL;
+ int i = 0;
+
+ newptr = GF_REALLOC(iobref->iobrefs,
+ iobref->allocated * 2 * (sizeof(*iobref->iobrefs)));
+ if (newptr) {
+ iobref->iobrefs = newptr;
+ iobref->allocated *= 2;
+
+ for (i = iobref->used; i < iobref->allocated; i++)
+ iobref->iobrefs[i] = NULL;
+ }
}
-
int
-__iobref_add (struct iobref *iobref, struct iobuf *iobuf)
+__iobref_add(struct iobref *iobref, struct iobuf *iobuf)
{
- int i = 0;
- int ret = -ENOMEM;
-
- GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
-
- if (iobref->used == iobref->alloced) {
- __iobref_grow (iobref);
-
- if (iobref->used == iobref->alloced) {
- ret = -ENOMEM;
- goto out;
- }
- }
-
- for (i = 0; i < iobref->alloced; i++) {
- if (iobref->iobrefs[i] == NULL) {
- iobref->iobrefs[i] = iobuf_ref (iobuf);
- iobref->used++;
- ret = 0;
- break;
- }
+ int i = 0;
+ int ret = -ENOMEM;
+
+ GF_VALIDATE_OR_GOTO("iobuf", iobref, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
+
+ if (iobref->used == iobref->allocated) {
+ __iobref_grow(iobref);
+
+ if (iobref->used == iobref->allocated) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ }
+
+ for (i = 0; i < iobref->allocated; i++) {
+ if (iobref->iobrefs[i] == NULL) {
+ iobref->iobrefs[i] = iobuf_ref(iobuf);
+ iobref->used++;
+ ret = 0;
+ break;
}
+ }
out:
- return ret;
+ return ret;
}
-
int
-iobref_add (struct iobref *iobref, struct iobuf *iobuf)
+iobref_add(struct iobref *iobref, struct iobuf *iobuf)
{
- int ret = -EINVAL;
+ int ret = -EINVAL;
- GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobref, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
- LOCK (&iobref->lock);
- {
- ret = __iobref_add (iobref, iobuf);
- }
- UNLOCK (&iobref->lock);
+ LOCK(&iobref->lock);
+ {
+ ret = __iobref_add(iobref, iobuf);
+ }
+ UNLOCK(&iobref->lock);
out:
- return ret;
+ return ret;
}
-
int
-iobref_merge (struct iobref *to, struct iobref *from)
+iobref_merge(struct iobref *to, struct iobref *from)
{
- int i = 0;
- int ret = -1;
- struct iobuf *iobuf = NULL;
+ int i = 0;
+ int ret = 0;
+ struct iobuf *iobuf = NULL;
- GF_VALIDATE_OR_GOTO ("iobuf", to, out);
- GF_VALIDATE_OR_GOTO ("iobuf", from, out);
+ GF_VALIDATE_OR_GOTO("iobuf", to, out);
+ GF_VALIDATE_OR_GOTO("iobuf", from, out);
- LOCK (&from->lock);
- {
- for (i = 0; i < from->alloced; i++) {
- iobuf = from->iobrefs[i];
+ LOCK(&from->lock);
+ {
+ for (i = 0; i < from->allocated; i++) {
+ iobuf = from->iobrefs[i];
- if (!iobuf)
- break;
+ if (!iobuf)
+ break;
- ret = iobref_add (to, iobuf);
+ ret = iobref_add(to, iobuf);
- if (ret < 0)
- break;
- }
+ if (ret < 0)
+ break;
}
- UNLOCK (&from->lock);
+ }
+ UNLOCK(&from->lock);
out:
- return ret;
+ return ret;
}
-
size_t
-iobuf_size (struct iobuf *iobuf)
+iobuf_size(struct iobuf *iobuf)
{
- size_t size = 0;
+ size_t size = 0;
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
- if (!iobuf->iobuf_arena) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND,
- "arena not found");
- goto out;
- }
+ if (!iobuf->iobuf_arena) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_ARENA_NOT_FOUND, NULL);
+ goto out;
+ }
- if (!iobuf->iobuf_arena->iobuf_pool) {
- gf_msg (THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND,
- "pool not found");
- goto out;
- }
+ if (!iobuf->iobuf_arena->iobuf_pool) {
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_POOL_NOT_FOUND, NULL);
+ goto out;
+ }
- size = iobuf->iobuf_arena->page_size;
+ size = iobuf->iobuf_arena->page_size;
out:
- return size;
+ return size;
}
-
size_t
-iobref_size (struct iobref *iobref)
+iobref_size(struct iobref *iobref)
{
- size_t size = 0;
- int i = 0;
+ size_t size = 0;
+ int i = 0;
- GF_VALIDATE_OR_GOTO ("iobuf", iobref, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iobref, out);
- LOCK (&iobref->lock);
- {
- for (i = 0; i < iobref->alloced; i++) {
- if (iobref->iobrefs[i])
- size += iobuf_size (iobref->iobrefs[i]);
- }
+ LOCK(&iobref->lock);
+ {
+ for (i = 0; i < iobref->allocated; i++) {
+ if (iobref->iobrefs[i])
+ size += iobuf_size(iobref->iobrefs[i]);
}
- UNLOCK (&iobref->lock);
+ }
+ UNLOCK(&iobref->lock);
out:
- return size;
+ return size;
}
void
-iobuf_info_dump (struct iobuf *iobuf, const char *key_prefix)
+iobuf_info_dump(struct iobuf *iobuf, const char *key_prefix)
{
- char key[GF_DUMP_MAX_BUF_LEN];
- struct iobuf my_iobuf;
- int ret = 0;
-
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf, out);
+ char key[GF_DUMP_MAX_BUF_LEN];
+ struct iobuf my_iobuf;
+ int ret = 0;
- memset(&my_iobuf, 0, sizeof(my_iobuf));
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf, out);
- ret = TRY_LOCK(&iobuf->lock);
- if (ret) {
- return;
- }
- memcpy(&my_iobuf, iobuf, sizeof(my_iobuf));
- UNLOCK(&iobuf->lock);
+ ret = TRY_LOCK(&iobuf->lock);
+ if (ret) {
+ return;
+ }
+ memcpy(&my_iobuf, iobuf, sizeof(my_iobuf));
+ UNLOCK(&iobuf->lock);
- gf_proc_dump_build_key(key, key_prefix,"ref");
- gf_proc_dump_write(key, "%d", my_iobuf.ref);
- gf_proc_dump_build_key(key, key_prefix,"ptr");
- gf_proc_dump_write(key, "%p", my_iobuf.ptr);
+ gf_proc_dump_build_key(key, key_prefix, "ref");
+ gf_proc_dump_write(key, "%" GF_PRI_ATOMIC, GF_ATOMIC_GET(my_iobuf.ref));
+ gf_proc_dump_build_key(key, key_prefix, "ptr");
+ gf_proc_dump_write(key, "%p", my_iobuf.ptr);
out:
- return;
+ return;
}
void
-iobuf_arena_info_dump (struct iobuf_arena *iobuf_arena, const char *key_prefix)
+iobuf_arena_info_dump(struct iobuf_arena *iobuf_arena, const char *key_prefix)
{
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 1;
- struct iobuf *trav;
-
- GF_VALIDATE_OR_GOTO ("iobuf", iobuf_arena, out);
-
- gf_proc_dump_build_key(key, key_prefix,"mem_base");
- gf_proc_dump_write(key, "%p", iobuf_arena->mem_base);
- gf_proc_dump_build_key(key, key_prefix, "active_cnt");
- 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);
- iobuf_info_dump(trav, key);
- }
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i = 1;
+ struct iobuf *trav;
+
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_arena, out);
+
+ gf_proc_dump_build_key(key, key_prefix, "mem_base");
+ gf_proc_dump_write(key, "%p", iobuf_arena->mem_base);
+ gf_proc_dump_build_key(key, key_prefix, "active_cnt");
+ 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, "%d", iobuf_arena->max_active);
+ gf_proc_dump_build_key(key, key_prefix, "page_size");
+ gf_proc_dump_write(key, "%" GF_PRI_SIZET, 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("%s", key);
+ iobuf_info_dump(trav, key);
+ }
out:
- return;
+ return;
}
void
-iobuf_stats_dump (struct iobuf_pool *iobuf_pool)
+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);
+ char msg[1024];
+ struct iobuf_arena *trav = NULL;
+ int i = 1;
+ int j = 0;
+ int ret = -1;
- memset(msg, 0, sizeof(msg));
+ GF_VALIDATE_OR_GOTO("iobuf", iobuf_pool, out);
- ret = pthread_mutex_trylock(&iobuf_pool->mutex);
+ ret = pthread_mutex_trylock(&iobuf_pool->mutex);
- if (ret) {
- return;
+ if (ret) {
+ return;
+ }
+ gf_proc_dump_add_section("iobuf.global");
+ gf_proc_dump_write("iobuf_pool", "%p", iobuf_pool);
+ gf_proc_dump_write("iobuf_pool.default_page_size", "%" GF_PRI_SIZET,
+ iobuf_pool->default_page_size);
+ gf_proc_dump_write("iobuf_pool.arena_size", "%" GF_PRI_SIZET,
+ iobuf_pool->arena_size);
+ 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("%s", msg);
+ iobuf_arena_info_dump(trav, msg);
+ i++;
}
- gf_proc_dump_add_section("iobuf.global");
- 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_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->purge[j], list)
+ {
+ snprintf(msg, sizeof(msg), "purge.%d", i);
+ gf_proc_dump_add_section("%s", 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("%s", msg);
+ iobuf_arena_info_dump(trav, msg);
+ i++;
+ }
+ }
- pthread_mutex_unlock(&iobuf_pool->mutex);
+ pthread_mutex_unlock(&iobuf_pool->mutex);
out:
- return;
+ return;
}
-
void
iobuf_to_iovec(struct iobuf *iob, struct iovec *iov)
{
- GF_VALIDATE_OR_GOTO ("iobuf", iob, out);
- GF_VALIDATE_OR_GOTO ("iobuf", iov, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iob, out);
+ GF_VALIDATE_OR_GOTO("iobuf", iov, out);
- iov->iov_base = iobuf_ptr (iob);
- iov->iov_len = iobuf_pagesize (iob);
+ iov->iov_base = iobuf_ptr(iob);
+ iov->iov_len = iobuf_pagesize(iob);
out:
- return;
+ return;
+}
+
+int
+iobuf_copy(struct iobuf_pool *iobuf_pool, const struct iovec *iovec_src,
+ int iovcnt, struct iobref **iobref, struct iobuf **iobuf,
+ struct iovec *iov_dst)
+{
+ size_t size = -1;
+ int ret = 0;
+
+ size = iov_length(iovec_src, iovcnt);
+
+ *iobuf = iobuf_get2(iobuf_pool, size);
+ if (!(*iobuf)) {
+ ret = -1;
+ errno = ENOMEM;
+ goto out;
+ }
+
+ *iobref = iobref_new();
+ if (!(*iobref)) {
+ iobuf_unref(*iobuf);
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
+
+ ret = iobref_add(*iobref, *iobuf);
+ if (ret) {
+ iobuf_unref(*iobuf);
+ iobref_unref(*iobref);
+ errno = ENOMEM;
+ ret = -1;
+ goto out;
+ }
+
+ iov_unload(iobuf_ptr(*iobuf), iovec_src, iovcnt);
+
+ iov_dst->iov_base = iobuf_ptr(*iobuf);
+ iov_dst->iov_len = size;
+
+out:
+ return ret;
}
diff --git a/libglusterfs/src/iobuf.h b/libglusterfs/src/iobuf.h
deleted file mode 100644
index 7e5cfe37a28..00000000000
--- a/libglusterfs/src/iobuf.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- 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_
-#define _IOBUF_H_
-
-#include "list.h"
-#include "common-utils.h"
-#include <pthread.h>
-#include <sys/mman.h>
-#include <sys/uio.h>
-
-#define GF_VARIABLE_IOBUF_COUNT 32
-
-#define GF_RDMA_DEVICE_COUNT 8
-
-/* Lets try to define the new anonymous mapping
- * flag, in case the system is still using the
- * now deprecated MAP_ANON flag.
- *
- * Also, this should ideally be in a centralized/common
- * header which can be used by other source files also.
- */
-#ifndef MAP_ANONYMOUS
-#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;
-
-/* one region of memory MMAPed from the operating system */
-/* each region MMAPs @arena_size bytes of memory */
-/* each arena hosts @arena_size / @page_size IOBUFs */
-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 {
- struct list_head list;
- struct {
- struct iobuf *next;
- struct iobuf *prev;
- };
- };
- struct iobuf_arena *iobuf_arena;
-
- gf_lock_t lock; /* for ->ptr and ->ref */
- 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 */
-};
-
-
-struct iobuf_arena {
- union {
- struct list_head list;
- struct {
- struct iobuf_arena *next;
- struct iobuf_arena *prev;
- };
- };
-
- struct list_head all_list;
- 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;
- struct iobuf *iobufs; /* allocated iobufs list */
-
- int active_cnt;
- struct iobuf active; /* head node iobuf
- (unused by itself) */
- 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 arena_size; /* size of memory region in
- arena */
- size_t default_page_size; /* default size of iobuf */
-
- int arena_cnt;
- struct list_head all_arenas;
- 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 */
- int rdma_device_count;
- struct list_head *mr_list[GF_RDMA_DEVICE_COUNT];
- void *device[GF_RDMA_DEVICE_COUNT];
- int (*rdma_registration)(void **, void*);
- int (*rdma_deregistration)(struct list_head**, struct iobuf_arena *);
-
-};
-
-
-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);
-struct iobuf *iobuf_ref (struct iobuf *iobuf);
-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_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;
- int alloced;
- int used;
-};
-
-struct iobref *iobref_new ();
-struct iobref *iobref_ref (struct iobref *iobref);
-void iobref_unref (struct iobref *iobref);
-int iobref_add (struct iobref *iobref, struct iobuf *iobuf);
-int iobref_merge (struct iobref *to, struct iobref *from);
-void iobref_clear (struct iobref *iobref);
-
-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 611615949fa..ce4b0e8255d 100644
--- a/libglusterfs/src/latency.c
+++ b/libglusterfs/src/latency.c
@@ -8,183 +8,77 @@
cases as published by the Free Software Foundation.
*/
-
/*
* This file contains functions to support dumping of
* latencies of FOPs broken down by subvolumes.
*/
-#include "glusterfs.h"
-#include "stack.h"
-#include "xlator.h"
-#include "common-utils.h"
-#include "statedump.h"
-#include "libglusterfs-messages.h"
-
-void
-gf_set_fop_from_fn_pointer (call_frame_t *frame, struct xlator_fops *fops, void *fn)
-{
- glusterfs_fop_t fop = -1;
-
- if (fops->stat == *(fop_stat_t *)&fn)
- fop = GF_FOP_STAT;
- else if (fops->readlink == *(fop_readlink_t *)&fn)
- fop = GF_FOP_READLINK;
- else if (fops->mknod == *(fop_mknod_t *)&fn)
- fop = GF_FOP_MKNOD;
- else if (fops->mkdir == *(fop_mkdir_t *)&fn)
- fop = GF_FOP_MKDIR;
- else if (fops->unlink == *(fop_unlink_t *)&fn)
- fop = GF_FOP_UNLINK;
- else if (fops->rmdir == *(fop_rmdir_t *)&fn)
- fop = GF_FOP_RMDIR;
- else if (fops->symlink == *(fop_symlink_t *)&fn)
- fop = GF_FOP_SYMLINK;
- else if (fops->rename == *(fop_rename_t *)&fn)
- fop = GF_FOP_RENAME;
- else if (fops->link == *(fop_link_t *)&fn)
- fop = GF_FOP_LINK;
- else if (fops->truncate == *(fop_truncate_t *)&fn)
- fop = GF_FOP_TRUNCATE;
- else if (fops->open == *(fop_open_t *)&fn)
- fop = GF_FOP_OPEN;
- else if (fops->readv == *(fop_readv_t *)&fn)
- fop = GF_FOP_READ;
- else if (fops->writev == *(fop_writev_t *)&fn)
- fop = GF_FOP_WRITE;
- else if (fops->statfs == *(fop_statfs_t *)&fn)
- fop = GF_FOP_STATFS;
- else if (fops->flush == *(fop_flush_t *)&fn)
- fop = GF_FOP_FLUSH;
- else if (fops->fsync == *(fop_fsync_t *)&fn)
- fop = GF_FOP_FSYNC;
- else if (fops->setxattr == *(fop_setxattr_t *)&fn)
- fop = GF_FOP_SETXATTR;
- else if (fops->getxattr == *(fop_getxattr_t *)&fn)
- fop = GF_FOP_GETXATTR;
- else if (fops->removexattr == *(fop_removexattr_t *)&fn)
- fop = GF_FOP_REMOVEXATTR;
- else if (fops->opendir == *(fop_opendir_t *)&fn)
- fop = GF_FOP_OPENDIR;
- else if (fops->fsyncdir == *(fop_fsyncdir_t *)&fn)
- fop = GF_FOP_FSYNCDIR;
- else if (fops->access == *(fop_access_t *)&fn)
- fop = GF_FOP_ACCESS;
- else if (fops->create == *(fop_create_t *)&fn)
- fop = GF_FOP_CREATE;
- else if (fops->ftruncate == *(fop_ftruncate_t *)&fn)
- fop = GF_FOP_FTRUNCATE;
- else if (fops->fstat == *(fop_fstat_t *)&fn)
- fop = GF_FOP_FSTAT;
- else if (fops->lk == *(fop_lk_t *)&fn)
- fop = GF_FOP_LK;
- else if (fops->lookup == *(fop_lookup_t *)&fn)
- fop = GF_FOP_LOOKUP;
- else if (fops->readdir == *(fop_readdir_t *)&fn)
- fop = GF_FOP_READDIR;
- else if (fops->inodelk == *(fop_inodelk_t *)&fn)
- fop = GF_FOP_INODELK;
- else if (fops->finodelk == *(fop_finodelk_t *)&fn)
- fop = GF_FOP_FINODELK;
- else if (fops->entrylk == *(fop_entrylk_t *)&fn)
- fop = GF_FOP_ENTRYLK;
- else if (fops->fentrylk == *(fop_fentrylk_t *)&fn)
- fop = GF_FOP_FENTRYLK;
- else if (fops->xattrop == *(fop_xattrop_t *)&fn)
- fop = GF_FOP_XATTROP;
- else if (fops->fxattrop == *(fop_fxattrop_t *)&fn)
- fop = GF_FOP_FXATTROP;
- else if (fops->fgetxattr == *(fop_fgetxattr_t *)&fn)
- fop = GF_FOP_FGETXATTR;
- else if (fops->fsetxattr == *(fop_fsetxattr_t *)&fn)
- fop = GF_FOP_FSETXATTR;
- else if (fops->rchecksum == *(fop_rchecksum_t *)&fn)
- fop = GF_FOP_RCHECKSUM;
- else if (fops->setattr == *(fop_setattr_t *)&fn)
- fop = GF_FOP_SETATTR;
- else if (fops->fsetattr == *(fop_fsetattr_t *)&fn)
- fop = GF_FOP_FSETATTR;
- else if (fops->readdirp == *(fop_readdirp_t *)&fn)
- fop = GF_FOP_READDIRP;
- else if (fops->getspec == *(fop_getspec_t *)&fn)
- fop = GF_FOP_GETSPEC;
- else
- fop = -1;
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/statedump.h"
- frame->op = fop;
-}
-
-
-void
-gf_update_latency (call_frame_t *frame)
+gf_latency_t *
+gf_latency_new(size_t n)
{
- double elapsed;
- struct timeval *begin, *end;
-
- fop_latency_t *lat;
+ int i = 0;
+ gf_latency_t *lat = NULL;
- begin = &frame->begin;
- end = &frame->end;
+ lat = GF_MALLOC(n * sizeof(*lat), gf_common_mt_latency_t);
+ if (!lat)
+ return NULL;
- elapsed = (end->tv_sec - begin->tv_sec) * 1e6
- + (end->tv_usec - begin->tv_usec);
-
- lat = &frame->this->latencies[frame->op];
-
- lat->total += elapsed;
- lat->count++;
- lat->mean = lat->mean + (elapsed - lat->mean) / lat->count;
+ for (i = 0; i < n; i++) {
+ gf_latency_reset(lat + i);
+ }
+ return lat;
}
void
-gf_latency_begin (call_frame_t *frame, void *fn)
+gf_latency_update(gf_latency_t *lat, struct timespec *begin,
+ struct timespec *end)
{
- gf_set_fop_from_fn_pointer (frame, frame->this->fops, fn);
+ if (!(begin->tv_sec && end->tv_sec)) {
+ /*Measure latency might have been enabled/disabled during the op*/
+ return;
+ }
- gettimeofday (&frame->begin, NULL);
-}
+ double elapsed = gf_tsdiff(begin, end);
+ if (lat->max < elapsed)
+ lat->max = elapsed;
-void
-gf_latency_end (call_frame_t *frame)
-{
- gettimeofday (&frame->end, NULL);
+ if (lat->min > elapsed)
+ lat->min = elapsed;
- gf_update_latency (frame);
+ lat->total += elapsed;
+ lat->count++;
}
void
-gf_proc_dump_latency_info (xlator_t *xl)
+gf_latency_reset(gf_latency_t *lat)
{
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
- char key[GF_DUMP_MAX_BUF_LEN];
- int i;
-
- snprintf (key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.latency", xl->name);
- gf_proc_dump_add_section (key_prefix);
-
- for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- gf_proc_dump_build_key (key, key_prefix,
- (char *)gf_fop_list[i]);
-
- gf_proc_dump_write (key, "%.03f,%"PRId64",%.03f",
- xl->latencies[i].mean,
- xl->latencies[i].count,
- xl->latencies[i].total);
- }
-
- memset (xl->latencies, 0, sizeof (xl->latencies));
+ if (!lat)
+ return;
+ memset(lat, 0, sizeof(*lat));
+ lat->min = ULLONG_MAX;
+ /* make sure 'min' is set to high value, so it would be
+ properly set later */
}
-
void
-gf_latency_toggle (int signum, glusterfs_ctx_t *ctx)
+gf_frame_latency_update(call_frame_t *frame)
{
- if (ctx) {
- ctx->measure_latency = !ctx->measure_latency;
- gf_msg ("[core]", GF_LOG_INFO, 0,
- LG_MSG_LATENCY_MEASUREMENT_STATE,
- "Latency measurement turned %s",
- ctx->measure_latency ? "on" : "off");
- }
+ gf_latency_t *lat;
+ /* Can happen mostly at initiator xlator, as STACK_WIND/UNWIND macros
+ set it right anyways for those frames */
+ if (!frame->op)
+ frame->op = frame->root->op;
+
+ if (frame->op < 0 || frame->op >= GF_FOP_MAXVALUE) {
+ gf_log("[core]", GF_LOG_WARNING, "Invalid frame op value: %d",
+ frame->op);
+ return;
+ }
+
+ lat = &frame->this->stats.interval.latencies[frame->op];
+ gf_latency_update(lat, &frame->begin, &frame->end);
}
diff --git a/libglusterfs/src/latency.h b/libglusterfs/src/latency.h
deleted file mode 100644
index 81acbf48478..00000000000
--- a/libglusterfs/src/latency.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- 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 __LATENCY_H__
-#define __LATENCY_H__
-
-#include "glusterfs.h"
-
-typedef struct fop_latency {
- uint64_t min; /* min time for the call (microseconds) */
- uint64_t max; /* max time for the call (microseconds) */
- double total; /* total time (microseconds) */
- double std; /* standard deviation */
- double mean; /* mean (microseconds) */
- uint64_t count;
-} fop_latency_t;
-
-void
-gf_latency_toggle (int signum, glusterfs_ctx_t *ctx);
-
-#endif /* __LATENCY_H__ */
diff --git a/libglusterfs/src/libglusterfs-messages.h b/libglusterfs/src/libglusterfs-messages.h
deleted file mode 100644
index 68754e6b869..00000000000
--- a/libglusterfs/src/libglusterfs-messages.h
+++ /dev/null
@@ -1,1756 +0,0 @@
-/*
- Copyright (c) 2015 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 _LG_MESSAGES_H_
-#define _LG_MESSAGES_H_
-
-#include "glfs-message-id.h"
-
-/* NOTE: Rules for message additions
- * 1) Each instance of a message is _better_ left with a unique message ID, even
- * if the message format is the same. Reasoning is that, if the message
- * format needs to change in one instance, the other instances are not
- * impacted or the new change does not change the ID of the instance being
- * modified.
- * 2) Addition of a message,
- * - Should increment the GLFS_NUM_MESSAGES
- * - Append to the list of messages defined, towards the end
- * - Retain macro naming as glfs_msg_X (for redability across developers)
- * NOTE: Rules for message format modifications
- * 3) Check acorss the code if the message ID macro in question is reused
- * anywhere. If reused then then the modifications should ensure correctness
- * everywhere, or needs a new message ID as (1) above was not adhered to. If
- * not used anywhere, proceed with the required modification.
- * NOTE: Rules for message deletion
- * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
- * anywhere, then can be deleted, but will leave a hole by design, as
- * addition rules specify modification to the end of the list and not filling
- * holes.
- */
-
-#define GLFS_LG_BASE GLFS_MSGID_COMP_LIBGLUSTERFS
-#define GLFS_LG_NUM_MESSAGES 204
-#define GLFS_LG_MSGID_END (GLFS_LG_BASE + GLFS_LG_NUM_MESSAGES + 1)
-/* Messaged with message IDs */
-#define glfs_msg_start_lg GLFS_LG_BASE, "Invalid: Start of messages"
-/*------------*/
-
-#define LG_MSG_ASPRINTF_FAILED (GLFS_LG_BASE + 1)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INVALID_ENTRY (GLFS_LG_BASE + 2)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_COUNT_LESS_THAN_ZERO (GLFS_LG_BASE + 3)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_COUNT_LESS_THAN_DATA_PAIRS (GLFS_LG_BASE + 4)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_VALUE_LENGTH_LESS_THAN_ZERO (GLFS_LG_BASE + 5)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_PAIRS_LESS_THAN_COUNT (GLFS_LG_BASE + 6)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_KEY_OR_VALUE_NULL (GLFS_LG_BASE + 7)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_FAILED_TO_LOG_DICT (GLFS_LG_BASE + 8)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_NULL_VALUE_IN_DICT (GLFS_LG_BASE + 9)
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DIR_OP_FAILED (GLFS_LG_BASE + 10)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_STORE_HANDLE_CREATE_FAILED (GLFS_LG_BASE + 11)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_FILE_OP_FAILED (GLFS_LG_BASE + 12)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_FILE_STAT_FAILED (GLFS_LG_BASE + 13)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_LOCK_FAILED (GLFS_LG_BASE + 14)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_UNLOCK_FAILED (GLFS_LG_BASE + 15)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DICT_SERIAL_FAILED (GLFS_LG_BASE + 16)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DICT_UNSERIAL_FAILED (GLFS_LG_BASE + 17)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_NO_MEMORY (GLFS_LG_BASE + 18)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_VOLUME_ERROR (GLFS_LG_BASE + 19)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_SUB_VOLUME_ERROR (GLFS_LG_BASE + 20)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_SYNTAX_ERROR (GLFS_LG_BASE + 21)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_BACKTICK_PARSE_FAILED (GLFS_LG_BASE + 22)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_BUFFER_ERROR (GLFS_LG_BASE + 23)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_STRDUP_ERROR (GLFS_LG_BASE + 24)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_HASH_FUNC_ERROR (GLFS_LG_BASE + 25)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_GET_BUCKET_FAILED (GLFS_LG_BASE + 26)
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INSERT_FAILED (GLFS_LG_BASE + 27)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_OUT_OF_RANGE (GLFS_LG_BASE + 28)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_VALIDATE_RETURNS (GLFS_LG_BASE + 29)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_VALIDATE_REC_FAILED (GLFS_LG_BASE + 30)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_RB_TABLE_CREATE_FAILED (GLFS_LG_BASE + 31)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-
-#define LG_MSG_PATH_NOT_FOUND (GLFS_LG_BASE + 32)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_EXPAND_FD_TABLE_FAILED (GLFS_LG_BASE + 33)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_MAPPING_FAILED (GLFS_LG_BASE + 34)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INIT_IOBUF_FAILED (GLFS_LG_BASE + 35)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_PAGE_SIZE_EXCEEDED (GLFS_LG_BASE + 36)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_ARENA_NOT_FOUND (GLFS_LG_BASE + 37)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_IOBUF_NOT_FOUND (GLFS_LG_BASE + 38)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_POOL_NOT_FOUND (GLFS_LG_BASE + 39)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_SET_ATTRIBUTE_FAILED (GLFS_LG_BASE + 40)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_READ_ATTRIBUTE_FAILED (GLFS_LG_BASE + 41)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_UNMOUNT_FAILED (GLFS_LG_BASE + 42)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_LATENCY_MEASUREMENT_STATE (GLFS_LG_BASE + 43)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_NO_PERM (GLFS_LG_BASE + 44)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_NO_KEY (GLFS_LG_BASE + 45)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DICT_NULL (GLFS_LG_BASE + 46)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INIT_TIMER_FAILED (GLFS_LG_BASE + 47)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_FD_ANONYMOUS_FAILED (GLFS_LG_BASE + 48)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_FD_CREATE_FAILED (GLFS_LG_BASE + 49)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_BUFFER_FULL (GLFS_LG_BASE + 50)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_FWRITE_FAILED (GLFS_LG_BASE + 51)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_PRINT_FAILED (GLFS_LG_BASE + 52)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_MEM_POOL_DESTROY (GLFS_LG_BASE + 53)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_EXPAND_CLIENT_TABLE_FAILED (GLFS_LG_BASE + 54)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DISCONNECT_CLIENT (GLFS_LG_BASE + 55)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_PIPE_CREATE_FAILED (GLFS_LG_BASE + 56)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_SET_PIPE_FAILED (GLFS_LG_BASE + 57)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_REGISTER_PIPE_FAILED (GLFS_LG_BASE + 58)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_POLL_IGNORE_MULTIPLE_THREADS (GLFS_LG_BASE + 59)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INDEX_NOT_FOUND (GLFS_LG_BASE + 60)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_EPOLL_FD_CREATE_FAILED (GLFS_LG_BASE + 61)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_SLOT_NOT_FOUND (GLFS_LG_BASE + 62)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
- #define LG_MSG_STALE_FD_FOUND (GLFS_LG_BASE + 63)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_GENERATION_MISMATCH (GLFS_LG_BASE + 64)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_PTHREAD_KEY_CREATE_FAILED (GLFS_LG_BASE + 65)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_TRANSLATOR_INIT_FAILED (GLFS_LG_BASE + 66)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_UUID_BUF_INIT_FAILED (GLFS_LG_BASE + 67)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_LKOWNER_BUF_INIT_FAILED (GLFS_LG_BASE + 68)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_SYNCTASK_INIT_FAILED (GLFS_LG_BASE + 69)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_SYNCOPCTX_INIT_FAILED (GLFS_LG_BASE + 70)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_GLOBAL_INIT_FAILED (GLFS_LG_BASE + 71)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_PTHREAD_FAILED (GLFS_LG_BASE + 72)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DIR_IS_SYMLINK (GLFS_LG_BASE + 73)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_RESOLVE_HOSTNAME_FAILED (GLFS_LG_BASE + 74)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_GETADDRINFO_FAILED (GLFS_LG_BASE + 75)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_GETNAMEINFO_FAILED (GLFS_LG_BASE + 76)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_PATH_ERROR (GLFS_LG_BASE + 77)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INET_PTON_FAILED (GLFS_LG_BASE + 78)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_NEGATIVE_NUM_PASSED (GLFS_LG_BASE + 79)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_GETHOSTNAME_FAILED (GLFS_LG_BASE + 80)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_RESERVED_PORTS_ERROR (GLFS_LG_BASE + 81)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INVALID_PORT (GLFS_LG_BASE + 82)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INVALID_FAMILY (GLFS_LG_BASE + 83)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_CONVERSION_FAILED (GLFS_LG_BASE + 84)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_SKIP_HEADER_FAILED (GLFS_LG_BASE + 85)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INVALID_LOG (GLFS_LG_BASE + 86)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_UTIMES_FAILED (GLFS_LG_BASE + 87)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_BACKTRACE_SAVE_FAILED (GLFS_LG_BASE + 88)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INIT_FAILED (GLFS_LG_BASE + 89)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_VALIDATION_FAILED (GLFS_LG_BASE + 90)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_GRAPH_ERROR (GLFS_LG_BASE + 91)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_UNKNOWN_OPTIONS_FAILED (GLFS_LG_BASE + 92)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_CTX_NULL (GLFS_LG_BASE + 93)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_TMPFILE_CREATE_FAILED (GLFS_LG_BASE + 94)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_DLOPEN_FAILED (GLFS_LG_BASE + 95)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_LOAD_FAILED (GLFS_LG_BASE + 96)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_DLSYM_ERROR (GLFS_LG_BASE + 97)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_TREE_NOT_FOUND (GLFS_LG_BASE + 98)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_PER_DENTRY (GLFS_LG_BASE + 99)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_DENTRY (GLFS_LG_BASE + 100)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_GETIFADDRS_FAILED (GLFS_LG_BASE + 101)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_REGEX_OP_FAILED (GLFS_LG_BASE + 102)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_FRAME_ERROR (GLFS_LG_BASE + 103)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_SET_PARAM_FAILED (GLFS_LG_BASE + 104)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_GET_PARAM_FAILED (GLFS_LG_BASE + 105)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_PREPARE_FAILED (GLFS_LG_BASE + 106)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_EXEC_FAILED (GLFS_LG_BASE + 107)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_BINDING_FAILED (GLFS_LG_BASE + 108)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_DELETE_FAILED (GLFS_LG_BASE + 109)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_GET_ID_FAILED (GLFS_LG_BASE + 110)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_CREATE_FAILED (GLFS_LG_BASE + 111)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_PARSE_FAILED (GLFS_LG_BASE + 112)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-
-#define LG_MSG_GETCONTEXT_FAILED (GLFS_LG_BASE + 113)
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_UPDATE_FAILED (GLFS_LG_BASE + 114)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_QUERY_CALL_BACK_FAILED (GLFS_LG_BASE + 115)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_GET_RECORD_FAILED (GLFS_LG_BASE + 116)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_DB_ERROR (GLFS_LG_BASE + 117)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_CONNECTION_ERROR (GLFS_LG_BASE + 118)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_NOT_MULTITHREAD_MODE (GLFS_LG_BASE + 119)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_SKIP_PATH (GLFS_LG_BASE + 120)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INVALID_FOP (GLFS_LG_BASE + 121)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_QUERY_FAILED (GLFS_LG_BASE + 122)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_CLEAR_COUNTER_FAILED (GLFS_LG_BASE + 123)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_LOCK_LIST_FAILED (GLFS_LG_BASE + 124)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_UNLOCK_LIST_FAILED (GLFS_LG_BASE + 125)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_ADD_TO_LIST_FAILED (GLFS_LG_BASE + 126)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INIT_DB_FAILED (GLFS_LG_BASE + 127)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_DELETE_FROM_LIST_FAILED (GLFS_LG_BASE + 128)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_CLOSE_CONNECTION_FAILED (GLFS_LG_BASE + 129)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INSERT_OR_UPDATE_FAILED (GLFS_LG_BASE + 130)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_FIND_OP_FAILED (GLFS_LG_BASE + 131)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_CONNECTION_INIT_FAILED (GLFS_LG_BASE + 132)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_COMPLETED_TASK (GLFS_LG_BASE + 133)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_WAKE_UP_ZOMBIE (GLFS_LG_BASE + 134)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_REWAITING_TASK (GLFS_LG_BASE + 135)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_SLEEP_ZOMBIE (GLFS_LG_BASE + 136)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_SWAPCONTEXT_FAILED (GLFS_LG_BASE + 137)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_UNSUPPORTED_PLUGIN (GLFS_LG_BASE + 138)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INVALID_DB_TYPE (GLFS_LG_BASE + 139)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_UNDERSIZED_BUF (GLFS_LG_BASE + 140)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DATA_CONVERSION_ERROR (GLFS_LG_BASE + 141)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DICT_ERROR (GLFS_LG_BASE + 142)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_IOBUFS_NOT_FOUND (GLFS_LG_BASE + 143)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_ENTRIES_NULL (GLFS_LG_BASE + 144)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_FD_NOT_FOUND_IN_FDTABLE (GLFS_LG_BASE + 145)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_REALLOC_FOR_FD_PTR_FAILED (GLFS_LG_BASE + 146)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DICT_SET_FAILED (GLFS_LG_BASE + 147)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_NULL_PTR (GLFS_LG_BASE + 148)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_RBTHASH_INIT_BUCKET_FAILED (GLFS_LG_BASE + 149)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_ASSERTION_FAILED (GLFS_LG_BASE + 150)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_HOSTNAME_NULL (GLFS_LG_BASE + 151)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INVALID_IPV4_FORMAT (GLFS_LG_BASE + 152)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_CTX_CLEANUP_STARTED (GLFS_LG_BASE + 153)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_TIMER_REGISTER_ERROR (GLFS_LG_BASE + 154)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_PTR_HEADER_CORRUPTED (GLFS_LG_BASE + 155)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INVALID_UPLINK (GLFS_LG_BASE + 156)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_CLIENT_NULL (GLFS_LG_BASE + 157)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_XLATOR_DOES_NOT_IMPLEMENT (GLFS_LG_BASE + 158)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DENTRY_NOT_FOUND (GLFS_LG_BASE + 159)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INODE_NOT_FOUND (GLFS_LG_BASE + 160)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INODE_TABLE_NOT_FOUND (GLFS_LG_BASE + 161)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DENTRY_CREATE_FAILED (GLFS_LG_BASE + 162)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INODE_CONTEXT_FREED (GLFS_LG_BASE + 163)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_UNKNOWN_LOCK_TYPE (GLFS_LG_BASE + 164)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_UNLOCK_BEFORE_LOCK (GLFS_LG_BASE + 165)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_LOCK_OWNER_ERROR (GLFS_LG_BASE + 166)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_MEMPOOL_PTR_NULL (GLFS_LG_BASE + 167)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_QUOTA_XATTRS_MISSING (GLFS_LG_BASE + 168)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INVALID_STRING (GLFS_LG_BASE + 169)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_BIND_REF (GLFS_LG_BASE + 170)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_REF_COUNT (GLFS_LG_BASE + 171)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INVALID_ARG (GLFS_LG_BASE + 172)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_VOL_OPTION_ADD (GLFS_LG_BASE + 173)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_XLATOR_OPTION_INVALID (GLFS_LG_BASE + 174)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_GETTIMEOFDAY_FAILED (GLFS_LG_BASE + 175)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_GRAPH_INIT_FAILED (GLFS_LG_BASE + 176)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_EVENT_NOTIFY_FAILED (GLFS_LG_BASE + 177)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_ACTIVE_GRAPH_NULL (GLFS_LG_BASE + 178)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_VOLFILE_PARSE_ERROR (GLFS_LG_BASE + 179)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_FD_INODE_NULL (GLFS_LG_BASE + 180)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INVALID_VOLFILE_ENTRY (GLFS_LG_BASE + 181)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_PER_DENTRY_FAILED (GLFS_LG_BASE + 182)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_PARENT_DENTRY_NOT_FOUND (GLFS_LG_BASE + 183)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_DENTRY_CYCLIC_LOOP (GLFS_LG_BASE + 184)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-
-#define LG_MSG_INVALID_POLL_IN (GLFS_LG_BASE + 185)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_INVALID_POLL_OUT (GLFS_LG_BASE + 186)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_EPOLL_FD_ADD_FAILED (GLFS_LG_BASE + 187)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_EPOLL_FD_DEL_FAILED (GLFS_LG_BASE + 188)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_EPOLL_FD_MODIFY_FAILED (GLFS_LG_BASE + 189)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_STARTED_EPOLL_THREAD (GLFS_LG_BASE + 190)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_EXITED_EPOLL_THREAD (GLFS_LG_BASE + 191)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_START_EPOLL_THREAD_FAILED (GLFS_LG_BASE + 192)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_FALLBACK_TO_POLL (GLFS_LG_BASE + 193)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_QUOTA_CONF_ERROR (GLFS_LG_BASE + 194)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_RBTHASH_GET_ENTRY_FAILED (GLFS_LG_BASE + 195)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_RBTHASH_GET_BUCKET_FAILED (GLFS_LG_BASE + 196)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_RBTHASH_INSERT_FAILED (GLFS_LG_BASE + 197)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_RBTHASH_INIT_ENTRY_FAILED (GLFS_LG_BASE + 198)
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_TMPFILE_DELETE_FAILED (GLFS_LG_BASE + 199)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_MEMPOOL_INVALID_FREE (GLFS_LG_BASE + 200)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_LOCK_FAILURE (GLFS_LG_BASE + 201)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_SET_LOG_LEVEL (GLFS_LG_BASE + 202)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_VERIFY_PLATFORM (GLFS_LG_BASE + 203)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-#define LG_MSG_RUNNER_LOG (GLFS_LG_BASE + 204)
-
-/*!
- * @messageid
- * @diagnosis
- * @recommendedaction
- *
- */
-/*------------*/
-
-#define glfs_msg_end_lg GLFS_LG_MSGID_END, "Invalid: End of messages"
-
-#endif /* !_LG_MESSAGES_H_ */
-
-
-
diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym
new file mode 100644
index 00000000000..5f18cd56cbe
--- /dev/null
+++ b/libglusterfs/src/libglusterfs.sym
@@ -0,0 +1,1193 @@
+are_dicts_equal
+args_access_cbk_store
+args_access_store
+args_create_cbk_store
+args_create_store
+args_discard_cbk_store
+args_discard_store
+args_entrylk_cbk_store
+args_entrylk_store
+args_fallocate_cbk_store
+args_fallocate_store
+args_fentrylk_cbk_store
+args_fentrylk_store
+args_fgetxattr_cbk_store
+args_fgetxattr_store
+args_finodelk_cbk_store
+args_finodelk_store
+args_flush_cbk_store
+args_flush_store
+args_fremovexattr_cbk_store
+args_fremovexattr_store
+args_fsetattr_cbk_store
+args_fsetattr_store
+args_fsetxattr_cbk_store
+args_fsetxattr_store
+args_fstat_cbk_store
+args_fstat_store
+args_fsync_cbk_store
+args_fsyncdir_cbk_store
+args_fsyncdir_store
+args_fsync_store
+args_ftruncate_cbk_store
+args_ftruncate_store
+args_fxattrop_cbk_store
+args_fxattrop_store
+args_getxattr_cbk_store
+args_getxattr_store
+args_inodelk_cbk_store
+args_inodelk_store
+args_ipc_cbk_store
+args_lease_cbk_store
+args_lease_store
+args_link_cbk_store
+args_link_store
+args_lk_cbk_store
+args_lk_store
+args_lookup_cbk_store
+args_lookup_store
+args_mkdir_cbk_store
+args_mkdir_store
+args_mknod_cbk_store
+args_mknod_store
+args_open_cbk_store
+args_opendir_cbk_store
+args_opendir_store
+args_open_store
+args_rchecksum_cbk_store
+args_rchecksum_store
+args_readdir_cbk_store
+args_readdirp_cbk_store
+args_readdirp_store
+args_readdir_store
+args_readlink_cbk_store
+args_readlink_store
+args_readv_cbk_store
+args_readv_store
+args_removexattr_cbk_store
+args_removexattr_store
+args_rename_cbk_store
+args_rename_store
+args_rmdir_cbk_store
+args_rmdir_store
+args_seek_cbk_store
+args_seek_store
+args_setattr_cbk_store
+args_setattr_store
+args_setxattr_cbk_store
+args_setxattr_store
+args_stat_cbk_store
+args_statfs_cbk_store
+args_statfs_store
+args_stat_store
+args_symlink_cbk_store
+args_symlink_store
+args_truncate_cbk_store
+args_truncate_store
+args_unlink_cbk_store
+args_unlink_store
+args_writev_cbk_store
+args_writev_store
+args_xattrop_cbk_store
+args_xattrop_store
+args_zerofill_cbk_store
+args_zerofill_store
+args_copy_file_range_cbk_store
+args_copy_file_range_store
+bin_to_data
+call_resume
+call_resume_keep_stub
+call_resume_wind
+call_stack_set_groups
+call_stub_destroy
+call_unwind_error
+call_unwind_error_keep_stub
+client_ctx_del
+client_ctx_get
+client_ctx_set
+client_dump
+close_fds_except
+cluster_fop_success_fill
+cluster_fstat
+cluster_ftruncate
+cluster_fxattrop
+cluster_getxattr
+cluster_inodelk
+cluster_link
+cluster_lookup
+cluster_mkdir
+cluster_mknod
+cluster_open
+cluster_readlink
+cluster_replies_wipe
+cluster_rmdir
+cluster_setattr
+cluster_setxattr
+cluster_symlink
+cluster_tiebreaker_inodelk
+cluster_uninodelk
+cluster_unlink
+cluster_xattrop
+cluster_xattrop_cbk
+copy_opts_to_child
+create_frame
+data_copy
+data_destroy
+data_from_dynptr
+data_from_uint64
+data_ref
+data_to_bin
+data_to_int32
+data_to_int64
+data_to_ptr
+data_to_str
+data_to_uint16
+data_to_uint32
+data_to_uint64
+data_to_uint8
+data_to_iatt
+data_unref
+default_access
+default_access_cbk
+default_access_failure_cbk
+default_access_resume
+default_create
+default_create_cbk
+default_create_failure_cbk
+default_create_resume
+default_discard
+default_discard_cbk
+default_discard_failure_cbk
+default_discard_resume
+default_entrylk
+default_entrylk_cbk
+default_entrylk_failure_cbk
+default_entrylk_resume
+default_fallocate
+default_fallocate_cbk
+default_fallocate_failure_cbk
+default_fallocate_resume
+default_fentrylk
+default_fentrylk_cbk
+default_fentrylk_failure_cbk
+default_fentrylk_resume
+default_fgetxattr
+default_fgetxattr_cbk
+default_fgetxattr_failure_cbk
+default_fgetxattr_resume
+default_finodelk
+default_finodelk_cbk
+default_finodelk_failure_cbk
+default_finodelk_resume
+default_flush
+default_flush_cbk
+default_flush_failure_cbk
+default_flush_resume
+default_forget
+default_fremovexattr
+default_fremovexattr_cbk
+default_fremovexattr_failure_cbk
+default_fremovexattr_resume
+default_fsetattr
+default_fsetattr_cbk
+default_fsetattr_failure_cbk
+default_fsetattr_resume
+default_fsetxattr
+default_fsetxattr_cbk
+default_fsetxattr_failure_cbk
+default_fsetxattr_resume
+default_fstat
+default_fstat_cbk
+default_fstat_failure_cbk
+default_fstat_resume
+default_fsync
+default_fsync_cbk
+default_fsyncdir
+default_fsyncdir_cbk
+default_fsyncdir_failure_cbk
+default_fsyncdir_resume
+default_fsync_failure_cbk
+default_fsync_resume
+default_ftruncate
+default_ftruncate_cbk
+default_ftruncate_failure_cbk
+default_ftruncate_resume
+default_fxattrop
+default_fxattrop_cbk
+default_fxattrop_failure_cbk
+default_fxattrop_resume
+default_getactivelk
+default_getactivelk_failure_cbk
+default_getactivelk_resume
+default_getspec
+default_getspec_cbk
+default_getxattr
+default_getxattr_cbk
+default_getxattr_failure_cbk
+default_getxattr_resume
+default_inodelk
+default_inodelk_cbk
+default_inodelk_failure_cbk
+default_inodelk_resume
+default_ipc
+default_ipc_cbk
+default_lease
+default_lease_failure_cbk
+default_lease_resume
+default_link
+default_link_cbk
+default_link_failure_cbk
+default_link_resume
+default_lk
+default_lk_cbk
+default_lk_failure_cbk
+default_lk_resume
+default_lookup
+default_lookup_cbk
+default_lookup_failure_cbk
+default_lookup_resume
+default_mem_acct_init
+default_mkdir
+default_mkdir_cbk
+default_mkdir_failure_cbk
+default_mkdir_resume
+default_mknod
+default_mknod_cbk
+default_mknod_failure_cbk
+default_mknod_resume
+default_notify
+default_open
+default_open_cbk
+default_opendir
+default_opendir_cbk
+default_opendir_failure_cbk
+default_opendir_resume
+default_open_failure_cbk
+default_open_resume
+default_rchecksum
+default_rchecksum_cbk
+default_rchecksum_failure_cbk
+default_rchecksum_resume
+default_readdir
+default_readdir_cbk
+default_readdir_failure_cbk
+default_readdirp
+default_readdirp_cbk
+default_readdirp_failure_cbk
+default_readdirp_resume
+default_readdir_resume
+default_readlink
+default_readlink_cbk
+default_readlink_failure_cbk
+default_readlink_resume
+default_readv
+default_readv_cbk
+default_readv_failure_cbk
+default_readv_resume
+default_release
+default_releasedir
+default_removexattr
+default_removexattr_cbk
+default_removexattr_failure_cbk
+default_removexattr_resume
+default_rename
+default_rename_cbk
+default_rename_failure_cbk
+default_rename_resume
+default_rmdir
+default_rmdir_cbk
+default_rmdir_failure_cbk
+default_rmdir_resume
+default_seek
+default_seek_cbk
+default_seek_failure_cbk
+default_seek_resume
+default_setactivelk
+default_setactivelk_failure_cbk
+default_setactivelk_resume
+default_setattr
+default_setattr_cbk
+default_setattr_failure_cbk
+default_setattr_resume
+default_setxattr
+default_setxattr_cbk
+default_setxattr_failure_cbk
+default_setxattr_resume
+default_stat
+default_stat_cbk
+default_stat_failure_cbk
+default_statfs
+default_statfs_cbk
+default_statfs_failure_cbk
+default_statfs_resume
+default_stat_resume
+default_symlink
+default_symlink_cbk
+default_symlink_failure_cbk
+default_symlink_resume
+default_truncate
+default_truncate_cbk
+default_truncate_failure_cbk
+default_truncate_resume
+default_unlink
+default_unlink_cbk
+default_unlink_failure_cbk
+default_unlink_resume
+default_writev
+default_writev_cbk
+default_writev_failure_cbk
+default_writev_resume
+default_xattrop
+default_xattrop_cbk
+default_xattrop_failure_cbk
+default_xattrop_resume
+default_zerofill
+default_zerofill_cbk
+default_zerofill_failure_cbk
+default_zerofill_resume
+default_put
+default_put_cbk
+default_put_failure_cbk
+default_put_resume
+default_copy_file_range
+default_copy_file_range_cbk
+default_copy_file_range_failure_cbk
+default_copy_file_range_resume
+dht_is_linkfile
+dict_add
+dict_addn
+dict_add_dynstr_with_alloc
+dict_allocate_and_serialize
+dict_copy
+dict_copy_with_ref
+dict_del
+dict_deln
+dict_dump_to_statedump
+dict_dump_to_str
+dict_dump_to_log
+dict_foreach
+dict_foreach_fnmatch
+dict_foreach_match
+dict_for_key_value
+dict_get
+dict_getn
+dict_get_bin
+dict_get_double
+dict_get_gfuuid
+dict_get_iatt
+dict_get_mdata
+dict_get_int16
+dict_get_int32
+dict_get_int32n
+dict_get_int64
+dict_get_int8
+dict_get_ptr
+dict_get_ptr_and_len
+dict_get_str
+dict_get_strn
+dict_get_str_boolean
+dict_get_uint32
+dict_get_uint64
+dict_get_with_ref
+dict_has_key_from_array
+dict_key_count
+dict_keys_join
+dict_lookup
+dict_new
+dict_null_foreach_fn
+dict_ref
+dict_remove_foreach_fn
+dict_rename_key
+dict_reset
+dict_serialize
+dict_serialized_length
+dict_serialized_length_lk
+dict_serialize_value_with_delim
+dict_set
+dict_setn
+dict_set_bin
+dict_set_double
+dict_set_dynptr
+dict_set_dynstr
+dict_set_dynstrn
+dict_set_dynstr_with_alloc
+dict_set_gfuuid
+dict_set_iatt
+dict_set_mdata
+dict_set_int16
+dict_set_int32
+dict_set_int32n
+dict_set_int64
+dict_set_int8
+dict_set_static_bin
+dict_set_static_ptr
+dict_set_str
+dict_set_strn
+dict_setn_nstrn
+dict_set_nstrn
+dict_set_uint32
+dict_set_uint64
+dict_set_flag
+dict_clear_flag
+dict_check_flag
+dict_unref
+dict_unserialize
+drop_token
+eh_destroy
+eh_dump
+eh_new
+eh_save_history
+entry_copy
+gf_event_dispatch
+gf_event_dispatch_destroy
+gf_event_handled
+gf_event_pool_destroy
+gf_event_pool_new
+gf_event_reconfigure_threads
+gf_event_register
+gf_event_select_on
+gf_event_unregister
+gf_event_unregister_close
+fd_anonymous
+fd_anonymous_with_flags
+fd_bind
+fd_close
+fd_create
+fd_create_uint64
+__fd_ctx_del
+fd_ctx_del
+fd_ctx_dump
+__fd_ctx_get
+fd_ctx_get
+__fd_ctx_set
+fd_ctx_set
+fd_is_anonymous
+fd_list_empty
+fd_lk_ctx_empty
+fd_lk_ctx_ref
+fd_lk_ctx_unref
+fd_lk_insert_and_merge
+fd_lookup
+fd_lookup_anonymous
+fd_lookup_uint64
+__fd_ref
+fd_ref
+fd_unref
+_fini
+fop_access_stub
+fop_create_stub
+fop_copy_file_range_stub
+fop_copy_file_range_cbk_stub
+fop_discard_stub
+fop_entrylk_stub
+fop_enum_to_pri_string
+fop_fallocate_stub
+fop_fentrylk_stub
+fop_fgetxattr_stub
+fop_finodelk_stub
+fop_flush_stub
+fop_fremovexattr_cbk_stub
+fop_fremovexattr_stub
+fop_fsetattr_stub
+fop_fsetxattr_cbk_stub
+fop_fsetxattr_stub
+fop_fstat_stub
+fop_fsync_cbk_stub
+fop_fsyncdir_stub
+fop_fsync_stub
+fop_ftruncate_cbk_stub
+fop_ftruncate_stub
+fop_fxattrop_stub
+fop_getactivelk_stub
+fop_getxattr_stub
+fop_icreate_stub
+fop_inodelk_stub
+fop_ipc_stub
+fop_lease_stub
+fop_link_stub
+fop_lk_stub
+fop_log_level
+fop_lookup_cbk_stub
+fop_lookup_stub
+fop_mkdir_stub
+fop_mknod_stub
+fop_namelink_stub
+fop_opendir_stub
+fop_open_stub
+fop_put_stub
+fop_rchecksum_stub
+fop_readdirp_stub
+fop_readdir_stub
+fop_readlink_stub
+fop_readv_stub
+fop_removexattr_cbk_stub
+fop_removexattr_stub
+fop_rename_cbk_stub
+fop_rename_stub
+fop_rmdir_cbk_stub
+fop_rmdir_stub
+fop_seek_stub
+fop_setactivelk_stub
+fop_setattr_stub
+fop_setxattr_stub
+fop_statfs_stub
+fop_stat_stub
+fop_symlink_stub
+fop_truncate_cbk_stub
+fop_truncate_stub
+fop_unlink_cbk_stub
+fop_unlink_stub
+fop_writev_cbk_stub
+fop_writev_stub
+fop_xattrop_stub
+fop_zerofill_stub
+generate_glusterfs_ctx_id
+get_checksum_for_file
+get_checksum_for_path
+get_file_mtime
+get_host_name
+get_mem_size
+get_path_name
+get_xlator_by_name
+get_xlator_by_type
+gf_array_insertionsort
+gf_asprintf
+gf_async
+gf_async_adjust_threads
+gf_async_ctrl
+gf_async_init
+gf_async_fini
+gf_backtrace_save
+gf_bits_count
+gf_bits_index
+gf_build_absolute_path
+__gf_calloc
+gf_canonicalize_path
+gf_check_log_format
+gf_check_logger
+gf_client_disconnect
+gf_client_dump_fdtables
+gf_client_dump_fdtables_to_dict
+gf_client_dump_inodes
+gf_client_dump_inodes_to_dict
+gf_client_get
+gf_client_put
+gf_client_ref
+gf_clienttable_alloc
+gf_client_unref
+gf_cmd_log
+gf_cmd_log_init
+gf_compare_sockaddr
+gf_deitransform
+gf_dirent_entry_free
+gf_dirent_for_name
+gf_dirent_free
+gf_dirent_orig_offset
+gf_dm_hashfn
+gf_dnscache_init
+gf_dnscache_deinit
+gf_errno_to_error
+gf_error_to_errno
+_gf_event
+gf_fd_fdptr_get
+gf_fd_fdtable_alloc
+gf_fd_fdtable_copy_all_fds
+gf_fd_fdtable_destroy
+gf_fd_fdtable_get_all_fds
+gf_fdptr_put
+gf_fd_put
+gf_fd_unused_get
+gf_fill_iatt_for_dirent
+gf_fop_int
+gf_fop_string
+__gf_free
+gf_free_mig_locks
+gf_getgrouplist
+gf_get_hostname_from_ip
+gf_get_index_by_elem
+gf_global_mem_acct_enable_set
+gfid_to_ino
+gf_inode_type_to_str
+gf_is_ip_in_net
+gf_is_local_addr
+gf_is_same_address
+gf_is_service_running
+gf_is_str_int
+gf_is_valid_xattr_namespace
+gf_is_zero_filled_stat
+gf_itransform
+gf_link_inodes_from_dirent
+_gf_log
+_gf_log_callingfn
+gf_log_disable_suppression_before_exit
+gf_log_dump_graph
+_gf_log_eh
+gf_log_fini
+gf_log_get_localtime
+gf_log_get_loglevel
+gf_log_globals_init
+gf_log_init
+gf_log_inject_timer_event
+gf_log_logrotate
+gf_log_set_localtime
+gf_log_set_log_buf_size
+gf_log_set_log_flush_timeout
+gf_log_set_logformat
+gf_log_set_logger
+gf_log_set_loglevel
+gf_lstat_dir
+__gf_malloc
+gf_mem_acct_enable_set
+gf_monitor_metrics
+_gf_msg
+_gf_msg_nomem
+gf_nwrite
+gf_path_strip_trailing_slashes
+gf_print_trace
+gf_proc_dump_add_section
+gf_proc_dump_info
+gf_proc_dump_init
+gf_proc_dump_mallinfo
+gf_proc_dump_mem_info
+gf_proc_dump_mem_info_to_dict
+gf_proc_dump_mempool_info
+gf_proc_dump_mempool_info_to_dict
+gf_proc_dump_pending_frames
+gf_proc_dump_pending_frames_to_dict
+gf_proc_dump_write
+gf_proc_dump_xlator_history
+gf_proc_dump_xlator_meminfo
+gf_proc_dump_xlator_private
+gf_proc_dump_xlator_profile
+gf_process_getspec_servers_list
+gf_process_reserved_ports
+__gf_realloc
+_gf_ref_get
+_gf_ref_init
+_gf_ref_put
+gf_resolve_ip6
+gf_resolve_path_parent
+gf_rev_dns_lookup
+gf_rev_dns_lookup_cached
+gf_rsync_strong_checksum
+gf_rsync_md5_checksum
+gf_rsync_weak_checksum
+gf_set_log_file_path
+gf_set_log_ident
+gf_set_timestamp
+gf_set_volfile_server_common
+_gf_smsg
+gf_sock_union_equal_addr
+gf_store_handle_create_on_absence
+gf_store_handle_destroy
+gf_store_handle_new
+gf_store_handle_retrieve
+gf_store_iter_destroy
+gf_store_iter_get_matching
+gf_store_iter_get_next
+gf_store_iter_new
+gf_store_lock
+gf_store_locked_local
+gf_store_mkdir
+gf_store_mkstemp
+gf_store_read_and_tokenize
+gf_store_rename_tmppath
+gf_store_retrieve_value
+gf_store_save_value
+gf_store_save_items
+gf_store_unlink_tmppath
+gf_store_unlock
+gf_string2boolean
+gf_string2bytesize_int64
+gf_string2bytesize_uint64
+gf_string2double
+gf_string2int
+gf_string2int32
+gf_string2percent
+gf_string2time
+gf_string2uint
+gf_string2uint32
+gf_string2uint64
+gf_string2uint_base10
+gf_strip_whitespace
+gf_strncpy
+gf_strTrim
+gf_strstr
+gf_thread_cleanup_xint
+gf_thread_create
+gf_thread_vcreate
+gf_thread_create_detached
+gf_thread_set_name
+gf_thread_set_vname
+gf_timer_call_after
+gf_timer_call_cancel
+gf_timer_registry_destroy
+_gf_timestuff
+gf_trim
+gf_tw_add_timer
+gf_tw_del_timer
+gf_tw_mod_timer
+gf_tw_mod_timer_pending
+gf_uint64_2human_readable
+gf_umount_lazy
+gf_update_latency
+gf_uuid_clear
+gf_uuid_compare
+gf_uuid_copy
+gf_uuid_is_null
+gf_uuid_generate
+gf_uuid_parse
+gf_uuid_unparse
+gf_valid_pid
+gf_vasprintf
+gf_volfile_reconfigure
+gf_xxh64_wrapper
+gf_zero_fill_stat
+gid_cache_add
+gid_cache_init
+gid_cache_lookup
+gid_cache_reconf
+gid_cache_release
+glusterd_check_log_level
+glusterfs_compute_sha256
+glusterfs_ctx_new
+glusterfs_ctx_tw_get
+glusterfs_ctx_tw_put
+glusterfs_delete_volfile_checksum
+glusterfs_globals_init
+glusterfs_graph_activate
+glusterfs_graph_attach
+glusterfs_graph_construct
+glusterfs_graph_deactivate
+glusterfs_graph_destroy
+glusterfs_graph_destroy_residual
+glusterfs_graph_prepare
+glusterfs_read_secure_access_file
+glusterfs_graph_print_file
+glusterfs_graph_set_first
+glusterfs_is_local_pathinfo
+glusterfs_leaf_position
+glusterfs_reachable_leaves
+__glusterfs_this_location
+glusterfs_this_set
+glusterfs_volfile_reconfigure
+glusterfs_xlator_link
+graph_reconf_validateopt
+_init
+inode_ctx_del2
+__inode_ctx_get0
+inode_ctx_get0
+__inode_ctx_get1
+inode_ctx_get1
+__inode_ctx_get2
+inode_ctx_get2
+inode_ctx_merge
+inode_ctx_reset0
+inode_ctx_reset1
+inode_ctx_reset2
+__inode_ctx_set0
+inode_ctx_set0
+__inode_ctx_set1
+inode_ctx_set1
+__inode_ctx_set2
+inode_ctx_set2
+inode_ctx_size
+inode_dump
+inode_dump_to_dict
+__inode_find
+inode_find
+inode_find_directory_name
+inode_forget
+inode_forget_with_unref
+inode_from_path
+inode_grep
+inode_grep_for_gfid
+inode_has_dentry
+inode_invalidate
+inode_is_linked
+inode_link
+inode_lookup
+inode_needs_lookup
+inode_new
+inode_parent
+__inode_path
+inode_path
+inode_ref
+inode_ref_reduce_by_n
+inode_rename
+inode_resolve
+inode_set_need_lookup
+inode_table_ctx_free
+inode_table_destroy
+inode_table_destroy_all
+inode_table_dump
+inode_table_dump_to_dict
+inode_table_new
+inode_table_with_invalidator
+__inode_table_set_lru_limit
+inode_table_set_lru_limit
+inode_unlink
+inode_unref
+int_to_data
+iobref_add
+iobref_clear
+iobref_merge
+iobref_new
+iobref_ref
+iobref_size
+iobref_unref
+iobuf_get
+iobuf_get2
+iobuf_get_page_aligned
+iobuf_pool_destroy
+iobuf_pool_new
+iobuf_size
+iobuf_to_iovec
+iobuf_unref
+iobuf_copy
+is_data_equal
+__is_fuse_call
+is_gf_log_command
+is_graph_topology_equal
+__is_root_gfid
+is_valid_lease_id
+leaseid_utoa
+gf_existing_leaseid
+gf_leaseid_get
+list_node_add
+list_node_add_order
+list_node_del
+lkowner_utoa
+loc_copy
+loc_copy_overload_parent
+loc_gfid
+loc_gfid_utoa
+loc_is_nameless
+loc_is_root
+loc_pargfid
+loc_path
+loc_touchup
+loc_wipe
+log_base2
+_mask_cancellation
+mask_match
+mem_get
+mem_get0
+mem_pool_destroy
+mem_pool_new_fn
+mem_pools_fini
+mem_pools_init
+mem_put
+mkdir_p
+next_token
+nwstrtail
+os_daemon
+os_daemon_return
+parser_deinit
+parser_get_next_match
+parser_init
+parser_set_string
+parser_unset_string
+quota_conf_read_gfid
+quota_conf_read_version
+quota_conf_skip_header
+quota_data_to_meta
+quota_dict_get_inode_meta
+quota_dict_get_meta
+quota_dict_set_meta
+quota_meta_is_null
+rb_create
+rb_delete
+rb_destroy
+rb_find
+rb_probe
+rbthash_get
+rbthash_insert
+rbthash_remove
+rbthash_table_destroy
+rbthash_table_init
+rbuf_dtor
+rbuf_get_buffer
+rbuf_init
+rbuf_reserve_write_area
+rbuf_wait_for_completion
+rbuf_write_complete
+recursive_rmdir
+runcmd
+runinit
+runner
+runner_add_arg
+runner_add_args
+runner_argprintf
+runner_chio
+runner_end
+runner_log
+runner_redir
+runner_run
+runner_run_nowait
+runner_run_reuse
+runner_start
+set_sys_log_level
+skipwhite
+strfd_close
+strfd_open
+strprintf
+strtail
+str_to_data
+SuperFastHash
+syncbarrier_destroy
+syncbarrier_init
+syncbarrier_wait
+syncbarrier_wake
+synccond_init
+synccond_destroy
+synccond_wait
+synccond_timedwait
+synccond_signal
+synccond_broadcast
+syncenv_destroy
+syncenv_new
+synclock_destroy
+synclock_init
+synclock_lock
+synclock_trylock
+synclock_unlock
+syncop_access
+syncop_close
+syncop_create
+syncop_copy_file_range
+syncopctx_getctx
+syncopctx_setfsgid
+syncopctx_setfsgroups
+syncopctx_setfslkowner
+syncopctx_setfspid
+syncopctx_setfsuid
+syncop_dirfd
+syncop_dir_scan
+syncop_discard
+syncop_fallocate
+syncop_flush
+syncop_fgetxattr
+syncop_fremovexattr
+syncop_fsetattr
+syncop_fsetxattr
+syncop_fstat
+syncop_fsync
+syncop_fsyncdir
+syncop_ftruncate
+syncop_ftw
+syncop_ftw_throttle
+syncop_fxattrop
+syncop_getactivelk
+syncop_getxattr
+syncop_gfid_to_path
+syncop_gfid_to_path_hard
+syncop_inode_find
+syncop_inodelk
+syncop_entrylk
+syncop_ipc
+syncop_is_subvol_local
+syncop_link
+syncop_listxattr
+syncop_lk
+syncop_lookup
+syncop_mkdir
+syncop_mknod
+syncop_mt_dir_scan
+syncop_open
+syncop_opendir
+syncop_readdir
+syncop_readdirp
+syncop_readlink
+syncop_readv
+syncop_removexattr
+syncop_rename
+syncop_rmdir
+syncop_seek
+syncop_setactivelk
+syncop_setattr
+syncop_setxattr
+syncop_stat
+syncop_statfs
+syncop_symlink
+syncop_truncate
+syncop_unlink
+syncop_write
+syncop_writev
+syncop_xattrop
+syncop_zerofill
+syncop_lease
+synctask_get
+synctask_new
+synctask_new1
+synctask_set
+synctask_setid
+synctask_sleep
+synctask_wake
+synctask_yield
+sys_access
+sys_chmod
+sys_chown
+sys_close
+sys_closedir
+sys_copy_file_range
+sys_creat
+sys_fallocate
+sys_fchmod
+sys_fchown
+sys_fdatasync
+sys_fgetxattr
+sys_flistxattr
+sys_fremovexattr
+sys_fsetxattr
+sys_fstat
+sys_fstatat
+sys_fsync
+sys_ftruncate
+sys_futimes
+sys_lchown
+sys_lgetxattr
+sys_link
+sys_linkat
+sys_llistxattr
+sys_lremovexattr
+sys_lseek
+sys_lsetxattr
+sys_lstat
+sys_mkdir
+sys_mkdirat
+sys_mknod
+sys_open
+sys_openat
+sys_opendir
+sys_pread
+sys_pwrite
+sys_pwritev
+sys_read
+sys_readdir
+sys_readlink
+sys_readv
+sys_rename
+sys_rmdir
+sys_stat
+sys_statvfs
+sys_symlink
+sys_symlinkat
+sys_truncate
+sys_unlink
+sys_unlinkat
+sys_utimensat
+sys_write
+sys_writev
+sys_socket
+sys_accept
+sys_kill
+sys_sysctl
+tbf_init
+tbf_throttle
+timespec_now
+timespec_now_realtime
+timespec_sub
+timespec_adjust_delta
+timespec_cmp
+token_iter_init
+trap
+trie_add
+trie_destroy
+trie_measure
+trie_measure_vec
+trie_new
+trienode_get_word
+_unmask_cancellation
+uuid_utoa
+uuid_utoa_r
+validate_brick_name
+valid_host_name
+valid_ipv4_address
+valid_internet_address
+xlator_destroy
+xlator_foreach
+xlator_foreach_depth_first
+xlator_init
+xlator_mem_acct_init
+xlator_mem_acct_unref
+xlator_notify
+xlator_option_info_list
+xlator_option_init_bool
+xlator_option_init_double
+xlator_option_init_int32
+xlator_option_init_path
+xlator_option_init_percent
+xlator_option_init_percent_or_size
+xlator_option_init_size
+xlator_option_init_size_uint64
+xlator_option_init_size_int64
+xlator_option_init_str
+xlator_option_init_time
+xlator_option_init_uint32
+xlator_option_init_uint64
+xlator_option_init_int64
+xlator_option_init_xlator
+xlator_option_reconf_bool
+xlator_option_reconf_int32
+xlator_option_reconf_path
+xlator_option_reconf_percent
+xlator_option_reconf_percent_or_size
+xlator_option_reconf_size
+xlator_option_reconf_size_uint64
+xlator_option_reconf_size_int64
+xlator_option_reconf_str
+xlator_option_reconf_time
+xlator_option_reconf_uint32
+xlator_option_reconf_uint64
+xlator_option_reconf_int64
+xlator_option_reconf_xlator
+xlator_options_validate
+xlator_options_validate_list
+xlator_option_validate
+xlator_option_validate_addr_list
+xlator_search_by_name
+xlator_set_inode_lru_limit
+xlator_set_type
+xlator_set_type_virtual
+xlator_subvolume_count
+xlator_tree_free_members
+xlator_volopt_dynload
+xlator_volume_option_get
+xlator_volume_option_get_list
+xlator_memrec_free
+xlator_mem_cleanup
+gluster_graph_take_reference
+default_fops
+gf_fop_list
+gf_upcall_list
+vol_type_str
+global_ctx
+global_ctx_mutex
+global_xlator
+use_spinlocks
+dump_options
+glusterfs_leaseid_buf_get
+glusterfs_leaseid_exist
+gf_replace_old_iatt_in_dict
+gf_replace_new_iatt_in_dict
+gf_changelog_init
+gf_changelog_register_generic
+gf_gfid_generate_from_xxh64
+find_xlator_option_in_cmd_args_t
+gf_d_type_from_ia_type
+glusterfs_graph_fini
+glusterfs_process_svc_attach_volfp
+glusterfs_mux_volfile_reconfigure
+glusterfs_process_svc_detach
+mgmt_is_multiplexed_daemon
+xlator_is_cleanup_starting
+gf_nanosleep
+gf_syncfs
+graph_total_client_xlator
+get_xattrs_to_heal
+gf_latency_statedump_and_reset
+gf_latency_new
+gf_latency_reset
+gf_latency_update
+gf_frame_latency_update
diff --git a/libglusterfs/src/list.h b/libglusterfs/src/list.h
deleted file mode 100644
index b8f9a6eebd8..00000000000
--- a/libglusterfs/src/list.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- 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
-#define _LLIST_H
-
-
-struct list_head {
- struct list_head *next;
- struct list_head *prev;
-};
-
-
-#define INIT_LIST_HEAD(head) do { \
- (head)->next = (head)->prev = head; \
- } while (0)
-
-
-static inline void
-list_add (struct list_head *new, struct list_head *head)
-{
- new->prev = head;
- new->next = head->next;
-
- new->prev->next = new;
- new->next->prev = new;
-}
-
-
-static inline void
-list_add_tail (struct list_head *new, struct list_head *head)
-{
- new->next = head;
- new->prev = head->prev;
-
- new->prev->next = new;
- new->next->prev = new;
-}
-
-
-/* This function will insert the element to the list in a order.
- Order will be based on the compare function provided as a input.
- If element to be inserted in ascending order compare should return:
- 0: if both the arguments are equal
- >0: if first argument is greater than second argument
- <0: if first argument is less than second argument */
-static inline void
-list_add_order (struct list_head *new, struct list_head *head,
- int (*compare)(struct list_head *, struct list_head *))
-{
- struct list_head *pos = head->prev;
-
- while ( pos != head ) {
- if (compare(new, pos) >= 0)
- break;
-
- /* Iterate the list in the reverse order. This will have
- better efficiency if the elements are inserted in the
- ascending order */
- pos = pos->prev;
- }
-
- list_add (new, pos);
-}
-
-static inline void
-list_del (struct list_head *old)
-{
- old->prev->next = old->next;
- old->next->prev = old->prev;
-
- old->next = (void *)0xbabebabe;
- old->prev = (void *)0xcafecafe;
-}
-
-
-static inline void
-list_del_init (struct list_head *old)
-{
- old->prev->next = old->next;
- old->next->prev = old->prev;
-
- old->next = old;
- old->prev = old;
-}
-
-
-static inline void
-list_move (struct list_head *list, struct list_head *head)
-{
- list_del (list);
- list_add (list, head);
-}
-
-
-static inline void
-list_move_tail (struct list_head *list, struct list_head *head)
-{
- list_del (list);
- list_add_tail (list, head);
-}
-
-
-static inline int
-list_empty (struct list_head *head)
-{
- return (head->next == head);
-}
-
-
-static inline void
-__list_splice (struct list_head *list, struct list_head *head)
-{
- (list->prev)->next = (head->next);
- (head->next)->prev = (list->prev);
-
- (head)->next = (list->next);
- (list->next)->prev = (head);
-}
-
-
-static inline void
-list_splice (struct list_head *list, struct list_head *head)
-{
- if (list_empty (list))
- return;
-
- __list_splice (list, head);
-}
-
-
-/* Splice moves @list to the head of the list at @head. */
-static inline void
-list_splice_init (struct list_head *list, struct list_head *head)
-{
- if (list_empty (list))
- return;
-
- __list_splice (list, head);
- INIT_LIST_HEAD (list);
-}
-
-
-static inline void
-__list_append (struct list_head *list, struct list_head *head)
-{
- (head->prev)->next = (list->next);
- (list->next)->prev = (head->prev);
- (head->prev) = (list->prev);
- (list->prev)->next = head;
-}
-
-
-static inline void
-list_append (struct list_head *list, struct list_head *head)
-{
- if (list_empty (list))
- return;
-
- __list_append (list, head);
-}
-
-
-/* Append moves @list to the end of @head */
-static inline void
-list_append_init (struct list_head *list, struct list_head *head)
-{
- if (list_empty (list))
- return;
-
- __list_append (list, head);
- INIT_LIST_HEAD (list);
-}
-
-static inline int
-list_is_last (struct list_head *list, struct list_head *head)
-{
- return (list->next == head);
-}
-
-static inline int
-list_is_singular(struct list_head *head)
-{
- return !list_empty(head) && (head->next == head->prev);
-}
-
-/**
- * list_replace - replace old entry by new one
- * @old : the element to be replaced
- * @new : the new element to insert
- *
- * If @old was empty, it will be overwritten.
- */
-static inline void list_replace(struct list_head *old,
- struct list_head *new)
-{
- new->next = old->next;
- new->next->prev = new;
- new->prev = old->prev;
- new->prev->next = new;
-}
-
-static inline void list_replace_init(struct list_head *old,
- struct list_head *new)
-{
- list_replace(old, new);
- INIT_LIST_HEAD(old);
-}
-
-/**
- * list_rotate_left - rotate the list to the left
- * @head: the head of the list
- */
-static inline void list_rotate_left (struct list_head *head)
-{
- struct list_head *first;
-
- if (!list_empty (head)) {
- first = head->next;
- list_move_tail (first, head);
- }
-}
-
-#define list_entry(ptr, type, member) \
- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-
-#define list_first_entry(ptr, type, member) \
- list_entry((ptr)->next, type, member)
-
-#define list_last_entry(ptr, type, member) \
- list_entry((ptr)->prev, type, member)
-
-#define list_next_entry(pos, member) \
- list_entry((pos)->member.next, typeof(*(pos)), member)
-
-#define list_prev_entry(pos, member) \
- list_entry((pos)->member.prev, typeof(*(pos)), member)
-
-#define list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-#define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-
-#define list_for_each_entry_safe(pos, n, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member), \
- n = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-#define list_for_each_entry_reverse(pos, head, member) \
- for (pos = list_entry((head)->prev, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.prev, typeof(*pos), member))
-
-
-#define list_for_each_entry_safe_reverse(pos, n, head, member) \
- for (pos = list_entry((head)->prev, typeof(*pos), member), \
- n = list_entry(pos->member.prev, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.prev, typeof(*n), member))
-
-/*
- * This list implementation has some advantages, but one disadvantage: you
- * can't use NULL to check whether you're at the head or tail. Thus, the
- * address of the head has to be an argument for these macros.
- */
-
-#define list_next(ptr, head, type, member) \
- (((ptr)->member.next == head) ? NULL \
- : list_entry((ptr)->member.next, type, member))
-
-#define list_prev(ptr, head, type, member) \
- (((ptr)->member.prev == head) ? NULL \
- : list_entry((ptr)->member.prev, type, member))
-
-#endif /* _LLIST_H */
diff --git a/libglusterfs/src/lkowner.h b/libglusterfs/src/lkowner.h
deleted file mode 100644
index c3e16760869..00000000000
--- a/libglusterfs/src/lkowner.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- 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
-
-#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));
-}
-
-static inline int
-is_lk_owner_null (gf_lkowner_t *lkowner)
-{
- int is_null = 1;
- int i = 0;
-
- if (lkowner == NULL || lkowner->len == 0)
- goto out;
-
- for (i = 0; i < lkowner->len; i++) {
- if (lkowner->data[i] != 0) {
- is_null = 0;
- break;
- }
- }
-out:
- return is_null;
-}
-
-#endif /* _LK_OWNER_H */
diff --git a/libglusterfs/src/locking.c b/libglusterfs/src/locking.c
new file mode 100644
index 00000000000..7577054e33a
--- /dev/null
+++ b/libglusterfs/src/locking.c
@@ -0,0 +1,27 @@
+/*
+ Copyright (c) 2015 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.
+*/
+
+#if defined(HAVE_SPINLOCK)
+/* None of this matters otherwise. */
+
+#include <pthread.h>
+#include <unistd.h>
+
+#define LOCKING_IMPL
+#include "glusterfs/locking.h"
+
+int use_spinlocks = 0;
+
+static void __attribute__((constructor)) gf_lock_setup(void)
+{
+ // use_spinlocks = (sysconf(_SC_NPROCESSORS_ONLN) > 1);
+}
+
+#endif
diff --git a/libglusterfs/src/locking.h b/libglusterfs/src/locking.h
deleted file mode 100644
index 24edf9aed44..00000000000
--- a/libglusterfs/src/locking.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- 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 _LOCKING_H
-#define _LOCKING_H
-
-#include <pthread.h>
-#ifdef GF_DARWIN_HOST_OS
-#include <libkern/OSAtomic.h>
-#define pthread_spinlock_t OSSpinLock
-#define pthread_spin_lock(l) OSSpinLockLock(l)
-#define pthread_spin_unlock(l) OSSpinLockUnlock(l)
-#define pthread_spin_destroy(l) 0
-#define pthread_spin_init(l, v) (*l = v)
-#endif
-
-
-#if HAVE_SPINLOCK
-#define LOCK_INIT(x) pthread_spin_init (x, 0)
-#define LOCK(x) pthread_spin_lock (x)
-#define TRY_LOCK(x) pthread_spin_trylock (x)
-#define UNLOCK(x) pthread_spin_unlock (x)
-#define LOCK_DESTROY(x) pthread_spin_destroy (x)
-
-typedef pthread_spinlock_t gf_lock_t;
-#else
-#define LOCK_INIT(x) pthread_mutex_init (x, 0)
-#define LOCK(x) pthread_mutex_lock (x)
-#define TRY_LOCK(x) pthread_mutex_trylock (x)
-#define UNLOCK(x) pthread_mutex_unlock (x)
-#define LOCK_DESTROY(x) pthread_mutex_destroy (x)
-
-typedef pthread_mutex_t gf_lock_t;
-#endif /* HAVE_SPINLOCK */
-
-
-#endif /* _LOCKING_H */
diff --git a/libglusterfs/src/logging.c b/libglusterfs/src/logging.c
index 7081b184de9..a930d3e3b63 100644
--- a/libglusterfs/src/logging.c
+++ b/libglusterfs/src/logging.c
@@ -17,6 +17,7 @@
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
+#include <sys/resource.h>
#ifdef HAVE_BACKTRACE
#include <execinfo.h>
@@ -26,142 +27,134 @@
#include <sys/stat.h>
-#define GF_JSON_MSG_LENGTH 8192
-#define GF_SYSLOG_CEE_FORMAT \
- "@cee: {\"msg\": \"%s\", \"gf_code\": \"%u\", \"gf_message\": \"%s\"}"
-#define GF_LOG_CONTROL_FILE "/etc/glusterfs/logger.conf"
-#define GF_LOG_BACKTRACE_DEPTH 5
-#define GF_LOG_BACKTRACE_SIZE 4096
-#define GF_LOG_TIMESTR_SIZE 256
-
-#include "xlator.h"
-#include "logging.h"
-#include "defaults.h"
-#include "glusterfs.h"
-#include "timer.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/syscall.h"
+
+#define GF_JSON_MSG_LENGTH 8192
+#define GF_SYSLOG_CEE_FORMAT \
+ "@cee: {\"msg\": \"%s\", \"gf_code\": \"%u\", \"gf_message\": \"%s\"}"
+#define GF_LOG_CONTROL_FILE "/etc/glusterfs/logger.conf"
+#define GF_LOG_BACKTRACE_DEPTH 5
+#define GF_LOG_BACKTRACE_SIZE 4096
+#define GF_MAX_SLOG_PAIR_COUNT 100
+
+#include "glusterfs/logging.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/timer.h"
+#include "glusterfs/libglusterfs-messages.h"
/* Do not replace gf_log in TEST_LOG with gf_msg, as there is a slight chance
* that it could lead to an infinite recursion.*/
-#define TEST_LOG(__msg, __args ...) \
- gf_log ("logging-infra", GF_LOG_DEBUG, __msg, ##__args);
+#define TEST_LOG(__msg, __args...) \
+ gf_log("logging-infra", GF_LOG_DEBUG, __msg, ##__args);
-void
-gf_log_flush_timeout_cbk (void *data);
+static void
+gf_log_flush_timeout_cbk(void *data);
int
-gf_log_inject_timer_event (glusterfs_ctx_t *ctx);
+gf_log_inject_timer_event(glusterfs_ctx_t *ctx);
static void
-gf_log_flush_extra_msgs (glusterfs_ctx_t *ctx, uint32_t new);
-
-static char *gf_level_strings[] = {"", /* NONE */
- "M", /* EMERGENCY */
- "A", /* ALERT */
- "C", /* CRITICAL */
- "E", /* ERROR */
- "W", /* WARNING */
- "N", /* NOTICE */
- "I", /* INFO */
- "D", /* DEBUG */
- "T", /* TRACE */
- ""
-};
-
-/* Ideally this should get moved to logging.h */
-struct _msg_queue {
- struct list_head msgs;
-};
+gf_log_flush_extra_msgs(glusterfs_ctx_t *ctx, uint32_t new);
-struct _log_msg {
- const char *msg;
- struct list_head queue;
+static int
+log_buf_init(log_buf_t *buf, const char *domain, const char *file,
+ const char *function, int32_t line, gf_loglevel_t level,
+ int errnum, uint64_t msgid, char **appmsgstr, int graph_id);
+static void
+gf_log_rotate(glusterfs_ctx_t *ctx);
+
+static char gf_level_strings[] = {
+ ' ', /* NONE */
+ 'M', /* EMERGENCY */
+ 'A', /* ALERT */
+ 'C', /* CRITICAL */
+ 'E', /* ERROR */
+ 'W', /* WARNING */
+ 'N', /* NOTICE */
+ 'I', /* INFO */
+ 'D', /* DEBUG */
+ 'T', /* TRACE */
};
void
-gf_log_logrotate (int signum)
+gf_log_logrotate(int signum)
{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
-
- if (ctx)
- ctx->log.logrotate = 1;
+ if (THIS->ctx) {
+ THIS->ctx->log.logrotate = 1;
+ THIS->ctx->log.cmd_history_logrotate = 1;
+ }
}
void
-gf_log_enable_syslog (void)
+gf_log_enable_syslog(void)
{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
-
- if (ctx)
- ctx->log.gf_log_syslog = 1;
+ if (THIS->ctx)
+ THIS->ctx->log.gf_log_syslog = 1;
}
void
-gf_log_disable_syslog (void)
+gf_log_disable_syslog(void)
{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
-
- if (ctx)
- ctx->log.gf_log_syslog = 0;
+ if (THIS->ctx)
+ THIS->ctx->log.gf_log_syslog = 0;
}
gf_loglevel_t
-gf_log_get_loglevel (void)
+gf_log_get_loglevel(void)
{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
-
- if (ctx)
- return ctx->log.loglevel;
- else
- /* return global defaults (see gf_log_globals_init) */
- return GF_LOG_INFO;
+ if (THIS->ctx)
+ return THIS->ctx->log.loglevel;
+ else
+ /* return global defaults (see gf_log_globals_init) */
+ return GF_LOG_INFO;
}
void
-gf_log_set_loglevel (gf_loglevel_t level)
+gf_log_set_loglevel(glusterfs_ctx_t *ctx, gf_loglevel_t level)
{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
+ if (ctx)
+ ctx->log.loglevel = level;
+}
- if (ctx)
- ctx->log.loglevel = level;
+int
+gf_log_get_localtime(void)
+{
+ if (THIS->ctx)
+ return THIS->ctx->log.localtime;
+ else
+ /* return global defaults (see gf_log_globals_init) */
+ return 0;
}
void
-gf_log_flush (void)
+gf_log_set_localtime(int on_off)
{
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
+ if (THIS->ctx)
+ THIS->ctx->log.localtime = on_off;
+}
- this = THIS;
- ctx = this->ctx;
+void
+gf_log_flush(void)
+{
+ xlator_t *this = THIS;
+ glusterfs_ctx_t *ctx = this->ctx;
- if (ctx && ctx->log.logger == gf_logger_glusterlog) {
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- fflush (ctx->log.gf_log_logfile);
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
- }
+ if (ctx && ctx->log.logger == gf_logger_glusterlog) {
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ fflush(ctx->log.gf_log_logfile);
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
+ }
- return;
+ return;
}
void
-gf_log_set_xl_loglevel (void *this, gf_loglevel_t level)
+gf_log_set_xl_loglevel(void *this, gf_loglevel_t level)
{
- xlator_t *xl = this;
- if (!xl)
- return;
- xl->ctx->log.gf_log_xl_log_set = 1;
- xl->loglevel = level;
+ xlator_t *xl = this;
+ if (!xl)
+ return;
+ xl->loglevel = level;
}
/* TODO: The following get/set functions are yet not invoked from anywhere
@@ -181,253 +174,204 @@ gf_log_set_xl_loglevel (void *this, gf_loglevel_t level)
*
* care needs to be taken to configure and start daemons based on the versions
* that supports these features */
-gf_log_format_t
-gf_log_get_logformat (void)
-{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
-
- if (ctx)
- return ctx->log.logformat;
- else
- /* return global defaluts (see gf_log_globals_init) */
- return gf_logformat_withmsgid;
-}
void
-gf_log_set_logformat (gf_log_format_t format)
-{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
-
- if (ctx)
- ctx->log.logformat = format;
-}
-
-gf_log_logger_t
-gf_log_get_logger (void)
+gf_log_set_logformat(gf_log_format_t format)
{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
-
- if (ctx)
- return ctx->log.logger;
- else
- /* return global defaluts (see gf_log_globals_init) */
- return gf_logger_glusterlog;
+ if (THIS->ctx)
+ THIS->ctx->log.logformat = format;
}
void
-gf_log_set_logger (gf_log_logger_t logger)
+gf_log_set_logger(gf_log_logger_t logger)
{
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
-
- if (ctx)
- ctx->log.logger = logger;
+ if (THIS->ctx)
+ THIS->ctx->log.logger = logger;
}
gf_loglevel_t
-gf_log_get_xl_loglevel (void *this)
+gf_log_get_xl_loglevel(void *this)
{
- xlator_t *xl = this;
- if (!xl)
- return 0;
- return xl->loglevel;
+ xlator_t *xl = this;
+ if (!xl)
+ return 0;
+ return xl->loglevel;
}
void
-gf_log_set_log_buf_size (uint32_t buf_size)
+gf_log_set_log_buf_size(uint32_t buf_size)
{
- uint32_t old = 0;
- glusterfs_ctx_t *ctx = THIS->ctx;
-
- pthread_mutex_lock (&ctx->log.log_buf_lock);
- {
- old = ctx->log.lru_size;
- ctx->log.lru_size = buf_size;
- }
- pthread_mutex_unlock (&ctx->log.log_buf_lock);
-
- /* If the old size is less than/equal to the new size, then do nothing.
- *
- * But if the new size is less than the old size, then
- * a. If the cur size of the buf is less than or equal the new size,
- * then do nothing.
- * b. But if the current size of the buf is greater than the new size,
- * then flush the least recently used (cur size - new_size) msgs
- * to disk.
- */
- if (buf_size < old)
- gf_log_flush_extra_msgs (ctx, buf_size);
+ uint32_t old = 0;
+ glusterfs_ctx_t *ctx = THIS->ctx;
+
+ pthread_mutex_lock(&ctx->log.log_buf_lock);
+ {
+ old = ctx->log.lru_size;
+ ctx->log.lru_size = buf_size;
+ }
+ pthread_mutex_unlock(&ctx->log.log_buf_lock);
+
+ /* If the old size is less than/equal to the new size, then do nothing.
+ *
+ * But if the new size is less than the old size, then
+ * a. If the cur size of the buf is less than or equal the new size,
+ * then do nothing.
+ * b. But if the current size of the buf is greater than the new size,
+ * then flush the least recently used (cur size - new_size) msgs
+ * to disk.
+ */
+ if (buf_size < old)
+ gf_log_flush_extra_msgs(ctx, buf_size);
}
void
-gf_log_set_log_flush_timeout (uint32_t timeout)
+gf_log_set_log_flush_timeout(uint32_t timeout)
{
- THIS->ctx->log.timeout = timeout;
-}
-
-log_buf_t *
-log_buf_new ()
-{
- log_buf_t *buf = NULL;
-
- buf = mem_get0 (THIS->ctx->logbuf_pool);
-
- return buf;
+ THIS->ctx->log.timeout = timeout;
}
/* If log_buf_init() fails (indicated by a return value of -1),
* call log_buf_destroy() to clean up memory allocated in heap and to return
* the log_buf_t object back to its memory pool.
*/
-int
-log_buf_init (log_buf_t *buf, const char *domain, const char *file,
- const char *function, int32_t line, gf_loglevel_t level,
- int errnum, uint64_t msgid, char **appmsgstr, int graph_id)
+static int
+log_buf_init(log_buf_t *buf, const char *domain, const char *file,
+ const char *function, int32_t line, gf_loglevel_t level,
+ int errnum, uint64_t msgid, char **appmsgstr, int graph_id)
{
- int ret = -1;
+ int ret = -1;
- if (!buf || !domain || !file || !function || !appmsgstr || !*appmsgstr)
- goto out;
+ if (!buf || !domain || !file || !function || !appmsgstr || !*appmsgstr)
+ goto out;
- buf->msg = gf_strdup (*appmsgstr);
- if (!buf->msg)
- goto out;
+ buf->msg = gf_strdup(*appmsgstr);
+ if (!buf->msg)
+ goto out;
- buf->msg_id = msgid;
- buf->errnum = errnum;
- buf->domain = gf_strdup (domain);
- if (!buf->domain)
- goto out;
+ buf->msg_id = msgid;
+ buf->errnum = errnum;
+ buf->domain = gf_strdup(domain);
+ if (!buf->domain)
+ goto out;
- buf->file = gf_strdup (file);
- if (!buf->file)
- goto out;
+ buf->file = gf_strdup(file);
+ if (!buf->file)
+ goto out;
- buf->function = gf_strdup (function);
- if (!buf->function)
- goto out;
+ buf->function = gf_strdup(function);
+ if (!buf->function)
+ goto out;
- buf->line = line;
- buf->level = level;
- buf->refcount = 0;
- buf->graph_id = graph_id;
- INIT_LIST_HEAD (&buf->msg_list);
+ buf->line = line;
+ buf->level = level;
+ buf->refcount = 0;
+ buf->graph_id = graph_id;
+ INIT_LIST_HEAD(&buf->msg_list);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
-int
-log_buf_destroy (log_buf_t *buf)
+static int
+log_buf_destroy(log_buf_t *buf)
{
+ if (!buf)
+ return -1;
- if (!buf)
- return -1;
-
- GF_FREE (buf->msg);
- GF_FREE (buf->domain);
- GF_FREE (buf->file);
- GF_FREE (buf->function);
+ GF_FREE(buf->msg);
+ GF_FREE(buf->domain);
+ GF_FREE(buf->file);
+ GF_FREE(buf->function);
- mem_put (buf);
- return 0;
+ mem_put(buf);
+ return 0;
}
static void
gf_log_rotate(glusterfs_ctx_t *ctx)
{
- int fd = -1;
- FILE *new_logfile = NULL;
- FILE *old_logfile = NULL;
-
- /* not involving locks on initial check to speed it up */
- if (ctx->log.logrotate) {
- /* let only one winner through on races */
- pthread_mutex_lock (&ctx->log.logfile_mutex);
-
- if (!ctx->log.logrotate) {
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
- return;
- } else {
- ctx->log.logrotate = 0;
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
- }
+ int fd = -1;
+ FILE *new_logfile = NULL;
+ FILE *old_logfile = NULL;
+
+ /* not involving locks on initial check to speed it up */
+ if (ctx->log.logrotate) {
+ /* let only one winner through on races */
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+
+ if (!ctx->log.logrotate) {
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
+ return;
+ } else {
+ ctx->log.logrotate = 0;
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
+ }
- fd = open (ctx->log.filename,
- O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
- if (fd < 0) {
- gf_msg ("logrotate", GF_LOG_ERROR, errno,
- LG_MSG_FILE_OP_FAILED, "failed to open "
- "logfile");
- return;
- }
- close (fd);
-
- new_logfile = fopen (ctx->log.filename, "a");
- if (!new_logfile) {
- gf_msg ("logrotate", GF_LOG_CRITICAL, errno,
- LG_MSG_FILE_OP_FAILED, "failed to open logfile"
- " %s", ctx->log.filename);
- return;
- }
+ fd = sys_open(ctx->log.filename, O_CREAT | O_WRONLY | O_APPEND,
+ S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ gf_smsg("logrotate", GF_LOG_ERROR, errno,
+ LG_MSG_OPEN_LOGFILE_FAILED, NULL);
+ return;
+ }
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
- if (ctx->log.logfile)
- old_logfile = ctx->log.logfile;
+ new_logfile = fdopen(fd, "a");
+ if (!new_logfile) {
+ gf_smsg("logrotate", GF_LOG_CRITICAL, errno,
+ LG_MSG_OPEN_LOGFILE_FAILED, "filename=%s",
+ ctx->log.filename, NULL);
+ sys_close(fd);
+ return;
+ }
- ctx->log.gf_log_logfile = ctx->log.logfile =
- new_logfile;
- }
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile)
+ old_logfile = ctx->log.logfile;
- if (old_logfile != NULL)
- fclose (old_logfile);
+ ctx->log.gf_log_logfile = ctx->log.logfile = new_logfile;
}
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
- return;
+ if (old_logfile != NULL)
+ fclose(old_logfile);
+ }
+
+ return;
}
void
-gf_log_globals_fini (void)
+gf_log_globals_fini(void)
{
- /* TODO: Nobody is invoking the fini, but cleanup needs to happen here,
- * needs cleanup for, log.ident, log.filename, closelog, log file close
- * rotate state, possibly under a lock */
- pthread_mutex_destroy (&THIS->ctx->log.logfile_mutex);
- pthread_mutex_destroy (&THIS->ctx->log.log_buf_lock);
+ /* TODO: Nobody is invoking the fini, but cleanup needs to happen here,
+ * needs cleanup for, log.ident, log.filename, closelog, log file close
+ * rotate state, possibly under a lock */
+ pthread_mutex_destroy(&THIS->ctx->log.logfile_mutex);
+ pthread_mutex_destroy(&THIS->ctx->log.log_buf_lock);
}
void
-gf_log_disable_suppression_before_exit (glusterfs_ctx_t *ctx)
+gf_log_disable_suppression_before_exit(glusterfs_ctx_t *ctx)
{
- /*
- * First set log buf size to 0. This would ensure two things:
- * i. that all outstanding log messages are flushed to disk, and
- * ii. all subsequent calls to gf_msg will result in the logs getting
- * directly flushed to disk without being buffered.
- *
- * Then, cancel the current log timer event.
- */
-
- gf_log_set_log_buf_size (0);
- pthread_mutex_lock (&ctx->log.log_buf_lock);
- {
- if (ctx->log.log_flush_timer) {
- gf_timer_call_cancel (ctx, ctx->log.log_flush_timer);
- ctx->log.log_flush_timer = NULL;
- }
+ /*
+ * First set log buf size to 0. This would ensure two things:
+ * i. that all outstanding log messages are flushed to disk, and
+ * ii. all subsequent calls to gf_msg will result in the logs getting
+ * directly flushed to disk without being buffered.
+ *
+ * Then, cancel the current log timer event.
+ */
+
+ gf_log_set_log_buf_size(0);
+ pthread_mutex_lock(&ctx->log.log_buf_lock);
+ {
+ if (ctx->log.log_flush_timer) {
+ gf_timer_call_cancel(ctx, ctx->log.log_flush_timer);
+ ctx->log.log_flush_timer = NULL;
}
- pthread_mutex_unlock (&ctx->log.log_buf_lock);
-
+ }
+ pthread_mutex_unlock(&ctx->log.log_buf_lock);
}
/** gf_log_fini - function to perform the cleanup of the log information
@@ -436,41 +380,43 @@ gf_log_disable_suppression_before_exit (glusterfs_ctx_t *ctx)
* failure: -1
*/
int
-gf_log_fini (void *data)
+gf_log_fini(void *data)
{
- glusterfs_ctx_t *ctx = data;
- int ret = 0;
- FILE *old_logfile = NULL;
+ glusterfs_ctx_t *ctx = data;
+ int ret = 0;
+ FILE *old_logfile = NULL;
- if (ctx == NULL) {
- ret = -1;
- goto out;
- }
+ if (ctx == NULL) {
+ ret = -1;
+ goto out;
+ }
- gf_log_disable_suppression_before_exit (ctx);
+ gf_log_disable_suppression_before_exit(ctx);
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
- if (ctx->log.logfile) {
- old_logfile = ctx->log.logfile;
-
- /* Logfile needs to be set to NULL, so that any
- call to gf_log after calling gf_log_fini, will
- log the message to stderr.
- */
- ctx->log.loglevel = GF_LOG_NONE;
- ctx->log.logfile = NULL;
- }
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ old_logfile = ctx->log.logfile;
+
+ /* Logfile needs to be set to NULL, so that any
+ call to gf_log after calling gf_log_fini, will
+ log the message to stderr.
+ */
+ ctx->log.loglevel = GF_LOG_NONE;
+ ctx->log.logfile = NULL;
}
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ }
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
- if (old_logfile && (fclose (old_logfile) != 0))
- ret = -1;
+ if (old_logfile && (fclose(old_logfile) != 0))
+ ret = -1;
- out:
- return ret;
-}
+ GF_FREE(ctx->log.ident);
+ GF_FREE(ctx->log.filename);
+out:
+ return ret;
+}
/**
* gf_openlog -function to open syslog specific to gluster based on
@@ -483,28 +429,27 @@ gf_log_fini (void *data)
*
* @return: void
*/
-void
-gf_openlog (const char *ident, int option, int facility)
+static void
+gf_openlog(const char *ident, int option, int facility)
{
- int _option = option;
- int _facility = facility;
-
- if (-1 == _option) {
- _option = LOG_PID | LOG_NDELAY;
- }
- if (-1 == _facility) {
- _facility = LOG_LOCAL1;
- }
-
- /* TODO: Should check for errors here and return appropriately */
- setlocale(LC_ALL, "");
- setlocale(LC_NUMERIC, "C"); /* C-locale for strtod, ... */
- /* close the previous syslog if open as we are changing settings */
- closelog ();
- openlog(ident, _option, _facility);
+ int _option = option;
+ int _facility = facility;
+
+ if (-1 == _option) {
+ _option = LOG_PID | LOG_NDELAY;
+ }
+ if (-1 == _facility) {
+ _facility = LOG_LOCAL1;
+ }
+
+ /* TODO: Should check for errors here and return appropriately */
+ setlocale(LC_ALL, "");
+ setlocale(LC_NUMERIC, "C"); /* C-locale for strtod, ... */
+ /* close the previous syslog if open as we are changing settings */
+ closelog();
+ openlog(ident, _option, _facility);
}
-
/**
* _json_escape -function to convert string to json encoded string
* @str: input string
@@ -528,88 +473,78 @@ gf_openlog (const char *ident, int option, int facility)
* buf = "I/O error\u001bon /tmp/bar file"
*
*/
-char *
+static char *
_json_escape(const char *str, char *buf, size_t len)
{
- static const unsigned char json_exceptions[UCHAR_MAX + 1] =
- {
- [0x01] = 1, [0x02] = 1, [0x03] = 1, [0x04] = 1,
- [0x05] = 1, [0x06] = 1, [0x07] = 1, [0x08] = 1,
- [0x09] = 1, [0x0a] = 1, [0x0b] = 1, [0x0c] = 1,
- [0x0d] = 1, [0x0e] = 1, [0x0f] = 1, [0x10] = 1,
- [0x11] = 1, [0x12] = 1, [0x13] = 1, [0x14] = 1,
- [0x15] = 1, [0x16] = 1, [0x17] = 1, [0x18] = 1,
- [0x19] = 1, [0x1a] = 1, [0x1b] = 1, [0x1c] = 1,
- [0x1d] = 1, [0x1e] = 1, [0x1f] = 1,
- ['\\'] = 1, ['"'] = 1
- };
- static const char json_hex_chars[16] = "0123456789abcdef";
- unsigned char *p = NULL;
- size_t pos = 0;
-
- if (!str || !buf || len <= 0) {
- return NULL;
- }
-
- for (p = (unsigned char *)str;
- *p && (pos + 1) < len;
- p++)
- {
- if (json_exceptions[*p] == 0) {
- buf[pos++] = *p;
- continue;
- }
-
- if ((pos + 2) >= len) {
- break;
- }
-
- switch (*p)
- {
- case '\b':
- buf[pos++] = '\\';
- buf[pos++] = 'b';
- break;
- case '\n':
- buf[pos++] = '\\';
- buf[pos++] = 'n';
- break;
- case '\r':
- buf[pos++] = '\\';
- buf[pos++] = 'r';
- break;
- case '\t':
- buf[pos++] = '\\';
- buf[pos++] = 't';
- break;
- case '\\':
- buf[pos++] = '\\';
- buf[pos++] = '\\';
- break;
- case '"':
- buf[pos++] = '\\';
- buf[pos++] = '"';
- break;
- default:
- if ((pos + 6) >= len) {
- buf[pos] = '\0';
- return (char *)p;
- }
- buf[pos++] = '\\';
- buf[pos++] = 'u';
- buf[pos++] = '0';
- buf[pos++] = '0';
- buf[pos++] = json_hex_chars[(*p) >> 4];
- buf[pos++] = json_hex_chars[(*p) & 0xf];
- break;
+ static const unsigned char json_exceptions[UCHAR_MAX + 1] = {
+ [0x01] = 1, [0x02] = 1, [0x03] = 1, [0x04] = 1, [0x05] = 1, [0x06] = 1,
+ [0x07] = 1, [0x08] = 1, [0x09] = 1, [0x0a] = 1, [0x0b] = 1, [0x0c] = 1,
+ [0x0d] = 1, [0x0e] = 1, [0x0f] = 1, [0x10] = 1, [0x11] = 1, [0x12] = 1,
+ [0x13] = 1, [0x14] = 1, [0x15] = 1, [0x16] = 1, [0x17] = 1, [0x18] = 1,
+ [0x19] = 1, [0x1a] = 1, [0x1b] = 1, [0x1c] = 1, [0x1d] = 1, [0x1e] = 1,
+ [0x1f] = 1, ['\\'] = 1, ['"'] = 1};
+ static const char json_hex_chars[16] = "0123456789abcdef";
+ unsigned char *p = NULL;
+ size_t pos = 0;
+
+ if (!str || !buf || len <= 0) {
+ return NULL;
+ }
+
+ for (p = (unsigned char *)str; *p && (pos + 1) < len; p++) {
+ if (json_exceptions[*p] == 0) {
+ buf[pos++] = *p;
+ continue;
+ }
+
+ if ((pos + 2) >= len) {
+ break;
+ }
+
+ switch (*p) {
+ case '\b':
+ buf[pos++] = '\\';
+ buf[pos++] = 'b';
+ break;
+ case '\n':
+ buf[pos++] = '\\';
+ buf[pos++] = 'n';
+ break;
+ case '\r':
+ buf[pos++] = '\\';
+ buf[pos++] = 'r';
+ break;
+ case '\t':
+ buf[pos++] = '\\';
+ buf[pos++] = 't';
+ break;
+ case '\\':
+ buf[pos++] = '\\';
+ buf[pos++] = '\\';
+ break;
+ case '"':
+ buf[pos++] = '\\';
+ buf[pos++] = '"';
+ break;
+ default:
+ if ((pos + 6) >= len) {
+ buf[pos] = '\0';
+ return (char *)p;
}
+ buf[pos++] = '\\';
+ buf[pos++] = 'u';
+ buf[pos++] = '0';
+ buf[pos++] = '0';
+ buf[pos++] = json_hex_chars[(*p) >> 4];
+ buf[pos++] = json_hex_chars[(*p) & 0xf];
+ break;
}
+ }
- buf[pos] = '\0';
- return (char *)p;
+ buf[pos] = '\0';
+ return (char *)p;
}
-
/**
* gf_syslog -function to submit message to syslog specific to gluster
* @facility_priority: facility_priority of syslog()
@@ -617,1823 +552,1895 @@ _json_escape(const char *str, char *buf, size_t len)
*
* @return: void
*/
-void
-gf_syslog (int facility_priority, char *format, ...)
+static void
+gf_syslog(int facility_priority, char *format, ...)
{
- char *msg = NULL;
- char json_msg[GF_JSON_MSG_LENGTH];
- GF_UNUSED char *p = NULL;
- va_list ap;
-
- GF_ASSERT (format);
-
- va_start (ap, format);
- if (vasprintf (&msg, format, ap) != -1) {
- p = _json_escape (msg, json_msg, GF_JSON_MSG_LENGTH);
- syslog (facility_priority, "%s", msg);
- free (msg);
- } else
- syslog (GF_LOG_CRITICAL, "vasprintf() failed, out of memory?");
- va_end (ap);
+ char *msg = NULL;
+ char json_msg[GF_JSON_MSG_LENGTH];
+ GF_UNUSED char *p = NULL;
+ va_list ap;
+
+ GF_ASSERT(format);
+
+ va_start(ap, format);
+ if (vasprintf(&msg, format, ap) != -1) {
+ p = _json_escape(msg, json_msg, GF_JSON_MSG_LENGTH);
+ syslog(facility_priority, "%s", msg);
+ free(msg);
+ } else
+ syslog(GF_LOG_CRITICAL, "vasprintf() failed, out of memory?");
+ va_end(ap);
}
void
-gf_log_globals_init (void *data)
+gf_log_globals_init(void *data, gf_loglevel_t level)
{
- glusterfs_ctx_t *ctx = data;
+ glusterfs_ctx_t *ctx = data;
- pthread_mutex_init (&ctx->log.logfile_mutex, NULL);
+ pthread_mutex_init(&ctx->log.logfile_mutex, NULL);
- ctx->log.loglevel = GF_LOG_INFO;
- ctx->log.gf_log_syslog = 1;
- ctx->log.sys_log_level = GF_LOG_CRITICAL;
- ctx->log.logger = gf_logger_glusterlog;
- ctx->log.logformat = gf_logformat_withmsgid;
- ctx->log.lru_size = GF_LOG_LRU_BUFSIZE_DEFAULT;
- ctx->log.timeout = GF_LOG_FLUSH_TIMEOUT_DEFAULT;
+ ctx->log.loglevel = level;
+ ctx->log.gf_log_syslog = 1;
+ ctx->log.sys_log_level = GF_LOG_CRITICAL;
+ ctx->log.logger = gf_logger_glusterlog;
+ ctx->log.logformat = gf_logformat_withmsgid;
+ ctx->log.lru_size = GF_LOG_LRU_BUFSIZE_DEFAULT;
+ ctx->log.timeout = GF_LOG_FLUSH_TIMEOUT_DEFAULT;
+ ctx->log.localtime = GF_LOG_LOCALTIME_DEFAULT;
- pthread_mutex_init (&ctx->log.log_buf_lock, NULL);
+ pthread_mutex_init(&ctx->log.log_buf_lock, NULL);
- INIT_LIST_HEAD (&ctx->log.lru_queue);
+ INIT_LIST_HEAD(&ctx->log.lru_queue);
#ifdef GF_LINUX_HOST_OS
- /* For the 'syslog' output. one can grep 'GlusterFS' in syslog
- for serious logs */
- openlog ("GlusterFS", LOG_PID, LOG_DAEMON);
+ /* For the 'syslog' output. one can grep 'GlusterFS' in syslog
+ for serious logs */
+ openlog("GlusterFS", LOG_PID, LOG_DAEMON);
#endif
-
}
int
-gf_log_init (void *data, const char *file, const char *ident)
+gf_log_init(void *data, const char *file, const char *ident)
{
- glusterfs_ctx_t *ctx = NULL;
- int fd = -1;
- struct stat buf;
-
- ctx = data;
-
- if (ctx == NULL) {
- fprintf (stderr, "ERROR: ctx is NULL\n");
- return -1;
- }
- if (ident) {
- ctx->log.ident = gf_strdup (ident);
- }
-
- /* we keep the files and the syslog open, so that on logger change, we
- * are ready to log anywhere, that the new value specifies */
- if (ctx->log.ident) {
- gf_openlog (ctx->log.ident, -1, LOG_DAEMON);
- } else {
- gf_openlog (NULL, -1, LOG_DAEMON);
- }
- /* TODO: make FACILITY configurable than LOG_DAEMON */
- if (stat (GF_LOG_CONTROL_FILE, &buf) == 0) {
- /* use syslog logging */
- ctx->log.log_control_file_found = 1;
- } else {
- /* use old style logging */
- ctx->log.log_control_file_found = 0;
- }
-
- if (!file) {
- fprintf (stderr, "ERROR: no filename specified\n");
- return -1;
+ glusterfs_ctx_t *ctx = data;
+ int fd = -1;
+ struct stat buf;
+
+ if (ctx == NULL) {
+ fprintf(stderr, "ERROR: ctx is NULL\n");
+ return -1;
+ }
+ if (ident) {
+ GF_FREE(ctx->log.ident);
+ ctx->log.ident = gf_strdup(ident);
+ }
+
+ /* we keep the files and the syslog open, so that on logger change, we
+ * are ready to log anywhere, that the new value specifies */
+ if (ctx->log.ident) {
+ gf_openlog(ctx->log.ident, -1, LOG_DAEMON);
+ } else {
+ gf_openlog(NULL, -1, LOG_DAEMON);
+ }
+ /* TODO: make FACILITY configurable than LOG_DAEMON */
+ if (sys_stat(GF_LOG_CONTROL_FILE, &buf) == 0) {
+ /* use syslog logging */
+ ctx->log.log_control_file_found = 1;
+ } else {
+ /* use old style logging */
+ ctx->log.log_control_file_found = 0;
+ }
+
+ if (!file) {
+ fprintf(stderr, "ERROR: no filename specified\n");
+ return -1;
+ }
+
+ /* free the (possible) previous filename */
+ GF_FREE(ctx->log.filename);
+ ctx->log.filename = NULL;
+
+ /* close and reopen logfile for log rotate */
+ if (ctx->log.logfile) {
+ fclose(ctx->log.logfile);
+ ctx->log.logfile = NULL;
+ ctx->log.gf_log_logfile = NULL;
+ }
+
+ if (strcmp(file, "-") == 0) {
+ int dupfd = -1;
+
+ ctx->log.filename = gf_strdup("/dev/stderr");
+ if (!ctx->log.filename) {
+ fprintf(stderr, "ERROR: strdup failed\n");
+ return -1;
}
- if (strcmp (file, "-") == 0) {
- int dupfd = -1;
-
- ctx->log.filename = gf_strdup ("/dev/stderr");
- if (!ctx->log.filename) {
- fprintf (stderr, "ERROR: strdup failed\n");
- return -1;
- }
-
- dupfd = dup (fileno (stderr));
- if (dupfd == -1) {
- fprintf (stderr, "ERROR: could not dup %d (%s)\n",
- fileno (stderr), strerror (errno));
- return -1;
- }
-
- ctx->log.logfile = fdopen (dupfd, "a");
- if (!ctx->log.logfile) {
- fprintf (stderr, "ERROR: could not fdopen on %d (%s)\n",
- dupfd, strerror (errno));
- return -1;
- }
-
- goto out;
+ dupfd = dup(fileno(stderr));
+ if (dupfd == -1) {
+ fprintf(stderr, "ERROR: could not dup %d (%s)\n", fileno(stderr),
+ strerror(errno));
+ return -1;
}
- ctx->log.filename = gf_strdup (file);
+ ctx->log.logfile = fdopen(dupfd, "a");
+ if (!ctx->log.logfile) {
+ fprintf(stderr, "ERROR: could not fdopen on %d (%s)\n", dupfd,
+ strerror(errno));
+ sys_close(dupfd);
+ return -1;
+ }
+ } else {
+ /* Also create parent dir */
+ char *logdir = gf_strdup(file);
+ if (!logdir) {
+ return -1;
+ }
+ char *tmp_index = rindex(logdir, '/');
+ if (tmp_index) {
+ tmp_index[0] = '\0';
+ }
+ if (mkdir_p(logdir, 0755, true)) {
+ /* EEXIST is handled in mkdir_p() itself */
+ gf_smsg("logging", GF_LOG_ERROR, 0, LG_MSG_STRDUP_ERROR,
+ "logdir=%s", logdir, "errno=%s", strerror(errno), NULL);
+ GF_FREE(logdir);
+ return -1;
+ }
+ /* no need of this variable */
+ GF_FREE(logdir);
+
+ ctx->log.filename = gf_strdup(file);
if (!ctx->log.filename) {
- fprintf (stderr, "ERROR: updating log-filename failed: %s\n",
- strerror (errno));
- return -1;
+ fprintf(stderr,
+ "ERROR: updating log-filename failed: "
+ "%s\n",
+ strerror(errno));
+ return -1;
}
- fd = open (file, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ fd = sys_open(file, O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR);
if (fd < 0) {
- fprintf (stderr, "ERROR: failed to create logfile"
- " \"%s\" (%s)\n", file, strerror (errno));
- return -1;
+ fprintf(stderr,
+ "ERROR: failed to create logfile"
+ " \"%s\" (%s)\n",
+ file, strerror(errno));
+ return -1;
}
- close (fd);
- ctx->log.logfile = fopen (file, "a");
+ ctx->log.logfile = fdopen(fd, "a");
if (!ctx->log.logfile) {
- fprintf (stderr, "ERROR: failed to open logfile \"%s\" (%s)\n",
- file, strerror (errno));
- return -1;
+ fprintf(stderr,
+ "ERROR: failed to open logfile \"%s\" "
+ "(%s)\n",
+ file, strerror(errno));
+ sys_close(fd);
+ return -1;
}
-out:
- ctx->log.gf_log_logfile = ctx->log.logfile;
+ }
- return 0;
+ ctx->log.gf_log_logfile = ctx->log.logfile;
+
+ return 0;
}
void
-set_sys_log_level (gf_loglevel_t level)
+set_sys_log_level(gf_loglevel_t level)
+{
+ if (THIS->ctx)
+ THIS->ctx->log.sys_log_level = level;
+}
+
+/* Check if we should be logging
+ * Return value: _gf_false : Print the log
+ * _gf_true : Do not Print the log
+ */
+static gf_boolean_t
+skip_logging(xlator_t *this, gf_loglevel_t level)
{
- glusterfs_ctx_t *ctx = NULL;
+ gf_loglevel_t existing_level = this->loglevel ? this->loglevel
+ : this->ctx->log.loglevel;
+ if (level > existing_level) {
+ return _gf_true;
+ }
- ctx = THIS->ctx;
+ if (level == GF_LOG_NONE) {
+ return _gf_true;
+ }
- if (ctx)
- ctx->log.sys_log_level = level;
+ return _gf_false;
}
int
-_gf_log_callingfn (const char *domain, const char *file, const char *function,
- int line, gf_loglevel_t level, const char *fmt, ...)
+_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;
- xlator_t *this = NULL;
- char *str1 = NULL;
- char *str2 = NULL;
- char *msg = NULL;
- char timestr[256] = {0,};
- char *callstr = NULL;
- struct timeval tv = {0,};
- size_t len = 0;
- int ret = 0;
- va_list ap;
- glusterfs_ctx_t *ctx = NULL;
-
- this = THIS;
- ctx = this->ctx;
-
- if (!ctx)
- goto out;
-
- if (ctx->log.gf_log_xl_log_set) {
- if (this->loglevel && (level > this->loglevel))
- goto out;
- }
- if (level > ctx->log.loglevel || level == GF_LOG_NONE)
- goto out;
-
- static char *level_strings[] = {"", /* NONE */
- "M", /* EMERGENCY */
- "A", /* ALERT */
- "C", /* CRITICAL */
- "E", /* ERROR */
- "W", /* WARNING */
- "N", /* NOTICE */
- "I", /* INFO */
- "D", /* DEBUG */
- "T", /* TRACE */
- ""};
-
- if (!domain || !file || !function || !fmt) {
- fprintf (stderr,
- "logging: %s:%s():%d: invalid argument\n",
- __FILE__, __PRETTY_FUNCTION__, __LINE__);
- return -1;
+ const char *basename = NULL;
+ xlator_t *this = THIS;
+ char *logline = NULL;
+ char *msg = NULL;
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ char *callstr = NULL;
+ struct timeval tv = {
+ 0,
+ };
+ int ret = 0;
+ va_list ap;
+ glusterfs_ctx_t *ctx = this->ctx;
+
+ if (!ctx)
+ goto out;
+
+ if (skip_logging(this, level))
+ goto out;
+
+ if (!domain || !file || !function || !fmt) {
+ fprintf(stderr, "logging: %s:%s():%d: invalid argument\n", __FILE__,
+ __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ basename = strrchr(file, '/');
+ if (basename)
+ basename++;
+ else
+ basename = file;
+
+ /*Saving the backtrace to pre-allocated ctx->btbuf
+ * to avoid allocating memory from the heap*/
+ callstr = gf_backtrace_save(NULL);
+
+ va_start(ap, fmt);
+ ret = vasprintf(&msg, fmt, ap);
+ va_end(ap);
+ if (-1 == ret) {
+ goto out;
+ }
+
+ if (ctx->log.log_control_file_found) {
+ int priority;
+ /* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
+ other level as is */
+ if (GF_LOG_TRACE == level || GF_LOG_NONE == level) {
+ priority = LOG_DEBUG;
+ } else {
+ priority = level - 1;
}
- basename = strrchr (file, '/');
- if (basename)
- basename++;
- else
- basename = file;
+ gf_syslog(priority, "[%s:%d:%s] %s %d-%s: %s", basename, line, function,
+ callstr, ((this->graph) ? this->graph->id : 0), domain, msg);
- /*Saving the backtrace to pre-allocated ctx->btbuf
- * to avoid allocating memory from the heap*/
- callstr = gf_backtrace_save (NULL);
+ goto out;
+ }
- if (ctx->log.log_control_file_found)
- {
- int priority;
- /* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
- other level as is */
- if (GF_LOG_TRACE == level || GF_LOG_NONE == level) {
- priority = LOG_DEBUG;
- } else {
- priority = level - 1;
- }
-
- va_start (ap, fmt);
- vasprintf (&str2, fmt, ap);
- va_end (ap);
+ ret = gettimeofday(&tv, NULL);
+ if (-1 == ret)
+ goto out;
- gf_syslog (priority, "[%s:%d:%s] %s %d-%s: %s",
- basename, line, function,
- callstr,
- ((this->graph) ? this->graph->id:0), domain,
- str2);
+ gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT);
- goto out;
- }
+ ret = gf_asprintf(&logline, "[%s] %c [%s:%d:%s] %s %d-%s: %s\n", timestr,
+ gf_level_strings[level], basename, line, function,
+ callstr, ((this->graph) ? this->graph->id : 0), domain,
+ msg);
+ if (-1 == ret) {
+ goto out;
+ }
- ret = gettimeofday (&tv, NULL);
- if (-1 == ret)
- goto out;
- va_start (ap, fmt);
- 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);
-
- ret = gf_asprintf (&str1, "[%s] %s [%s:%d:%s] %s %d-%s: ",
- timestr, level_strings[level],
- basename, line, function, callstr,
- ((this->graph) ? this->graph->id:0), domain);
- if (-1 == ret) {
- goto out;
- }
-
- ret = vasprintf (&str2, fmt, ap);
- if (-1 == ret) {
- goto out;
- }
-
- va_end (ap);
-
- len = strlen (str1);
- msg = GF_MALLOC (len + strlen (str2) + 1, gf_common_mt_char);
- if (!msg) {
- ret = -1;
- goto out;
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ fputs(logline, ctx->log.logfile);
+ fflush(ctx->log.logfile);
+ } else if (ctx->log.loglevel >= level) {
+ fputs(logline, stderr);
+ fflush(stderr);
}
- strcpy (msg, str1);
- strcpy (msg + len, str2);
-
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
- if (ctx->log.logfile) {
- fprintf (ctx->log.logfile, "%s\n", msg);
- fflush (ctx->log.logfile);
- } else if (ctx->log.loglevel >= level) {
- fprintf (stderr, "%s\n", msg);
- fflush (stderr);
- }
-
#ifdef GF_LINUX_HOST_OS
- /* We want only serious log in 'syslog', not our debug
- and trace logs */
- if (ctx->log.gf_log_syslog && level &&
- (level <= ctx->log.sys_log_level))
- syslog ((level-1), "%s\n", msg);
+ /* We want only serious log in 'syslog', not our debug
+ and trace logs */
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
+ syslog((level - 1), "%s", logline);
#endif
- }
+ }
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
out:
- GF_FREE (msg);
- GF_FREE (str1);
+ GF_FREE(logline);
- FREE (str2);
+ FREE(msg);
- return ret;
+ return ret;
}
-int
-_gf_msg_plain_internal (gf_loglevel_t level, const char *msg)
+static int
+_gf_msg_plain_internal(gf_loglevel_t level, const char *msg)
{
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
- int priority;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ int priority;
- this = THIS;
- ctx = this->ctx;
+ this = THIS;
+ ctx = this->ctx;
- /* log to the configured logging service */
- switch (ctx->log.logger) {
+ /* log to the configured logging service */
+ switch (ctx->log.logger) {
case gf_logger_syslog:
- if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
- SET_LOG_PRIO (level, priority);
+ if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
+ SET_LOG_PRIO(level, priority);
- syslog (priority, "%s", msg);
- break;
- }
- /* NOTE: If syslog control file is absent, which is another
- * way to control logging to syslog, then we will fall through
- * to the gluster log. The ideal way to do things would be to
- * not have the extra control file check */
+ syslog(priority, "%s", msg);
+ break;
+ }
+ /* NOTE: If syslog control file is absent, which is another
+ * way to control logging to syslog, then we will fall through
+ * to the gluster log. The ideal way to do things would be to
+ * not have the extra control file check */
case gf_logger_glusterlog:
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
- if (ctx->log.logfile) {
- fprintf (ctx->log.logfile, "%s\n", msg);
- fflush (ctx->log.logfile);
- } else {
- fprintf (stderr, "%s\n", msg);
- fflush (stderr);
- }
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ fprintf(ctx->log.logfile, "%s\n", msg);
+ fflush(ctx->log.logfile);
+ } else {
+ fprintf(stderr, "%s\n", msg);
+ fflush(stderr);
+ }
#ifdef GF_LINUX_HOST_OS
- /* We want only serious logs in 'syslog', not our debug
- * and trace logs */
- if (ctx->log.gf_log_syslog && level &&
- (level <= ctx->log.sys_log_level))
- syslog ((level-1), "%s\n", msg);
+ /* We want only serious logs in 'syslog', not our debug
+ * and trace logs */
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
+ syslog((level - 1), "%s\n", msg);
#endif
- }
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ }
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
- break;
- }
+ break;
+ }
- return 0;
+ return 0;
}
int
-_gf_msg_plain (gf_loglevel_t level, const char *fmt, ...)
+_gf_msg_plain(gf_loglevel_t level, const char *fmt, ...)
{
- xlator_t *this = NULL;
- int ret = 0;
- va_list ap;
- char *msg = NULL;
- glusterfs_ctx_t *ctx = NULL;
+ xlator_t *this = NULL;
+ int ret = 0;
+ va_list ap;
+ char *msg = NULL;
+ glusterfs_ctx_t *ctx = NULL;
- this = THIS;
- ctx = this->ctx;
+ this = THIS;
+ ctx = this->ctx;
- if (!ctx)
- goto out;
+ if (!ctx)
+ goto out;
- if (ctx->log.gf_log_xl_log_set) {
- if (this->loglevel && (level > this->loglevel))
- goto out;
- }
- if (level > ctx->log.loglevel || level == GF_LOG_NONE)
- goto out;
+ if (skip_logging(this, level))
+ goto out;
- va_start (ap, fmt);
- ret = vasprintf (&msg, fmt, ap);
- va_end (ap);
- if (-1 == ret) {
- goto out;
- }
+ va_start(ap, fmt);
+ ret = vasprintf(&msg, fmt, ap);
+ va_end(ap);
+ if (-1 == ret) {
+ goto out;
+ }
- ret = _gf_msg_plain_internal (level, msg);
+ ret = _gf_msg_plain_internal(level, msg);
- FREE (msg);
+ FREE(msg);
out:
- return ret;
+ return ret;
}
int
-_gf_msg_vplain (gf_loglevel_t level, const char *fmt, va_list ap)
+_gf_msg_vplain(gf_loglevel_t level, const char *fmt, va_list ap)
{
- xlator_t *this = NULL;
- int ret = 0;
- char *msg = NULL;
- glusterfs_ctx_t *ctx = NULL;
+ xlator_t *this = NULL;
+ int ret = 0;
+ char *msg = NULL;
+ glusterfs_ctx_t *ctx = NULL;
- this = THIS;
- ctx = this->ctx;
+ this = THIS;
+ ctx = this->ctx;
- if (!ctx)
- goto out;
+ if (!ctx)
+ goto out;
- if (ctx->log.gf_log_xl_log_set) {
- if (this->loglevel && (level > this->loglevel))
- goto out;
- }
- if (level > ctx->log.loglevel || level == GF_LOG_NONE)
- goto out;
+ if (skip_logging(this, level))
+ goto out;
- ret = vasprintf (&msg, fmt, ap);
- if (-1 == ret) {
- goto out;
- }
+ ret = vasprintf(&msg, fmt, ap);
+ if (-1 == ret) {
+ goto out;
+ }
- ret = _gf_msg_plain_internal (level, msg);
+ ret = _gf_msg_plain_internal(level, msg);
- FREE (msg);
+ FREE(msg);
out:
- return ret;
+ return ret;
}
int
-_gf_msg_plain_nomem (gf_loglevel_t level, const char *msg)
+_gf_msg_plain_nomem(gf_loglevel_t level, const char *msg)
{
- xlator_t *this = NULL;
- int ret = 0;
- glusterfs_ctx_t *ctx = NULL;
+ xlator_t *this = NULL;
+ int ret = 0;
+ glusterfs_ctx_t *ctx = NULL;
- this = THIS;
- ctx = this->ctx;
+ this = THIS;
+ ctx = this->ctx;
- if (!ctx)
- goto out;
+ if (!ctx)
+ goto out;
- if (ctx->log.gf_log_xl_log_set) {
- if (this->loglevel && (level > this->loglevel))
- goto out;
- }
- if (level > ctx->log.loglevel || level == GF_LOG_NONE)
- goto out;
+ if (skip_logging(this, level))
+ goto out;
- ret = _gf_msg_plain_internal (level, msg);
+ ret = _gf_msg_plain_internal(level, msg);
out:
- return ret;
+ return ret;
}
void
-_gf_msg_backtrace_nomem (gf_loglevel_t level, int stacksize)
+_gf_msg_backtrace_nomem(gf_loglevel_t level, int stacksize)
{
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
- void *array[200];
- size_t bt_size = 0;
- int fd = -1;
-
- this = THIS;
- ctx = this->ctx;
-
- if (!ctx)
- goto out;
-
- /* syslog does not have fd support, hence no no-mem variant */
- if (ctx->log.logger != gf_logger_glusterlog)
- goto out;
-
- if (ctx->log.gf_log_xl_log_set) {
- if (this->loglevel && (level > this->loglevel))
- goto out;
- }
- if (level > ctx->log.loglevel || level == GF_LOG_NONE)
- goto out;
-
- bt_size = backtrace (array, ((stacksize <= 200)? stacksize : 200));
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
- fd = ctx->log.logfile?
- fileno (ctx->log.logfile) :
- fileno (stderr);
- if (bt_size && (fd != -1)) {
- /* print to the file fd, to prevent any
- allocations from backtrace_symbols
- */
- backtrace_symbols_fd (&array[0], bt_size, fd);
- }
- }
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ void *array[200];
+ size_t bt_size = 0;
+ int fd = -1;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ if (!ctx)
+ goto out;
+
+ /* syslog does not have fd support, hence no no-mem variant */
+ if (ctx->log.logger != gf_logger_glusterlog)
+ goto out;
+
+ if (skip_logging(this, level))
+ goto out;
+
+ bt_size = backtrace(array, ((stacksize <= 200) ? stacksize : 200));
+ if (!bt_size)
+ goto out;
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ fd = ctx->log.logfile ? fileno(ctx->log.logfile) : fileno(stderr);
+ if (fd != -1) {
+ /* print to the file fd, to prevent any
+ allocations from backtrace_symbols
+ */
+ backtrace_symbols_fd(&array[0], bt_size, fd);
+ }
+ }
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
out:
- return;
+ return;
}
int
-_gf_msg_backtrace (int stacksize, char *callstr, size_t strsize)
+_gf_msg_backtrace(int stacksize, char *callstr, size_t strsize)
{
- int ret = -1;
- int i = 0;
- int size = 0;
- int savstrsize = strsize;
- void *array[200];
- char **callingfn = NULL;
-
- /* We chop off last 2 anyway, so if request is less than tolerance
- * nothing to do */
- if (stacksize < 3)
- goto out;
-
- size = backtrace (array, ((stacksize <= 200)? stacksize : 200));
- if ((size - 3) < 0)
- goto out;
- if (size)
- callingfn = backtrace_symbols (&array[2], size - 2);
- if (!callingfn)
- goto out;
-
- ret = snprintf (callstr, strsize, "(");
- PRINT_SIZE_CHECK (ret, out, strsize);
-
- for ((i = size - 3); i >= 0; i--) {
- ret = snprintf (callstr + savstrsize - strsize, strsize,
- "-->%s ", callingfn[i]);
- PRINT_SIZE_CHECK (ret, out, strsize);
- }
-
- ret = snprintf (callstr + savstrsize - strsize, strsize, ")");
- PRINT_SIZE_CHECK (ret, out, strsize);
+ int ret = -1;
+ int i = 0;
+ int size = 0;
+ int savstrsize = strsize;
+ void *array[200];
+ char **callingfn = NULL;
+
+ /* We chop off last 2 anyway, so if request is less than tolerance
+ * nothing to do */
+ if (stacksize < 3)
+ goto out;
+
+ size = backtrace(array, ((stacksize <= 200) ? stacksize : 200));
+ if ((size - 3) < 0)
+ goto out;
+ if (size)
+ callingfn = backtrace_symbols(&array[2], size - 2);
+ if (!callingfn)
+ goto out;
+
+ ret = snprintf(callstr, strsize, "(");
+ PRINT_SIZE_CHECK(ret, out, strsize);
+
+ for ((i = size - 3); i >= 0; i--) {
+ ret = snprintf(callstr + savstrsize - strsize, strsize, "-->%s ",
+ callingfn[i]);
+ PRINT_SIZE_CHECK(ret, out, strsize);
+ }
+
+ ret = snprintf(callstr + savstrsize - strsize, strsize, ")");
+ PRINT_SIZE_CHECK(ret, out, strsize);
out:
- FREE (callingfn);
- return ret;
+ FREE(callingfn);
+ return ret;
}
int
-_gf_msg_nomem (const char *domain, const char *file,
- const char *function, int line, gf_loglevel_t level,
- size_t size)
+_gf_msg_nomem(const char *domain, const char *file, const char *function,
+ int line, gf_loglevel_t level, size_t size)
{
- const char *basename = NULL;
- xlator_t *this = NULL;
- struct timeval tv = {0,};
- int ret = 0;
- int fd = -1;
- char msg[2048] = {0,};
- char timestr[GF_LOG_TIMESTR_SIZE] = {0,};
- glusterfs_ctx_t *ctx = NULL;
- int wlen = 0;
- int priority;
-
- this = THIS;
- ctx = this->ctx;
-
- if (!ctx)
- goto out;
-
- if (ctx->log.gf_log_xl_log_set) {
- if (this->loglevel && (level > this->loglevel))
- goto out;
- }
- if (level > ctx->log.loglevel || level == GF_LOG_NONE)
- goto out;
-
- if (!domain || !file || !function) {
- fprintf (stderr,
- "logging: %s:%s():%d: invalid argument\n",
- __FILE__, __PRETTY_FUNCTION__, __LINE__);
- return -1;
- }
-
- GET_FILE_NAME_TO_LOG (file, basename);
-
- ret = gettimeofday (&tv, NULL);
- if (-1 == ret)
- goto out;
- gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
- ret = snprintf (timestr + strlen (timestr),
- sizeof timestr - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, tv.tv_usec);
- if (-1 == ret) {
- goto out;
- }
+ const char *basename = NULL;
+ xlator_t *this = NULL;
+ struct timeval tv = {
+ 0,
+ };
+ int ret = 0;
+ int fd = -1;
+ char msg[2048] = {
+ 0,
+ };
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ glusterfs_ctx_t *ctx = NULL;
+ int wlen = 0;
+ int priority;
+ struct rusage r_usage;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ if (!ctx)
+ goto out;
+
+ if (skip_logging(this, level))
+ goto out;
+
+ if (!domain || !file || !function) {
+ fprintf(stderr, "logging: %s:%s():%d: invalid argument\n", __FILE__,
+ __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ GET_FILE_NAME_TO_LOG(file, basename);
+
+ ret = gettimeofday(&tv, NULL);
+ if (-1 == ret)
+ goto out;
+ gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT);
+
+ /* TODO: Currently we print in the enhanced format, with a message ID
+ * of 0. Need to enhance this to support format as configured */
+ wlen = snprintf(
+ msg, sizeof msg,
+ "[%s] %c [MSGID: %" PRIu64
+ "]"
+ " [%s:%d:%s] %s: no memory "
+ "available for size (%" GF_PRI_SIZET
+ ") current memory usage in kilobytes %ld"
+ " [call stack follows]\n",
+ timestr, gf_level_strings[level], (uint64_t)0, basename, line, function,
+ domain, size,
+ (!getrusage(RUSAGE_SELF, &r_usage) ? r_usage.ru_maxrss : 0));
+ if (-1 == wlen) {
+ ret = -1;
+ goto out;
+ }
+
+ /* log to the configured logging service */
+ switch (ctx->log.logger) {
+ case gf_logger_syslog:
+ if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
+ SET_LOG_PRIO(level, priority);
- /* TODO: Currently we print in the enhanced format, with a message ID
- * of 0. Need to enhance this to support format as configured */
- ret = snprintf (msg, sizeof msg, "[%s] %s [MSGID: %"PRIu64"]"
- " [%s:%d:%s] %s: no memory "
- "available for size (%"GF_PRI_SIZET")"
- " [call stack follows]\n",
- timestr, gf_level_strings[level], (uint64_t) 0,
- basename, line, function, domain, size);
- if (-1 == ret) {
- goto out;
- }
+ /* if syslog allocates, then this may fail, but we
+ * cannot do much about it at the moment */
+ /* There is no fd for syslog, hence no stack printed */
+ syslog(priority, "%s", msg);
+ break;
+ }
+ /* NOTE: If syslog control file is absent, which is another
+ * way to control logging to syslog, then we will fall through
+ * to the gluster log. The ideal way to do things would be to
+ * not have the extra control file check */
+ case gf_logger_glusterlog:
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ fd = ctx->log.logfile ? fileno(ctx->log.logfile)
+ : fileno(stderr);
+ if (fd == -1) {
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
+ goto out;
+ }
- /* log to the configured logging service */
- switch (ctx->log.logger) {
- case gf_logger_syslog:
- if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
- SET_LOG_PRIO (level, priority);
-
- /* if syslog allocates, then this may fail, but we
- * cannot do much about it at the moment */
- /* There is no fd for syslog, hence no stack printed */
- syslog (priority, "%s", msg);
- break;
+ /* write directly to the fd to prevent out of order
+ * message and stack */
+ ret = sys_write(fd, msg, wlen);
+ if (ret == -1) {
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
+ goto out;
}
- /* NOTE: If syslog control file is absent, which is another
- * way to control logging to syslog, then we will fall through
- * to the gluster log. The ideal way to do things would be to
- * not have the extra control file check */
- case gf_logger_glusterlog:
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
- fd = ctx->log.logfile? fileno (ctx->log.logfile) :
- fileno (stderr);
- if (fd == -1) {
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
- goto out;
- }
-
- wlen = strlen (msg);
-
- /* write directly to the fd to prevent out of order
- * message and stack */
- ret = write (fd, msg, wlen);
- if (ret == -1) {
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
- goto out;
- }
#ifdef GF_LINUX_HOST_OS
- /* We want only serious log in 'syslog', not our debug
- * and trace logs */
- if (ctx->log.gf_log_syslog && level &&
- (level <= ctx->log.sys_log_level))
- syslog ((level-1), "%s\n", msg);
+ /* We want only serious log in 'syslog', not our debug
+ * and trace logs */
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
+ syslog((level - 1), "%s\n", msg);
#endif
- }
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ }
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
- _gf_msg_backtrace_nomem (level, GF_LOG_BACKTRACE_DEPTH);
+ _gf_msg_backtrace_nomem(level, GF_LOG_BACKTRACE_DEPTH);
- break;
- }
+ break;
+ }
out:
- return ret;
+ return ret;
}
static int
-gf_log_syslog (glusterfs_ctx_t *ctx, const char *domain, const char *file,
- const char *function, int32_t line, gf_loglevel_t level,
- int errnum, uint64_t msgid, char **appmsgstr, char *callstr,
- int graph_id, gf_log_format_t fmt)
+gf_log_syslog(glusterfs_ctx_t *ctx, const char *domain, const char *file,
+ const char *function, int32_t line, gf_loglevel_t level,
+ int errnum, uint64_t msgid, char **appmsgstr, char *callstr,
+ int graph_id, gf_log_format_t fmt)
{
- int priority;
-
- SET_LOG_PRIO (level, priority);
-
- /* log with appropriate format */
- switch (fmt) {
- case gf_logformat_traditional:
- if (!callstr) {
- if (errnum)
- syslog (priority, "[%s:%d:%s] %d-%s: %s [%s]",
- file, line, function, graph_id, domain,
- *appmsgstr, strerror(errnum));
- else
- syslog (priority, "[%s:%d:%s] %d-%s: %s",
- file, line, function, graph_id, domain,
- *appmsgstr);
- } else {
- if (errnum)
- syslog (priority, "[%s:%d:%s] %s %d-%s:"
- " %s [%s]",
- file, line, function, callstr, graph_id,
- domain, *appmsgstr, strerror(errnum));
- else
- syslog (priority, "[%s:%d:%s] %s %d-%s: %s",
- file, line, function, callstr, graph_id,
- domain, *appmsgstr);
- }
- break;
- case gf_logformat_withmsgid:
- if (!callstr) {
- if (errnum)
- syslog (priority, "[MSGID: %"PRIu64"]"
- " [%s:%d:%s] %d-%s: %s [%s]", msgid,
- file, line, function, graph_id, domain,
- *appmsgstr, strerror(errnum));
- else
- syslog (priority, "[MSGID: %"PRIu64"]"
- " [%s:%d:%s] %d-%s: %s",
- msgid, file, line, function, graph_id,
- domain, *appmsgstr);
- } else {
- if (errnum)
- syslog (priority, "[MSGID: %"PRIu64"]"
- " [%s:%d:%s] %s %d-%s: %s [%s]",
- msgid, file, line, function, callstr,
- graph_id, domain, *appmsgstr,
- strerror(errnum));
- else
- syslog (priority, "[MSGID: %"PRIu64"]"
- " [%s:%d:%s] %s %d-%s: %s",
- msgid, file, line, function, callstr,
- graph_id, domain, *appmsgstr);
- }
- break;
- case gf_logformat_cee:
- /* TODO: Enhance CEE with additional parameters */
- gf_syslog (priority, "[%s:%d:%s] %d-%s: %s",
- file, line, function, graph_id, domain, *appmsgstr);
- break;
-
- default:
- /* NOTE: should not get here without logging */
- break;
- }
-
- /* TODO: There can be no errors from gf_syslog? */
- return 0;
+ int priority;
+
+ SET_LOG_PRIO(level, priority);
+
+ /* log with appropriate format */
+ switch (fmt) {
+ case gf_logformat_traditional:
+ if (!callstr) {
+ if (errnum)
+ syslog(priority, "[%s:%d:%s] %d-%s: %s [%s]", file, line,
+ function, graph_id, domain, *appmsgstr,
+ strerror(errnum));
+ else
+ syslog(priority, "[%s:%d:%s] %d-%s: %s", file, line,
+ function, graph_id, domain, *appmsgstr);
+ } else {
+ if (errnum)
+ syslog(priority,
+ "[%s:%d:%s] %s %d-%s:"
+ " %s [%s]",
+ file, line, function, callstr, graph_id, domain,
+ *appmsgstr, strerror(errnum));
+ else
+ syslog(priority, "[%s:%d:%s] %s %d-%s: %s", file, line,
+ function, callstr, graph_id, domain, *appmsgstr);
+ }
+ break;
+ case gf_logformat_withmsgid:
+ if (!callstr) {
+ if (errnum)
+ syslog(priority,
+ "[MSGID: %" PRIu64
+ "]"
+ " [%s:%d:%s] %d-%s: %s [%s]",
+ msgid, file, line, function, graph_id, domain,
+ *appmsgstr, strerror(errnum));
+ else
+ syslog(priority,
+ "[MSGID: %" PRIu64
+ "]"
+ " [%s:%d:%s] %d-%s: %s",
+ msgid, file, line, function, graph_id, domain,
+ *appmsgstr);
+ } else {
+ if (errnum)
+ syslog(priority,
+ "[MSGID: %" PRIu64
+ "]"
+ " [%s:%d:%s] %s %d-%s: %s [%s]",
+ msgid, file, line, function, callstr, graph_id,
+ domain, *appmsgstr, strerror(errnum));
+ else
+ syslog(priority,
+ "[MSGID: %" PRIu64
+ "]"
+ " [%s:%d:%s] %s %d-%s: %s",
+ msgid, file, line, function, callstr, graph_id,
+ domain, *appmsgstr);
+ }
+ break;
+ case gf_logformat_cee:
+ /* TODO: Enhance CEE with additional parameters */
+ gf_syslog(priority, "[%s:%d:%s] %d-%s: %s", file, line, function,
+ graph_id, domain, *appmsgstr);
+ break;
+
+ default:
+ /* NOTE: should not get here without logging */
+ break;
+ }
+
+ /* TODO: There can be no errors from gf_syslog? */
+ return 0;
}
static int
-gf_log_glusterlog (glusterfs_ctx_t *ctx, const char *domain, const char *file,
- const char *function, int32_t line, gf_loglevel_t level,
- int errnum, uint64_t msgid, char **appmsgstr, char *callstr,
- struct timeval tv, int graph_id, gf_log_format_t fmt)
+gf_log_glusterlog(glusterfs_ctx_t *ctx, const char *domain, const char *file,
+ const char *function, int32_t line, gf_loglevel_t level,
+ int errnum, uint64_t msgid, char **appmsgstr, char *callstr,
+ struct timeval tv, int graph_id, gf_log_format_t fmt)
{
- char timestr[GF_LOG_TIMESTR_SIZE] = {0,};
- char *header = NULL;
- char *footer = NULL;
- char *msg = NULL;
- size_t hlen = 0, flen = 0, mlen = 0;
- int ret = 0;
-
- /* rotate if required */
- gf_log_rotate(ctx);
-
- /* format the time stamp */
- 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);
-
- /* generate header and footer */
- if (fmt == gf_logformat_traditional) {
- if (!callstr) {
- ret = gf_asprintf (&header, "[%s] %s [%s:%d:%s]"
- " %d-%s: ",
- timestr, gf_level_strings[level],
- file, line, function, graph_id,
- domain);
- } else {
- ret = gf_asprintf (&header, "[%s] %s [%s:%d:%s] %s"
- " %d-%s: ",
- timestr, gf_level_strings[level],
- file, line, function, callstr,
- graph_id, domain);
- }
- if (-1 == ret) {
- goto err;
- }
- } else { /* gf_logformat_withmsgid */
- /* CEE log format unsupported in logger_glusterlog, so just
- * print enhanced log format */
- if (!callstr) {
- ret = gf_asprintf (&header, "[%s] %s [MSGID: %"PRIu64"]"
- " [%s:%d:%s] %d-%s: ",
- timestr, gf_level_strings[level],
- msgid, file, line, function,
- graph_id, domain);
- } else {
- ret = gf_asprintf (&header, "[%s] %s [MSGID: %"PRIu64"]"
- " [%s:%d:%s] %s %d-%s: ",
- timestr, gf_level_strings[level],
- msgid, file, line, function, callstr,
- graph_id, domain);
- }
- if (-1 == ret) {
- goto err;
- }
- }
-
- if (errnum) {
- ret = gf_asprintf (&footer, " [%s]",strerror(errnum));
- if (-1 == ret) {
- goto err;
- }
- }
-
- /* generate the full message to log */
- hlen = strlen (header);
- flen = footer? strlen (footer) : 0;
- mlen = strlen (*appmsgstr);
- msg = GF_MALLOC (hlen + flen + mlen + 1, gf_common_mt_char);
- if (!msg) {
- ret = -1;
- goto err;
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ char *header = NULL;
+ char *footer = NULL;
+ int ret = 0;
+
+ /* rotate if required */
+ gf_log_rotate(ctx);
+
+ /* format the time stamp */
+ gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT);
+
+ /* generate footer */
+ if (errnum) {
+ ret = gf_asprintf(&footer, " [%s]\n", strerror(errnum));
+ } else {
+ ret = gf_asprintf(&footer, " \n");
+ }
+ if (-1 == ret) {
+ goto err;
+ }
+
+ /* generate message, inc. the header */
+ if (fmt == gf_logformat_traditional) {
+ if (!callstr) {
+ ret = gf_asprintf(&header,
+ "[%s] %c [%s:%d:%s]"
+ " %d-%s: %s",
+ timestr, gf_level_strings[level], file, line,
+ function, graph_id, domain, *appmsgstr);
+ } else {
+ ret = gf_asprintf(&header,
+ "[%s] %c [%s:%d:%s] %s"
+ " %d-%s: %s",
+ timestr, gf_level_strings[level], file, line,
+ function, callstr, graph_id, domain, *appmsgstr);
+ }
+ } else { /* gf_logformat_withmsgid */
+ /* CEE log format unsupported in logger_glusterlog, so just
+ * print enhanced log format */
+ if (!callstr) {
+ ret = gf_asprintf(&header,
+ "[%s] %c [MSGID: %" PRIu64
+ "]"
+ " [%s:%d:%s] %d-%s: %s",
+ timestr, gf_level_strings[level], msgid, file,
+ line, function, graph_id, domain, *appmsgstr);
+ } else {
+ ret = gf_asprintf(&header,
+ "[%s] %c [MSGID: %" PRIu64
+ "]"
+ " [%s:%d:%s] %s %d-%s: %s",
+ timestr, gf_level_strings[level], msgid, file,
+ line, function, callstr, graph_id, domain,
+ *appmsgstr);
+ }
+ }
+ if (-1 == ret) {
+ goto err;
+ }
+
+ /* send the full message to log */
+
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ fprintf(ctx->log.logfile, "%s%s", header, footer);
+ fflush(ctx->log.logfile);
+ } else if (ctx->log.loglevel >= level) {
+ fprintf(stderr, "%s%s", header, footer);
+ fflush(stderr);
}
- strcpy (msg, header);
- strcpy (msg + hlen, *appmsgstr);
- if (footer)
- strcpy (msg + hlen + mlen, footer);
-
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
- if (ctx->log.logfile) {
- fprintf (ctx->log.logfile, "%s\n", msg);
- fflush (ctx->log.logfile);
- } else if (ctx->log.loglevel >= level) {
- fprintf (stderr, "%s\n", msg);
- fflush (stderr);
- }
-
#ifdef GF_LINUX_HOST_OS
- /* We want only serious logs in 'syslog', not our debug
- * and trace logs */
- if (ctx->log.gf_log_syslog && level &&
- (level <= ctx->log.sys_log_level))
- syslog ((level-1), "%s\n", msg);
-#endif
+ /* We want only serious logs in 'syslog', not our debug
+ * and trace logs */
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level)) {
+ syslog((level - 1), "%s%s", header, footer);
}
+#endif
+ }
- /* TODO: Plugin in memory log buffer retention here. For logs not
- * flushed during cores, it would be useful to retain some of the last
- * few messages in memory */
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
- ret = 0;
+ /* TODO: Plugin in memory log buffer retention here. For logs not
+ * flushed during cores, it would be useful to retain some of the last
+ * few messages in memory */
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
+ ret = 0;
err:
- GF_FREE (msg);
- GF_FREE (header);
- GF_FREE (footer);
+ GF_FREE(header);
+ GF_FREE(footer);
- return ret;
+ return ret;
}
static int
-gf_syslog_log_repetitions (const char *domain, const char *file,
- const char *function, int32_t line,
- gf_loglevel_t level, int errnum, uint64_t msgid,
- char **appmsgstr, char *callstr, int refcount,
- struct timeval oldest, struct timeval latest,
- int graph_id)
+gf_syslog_log_repetitions(const char *domain, const char *file,
+ const char *function, int32_t line,
+ gf_loglevel_t level, int errnum, uint64_t msgid,
+ char **appmsgstr, char *callstr, int refcount,
+ struct timeval oldest, struct timeval latest,
+ int graph_id)
{
- int priority;
- char timestr_latest[256] = {0,};
- char timestr_oldest[256] = {0,};
-
- SET_LOG_PRIO (level, priority);
-
- gf_time_fmt (timestr_latest, sizeof timestr_latest, latest.tv_sec,
- gf_timefmt_FT);
- snprintf (timestr_latest + strlen (timestr_latest),
- sizeof (timestr_latest) - strlen (timestr_latest),
- ".%"GF_PRI_SUSECONDS, latest.tv_usec);
-
- gf_time_fmt (timestr_oldest, sizeof timestr_oldest, oldest.tv_sec,
- gf_timefmt_FT);
- snprintf (timestr_oldest + strlen (timestr_oldest),
- sizeof (timestr_oldest) - strlen (timestr_oldest),
- ".%"GF_PRI_SUSECONDS, oldest.tv_usec);
-
- if (errnum) {
- syslog (priority, "The message \"[MSGID: %"PRIu64"] [%s:%d:%s] "
- "%d-%s: %s [%s] \" repeated %d times between %s and %s",
- msgid, file, line, function, graph_id, domain,
- *appmsgstr, strerror(errnum), refcount, timestr_oldest,
- timestr_latest);
- } else {
- syslog (priority, "The message \"[MSGID: %"PRIu64"] [%s:%d:%s] "
- "%d-%s: %s \" repeated %d times between %s and %s",
- msgid, file, line, function, graph_id, domain,
- *appmsgstr, refcount, timestr_oldest, timestr_latest);
- }
- return 0;
+ int priority;
+ char timestr_latest[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ char timestr_oldest[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+
+ SET_LOG_PRIO(level, priority);
+
+ gf_time_fmt_tv(timestr_latest, sizeof timestr_latest, &latest,
+ gf_timefmt_FT);
+ gf_time_fmt_tv(timestr_oldest, sizeof timestr_oldest, &oldest,
+ gf_timefmt_FT);
+
+ if (errnum) {
+ syslog(priority,
+ "The message \"[MSGID: %" PRIu64
+ "] [%s:%d:%s] "
+ "%d-%s: %s [%s] \" repeated %d times between %s"
+ " and %s",
+ msgid, file, line, function, graph_id, domain, *appmsgstr,
+ strerror(errnum), refcount, timestr_oldest, timestr_latest);
+ } else {
+ syslog(priority,
+ "The message \"[MSGID: %" PRIu64
+ "] [%s:%d:%s] "
+ "%d-%s: %s \" repeated %d times between %s"
+ " and %s",
+ msgid, file, line, function, graph_id, domain, *appmsgstr,
+ refcount, timestr_oldest, timestr_latest);
+ }
+ return 0;
}
static int
-gf_glusterlog_log_repetitions (glusterfs_ctx_t *ctx, const char *domain,
- const char *file, const char *function,
- int32_t line, gf_loglevel_t level, int errnum,
- uint64_t msgid, char **appmsgstr, char *callstr,
- int refcount, struct timeval oldest,
- struct timeval latest, int graph_id)
+gf_glusterlog_log_repetitions(glusterfs_ctx_t *ctx, const char *domain,
+ const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum,
+ uint64_t msgid, char **appmsgstr, char *callstr,
+ int refcount, struct timeval oldest,
+ struct timeval latest, int graph_id)
{
- int ret = 0;
- size_t hlen = 0;
- size_t flen = 0;
- size_t mlen = 0;
- char timestr_latest[256] = {0,};
- char timestr_oldest[256] = {0,};
- char errstr[256] = {0,};
- char *header = NULL;
- char *footer = NULL;
- char *msg = NULL;
-
- if (!ctx)
- goto err;
-
- gf_log_rotate (ctx);
-
- gf_time_fmt (timestr_latest, sizeof timestr_latest, latest.tv_sec,
- gf_timefmt_FT);
- snprintf (timestr_latest + strlen (timestr_latest),
- sizeof (timestr_latest) - strlen (timestr_latest),
- ".%"GF_PRI_SUSECONDS, latest.tv_usec);
-
- gf_time_fmt (timestr_oldest, sizeof timestr_oldest, oldest.tv_sec,
- gf_timefmt_FT);
- snprintf (timestr_oldest + strlen (timestr_oldest),
- sizeof (timestr_oldest) - strlen (timestr_oldest),
- ".%"GF_PRI_SUSECONDS, oldest.tv_usec);
-
- ret = gf_asprintf (&header, "The message \"%s [MSGID: %"PRIu64"]"
- " [%s:%d:%s] %d-%s: ", gf_level_strings[level],
- msgid, file, line, function, graph_id, domain);
- if (-1 == ret)
- goto err;
-
- if (errnum)
- snprintf (errstr, sizeof (errstr) - 1, " [%s]",
- strerror (errnum));
-
- ret = gf_asprintf (&footer, "%s\" repeated %d times between"
- " [%s] and [%s]", errstr, refcount, timestr_oldest,
- timestr_latest);
- if (-1 == ret)
- goto err;
-
- /* generate the full message to log */
- hlen = strlen (header);
- flen = strlen (footer);
- mlen = strlen (*appmsgstr);
- msg = GF_MALLOC (hlen + flen + mlen + 1, gf_common_mt_char);
- if (!msg) {
- ret = -1;
- goto err;
+ int ret = 0;
+ char timestr_latest[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ char timestr_oldest[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ char errstr[256] = {
+ 0,
+ };
+ char *header = NULL;
+ char *footer = NULL;
+
+ if (!ctx)
+ goto err;
+
+ gf_log_rotate(ctx);
+
+ ret = gf_asprintf(&header,
+ "The message \"%c [MSGID: %" PRIu64
+ "]"
+ " [%s:%d:%s] %d-%s: %s",
+ gf_level_strings[level], msgid, file, line, function,
+ graph_id, domain, *appmsgstr);
+ if (-1 == ret) {
+ goto err;
+ }
+
+ gf_time_fmt_tv(timestr_latest, sizeof timestr_latest, &latest,
+ gf_timefmt_FT);
+
+ gf_time_fmt_tv(timestr_oldest, sizeof timestr_oldest, &oldest,
+ gf_timefmt_FT);
+
+ if (errnum)
+ snprintf(errstr, sizeof(errstr) - 1, " [%s]", strerror(errnum));
+
+ ret = gf_asprintf(&footer, "%s\" repeated %d times between [%s] and [%s]",
+ errstr, refcount, timestr_oldest, timestr_latest);
+ if (-1 == ret) {
+ ret = -1;
+ goto err;
+ }
+
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ fprintf(ctx->log.logfile, "%s%s\n", header, footer);
+ fflush(ctx->log.logfile);
+ } else if (ctx->log.loglevel >= level) {
+ fprintf(stderr, "%s%s\n", header, footer);
+ fflush(stderr);
}
- strcpy (msg, header);
- strcpy (msg + hlen, *appmsgstr);
- strcpy (msg + hlen + mlen, footer);
-
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
- if (ctx->log.logfile) {
- fprintf (ctx->log.logfile, "%s\n", msg);
- fflush (ctx->log.logfile);
- } else if (ctx->log.loglevel >= level) {
- fprintf (stderr, "%s\n", msg);
- fflush (stderr);
- }
-
#ifdef GF_LINUX_HOST_OS
- /* We want only serious logs in 'syslog', not our debug
- * and trace logs */
- if (ctx->log.gf_log_syslog && level &&
- (level <= ctx->log.sys_log_level))
- syslog ((level-1), "%s\n", msg);
+ /* We want only serious logs in 'syslog', not our debug
+ * and trace logs */
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
+ syslog((level - 1), "%s%s\n", header, footer);
#endif
- }
+ }
- /* TODO: Plugin in memory log buffer retention here. For logs not
- * flushed during cores, it would be useful to retain some of the last
- * few messages in memory */
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
- ret = 0;
+ /* TODO: Plugin in memory log buffer retention here. For logs not
+ * flushed during cores, it would be useful to retain some of the last
+ * few messages in memory */
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
+ ret = 0;
err:
- GF_FREE (msg);
- GF_FREE (header);
- GF_FREE (footer);
+ GF_FREE(header);
+ GF_FREE(footer);
- return ret;
+ return ret;
}
static int
-gf_log_print_with_repetitions (glusterfs_ctx_t *ctx, const char *domain,
- const char *file, const char *function,
- int32_t line, gf_loglevel_t level, int errnum,
- uint64_t msgid, char **appmsgstr, char *callstr,
- int refcount, struct timeval oldest,
- struct timeval latest, int graph_id)
+gf_log_print_with_repetitions(glusterfs_ctx_t *ctx, const char *domain,
+ const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum,
+ uint64_t msgid, char **appmsgstr, char *callstr,
+ int refcount, struct timeval oldest,
+ struct timeval latest, int graph_id)
{
- int ret = -1;
- gf_log_logger_t logger = 0;
-
- logger = ctx->log.logger;
-
-
- switch (logger) {
- case gf_logger_syslog:
- if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
- ret = gf_syslog_log_repetitions (domain, file, function,
- line, level, errnum,
- msgid, appmsgstr,
- callstr, refcount,
- oldest, latest,
- graph_id);
- break;
- }
- case gf_logger_glusterlog:
- ret = gf_glusterlog_log_repetitions (ctx, domain, file,
- function, line, level,
- errnum, msgid, appmsgstr,
- callstr, refcount, oldest,
- latest, graph_id);
+ int ret = -1;
+ gf_log_logger_t logger = ctx->log.logger;
+
+ switch (logger) {
+ case gf_logger_syslog:
+ if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
+ ret = gf_syslog_log_repetitions(
+ domain, file, function, line, level, errnum, msgid,
+ appmsgstr, callstr, refcount, oldest, latest, graph_id);
break;
- }
+ }
+ /* NOTE: If syslog control file is absent, which is another
+ * way to control logging to syslog, then we will fall through
+ * to the gluster log. The ideal way to do things would be to
+ * not have the extra control file check */
- return ret;
+ case gf_logger_glusterlog:
+ ret = gf_glusterlog_log_repetitions(
+ ctx, domain, file, function, line, level, errnum, msgid,
+ appmsgstr, callstr, refcount, oldest, latest, graph_id);
+ break;
+ }
+
+ return ret;
}
static int
-gf_log_print_plain_fmt (glusterfs_ctx_t *ctx, const char *domain,
- const char *file, const char *function, int32_t line,
- gf_loglevel_t level, int errnum, uint64_t msgid,
- char **appmsgstr, char *callstr, struct timeval tv,
- int graph_id, gf_log_format_t fmt)
+gf_log_print_plain_fmt(glusterfs_ctx_t *ctx, const char *domain,
+ const char *file, const char *function, int32_t line,
+ gf_loglevel_t level, int errnum, uint64_t msgid,
+ char **appmsgstr, char *callstr, struct timeval tv,
+ int graph_id, gf_log_format_t fmt)
{
- int ret = -1;
- gf_log_logger_t logger = 0;
+ int ret = -1;
+ gf_log_logger_t logger = 0;
- logger = ctx->log.logger;
+ logger = ctx->log.logger;
- /* log to the configured logging service */
- switch (logger) {
+ /* log to the configured logging service */
+ switch (logger) {
case gf_logger_syslog:
- if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
- ret = gf_log_syslog (ctx, domain, file, function, line,
- level, errnum, msgid, appmsgstr,
- callstr, graph_id, fmt);
- break;
- }
- /* NOTE: If syslog control file is absent, which is another
- * way to control logging to syslog, then we will fall through
- * to the gluster log. The ideal way to do things would be to
- * not have the extra control file check */
- case gf_logger_glusterlog:
- ret = gf_log_glusterlog (ctx, domain, file, function, line,
- level, errnum, msgid, appmsgstr,
- callstr, tv, graph_id, fmt);
+ if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
+ ret = gf_log_syslog(ctx, domain, file, function, line, level,
+ errnum, msgid, appmsgstr, callstr, graph_id,
+ fmt);
break;
- }
+ }
+ /* NOTE: If syslog control file is absent, which is another
+ * way to control logging to syslog, then we will fall through
+ * to the gluster log. The ideal way to do things would be to
+ * not have the extra control file check */
+ case gf_logger_glusterlog:
+ ret = gf_log_glusterlog(ctx, domain, file, function, line, level,
+ errnum, msgid, appmsgstr, callstr, tv,
+ graph_id, fmt);
+ break;
+ }
- return ret;
+ return ret;
}
void
-gf_log_flush_message (log_buf_t *buf, glusterfs_ctx_t *ctx)
+gf_log_flush_message(log_buf_t *buf, glusterfs_ctx_t *ctx)
{
- if (buf->refcount == 1) {
- (void) gf_log_print_plain_fmt (ctx, buf->domain, buf->file,
- buf->function, buf->line,
- buf->level, buf->errnum,
- buf->msg_id, &buf->msg, NULL,
- buf->latest, buf->graph_id,
- gf_logformat_withmsgid);
- }
-
- if (buf->refcount > 1) {
- gf_log_print_with_repetitions (ctx, buf->domain, buf->file,
- buf->function, buf->line,
- buf->level, buf->errnum,
- buf->msg_id, &buf->msg, NULL,
- buf->refcount, buf->oldest,
- buf->latest, buf->graph_id);
- }
- return;
+ if (buf->refcount == 1) {
+ (void)gf_log_print_plain_fmt(ctx, buf->domain, buf->file, buf->function,
+ buf->line, buf->level, buf->errnum,
+ buf->msg_id, &buf->msg, NULL, buf->latest,
+ buf->graph_id, gf_logformat_withmsgid);
+ }
+
+ if (buf->refcount > 1) {
+ gf_log_print_with_repetitions(
+ ctx, buf->domain, buf->file, buf->function, buf->line, buf->level,
+ buf->errnum, buf->msg_id, &buf->msg, NULL, buf->refcount,
+ buf->oldest, buf->latest, buf->graph_id);
+ }
+ return;
}
static void
-gf_log_flush_list (struct list_head *copy, glusterfs_ctx_t *ctx)
+gf_log_flush_list(struct list_head *copy, glusterfs_ctx_t *ctx)
{
- log_buf_t *iter = NULL;
- log_buf_t *tmp = NULL;
-
- list_for_each_entry_safe (iter, tmp, copy, msg_list) {
- gf_log_flush_message (iter, ctx);
- list_del_init (&iter->msg_list);
- log_buf_destroy (iter);
- }
+ log_buf_t *iter = NULL;
+ log_buf_t *tmp = NULL;
+
+ list_for_each_entry_safe(iter, tmp, copy, msg_list)
+ {
+ gf_log_flush_message(iter, ctx);
+ list_del_init(&iter->msg_list);
+ log_buf_destroy(iter);
+ }
}
void
-gf_log_flush_msgs (glusterfs_ctx_t *ctx)
+gf_log_flush_msgs(glusterfs_ctx_t *ctx)
{
- struct list_head copy;
+ struct list_head copy;
- INIT_LIST_HEAD (&copy);
+ INIT_LIST_HEAD(&copy);
- pthread_mutex_lock (&ctx->log.log_buf_lock);
- {
- list_splice_init (&ctx->log.lru_queue, &copy);
- ctx->log.lru_cur_size = 0;
- }
- pthread_mutex_unlock (&ctx->log.log_buf_lock);
+ pthread_mutex_lock(&ctx->log.log_buf_lock);
+ {
+ list_splice_init(&ctx->log.lru_queue, &copy);
+ ctx->log.lru_cur_size = 0;
+ }
+ pthread_mutex_unlock(&ctx->log.log_buf_lock);
- gf_log_flush_list (&copy, ctx);
+ gf_log_flush_list(&copy, ctx);
- return;
+ return;
}
static void
-gf_log_flush_extra_msgs (glusterfs_ctx_t *ctx, uint32_t new)
+gf_log_flush_extra_msgs(glusterfs_ctx_t *ctx, uint32_t new)
{
- int count = 0;
- int i = 0;
- log_buf_t *iter = NULL;
- log_buf_t *tmp = NULL;
- struct list_head copy;
-
- INIT_LIST_HEAD (&copy);
-
- /* If the number of outstanding log messages does not cause list
- * overflow even after reducing the size of the list, then do nothing.
- * Otherwise (that is if there are more items in the list than there
- * need to be after reducing its size), move the least recently used
- * 'diff' elements to be flushed into a separate list...
- */
-
- pthread_mutex_lock (&ctx->log.log_buf_lock);
+ int count = 0;
+ int i = 0;
+ log_buf_t *iter = NULL;
+ log_buf_t *tmp = NULL;
+ struct list_head copy;
+
+ INIT_LIST_HEAD(&copy);
+
+ /* If the number of outstanding log messages does not cause list
+ * overflow even after reducing the size of the list, then do nothing.
+ * Otherwise (that is if there are more items in the list than there
+ * need to be after reducing its size), move the least recently used
+ * 'diff' elements to be flushed into a separate list...
+ */
+
+ pthread_mutex_lock(&ctx->log.log_buf_lock);
+ {
+ if (ctx->log.lru_cur_size <= new)
+ goto unlock;
+ count = ctx->log.lru_cur_size - new;
+ list_for_each_entry_safe(iter, tmp, &ctx->log.lru_queue, msg_list)
{
- if (ctx->log.lru_cur_size <= new)
- goto unlock;
- count = ctx->log.lru_cur_size - new;
- list_for_each_entry_safe (iter, tmp, &ctx->log.lru_queue,
- msg_list) {
- if (i == count)
- break;
-
- list_del_init (&iter->msg_list);
- list_add_tail (&iter->msg_list, &copy);
- i++;
- }
- ctx->log.lru_cur_size = ctx->log.lru_cur_size - count;
+ if (i == count)
+ break;
+
+ list_del_init(&iter->msg_list);
+ list_add_tail(&iter->msg_list, &copy);
+ i++;
}
- // ... quickly unlock ...
+ ctx->log.lru_cur_size = ctx->log.lru_cur_size - count;
+ }
+ // ... quickly unlock ...
unlock:
- pthread_mutex_unlock (&ctx->log.log_buf_lock);
- if (list_empty (&copy))
- return;
+ pthread_mutex_unlock(&ctx->log.log_buf_lock);
+ if (list_empty(&copy))
+ return;
- TEST_LOG("Log buffer size reduced. About to flush %d extra log "
- "messages", count);
- // ... and then flush them outside the lock.
- gf_log_flush_list (&copy, ctx);
- TEST_LOG("Just flushed %d extra log messages", count);
+ TEST_LOG(
+ "Log buffer size reduced. About to flush %d extra log "
+ "messages",
+ count);
+ // ... and then flush them outside the lock.
+ gf_log_flush_list(&copy, ctx);
+ TEST_LOG("Just flushed %d extra log messages", count);
- return;
+ return;
}
static int
-__gf_log_inject_timer_event (glusterfs_ctx_t *ctx)
+__gf_log_inject_timer_event(glusterfs_ctx_t *ctx)
{
- int ret = -1;
- struct timespec timeout = {0,};
+ int ret = -1;
+ struct timespec timeout = {
+ 0,
+ };
- if (!ctx)
- goto out;
+ if (!ctx)
+ goto out;
- if (ctx->log.log_flush_timer) {
- gf_timer_call_cancel (ctx, ctx->log.log_flush_timer);
- ctx->log.log_flush_timer = NULL;
- }
+ if (ctx->log.log_flush_timer) {
+ gf_timer_call_cancel(ctx, ctx->log.log_flush_timer);
+ ctx->log.log_flush_timer = NULL;
+ }
- timeout.tv_sec = ctx->log.timeout;
- timeout.tv_nsec = 0;
+ timeout.tv_sec = ctx->log.timeout;
+ timeout.tv_nsec = 0;
- TEST_LOG("Starting timer now. Timeout = %u, current buf size = %d",
- ctx->log.timeout, ctx->log.lru_size);
- ctx->log.log_flush_timer = gf_timer_call_after (ctx, timeout,
- gf_log_flush_timeout_cbk,
- (void *)ctx);
- if (!ctx->log.log_flush_timer)
- goto out;
+ TEST_LOG("Starting timer now. Timeout = %u, current buf size = %d",
+ ctx->log.timeout, ctx->log.lru_size);
+ ctx->log.log_flush_timer = gf_timer_call_after(
+ ctx, timeout, gf_log_flush_timeout_cbk, (void *)ctx);
+ if (!ctx->log.log_flush_timer)
+ goto out;
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
int
-gf_log_inject_timer_event (glusterfs_ctx_t *ctx)
+gf_log_inject_timer_event(glusterfs_ctx_t *ctx)
{
- int ret = -1;
+ int ret = -1;
- if (!ctx)
- return -1;
+ if (!ctx)
+ return -1;
- pthread_mutex_lock (&ctx->log.log_buf_lock);
- {
- ret = __gf_log_inject_timer_event (ctx);
- }
- pthread_mutex_unlock (&ctx->log.log_buf_lock);
+ pthread_mutex_lock(&ctx->log.log_buf_lock);
+ {
+ ret = __gf_log_inject_timer_event(ctx);
+ }
+ pthread_mutex_unlock(&ctx->log.log_buf_lock);
- return ret;
+ return ret;
}
void
-gf_log_flush_timeout_cbk (void *data)
+gf_log_flush_timeout_cbk(void *data)
{
- glusterfs_ctx_t *ctx = NULL;
+ glusterfs_ctx_t *ctx = NULL;
- ctx = (glusterfs_ctx_t *) data;
+ ctx = (glusterfs_ctx_t *)data;
- TEST_LOG("Log timer timed out. About to flush outstanding messages if "
- "present");
- gf_log_flush_msgs (ctx);
+ TEST_LOG(
+ "Log timer timed out. About to flush outstanding messages if "
+ "present");
+ gf_log_flush_msgs(ctx);
- (void) gf_log_inject_timer_event (ctx);
+ (void)gf_log_inject_timer_event(ctx);
- return;
+ return;
}
static int
-_gf_msg_internal (const char *domain, const char *file, const char *function,
- int32_t line, gf_loglevel_t level, int errnum, uint64_t msgid,
- char **appmsgstr, char *callstr, int graph_id)
+_gf_msg_internal(const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum, uint64_t msgid,
+ char **appmsgstr, char *callstr, int graph_id)
{
- int ret = -1;
- uint32_t size = 0;
- const char *basename = NULL;
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
- log_buf_t *iter = NULL;
- log_buf_t *buf_tmp = NULL;
- log_buf_t *buf_new = NULL;
- log_buf_t *first = NULL;
- struct timeval tv = {0,};
- gf_boolean_t found = _gf_false;
- gf_boolean_t flush_lru = _gf_false;
- gf_boolean_t flush_logged_msg = _gf_false;
-
- this = THIS;
- ctx = this->ctx;
-
- if (!ctx)
- goto out;
+ int ret = -1;
+ uint32_t size = 0;
+ const char *basename = NULL;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ log_buf_t *iter = NULL;
+ log_buf_t *buf_tmp = NULL;
+ log_buf_t *buf_new = NULL;
+ log_buf_t *first = NULL;
+ struct timeval tv = {
+ 0,
+ };
+ gf_boolean_t found = _gf_false;
+ gf_boolean_t flush_lru = _gf_false;
+ gf_boolean_t flush_logged_msg = _gf_false;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ if (!ctx)
+ goto out;
+
+ GET_FILE_NAME_TO_LOG(file, basename);
+
+ ret = gettimeofday(&tv, NULL);
+ if (ret)
+ goto out;
+
+ /* If this function is called via _gf_msg_callingfn () (indicated by a
+ * non-NULL callstr), or if the logformat is traditional, flush the
+ * message directly to disk.
+ */
+
+ if ((callstr) || (ctx->log.logformat == gf_logformat_traditional)) {
+ ret = gf_log_print_plain_fmt(ctx, domain, basename, function, line,
+ level, errnum, msgid, appmsgstr, callstr,
+ tv, graph_id, gf_logformat_traditional);
+ goto out;
+ }
+
+ pthread_mutex_lock(&ctx->log.log_buf_lock);
+ {
+ /* Check if the msg being logged is already part of the list */
+ list_for_each_entry_safe_reverse(iter, buf_tmp, &ctx->log.lru_queue,
+ msg_list)
+ {
+ if (first == NULL)
+ // Remember the first (lru) element in first ptr
+ first = iter;
- GET_FILE_NAME_TO_LOG (file, basename);
+ /* Try to fail the search early on by doing the less
+ * expensive integer comparisons and continue to string
+ * parameter comparisons only after all int parameters
+ * are found to be matching.
+ */
+ if (line != iter->line)
+ continue;
- ret = gettimeofday (&tv, NULL);
- if (ret)
- goto out;
+ if (errnum != iter->errnum)
+ continue;
- /* If this function is called via _gf_msg_callingfn () (indicated by a
- * non-NULL callstr), or if the logformat is traditional, flush the
- * message directly to disk.
- */
+ if (msgid != iter->msg_id)
+ continue;
- if ((callstr) || (ctx->log.logformat == gf_logformat_traditional)) {
- ret = gf_log_print_plain_fmt (ctx, domain, basename, function,
- line, level, errnum, msgid,
- appmsgstr, callstr, tv, graph_id,
- gf_logformat_traditional);
- goto out;
- }
+ if (level != iter->level)
+ continue;
- pthread_mutex_lock (&ctx->log.log_buf_lock);
- {
- /* Check if the msg being logged is already part of the list */
- list_for_each_entry_safe_reverse (iter, buf_tmp,
- &ctx->log.lru_queue,
- msg_list) {
- if (first == NULL)
- // Remember the first (lru) element in first ptr
- first = iter;
-
- /* Try to fail the search early on by doing the less
- * expensive integer comparisons and continue to string
- * parameter comparisons only after all int parameters
- * are found to be matching.
- */
- if (line != iter->line)
- continue;
-
- if (errnum != iter->errnum)
- continue;
-
- if (msgid != iter->msg_id)
- continue;
-
- if (level != iter->level)
- continue;
-
- if (graph_id != iter->graph_id)
- continue;
-
- if (strcmp (domain, iter->domain))
- continue;
-
- if (strcmp (basename, iter->file))
- continue;
-
- if (strcmp (function, iter->function))
- continue;
-
- if (strcmp (*appmsgstr, iter->msg))
- continue;
-
- //Ah! Found a match!
- list_move_tail (&iter->msg_list, &ctx->log.lru_queue);
- iter->refcount++;
- found = _gf_true;
- //Update the 'latest' timestamp.
- memcpy ((void *)&(iter->latest), (void *)&tv,
- sizeof (struct timeval));
- break;
- }
- if (found) {
- ret = 0;
- goto unlock;
- }
- // else ...
-
- size = ctx->log.lru_size;
- /* If the upper limit on the log buf size is 0, flush the msg to
- * disk directly after unlock. There's no need to buffer the
- * msg here.
- */
- if (size == 0) {
- flush_logged_msg = _gf_true;
- goto unlock;
- } else if ((ctx->log.lru_cur_size + 1) > size) {
- /* If the list is full, flush the lru msg to disk and also
- * release it after unlock, and ...
- * */
- if (first->refcount >= 1)
- TEST_LOG("Buffer overflow of a buffer whose size limit "
- "is %d. About to flush least recently used log"
- " message to disk", size);
- list_del_init (&first->msg_list);
- ctx->log.lru_cur_size--;
- flush_lru = _gf_true;
- }
- /* create a new list element, initialise and enqueue it.
- * Additionally, this being the first occurrence of the msg,
- * log it directly to disk after unlock. */
- buf_new = log_buf_new ();
- if (!buf_new) {
- ret = -1;
- goto unlock;
- }
- ret = log_buf_init (buf_new, domain, basename, function, line,
- level, errnum, msgid, appmsgstr, graph_id);
- if (ret) {
- log_buf_destroy (buf_new);
- goto unlock;
- }
+ if (graph_id != iter->graph_id)
+ continue;
- memcpy ((void *)&(buf_new->latest), (void *)&tv,
- sizeof (struct timeval));
- memcpy ((void *)&(buf_new->oldest), (void *)&tv,
- sizeof (struct timeval));
+ if (strcmp(domain, iter->domain))
+ continue;
- list_add_tail (&buf_new->msg_list, &ctx->log.lru_queue);
- ctx->log.lru_cur_size++;
- flush_logged_msg = _gf_true;
- ret = 0;
- }
-unlock:
- pthread_mutex_unlock (&ctx->log.log_buf_lock);
+ if (strcmp(basename, iter->file))
+ continue;
- /* Value of @ret is a don't-care below since irrespective of success or
- * failure post setting of @flush_lru, @first must be flushed and freed.
- */
- if (flush_lru) {
- gf_log_flush_message (first, ctx);
- log_buf_destroy (first);
+ if (strcmp(function, iter->function))
+ continue;
+
+ if (strcmp(*appmsgstr, iter->msg))
+ continue;
+
+ // Ah! Found a match!
+ list_move_tail(&iter->msg_list, &ctx->log.lru_queue);
+ iter->refcount++;
+ found = _gf_true;
+ // Update the 'latest' timestamp.
+ memcpy((void *)&(iter->latest), (void *)&tv,
+ sizeof(struct timeval));
+ break;
}
- /* Similarly, irrespective of whether all operations since setting of
- * @flush_logged_msg were successful or not, flush the message being
- * logged to disk in the plain format.
- */
- if (flush_logged_msg) {
- ret = gf_log_print_plain_fmt (ctx, domain, basename,
- function, line, level,
- errnum, msgid, appmsgstr,
- callstr, tv, graph_id,
- gf_logformat_withmsgid);
+ if (found) {
+ ret = 0;
+ goto unlock;
}
+ // else ...
+
+ size = ctx->log.lru_size;
+ /* If the upper limit on the log buf size is 0, flush the msg to
+ * disk directly after unlock. There's no need to buffer the
+ * msg here.
+ */
+ if (size == 0) {
+ flush_logged_msg = _gf_true;
+ goto unlock;
+ } else if (((ctx->log.lru_cur_size + 1) > size) && (first)) {
+ /* If the list is full, flush the lru msg to disk and also
+ * release it after unlock, and ...
+ * */
+ if (first->refcount >= 1)
+ TEST_LOG(
+ "Buffer overflow of a buffer whose size limit "
+ "is %d. About to flush least recently used log"
+ " message to disk",
+ size);
+ list_del_init(&first->msg_list);
+ ctx->log.lru_cur_size--;
+ flush_lru = _gf_true;
+ }
+ /* create a new list element, initialise and enqueue it.
+ * Additionally, this being the first occurrence of the msg,
+ * log it directly to disk after unlock. */
+ buf_new = mem_get0(THIS->ctx->logbuf_pool);
+ if (!buf_new) {
+ ret = -1;
+ goto unlock;
+ }
+ ret = log_buf_init(buf_new, domain, basename, function, line, level,
+ errnum, msgid, appmsgstr, graph_id);
+ if (ret) {
+ log_buf_destroy(buf_new);
+ goto unlock;
+ }
+
+ memcpy((void *)&(buf_new->latest), (void *)&tv, sizeof(struct timeval));
+ memcpy((void *)&(buf_new->oldest), (void *)&tv, sizeof(struct timeval));
+
+ list_add_tail(&buf_new->msg_list, &ctx->log.lru_queue);
+ ctx->log.lru_cur_size++;
+ flush_logged_msg = _gf_true;
+ ret = 0;
+ }
+unlock:
+ pthread_mutex_unlock(&ctx->log.log_buf_lock);
+
+ /* Value of @ret is a don't-care below since irrespective of success or
+ * failure post setting of @flush_lru, @first must be flushed and freed.
+ */
+ if (flush_lru) {
+ gf_log_flush_message(first, ctx);
+ log_buf_destroy(first);
+ }
+ /* Similarly, irrespective of whether all operations since setting of
+ * @flush_logged_msg were successful or not, flush the message being
+ * logged to disk in the plain format.
+ */
+ if (flush_logged_msg) {
+ ret = gf_log_print_plain_fmt(ctx, domain, basename, function, line,
+ level, errnum, msgid, appmsgstr, callstr,
+ tv, graph_id, gf_logformat_withmsgid);
+ }
out:
- return ret;
+ return ret;
}
int
-_gf_msg (const char *domain, const char *file, const char *function,
- int32_t line, gf_loglevel_t level, int errnum, int trace,
- uint64_t msgid, const char *fmt, ...)
+_gf_msg(const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum, int trace,
+ uint64_t msgid, const char *fmt, ...)
{
- int ret = 0;
- char *msgstr = NULL;
- va_list ap;
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
- char callstr[GF_LOG_BACKTRACE_SIZE] = {0,};
- int passcallstr = 0;
- int log_inited = 0;
-
- /* in args check */
- if (!domain || !file || !function || !fmt) {
- fprintf (stderr,
- "logging: %s:%s():%d: invalid argument\n",
- __FILE__, __PRETTY_FUNCTION__, __LINE__);
- return -1;
- }
-
- this = THIS;
-
- if (this == NULL)
- return -1;
-
- ctx = this->ctx;
- if (ctx == NULL) {
- /* messages before context initialization are ignored */
+ int ret = 0;
+ char *msgstr = NULL;
+ va_list ap;
+ xlator_t *this = THIS;
+ glusterfs_ctx_t *ctx = NULL;
+ char *callstr = NULL;
+ int log_inited = 0;
+
+ if (this == NULL)
+ return -1;
+
+ ctx = this->ctx;
+ if (ctx == NULL) {
+ /* messages before context initialization are ignored */
+ return -1;
+ }
+
+ /* check if we should be logging */
+ if (skip_logging(this, level))
+ goto out;
+
+ /* in args check */
+ if (!domain || !file || !function || !fmt) {
+ fprintf(stderr, "logging: %s:%s():%d: invalid argument\n", __FILE__,
+ __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ /* form the message */
+ va_start(ap, fmt);
+ ret = vasprintf(&msgstr, fmt, ap);
+ va_end(ap);
+
+ /* log */
+ if (ret != -1) {
+ if (trace) {
+ callstr = GF_MALLOC(GF_LOG_BACKTRACE_SIZE, gf_common_mt_char);
+ if (callstr == NULL)
return -1;
- }
- /* check if we should be logging */
- if (ctx->log.gf_log_xl_log_set) {
- if (this->loglevel && (level > this->loglevel))
- goto out;
+ ret = _gf_msg_backtrace(GF_LOG_BACKTRACE_DEPTH, callstr,
+ GF_LOG_BACKTRACE_SIZE);
+ if (ret < 0) {
+ GF_FREE(callstr);
+ callstr = NULL;
+ }
}
- if (level > ctx->log.loglevel || level == GF_LOG_NONE)
- goto out;
- if (trace) {
- ret = _gf_msg_backtrace (GF_LOG_BACKTRACE_DEPTH, callstr,
- GF_LOG_BACKTRACE_SIZE);
- if (ret >= 0)
- passcallstr = 1;
- else
- ret = 0;
- }
-
- pthread_mutex_lock (&ctx->log.logfile_mutex);
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
{
- if (ctx->log.logfile) {
- log_inited = 1;
- }
- }
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
-
- /* form the message */
- va_start (ap, fmt);
- ret = vasprintf (&msgstr, fmt, ap);
- va_end (ap);
-
- /* log */
- if (ret != -1) {
- if (!log_inited && ctx->log.gf_log_syslog) {
- ret = gf_log_syslog (ctx, domain, file, function, line,
- level, errnum, msgid, &msgstr,
- (passcallstr? callstr : NULL),
- (this->graph)? this->graph->id : 0,
- gf_logformat_traditional);
- } else {
- ret = _gf_msg_internal (domain, file, function, line,
- level, errnum, msgid, &msgstr,
- (passcallstr? callstr : NULL),
- (this->graph)? this->graph->id : 0);
- }
- } else {
- /* man (3) vasprintf states on error strp contents
- * are undefined, be safe */
- msgstr = NULL;
+ if (ctx->log.logfile) {
+ log_inited = 1;
+ }
}
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
- FREE (msgstr);
+ if (!log_inited && ctx->log.gf_log_syslog) {
+ ret = gf_log_syslog(
+ ctx, domain, file, function, line, level, errnum, msgid,
+ &msgstr, (callstr ? callstr : NULL),
+ (this->graph) ? this->graph->id : 0, gf_logformat_traditional);
+ } else {
+ ret = _gf_msg_internal(domain, file, function, line, level, errnum,
+ msgid, &msgstr, (callstr ? callstr : NULL),
+ (this->graph) ? this->graph->id : 0);
+ }
+ } else {
+ /* man (3) vasprintf states on error strp contents
+ * are undefined, be safe */
+ msgstr = NULL;
+ }
+ if (callstr)
+ GF_FREE(callstr);
+ FREE(msgstr);
out:
- return ret;
+ return ret;
}
/* TODO: Deprecate (delete) _gf_log, _gf_log_callingfn,
* once messages are changed to use _gf_msgXXX APIs for logging */
int
-_gf_log (const char *domain, const char *file, const char *function, int line,
- gf_loglevel_t level, const char *fmt, ...)
+_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;
- char timestr[GF_LOG_TIMESTR_SIZE] = {0,};
- struct timeval tv = {0,};
- char *str1 = NULL;
- char *str2 = NULL;
- char *msg = NULL;
- size_t len = 0;
- int ret = 0;
- int fd = -1;
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
-
- this = THIS;
- ctx = this->ctx;
-
- if (!ctx)
- goto out;
-
- if (ctx->log.gf_log_xl_log_set) {
- if (this->loglevel && (level > this->loglevel))
- goto out;
- }
- if (level > ctx->log.loglevel || level == GF_LOG_NONE)
- goto out;
-
- static char *level_strings[] = {"", /* NONE */
- "M", /* EMERGENCY */
- "A", /* ALERT */
- "C", /* CRITICAL */
- "E", /* ERROR */
- "W", /* WARNING */
- "N", /* NOTICE */
- "I", /* INFO */
- "D", /* DEBUG */
- "T", /* TRACE */
- ""};
-
- if (!domain || !file || !function || !fmt) {
- fprintf (stderr,
- "logging: %s:%s():%d: invalid argument\n",
- __FILE__, __PRETTY_FUNCTION__, __LINE__);
- return -1;
+ const char *basename = NULL;
+ FILE *new_logfile = NULL;
+ va_list ap;
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ struct timeval tv = {
+ 0,
+ };
+ char *logline = NULL;
+ char *msg = NULL;
+ int ret = 0;
+ int fd = -1;
+ xlator_t *this = THIS;
+ glusterfs_ctx_t *ctx = this->ctx;
+
+ if (!ctx)
+ goto out;
+
+ if (skip_logging(this, level))
+ goto out;
+
+ if (!domain || !file || !function || !fmt) {
+ fprintf(stderr, "logging: %s:%s():%d: invalid argument\n", __FILE__,
+ __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ basename = strrchr(file, '/');
+ if (basename)
+ basename++;
+ else
+ basename = file;
+
+ va_start(ap, fmt);
+ ret = vasprintf(&msg, fmt, ap);
+ va_end(ap);
+ if (-1 == ret) {
+ goto err;
+ }
+
+ if (ctx->log.log_control_file_found) {
+ int priority;
+ /* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
+ other level as is */
+ if (GF_LOG_TRACE == level || GF_LOG_NONE == level) {
+ priority = LOG_DEBUG;
+ } else {
+ priority = level - 1;
}
- basename = strrchr (file, '/');
- if (basename)
- basename++;
- else
- basename = file;
-
- if (ctx->log.log_control_file_found)
- {
- int priority;
- /* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
- other level as is */
- if (GF_LOG_TRACE == level || GF_LOG_NONE == level) {
- priority = LOG_DEBUG;
- } else {
- priority = level - 1;
- }
+ gf_syslog(priority, "[%s:%d:%s] %d-%s: %s", basename, line, function,
+ ((this->graph) ? this->graph->id : 0), domain, msg);
+ goto err;
+ }
- va_start (ap, fmt);
- vasprintf (&str2, fmt, ap);
- va_end (ap);
+ if (ctx->log.logrotate) {
+ ctx->log.logrotate = 0;
- gf_syslog (priority, "[%s:%d:%s] %d-%s: %s",
- basename, line, function,
- ((this->graph) ? this->graph->id:0), domain, str2);
- goto err;
+ fd = sys_open(ctx->log.filename, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ gf_smsg("logrotate", GF_LOG_ERROR, errno,
+ LG_MSG_OPEN_LOGFILE_FAILED, NULL);
+ return -1;
}
+ sys_close(fd);
- if (ctx->log.logrotate) {
- ctx->log.logrotate = 0;
-
- fd = open (ctx->log.filename,
- O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
- if (fd < 0) {
- gf_msg ("logrotate", GF_LOG_ERROR, errno,
- LG_MSG_FILE_OP_FAILED,
- "failed to open logfile");
- return -1;
- }
- close (fd);
-
- new_logfile = fopen (ctx->log.filename, "a");
- if (!new_logfile) {
- gf_msg ("logrotate", GF_LOG_CRITICAL, errno,
- LG_MSG_FILE_OP_FAILED,
- "failed to open logfile %s",
- ctx->log.filename);
- goto log;
- }
-
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
- if (ctx->log.logfile)
- fclose (ctx->log.logfile);
+ new_logfile = fopen(ctx->log.filename, "a");
+ if (!new_logfile) {
+ gf_smsg("logrotate", GF_LOG_CRITICAL, errno,
+ LG_MSG_OPEN_LOGFILE_FAILED, "filename=%s",
+ ctx->log.filename, NULL);
+ goto log;
+ }
- ctx->log.gf_log_logfile =
- ctx->log.logfile = new_logfile;
- }
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile)
+ fclose(ctx->log.logfile);
+ ctx->log.gf_log_logfile = ctx->log.logfile = new_logfile;
}
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
+ }
log:
- ret = gettimeofday (&tv, NULL);
- if (-1 == ret)
- goto out;
- va_start (ap, fmt);
- 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);
-
- ret = gf_asprintf (&str1, "[%s] %s [%s:%d:%s] %d-%s: ",
- timestr, level_strings[level],
- basename, line, function,
- ((this->graph)?this->graph->id:0), domain);
- if (-1 == ret) {
- goto err;
- }
+ ret = gettimeofday(&tv, NULL);
+ if (-1 == ret)
+ goto out;
- ret = vasprintf (&str2, fmt, ap);
- if (-1 == ret) {
- goto err;
- }
+ gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT);
- va_end (ap);
+ ret = gf_asprintf(&logline, "[%s] %c [%s:%d:%s] %d-%s: %s\n", timestr,
+ gf_level_strings[level], basename, line, function,
+ ((this->graph) ? this->graph->id : 0), domain, msg);
+ if (-1 == ret) {
+ goto err;
+ }
- len = strlen (str1);
- msg = GF_MALLOC (len + strlen (str2) + 1, gf_common_mt_char);
- if (!msg) {
- goto err;
+ pthread_mutex_lock(&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ fputs(logline, ctx->log.logfile);
+ fflush(ctx->log.logfile);
+ } else if (ctx->log.loglevel >= level) {
+ fputs(logline, stderr);
+ fflush(stderr);
}
- strcpy (msg, str1);
- strcpy (msg + len, str2);
-
- pthread_mutex_lock (&ctx->log.logfile_mutex);
- {
-
- if (ctx->log.logfile) {
- fprintf (ctx->log.logfile, "%s\n", msg);
- fflush (ctx->log.logfile);
- } else if (ctx->log.loglevel >= level) {
- fprintf (stderr, "%s\n", msg);
- fflush (stderr);
- }
-
#ifdef GF_LINUX_HOST_OS
- /* We want only serious log in 'syslog', not our debug
- and trace logs */
- if (ctx->log.gf_log_syslog && level &&
- (level <= ctx->log.sys_log_level))
- syslog ((level-1), "%s\n", msg);
+ /* We want only serious log in 'syslog', not our debug
+ and trace logs */
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
+ syslog((level - 1), "%s", logline);
#endif
- }
+ }
- pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ pthread_mutex_unlock(&ctx->log.logfile_mutex);
err:
- GF_FREE (msg);
-
- GF_FREE (str1);
+ GF_FREE(logline);
- FREE (str2);
+ FREE(msg);
out:
- return (0);
+ return (0);
}
int
-_gf_log_eh (const char *function, const char *fmt, ...)
+_gf_log_eh(const char *function, const char *fmt, ...)
{
- int ret = -1;
- va_list ap;
- char *str1 = NULL;
- char *str2 = NULL;
- char *msg = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- ret = gf_asprintf (&str1, "[%d] %s: ",
- ((this->graph)?this->graph->id:0),
- function);
- if (-1 == ret) {
- goto out;
- }
+ int ret = -1;
+ va_list ap;
+ char *logline = NULL;
+ char *msg = NULL;
+ xlator_t *this = NULL;
- va_start (ap, fmt);
+ this = THIS;
- ret = vasprintf (&str2, fmt, ap);
- if (-1 == ret) {
- goto out;
- }
-
- va_end (ap);
-
- msg = GF_MALLOC (strlen (str1) + strlen (str2) + 1, gf_common_mt_char);
- if (!msg) {
- ret = -1;
- goto out;
- }
+ va_start(ap, fmt);
+ ret = vasprintf(&msg, fmt, ap);
+ va_end(ap);
+ if (-1 == ret) {
+ goto out;
+ }
- strcpy (msg, str1);
- strcat (msg, str2);
+ ret = gf_asprintf(&logline, "[%d] %s: %s",
+ ((this->graph) ? this->graph->id : 0), function, msg);
+ if (-1 == ret) {
+ goto out;
+ }
- ret = eh_save_history (this->history, msg);
+ ret = eh_save_history(this->history, logline);
out:
- GF_FREE (str1);
+ GF_FREE(logline);
- /* Use FREE instead of GF_FREE since str2 was allocated by vasprintf */
- if (str2)
- FREE (str2);
+ FREE(msg);
- return ret;
+ return ret;
}
int
-gf_cmd_log_init (const char *filename)
+gf_cmd_log_init(const char *filename)
{
- int fd = -1;
- xlator_t *this = NULL;
- glusterfs_ctx_t *ctx = NULL;
-
- this = THIS;
- ctx = this->ctx;
-
- if (!ctx)
- return -1;
+ int fd = -1;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ if (!ctx)
+ return -1;
+
+ if (!filename) {
+ gf_smsg(this->name, GF_LOG_CRITICAL, 0, LG_MSG_FILENAME_NOT_SPECIFIED,
+ "gf_cmd_log_init", NULL);
+ return -1;
+ }
+
+ ctx->log.cmd_log_filename = gf_strdup(filename);
+ if (!ctx->log.cmd_log_filename) {
+ return -1;
+ }
+ /* close and reopen cmdlogfile for log rotate*/
+ if (ctx->log.cmdlogfile) {
+ fclose(ctx->log.cmdlogfile);
+ ctx->log.cmdlogfile = NULL;
+ }
+
+ fd = sys_open(ctx->log.cmd_log_filename, O_CREAT | O_WRONLY | O_APPEND,
+ S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ gf_smsg(this->name, GF_LOG_CRITICAL, errno, LG_MSG_OPEN_LOGFILE_FAILED,
+ "cmd_log_file", NULL);
+ return -1;
+ }
+
+ ctx->log.cmdlogfile = fdopen(fd, "a");
+ if (!ctx->log.cmdlogfile) {
+ gf_smsg(this->name, GF_LOG_CRITICAL, errno, LG_MSG_OPEN_LOGFILE_FAILED,
+ "gf_cmd_log_init: %s", ctx->log.cmd_log_filename, NULL);
+ sys_close(fd);
+ return -1;
+ }
+ return 0;
+}
- if (!filename){
- gf_msg (this->name, GF_LOG_CRITICAL, 0, LG_MSG_INVALID_ENTRY,
- "gf_cmd_log_init: no filename specified\n");
- return -1;
- }
+int
+gf_cmd_log(const char *domain, const char *fmt, ...)
+{
+ va_list ap;
+ char timestr[GF_TIMESTR_SIZE];
+ struct timeval tv = {
+ 0,
+ };
+ char *logline = NULL;
+ char *msg = NULL;
+ int ret = 0;
+ int fd = -1;
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (!ctx)
+ return -1;
+
+ if (!ctx->log.cmdlogfile)
+ return -1;
+
+ if (!domain || !fmt) {
+ gf_msg_trace("glusterd", 0, "logging: invalid argument\n");
+ return -1;
+ }
+
+ ret = gettimeofday(&tv, NULL);
+ if (ret == -1)
+ goto out;
+ va_start(ap, fmt);
+ ret = vasprintf(&msg, fmt, ap);
+ va_end(ap);
+ if (ret == -1) {
+ goto out;
+ }
+
+ gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT);
+
+ ret = gf_asprintf(&logline, "[%s] %s : %s\n", timestr, domain, msg);
+ if (ret == -1) {
+ goto out;
+ }
+
+ /* close and reopen cmdlogfile fd for in case of log rotate*/
+ if (ctx->log.cmd_history_logrotate) {
+ ctx->log.cmd_history_logrotate = 0;
- ctx->log.cmd_log_filename = gf_strdup (filename);
- if (!ctx->log.cmd_log_filename) {
- return -1;
- }
- /* close and reopen cmdlogfile for log rotate*/
if (ctx->log.cmdlogfile) {
- fclose (ctx->log.cmdlogfile);
- ctx->log.cmdlogfile = NULL;
+ fclose(ctx->log.cmdlogfile);
+ ctx->log.cmdlogfile = NULL;
}
- fd = open (ctx->log.cmd_log_filename,
- O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ fd = sys_open(ctx->log.cmd_log_filename, O_CREAT | O_WRONLY | O_APPEND,
+ S_IRUSR | S_IWUSR);
if (fd < 0) {
- gf_msg (this->name, GF_LOG_CRITICAL, errno,
- LG_MSG_FILE_OP_FAILED, "failed to open cmd_log_file");
- return -1;
+ gf_smsg(THIS->name, GF_LOG_CRITICAL, errno,
+ LG_MSG_OPEN_LOGFILE_FAILED, "name=%s",
+ ctx->log.cmd_log_filename, NULL);
+ ret = -1;
+ goto out;
}
- close (fd);
-
- ctx->log.cmdlogfile = fopen (ctx->log.cmd_log_filename, "a");
- if (!ctx->log.cmdlogfile){
- gf_msg (this->name, GF_LOG_CRITICAL, errno,
- LG_MSG_FILE_OP_FAILED,
- "gf_cmd_log_init: failed to open logfile \"%s\" "
- "\n", ctx->log.cmd_log_filename);
- return -1;
+
+ ctx->log.cmdlogfile = fdopen(fd, "a");
+ if (!ctx->log.cmdlogfile) {
+ gf_smsg(THIS->name, GF_LOG_CRITICAL, errno,
+ LG_MSG_OPEN_LOGFILE_FAILED, "name=%s",
+ ctx->log.cmd_log_filename, NULL);
+ ret = -1;
+ sys_close(fd);
+ goto out;
}
- return 0;
-}
+ }
-int
-gf_cmd_log (const char *domain, const char *fmt, ...)
-{
- 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;
- glusterfs_ctx_t *ctx = NULL;
-
- ctx = THIS->ctx;
-
- if (!ctx)
- return -1;
+ fputs(logline, ctx->log.cmdlogfile);
+ fflush(ctx->log.cmdlogfile);
- if (!ctx->log.cmdlogfile)
- return -1;
+out:
+ GF_FREE(logline);
+ FREE(msg);
- if (!domain || !fmt) {
- gf_msg_trace ("glusterd", 0,
- "logging: invalid argument\n");
- return -1;
- }
+ return ret;
+}
- ret = gettimeofday (&tv, NULL);
- if (ret == -1)
+static int
+_do_slog_format(int errnum, const char *event, va_list inp, char **msg)
+{
+ va_list valist_tmp;
+ int i = 0;
+ int j = 0;
+ int k = 0;
+ int ret = 0;
+ char *fmt = NULL;
+ char *buffer = NULL;
+ int num_format_chars = 0;
+ char format_char = '%';
+ char *tmp1 = NULL;
+ char *tmp2 = NULL;
+ char temp_sep[3] = "";
+
+ tmp2 = gf_strdup("");
+ if (!tmp2) {
+ ret = -1;
+ goto out;
+ }
+
+ /* Hardcoded value for max key value pairs, exits early */
+ /* from loop if found NULL */
+ for (i = 0; i < GF_MAX_SLOG_PAIR_COUNT; i++) {
+ fmt = va_arg(inp, char *);
+ if (fmt == NULL) {
+ break;
+ }
+
+ /* Get number of times % is used in input for formatting, */
+ /* this count will be used to skip those many args from the */
+ /* main list and will be used to format inner format */
+ num_format_chars = 0;
+ for (k = 0; fmt[k] != '\0'; k++) {
+ /* If %% is used then that is escaped */
+ if (fmt[k] == format_char && fmt[k + 1] == format_char) {
+ k++;
+ } else if (fmt[k] == format_char) {
+ num_format_chars++;
+ }
+ }
+
+ tmp1 = gf_strdup(tmp2);
+ if (!tmp1) {
+ ret = -1;
+ goto out;
+ }
+
+ GF_FREE(tmp2);
+ tmp2 = NULL;
+
+ if (num_format_chars > 0) {
+ /* Make separate valist and format the string */
+ va_copy(valist_tmp, inp);
+ ret = gf_vasprintf(&buffer, fmt, valist_tmp);
+ if (ret < 0) {
+ va_end(valist_tmp);
goto out;
- va_start (ap, fmt);
- gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
- snprintf (timestr + strlen (timestr),
- GF_LOG_TIMESTR_SIZE - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, tv.tv_usec);
-
- ret = gf_asprintf (&str1, "[%s] %s : ",
- timestr, domain);
- if (ret == -1) {
+ }
+ va_end(valist_tmp);
+
+ for (j = 0; j < num_format_chars; j++) {
+ /* Skip the va_arg value since these values
+ are already used for internal formatting */
+ (void)va_arg(inp, void *);
+ }
+
+ ret = gf_asprintf(&tmp2, "%s%s{%s}", tmp1, temp_sep, buffer);
+ if (ret < 0)
goto out;
- }
- ret = vasprintf (&str2, fmt, ap);
- if (ret == -1) {
+ GF_FREE(buffer);
+ buffer = NULL;
+ } else {
+ ret = gf_asprintf(&tmp2, "%s%s{%s}", tmp1, temp_sep, fmt);
+ if (ret < 0)
goto out;
}
- va_end (ap);
+ /* Set seperator for next iteration */
+ temp_sep[0] = ',';
+ temp_sep[1] = ' ';
+ temp_sep[2] = 0;
- len = strlen (str1);
- msg = GF_MALLOC (len + strlen (str2) + 1, gf_common_mt_char);
- if (!msg) {
- goto out;
- }
+ GF_FREE(tmp1);
+ tmp1 = NULL;
+ }
+
+ tmp1 = gf_strdup(tmp2);
+ if (!tmp1) {
+ ret = -1;
+ goto out;
+ }
+ GF_FREE(tmp2);
+ tmp2 = NULL;
+
+ if (errnum) {
+ ret = gf_asprintf(&tmp2, "%s [%s%s{errno=%d}, {error=%s}]", event, tmp1,
+ temp_sep, errnum, strerror(errnum));
+ } else {
+ ret = gf_asprintf(&tmp2, "%s [%s]", event, tmp1);
+ }
- strcpy (msg, str1);
- strcpy (msg + len, str2);
+ if (ret == -1)
+ goto out;
- fprintf (ctx->log.cmdlogfile, "%s\n", msg);
- fflush (ctx->log.cmdlogfile);
+ *msg = gf_strdup(tmp2);
+ if (!*msg)
+ ret = -1;
out:
- GF_FREE (msg);
+ if (buffer)
+ GF_FREE(buffer);
- GF_FREE (str1);
+ if (tmp1)
+ GF_FREE(tmp1);
- FREE (str2);
+ if (tmp2)
+ GF_FREE(tmp2);
- return (0);
+ return ret;
+}
+
+int
+_gf_smsg(const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum, int trace,
+ uint64_t msgid, const char *event, ...)
+{
+ va_list valist;
+ char *msg = NULL;
+ int ret = 0;
+ xlator_t *this = THIS;
+
+ if (skip_logging(this, level))
+ return ret;
+
+ va_start(valist, event);
+ ret = _do_slog_format(errnum, event, valist, &msg);
+ if (ret == -1)
+ goto out;
+
+ /* Pass errnum as zero since it is already formated as required */
+ ret = _gf_msg(domain, file, function, line, level, 0, trace, msgid, "%s",
+ msg);
+
+out:
+ va_end(valist);
+ if (msg)
+ GF_FREE(msg);
+ return ret;
}
diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h
deleted file mode 100644
index 515b4372e8a..00000000000
--- a/libglusterfs/src/logging.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- 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__
-#define __LOGGING_H__
-
-#include <sys/time.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <pthread.h>
-#include "list.h"
-
-#ifdef GF_DARWIN_HOST_OS
-#define GF_PRI_FSBLK "u"
-#define GF_PRI_DEV PRId32
-#define GF_PRI_INODE PRIu64
-#define GF_PRI_NLINK PRIu32
-#define GF_PRI_SECOND "ld"
-#define GF_PRI_SUSECONDS "06d"
-#define GF_PRI_USEC "d"
-#else
-#define GF_PRI_FSBLK PRIu64
-#define GF_PRI_DEV PRIu64
-#define GF_PRI_INODE PRIu64
-#define GF_PRI_NLINK PRIu32
-#define GF_PRI_SECOND "lu"
-#define GF_PRI_SUSECONDS "06ld"
-#define GF_PRI_USEC "ld"
-#endif
-#define GF_PRI_BLKSIZE PRId32
-#define GF_PRI_SIZET "zu"
-
-#ifdef GF_DARWIN_HOST_OS
-#define GF_PRI_TIME "ld"
-#else
-#define GF_PRI_TIME PRIu64
-#endif
-
-#if 0
-/* Syslog definitions :-) */
-#define LOG_EMERG 0 /* system is unusable */
-#define LOG_ALERT 1 /* action must be taken immediately */
-#define LOG_CRIT 2 /* critical conditions */
-#define LOG_ERR 3 /* error conditions */
-#define LOG_WARNING 4 /* warning conditions */
-#define LOG_NOTICE 5 /* normal but significant condition */
-#define LOG_INFO 6 /* informational */
-#define LOG_DEBUG 7 /* debug-level messages */
-#endif
-
-#define GF_LOG_FORMAT_NO_MSG_ID "no-msg-id"
-#define GF_LOG_FORMAT_WITH_MSG_ID "with-msg-id"
-
-#define GF_LOGGER_GLUSTER_LOG "gluster-log"
-#define GF_LOGGER_SYSLOG "syslog"
-
-typedef enum {
- GF_LOG_NONE,
- GF_LOG_EMERG,
- GF_LOG_ALERT,
- GF_LOG_CRITICAL, /* fatal errors */
- GF_LOG_ERROR, /* major failures (not necessarily fatal) */
- GF_LOG_WARNING, /* info about normal operation */
- GF_LOG_NOTICE,
- GF_LOG_INFO, /* Normal information */
- GF_LOG_DEBUG, /* internal errors */
- GF_LOG_TRACE, /* full trace of operation */
-} gf_loglevel_t;
-
-/* format for the logs */
-typedef enum {
- gf_logformat_traditional = 0, /* Format as in gluster 3.5 */
- gf_logformat_withmsgid, /* Format enhanced with MsgID, ident, errstr */
- gf_logformat_cee /* log enhanced format in cee */
-} gf_log_format_t;
-
-/* log infrastructure to log to */
-typedef enum {
- gf_logger_glusterlog = 0, /* locations and files as in gluster 3.5 */
- gf_logger_syslog /* log to (r)syslog, based on (r)syslog conf */
- /* NOTE: In the future journald, lumberjack, next new thing here */
-} gf_log_logger_t;
-
-#define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
-#define DEFAULT_LOG_LEVEL GF_LOG_INFO
-
-typedef struct gf_log_handle_ {
- pthread_mutex_t logfile_mutex;
- uint8_t logrotate;
- gf_loglevel_t loglevel;
- int gf_log_syslog;
- gf_loglevel_t sys_log_level;
- char gf_log_xl_log_set;
- char *filename;
- FILE *logfile;
- FILE *gf_log_logfile;
- char *cmd_log_filename;
- FILE *cmdlogfile;
- gf_log_logger_t logger;
- gf_log_format_t logformat;
- char *ident;
- int log_control_file_found;
- struct list_head lru_queue;
- uint32_t lru_size;
- uint32_t lru_cur_size;
- uint32_t timeout;
- pthread_mutex_t log_buf_lock;
- struct _gf_timer *log_flush_timer;
-} gf_log_handle_t;
-
-
-typedef struct log_buf_ {
- char *msg;
- uint64_t msg_id;
- int errnum;
- struct timeval oldest;
- struct timeval latest;
- char *domain;
- char *file;
- char *function;
- int32_t line;
- gf_loglevel_t level;
- int refcount;
- int graph_id;
- struct list_head msg_list;
-} log_buf_t;
-
-void gf_log_globals_init (void *ctx);
-int gf_log_init (void *data, const char *filename, const char *ident);
-
-void gf_log_logrotate (int signum);
-
-void gf_log_cleanup (void);
-
-/* Internal interfaces to log messages with message IDs */
-int _gf_msg (const char *domain, const char *file,
- const char *function, int32_t line, gf_loglevel_t level,
- int errnum, int trace, uint64_t msgid, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 9, 10)));
-
-void _gf_msg_backtrace_nomem (gf_loglevel_t level, int stacksize);
-
-int _gf_msg_plain (gf_loglevel_t level, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));
-
-int _gf_msg_plain_nomem (gf_loglevel_t level, const char *msg);
-
-int _gf_msg_vplain (gf_loglevel_t level, const char *fmt, va_list ap);
-
-int _gf_msg_nomem (const char *domain, const char *file,
- const char *function, int line, gf_loglevel_t level,
- size_t size);
-
-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_eh (const char *function, const char *fmt, ...);
-
-
-
-/* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
- * other level as is */
-#define SET_LOG_PRIO(level, priority) do { \
- if (GF_LOG_TRACE == (level) || GF_LOG_NONE == (level)) { \
- priority = LOG_DEBUG; \
- } else { \
- priority = (level) - 1; \
- } \
- } while (0)
-
-/* extract just the file name from the path */
-#define GET_FILE_NAME_TO_LOG(file, basename) do { \
- basename = strrchr ((file), '/'); \
- if (basename) \
- basename++; \
- else \
- basename = (file); \
- } while (0)
-
-#define PRINT_SIZE_CHECK(ret, label, strsize) do { \
- if (ret < 0) \
- goto label; \
- if ((strsize - ret) > 0) { \
- strsize -= ret; \
- } else { \
- ret = 0; \
- goto label; \
- } \
- } while (0)
-
-#define FMT_WARN(fmt...) do { if (0) printf (fmt); } while (0)
-
-/* Interface to log messages with message IDs */
-#define gf_msg(dom, levl, errnum, msgid, fmt...) do { \
- _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \
- levl, errnum, 0, msgid, ##fmt); \
- } while (0)
-
-/* no frills, no thrills, just a vanilla message, used to print the graph */
-#define gf_msg_plain(levl, fmt...) do { \
- _gf_msg_plain (levl, ##fmt); \
- } while (0)
-
-#define gf_msg_plain_nomem(levl, msg) do { \
- _gf_msg_plain_nomem (levl, msg); \
- } while (0)
-
-#define gf_msg_vplain(levl, fmt, va) do { \
- _gf_msg_vplain (levl, fmt, va); \
- } while (0)
-
-#define gf_msg_backtrace_nomem(level, stacksize) do { \
- _gf_msg_backtrace_nomem (level, stacksize); \
- } while (0)
-
-#define gf_msg_callingfn(dom, levl, errnum, msgid, fmt...) do { \
- _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \
- levl, errnum, 1, msgid, ##fmt); \
- } while (0)
-
-/* No malloc or calloc should be called in this function */
-#define gf_msg_nomem(dom, levl, size) do { \
- _gf_msg_nomem (dom, __FILE__, __FUNCTION__, __LINE__, \
- levl, size); \
- } while (0)
-
-/* Debug or trace messages do not need message IDs as these are more developer
- * related. Hence, the following abstractions are provided for the same */
-#define gf_msg_debug(dom, errnum, fmt...) do { \
- _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \
- GF_LOG_DEBUG, errnum, 0, 0, ##fmt); \
- } while (0)
-
-#define gf_msg_trace(dom, errnum, fmt...) do { \
- _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \
- GF_LOG_TRACE, errnum, 0, 0, ##fmt); \
- } while (0)
-
-#define gf_log(dom, levl, fmt...) do { \
- FMT_WARN (fmt); \
- _gf_log (dom, __FILE__, __FUNCTION__, __LINE__, \
- levl, ##fmt); \
- } while (0)
-
-#define gf_log_eh(fmt...) do { \
- FMT_WARN (fmt); \
- _gf_log_eh (__FUNCTION__, ##fmt); \
- } while (0)
-
-#define gf_log_callingfn(dom, levl, fmt...) do { \
- FMT_WARN (fmt); \
- _gf_log_callingfn (dom, __FILE__, __FUNCTION__, __LINE__, \
- levl, ##fmt); \
- } while (0)
-
-
-/* Log once in GF_UNIVERSAL_ANSWER times */
-#define GF_LOG_OCCASIONALLY(var, args...) if (!(var++%GF_UNIVERSAL_ANSWER)) { \
- gf_log (args); \
- }
-
-void gf_log_disable_syslog (void);
-void gf_log_enable_syslog (void);
-gf_loglevel_t gf_log_get_loglevel (void);
-void gf_log_set_loglevel (gf_loglevel_t level);
-void gf_log_flush (void);
-gf_loglevel_t gf_log_get_xl_loglevel (void *xl);
-void gf_log_set_xl_loglevel (void *xl, gf_loglevel_t level);
-
-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);
-
-int gf_log_fini(void *data);
-
-void
-gf_log_set_logger (gf_log_logger_t logger);
-
-void
-gf_log_set_logformat (gf_log_format_t format);
-
-void
-gf_log_set_log_buf_size (uint32_t buf_size);
-
-void
-gf_log_set_log_flush_timeout (uint32_t timeout);
-
-struct _glusterfs_ctx;
-
-void
-gf_log_flush_msgs (struct _glusterfs_ctx *ctx);
-
-int
-gf_log_inject_timer_event (struct _glusterfs_ctx *ctx);
-
-void
-gf_log_disable_suppression_before_exit (struct _glusterfs_ctx *ctx);
-
-#define GF_DEBUG(xl, format, args...) \
- gf_log ((xl)->name, GF_LOG_DEBUG, format, ##args)
-#define GF_INFO(xl, format, args...) \
- gf_log ((xl)->name, GF_LOG_INFO, format, ##args)
-#define GF_WARNING(xl, format, args...) \
- gf_log ((xl)->name, GF_LOG_WARNING, format, ##args)
-#define GF_ERROR(xl, format, args...) \
- gf_log ((xl)->name, GF_LOG_ERROR, format, ##args)
-
-#endif /* __LOGGING_H__ */
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index 1ed1aba6c2d..2d5a12b0a00 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -8,619 +8,925 @@
cases as published by the Free Software Foundation.
*/
-#include "mem-pool.h"
-#include "logging.h"
-#include "xlator.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/common-utils.h" // for GF_ASSERT, gf_thread_cr...
+#include "glusterfs/globals.h" // for xlator_t, THIS
#include <stdlib.h>
#include <stdarg.h>
-#define GF_MEM_POOL_LIST_BOUNDARY (sizeof(struct list_head))
-#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 GLUSTERFS_ENV_MEM_ACCT_STR "GLUSTERFS_DISABLE_MEM_ACCT"
-
#include "unittest/unittest.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/libglusterfs-messages.h"
void
-gf_mem_acct_enable_set (void *data)
+gf_mem_acct_enable_set(void *data)
{
- glusterfs_ctx_t *ctx = NULL;
+ glusterfs_ctx_t *ctx = NULL;
- REQUIRE(data != NULL);
+ REQUIRE(data != NULL);
- ctx = data;
+ ctx = data;
- GF_ASSERT (ctx != NULL);
+ GF_ASSERT(ctx != NULL);
- ctx->mem_acct_enable = 1;
+ ctx->mem_acct_enable = 1;
- ENSURE(1 == ctx->mem_acct_enable);
+ ENSURE(1 == ctx->mem_acct_enable);
- return;
+ return;
}
-int
-gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr, size_t size,
- uint32_t type, const char *typestr)
+static void *
+gf_mem_header_prepare(struct mem_header *header, size_t size)
{
+ void *ptr;
- void *ptr = NULL;
- struct mem_header *header = NULL;
+ header->size = size;
- if (!alloc_ptr)
- return -1;
+ ptr = header + 1;
- ptr = *alloc_ptr;
+ /* data follows in this gap of 'size' bytes */
+ *(uint32_t *)(ptr + size) = GF_MEM_TRAILER_MAGIC;
- GF_ASSERT (xl != NULL);
+ return ptr;
+}
- GF_ASSERT (xl->mem_acct != NULL);
+static void *
+gf_mem_set_acct_info(struct mem_acct *mem_acct, struct mem_header *header,
+ size_t size, uint32_t type, const char *typestr)
+{
+ struct mem_acct_rec *rec = NULL;
+ bool new_ref = false;
- GF_ASSERT (type <= xl->mem_acct->num_types);
+ if (mem_acct != NULL) {
+ GF_ASSERT(type <= mem_acct->num_types);
- LOCK(&xl->mem_acct->rec[type].lock);
+ rec = &mem_acct->rec[type];
+ LOCK(&rec->lock);
{
- if (!xl->mem_acct->rec[type].typestr)
- xl->mem_acct->rec[type].typestr = typestr;
- 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);
- xl->mem_acct->rec[type].max_num_allocs =
- max (xl->mem_acct->rec[type].max_num_allocs,
- xl->mem_acct->rec[type].num_allocs);
+ if (!rec->typestr) {
+ rec->typestr = typestr;
+ }
+ rec->size += size;
+ new_ref = (rec->num_allocs == 0);
+ rec->num_allocs++;
+ rec->total_allocs++;
+ rec->max_size = max(rec->max_size, rec->size);
+ rec->max_num_allocs = max(rec->max_num_allocs, rec->num_allocs);
+
+#ifdef DEBUG
+ list_add(&header->acct_list, &rec->obj_list);
+#endif
+ }
+ UNLOCK(&rec->lock);
+
+ /* We only take a reference for each memory type used, not for each
+ * allocation. This minimizes the use of atomic operations. */
+ if (new_ref) {
+ GF_ATOMIC_INC(mem_acct->refcnt);
}
- UNLOCK(&xl->mem_acct->rec[type].lock);
+ }
+
+ header->type = type;
+ header->mem_acct = mem_acct;
+ header->magic = GF_MEM_HEADER_MAGIC;
- INCREMENT_ATOMIC (xl->mem_acct->lock, xl->mem_acct->refcnt);
+ return gf_mem_header_prepare(header, size);
+}
- header = (struct mem_header *) ptr;
- header->type = type;
- header->size = size;
- header->mem_acct = xl->mem_acct;
- header->magic = GF_MEM_HEADER_MAGIC;
+static void *
+gf_mem_update_acct_info(struct mem_acct *mem_acct, struct mem_header *header,
+ size_t size)
+{
+ struct mem_acct_rec *rec = NULL;
- ptr += sizeof (struct mem_header);
+ if (mem_acct != NULL) {
+ rec = &mem_acct->rec[header->type];
+ LOCK(&rec->lock);
+ {
+ rec->size += size - header->size;
+ rec->total_allocs++;
+ rec->max_size = max(rec->max_size, rec->size);
- /* data follows in this gap of 'size' bytes */
- *(uint32_t *) (ptr + size) = GF_MEM_TRAILER_MAGIC;
+#ifdef DEBUG
+ /* The old 'header' already was present in 'obj_list', but
+ * realloc() could have changed its address. We need to remove
+ * the old item from the list and add the new one. This can be
+ * done this way because list_move() doesn't use the pointers
+ * to the old location (which are not valid anymore) already
+ * present in the list, it simply overwrites them. */
+ list_move(&header->acct_list, &rec->obj_list);
+#endif
+ }
+ UNLOCK(&rec->lock);
+ }
- *alloc_ptr = ptr;
- return 0;
+ return gf_mem_header_prepare(header, size);
}
+static bool
+gf_mem_acct_enabled(void)
+{
+ xlator_t *x = THIS;
+ /* Low-level __gf_xxx() may be called
+ before ctx is initialized. */
+ return x->ctx && x->ctx->mem_acct_enable;
+}
void *
-__gf_calloc (size_t nmemb, size_t size, uint32_t type, const char *typestr)
+__gf_calloc(size_t nmemb, size_t size, uint32_t type, const char *typestr)
{
- size_t tot_size = 0;
- size_t req_size = 0;
- char *ptr = NULL;
- xlator_t *xl = NULL;
+ size_t tot_size = 0;
+ size_t req_size = 0;
+ void *ptr = NULL;
+ xlator_t *xl = NULL;
- if (!THIS->ctx->mem_acct_enable)
- return CALLOC (nmemb, size);
+ if (!gf_mem_acct_enabled())
+ return CALLOC(nmemb, size);
- xl = THIS;
+ xl = THIS;
- req_size = nmemb * size;
- tot_size = req_size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
+ req_size = nmemb * size;
+ tot_size = req_size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
- ptr = calloc (1, tot_size);
+ ptr = calloc(1, tot_size);
- if (!ptr) {
- gf_msg_nomem ("", GF_LOG_ALERT, tot_size);
- return NULL;
- }
- gf_mem_set_acct_info (xl, &ptr, req_size, type, typestr);
+ if (!ptr) {
+ gf_msg_nomem("", GF_LOG_ALERT, tot_size);
+ return NULL;
+ }
- return (void *)ptr;
+ return gf_mem_set_acct_info(xl->mem_acct, ptr, req_size, type, typestr);
}
void *
-__gf_malloc (size_t size, uint32_t type, const char *typestr)
+__gf_malloc(size_t size, uint32_t type, const char *typestr)
{
- size_t tot_size = 0;
- char *ptr = NULL;
- xlator_t *xl = NULL;
+ size_t tot_size = 0;
+ void *ptr = NULL;
+ xlator_t *xl = NULL;
- if (!THIS->ctx->mem_acct_enable)
- return MALLOC (size);
+ if (!gf_mem_acct_enabled())
+ return MALLOC(size);
- xl = THIS;
+ xl = THIS;
- tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
+ tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
- ptr = malloc (tot_size);
- if (!ptr) {
- gf_msg_nomem ("", GF_LOG_ALERT, tot_size);
- return NULL;
- }
- gf_mem_set_acct_info (xl, &ptr, size, type, typestr);
+ ptr = malloc(tot_size);
+ if (!ptr) {
+ gf_msg_nomem("", GF_LOG_ALERT, tot_size);
+ return NULL;
+ }
- return (void *)ptr;
+ return gf_mem_set_acct_info(xl->mem_acct, ptr, size, type, typestr);
}
void *
-__gf_realloc (void *ptr, size_t size)
+__gf_realloc(void *ptr, size_t size)
{
- size_t tot_size = 0;
- char *new_ptr;
- struct mem_header *old_header = NULL;
- struct mem_header *new_header = NULL;
- struct mem_header tmp_header;
-
- if (!THIS->ctx->mem_acct_enable)
- return REALLOC (ptr, size);
-
- REQUIRE(NULL != ptr);
-
- old_header = (struct mem_header *) (ptr - GF_MEM_HEADER_SIZE);
- GF_ASSERT (old_header->magic == GF_MEM_HEADER_MAGIC);
- tmp_header = *old_header;
-
- tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
- new_ptr = realloc (old_header, tot_size);
- if (!new_ptr) {
- gf_msg_nomem ("", GF_LOG_ALERT, tot_size);
- return NULL;
- }
+ size_t tot_size = 0;
+ struct mem_header *header = NULL;
+
+ if (!gf_mem_acct_enabled())
+ return REALLOC(ptr, size);
- /*
- * We used to pass (char **)&ptr as the second
- * argument after the value of realloc was saved
- * in ptr, but the compiler warnings complained
- * about the casting to and forth from void ** to
- * char **.
- * TBD: it would be nice to adjust the memory accounting info here,
- * but calling gf_mem_set_acct_info here is wrong because it bumps
- * up counts as though this is a new allocation - which it's not.
- * The consequence of doing nothing here is only that the sizes will be
- * wrong, but at least the counts won't be.
- uint32_t type = 0;
- xlator_t *xl = NULL;
- type = header->type;
- xl = (xlator_t *) header->xlator;
- gf_mem_set_acct_info (xl, &new_ptr, size, type, NULL);
- */
-
- new_header = (struct mem_header *) new_ptr;
- *new_header = tmp_header;
- new_header->size = size;
-
- new_ptr += sizeof (struct mem_header);
- /* data follows in this gap of 'size' bytes */
- *(uint32_t *) (new_ptr + size) = GF_MEM_TRAILER_MAGIC;
-
- return (void *)new_ptr;
+ REQUIRE(NULL != ptr);
+
+ header = (struct mem_header *)(ptr - GF_MEM_HEADER_SIZE);
+ GF_ASSERT(header->magic == GF_MEM_HEADER_MAGIC);
+
+ tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
+ header = realloc(header, tot_size);
+ if (!header) {
+ gf_msg_nomem("", GF_LOG_ALERT, tot_size);
+ return NULL;
+ }
+
+ return gf_mem_update_acct_info(header->mem_acct, header, size);
}
int
-gf_vasprintf (char **string_ptr, const char *format, va_list arg)
+gf_vasprintf(char **string_ptr, const char *format, va_list arg)
{
- va_list arg_save;
- char *str = NULL;
- int size = 0;
- int rv = 0;
-
- if (!string_ptr || !format)
- return -1;
-
- va_copy (arg_save, arg);
-
- size = vsnprintf (NULL, 0, format, arg);
- size++;
- str = GF_MALLOC (size, gf_common_mt_asprintf);
- if (str == NULL) {
- /* log is done in GF_MALLOC itself */
- return -1;
- }
- rv = vsnprintf (str, size, format, arg_save);
-
- *string_ptr = str;
- return (rv);
+ va_list arg_save;
+ char *str = NULL;
+ int size = 0;
+ int rv = 0;
+
+ if (!string_ptr || !format)
+ return -1;
+
+ va_copy(arg_save, arg);
+
+ size = vsnprintf(NULL, 0, format, arg);
+ size++;
+ str = GF_MALLOC(size, gf_common_mt_asprintf);
+ if (str == NULL) {
+ /* log is done in GF_MALLOC itself */
+ va_end(arg_save);
+ return -1;
+ }
+ rv = vsnprintf(str, size, format, arg_save);
+
+ *string_ptr = str;
+ va_end(arg_save);
+ return (rv);
}
int
-gf_asprintf (char **string_ptr, const char *format, ...)
+gf_asprintf(char **string_ptr, const char *format, ...)
{
- va_list arg;
- int rv = 0;
+ va_list arg;
+ int rv = 0;
- va_start (arg, format);
- rv = gf_vasprintf (string_ptr, format, arg);
- va_end (arg);
+ va_start(arg, format);
+ rv = gf_vasprintf(string_ptr, format, arg);
+ va_end(arg);
- return rv;
+ return rv;
}
#ifdef DEBUG
void
-__gf_mem_invalidate (void *ptr)
+__gf_mem_invalidate(void *ptr)
{
- struct mem_header *header = ptr;
- void *end = NULL;
-
- struct mem_invalid inval = {
- .magic = GF_MEM_INVALID_MAGIC,
- .mem_acct = header->mem_acct,
- .type = header->type,
- .size = header->size,
- .baseaddr = ptr + GF_MEM_HEADER_SIZE,
- };
-
- /* calculate the last byte of the allocated area */
- end = ptr + GF_MEM_HEADER_SIZE + inval.size + GF_MEM_TRAILER_SIZE;
-
- /* overwrite the old mem_header */
- memcpy (ptr, &inval, sizeof (inval));
- ptr += sizeof (inval);
-
- /* zero out remaining (old) mem_header bytes) */
- memset (ptr, 0x00, sizeof (*header) - sizeof (inval));
- ptr += sizeof (*header) - sizeof (inval);
-
- /* zero out the first byte of data */
- *(uint32_t *)(ptr) = 0x00;
- ptr += 1;
-
- /* repeated writes of invalid structurein data area */
- while ((ptr + (sizeof (inval))) < (end - 1)) {
- memcpy (ptr, &inval, sizeof (inval));
- ptr += sizeof (inval);
- }
-
- /* fill out remaining data area with 0xff */
- memset (ptr, 0xff, end - ptr);
+ struct mem_header *header = ptr;
+ void *end = NULL;
+
+ struct mem_invalid inval = {
+ .magic = GF_MEM_INVALID_MAGIC,
+ .mem_acct = header->mem_acct,
+ .type = header->type,
+ .size = header->size,
+ .baseaddr = ptr + GF_MEM_HEADER_SIZE,
+ };
+
+ /* calculate the last byte of the allocated area */
+ end = ptr + GF_MEM_HEADER_SIZE + inval.size + GF_MEM_TRAILER_SIZE;
+
+ /* overwrite the old mem_header */
+ memcpy(ptr, &inval, sizeof(inval));
+ ptr += sizeof(inval);
+
+ /* zero out remaining (old) mem_header bytes) */
+ memset(ptr, 0x00, sizeof(*header) - sizeof(inval));
+ ptr += sizeof(*header) - sizeof(inval);
+
+ /* zero out the first byte of data */
+ *(uint32_t *)(ptr) = 0x00;
+ ptr += 1;
+
+ /* repeated writes of invalid structurein data area */
+ while ((ptr + (sizeof(inval))) < (end - 1)) {
+ memcpy(ptr, &inval, sizeof(inval));
+ ptr += sizeof(inval);
+ }
+
+ /* fill out remaining data area with 0xff */
+ memset(ptr, 0xff, end - ptr);
}
#endif /* DEBUG */
-void
-__gf_free (void *free_ptr)
+/* Coverity taint NOTE: pointers passed to free, would operate on
+pointer-GF_MEM_HEADER_SIZE content and if the pointer was used for any IO
+related purpose, the pointer stands tainted, and hence coverity would consider
+access to the said region as tainted. The following directive to coverity hence
+sanitizes the pointer, thus removing any taint to the same within this function.
+If the pointer is accessed outside the scope of this function without any
+checks on content read from an IO operation, taints will still be reported, and
+needs appropriate addressing. */
+
+/* coverity[ +tainted_data_sanitize : arg-0 ] */
+static void
+gf_free_sanitize(void *s)
{
- void *ptr = NULL;
- struct mem_acct *mem_acct;
- struct mem_header *header = NULL;
-
- if (!THIS->ctx->mem_acct_enable) {
- FREE (free_ptr);
- return;
- }
-
- if (!free_ptr)
- return;
-
- ptr = free_ptr - GF_MEM_HEADER_SIZE;
- header = (struct mem_header *) ptr;
+}
- //Possible corruption, assert here
- GF_ASSERT (GF_MEM_HEADER_MAGIC == header->magic);
+void
+__gf_free(void *free_ptr)
+{
+ void *ptr = NULL;
+ struct mem_acct *mem_acct;
+ struct mem_header *header = NULL;
+ bool last_ref = false;
- mem_acct = header->mem_acct;
- if (!mem_acct) {
- goto free;
- }
+ if (!gf_mem_acct_enabled()) {
+ FREE(free_ptr);
+ return;
+ }
- // This points to a memory overrun
- GF_ASSERT (GF_MEM_TRAILER_MAGIC ==
- *(uint32_t *)((char *)free_ptr + header->size));
+ if (!free_ptr)
+ return;
- LOCK (&mem_acct->rec[header->type].lock);
- {
- mem_acct->rec[header->type].size -= header->size;
- mem_acct->rec[header->type].num_allocs--;
- /* If all the instaces are freed up then ensure typestr is
- * set to NULL */
- if (!mem_acct->rec[header->type].num_allocs)
- mem_acct->rec[header->type].typestr = NULL;
+ gf_free_sanitize(free_ptr);
+ ptr = free_ptr - GF_MEM_HEADER_SIZE;
+ header = (struct mem_header *)ptr;
+
+ // Possible corruption, assert here
+ GF_ASSERT(GF_MEM_HEADER_MAGIC == header->magic);
+
+ mem_acct = header->mem_acct;
+ if (!mem_acct) {
+ goto free;
+ }
+
+ // This points to a memory overrun
+ GF_ASSERT(GF_MEM_TRAILER_MAGIC ==
+ *(uint32_t *)((char *)free_ptr + header->size));
+
+ LOCK(&mem_acct->rec[header->type].lock);
+ {
+ mem_acct->rec[header->type].size -= header->size;
+ mem_acct->rec[header->type].num_allocs--;
+ /* If all the instances are freed up then ensure typestr is set
+ * to NULL */
+ if (!mem_acct->rec[header->type].num_allocs) {
+ last_ref = true;
+ mem_acct->rec[header->type].typestr = NULL;
}
- UNLOCK (&mem_acct->rec[header->type].lock);
+#ifdef DEBUG
+ list_del(&header->acct_list);
+#endif
+ }
+ UNLOCK(&mem_acct->rec[header->type].lock);
- if (DECREMENT_ATOMIC (mem_acct->lock, mem_acct->refcnt) == 0) {
- FREE (mem_acct);
- }
+ if (last_ref) {
+ xlator_mem_acct_unref(mem_acct);
+ }
free:
#ifdef DEBUG
- __gf_mem_invalidate (ptr);
+ __gf_mem_invalidate(ptr);
#endif
- FREE (ptr);
+ FREE(ptr);
}
-
+#if defined(GF_DISABLE_MEMPOOL)
struct mem_pool *
-mem_pool_new_fn (unsigned long sizeof_type,
- unsigned long count, char *name)
+mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type,
+ unsigned long count, char *name)
{
- struct mem_pool *mem_pool = NULL;
- unsigned long padded_sizeof_type = 0;
- GF_UNUSED void *pool = NULL;
- GF_UNUSED int i = 0;
- int ret = 0;
- GF_UNUSED struct list_head *list = NULL;
- glusterfs_ctx_t *ctx = NULL;
-
- if (!sizeof_type || !count) {
- gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return NULL;
- }
- padded_sizeof_type = sizeof_type + GF_MEM_POOL_PAD_BOUNDARY;
+ struct mem_pool *new;
- mem_pool = GF_CALLOC (sizeof (*mem_pool), 1, gf_common_mt_mem_pool);
- if (!mem_pool)
- return NULL;
+ new = GF_MALLOC(sizeof(struct mem_pool), gf_common_mt_mem_pool);
+ if (!new)
+ return NULL;
- ret = gf_asprintf (&mem_pool->name, "%s:%s", THIS->name, name);
- if (ret < 0)
- return NULL;
+ new->sizeof_type = sizeof_type;
+ return new;
+}
- if (!mem_pool->name) {
- GF_FREE (mem_pool);
- return NULL;
- }
+void
+mem_pool_destroy(struct mem_pool *pool)
+{
+ GF_FREE(pool);
+}
- LOCK_INIT (&mem_pool->lock);
- INIT_LIST_HEAD (&mem_pool->list);
- INIT_LIST_HEAD (&mem_pool->global_list);
+#else /* !GF_DISABLE_MEMPOOL */
- mem_pool->padded_sizeof_type = padded_sizeof_type;
- mem_pool->real_sizeof_type = sizeof_type;
+static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER;
+static struct list_head pool_threads;
+static pthread_mutex_t pool_free_lock = PTHREAD_MUTEX_INITIALIZER;
+static struct list_head pool_free_threads;
+static struct mem_pool_shared pools[NPOOLS];
+static size_t pool_list_size;
-#ifndef DEBUG
- mem_pool->cold_count = count;
- pool = GF_CALLOC (count, padded_sizeof_type, gf_common_mt_long);
- if (!pool) {
- GF_FREE (mem_pool->name);
- GF_FREE (mem_pool);
- return NULL;
- }
+static __thread per_thread_pool_list_t *thread_pool_list = NULL;
- for (i = 0; i < count; i++) {
- list = pool + (i * (padded_sizeof_type));
- INIT_LIST_HEAD (list);
- list_add_tail (list, &mem_pool->list);
- }
+#define N_COLD_LISTS 1024
+#define POOL_SWEEP_SECS 30
- mem_pool->pool = pool;
- mem_pool->pool_end = pool + (count * (padded_sizeof_type));
-#endif
+typedef struct {
+ pooled_obj_hdr_t *cold_lists[N_COLD_LISTS];
+ unsigned int n_cold_lists;
+} sweep_state_t;
- /* add this pool to the global list */
- ctx = THIS->ctx;
- if (!ctx)
- goto out;
+enum init_state {
+ GF_MEMPOOL_INIT_NONE = 0,
+ GF_MEMPOOL_INIT_EARLY,
+ GF_MEMPOOL_INIT_LATE,
+ GF_MEMPOOL_INIT_DESTROY
+};
- list_add (&mem_pool->global_list, &ctx->mempool_list);
+static enum init_state init_done = GF_MEMPOOL_INIT_NONE;
+static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
+static unsigned int init_count = 0;
+static pthread_t sweeper_tid;
-out:
- return mem_pool;
-}
-
-void*
-mem_get0 (struct mem_pool *mem_pool)
+static bool
+collect_garbage(sweep_state_t *state, per_thread_pool_list_t *pool_list)
{
- void *ptr = NULL;
-
- if (!mem_pool) {
- gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return NULL;
+ unsigned int i;
+ per_thread_pool_t *pt_pool;
+
+ (void)pthread_spin_lock(&pool_list->lock);
+
+ for (i = 0; i < NPOOLS; ++i) {
+ pt_pool = &pool_list->pools[i];
+ if (pt_pool->cold_list) {
+ if (state->n_cold_lists >= N_COLD_LISTS) {
+ (void)pthread_spin_unlock(&pool_list->lock);
+ return true;
+ }
+ state->cold_lists[state->n_cold_lists++] = pt_pool->cold_list;
}
+ pt_pool->cold_list = pt_pool->hot_list;
+ pt_pool->hot_list = NULL;
+ }
- ptr = mem_get(mem_pool);
+ (void)pthread_spin_unlock(&pool_list->lock);
- if (ptr)
- memset(ptr, 0, mem_pool->real_sizeof_type);
+ return false;
+}
- return ptr;
+static void
+free_obj_list(pooled_obj_hdr_t *victim)
+{
+ pooled_obj_hdr_t *next;
+
+ while (victim) {
+ next = victim->next;
+ free(victim);
+ victim = next;
+ }
}
-void *
-mem_get (struct mem_pool *mem_pool)
+static void *
+pool_sweeper(void *arg)
{
- struct list_head *list = NULL;
- void *ptr = NULL;
- int *in_use = NULL;
- struct mem_pool **pool_ptr = NULL;
-
- if (!mem_pool) {
- gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return NULL;
+ sweep_state_t state;
+ per_thread_pool_list_t *pool_list;
+ uint32_t i;
+ bool pending;
+
+ /*
+ * This is all a bit inelegant, but the point is to avoid doing
+ * expensive things (like freeing thousands of objects) while holding a
+ * global lock. Thus, we split each iteration into two passes, with
+ * only the first and fastest holding the lock.
+ */
+
+ pending = true;
+
+ for (;;) {
+ /* If we know there's pending work to do (or it's the first run), we
+ * do collect garbage more often. */
+ sleep(pending ? POOL_SWEEP_SECS / 5 : POOL_SWEEP_SECS);
+
+ (void)pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ state.n_cold_lists = 0;
+ pending = false;
+
+ /* First pass: collect stuff that needs our attention. */
+ (void)pthread_mutex_lock(&pool_lock);
+ list_for_each_entry(pool_list, &pool_threads, thr_list)
+ {
+ if (collect_garbage(&state, pool_list)) {
+ pending = true;
+ }
}
+ (void)pthread_mutex_unlock(&pool_lock);
- LOCK (&mem_pool->lock);
- {
- mem_pool->alloc_count++;
- if (mem_pool->cold_count) {
- list = mem_pool->list.next;
- list_del (list);
-
- 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 +
- GF_MEM_POOL_PTR);
- *in_use = 1;
-
- goto fwd_addr_out;
- }
-
- /* 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 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.
- *
- * I am working around this by performing a regular allocation
- * , just the way the caller would've done when not using the
- * mem-pool. That also means, we're not padding the size with
- * the list_head structure because, this will not be added to
- * the list of chunks that belong to the mem-pool allocated
- * initially.
- *
- * This is the best we can do without adding functionality for
- * managing multiple slabs. That does not interest us at present
- * because it is too much work knowing that a better slab
- * allocator is coming RSN.
- */
- 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);
-
- /* Memory coming from the heap need not be transformed from a
- * chunkhead to a usable pointer since it is not coming from
- * the pool.
- */
+ /* Second pass: free cold objects from live pools. */
+ for (i = 0; i < state.n_cold_lists; ++i) {
+ free_obj_list(state.cold_lists[i]);
}
-fwd_addr_out:
- pool_ptr = mem_pool_from_ptr (ptr);
- *pool_ptr = (struct mem_pool *)mem_pool;
- ptr = mem_pool_chunkhead2ptr (ptr);
- UNLOCK (&mem_pool->lock);
+ (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ }
- return ptr;
+ return NULL;
}
-
-static int
-__is_member (struct mem_pool *pool, void *ptr)
+void
+mem_pool_thread_destructor(per_thread_pool_list_t *pool_list)
{
- if (!pool || !ptr) {
- gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return -1;
+ per_thread_pool_t *pt_pool;
+ uint32_t i;
+
+ if (pool_list == NULL) {
+ pool_list = thread_pool_list;
+ }
+
+ /* The current thread is terminating. None of the allocated objects will
+ * be used again. We can directly destroy them here instead of delaying
+ * it until the next sweeper loop. */
+ if (pool_list != NULL) {
+ /* Remove pool_list from the global list to avoid that sweeper
+ * could touch it. */
+ pthread_mutex_lock(&pool_lock);
+ list_del(&pool_list->thr_list);
+ pthread_mutex_unlock(&pool_lock);
+
+ /* We need to protect hot/cold changes from potential mem_put() calls
+ * that reference this pool_list. Once poison is set to true, we are
+ * sure that no one else will touch hot/cold lists. The only possible
+ * race is when at the same moment a mem_put() is adding a new item
+ * to the hot list. We protect from that by taking pool_list->lock.
+ * After that we don't need the lock to destroy the hot/cold lists. */
+ pthread_spin_lock(&pool_list->lock);
+ pool_list->poison = true;
+ pthread_spin_unlock(&pool_list->lock);
+
+ for (i = 0; i < NPOOLS; i++) {
+ pt_pool = &pool_list->pools[i];
+
+ free_obj_list(pt_pool->hot_list);
+ pt_pool->hot_list = NULL;
+
+ free_obj_list(pt_pool->cold_list);
+ pt_pool->cold_list = NULL;
}
- if (ptr < pool->pool || ptr >= pool->pool_end)
- return 0;
+ pthread_mutex_lock(&pool_free_lock);
+ list_add(&pool_list->thr_list, &pool_free_threads);
+ pthread_mutex_unlock(&pool_free_lock);
+
+ thread_pool_list = NULL;
+ }
+}
+
+static __attribute__((constructor)) void
+mem_pools_preinit(void)
+{
+ unsigned int i;
+
+ INIT_LIST_HEAD(&pool_threads);
+ INIT_LIST_HEAD(&pool_free_threads);
+
+ for (i = 0; i < NPOOLS; ++i) {
+ pools[i].power_of_two = POOL_SMALLEST + i;
+
+ GF_ATOMIC_INIT(pools[i].allocs_hot, 0);
+ GF_ATOMIC_INIT(pools[i].allocs_cold, 0);
+ GF_ATOMIC_INIT(pools[i].allocs_stdc, 0);
+ GF_ATOMIC_INIT(pools[i].frees_to_list, 0);
+ }
+
+ pool_list_size = sizeof(per_thread_pool_list_t) +
+ sizeof(per_thread_pool_t) * (NPOOLS - 1);
- if ((mem_pool_ptr2chunkhead (ptr) - pool->pool)
- % pool->padded_sizeof_type)
- return -1;
+ init_done = GF_MEMPOOL_INIT_EARLY;
+}
- return 1;
+static __attribute__((destructor)) void
+mem_pools_postfini(void)
+{
+ /* TODO: This function should destroy all per thread memory pools that
+ * are still alive, but this is not possible right now because glibc
+ * starts calling destructors as soon as exit() is called, and
+ * gluster doesn't ensure that all threads have been stopped before
+ * calling exit(). Existing threads would crash when they try to use
+ * memory or they terminate if we destroy things here.
+ *
+ * When we propertly terminate all threads, we can add the needed
+ * code here. Till then we need to leave the memory allocated. Most
+ * probably this function will be executed on process termination,
+ * so the memory will be released anyway by the system. */
}
+/* Call mem_pools_init() once threading has been configured completely. This
+ * prevent the pool_sweeper thread from getting killed once the main() thread
+ * exits during deamonizing. */
+void
+mem_pools_init(void)
+{
+ pthread_mutex_lock(&init_mutex);
+ if ((init_count++) == 0) {
+ (void)gf_thread_create(&sweeper_tid, NULL, pool_sweeper, NULL,
+ "memsweep");
+
+ init_done = GF_MEMPOOL_INIT_LATE;
+ }
+ pthread_mutex_unlock(&init_mutex);
+}
void
-mem_put (void *ptr)
+mem_pools_fini(void)
{
- struct list_head *list = NULL;
- int *in_use = NULL;
- void *head = NULL;
- struct mem_pool **tmp = NULL;
- struct mem_pool *pool = NULL;
-
- if (!ptr) {
- gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL,
- LG_MSG_INVALID_ARG, "invalid argument");
- return;
+ pthread_mutex_lock(&init_mutex);
+ switch (init_count) {
+ case 0:
+ /*
+ * If init_count is already zero (as e.g. if somebody called this
+ * before mem_pools_init) then the sweeper was probably never even
+ * started so we don't need to stop it. Even if there's some crazy
+ * circumstance where there is a sweeper but init_count is still
+ * zero, that just means we'll leave it running. Not perfect, but
+ * far better than any known alternative.
+ */
+ break;
+ case 1: {
+ /* if mem_pools_init() was not called, sweeper_tid will be invalid
+ * and the functions will error out. That is not critical. In all
+ * other cases, the sweeper_tid will be valid and the thread gets
+ * stopped. */
+ (void)pthread_cancel(sweeper_tid);
+ (void)pthread_join(sweeper_tid, NULL);
+
+ /* There could be threads still running in some cases, so we can't
+ * destroy pool_lists in use. We can also not destroy unused
+ * pool_lists because some allocated objects may still be pointing
+ * to them. */
+ mem_pool_thread_destructor(NULL);
+
+ init_done = GF_MEMPOOL_INIT_DESTROY;
+ /* Fall through. */
}
+ default:
+ --init_count;
+ }
+ pthread_mutex_unlock(&init_mutex);
+}
+
+void
+mem_pool_destroy(struct mem_pool *pool)
+{
+ if (!pool)
+ return;
+
+ /* remove this pool from the owner (glusterfs_ctx_t) */
+ LOCK(&pool->ctx->lock);
+ {
+ list_del(&pool->owner);
+ }
+ UNLOCK(&pool->ctx->lock);
+
+ /* free this pool, but keep the mem_pool_shared */
+ GF_FREE(pool);
+
+ /*
+ * Pools are now permanent, so the mem_pool->pool is kept around. All
+ * of the objects *in* the pool will eventually be freed via the
+ * pool-sweeper thread, and this way we don't have to add a lot of
+ * reference-counting complexity.
+ */
+}
+
+struct mem_pool *
+mem_pool_new_fn(glusterfs_ctx_t *ctx, unsigned long sizeof_type,
+ unsigned long count, char *name)
+{
+ unsigned long extra_size, size;
+ unsigned int power;
+ struct mem_pool *new = NULL;
+ struct mem_pool_shared *pool = NULL;
+
+ if (!sizeof_type) {
+ gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return NULL;
+ }
+
+ /* This is the overhead we'll have because of memory accounting for each
+ * memory block. */
+ extra_size = sizeof(pooled_obj_hdr_t);
+
+ /* We need to compute the total space needed to hold the data type and
+ * the header. Given that the smallest block size we have in the pools
+ * is 2^POOL_SMALLEST, we need to take the MAX(size, 2^POOL_SMALLEST).
+ * However, since this value is only needed to compute its rounded
+ * logarithm in base 2, and this only depends on the highest bit set,
+ * we can simply do a bitwise or with the minimum size. We need to
+ * subtract 1 for correct handling of sizes that are exactly a power
+ * of 2. */
+ size = (sizeof_type + extra_size - 1UL) | ((1UL << POOL_SMALLEST) - 1UL);
+
+ /* We compute the logarithm in base 2 rounded up of the resulting size.
+ * This value will identify which pool we need to use from the pools of
+ * powers of 2. This is equivalent to finding the position of the highest
+ * bit set. */
+ power = sizeof(size) * 8 - __builtin_clzl(size);
+ if (power > POOL_LARGEST) {
+ gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return NULL;
+ }
+ pool = &pools[power - POOL_SMALLEST];
+
+ new = GF_MALLOC(sizeof(struct mem_pool), gf_common_mt_mem_pool);
+ if (!new)
+ return NULL;
+
+ new->ctx = ctx;
+ new->sizeof_type = sizeof_type;
+ new->count = count;
+ new->name = name;
+ new->xl_name = THIS->name;
+ new->pool = pool;
+ GF_ATOMIC_INIT(new->active, 0);
+#ifdef DEBUG
+ GF_ATOMIC_INIT(new->hit, 0);
+ GF_ATOMIC_INIT(new->miss, 0);
+#endif
+ INIT_LIST_HEAD(&new->owner);
+
+ LOCK(&ctx->lock);
+ {
+ list_add(&new->owner, &ctx->mempool_list);
+ }
+ UNLOCK(&ctx->lock);
+
+ return new;
+}
- list = head = mem_pool_ptr2chunkhead (ptr);
- tmp = mem_pool_from_ptr (head);
- if (!tmp) {
- gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, 0,
- LG_MSG_PTR_HEADER_CORRUPTED,
- "ptr header is corrupted");
- return;
+per_thread_pool_list_t *
+mem_get_pool_list(void)
+{
+ per_thread_pool_list_t *pool_list;
+ unsigned int i;
+
+ pool_list = thread_pool_list;
+ if (pool_list) {
+ return pool_list;
+ }
+
+ (void)pthread_mutex_lock(&pool_free_lock);
+ if (!list_empty(&pool_free_threads)) {
+ pool_list = list_entry(pool_free_threads.next, per_thread_pool_list_t,
+ thr_list);
+ list_del(&pool_list->thr_list);
+ }
+ (void)pthread_mutex_unlock(&pool_free_lock);
+
+ if (!pool_list) {
+ pool_list = MALLOC(pool_list_size);
+ if (!pool_list) {
+ return NULL;
}
- pool = *tmp;
- if (!pool) {
- gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, 0,
- LG_MSG_MEMPOOL_PTR_NULL,
- "mem-pool ptr is NULL");
- return;
+ INIT_LIST_HEAD(&pool_list->thr_list);
+ (void)pthread_spin_init(&pool_list->lock, PTHREAD_PROCESS_PRIVATE);
+ for (i = 0; i < NPOOLS; ++i) {
+ pool_list->pools[i].parent = &pools[i];
+ pool_list->pools[i].hot_list = NULL;
+ pool_list->pools[i].cold_list = NULL;
}
- LOCK (&pool->lock);
- {
+ }
+
+ /* There's no need to take pool_list->lock, because this is already an
+ * atomic operation and we don't need to synchronize it with any change
+ * in hot/cold lists. */
+ pool_list->poison = false;
+
+ (void)pthread_mutex_lock(&pool_lock);
+ list_add(&pool_list->thr_list, &pool_threads);
+ (void)pthread_mutex_unlock(&pool_lock);
+
+ thread_pool_list = pool_list;
+
+ /* Ensure that all memory objects associated to the new pool_list are
+ * destroyed when the thread terminates. */
+ gf_thread_needs_cleanup();
+
+ return pool_list;
+}
- switch (__is_member (pool, ptr))
- {
- case 1:
- in_use = (head + GF_MEM_POOL_LIST_BOUNDARY +
- GF_MEM_POOL_PTR);
- if (!is_mem_chunk_in_use(in_use)) {
- gf_msg_callingfn ("mem-pool", GF_LOG_CRITICAL,
- 0,
- LG_MSG_MEMPOOL_INVALID_FREE,
- "mem_put called on freed ptr"
- " %p of mem pool %p", ptr,
- pool);
- break;
- }
- pool->hot_count--;
- pool->cold_count++;
- *in_use = 0;
- list_add (list, &pool->list);
- break;
- case -1:
- /* For some reason, the address given is within
- * the address range of the mem-pool but does not align
- * with the expected start of a chunk that includes
- * the list headers also. Sounds like a problem in
- * layers of clouds up above us. ;)
- */
- abort ();
- break;
- case 0:
- /* The address is outside the range of the mem-pool. We
- * assume here that this address was allocated at a
- * point when the mem-pool was out of chunks in mem_get
- * or the programmer has made a mistake by calling the
- * wrong de-allocation interface. We do
- * not have enough info to distinguish between the two
- * situations.
- */
- pool->curr_stdalloc--;
- GF_FREE (list);
- break;
- default:
- /* log error */
- break;
- }
+static pooled_obj_hdr_t *
+mem_get_from_pool(struct mem_pool *mem_pool)
+{
+ per_thread_pool_list_t *pool_list;
+ per_thread_pool_t *pt_pool;
+ pooled_obj_hdr_t *retval;
+#ifdef DEBUG
+ gf_boolean_t hit = _gf_true;
+#endif
+
+ pool_list = mem_get_pool_list();
+ if (!pool_list || pool_list->poison) {
+ return NULL;
+ }
+
+ pt_pool = &pool_list->pools[mem_pool->pool->power_of_two - POOL_SMALLEST];
+
+ (void)pthread_spin_lock(&pool_list->lock);
+
+ retval = pt_pool->hot_list;
+ if (retval) {
+ pt_pool->hot_list = retval->next;
+ (void)pthread_spin_unlock(&pool_list->lock);
+ GF_ATOMIC_INC(pt_pool->parent->allocs_hot);
+ } else {
+ retval = pt_pool->cold_list;
+ if (retval) {
+ pt_pool->cold_list = retval->next;
+ (void)pthread_spin_unlock(&pool_list->lock);
+ GF_ATOMIC_INC(pt_pool->parent->allocs_cold);
+ } else {
+ (void)pthread_spin_unlock(&pool_list->lock);
+ GF_ATOMIC_INC(pt_pool->parent->allocs_stdc);
+ retval = malloc(1 << pt_pool->parent->power_of_two);
+#ifdef DEBUG
+ hit = _gf_false;
+#endif
}
- UNLOCK (&pool->lock);
+ }
+
+ if (retval != NULL) {
+ retval->pool = mem_pool;
+ retval->power_of_two = mem_pool->pool->power_of_two;
+#ifdef DEBUG
+ if (hit == _gf_true)
+ GF_ATOMIC_INC(mem_pool->hit);
+ else
+ GF_ATOMIC_INC(mem_pool->miss);
+#endif
+ retval->magic = GF_MEM_HEADER_MAGIC;
+ retval->pool_list = pool_list;
+ }
+
+ return retval;
}
-void
-mem_pool_destroy (struct mem_pool *pool)
+#endif /* GF_DISABLE_MEMPOOL */
+
+void *
+mem_get0(struct mem_pool *mem_pool)
{
- if (!pool)
- return;
+ void *ptr = mem_get(mem_pool);
+ if (ptr) {
+#if defined(GF_DISABLE_MEMPOOL)
+ memset(ptr, 0, mem_pool->sizeof_type);
+#else
+ memset(ptr, 0, AVAILABLE_SIZE(mem_pool->pool->power_of_two));
+#endif
+ }
- gf_msg (THIS->name, GF_LOG_INFO, 0, LG_MSG_MEM_POOL_DESTROY, "size=%lu "
- "max=%d total=%"PRIu64, pool->padded_sizeof_type,
- pool->max_alloc, pool->alloc_count);
+ return ptr;
+}
- list_del (&pool->global_list);
+void *
+mem_get(struct mem_pool *mem_pool)
+{
+ if (!mem_pool) {
+ gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return NULL;
+ }
+
+#if defined(GF_DISABLE_MEMPOOL)
+ return GF_MALLOC(mem_pool->sizeof_type, gf_common_mt_mem_pool);
+#else
+ pooled_obj_hdr_t *retval = mem_get_from_pool(mem_pool);
+ if (!retval) {
+ return NULL;
+ }
+
+ GF_ATOMIC_INC(mem_pool->active);
+
+ return retval + 1;
+#endif /* GF_DISABLE_MEMPOOL */
+}
- LOCK_DESTROY (&pool->lock);
- GF_FREE (pool->name);
- GF_FREE (pool->pool);
- GF_FREE (pool);
+void
+mem_put(void *ptr)
+{
+#if defined(GF_DISABLE_MEMPOOL)
+ GF_FREE(ptr);
+#else
+ pooled_obj_hdr_t *hdr;
+ per_thread_pool_list_t *pool_list;
+ per_thread_pool_t *pt_pool;
+
+ if (!ptr) {
+ gf_msg_callingfn("mem-pool", GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG,
+ "invalid argument");
+ return;
+ }
+
+ hdr = ((pooled_obj_hdr_t *)ptr) - 1;
+ if (hdr->magic != GF_MEM_HEADER_MAGIC) {
+ /* Not one of ours; don't touch it. */
+ return;
+ }
+ if (!hdr->pool_list) {
+ gf_msg_callingfn("mem-pool", GF_LOG_CRITICAL, EINVAL,
+ LG_MSG_INVALID_ARG,
+ "invalid argument hdr->pool_list NULL");
return;
+ }
+
+ pool_list = hdr->pool_list;
+ pt_pool = &pool_list->pools[hdr->power_of_two - POOL_SMALLEST];
+
+ if (hdr->pool)
+ GF_ATOMIC_DEC(hdr->pool->active);
+
+ hdr->magic = GF_MEM_INVALID_MAGIC;
+
+ (void)pthread_spin_lock(&pool_list->lock);
+ if (!pool_list->poison) {
+ hdr->next = pt_pool->hot_list;
+ pt_pool->hot_list = hdr;
+ (void)pthread_spin_unlock(&pool_list->lock);
+ GF_ATOMIC_INC(pt_pool->parent->frees_to_list);
+ } else {
+ /* If the owner thread of this element has terminated, we simply
+ * release its memory. */
+ (void)pthread_spin_unlock(&pool_list->lock);
+ free(hdr);
+ }
+#endif /* GF_DISABLE_MEMPOOL */
}
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
deleted file mode 100644
index 5115cef9f93..00000000000
--- a/libglusterfs/src/mem-pool.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- 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_
-#define _MEM_POOL_H_
-
-#include "list.h"
-#include "locking.h"
-#include "logging.h"
-#include "mem-types.h"
-#include <stdlib.h>
-#include <inttypes.h>
-#include <string.h>
-#include <stdarg.h>
-
-/*
- * Need this for unit tests since inline functions
- * access memory allocation and need to use the
- * unit test versions
- */
-#ifdef UNIT_TESTING
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#endif
-
-#define GF_MEM_TRAILER_SIZE 8
-#define GF_MEM_HEADER_MAGIC 0xCAFEBABE
-#define GF_MEM_TRAILER_MAGIC 0xBAADF00D
-#define GF_MEM_INVALID_MAGIC 0xDEADC0DE
-
-struct mem_acct_rec {
- const char *typestr;
- size_t size;
- size_t max_size;
- uint32_t num_allocs;
- uint32_t total_allocs;
- uint32_t max_num_allocs;
- gf_lock_t lock;
-};
-
-struct mem_acct {
- uint32_t num_types;
- /*
- * The lock is only used on ancient platforms (e.g. RHEL5) to keep
- * refcnt increment/decrement atomic. We could even make its existence
- * conditional on the right set of version/feature checks, but it's so
- * lightweight that it's not worth the obfuscation.
- */
- gf_lock_t lock;
- unsigned int refcnt;
- struct mem_acct_rec rec[0];
-};
-
-struct mem_header {
- uint32_t type;
- size_t size;
- struct mem_acct *mem_acct;
- uint32_t magic;
- int padding[8];
-};
-
-#define GF_MEM_HEADER_SIZE (sizeof (struct mem_header))
-
-#ifdef DEBUG
-struct mem_invalid {
- uint32_t magic;
- void *mem_acct;
- uint32_t type;
- size_t size;
- void *baseaddr;
-};
-#endif
-
-void *
-__gf_calloc (size_t cnt, size_t size, uint32_t type, const char *typestr);
-
-void *
-__gf_malloc (size_t size, uint32_t type, const char *typestr);
-
-void *
-__gf_realloc (void *ptr, size_t size);
-
-int
-gf_vasprintf (char **string_ptr, const char *format, va_list arg);
-
-int
-gf_asprintf (char **string_ptr, const char *format, ...);
-
-void
-__gf_free (void *ptr);
-
-
-static inline
-void* __gf_default_malloc (size_t size)
-{
- void *ptr = NULL;
-
- ptr = malloc (size);
- if (!ptr)
- gf_msg_nomem ("", GF_LOG_ALERT, size);
-
- return ptr;
-}
-
-static inline
-void* __gf_default_calloc (int cnt, size_t size)
-{
- void *ptr = NULL;
-
- ptr = calloc (cnt, size);
- if (!ptr)
- gf_msg_nomem ("", GF_LOG_ALERT, (cnt * size));
-
- return ptr;
-}
-
-static inline
-void* __gf_default_realloc (void *oldptr, size_t size)
-{
- void *ptr = NULL;
-
- ptr = realloc (oldptr, size);
- if (!ptr)
- gf_msg_nomem ("", GF_LOG_ALERT, size);
-
- return ptr;
-}
-
-#define MALLOC(size) __gf_default_malloc(size)
-#define CALLOC(cnt,size) __gf_default_calloc(cnt,size)
-#define REALLOC(ptr,size) __gf_default_realloc(ptr,size)
-
-#define FREE(ptr) \
- do { \
- if (ptr != NULL) { \
- free ((void *)ptr); \
- ptr = (void *)0xeeeeeeee; \
- } \
- } while (0)
-
-#define GF_CALLOC(nmemb, size, type) __gf_calloc (nmemb, size, type, #type)
-
-#define GF_MALLOC(size, type) __gf_malloc (size, type, #type)
-
-#define GF_REALLOC(ptr, size) __gf_realloc (ptr, size)
-
-#define GF_FREE(free_ptr) __gf_free (free_ptr)
-
-static inline
-char *gf_strndup (const char *src, size_t len)
-{
- char *dup_str = NULL;
-
- if (!src) {
- goto out;
- }
-
- dup_str = GF_CALLOC (1, len + 1, gf_common_mt_strdup);
- if (!dup_str) {
- goto out;
- }
-
- memcpy (dup_str, src, len);
-out:
- return dup_str;
-}
-
-static inline
-char * gf_strdup (const char *src)
-{
-
- char *dup_str = NULL;
- size_t len = 0;
-
- len = strlen (src) + 1;
-
- dup_str = GF_CALLOC(1, len, gf_common_mt_strdup);
-
- if (!dup_str)
- return NULL;
-
- memcpy (dup_str, src, len);
-
- return dup_str;
-}
-
-static inline void *
-gf_memdup (const void *src, size_t size)
-{
- void *dup_mem = NULL;
-
- dup_mem = GF_CALLOC(1, size, gf_common_mt_strdup);
- if (!dup_mem)
- goto out;
-
- memcpy (dup_mem, src, size);
-
-out:
- return dup_mem;
-}
-
-struct mem_pool {
- struct list_head list;
- int hot_count;
- int cold_count;
- gf_lock_t lock;
- unsigned long padded_sizeof_type;
- 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, char *name);
-
-#define mem_pool_new(type,count) mem_pool_new_fn (sizeof(type), count, #type)
-
-void mem_put (void *ptr);
-void *mem_get (struct mem_pool *pool);
-void *mem_get0 (struct mem_pool *pool);
-
-void mem_pool_destroy (struct mem_pool *pool);
-
-void gf_mem_acct_enable_set (void *ctx);
-
-#endif /* _MEM_POOL_H */
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h
deleted file mode 100644
index 84949c61487..00000000000
--- a/libglusterfs/src/mem-types.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- 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_TYPES_H__
-#define __MEM_TYPES_H__
-
-
-enum gf_common_mem_types_ {
- gf_common_mt_call_stub_t,
- gf_common_mt_dnscache6,
- gf_common_mt_data_pair_t,
- gf_common_mt_data_t,
- gf_common_mt_dict_t,
- gf_common_mt_event_pool,
- gf_common_mt_reg,
- gf_common_mt_pollfd,
- gf_common_mt_epoll_event,
- gf_common_mt_fdentry_t,
- gf_common_mt_fdtable_t,
- gf_common_mt_fd_t,
- gf_common_mt_fd_ctx,
- gf_common_mt_gf_dirent_t,
- gf_common_mt_glusterfs_ctx_t,
- gf_common_mt_dentry_t,
- gf_common_mt_inode_t,
- gf_common_mt_inode_ctx,
- gf_common_mt_list_head,
- gf_common_mt_inode_table_t,
- gf_common_mt_xlator_t,
- gf_common_mt_xlator_list_t,
- gf_common_mt_log_msg,
- gf_common_mt_client_log,
- gf_common_mt_volume_opt_list_t,
- gf_common_mt_gf_hdr_common_t,
- gf_common_mt_call_frame_t,
- gf_common_mt_call_stack_t,
- gf_common_mt_gf_timer_t,
- gf_common_mt_gf_timer_registry_t,
- gf_common_mt_transport,
- gf_common_mt_transport_msg,
- gf_common_mt_auth_handle_t,
- gf_common_mt_iobuf,
- gf_common_mt_iobuf_arena,
- gf_common_mt_iobref,
- gf_common_mt_iobuf_pool,
- gf_common_mt_iovec,
- gf_common_mt_memdup,
- gf_common_mt_asprintf,
- gf_common_mt_strdup,
- gf_common_mt_socket_private_t,
- gf_common_mt_ioq,
- gf_common_mt_transport_t,
- gf_common_mt_socket_local_t,
- gf_common_mt_char,
- gf_common_mt_rbthash_table_t,
- gf_common_mt_rbthash_bucket,
- gf_common_mt_mem_pool,
- gf_common_mt_long,
- gf_common_mt_rpcsvc_auth_list,
- gf_common_mt_rpcsvc_t,
- gf_common_mt_rpcsvc_conn_t,
- gf_common_mt_rpcsvc_program_t,
- gf_common_mt_rpcsvc_listener_t,
- gf_common_mt_rpcsvc_wrapper_t,
- gf_common_mt_rpcsvc_stage_t,
- gf_common_mt_rpcclnt_t,
- gf_common_mt_rpcclnt_savedframe_t,
- gf_common_mt_rpc_trans_t,
- gf_common_mt_rpc_trans_pollin_t,
- gf_common_mt_rpc_trans_handover_t,
- gf_common_mt_rpc_trans_reqinfo_t,
- gf_common_mt_rpc_trans_rsp_t,
- gf_common_mt_glusterfs_graph_t,
- gf_common_mt_rdma_private_t,
- gf_common_mt_rdma_ioq_t,
- gf_common_mt_rpc_transport_t,
- gf_common_mt_rdma_local_t,
- gf_common_mt_rdma_post_t,
- gf_common_mt_qpent,
- gf_common_mt_rdma_device_t,
- gf_common_mt_rdma_context_t,
- gf_common_mt_sge,
- gf_common_mt_rpcclnt_cb_program_t,
- gf_common_mt_libxl_marker_local,
- gf_common_mt_graph_buf,
- gf_common_mt_trie_trie,
- gf_common_mt_trie_data,
- gf_common_mt_trie_node,
- gf_common_mt_trie_buf,
- gf_common_mt_trie_end,
- gf_common_mt_run_argv,
- gf_common_mt_run_logbuf,
- gf_common_mt_fd_lk_ctx_t,
- gf_common_mt_fd_lk_ctx_node_t,
- gf_common_mt_buffer_t,
- gf_common_mt_circular_buffer_t,
- gf_common_mt_eh_t,
- gf_common_mt_store_handle_t,
- gf_common_mt_store_iter_t,
- gf_common_mt_drc_client_t,
- gf_common_mt_drc_globals_t,
- gf_common_mt_drc_rbtree_node_t,
- gf_common_mt_iov_base_t,
- gf_common_mt_groups_t,
- gf_common_mt_cliententry_t,
- gf_common_mt_clienttable_t,
- gf_common_mt_client_t,
- gf_common_mt_client_ctx,
- gf_common_mt_lock_table,
- gf_common_mt_locker,
- gf_common_mt_auxgids,
- gf_common_mt_syncopctx,
- gf_common_mt_iobrefs,
- gf_common_mt_gsync_status_t,
- gf_common_mt_uuid_t,
- gf_common_mt_mgmt_v3_lock_obj_t,
- gf_common_mt_txn_opinfo_obj_t,
- gf_common_mt_strfd_t,
- gf_common_mt_strfd_data_t,
- gf_common_mt_regex_t,
- gf_common_mt_ereg,
- gf_common_mt_wr,
- gf_common_mt_rdma_arena_mr,
- gf_common_mt_parser_t,
- gf_common_quota_meta_t,
- /*related to gfdb library*/
- gfdb_mt_time_t,
- gf_mt_sql_cbk_args_t,
- gf_mt_gfdb_query_record_t,
- gf_mt_gfdb_link_info_t,
- gf_mt_gfdb_db_operations_t,
- gf_mt_sql_connection_t,
- gf_mt_sql_conn_node_t,
- gf_mt_db_conn_node_t,
- gf_mt_db_connection_t,
- gfdb_mt_db_record_t,
- /*related to gfdb library*/
- gf_common_mt_rbuf_t,
- gf_common_mt_rlist_t,
- gf_common_mt_rvec_t,
- /* glusterd can load the nfs-xlator dynamically and needs these two */
- gf_common_mt_nfs_netgroups,
- gf_common_mt_nfs_exports,
- gf_common_mt_gf_brick_spec_t,
- gf_common_mt_gf_timer_entry_t,
- gf_common_mt_int,
- gf_common_mt_pointer,
- gf_common_mt_synctask,
- gf_common_mt_syncstack,
- gf_common_mt_syncenv,
- gf_common_mt_end
-};
-#endif
diff --git a/libglusterfs/src/monitoring.c b/libglusterfs/src/monitoring.c
new file mode 100644
index 00000000000..fbb68dc8622
--- /dev/null
+++ b/libglusterfs/src/monitoring.c
@@ -0,0 +1,282 @@
+/*
+ Copyright (c) 2017 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 "glusterfs/monitoring.h"
+#include "glusterfs/xlator.h"
+#include "glusterfs/syscall.h"
+
+#include <stdlib.h>
+
+static void
+dump_mem_acct_details(xlator_t *xl, int fd)
+{
+ struct mem_acct_rec *mem_rec;
+ int i = 0;
+
+ if (!xl || !xl->mem_acct || (xl->ctx->active != xl->graph))
+ return;
+
+ dprintf(fd, "# %s.%s.total.num_types %d\n", xl->type, xl->name,
+ xl->mem_acct->num_types);
+
+ dprintf(fd,
+ "# type, in-use-size, in-use-units, max-size, "
+ "max-units, total-allocs\n");
+
+ for (i = 0; i < xl->mem_acct->num_types; i++) {
+ mem_rec = &xl->mem_acct->rec[i];
+ if (mem_rec->num_allocs == 0)
+ continue;
+ dprintf(fd, "# %s, %" PRIu64 ", %u, %" PRIu64 ", %u, %" PRIu64 "\n",
+ mem_rec->typestr, mem_rec->size, mem_rec->num_allocs,
+ mem_rec->max_size, mem_rec->max_num_allocs,
+ mem_rec->total_allocs);
+ }
+}
+
+static void
+dump_global_memory_accounting(int fd)
+{
+#if MEMORY_ACCOUNTING_STATS
+ int i = 0;
+ uint64_t count = 0;
+
+ uint64_t tcalloc = GF_ATOMIC_GET(gf_memory_stat_counts.total_calloc);
+ uint64_t tmalloc = GF_ATOMIC_GET(gf_memory_stat_counts.total_malloc);
+ uint64_t tfree = GF_ATOMIC_GET(gf_memory_stat_counts.total_free);
+
+ dprintf(fd, "memory.total.calloc %lu\n", tcalloc);
+ dprintf(fd, "memory.total.malloc %lu\n", tmalloc);
+ dprintf(fd, "memory.total.realloc %lu\n",
+ GF_ATOMIC_GET(gf_memory_stat_counts.total_realloc));
+ dprintf(fd, "memory.total.free %lu\n", tfree);
+ dprintf(fd, "memory.total.in-use %lu\n", ((tcalloc + tmalloc) - tfree));
+
+ for (i = 0; i < GF_BLK_MAX_VALUE; i++) {
+ count = GF_ATOMIC_GET(gf_memory_stat_counts.blk_size[i]);
+ dprintf(fd, "memory.total.blk_size.%s %lu\n",
+ gf_mem_stats_blk[i].blk_size_str, count);
+ }
+
+ dprintf(fd, "#----\n");
+#endif
+
+ /* This is not a metric to be watched in admin guide,
+ but keeping it here till we resolve all leak-issues
+ would be great */
+}
+
+static void
+dump_latency_and_count(xlator_t *xl, int fd)
+{
+ int32_t index = 0;
+ uint64_t fop;
+ uint64_t cbk;
+ uint64_t count;
+
+ if (xl->winds) {
+ dprintf(fd, "%s.total.pending-winds.count %" PRIu64 "\n", xl->name,
+ xl->winds);
+ }
+
+ /* Need 'fuse' data, and don't need all the old graph info */
+ if ((xl != xl->ctx->master) && (xl->ctx->active != xl->graph))
+ return;
+
+ count = GF_ATOMIC_GET(xl->stats.total.count);
+ dprintf(fd, "%s.total.fop-count %" PRIu64 "\n", xl->name, count);
+
+ count = GF_ATOMIC_GET(xl->stats.interval.count);
+ dprintf(fd, "%s.interval.fop-count %" PRIu64 "\n", xl->name, count);
+ GF_ATOMIC_INIT(xl->stats.interval.count, 0);
+
+ for (index = 0; index < GF_FOP_MAXVALUE; index++) {
+ fop = GF_ATOMIC_GET(xl->stats.total.metrics[index].fop);
+ if (fop) {
+ dprintf(fd, "%s.total.%s.count %" PRIu64 "\n", xl->name,
+ gf_fop_list[index], fop);
+ }
+ fop = GF_ATOMIC_GET(xl->stats.interval.metrics[index].fop);
+ if (fop) {
+ dprintf(fd, "%s.interval.%s.count %" PRIu64 "\n", xl->name,
+ gf_fop_list[index], fop);
+ }
+ cbk = GF_ATOMIC_GET(xl->stats.interval.metrics[index].cbk);
+ if (cbk) {
+ dprintf(fd, "%s.interval.%s.fail_count %" PRIu64 "\n", xl->name,
+ gf_fop_list[index], cbk);
+ }
+ if (xl->stats.interval.latencies[index].count != 0) {
+ dprintf(fd, "%s.interval.%s.latency %lf\n", xl->name,
+ gf_fop_list[index],
+ (((double)xl->stats.interval.latencies[index].total) /
+ xl->stats.interval.latencies[index].count));
+ dprintf(fd, "%s.interval.%s.max %" PRIu64 "\n", xl->name,
+ gf_fop_list[index],
+ xl->stats.interval.latencies[index].max);
+ dprintf(fd, "%s.interval.%s.min %" PRIu64 "\n", xl->name,
+ gf_fop_list[index],
+ xl->stats.interval.latencies[index].min);
+ }
+ GF_ATOMIC_INIT(xl->stats.interval.metrics[index].cbk, 0);
+ GF_ATOMIC_INIT(xl->stats.interval.metrics[index].fop, 0);
+ }
+ memset(xl->stats.interval.latencies, 0,
+ sizeof(xl->stats.interval.latencies));
+}
+
+static inline void
+dump_call_stack_details(glusterfs_ctx_t *ctx, int fd)
+{
+ dprintf(fd, "total.stack.count %" PRIu64 "\n",
+ GF_ATOMIC_GET(ctx->pool->total_count));
+ dprintf(fd, "total.stack.in-flight %" PRIu64 "\n", ctx->pool->cnt);
+}
+
+static inline void
+dump_dict_details(glusterfs_ctx_t *ctx, int fd)
+{
+ uint64_t total_dicts = 0;
+ uint64_t total_pairs = 0;
+
+ total_dicts = GF_ATOMIC_GET(ctx->stats.total_dicts_used);
+ total_pairs = GF_ATOMIC_GET(ctx->stats.total_pairs_used);
+
+ dprintf(fd, "total.dict.max-pairs-per %" PRIu64 "\n",
+ GF_ATOMIC_GET(ctx->stats.max_dict_pairs));
+ dprintf(fd, "total.dict.pairs-used %" PRIu64 "\n", total_pairs);
+ dprintf(fd, "total.dict.used %" PRIu64 "\n", total_dicts);
+ dprintf(fd, "total.dict.average-pairs %" PRIu64 "\n",
+ (total_pairs / total_dicts));
+}
+
+static void
+dump_inode_stats(glusterfs_ctx_t *ctx, int fd)
+{
+}
+
+static void
+dump_global_metrics(glusterfs_ctx_t *ctx, int fd)
+{
+ struct timeval tv;
+ time_t nowtime;
+ struct tm *nowtm;
+ char tmbuf[64] = {
+ 0,
+ };
+
+ gettimeofday(&tv, NULL);
+ nowtime = tv.tv_sec;
+ nowtm = localtime(&nowtime);
+ strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", nowtm);
+
+ /* Let every file have information on which process dumped info */
+ dprintf(fd, "## %s\n", ctx->cmdlinestr);
+ dprintf(fd, "### %s\n", tmbuf);
+ dprintf(fd, "### BrickName: %s\n", ctx->cmd_args.brick_name);
+ dprintf(fd, "### MountName: %s\n", ctx->cmd_args.mount_point);
+ dprintf(fd, "### VolumeName: %s\n", ctx->cmd_args.volume_name);
+
+ /* Dump memory accounting */
+ dump_global_memory_accounting(fd);
+ dprintf(fd, "# -----\n");
+
+ dump_call_stack_details(ctx, fd);
+ dump_dict_details(ctx, fd);
+ dprintf(fd, "# -----\n");
+
+ dump_inode_stats(ctx, fd);
+ dprintf(fd, "# -----\n");
+}
+
+static void
+dump_xl_metrics(glusterfs_ctx_t *ctx, int fd)
+{
+ xlator_t *xl;
+
+ xl = ctx->active->top;
+
+ while (xl) {
+ dump_latency_and_count(xl, fd);
+ dump_mem_acct_details(xl, fd);
+ if (xl->dump_metrics)
+ xl->dump_metrics(xl, fd);
+ xl = xl->next;
+ }
+
+ if (ctx->master) {
+ xl = ctx->master;
+
+ dump_latency_and_count(xl, fd);
+ dump_mem_acct_details(xl, fd);
+ if (xl->dump_metrics)
+ xl->dump_metrics(xl, fd);
+ }
+
+ return;
+}
+
+char *
+gf_monitor_metrics(glusterfs_ctx_t *ctx)
+{
+ int ret = -1;
+ int fd = 0;
+ char *filepath = NULL, *dumppath = NULL;
+
+ gf_msg_trace("monitoring", 0, "received monitoring request (sig:USR2)");
+
+ dumppath = ctx->config.metrics_dumppath;
+ if (dumppath == NULL) {
+ dumppath = GLUSTER_METRICS_DIR;
+ }
+ ret = mkdir_p(dumppath, 0755, true);
+ if (ret) {
+ /* EEXIST is handled in mkdir_p() itself */
+ gf_msg("monitoring", GF_LOG_ERROR, 0, LG_MSG_STRDUP_ERROR,
+ "failed to create metrics dir %s (%s)", dumppath,
+ strerror(errno));
+ return NULL;
+ }
+
+ ret = gf_asprintf(&filepath, "%s/gmetrics.XXXXXX", dumppath);
+ if (ret < 0) {
+ return NULL;
+ }
+
+ /* coverity[secure_temp] mkstemp uses 0600 as the mode and is safe */
+ fd = mkstemp(filepath);
+ if (fd < 0) {
+ gf_msg("monitoring", GF_LOG_ERROR, 0, LG_MSG_STRDUP_ERROR,
+ "failed to open tmp file %s (%s)", filepath, strerror(errno));
+ GF_FREE(filepath);
+ return NULL;
+ }
+
+ dump_global_metrics(ctx, fd);
+
+ dump_xl_metrics(ctx, fd);
+
+ /* This below line is used just to capture any errors with dprintf() */
+ ret = dprintf(fd, "\n# End of metrics\n");
+ if (ret < 0) {
+ gf_msg("monitoring", GF_LOG_WARNING, 0, LG_MSG_STRDUP_ERROR,
+ "dprintf() failed: %s", strerror(errno));
+ }
+
+ ret = sys_fsync(fd);
+ if (ret < 0) {
+ gf_msg("monitoring", GF_LOG_WARNING, 0, LG_MSG_STRDUP_ERROR,
+ "fsync() failed: %s", strerror(errno));
+ }
+ sys_close(fd);
+
+ /* Figure this out, not happy with returning this string */
+ return filepath;
+}
diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c
index c8f2585ae2b..f6b5aa0ea23 100644
--- a/libglusterfs/src/options.c
+++ b/libglusterfs/src/options.c
@@ -10,1199 +10,1212 @@
#include <fnmatch.h>
-#include "xlator.h"
-#include "defaults.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/xlator.h"
+#include "glusterfs/defaults.h"
+#include "glusterfs/libglusterfs-messages.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)
+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_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%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_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- goto out;
- }
-
- ret = 0;
+ int ret = -1;
+ char errstr[256];
+
+ if (strstr(value, "../")) {
+ snprintf(errstr, 256, "invalid path given '%s'", value);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ 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_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ ret = 0;
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
- return ret;
+ 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)
+xlator_option_validate_int(xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
{
- long long inputll = 0;
- unsigned long long uinputll = 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_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- goto out;
- }
-
- /* Handle '-0' */
- if ((inputll == 0) && (gf_string2ulonglong (value, &uinputll) != 0)) {
- snprintf (errstr, 256,
- "invalid number format \"%s\" in option \"%s\"",
- value, key);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0) &&
- (opt->validate == GF_OPT_VALIDATE_BOTH)) {
- gf_msg_trace (xl->name, 0, "no range check required for "
- "'option %s %s'", key, value);
- ret = 0;
- goto out;
+ long long inputll = 0;
+ unsigned long long uinputll = 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_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ /* Handle '-0' */
+ if ((inputll == 0) && (gf_string2ulonglong(value, &uinputll) != 0)) {
+ snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"",
+ value, key);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0) &&
+ (opt->validate == GF_OPT_VALIDATE_BOTH)) {
+ gf_msg_trace(xl->name, 0,
+ "no range check required for "
+ "'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+
+ if (opt->validate == GF_OPT_VALIDATE_MIN) {
+ if (inputll < opt->min) {
+ snprintf(errstr, 256,
+ "'%lld' in 'option %s %s' is smaller than "
+ "minimum value '%.0f'",
+ inputll, key, value, opt->min);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
}
-
- if (opt->validate == GF_OPT_VALIDATE_MIN) {
- if (inputll < opt->min) {
- snprintf (errstr, 256,
- "'%lld' in 'option %s %s' is smaller than "
- "minimum value '%.0f'", inputll, key,
- value, opt->min);
- gf_msg (xl->name, GF_LOG_ERROR, 0,
- LG_MSG_INVALID_ENTRY, "%s", errstr);
- goto out;
- }
- } else if (opt->validate == GF_OPT_VALIDATE_MAX) {
- if (inputll > opt->max) {
- snprintf (errstr, 256,
- "'%lld' in 'option %s %s' is greater than "
- "maximum value '%.0f'", inputll, key,
- value, opt->max);
- gf_msg (xl->name, GF_LOG_ERROR, 0,
- LG_MSG_INVALID_ENTRY, "%s", errstr);
- goto out;
- }
- } else if ((inputll < opt->min) || (inputll > opt->max)) {
- snprintf (errstr, 256,
- "'%lld' in 'option %s %s' is out of range "
- "[%.0f - %.0f]",
- inputll, key, value, opt->min, opt->max);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s",
- errstr);
- goto out;
+ } else if (opt->validate == GF_OPT_VALIDATE_MAX) {
+ if (inputll > opt->max) {
+ snprintf(errstr, 256,
+ "'%lld' in 'option %s %s' is greater than "
+ "maximum value '%.0f'",
+ inputll, key, value, opt->max);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
}
-
- ret = 0;
+ } else if ((inputll < opt->min) || (inputll > opt->max)) {
+ snprintf(errstr, 256,
+ "'%lld' in 'option %s %s' is out of range "
+ "[%.0f - %.0f]",
+ inputll, key, value, opt->min, opt->max);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ ret = 0;
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
- return ret;
+ 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)
+xlator_option_validate_sizet(xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
{
- size_t size = 0;
- int ret = 0;
- char errstr[256];
-
- /* Check the range */
- if (gf_string2bytesize_size (value, &size) != 0) {
- snprintf (errstr, 256,
- "invalid number format \"%s\" in option \"%s\"",
- value, key);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- ret = -1;
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_msg_trace (xl->name, 0, "no range check required for "
- "'option %s %s'", key, value);
- goto out;
- }
-
- if ((size < opt->min) || (size > opt->max)) {
- if ((strncmp (key, "cache-size", 10) == 0) &&
- (size > opt->max)) {
- snprintf (errstr, 256, "Cache size %" GF_PRI_SIZET " is out of "
- "range [%.0f - %.0f]",
- size, opt->min, opt->max);
- gf_msg (xl->name, GF_LOG_WARNING, 0,
- LG_MSG_OUT_OF_RANGE, "%s", errstr);
- } else {
- snprintf (errstr, 256,
- "'%" GF_PRI_SIZET "' in 'option %s %s' "
- "is out of range [%.0f - %.0f]",
- size, key, value, opt->min, opt->max);
- gf_msg (xl->name, GF_LOG_ERROR, 0,
- LG_MSG_OUT_OF_RANGE, "%s", errstr);
- ret = -1;
- }
- }
+ uint64_t size = 0;
+ int ret = 0;
+ char errstr[256];
+
+ /* Check the range */
+ if (gf_string2bytesize_uint64(value, &size) != 0) {
+ snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"",
+ value, key);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ ret = -1;
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_msg_trace(xl->name, 0,
+ "no range check required for "
+ "'option %s %s'",
+ key, value);
+ goto out;
+ }
+
+ if ((size < opt->min) || (size > opt->max)) {
+ snprintf(errstr, 256,
+ "'%" PRIu64
+ "' in 'option %s %s' is out of range [%.0f - %.0f]",
+ size, key, value, opt->min, opt->max);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s",
+ errstr, NULL);
+ ret = -1;
+ }
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
- return ret;
+ 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)
+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 is_valid;
-
-
- /* Check if the value is one of
- '0|1|on|off|no|yes|true|false|enable|disable' */
-
- if (gf_string2boolean (value, &is_valid) != 0) {
- snprintf (errstr, 256,
- "option %s %s: '%s' is not a valid boolean value",
- key, value, value);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- goto out;
- }
-
- ret = 0;
+ int ret = -1;
+ char errstr[256];
+ gf_boolean_t is_valid;
+
+ /* Check if the value is one of
+ '0|1|on|off|no|yes|true|false|enable|disable' */
+
+ if (gf_string2boolean(value, &is_valid) != 0) {
+ snprintf(errstr, 256, "option %s %s: '%s' is not a valid boolean value",
+ key, value, value);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ ret = 0;
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
- return ret;
+ 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)
+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;
+ 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;
}
-
- if (!xlopt) {
- snprintf (errstr, 256,
- "option %s %s: '%s' is not a valid volume name",
- key, value, value);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- goto out;
- }
-
- ret = 0;
+ xlopt = xlopt->next;
+ }
+
+ if (!xlopt) {
+ snprintf(errstr, 256, "option %s %s: '%s' is not a valid volume name",
+ key, value, value);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ ret = 0;
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
- return ret;
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup(errstr);
+ return ret;
}
-void
-set_error_str (char *errstr, size_t len, volume_option_t *opt, const char *key,
- const char *value)
+static void
+set_error_str(char *errstr, size_t len, volume_option_t *opt, const char *key,
+ const char *value)
{
- int i = 0;
- char given_array[4096] = {0,};
-
- 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, len, "option %s %s: '%s' is not valid "
- "(possible options are %s)", key, value, value, given_array);
- return;
+ int i = 0;
+ int ret = 0;
+
+ ret = snprintf(errstr, len,
+ "option %s %s: '%s' is not valid "
+ "(possible options are ",
+ key, value, value);
+
+ for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i];) {
+ ret += snprintf(errstr + ret, len - ret, "%s", opt->value[i]);
+ if (((++i) < ZR_OPTION_MAX_ARRAY_SIZE) && (opt->value[i]))
+ ret += snprintf(errstr + ret, len - ret, ", ");
+ else
+ ret += snprintf(errstr + ret, len - ret, ".)");
+ }
+ return;
}
-int
-is_all_whitespaces (const char *value)
+static int
+is_all_whitespaces(const char *value)
{
- int i = 0;
- size_t len = 0;
+ int i = 0;
- if (value == NULL)
- return -1;
+ if (value == NULL)
+ return -1;
- len = strlen (value);
+ for (i = 0; value[i] != '\0'; i++) {
+ if (value[i] == ' ')
+ continue;
+ else
+ return 0;
+ }
- for (i = 0; i < len; i++) {
- if (value[i] == ' ')
- continue;
- else
- return 0;
- }
-
- return 1;
+ return 1;
}
static int
-xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
- volume_option_t *opt, char **op_errstr)
+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[4096] = {0,};
-
- /* Check if the '*str' is valid */
- if (GF_OPTION_LIST_EMPTY(opt)) {
- ret = 0;
- goto out;
- }
-
- if (is_all_whitespaces (value) == 1)
- 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]))
- goto out;
- /* 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.
- */
+ int ret = -1;
+ int i = 0;
+ /* Check if the '*str' is valid */
+ if (GF_OPTION_LIST_EMPTY(opt)) {
ret = 0;
+ goto out;
+ }
-out:
- if (ret) {
- set_error_str (errstr, sizeof (errstr), opt, key, value);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- if (op_errstr)
- *op_errstr = gf_strdup (errstr);
- }
- return ret;
-}
-
+ if (is_all_whitespaces(value) == 1)
+ goto out;
-static int
-xlator_option_validate_percent (xlator_t *xl, const char *key, const char *value,
- volume_option_t *opt, char **op_errstr)
-{
- double percent = 0;
- int ret = -1;
- char errstr[256];
-
- /* 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_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- 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;
}
-
- if ((percent < 0.0) || (percent > 100.0)) {
- snprintf (errstr, 256,
- "'%lf' in 'option %s %s' is out of range [0 - 100]",
- percent, key, value);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s",
- errstr);
- goto out;
+#else
+ if (fnmatch(opt->value[i], value, FNM_EXTMATCH) == 0) {
+ ret = 0;
+ break;
}
+#endif
+ }
+
+ if ((i == ZR_OPTION_MAX_ARRAY_SIZE) || (!opt->value[i]))
+ goto out;
+ /* 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.
+ */
+
+ ret = 0;
- ret = 0;
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
- return ret;
+ if (ret) {
+ char errstr[4096];
+ set_error_str(errstr, sizeof(errstr), opt, key, value);
+
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ if (op_errstr)
+ *op_errstr = gf_strdup(errstr);
+ }
+ return ret;
}
static int
-xlator_option_validate_fractional_value (const char *value)
+xlator_option_validate_percent(xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
{
- const char *s = NULL;
- int ret = 0;
-
- s = strchr (value, '.');
- if (s) {
- for (s = s+1; *s != '\0'; s++) {
- if (*s != '0') {
- return -1;
- }
- }
- }
-
- return ret;
+ double percent = 0;
+ int ret = -1;
+ char errstr[256];
+
+ /* 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_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ if ((percent < 0.0) || (percent > 100.0)) {
+ snprintf(errstr, 256,
+ "'%lf' in 'option %s %s' is out of range [0 - 100]", percent,
+ key, value);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s",
+ errstr, NULL);
+ 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)
+xlator_option_validate_fractional_value(const char *value)
{
- int ret = -1;
- char errstr[256];
- double size = 0;
- gf_boolean_t is_percent = _gf_false;
-
- if (gf_string2percent_or_bytesize (value, &size, &is_percent) == 0) {
- if (is_percent) {
- if ((size < 0.0) || (size > 100.0)) {
- snprintf (errstr, sizeof (errstr),
- "'%lf' in 'option %s %s' is out"
- " of range [0 - 100]", size, key,
- value);
- gf_msg (xl->name, GF_LOG_ERROR, 0,
- LG_MSG_OUT_OF_RANGE, "%s", errstr);
- goto out;
- }
- ret = 0;
- goto out;
- }
-
- /*Input value of size(in byte) should not be fractional*/
- ret = xlator_option_validate_fractional_value (value);
- if (ret) {
- snprintf (errstr, sizeof (errstr), "'%lf' in 'option %s"
- " %s' should not be fractional value. Use "
- "valid unsigned integer value.", size, key,
- value);
- gf_msg (xl->name, GF_LOG_ERROR, 0,
- LG_MSG_INVALID_ENTRY, "%s", errstr);
- goto out;
- }
-
- /* Check the range */
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_msg_trace (xl->name, 0, "no range check required "
- "for 'option %s %s'", key, value);
- ret = 0;
- goto out;
- }
- if ((size < opt->min) || (size > opt->max)) {
- snprintf (errstr, 256,
- "'%lf' in 'option %s %s'"
- " is out of range [%.0f - %.0f]",
- size, key, value, opt->min, opt->max);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE,
- "%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_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
+ const char *s = NULL;
+ int ret = 0;
+ s = strchr(value, '.');
+ if (s) {
+ for (s = s + 1; *s != '\0'; s++) {
+ if (*s != '0') {
+ return -1;
+ }
+ }
+ }
-out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
- return ret;
+ return ret;
}
-
static int
-xlator_option_validate_time (xlator_t *xl, const char *key, const char *value,
- volume_option_t *opt, char **op_errstr)
+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];
- 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_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
+ int ret = -1;
+ char errstr[256];
+ double size = 0;
+ gf_boolean_t is_percent = _gf_false;
+
+ if (gf_string2percent_or_bytesize(value, &size, &is_percent) == 0) {
+ if (is_percent) {
+ if ((size < 0.0) || (size > 100.0)) {
+ snprintf(errstr, sizeof(errstr),
+ "'%lf' in 'option %s %s' is out"
+ " of range [0 - 100]",
+ size, key, value);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE,
+ "error=%s", errstr, NULL);
goto out;
+ }
+ ret = 0;
+ goto out;
}
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_msg_trace (xl->name, 0, "no range check required for "
- "'option %s %s'", key, value);
- ret = 0;
- goto out;
+ /*Input value of size(in byte) should not be fractional*/
+ ret = xlator_option_validate_fractional_value(value);
+ if (ret) {
+ snprintf(errstr, sizeof(errstr),
+ "'%lf' in 'option %s"
+ " %s' should not be fractional value. Use "
+ "valid unsigned integer value.",
+ size, key, value);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
}
- if ((input_time < opt->min) || (input_time > opt->max)) {
- snprintf (errstr, 256,
- "'%"PRIu32"' in 'option %s %s' is "
- "out of range [%.0f - %.0f]",
- input_time, key, value,
- opt->min, opt->max);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s",
- errstr);
- goto out;
+ /* Check the range */
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_msg_trace(xl->name, 0,
+ "no range check required "
+ "for 'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+ if ((size < opt->min) || (size > opt->max)) {
+ snprintf(errstr, 256,
+ "'%lf' in 'option %s %s'"
+ " is out of range [%.0f - %.0f]",
+ size, key, value, opt->min, opt->max);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s",
+ errstr, NULL);
+ 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_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s", errstr,
+ NULL);
+
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
- return ret;
+ 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)
+xlator_option_validate_time(xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
{
- double input = 0.0;
- int ret = -1;
- char errstr[256];
-
- /* Check the range */
- if (gf_string2double (value, &input) != 0) {
- snprintf (errstr, 256,
- "invalid number format \"%s\" in option \"%s\"",
- value, key);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- goto out;
- }
+ 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_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0)) {
+ gf_msg_trace(xl->name, 0,
+ "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 [%.0f - %.0f]",
+ input_time, key, value, opt->min, opt->max);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret && op_errstr)
+ *op_errstr = gf_strdup(errstr);
+ return ret;
+}
- if ((opt->min == 0) && (opt->max == 0) &&
- (opt->validate == GF_OPT_VALIDATE_BOTH)) {
- gf_msg_trace (xl->name, 0, "no range check required for "
- "'option %s %s'", key, value);
- ret = 0;
- goto out;
+static int
+xlator_option_validate_double(xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
+{
+ double input = 0.0;
+ int ret = -1;
+ char errstr[256];
+
+ /* Check the range */
+ if (gf_string2double(value, &input) != 0) {
+ snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"",
+ value, key);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ if ((opt->min == 0) && (opt->max == 0) &&
+ (opt->validate == GF_OPT_VALIDATE_BOTH)) {
+ gf_msg_trace(xl->name, 0,
+ "no range check required for "
+ "'option %s %s'",
+ key, value);
+ ret = 0;
+ goto out;
+ }
+
+ if (opt->validate == GF_OPT_VALIDATE_MIN) {
+ if (input < opt->min) {
+ snprintf(errstr, 256,
+ "'%f' in 'option %s %s' is smaller than "
+ "minimum value '%f'",
+ input, key, value, opt->min);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
}
-
- if (opt->validate == GF_OPT_VALIDATE_MIN) {
- if (input < opt->min) {
- snprintf (errstr, 256,
- "'%f' in 'option %s %s' is smaller than "
- "minimum value '%f'", input, key,
- value, opt->min);
- gf_msg (xl->name, GF_LOG_ERROR, 0,
- LG_MSG_INVALID_ENTRY, "%s", errstr);
- goto out;
- }
- } else if (opt->validate == GF_OPT_VALIDATE_MAX) {
- if (input > opt->max) {
- snprintf (errstr, 256,
- "'%f' in 'option %s %s' is greater than "
- "maximum value '%f'", input, key,
- value, opt->max);
- gf_msg (xl->name, GF_LOG_ERROR, 0,
- LG_MSG_INVALID_ENTRY, "%s", errstr);
- goto out;
- }
- } else if ((input < opt->min) || (input > opt->max)) {
- snprintf (errstr, 256,
- "'%f' in 'option %s %s' is out of range "
- "[%f - %f]",
- input, key, value, opt->min, opt->max);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s",
- errstr);
- goto out;
+ } else if (opt->validate == GF_OPT_VALIDATE_MAX) {
+ if (input > opt->max) {
+ snprintf(errstr, 256,
+ "'%f' in 'option %s %s' is greater than "
+ "maximum value '%f'",
+ input, key, value, opt->max);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ goto out;
}
-
- ret = 0;
+ } else if ((input < opt->min) || (input > opt->max)) {
+ snprintf(errstr, 256,
+ "'%f' in 'option %s %s' is out of range "
+ "[%f - %f]",
+ input, key, value, opt->min, opt->max);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "error=%s",
+ errstr, NULL);
+ goto out;
+ }
+
+ ret = 0;
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
- return ret;
+ 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)
+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_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- if (op_errstr)
- *op_errstr = gf_strdup (errstr);
- }
+ int ret = -1;
+ char errstr[256];
- ret = 0;
+ if (!valid_internet_address((char *)value, _gf_false, _gf_false)) {
+ snprintf(errstr, 256, "option %s %s: Can not parse %s address", key,
+ value, value);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ if (op_errstr)
+ *op_errstr = gf_strdup(errstr);
+ }
- return ret;
+ 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
+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[4096] = {0,};
-
- dup_val = gf_strdup (value);
- if (!dup_val)
- goto out;
-
- addr_tok = strtok_r (dup_val, ",", &save_ptr);
- if (addr_tok == NULL)
- goto out;
+ int ret = -1;
+ char *dup_val = NULL;
+ char *addr_tok = NULL;
+ char *save_ptr = NULL;
+ char *entry = NULL;
+ char *entry_ptr = NULL;
+ char *dir_and_addr = NULL;
+ char *addr_ptr = NULL;
+ char *addr_list = NULL;
+ char *addr = NULL;
+ char *dir = NULL;
+
+ dup_val = gf_strdup(value);
+ if (!dup_val)
+ goto out;
+
+ if (dup_val[0] != '/' && !strchr(dup_val, '(')) {
+ /* Possible old format, handle it for back-ward compatibility */
+ addr_tok = strtok_r(dup_val, ",", &save_ptr);
while (addr_tok) {
- if (!valid_internet_address (addr_tok, _gf_true))
- goto out;
+ if (!valid_internet_address(addr_tok, _gf_true, _gf_true))
+ goto out;
- addr_tok = strtok_r (NULL, ",", &save_ptr);
+ addr_tok = strtok_r(NULL, ",", &save_ptr);
}
ret = 0;
-
-out:
- if (ret) {
- snprintf (errstr, sizeof (errstr), "option %s %s: '%s' is not "
- "a valid internet-address-list", key, value, value);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- if (op_errstr)
- *op_errstr = gf_strdup (errstr);
+ goto out;
+ }
+
+ /* Lets handle the value with new format */
+ entry = strtok_r(dup_val, ",", &entry_ptr);
+ while (entry) {
+ dir_and_addr = gf_strdup(entry);
+ if (!dir_and_addr)
+ goto out;
+
+ dir = strtok_r(dir_and_addr, "(", &addr_ptr);
+ if (dir[0] != '/') {
+ /* Valid format should be starting from '/' */
+ goto out;
}
- GF_FREE (dup_val);
-
- return ret;
-}
+ /* dir = strtok_r (NULL, " =", &addr_tmp); */
+ addr = strtok_r(NULL, ")", &addr_ptr);
+ if (!addr)
+ goto out;
-static int
-xlator_option_validate_mntauth (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[4096] = {0,};
-
- dup_val = gf_strdup (value);
- if (!dup_val)
- goto out;
+ addr_list = gf_strdup(addr);
+ if (!addr_list)
+ goto out;
- addr_tok = strtok_r (dup_val, ",", &save_ptr);
+ /* This format be separated by '|' */
+ addr_tok = strtok_r(addr_list, "|", &save_ptr);
if (addr_tok == NULL)
- goto out;
+ goto out;
while (addr_tok) {
- if (!valid_mount_auth_address (addr_tok))
- goto out;
+ if (!valid_internet_address(addr_tok, _gf_true, _gf_true))
+ goto out;
- addr_tok = strtok_r (NULL, ",", &save_ptr);
+ addr_tok = strtok_r(NULL, "|", &save_ptr);
}
- ret = 0;
+ entry = strtok_r(NULL, ",", &entry_ptr);
+ GF_FREE(dir_and_addr);
+ GF_FREE(addr_list);
+ addr_list = NULL;
+ dir_and_addr = NULL;
+ }
+
+ ret = 0;
out:
- if (ret) {
- snprintf (errstr, sizeof (errstr), "option %s %s: '%s' is not "
- "a valid mount-auth-address", key, value, value);
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
- errstr);
- if (op_errstr)
- *op_errstr = gf_strdup (errstr);
- }
- GF_FREE (dup_val);
+ if (ret) {
+ char errstr[4096];
+ snprintf(errstr, sizeof(errstr),
+ "option %s %s: '%s' is not "
+ "a valid internet-address-list",
+ key, value, value);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ if (op_errstr)
+ *op_errstr = gf_strdup(errstr);
+ }
+ GF_FREE(dup_val);
+ GF_FREE(dir_and_addr);
+ GF_FREE(addr_list);
+ return ret;
+}
- return ret;
+static int
+xlator_option_validate_mntauth(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;
+
+ dup_val = gf_strdup(value);
+ if (!dup_val)
+ goto out;
+
+ addr_tok = strtok_r(dup_val, ",", &save_ptr);
+ if (addr_tok == NULL)
+ goto out;
+ while (addr_tok) {
+ if (!valid_mount_auth_address(addr_tok))
+ goto out;
+
+ addr_tok = strtok_r(NULL, ",", &save_ptr);
+ }
+ ret = 0;
+
+out:
+ if (ret) {
+ char errstr[4096];
+ snprintf(errstr, sizeof(errstr),
+ "option %s %s: '%s' is not "
+ "a valid mount-auth-address",
+ key, value, value);
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "error=%s",
+ errstr, NULL);
+ if (op_errstr)
+ *op_errstr = gf_strdup(errstr);
+ }
+ 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)
+gf_validate_size(const char *sizestr, volume_option_t *opt)
{
- size_t value = 0;
- int ret = 0;
+ uint64_t value = 0;
+ int ret = 0;
- GF_ASSERT (opt);
+ GF_ASSERT(opt);
- if (gf_string2bytesize_size (sizestr, &value) != 0 ||
- value < opt->min ||
- value % 512) {
- ret = -1;
- goto out;
- }
+ if (gf_string2bytesize_uint64(sizestr, &value) != 0 || value < opt->min ||
+ value % 512) {
+ ret = -1;
+ goto out;
+ }
- out:
- gf_msg_debug (THIS->name, 0, "Returning %d", ret);
- return ret;
+out:
+ gf_msg_debug(THIS->name, 0, "Returning %d", ret);
+ return ret;
}
static int
-gf_validate_number (const char *numstr, volume_option_t *opt)
+gf_validate_number(const char *numstr, volume_option_t *opt)
{
- int32_t value;
- return gf_string2int32 (numstr, &value);
+ 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 *))
+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);
- if (str_ptr == NULL) {
- ret = -1;
- goto out;
+ 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);
+ if (str_ptr == NULL) {
+ ret = -1;
+ goto out;
+ }
+ while (str_ptr) {
+ key = strtok_r(str_ptr, ":", &substr_sav);
+ if (!key || (key_validator && key_validator(key))) {
+ ret = -1;
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY,
+ "list=%s", string, "key=%s", key ? key : "", NULL);
+ goto out;
}
- while (str_ptr) {
-
- key = strtok_r (str_ptr, ":", &substr_sav);
- if (!key ||
- (key_validator && key_validator(key))) {
- ret = -1;
- gf_msg (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INVALID_ENTRY, "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_msg (THIS->name, GF_LOG_WARNING, 0,
- LG_MSG_INVALID_ENTRY, "invalid list '%s', "
- "value '%s' not valid.", string, key);
- goto out;
- }
-
- str_ptr = strtok_r (NULL, ",", &str_sav);
- substr_sav = NULL;
+
+ value = strtok_r(NULL, ":", &substr_sav);
+ if (!value || (value_validator && value_validator(value, opt))) {
+ ret = -1;
+ gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY,
+ "list=%s", string, "value=%s", key, NULL);
+ goto out;
}
- out:
- GF_FREE (dup_string);
- gf_msg_debug (THIS->name, 0, "Returning %d", ret);
- return ret;
+ str_ptr = strtok_r(NULL, ",", &str_sav);
+ substr_sav = NULL;
+ }
+
+out:
+ GF_FREE(dup_string);
+ gf_msg_debug(THIS->name, 0, "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)
+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;
+ 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)
+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;
-
+ 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)
+xlator_option_validate_any(xlator_t *xl, const char *key, const char *value,
+ volume_option_t *opt, char **op_errstr)
{
- return 0;
+ return 0;
}
-typedef int (xlator_option_validator_t) (xlator_t *xl, const char *key,
- const char *value,
- volume_option_t *opt, char **operrstr);
+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)
+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_CLIENT_AUTH_ADDR] = xlator_option_validate_mntauth,
- [GF_OPTION_TYPE_MAX] = NULL,
- };
-
- if (opt->type > GF_OPTION_TYPE_MAX) {
- gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
- "unknown option type '%d'", opt->type);
- goto out;
- }
-
- validate = validators[opt->type];
-
- ret = validate (xl, key, value, opt, 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_CLIENT_AUTH_ADDR] = xlator_option_validate_mntauth,
+ [GF_OPTION_TYPE_MAX] = NULL,
+ };
+
+ if (opt->type > GF_OPTION_TYPE_MAX) {
+ gf_smsg(xl->name, GF_LOG_ERROR, 0, LG_MSG_UNKNOWN_OPTION_TYPE,
+ "type=%d", opt->type, NULL);
+ goto out;
+ }
+
+ validate = validators[opt->type];
+
+ ret = validate(xl, key, value, opt, op_errstr);
out:
- return ret;
+ return ret;
}
-
volume_option_t *
-xlator_volume_option_get_list (volume_opt_list_t *vol_list, const char *key)
+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;
- }
- }
+ volume_option_t *opt = NULL;
+ volume_opt_list_t *opt_list = 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) {
+ return &opt[index];
+ }
}
-out:
- return found;
-}
+ }
+ return NULL;
+}
volume_option_t *
-xlator_volume_option_get (xlator_t *xl, const char *key)
+xlator_volume_option_get(xlator_t *xl, const char *key)
{
- volume_opt_list_t *vol_list = NULL;
- volume_option_t *found = NULL;
+ 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;
- }
+ list_for_each_entry(vol_list, &xl->volume_options, list)
+ {
+ found = xlator_volume_option_get_list(vol_list, key);
+ if (found)
+ break;
+ }
- return found;
+ return found;
}
-
static int
-xl_opt_validate (dict_t *dict, char *key, data_t *value, void *data)
+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 0;
-
- ret = xlator_option_validate (xl, key, value->data, opt, &errstr);
- if (ret)
- gf_msg (xl->name, GF_LOG_WARNING, 0, LG_MSG_VALIDATE_RETURNS,
- "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_msg (xl->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY,
- "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);
- }
+ 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 0;
-}
+ ret = xlator_option_validate(xl, key, value->data, opt, &errstr);
+ if (ret)
+ gf_smsg(xl->name, GF_LOG_WARNING, 0, LG_MSG_VALIDATE_RETURNS, "key=%s",
+ key, "ret=%d", ret, NULL);
+
+ if (errstr)
+ /* possible small leak of previously set stub->errstr */
+ stub->errstr = errstr;
+
+ if (fnmatch(opt->key[0], key, FNM_NOESCAPE) != 0) {
+ gf_smsg(xl->name, GF_LOG_DEBUG, 0, LG_MSG_OPTION_DEPRECATED, "key=%s",
+ key, "preferred=%s", opt->key[0], NULL);
+ dict_set(dict, opt->key[0], value);
+ dict_del(dict, key);
+ }
+ return 0;
+}
int
-xlator_options_validate_list (xlator_t *xl, dict_t *options,
- volume_opt_list_t *vol_opt, char **op_errstr)
+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 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)
+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_msg_debug (THIS->name, 0, "'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);
- }
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+
+ if (!xl) {
+ gf_msg_debug(THIS->name, 0, "'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;
+ return ret;
}
-
int
-xlator_validate_rec (xlator_t *xlator, char **op_errstr)
+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);
+ int ret = -1;
+ xlator_list_t *trav = NULL;
+ xlator_t *old_THIS = NULL;
- trav = xlator->children;
+ GF_VALIDATE_OR_GOTO("xlator", xlator, out);
- while (trav) {
- if (xlator_validate_rec (trav->xlator, op_errstr)) {
- gf_msg ("xlator", GF_LOG_WARNING, 0,
- LG_MSG_VALIDATE_REC_FAILED, "validate_rec "
- "failed");
- goto out;
- }
+ trav = xlator->children;
- trav = trav->next;
+ while (trav) {
+ if (xlator_validate_rec(trav->xlator, op_errstr)) {
+ gf_smsg("xlator", GF_LOG_WARNING, 0, LG_MSG_VALIDATE_REC_FAILED,
+ NULL);
+ goto out;
}
- if (xlator_dynload (xlator))
- gf_msg_debug (xlator->name, 0, "Did not load the symbols");
+ trav = trav->next;
+ }
- old_THIS = THIS;
- THIS = xlator;
+ if (xlator_dynload(xlator))
+ gf_msg_debug(xlator->name, 0, "Did not load the symbols");
- /* Need this here, as this graph has not yet called init() */
- if (!xlator->mem_acct) {
- if (!xlator->mem_acct_init)
- xlator->mem_acct_init = default_mem_acct_init;
- xlator->mem_acct_init (xlator);
- }
+ old_THIS = THIS;
+ THIS = xlator;
- ret = xlator_options_validate (xlator, xlator->options, op_errstr);
- THIS = old_THIS;
+ /* Need this here, as this graph has not yet called init() */
+ if (!xlator->mem_acct) {
+ if (!xlator->mem_acct_init)
+ xlator->mem_acct_init = default_mem_acct_init;
+ xlator->mem_acct_init(xlator);
+ }
- if (ret) {
- gf_msg (xlator->name, GF_LOG_INFO, 0, LG_MSG_INVALID_ENTRY,
- "%s", *op_errstr);
- goto out;
- }
+ ret = xlator_options_validate(xlator, xlator->options, op_errstr);
+ THIS = old_THIS;
- gf_msg_debug (xlator->name, 0, "Validated options");
+ if (ret) {
+ gf_smsg(xlator->name, GF_LOG_INFO, 0, LG_MSG_INVALID_ENTRY, "%s",
+ *op_errstr, NULL);
+ goto out;
+ }
- ret = 0;
+ gf_msg_debug(xlator->name, 0, "Validated options");
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
int
-graph_reconf_validateopt (glusterfs_graph_t *graph, char **op_errstr)
+graph_reconf_validateopt(glusterfs_graph_t *graph, char **op_errstr)
{
- xlator_t *xlator = NULL;
- int ret = -1;
+ xlator_t *xlator = NULL;
+ int ret = -1;
- GF_ASSERT (graph);
+ GF_ASSERT(graph);
- xlator = graph->first;
+ xlator = graph->first;
- ret = xlator_validate_rec (xlator, op_errstr);
+ ret = xlator_validate_rec(xlator, op_errstr);
- return ret;
+ return ret;
}
-
static int
-xlator_reconfigure_rec (xlator_t *old_xl, xlator_t *new_xl)
+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;
+ 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);
+ GF_VALIDATE_OR_GOTO("xlator", old_xl, out);
+ GF_VALIDATE_OR_GOTO("xlator", new_xl, out);
- trav1 = old_xl->children;
- trav2 = new_xl->children;
+ trav1 = old_xl->children;
+ trav2 = new_xl->children;
- while (trav1 && trav2) {
- ret = xlator_reconfigure_rec (trav1->xlator, trav2->xlator);
- if (ret)
- goto out;
+ while (trav1 && trav2) {
+ ret = xlator_reconfigure_rec(trav1->xlator, trav2->xlator);
+ if (ret)
+ goto out;
- gf_msg_debug (trav1->xlator->name, 0, "reconfigured");
+ gf_msg_debug(trav1->xlator->name, 0, "reconfigured");
- trav1 = trav1->next;
- trav2 = trav2->next;
- }
+ trav1 = trav1->next;
+ trav2 = trav2->next;
+ }
- if (old_xl->reconfigure) {
- old_THIS = THIS;
- THIS = old_xl;
+ if (old_xl->reconfigure) {
+ old_THIS = THIS;
+ THIS = old_xl;
- ret = old_xl->reconfigure (old_xl, new_xl->options);
+ xlator_init_lock();
+ handle_default_options(old_xl, new_xl->options);
+ ret = old_xl->reconfigure(old_xl, new_xl->options);
+ xlator_init_unlock();
- THIS = old_THIS;
+ THIS = old_THIS;
- if (ret)
- goto out;
- } else {
- gf_msg_debug (old_xl->name, 0, "No reconfigure() found");
- }
+ if (ret)
+ goto out;
+ } else {
+ gf_msg_debug(old_xl->name, 0, "No reconfigure() found");
+ }
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
int
-xlator_tree_reconfigure (xlator_t *old_xl, xlator_t *new_xl)
+xlator_tree_reconfigure(xlator_t *old_xl, xlator_t *new_xl)
{
- xlator_t *new_top = NULL;
- xlator_t *old_top = NULL;
+ xlator_t *new_top = NULL;
+ xlator_t *old_top = NULL;
- GF_ASSERT (old_xl);
- GF_ASSERT (new_xl);
+ GF_ASSERT(old_xl);
+ GF_ASSERT(new_xl);
- old_top = old_xl;
- new_top = new_xl;
+ old_top = old_xl;
+ new_top = new_xl;
- return xlator_reconfigure_rec (old_top, new_top);
+ 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)
+xlator_option_info_list(volume_opt_list_t *list, char *key, char **def_val,
+ char **descr)
{
- int ret = -1;
- volume_option_t *opt = NULL;
-
+ int ret = -1;
+ volume_option_t *opt = NULL;
- opt = xlator_volume_option_get_list (list, key);
- if (!opt)
- goto out;
+ 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;
+ if (def_val)
+ *def_val = opt->default_value;
+ if (descr)
+ *descr = opt->description;
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
-
static int
-pass (char *in, char **out)
+pass(char *in, char **out)
{
- *out = in;
- return 0;
+ *out = in;
+ return 0;
}
-
static int
-xl_by_name (char *in, xlator_t **out)
+xl_by_name(char *in, xlator_t **out)
{
- xlator_t *xl = NULL;
+ xlator_t *xl = NULL;
- xl = xlator_search_by_name (THIS, in);
+ xl = xlator_search_by_name(THIS, in);
- if (!xl)
- return -1;
- *out = xl;
- return 0;
+ if (!xl)
+ return -1;
+ *out = xl;
+ return 0;
}
-
static int
-pc_or_size (char *in, double *out)
+pc_or_size(char *in, double *out)
{
- double pc = 0;
- int ret = 0;
- size_t size = 0;
-
- if (gf_string2percent (in, &pc) == 0) {
- if (pc > 100.0) {
- ret = gf_string2bytesize_size (in, &size);
- if (!ret)
- *out = size;
- } else {
- *out = pc;
- }
+ double pc = 0;
+ int ret = 0;
+ uint64_t size = 0;
+
+ if (gf_string2percent(in, &pc) == 0) {
+ if (pc > 100.0) {
+ ret = gf_string2bytesize_uint64(in, &size);
+ if (!ret)
+ *out = size;
} else {
- ret = gf_string2bytesize_size (in, &size);
- if (!ret)
- *out = size;
+ *out = pc;
}
- return ret;
+ } else {
+ ret = gf_string2bytesize_uint64(in, &size);
+ if (!ret)
+ *out = size;
+ }
+ return ret;
}
DEFINE_INIT_OPT(char *, str, pass);
@@ -1210,7 +1223,7 @@ 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(size_t, size, gf_string2bytesize_size);
+DEFINE_INIT_OPT(uint64_t, size, gf_string2bytesize_uint64);
DEFINE_INIT_OPT(uint64_t, size_uint64, gf_string2bytesize_uint64);
DEFINE_INIT_OPT(double, percent, gf_string2percent);
DEFINE_INIT_OPT(double, percent_or_size, pc_or_size);
@@ -1220,13 +1233,12 @@ DEFINE_INIT_OPT(char *, path, pass);
DEFINE_INIT_OPT(double, double, gf_string2double);
DEFINE_INIT_OPT(uint32_t, time, gf_string2time);
-
DEFINE_RECONF_OPT(char *, str, pass);
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(size_t, size, gf_string2bytesize_size);
+DEFINE_RECONF_OPT(uint64_t, size, gf_string2bytesize_uint64);
DEFINE_RECONF_OPT(uint64_t, size_uint64, gf_string2bytesize_uint64);
DEFINE_RECONF_OPT(double, percent, gf_string2percent);
DEFINE_RECONF_OPT(double, percent_or_size, pc_or_size);
diff --git a/libglusterfs/src/options.h b/libglusterfs/src/options.h
deleted file mode 100644
index 3154dcefc02..00000000000
--- a/libglusterfs/src/options.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- 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
-
-#include <stdio.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include "xlator.h"
-#include "libglusterfs-messages.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_CLIENT_AUTH_ADDR,
- GF_OPTION_TYPE_MAX,
-} volume_option_type_t;
-
-typedef enum {
- GF_OPT_VALIDATE_BOTH = 0,
- GF_OPT_VALIDATE_MIN,
- GF_OPT_VALIDATE_MAX,
-} opt_validate_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;
- double min; /* 0 means no range */
- double 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 */
- /* Required for int options where only the min value
- * is given and is 0. This will cause validation not to
- * happen
- */
- opt_validate_type_t validate;
-} 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);
-
-volume_option_t *
-xlator_volume_option_get_list (volume_opt_list_t *vol_list, 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(size_t, size);
-DECLARE_INIT_OPT(uint64_t, size_uint64);
-DECLARE_INIT_OPT(double, percent);
-DECLARE_INIT_OPT(double, percent_or_size);
-DECLARE_INIT_OPT(gf_boolean_t, bool);
-DECLARE_INIT_OPT(xlator_t *, xlator);
-DECLARE_INIT_OPT(char *, path);
-DECLARE_INIT_OPT(double, double);
-DECLARE_INIT_OPT(uint32_t, time);
-
-
-#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_msg (this->name, GF_LOG_WARNING, EINVAL, \
- LG_MSG_INVALID_ENTRY, \
- "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_msg_trace (this->name, 0, "option %s not set", \
- key); \
- *val_p = (type_t)0; \
- return 0; \
- } \
- if (value == def_value) { \
- gf_msg_trace (this->name, 0, "option %s using default" \
- " value %s", key, value); \
- } else { \
- gf_msg_debug (this->name, 0, "option %s using set" \
- " value %s", key, value); \
- } \
- old_THIS = THIS; \
- THIS = this; \
- ret = conv (value, val_p); \
- THIS = old_THIS; \
- if (ret) { \
- gf_msg (this->name, GF_LOG_INFO, 0, \
- LG_MSG_CONVERSION_FAILED, \
- "option %s conversion failed value %s", \
- key, value); \
- 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(size_t, size);
-DECLARE_RECONF_OPT(uint64_t, size_uint64);
-DECLARE_RECONF_OPT(double, percent);
-DECLARE_RECONF_OPT(double, percent_or_size);
-DECLARE_RECONF_OPT(gf_boolean_t, bool);
-DECLARE_RECONF_OPT(xlator_t *, xlator);
-DECLARE_RECONF_OPT(char *, path);
-DECLARE_RECONF_OPT(double, double);
-DECLARE_RECONF_OPT(uint32_t, time);
-
-
-#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_msg (this->name, GF_LOG_WARNING, EINVAL, \
- LG_MSG_INVALID_ENTRY, \
- "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_msg_trace (this->name, 0, "option %s not set", key); \
- *val_p = (type_t)0; \
- return 0; \
- } \
- if (value == def_value) { \
- gf_msg_trace (this->name, 0, \
- "option %s using default value %s", \
- key, value); \
- } else { \
- gf_msg_debug (this->name, 0, \
- "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/parse-utils.c b/libglusterfs/src/parse-utils.c
index 304232f6b56..4531d5f0170 100644
--- a/libglusterfs/src/parse-utils.c
+++ b/libglusterfs/src/parse-utils.c
@@ -14,13 +14,11 @@
#include <regex.h>
#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "parse-utils.h"
-#include "mem-pool.h"
-#include "common-utils.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/parse-utils.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/libglusterfs-messages.h"
/**
* parser_init: Initialize a parser with the a string to parse and
@@ -36,33 +34,33 @@
* : failure: NULL (on failure to compile regex or allocate memory)
*/
struct parser *
-parser_init (const char *regex)
+parser_init(const char *regex)
{
- int rc = 0;
- struct parser *parser = NULL;
-
- parser = GF_MALLOC (sizeof(*parser), gf_common_mt_parser_t);
- if (!parser)
- goto out;
-
- parser->regex = gf_strdup (regex);
- if (!parser->regex) {
- GF_FREE (parser);
- parser = NULL;
- goto out;
- }
-
- rc = regcomp (&parser->preg, parser->regex, REG_EXTENDED);
- if (rc != 0) {
- gf_msg (GF_PARSE, GF_LOG_INFO, 0, LG_MSG_REGEX_OP_FAILED,
- "Failed to compile regex pattern.");
- parser_deinit (parser);
- parser = NULL;
- goto out;
- }
- parser->complete_str = NULL;
+ int rc = 0;
+ struct parser *parser = NULL;
+
+ parser = GF_MALLOC(sizeof(*parser), gf_common_mt_parser_t);
+ if (!parser)
+ goto out;
+
+ parser->regex = gf_strdup(regex);
+ if (!parser->regex) {
+ GF_FREE(parser);
+ parser = NULL;
+ goto out;
+ }
+
+ rc = regcomp(&parser->preg, parser->regex, REG_EXTENDED);
+ if (rc != 0) {
+ gf_msg(GF_PARSE, GF_LOG_INFO, 0, LG_MSG_REGEX_OP_FAILED,
+ "Failed to compile regex pattern.");
+ parser_deinit(parser);
+ parser = NULL;
+ goto out;
+ }
+ parser->complete_str = NULL;
out:
- return parser;
+ return parser;
}
/**
@@ -78,22 +76,22 @@ out:
* failure: -EINVAL for NULL args, -ENOMEM for allocation errors
*/
int
-parser_set_string (struct parser *parser, const char *complete_str)
+parser_set_string(struct parser *parser, const char *complete_str)
{
- int ret = -EINVAL;
+ int ret = -EINVAL;
- GF_VALIDATE_OR_GOTO (GF_PARSE, parser, out);
- GF_VALIDATE_OR_GOTO (GF_PARSE, complete_str, out);
+ GF_VALIDATE_OR_GOTO(GF_PARSE, parser, out);
+ GF_VALIDATE_OR_GOTO(GF_PARSE, complete_str, out);
- parser->complete_str = gf_strdup (complete_str);
- GF_CHECK_ALLOC_AND_LOG (GF_PARSE, parser, ret,
- "Failed to duplicate string!", out);
+ parser->complete_str = gf_strdup(complete_str);
+ GF_CHECK_ALLOC_AND_LOG(GF_PARSE, parser, ret, "Failed to duplicate string!",
+ out);
- /* Point the temp internal string to what we just dup'ed */
- parser->_rstr = (char *)parser->complete_str;
- ret = 0;
+ /* Point the temp internal string to what we just dup'ed */
+ parser->_rstr = (char *)parser->complete_str;
+ ret = 0;
out:
- return ret;
+ return ret;
}
/**
@@ -107,17 +105,17 @@ out:
* : failure: -EINVAL on NULL args
*/
int
-parser_unset_string (struct parser *parser)
+parser_unset_string(struct parser *parser)
{
- int ret = -EINVAL;
+ int ret = -EINVAL;
- GF_VALIDATE_OR_GOTO (GF_PARSE, parser, out);
+ GF_VALIDATE_OR_GOTO(GF_PARSE, parser, out);
- GF_FREE (parser->complete_str);
- parser->complete_str = NULL; /* Avoid double frees in parser_deinit */
- ret = 0;
+ GF_FREE(parser->complete_str);
+ parser->complete_str = NULL; /* Avoid double frees in parser_deinit */
+ ret = 0;
out:
- return ret;
+ return ret;
}
/**
@@ -128,15 +126,15 @@ out:
* @return : nothing
*/
void
-parser_deinit (struct parser *ptr)
+parser_deinit(struct parser *ptr)
{
- if (!ptr)
- return;
+ if (!ptr)
+ return;
- regfree (&ptr->preg);
- GF_FREE (ptr->complete_str);
- GF_FREE (ptr->regex);
- GF_FREE (ptr);
+ regfree(&ptr->preg);
+ GF_FREE(ptr->complete_str);
+ GF_FREE(ptr->regex);
+ GF_FREE(ptr);
}
/**
@@ -149,29 +147,28 @@ parser_deinit (struct parser *ptr)
* : failure: NULL
*/
char *
-parser_get_next_match (struct parser *parser)
+parser_get_next_match(struct parser *parser)
{
- int rc = -EINVAL;
- size_t copy_len = 0;
- char *match = NULL;
+ int rc = -EINVAL;
+ size_t copy_len = 0;
+ char *match = NULL;
- GF_VALIDATE_OR_GOTO (GF_PARSE, parser, out);
+ GF_VALIDATE_OR_GOTO(GF_PARSE, parser, out);
- rc = regexec (&parser->preg, parser->_rstr, 1, parser->pmatch, 0);
- if (rc != 0) {
- gf_msg_debug (GF_PARSE, 0,
- "Could not match %s with regex %s",
- parser->_rstr, parser->regex);
- goto out;
- }
+ rc = regexec(&parser->preg, parser->_rstr, 1, parser->pmatch, 0);
+ if (rc != 0) {
+ gf_msg_debug(GF_PARSE, 0, "Could not match %s with regex %s",
+ parser->_rstr, parser->regex);
+ goto out;
+ }
- copy_len = parser->pmatch[0].rm_eo - parser->pmatch[0].rm_so;
+ copy_len = parser->pmatch[0].rm_eo - parser->pmatch[0].rm_so;
- match = gf_strndup (parser->_rstr + parser->pmatch[0].rm_so, copy_len);
- GF_CHECK_ALLOC_AND_LOG (GF_PARSE, match, rc,
- "Duplicating match failed!", out);
+ match = gf_strndup(parser->_rstr + parser->pmatch[0].rm_so, copy_len);
+ GF_CHECK_ALLOC_AND_LOG(GF_PARSE, match, rc, "Duplicating match failed!",
+ out);
- parser->_rstr = &parser->_rstr[parser->pmatch[0].rm_eo];
+ parser->_rstr = &parser->_rstr[parser->pmatch[0].rm_eo];
out:
- return match;
+ return match;
}
diff --git a/libglusterfs/src/quota-common-utils.c b/libglusterfs/src/quota-common-utils.c
index 5e688e50856..804e2f0ad4b 100644
--- a/libglusterfs/src/quota-common-utils.c
+++ b/libglusterfs/src/quota-common-utils.c
@@ -8,227 +8,234 @@
cases as published by the Free Software Foundation.
*/
+#include "glusterfs/dict.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/byte-order.h"
+#include "glusterfs/quota-common-utils.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+gf_boolean_t
+quota_meta_is_null(const quota_meta_t *meta)
+{
+ if (meta->size == 0 && meta->file_count == 0 && meta->dir_count == 0)
+ return _gf_true;
-#include "dict.h"
-#include "logging.h"
-#include "byte-order.h"
-#include "quota-common-utils.h"
-#include "common-utils.h"
-#include "libglusterfs-messages.h"
+ return _gf_false;
+}
int32_t
-quota_data_to_meta (data_t *data, char *key, quota_meta_t *meta)
+quota_data_to_meta(data_t *data, quota_meta_t *meta)
{
- int32_t ret = -1;
- quota_meta_t *value = NULL;
- int64_t *size = NULL;
-
- if (!data || !key || !meta)
- goto out;
-
- if (data->len > sizeof (int64_t)) {
- value = (quota_meta_t *) data->data;
- meta->size = ntoh64 (value->size);
- meta->file_count = ntoh64 (value->file_count);
- if (data->len > (sizeof (int64_t)) * 2)
- meta->dir_count = ntoh64 (value->dir_count);
- else
- meta->dir_count = 0;
- } else {
- size = (int64_t *) data->data;
- meta->size = ntoh64 (*size);
- meta->file_count = 0;
- meta->dir_count = 0;
- /* This can happen during software upgrade.
- * Older version of glusterfs will not have inode count.
- * Return failure, this will be healed as part of lookup
- */
- gf_msg_callingfn ("quota", GF_LOG_DEBUG, 0,
- LG_MSG_QUOTA_XATTRS_MISSING, "Object quota "
- "xattrs missing: len = %d", data->len);
- ret = -2;
- goto out;
- }
-
- ret = 0;
+ int32_t ret = -1;
+ quota_meta_t *value = NULL;
+ int64_t *size = NULL;
+
+ if (!data || !meta)
+ goto out;
+
+ if (data->len > sizeof(int64_t)) {
+ value = (quota_meta_t *)data->data;
+ meta->size = ntoh64(value->size);
+ meta->file_count = ntoh64(value->file_count);
+ if (data->len > (sizeof(int64_t)) * 2)
+ meta->dir_count = ntoh64(value->dir_count);
+ else
+ meta->dir_count = 0;
+ } else {
+ size = (int64_t *)data->data;
+ meta->size = ntoh64(*size);
+ meta->file_count = 0;
+ meta->dir_count = 0;
+ /* This can happen during software upgrade.
+ * Older version of glusterfs will not have inode count.
+ * Return failure, this will be healed as part of lookup
+ */
+ gf_msg_callingfn("quota", GF_LOG_DEBUG, 0, LG_MSG_QUOTA_XATTRS_MISSING,
+ "Object quota "
+ "xattrs missing: len = %d",
+ data->len);
+ ret = -2;
+ goto out;
+ }
+
+ ret = 0;
out:
- return ret;
+ return ret;
}
int32_t
-quota_dict_get_inode_meta (dict_t *dict, char *key, quota_meta_t *meta)
+quota_dict_get_inode_meta(dict_t *dict, char *key, const int keylen,
+ quota_meta_t *meta)
{
- int32_t ret = -1;
- data_t *data = NULL;
+ int32_t ret = -1;
+ data_t *data = NULL;
- if (!dict || !key || !meta)
- goto out;
+ if (!dict || !key || !meta)
+ goto out;
- data = dict_get (dict, key);
- if (!data || !data->data)
- goto out;
+ data = dict_getn(dict, key, keylen);
+ if (!data || !data->data)
+ goto out;
- ret = quota_data_to_meta (data, key, meta);
+ ret = quota_data_to_meta(data, meta);
out:
- return ret;
+ return ret;
}
int32_t
-quota_dict_get_meta (dict_t *dict, char *key, quota_meta_t *meta)
+quota_dict_get_meta(dict_t *dict, char *key, const int keylen,
+ quota_meta_t *meta)
{
- int32_t ret = -1;
+ int32_t ret = -1;
- ret = quota_dict_get_inode_meta (dict, key, meta);
- if (ret == -2)
- ret = 0;
+ ret = quota_dict_get_inode_meta(dict, key, keylen, meta);
+ if (ret == -2)
+ ret = 0;
- return ret;
+ return ret;
}
int32_t
-quota_dict_set_meta (dict_t *dict, char *key, const quota_meta_t *meta,
- ia_type_t ia_type)
+quota_dict_set_meta(dict_t *dict, char *key, const quota_meta_t *meta,
+ ia_type_t ia_type)
{
- int32_t ret = -ENOMEM;
- quota_meta_t *value = NULL;
-
- value = GF_CALLOC (1, sizeof (quota_meta_t), gf_common_quota_meta_t);
- if (value == NULL) {
- goto out;
- }
-
- value->size = hton64 (meta->size);
- value->file_count = hton64 (meta->file_count);
- value->dir_count = hton64 (meta->dir_count);
-
- if (ia_type == IA_IFDIR) {
- ret = dict_set_bin (dict, key, value, sizeof (*value));
- } else {
- /* For a file we don't need to store dir_count in the
- * quota size xattr, so we set the len of the data in the dict
- * as 128bits, so when the posix xattrop reads the dict, it only
- * performs operations on size and file_count
- */
- ret = dict_set_bin (dict, key, value,
- sizeof (*value) - sizeof (int64_t));
- }
-
- if (ret < 0) {
- gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
- LG_MSG_DICT_SET_FAILED, "dict set failed");
- GF_FREE (value);
- }
+ int32_t ret = -ENOMEM;
+ quota_meta_t *value = NULL;
+
+ value = GF_MALLOC(sizeof(quota_meta_t), gf_common_quota_meta_t);
+ if (value == NULL) {
+ goto out;
+ }
+
+ value->size = hton64(meta->size);
+ value->file_count = hton64(meta->file_count);
+ value->dir_count = hton64(meta->dir_count);
+
+ if (ia_type == IA_IFDIR) {
+ ret = dict_set_bin(dict, key, value, sizeof(*value));
+ } else {
+ /* For a file we don't need to store dir_count in the
+ * quota size xattr, so we set the len of the data in the dict
+ * as 128bits, so when the posix xattrop reads the dict, it only
+ * performs operations on size and file_count
+ */
+ ret = dict_set_bin(dict, key, value, sizeof(*value) - sizeof(int64_t));
+ }
+
+ if (ret < 0) {
+ gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_DICT_SET_FAILED,
+ "dict set failed");
+ GF_FREE(value);
+ }
out:
- return ret;
+ return ret;
}
int32_t
-quota_conf_read_header (int fd, char *buf)
+quota_conf_read_header(int fd, char *buf)
{
- int header_len = 0;
- int ret = 0;
+ int ret = 0;
+ const int header_len = SLEN(QUOTA_CONF_HEADER);
- header_len = strlen (QUOTA_CONF_HEADER);
+ ret = gf_nread(fd, buf, header_len);
+ if (ret <= 0) {
+ goto out;
+ } else if (ret > 0 && ret != header_len) {
+ ret = -1;
+ goto out;
+ }
- ret = gf_nread (fd, buf, header_len);
- if (ret <= 0) {
- goto out;
- } else if (ret > 0 && ret != header_len) {
- ret = -1;
- goto out;
- }
-
- buf[header_len-1] = 0;
+ buf[header_len - 1] = 0;
out:
- if (ret < 0)
- gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
- LG_MSG_QUOTA_CONF_ERROR, "failed to read "
- "header from a quota conf");
+ if (ret < 0)
+ gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
+ "failed to read "
+ "header from a quota conf");
- return ret;
+ return ret;
}
int32_t
-quota_conf_read_version (int fd, float *version)
+quota_conf_read_version(int fd, float *version)
{
- int ret = 0;
- char buf[PATH_MAX] = "";
- char *tail = NULL;
- float value = 0.0f;
-
- ret = quota_conf_read_header (fd, buf);
- if (ret == 0) {
- /* quota.conf is empty */
- value = GF_QUOTA_CONF_VERSION;
- goto out;
- } else if (ret < 0) {
- goto out;
- }
-
- value = strtof ((buf + strlen(buf) - 3), &tail);
- if (tail[0] != '\0') {
- ret = -1;
- gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
- LG_MSG_QUOTA_CONF_ERROR, "invalid quota conf"
- " version");
- goto out;
- }
-
- ret = 0;
+ int ret = 0;
+ char buf[PATH_MAX] = "";
+ char *tail = NULL;
+ float value = 0.0f;
+
+ ret = quota_conf_read_header(fd, buf);
+ if (ret == 0) {
+ /* quota.conf is empty */
+ value = GF_QUOTA_CONF_VERSION;
+ goto out;
+ } else if (ret < 0) {
+ goto out;
+ }
+
+ value = strtof((buf + strlen(buf) - 3), &tail);
+ if (tail[0] != '\0') {
+ ret = -1;
+ gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
+ "invalid quota conf"
+ " version");
+ goto out;
+ }
+
+ ret = 0;
out:
- if (ret >= 0)
- *version = value;
- else
- gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
- LG_MSG_QUOTA_CONF_ERROR, "failed to "
- "read version from a quota conf header");
-
- return ret;
+ if (ret >= 0)
+ *version = value;
+ else
+ gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
+ "failed to "
+ "read version from a quota conf header");
+
+ return ret;
}
int32_t
-quota_conf_read_gfid (int fd, void *buf, char *type, float version)
+quota_conf_read_gfid(int fd, void *buf, char *type, float version)
{
- int ret = 0;
-
- ret = gf_nread (fd, buf, 16);
- if (ret <= 0)
- goto out;
-
- if (ret != 16) {
- ret = -1;
- goto out;
- }
-
- if (version >= 1.2f) {
- ret = gf_nread (fd, type, 1);
- if (ret != 1) {
- ret = -1;
- goto out;
- }
- ret = 17;
- } else {
- *type = GF_QUOTA_CONF_TYPE_USAGE;
+ int ret = 0;
+
+ ret = gf_nread(fd, buf, 16);
+ if (ret <= 0)
+ goto out;
+
+ if (ret != 16) {
+ ret = -1;
+ goto out;
+ }
+
+ if (version >= 1.2f) {
+ ret = gf_nread(fd, type, 1);
+ if (ret != 1) {
+ ret = -1;
+ goto out;
}
+ ret = 17;
+ } else {
+ *type = GF_QUOTA_CONF_TYPE_USAGE;
+ }
out:
- if (ret < 0)
- gf_msg_callingfn ("quota", GF_LOG_ERROR, 0,
- LG_MSG_QUOTA_CONF_ERROR, "failed to "
- "read gfid from a quota conf");
+ if (ret < 0)
+ gf_msg_callingfn("quota", GF_LOG_ERROR, 0, LG_MSG_QUOTA_CONF_ERROR,
+ "failed to "
+ "read gfid from a quota conf");
- return ret;
+ return ret;
}
int32_t
-quota_conf_skip_header (int fd)
+quota_conf_skip_header(int fd)
{
- return gf_skip_header_section (fd, strlen (QUOTA_CONF_HEADER));
+ return gf_skip_header_section(fd, strlen(QUOTA_CONF_HEADER));
}
-
diff --git a/libglusterfs/src/quota-common-utils.h b/libglusterfs/src/quota-common-utils.h
deleted file mode 100644
index c930db8e86c..00000000000
--- a/libglusterfs/src/quota-common-utils.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- Copyright (c) 2015 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 _QUOTA_COMMON_UTILS_H
-#define _QUOTA_COMMON_UTILS_H
-
-#include "iatt.h"
-
-#define GF_QUOTA_CONF_VERSION 1.2
-#define QUOTA_CONF_HEADER \
- "GlusterFS Quota conf | version: v1.2\n"
-#define QUOTA_CONF_HEADER_1_1 \
- "GlusterFS Quota conf | version: v1.1\n"
-
-typedef enum {
- GF_QUOTA_CONF_TYPE_USAGE = 1,
- GF_QUOTA_CONF_TYPE_OBJECTS
-} gf_quota_conf_type_t;
-
-struct _quota_limits {
- int64_t hl;
- int64_t sl;
-} __attribute__ ((__packed__));
-typedef struct _quota_limits quota_limits_t;
-
-struct _quota_meta {
- int64_t size;
- int64_t file_count;
- int64_t dir_count;
-} __attribute__ ((__packed__));
-typedef struct _quota_meta quota_meta_t;
-
-int32_t
-quota_data_to_meta (data_t *data, char *key, quota_meta_t *meta);
-
-int32_t
-quota_dict_get_inode_meta (dict_t *dict, char *key, quota_meta_t *meta);
-
-int32_t
-quota_dict_get_meta (dict_t *dict, char *key, quota_meta_t *meta);
-
-int32_t
-quota_dict_set_meta (dict_t *dict, char *key, const quota_meta_t *meta,
- ia_type_t ia_type);
-
-int32_t
-quota_conf_read_header (int fd, char *buf);
-
-int32_t
-quota_conf_read_version (int fd, float *version);
-
-int32_t
-quota_conf_read_gfid (int fd, void *buf, char *type, float version);
-
-int32_t
-quota_conf_skip_header (int fd);
-
-#endif /* _QUOTA_COMMON_UTILS_H */
diff --git a/libglusterfs/src/rbthash.c b/libglusterfs/src/rbthash.c
index 52d8a15fd2c..c90b5a21f44 100644
--- a/libglusterfs/src/rbthash.c
+++ b/libglusterfs/src/rbthash.c
@@ -8,70 +8,66 @@
cases as published by the Free Software Foundation.
*/
-
-#include "rbthash.h"
+#include "glusterfs/rbthash.h"
#include "rb.h"
-#include "locking.h"
-#include "mem-pool.h"
-#include "logging.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/locking.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/libglusterfs-messages.h"
#include <pthread.h>
#include <string.h>
-
int
-rbthash_comparator (void *entry1, void *entry2, void *param)
+rbthash_comparator(void *entry1, void *entry2, void *param)
{
- int ret = 0;
- rbthash_entry_t *e1 = NULL;
- rbthash_entry_t *e2 = NULL;
+ int ret = 0;
+ rbthash_entry_t *e1 = NULL;
+ rbthash_entry_t *e2 = NULL;
- if ((!entry1) || (!entry2) || (!param))
- return -1;
+ if ((!entry1) || (!entry2) || (!param))
+ return -1;
- e1 = (rbthash_entry_t *)entry1;
- e2 = (rbthash_entry_t *)entry2;
+ e1 = (rbthash_entry_t *)entry1;
+ e2 = (rbthash_entry_t *)entry2;
- if (e1->keylen != e2->keylen) {
- if (e1->keylen < e2->keylen)
- ret = -1;
- else if (e1->keylen > e2->keylen)
- ret = 1;
- } else
- ret = memcmp (e1->key, e2->key, e1->keylen);
+ if (e1->keylen != e2->keylen) {
+ if (e1->keylen < e2->keylen)
+ ret = -1;
+ else if (e1->keylen > e2->keylen)
+ ret = 1;
+ } else
+ ret = memcmp(e1->key, e2->key, e1->keylen);
- return ret;
+ return ret;
}
-
int
-__rbthash_init_buckets (rbthash_table_t *tbl, int buckets)
+__rbthash_init_buckets(rbthash_table_t *tbl, int buckets)
{
- int i = 0;
- int ret = -1;
-
- if (!tbl)
- return -1;
-
- for (; i < buckets; i++) {
- LOCK_INIT (&tbl->buckets[i].bucketlock);
- tbl->buckets[i].bucket = rb_create ((rb_comparison_func *)rbthash_comparator, tbl, NULL);
- if (!tbl->buckets[i].bucket) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
- LG_MSG_RB_TABLE_CREATE_FAILED, "Failed to "
- "create rb table bucket");
- ret = -1;
- goto err;
- }
+ int i = 0;
+ int ret = -1;
+
+ if (!tbl)
+ return -1;
+
+ for (; i < buckets; i++) {
+ LOCK_INIT(&tbl->buckets[i].bucketlock);
+ tbl->buckets[i].bucket = rb_create(
+ (rb_comparison_func *)rbthash_comparator, tbl, NULL);
+ if (!tbl->buckets[i].bucket) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RB_TABLE_CREATE_FAILED,
+ NULL);
+ ret = -1;
+ goto err;
}
+ }
- ret = 0;
+ ret = 0;
err:
- return ret;
+ return ret;
}
-
/*
* rbthash_table_init - Initialize a RBT based hash table
* @buckets - Number of buckets in the hash table
@@ -83,390 +79,376 @@ err:
*/
rbthash_table_t *
-rbthash_table_init (int buckets, rbt_hasher_t hfunc,
- rbt_data_destroyer_t dfunc,
- unsigned long expected_entries,
- struct mem_pool *entrypool)
+rbthash_table_init(glusterfs_ctx_t *ctx, int buckets, rbt_hasher_t hfunc,
+ rbt_data_destroyer_t dfunc, unsigned long expected_entries,
+ struct mem_pool *entrypool)
{
- rbthash_table_t *newtab = NULL;
- int ret = -1;
-
- if (!hfunc) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_HASH_FUNC_ERROR,
- "Hash function not given");
- return NULL;
+ rbthash_table_t *newtab = NULL;
+ int ret = -1;
+
+ if (!hfunc) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_HASH_FUNC_ERROR, NULL);
+ return NULL;
+ }
+
+ if (!entrypool && !expected_entries) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_ENTRIES_NOT_PROVIDED, NULL);
+ return NULL;
+ }
+
+ if (entrypool && expected_entries) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_ENTRIES_PROVIDED, NULL);
+ return NULL;
+ }
+
+ newtab = GF_CALLOC(1, sizeof(*newtab), gf_common_mt_rbthash_table_t);
+ if (!newtab)
+ return NULL;
+
+ newtab->buckets = GF_CALLOC(buckets, sizeof(struct rbthash_bucket),
+ gf_common_mt_rbthash_bucket);
+ if (!newtab->buckets) {
+ goto free_newtab;
+ }
+
+ if (expected_entries) {
+ newtab->entrypool = mem_pool_new_ctx(ctx, rbthash_entry_t,
+ expected_entries);
+ if (!newtab->entrypool) {
+ goto free_buckets;
}
-
- if (!entrypool && !expected_entries) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
- "Both mem-pool and expected entries not provided");
- return NULL;
- }
-
- if (entrypool && expected_entries) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
- "Both mem-pool and expected entries are provided");
- return NULL;
- }
-
-
- newtab = GF_CALLOC (1, sizeof (*newtab),
- gf_common_mt_rbthash_table_t);
- if (!newtab)
- return NULL;
-
- newtab->buckets = GF_CALLOC (buckets, sizeof (struct rbthash_bucket),
- gf_common_mt_rbthash_bucket);
- if (!newtab->buckets) {
- goto free_newtab;
- }
-
- if (expected_entries) {
- newtab->entrypool =
- mem_pool_new (rbthash_entry_t, expected_entries);
- if (!newtab->entrypool) {
- goto free_buckets;
- }
- newtab->pool_alloced = _gf_true;
- } else {
- newtab->entrypool = entrypool;
- }
-
- LOCK_INIT (&newtab->tablelock);
- INIT_LIST_HEAD (&newtab->list);
- newtab->numbuckets = buckets;
- ret = __rbthash_init_buckets (newtab, buckets);
-
- if (ret == -1) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
- LG_MSG_RBTHASH_INIT_BUCKET_FAILED,
- "Failed to init buckets");
- if (newtab->pool_alloced)
- mem_pool_destroy (newtab->entrypool);
- } else {
- gf_msg_trace (GF_RBTHASH, 0, "Inited hash table: buckets:"
- " %d", buckets);
- }
-
- newtab->hashfunc = hfunc;
- newtab->dfunc = dfunc;
+ newtab->pool_alloced = _gf_true;
+ } else {
+ newtab->entrypool = entrypool;
+ }
+
+ LOCK_INIT(&newtab->tablelock);
+ INIT_LIST_HEAD(&newtab->list);
+ newtab->numbuckets = buckets;
+ ret = __rbthash_init_buckets(newtab, buckets);
+
+ if (ret == -1) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INIT_BUCKET_FAILED,
+ NULL);
+ if (newtab->pool_alloced)
+ mem_pool_destroy(newtab->entrypool);
+ } else {
+ gf_msg_trace(GF_RBTHASH, 0,
+ "Inited hash table: buckets:"
+ " %d",
+ buckets);
+ }
+
+ newtab->hashfunc = hfunc;
+ newtab->dfunc = dfunc;
free_buckets:
- if (ret == -1)
- GF_FREE (newtab->buckets);
+ if (ret == -1)
+ GF_FREE(newtab->buckets);
free_newtab:
- if (ret == -1) {
- GF_FREE (newtab);
- newtab = NULL;
- }
+ if (ret == -1) {
+ GF_FREE(newtab);
+ newtab = NULL;
+ }
- return newtab;
+ return newtab;
}
rbthash_entry_t *
-rbthash_init_entry (rbthash_table_t *tbl, void *data, void *key, int keylen)
+rbthash_init_entry(rbthash_table_t *tbl, void *data, void *key, int keylen)
{
- int ret = -1;
- rbthash_entry_t *entry = NULL;
-
- if ((!tbl) || (!data) || (!key))
- return NULL;
-
- entry = mem_get (tbl->entrypool);
- if (!entry) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
- LG_MSG_RBTHASH_GET_ENTRY_FAILED,
- "Failed to get entry from mem-pool");
- goto ret;
- }
-
- entry->data = data;
- entry->key = GF_CALLOC (keylen, sizeof (char), gf_common_mt_char);
- if (!entry->key) {
- goto free_entry;
- }
-
- INIT_LIST_HEAD (&entry->list);
- memcpy (entry->key, key, keylen);
- entry->keylen = keylen;
- entry->keyhash = tbl->hashfunc (entry->key, entry->keylen);
- gf_msg_trace (GF_RBTHASH, 0, "HASH: %u", entry->keyhash);
-
- ret = 0;
+ int ret = -1;
+ rbthash_entry_t *entry = NULL;
+
+ if ((!tbl) || (!data) || (!key))
+ return NULL;
+
+ entry = mem_get(tbl->entrypool);
+ if (!entry) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_ENTRY_FAILED,
+ NULL);
+ goto ret;
+ }
+
+ entry->data = data;
+ entry->key = GF_MALLOC(keylen, gf_common_mt_char);
+ if (!entry->key) {
+ goto free_entry;
+ }
+
+ INIT_LIST_HEAD(&entry->list);
+ memcpy(entry->key, key, keylen);
+ entry->keylen = keylen;
+ entry->keyhash = tbl->hashfunc(entry->key, entry->keylen);
+ gf_msg_trace(GF_RBTHASH, 0, "HASH: %u", entry->keyhash);
+
+ ret = 0;
free_entry:
- if (ret == -1) {
- mem_put (entry);
- entry = NULL;
- }
+ if (ret == -1) {
+ mem_put(entry);
+ entry = NULL;
+ }
ret:
- return entry;
+ return entry;
}
-
void
-rbthash_deinit_entry (rbthash_table_t *tbl, rbthash_entry_t *entry)
+rbthash_deinit_entry(rbthash_table_t *tbl, rbthash_entry_t *entry)
{
+ if (!entry)
+ return;
- if (!entry)
- return;
-
- GF_FREE (entry->key);
-
- if (tbl) {
- if ((entry->data) && (tbl->dfunc))
- tbl->dfunc (entry->data);
+ GF_FREE(entry->key);
- LOCK (&tbl->tablelock);
- {
- list_del_init (&entry->list);
- }
- UNLOCK (&tbl->tablelock);
+ if (tbl) {
+ if ((entry->data) && (tbl->dfunc))
+ tbl->dfunc(entry->data);
- mem_put (entry);
+ LOCK(&tbl->tablelock);
+ {
+ list_del_init(&entry->list);
}
+ UNLOCK(&tbl->tablelock);
- return;
-}
+ mem_put(entry);
+ }
+ return;
+}
static struct rbthash_bucket *
-rbthash_entry_bucket (rbthash_table_t *tbl, rbthash_entry_t * entry)
+rbthash_entry_bucket(rbthash_table_t *tbl, rbthash_entry_t *entry)
{
- int nbucket = 0;
+ int nbucket = 0;
- nbucket = (entry->keyhash % tbl->numbuckets);
- gf_msg_trace (GF_RBTHASH, 0, "BUCKET: %d", nbucket);
- return &tbl->buckets[nbucket];
+ nbucket = (entry->keyhash % tbl->numbuckets);
+ gf_msg_trace(GF_RBTHASH, 0, "BUCKET: %d", nbucket);
+ return &tbl->buckets[nbucket];
}
-
int
-rbthash_insert_entry (rbthash_table_t *tbl, rbthash_entry_t *entry)
+rbthash_insert_entry(rbthash_table_t *tbl, rbthash_entry_t *entry)
{
- struct rbthash_bucket *bucket = NULL;
- int ret = -1;
-
- if ((!tbl) || (!entry))
- return -1;
-
- bucket = rbthash_entry_bucket (tbl, entry);
- if (!bucket) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
- LG_MSG_RBTHASH_GET_BUCKET_FAILED,
- "Failed to get bucket");
- goto err;
+ struct rbthash_bucket *bucket = NULL;
+ int ret = -1;
+
+ if ((!tbl) || (!entry))
+ return -1;
+
+ bucket = rbthash_entry_bucket(tbl, entry);
+ if (!bucket) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED,
+ NULL);
+ goto err;
+ }
+
+ ret = 0;
+ LOCK(&bucket->bucketlock);
+ {
+ if (!rb_probe(bucket->bucket, (void *)entry)) {
+ UNLOCK(&bucket->bucketlock);
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED,
+ NULL);
+ ret = -1;
+ goto err;
}
-
- ret = 0;
- LOCK (&bucket->bucketlock);
- {
- if (!rb_probe (bucket->bucket, (void *)entry)) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
- LG_MSG_RBTHASH_INSERT_FAILED, "Failed to insert"
- " entry");
- ret = -1;
- }
- }
- UNLOCK (&bucket->bucketlock);
+ }
+ UNLOCK(&bucket->bucketlock);
err:
- return ret;
+ return ret;
}
-
int
-rbthash_insert (rbthash_table_t *tbl, void *data, void *key, int keylen)
+rbthash_insert(rbthash_table_t *tbl, void *data, void *key, int keylen)
{
- rbthash_entry_t *entry = NULL;
- int ret = -1;
-
- if ((!tbl) || (!data) || (!key))
- return -1;
-
- entry = rbthash_init_entry (tbl, data, key, keylen);
- if (!entry) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
- LG_MSG_RBTHASH_INIT_ENTRY_FAILED,
- "Failed to init entry");
- goto err;
- }
-
- ret = rbthash_insert_entry (tbl, entry);
-
- if (ret == -1) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
- LG_MSG_RBTHASH_INSERT_FAILED,
- "Failed to insert entry");
- rbthash_deinit_entry (tbl, entry);
- }
-
- LOCK (&tbl->tablelock);
- {
- list_add_tail (&entry->list, &tbl->list);
- }
- UNLOCK (&tbl->tablelock);
+ rbthash_entry_t *entry = NULL;
+ int ret = -1;
+
+ if ((!tbl) || (!data) || (!key))
+ return -1;
+
+ entry = rbthash_init_entry(tbl, data, key, keylen);
+ if (!entry) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INIT_ENTRY_FAILED,
+ NULL);
+ goto err;
+ }
+
+ ret = rbthash_insert_entry(tbl, entry);
+
+ if (ret == -1) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_INSERT_FAILED,
+ NULL);
+ rbthash_deinit_entry(tbl, entry);
+ goto err;
+ }
+
+ LOCK(&tbl->tablelock);
+ {
+ list_add_tail(&entry->list, &tbl->list);
+ }
+ UNLOCK(&tbl->tablelock);
err:
- return ret;
+ return ret;
}
static struct rbthash_bucket *
-rbthash_key_bucket (rbthash_table_t *tbl, void *key, int keylen)
+rbthash_key_bucket(rbthash_table_t *tbl, void *key, int keylen)
{
- uint32_t keyhash = 0;
- int nbucket = 0;
+ uint32_t keyhash = 0;
+ int nbucket = 0;
- if ((!tbl) || (!key))
- return NULL;
+ if ((!tbl) || (!key))
+ return NULL;
- keyhash = tbl->hashfunc (key, keylen);
- gf_msg_trace (GF_RBTHASH, 0, "HASH: %u", keyhash);
- nbucket = (keyhash % tbl->numbuckets);
- gf_msg_trace (GF_RBTHASH, 0, "BUCKET: %u", nbucket);
+ keyhash = tbl->hashfunc(key, keylen);
+ gf_msg_trace(GF_RBTHASH, 0, "HASH: %u", keyhash);
+ nbucket = (keyhash % tbl->numbuckets);
+ gf_msg_trace(GF_RBTHASH, 0, "BUCKET: %u", nbucket);
- return &tbl->buckets[nbucket];
+ return &tbl->buckets[nbucket];
}
-
void *
-rbthash_get (rbthash_table_t *tbl, void *key, int keylen)
+rbthash_get(rbthash_table_t *tbl, void *key, int keylen)
{
- struct rbthash_bucket *bucket = NULL;
- rbthash_entry_t *entry = NULL;
- rbthash_entry_t searchentry = {0, };
-
- if ((!tbl) || (!key))
- return NULL;
-
- bucket = rbthash_key_bucket (tbl, key, keylen);
- if (!bucket) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_GET_BUCKET_FAILED,
- "Failed to get bucket");
- return NULL;
- }
-
- searchentry.key = key;
- searchentry.keylen = keylen;
- LOCK (&bucket->bucketlock);
- {
- entry = rb_find (bucket->bucket, &searchentry);
- }
- UNLOCK (&bucket->bucketlock);
-
- if (!entry)
- return NULL;
-
- return entry->data;
+ struct rbthash_bucket *bucket = NULL;
+ rbthash_entry_t *entry = NULL;
+ rbthash_entry_t searchentry = {
+ 0,
+ };
+
+ if ((!tbl) || (!key))
+ return NULL;
+
+ bucket = rbthash_key_bucket(tbl, key, keylen);
+ if (!bucket) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED,
+ NULL);
+ return NULL;
+ }
+
+ searchentry.key = key;
+ searchentry.keylen = keylen;
+ LOCK(&bucket->bucketlock);
+ {
+ entry = rb_find(bucket->bucket, &searchentry);
+ }
+ UNLOCK(&bucket->bucketlock);
+
+ if (!entry)
+ return NULL;
+
+ return entry->data;
}
-
void *
-rbthash_remove (rbthash_table_t *tbl, void *key, int keylen)
+rbthash_remove(rbthash_table_t *tbl, void *key, int keylen)
{
- struct rbthash_bucket *bucket = NULL;
- rbthash_entry_t *entry = NULL;
- rbthash_entry_t searchentry = {0, };
- void *dataref = NULL;
-
- if ((!tbl) || (!key))
- return NULL;
-
- bucket = rbthash_key_bucket (tbl, key, keylen);
- if (!bucket) {
- gf_msg (GF_RBTHASH, GF_LOG_ERROR, 0,
- LG_MSG_RBTHASH_GET_BUCKET_FAILED,
- "Failed to get bucket");
- return NULL;
- }
-
- searchentry.key = key;
- searchentry.keylen = keylen;
-
- LOCK (&bucket->bucketlock);
- {
- entry = rb_delete (bucket->bucket, &searchentry);
- }
- UNLOCK (&bucket->bucketlock);
-
- if (!entry)
- return NULL;
-
- GF_FREE (entry->key);
- dataref = entry->data;
-
- LOCK (&tbl->tablelock);
- {
- list_del_init (&entry->list);
- }
- UNLOCK (&tbl->tablelock);
-
- mem_put (entry);
-
- return dataref;
+ struct rbthash_bucket *bucket = NULL;
+ rbthash_entry_t *entry = NULL;
+ rbthash_entry_t searchentry = {
+ 0,
+ };
+ void *dataref = NULL;
+
+ if ((!tbl) || (!key))
+ return NULL;
+
+ bucket = rbthash_key_bucket(tbl, key, keylen);
+ if (!bucket) {
+ gf_smsg(GF_RBTHASH, GF_LOG_ERROR, 0, LG_MSG_RBTHASH_GET_BUCKET_FAILED,
+ NULL);
+ return NULL;
+ }
+
+ searchentry.key = key;
+ searchentry.keylen = keylen;
+
+ LOCK(&bucket->bucketlock);
+ {
+ entry = rb_delete(bucket->bucket, &searchentry);
+ }
+ UNLOCK(&bucket->bucketlock);
+
+ if (!entry)
+ return NULL;
+
+ GF_FREE(entry->key);
+ dataref = entry->data;
+
+ LOCK(&tbl->tablelock);
+ {
+ list_del_init(&entry->list);
+ }
+ UNLOCK(&tbl->tablelock);
+
+ mem_put(entry);
+
+ return dataref;
}
-
void
-rbthash_entry_deiniter (void *entry, void *rbparam)
+rbthash_entry_deiniter(void *entry, void *rbparam)
{
- if (!entry)
- return;
+ if (!entry)
+ return;
- rbthash_deinit_entry (rbparam, entry);
+ rbthash_deinit_entry(rbparam, entry);
}
-
void
-rbthash_table_destroy_buckets (rbthash_table_t *tbl)
+rbthash_table_destroy_buckets(rbthash_table_t *tbl)
{
- int x = 0;
- if (!tbl)
- return;
+ int x = 0;
+ if (!tbl)
+ return;
- for (;x < tbl->numbuckets; x++) {
- LOCK_DESTROY (&tbl->buckets[x].bucketlock);
- rb_destroy (tbl->buckets[x].bucket, rbthash_entry_deiniter);
- }
+ for (; x < tbl->numbuckets; x++) {
+ LOCK_DESTROY(&tbl->buckets[x].bucketlock);
+ rb_destroy(tbl->buckets[x].bucket, rbthash_entry_deiniter);
+ }
- return;
+ return;
}
-
void
-rbthash_table_destroy (rbthash_table_t *tbl)
+rbthash_table_destroy(rbthash_table_t *tbl)
{
- if (!tbl)
- return;
+ if (!tbl)
+ return;
- rbthash_table_destroy_buckets (tbl);
- if (tbl->pool_alloced)
- mem_pool_destroy (tbl->entrypool);
+ rbthash_table_destroy_buckets(tbl);
+ if (tbl->pool_alloced)
+ mem_pool_destroy(tbl->entrypool);
- GF_FREE (tbl->buckets);
- GF_FREE (tbl);
+ GF_FREE(tbl->buckets);
+ GF_FREE(tbl);
}
-
void
-rbthash_table_traverse (rbthash_table_t *tbl, rbt_traverse_t traverse,
- void *mydata)
+rbthash_table_traverse(rbthash_table_t *tbl, rbt_traverse_t traverse,
+ void *mydata)
{
- rbthash_entry_t *entry = NULL;
+ rbthash_entry_t *entry = NULL;
- if ((tbl == NULL) || (traverse == NULL)) {
- goto out;
- }
+ if ((tbl == NULL) || (traverse == NULL)) {
+ goto out;
+ }
- LOCK (&tbl->tablelock);
+ LOCK(&tbl->tablelock);
+ {
+ list_for_each_entry(entry, &tbl->list, list)
{
- list_for_each_entry (entry, &tbl->list, list) {
- traverse (entry->data, mydata);
- }
+ traverse(entry->data, mydata);
}
- UNLOCK (&tbl->tablelock);
+ }
+ UNLOCK(&tbl->tablelock);
out:
- return;
+ return;
}
diff --git a/libglusterfs/src/rbthash.h b/libglusterfs/src/rbthash.h
deleted file mode 100644
index b093ce9982d..00000000000
--- a/libglusterfs/src/rbthash.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- 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 __RBTHASH_TABLE_H_
-#define __RBTHASH_TABLE_H_
-#include "rb.h"
-#include "locking.h"
-#include "mem-pool.h"
-#include "logging.h"
-#include "common-utils.h"
-#include "list.h"
-
-#include <pthread.h>
-
-#define GF_RBTHASH_MEMPOOL 16384 //1048576
-#define GF_RBTHASH "rbthash"
-
-struct rbthash_bucket {
- struct rb_table *bucket;
- gf_lock_t bucketlock;
-};
-
-typedef struct rbthash_entry {
- void *data;
- void *key;
- 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;
- int numbuckets;
- struct mem_pool *entrypool;
- gf_lock_t tablelock;
- struct rbthash_bucket *buckets;
- 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 *
-rbthash_table_init (int buckets, rbt_hasher_t hfunc,
- rbt_data_destroyer_t dfunc, unsigned long expected_entries,
- struct mem_pool *entrypool);
-
-extern int
-rbthash_insert (rbthash_table_t *tbl, void *data, void *key, int keylen);
-
-extern void *
-rbthash_get (rbthash_table_t *tbl, void *key, int keylen);
-
-extern void *
-rbthash_remove (rbthash_table_t *tbl, void *key, int keylen);
-
-extern void *
-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/refcount.c b/libglusterfs/src/refcount.c
index 96edc10982a..d5a5a82fa0f 100644
--- a/libglusterfs/src/refcount.c
+++ b/libglusterfs/src/refcount.c
@@ -8,105 +8,101 @@
cases as published by the Free Software Foundation.
*/
-#include "common-utils.h"
-#include "refcount.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/refcount.h"
#ifndef REFCOUNT_NEEDS_LOCK
-unsigned int
-_gf_ref_get (gf_ref_t *ref)
+void *
+_gf_ref_get(gf_ref_t *ref)
{
- unsigned int cnt = __sync_fetch_and_add (&ref->cnt, 1);
-
- /* if cnt == 0, we're in a fatal position, the object will be free'd
- *
- * There is a race when two threads do a _gf_ref_get(). Only one of
- * them may get a 0 returned. That is acceptible, because one
- * _gf_ref_get() returning 0 should be handled as a fatal problem and
- * when correct usage/locking is used, it should never happen.
- */
- GF_ASSERT (cnt != 0);
-
- return cnt;
+ unsigned int cnt = __sync_fetch_and_add(&ref->cnt, 1);
+
+ /* if cnt == 0, we're in a fatal position, the object will be free'd
+ *
+ * There is a race when two threads do a _gf_ref_get(). Only one of
+ * them may get a 0 returned. That is acceptable, because one
+ * _gf_ref_get() returning 0 should be handled as a fatal problem and
+ * when correct usage/locking is used, it should never happen.
+ */
+ GF_ASSERT(cnt != 0);
+
+ return cnt ? ref->data : NULL;
}
unsigned int
-_gf_ref_put (gf_ref_t *ref)
+_gf_ref_put(gf_ref_t *ref)
{
- unsigned int cnt = __sync_fetch_and_sub (&ref->cnt, 1);
-
- /* if cnt == 1, the last user just did a _gf_ref_put()
- *
- * When cnt == 0, one _gf_ref_put() was done too much and there has
- * been a thread using the refcounted structure when it was not
- * supposed to.
- */
- GF_ASSERT (cnt != 0);
-
- if (cnt == 1 && ref->release) {
- ref->release (ref->data);
- /* set return value to 0 to inform the caller correctly */
- cnt = 0;
- }
-
- return cnt;
+ unsigned int cnt = __sync_fetch_and_sub(&ref->cnt, 1);
+
+ /* if cnt == 1, the last user just did a _gf_ref_put()
+ *
+ * When cnt == 0, one _gf_ref_put() was done too much and there has
+ * been a thread using the refcounted structure when it was not
+ * supposed to.
+ */
+ GF_ASSERT(cnt != 0);
+
+ if (cnt == 1 && ref->release)
+ ref->release(ref->data);
+
+ return (cnt != 1);
}
#else
-unsigned int
-_gf_ref_get (gf_ref_t *ref)
+void *
+_gf_ref_get(gf_ref_t *ref)
{
- unsigned int cnt = 0;
-
- LOCK (&ref->lk);
- {
- /* never can be 0, should have been free'd */
- if (ref->cnt > 0)
- cnt = ++ref->cnt;
- else
- GF_ASSERT (ref->cnt > 0);
- }
- UNLOCK (&ref->lk);
-
- return cnt;
+ unsigned int cnt = 0;
+
+ LOCK(&ref->lk);
+ {
+ /* never can be 0, should have been free'd */
+ if (ref->cnt > 0)
+ cnt = ++ref->cnt;
+ else
+ GF_ASSERT(ref->cnt > 0);
+ }
+ UNLOCK(&ref->lk);
+
+ return cnt ? ref->data : NULL;
}
unsigned int
-_gf_ref_put (gf_ref_t *ref)
+_gf_ref_put(gf_ref_t *ref)
{
- unsigned int cnt = 0;
- int release = 0;
-
- LOCK (&ref->lk);
- {
- if (ref->cnt != 0) {
- cnt = --ref->cnt;
- /* call release() only when cnt == 0 */
- release = (cnt == 0);
- } else
- GF_ASSERT (ref->cnt != 0);
- }
- UNLOCK (&ref->lk);
-
- if (release && ref->release)
- ref->release (ref->data);
-
- return cnt;
+ unsigned int cnt = 0;
+ int release = 0;
+
+ LOCK(&ref->lk);
+ {
+ if (ref->cnt != 0) {
+ cnt = --ref->cnt;
+ /* call release() only when cnt == 0 */
+ release = (cnt == 0);
+ } else
+ GF_ASSERT(ref->cnt != 0);
+ }
+ UNLOCK(&ref->lk);
+
+ if (release && ref->release)
+ ref->release(ref->data);
+
+ return !release;
}
#endif /* REFCOUNT_NEEDS_LOCK */
-
void
-_gf_ref_init (gf_ref_t *ref, gf_ref_release_t release, void *data)
+_gf_ref_init(gf_ref_t *ref, gf_ref_release_t release, void *data)
{
- GF_ASSERT (ref);
+ GF_ASSERT(ref);
#ifdef REFCOUNT_NEEDS_LOCK
- LOCK_INIT (&ref->lk);
+ LOCK_INIT(&ref->lk);
#endif
- ref->cnt = 1;
- ref->release = release;
- ref->data = data;
+ ref->cnt = 1;
+ ref->release = release;
+ ref->data = data;
}
diff --git a/libglusterfs/src/revision.h b/libglusterfs/src/revision.h
deleted file mode 100644
index c1ea4a9e9fe..00000000000
--- a/libglusterfs/src/revision.h
+++ /dev/null
@@ -1 +0,0 @@
-#define GLUSTERFS_REPOSITORY_REVISION "git://git.gluster.com/glusterfs.git"
diff --git a/libglusterfs/src/rot-buffs.c b/libglusterfs/src/rot-buffs.c
index 4f3eb35fa96..260bf16ecea 100644
--- a/libglusterfs/src/rot-buffs.c
+++ b/libglusterfs/src/rot-buffs.c
@@ -10,10 +10,10 @@
#include <math.h>
-#include "mem-types.h"
-#include "mem-pool.h"
+#include "glusterfs/mem-types.h"
+#include "glusterfs/mem-pool.h"
-#include "rot-buffs.h"
+#include "glusterfs/rot-buffs.h"
/**
* Producer-Consumer based on top of rotational buffers.
@@ -26,384 +26,383 @@
* TODO: do away with opaques (use arrays with indexing).
*/
-#define ROT_BUFF_DEFAULT_COUNT 2
-#define ROT_BUFF_ALLOC_SIZE (1 * 1024 * 1024) /* 1MB per iovec */
+#define ROT_BUFF_DEFAULT_COUNT 2
+#define ROT_BUFF_ALLOC_SIZE (1 * 1024 * 1024) /* 1MB per iovec */
-#define RLIST_IOV_MELDED_ALLOC_SIZE (RBUF_IOVEC_SIZE + ROT_BUFF_ALLOC_SIZE)
+#define RLIST_IOV_MELDED_ALLOC_SIZE (RBUF_IOVEC_SIZE + ROT_BUFF_ALLOC_SIZE)
/**
- * iovec list is not shrinked (deallocated) if usage/total count
+ * iovec list is not shrunk (deallocated) if usage/total count
* falls in this range. this is the fast path and should satisfy
* most of the workloads. for the rest shrinking iovec list is
* generous.
*/
-#define RVEC_LOW_WATERMARK_COUNT 1
+#define RVEC_LOW_WATERMARK_COUNT 1
#define RVEC_HIGH_WATERMARK_COUNT (1 << 4)
-static inline
-rbuf_list_t *rbuf_current_buffer (rbuf_t *rbuf)
+static inline rbuf_list_t *
+rbuf_current_buffer(rbuf_t *rbuf)
{
- return rbuf->current;
+ return rbuf->current;
}
static void
-rlist_mark_waiting (rbuf_list_t *rlist)
+rlist_mark_waiting(rbuf_list_t *rlist)
{
- LOCK (&rlist->c_lock);
- {
- rlist->awaiting = _gf_true;
- }
- UNLOCK (&rlist->c_lock);
+ LOCK(&rlist->c_lock);
+ {
+ rlist->awaiting = _gf_true;
+ }
+ UNLOCK(&rlist->c_lock);
}
static int
-__rlist_has_waiter (rbuf_list_t *rlist)
+__rlist_has_waiter(rbuf_list_t *rlist)
{
- return (rlist->awaiting == _gf_true);
+ return (rlist->awaiting == _gf_true);
}
static void *
-rbuf_alloc_rvec ()
+rbuf_alloc_rvec()
{
- return GF_CALLOC (1, RLIST_IOV_MELDED_ALLOC_SIZE, gf_common_mt_rvec_t);
+ return GF_CALLOC(1, RLIST_IOV_MELDED_ALLOC_SIZE, gf_common_mt_rvec_t);
}
static void
-rlist_reset_vector_usage (rbuf_list_t *rlist)
+rlist_reset_vector_usage(rbuf_list_t *rlist)
{
- rlist->used = 1;
+ rlist->used = 1;
}
static void
-rlist_increment_vector_usage (rbuf_list_t *rlist)
+rlist_increment_vector_usage(rbuf_list_t *rlist)
{
- rlist->used++;
+ rlist->used++;
}
static void
-rlist_increment_total_usage (rbuf_list_t *rlist)
+rlist_increment_total_usage(rbuf_list_t *rlist)
{
- rlist->total++;
+ rlist->total++;
}
static int
-rvec_in_watermark_range (rbuf_list_t *rlist)
+rvec_in_watermark_range(rbuf_list_t *rlist)
{
- return ((rlist->total >= RVEC_LOW_WATERMARK_COUNT)
- && (rlist->total <= RVEC_HIGH_WATERMARK_COUNT));
+ return ((rlist->total >= RVEC_LOW_WATERMARK_COUNT) &&
+ (rlist->total <= RVEC_HIGH_WATERMARK_COUNT));
}
static void
-rbuf_reset_rvec (rbuf_iovec_t *rvec)
+rbuf_reset_rvec(rbuf_iovec_t *rvec)
{
- /* iov_base is _never_ modified */
- rvec->iov.iov_len = 0;
+ GF_VALIDATE_OR_GOTO("libglusterfs", rvec, err);
+ /* iov_base is _never_ modified */
+ rvec->iov.iov_len = 0;
+err:
+ return;
}
/* TODO: alloc multiple rbuf_iovec_t */
static int
-rlist_add_new_vec (rbuf_list_t *rlist)
+rlist_add_new_vec(rbuf_list_t *rlist)
{
- rbuf_iovec_t *rvec = NULL;
+ rbuf_iovec_t *rvec = NULL;
- rvec = (rbuf_iovec_t *) rbuf_alloc_rvec ();
- if (!rvec)
- return -1;
- INIT_LIST_HEAD (&rvec->list);
- rvec->iov.iov_base = ((char *)rvec) + RBUF_IOVEC_SIZE;
- rvec->iov.iov_len = 0;
+ rvec = (rbuf_iovec_t *)rbuf_alloc_rvec();
+ if (!rvec)
+ return -1;
+ INIT_LIST_HEAD(&rvec->list);
+ rvec->iov.iov_base = ((char *)rvec) + RBUF_IOVEC_SIZE;
+ rvec->iov.iov_len = 0;
- list_add_tail (&rvec->list, &rlist->veclist);
+ list_add_tail(&rvec->list, &rlist->veclist);
- rlist->rvec = rvec; /* cache the latest */
+ rlist->rvec = rvec; /* cache the latest */
- rlist_increment_vector_usage (rlist);
- rlist_increment_total_usage (rlist);
+ rlist_increment_vector_usage(rlist);
+ rlist_increment_total_usage(rlist);
- return 0;
+ return 0;
}
static void
-rlist_free_rvec (rbuf_iovec_t *rvec)
+rlist_free_rvec(rbuf_iovec_t *rvec)
{
- if (!rvec)
- return;
- list_del (&rvec->list);
- GF_FREE (rvec);
+ if (!rvec)
+ return;
+ list_del(&rvec->list);
+ GF_FREE(rvec);
}
static void
-rlist_purge_all_rvec (rbuf_list_t *rlist)
+rlist_purge_all_rvec(rbuf_list_t *rlist)
{
- rbuf_iovec_t *rvec = NULL;
-
- if (!rlist)
- return;
- while (!list_empty (&rlist->veclist)) {
- rvec = list_first_entry (&rlist->veclist, rbuf_iovec_t, list);
- rlist_free_rvec (rvec);
- }
+ rbuf_iovec_t *rvec = NULL;
+
+ if (!rlist)
+ return;
+ while (!list_empty(&rlist->veclist)) {
+ rvec = list_first_entry(&rlist->veclist, rbuf_iovec_t, list);
+ rlist_free_rvec(rvec);
+ }
}
static void
-rlist_shrink_rvec (rbuf_list_t *rlist, unsigned long long shrink)
+rlist_shrink_rvec(rbuf_list_t *rlist, unsigned long long shrink)
{
- rbuf_iovec_t *rvec = NULL;
+ rbuf_iovec_t *rvec = NULL;
- while (!list_empty (&rlist->veclist) && (shrink-- > 0)) {
- rvec = list_first_entry (&rlist->veclist, rbuf_iovec_t, list);
- rlist_free_rvec (rvec);
- }
+ while (!list_empty(&rlist->veclist) && (shrink-- > 0)) {
+ rvec = list_first_entry(&rlist->veclist, rbuf_iovec_t, list);
+ rlist_free_rvec(rvec);
+ }
}
static void
-rbuf_purge_rlist (rbuf_t *rbuf)
+rbuf_purge_rlist(rbuf_t *rbuf)
{
- rbuf_list_t *rlist = NULL;
+ rbuf_list_t *rlist = NULL;
- while (!list_empty (&rbuf->freelist)) {
- rlist = list_first_entry (&rbuf->freelist, rbuf_list_t, list);
- list_del (&rlist->list);
+ while (!list_empty(&rbuf->freelist)) {
+ rlist = list_first_entry(&rbuf->freelist, rbuf_list_t, list);
+ list_del(&rlist->list);
- rlist_purge_all_rvec (rlist);
+ rlist_purge_all_rvec(rlist);
- LOCK_DESTROY (&rlist->c_lock);
+ LOCK_DESTROY(&rlist->c_lock);
- (void) pthread_mutex_destroy (&rlist->b_lock);
- (void) pthread_cond_destroy (&rlist->b_cond);
+ (void)pthread_mutex_destroy(&rlist->b_lock);
+ (void)pthread_cond_destroy(&rlist->b_cond);
- GF_FREE (rlist);
- }
+ GF_FREE(rlist);
+ }
}
rbuf_t *
-rbuf_init (int bufcount)
+rbuf_init(int bufcount)
{
- int j = 0;
- int ret = 0;
- rbuf_t *rbuf = NULL;
- rbuf_list_t *rlist = NULL;
-
- if (bufcount <= 0)
- bufcount = ROT_BUFF_DEFAULT_COUNT;
-
- rbuf = GF_CALLOC (1, sizeof (rbuf_t), gf_common_mt_rbuf_t);
- if (!rbuf)
- goto error_return;
-
- LOCK_INIT (&rbuf->lock);
- INIT_LIST_HEAD (&rbuf->freelist);
-
- /* it could have been one big calloc() but this is just once.. */
- for (j = 0; j < bufcount; j++) {
- rlist = GF_CALLOC (1,
- sizeof (rbuf_list_t), gf_common_mt_rlist_t);
- if (!rlist) {
- ret = -1;
- break;
- }
-
- INIT_LIST_HEAD (&rlist->list);
- INIT_LIST_HEAD (&rlist->veclist);
-
- rlist->pending = rlist->completed = 0;
-
- ret = rlist_add_new_vec (rlist);
- if (ret)
- break;
-
- LOCK_INIT (&rlist->c_lock);
-
- rlist->awaiting = _gf_false;
- ret = pthread_mutex_init (&rlist->b_lock, 0);
- if (ret != 0) {
- GF_FREE (rlist);
- break;
- }
-
- ret = pthread_cond_init (&rlist->b_cond, 0);
- if (ret != 0) {
- GF_FREE (rlist);
- break;
- }
-
- list_add_tail (&rlist->list, &rbuf->freelist);
+ int j = 0;
+ int ret = 0;
+ rbuf_t *rbuf = NULL;
+ rbuf_list_t *rlist = NULL;
+
+ if (bufcount <= 0)
+ bufcount = ROT_BUFF_DEFAULT_COUNT;
+
+ rbuf = GF_CALLOC(1, sizeof(rbuf_t), gf_common_mt_rbuf_t);
+ if (!rbuf)
+ goto error_return;
+
+ LOCK_INIT(&rbuf->lock);
+ INIT_LIST_HEAD(&rbuf->freelist);
+
+ /* it could have been one big calloc() but this is just once.. */
+ for (j = 0; j < bufcount; j++) {
+ rlist = GF_CALLOC(1, sizeof(rbuf_list_t), gf_common_mt_rlist_t);
+ if (!rlist) {
+ ret = -1;
+ break;
}
- if (ret != 0)
- goto dealloc_rlist;
+ INIT_LIST_HEAD(&rlist->list);
+ INIT_LIST_HEAD(&rlist->veclist);
- /* cache currently used buffer: first in the list */
- rbuf->current = list_first_entry (&rbuf->freelist, rbuf_list_t, list);
- return rbuf;
+ rlist->pending = rlist->completed = 0;
- dealloc_rlist:
- rbuf_purge_rlist (rbuf);
- LOCK_DESTROY (&rbuf->lock);
- GF_FREE (rbuf);
- error_return:
- return NULL;
+ ret = rlist_add_new_vec(rlist);
+ if (ret)
+ break;
+
+ LOCK_INIT(&rlist->c_lock);
+
+ rlist->awaiting = _gf_false;
+ ret = pthread_mutex_init(&rlist->b_lock, 0);
+ if (ret != 0) {
+ GF_FREE(rlist);
+ break;
+ }
+
+ ret = pthread_cond_init(&rlist->b_cond, 0);
+ if (ret != 0) {
+ GF_FREE(rlist);
+ break;
+ }
+
+ list_add_tail(&rlist->list, &rbuf->freelist);
+ }
+
+ if (ret != 0)
+ goto dealloc_rlist;
+
+ /* cache currently used buffer: first in the list */
+ rbuf->current = list_first_entry(&rbuf->freelist, rbuf_list_t, list);
+ return rbuf;
+
+dealloc_rlist:
+ rbuf_purge_rlist(rbuf);
+ LOCK_DESTROY(&rbuf->lock);
+ GF_FREE(rbuf);
+error_return:
+ return NULL;
}
void
-rbuf_dtor (rbuf_t *rbuf)
+rbuf_dtor(rbuf_t *rbuf)
{
- if (!rbuf)
- return;
- rbuf->current = NULL;
- rbuf_purge_rlist (rbuf);
- LOCK_DESTROY (&rbuf->lock);
+ if (!rbuf)
+ return;
+ rbuf->current = NULL;
+ rbuf_purge_rlist(rbuf);
+ LOCK_DESTROY(&rbuf->lock);
- GF_FREE (rbuf);
+ GF_FREE(rbuf);
}
static char *
-rbuf_adjust_write_area (struct iovec *iov, size_t bytes)
+rbuf_adjust_write_area(struct iovec *iov, size_t bytes)
{
- char *wbuf = NULL;
+ char *wbuf = NULL;
- wbuf = iov->iov_base + iov->iov_len;
- iov->iov_len += bytes;
- return wbuf;
+ wbuf = iov->iov_base + iov->iov_len;
+ iov->iov_len += bytes;
+ return wbuf;
}
static char *
-rbuf_alloc_write_area (rbuf_list_t *rlist, size_t bytes)
+rbuf_alloc_write_area(rbuf_list_t *rlist, size_t bytes)
{
- int ret = 0;
- struct iovec *iov = NULL;
-
- /* check for available space in _current_ IO buffer */
- iov = &rlist->rvec->iov;
- if (iov->iov_len + bytes <= ROT_BUFF_ALLOC_SIZE)
- return rbuf_adjust_write_area (iov, bytes); /* fast path */
-
- /* not enough bytes, try next available buffers */
- if (list_is_last (&rlist->rvec->list, &rlist->veclist)) {
- /* OH! consumed all vector buffers */
- GF_ASSERT (rlist->used == rlist->total);
- ret = rlist_add_new_vec (rlist);
- if (ret)
- goto error_return;
- } else {
- /* not the end, have available rbuf_iovec's */
- rlist->rvec = list_next_entry (rlist->rvec, list);
- rlist->used++;
- rbuf_reset_rvec (rlist->rvec);
- }
+ int ret = 0;
+ struct iovec *iov = NULL;
+
+ /* check for available space in _current_ IO buffer */
+ iov = &rlist->rvec->iov;
+ if (iov->iov_len + bytes <= ROT_BUFF_ALLOC_SIZE)
+ return rbuf_adjust_write_area(iov, bytes); /* fast path */
+
+ /* not enough bytes, try next available buffers */
+ if (list_is_last(&rlist->rvec->list, &rlist->veclist)) {
+ /* OH! consumed all vector buffers */
+ GF_ASSERT(rlist->used == rlist->total);
+ ret = rlist_add_new_vec(rlist);
+ if (ret)
+ goto error_return;
+ } else {
+ /* not the end, have available rbuf_iovec's */
+ rlist->rvec = list_next_entry(rlist->rvec, list);
+ rlist->used++;
+ rbuf_reset_rvec(rlist->rvec);
+ }
- iov = &rlist->rvec->iov;
- return rbuf_adjust_write_area (iov, bytes);
+ iov = &rlist->rvec->iov;
+ return rbuf_adjust_write_area(iov, bytes);
- error_return:
- return NULL;
+error_return:
+ return NULL;
}
char *
-rbuf_reserve_write_area (rbuf_t *rbuf, size_t bytes, void **opaque)
+rbuf_reserve_write_area(rbuf_t *rbuf, size_t bytes, void **opaque)
{
- char *wbuf = NULL;
- rbuf_list_t *rlist = NULL;
-
- if (!rbuf || (bytes <= 0) || (bytes > ROT_BUFF_ALLOC_SIZE) || !opaque)
- return NULL;
-
- LOCK (&rbuf->lock);
- {
- rlist = rbuf_current_buffer (rbuf);
- wbuf = rbuf_alloc_write_area (rlist, bytes);
- if (!wbuf)
- goto unblock;
- rlist->pending++;
- }
- unblock:
- UNLOCK (&rbuf->lock);
+ char *wbuf = NULL;
+ rbuf_list_t *rlist = NULL;
+
+ if (!rbuf || (bytes <= 0) || (bytes > ROT_BUFF_ALLOC_SIZE) || !opaque)
+ return NULL;
- if (wbuf)
- *opaque = rlist;
- return wbuf;
+ LOCK(&rbuf->lock);
+ {
+ rlist = rbuf_current_buffer(rbuf);
+ wbuf = rbuf_alloc_write_area(rlist, bytes);
+ if (!wbuf)
+ goto unblock;
+ rlist->pending++;
+ }
+unblock:
+ UNLOCK(&rbuf->lock);
+
+ if (wbuf)
+ *opaque = rlist;
+ return wbuf;
}
static void
-rbuf_notify_waiter (rbuf_list_t *rlist)
+rbuf_notify_waiter(rbuf_list_t *rlist)
{
- pthread_mutex_lock (&rlist->b_lock);
- {
- pthread_cond_signal (&rlist->b_cond);
- }
- pthread_mutex_unlock (&rlist->b_lock);
+ pthread_mutex_lock(&rlist->b_lock);
+ {
+ pthread_cond_signal(&rlist->b_cond);
+ }
+ pthread_mutex_unlock(&rlist->b_lock);
}
int
-rbuf_write_complete (void *opaque)
+rbuf_write_complete(void *opaque)
{
- rbuf_list_t *rlist = NULL;
- gf_boolean_t notify = _gf_false;
-
- if (!opaque)
- return -1;
-
- rlist = opaque;
-
- LOCK (&rlist->c_lock);
- {
- rlist->completed++;
- /**
- * it's safe to test ->pending without rbuf->lock *only* if
- * there's a waiter as there can be no new incoming writes.
- */
- if (__rlist_has_waiter (rlist)
- && (rlist->completed == rlist->pending))
- notify = _gf_true;
- }
- UNLOCK (&rlist->c_lock);
+ rbuf_list_t *rlist = NULL;
+ gf_boolean_t notify = _gf_false;
+
+ if (!opaque)
+ return -1;
+
+ rlist = opaque;
+
+ LOCK(&rlist->c_lock);
+ {
+ rlist->completed++;
+ /**
+ * it's safe to test ->pending without rbuf->lock *only* if
+ * there's a waiter as there can be no new incoming writes.
+ */
+ if (__rlist_has_waiter(rlist) && (rlist->completed == rlist->pending))
+ notify = _gf_true;
+ }
+ UNLOCK(&rlist->c_lock);
- if (notify)
- rbuf_notify_waiter (rlist);
+ if (notify)
+ rbuf_notify_waiter(rlist);
- return 0;
+ return 0;
}
int
-rbuf_get_buffer (rbuf_t *rbuf,
- void **opaque, sequence_fn *seqfn, void *mydata)
+rbuf_get_buffer(rbuf_t *rbuf, void **opaque, sequence_fn *seqfn, void *mydata)
{
- int retval = RBUF_CONSUMABLE;
- rbuf_list_t *rlist = NULL;
-
- if (!rbuf || !opaque)
- return -1;
-
- LOCK (&rbuf->lock);
- {
- rlist = rbuf_current_buffer (rbuf);
- if (!rlist->pending) {
- retval = RBUF_EMPTY;
- goto unblock;
- }
-
- if (list_is_singular (&rbuf->freelist)) {
- /**
- * removal would lead to writer starvation, disallow
- * switching.
- */
- retval = RBUF_WOULD_STARVE;
- goto unblock;
- }
-
- list_del_init (&rlist->list);
- if (seqfn)
- seqfn (rlist, mydata);
- rbuf->current =
- list_first_entry (&rbuf->freelist, rbuf_list_t, list);
+ int retval = RBUF_CONSUMABLE;
+ rbuf_list_t *rlist = NULL;
+
+ if (!rbuf || !opaque)
+ return -1;
+
+ LOCK(&rbuf->lock);
+ {
+ rlist = rbuf_current_buffer(rbuf);
+ if (!rlist->pending) {
+ retval = RBUF_EMPTY;
+ goto unblock;
+ }
+
+ if (list_is_singular(&rbuf->freelist)) {
+ /**
+ * removal would lead to writer starvation, disallow
+ * switching.
+ */
+ retval = RBUF_WOULD_STARVE;
+ goto unblock;
}
- unblock:
- UNLOCK (&rbuf->lock);
- if (retval == RBUF_CONSUMABLE)
- *opaque = rlist; /* caller _owns_ the buffer */
+ list_del_init(&rlist->list);
+ if (seqfn)
+ seqfn(rlist, mydata);
+ rbuf->current = list_first_entry(&rbuf->freelist, rbuf_list_t, list);
+ }
+unblock:
+ UNLOCK(&rbuf->lock);
- return retval;
+ if (retval == RBUF_CONSUMABLE)
+ *opaque = rlist; /* caller _owns_ the buffer */
+
+ return retval;
}
/**
@@ -412,10 +411,10 @@ rbuf_get_buffer (rbuf_t *rbuf,
*/
static void
-__rbuf_wait_for_writers (rbuf_list_t *rlist)
+__rbuf_wait_for_writers(rbuf_list_t *rlist)
{
- while (rlist->completed != rlist->pending)
- pthread_cond_wait (&rlist->b_cond, &rlist->b_lock);
+ while (rlist->completed != rlist->pending)
+ pthread_cond_wait(&rlist->b_cond, &rlist->b_lock);
}
#ifndef M_E
@@ -423,69 +422,69 @@ __rbuf_wait_for_writers (rbuf_list_t *rlist)
#endif
static void
-rlist_shrink_vector (rbuf_list_t *rlist)
+rlist_shrink_vector(rbuf_list_t *rlist)
{
- unsigned long long shrink = 0;
-
- /**
- * fast path: don't bother to deallocate if vectors are hardly
- * used.
- */
- if (rvec_in_watermark_range (rlist))
- return;
-
- /**
- * Calculate the shrink count based on total allocated vectors.
- * Note that the calculation sticks to rlist->total irrespective
- * of the actual usage count (rlist->used). Later, ->used could
- * be used to apply slack to the calculation based on how much
- * it lags from ->total. For now, let's stick to slow decay.
- */
- shrink = rlist->total - (rlist->total * pow (M_E, -0.2));
-
- rlist_shrink_rvec (rlist, shrink);
- rlist->total -= shrink;
+ unsigned long long shrink = 0;
+
+ /**
+ * fast path: don't bother to deallocate if vectors are hardly
+ * used.
+ */
+ if (rvec_in_watermark_range(rlist))
+ return;
+
+ /**
+ * Calculate the shrink count based on total allocated vectors.
+ * Note that the calculation sticks to rlist->total irrespective
+ * of the actual usage count (rlist->used). Later, ->used could
+ * be used to apply slack to the calculation based on how much
+ * it lags from ->total. For now, let's stick to slow decay.
+ */
+ shrink = rlist->total - (rlist->total * pow(M_E, -0.2));
+
+ rlist_shrink_rvec(rlist, shrink);
+ rlist->total -= shrink;
}
int
-rbuf_wait_for_completion (rbuf_t *rbuf, void *opaque,
- void (*fn)(rbuf_list_t *, void *), void *arg)
+rbuf_wait_for_completion(rbuf_t *rbuf, void *opaque,
+ void (*fn)(rbuf_list_t *, void *), void *arg)
{
- rbuf_list_t *rlist = NULL;
+ rbuf_list_t *rlist = NULL;
- if (!rbuf || !opaque)
- return -1;
+ if (!rbuf || !opaque)
+ return -1;
- rlist = opaque;
+ rlist = opaque;
- pthread_mutex_lock (&rlist->b_lock);
- {
- rlist_mark_waiting (rlist);
- __rbuf_wait_for_writers (rlist);
- }
- pthread_mutex_unlock (&rlist->b_lock);
+ pthread_mutex_lock(&rlist->b_lock);
+ {
+ rlist_mark_waiting(rlist);
+ __rbuf_wait_for_writers(rlist);
+ }
+ pthread_mutex_unlock(&rlist->b_lock);
- /**
- * from here on, no need of locking until the rlist is put
- * back into rotation.
- */
+ /**
+ * from here on, no need of locking until the rlist is put
+ * back into rotation.
+ */
- fn (rlist, arg); /* invoke dispatcher */
+ fn(rlist, arg); /* invoke dispatcher */
- rlist->awaiting = _gf_false;
- rlist->pending = rlist->completed = 0;
+ rlist->awaiting = _gf_false;
+ rlist->pending = rlist->completed = 0;
- rlist_shrink_vector (rlist);
- rlist_reset_vector_usage (rlist);
+ rlist_shrink_vector(rlist);
+ rlist_reset_vector_usage(rlist);
- rlist->rvec = list_first_entry (&rlist->veclist, rbuf_iovec_t, list);
- rbuf_reset_rvec (rlist->rvec);
+ rlist->rvec = list_first_entry(&rlist->veclist, rbuf_iovec_t, list);
+ rbuf_reset_rvec(rlist->rvec);
- LOCK (&rbuf->lock);
- {
- list_add_tail (&rlist->list, &rbuf->freelist);
- }
- UNLOCK (&rbuf->lock);
+ LOCK(&rbuf->lock);
+ {
+ list_add_tail(&rlist->list, &rbuf->freelist);
+ }
+ UNLOCK(&rbuf->lock);
- return 0;
+ return 0;
}
diff --git a/libglusterfs/src/rot-buffs.h b/libglusterfs/src/rot-buffs.h
deleted file mode 100644
index aac24a4f571..00000000000
--- a/libglusterfs/src/rot-buffs.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- Copyright (c) 2008-2015 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 __ROT_BUFFS_H
-#define __ROT_BUFFS_H
-
-#include "list.h"
-#include "locking.h"
-#include "common-utils.h"
-
-typedef struct rbuf_iovec {
- struct iovec iov;
-
- struct list_head list;
-} rbuf_iovec_t;
-
-#define RBUF_IOVEC_SIZE (sizeof (rbuf_iovec_t))
-
-typedef struct rbuf_list {
- gf_lock_t c_lock;
-
- pthread_mutex_t b_lock; /* protects this structure */
- pthread_cond_t b_cond; /* signal for writer completion */
-
- gf_boolean_t awaiting;
-
- unsigned long long pending; /* pending writers */
- unsigned long long completed; /* completed writers */
-
- rbuf_iovec_t *rvec; /* currently used IO vector */
-
- struct list_head veclist; /* list of attached rbuf_iov */
-
- unsigned long long used; /* consumable entries
- attached in ->veclist */
- unsigned long long total; /* total entries in ->veclist (used
- during deallocation) */
-
- unsigned long seq[2]; /* if interested, this whould store
- the start sequence number and the
- range */
-
- struct list_head list; /* attachment to rbuf_t */
-} rbuf_list_t;
-
-struct rlist_iter {
- struct list_head veclist;
-
- unsigned long long iter;
-};
-
-#define RLIST_ENTRY_COUNT(rlist) rlist->used
-
-#define rlist_iter_init(riter, rlist) \
- do { \
- (riter)->iter = rlist->used; \
- (riter)->veclist = rlist->veclist; \
- } while (0)
-
-#define rvec_for_each_entry(pos, riter) \
- for (pos = list_entry \
- ((riter)->veclist.next, typeof(*pos), list); \
- (riter)->iter > 0; \
- pos = list_entry \
- (pos->list.next, typeof(*pos), list), \
- --((riter)->iter))
-
-/**
- * Sequence number assigment routine is called during buffer
- * switch under rbuff ->lock.
- */
-typedef void (sequence_fn) (rbuf_list_t *, void *);
-
-#define RLIST_STORE_SEQ(rlist, start, range) \
- do { \
- rlist->seq[0] = start; \
- rlist->seq[1] = range; \
- } while (0)
-
-#define RLIST_GET_SEQ(rlist, start, range) \
- do { \
- start = rlist->seq[0]; \
- range = rlist->seq[1]; \
- } while (0)
-
-typedef struct rbuf {
- gf_lock_t lock; /* protects "current" rlist */
-
- rbuf_list_t *current; /* cached pointer to first free rlist */
-
- struct list_head freelist;
-} rbuf_t;
-
-typedef enum {
- RBUF_CONSUMABLE = 1,
- RBUF_BUSY,
- RBUF_EMPTY,
- RBUF_WOULD_STARVE,
-} rlist_retval_t;
-
-/* Initialization/Destruction */
-rbuf_t *rbuf_init (int);
-void rbuf_dtor (rbuf_t *);
-
-/* Producer API */
-char *rbuf_reserve_write_area (rbuf_t *, size_t, void **);
-int rbuf_write_complete (void *);
-
-/* Consumer API */
-int rbuf_get_buffer (rbuf_t *, void **, sequence_fn *, void *);
-int rbuf_wait_for_completion (rbuf_t *, void *,
- void (*)(rbuf_list_t *, void *), void *);
-
-#endif
diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c
index 6018a58ad5f..58f95a7e610 100644
--- a/libglusterfs/src/run.c
+++ b/libglusterfs/src/run.c
@@ -23,9 +23,31 @@
#include <assert.h>
#include <signal.h>
#include <sys/wait.h>
-#include <sys/resource.h>
+#include "glusterfs/syscall.h"
-#ifdef RUN_STANDALONE
+/*
+ * Following defines are available for helping development:
+ * RUN_STANDALONE and RUN_DO_DEMO.
+ *
+ * Compiling a standalone object file with no dependencies
+ * on glusterfs:
+ * $ cc -DRUN_STANDALONE -c run.c
+ *
+ * Compiling a demo program that exercises bits of run.c
+ * functionality (linking to glusterfs):
+ * $ cc -DRUN_DO_DEMO -orun run.c `pkg-config --libs --cflags glusterfs-api`
+ *
+ * Compiling a demo program that exercises bits of run.c
+ * functionality (with no dependence on glusterfs):
+ *
+ * $ cc -DRUN_DO_DEMO -DRUN_STANDALONE -orun run.c
+ */
+#if defined(RUN_STANDALONE) || defined(RUN_DO_DEMO)
+int
+close_fds_except(int *fdv, size_t count);
+#define sys_read(f, b, c) read(f, b, c)
+#define sys_write(f, b, c) write(f, b, c)
+#define sys_close(f) close(f)
#define GF_CALLOC(n, s, t) calloc(n, s)
#define GF_ASSERT(cond) assert(cond)
#define GF_REALLOC(p, s) realloc(p, s)
@@ -33,481 +55,516 @@
#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 gf_msg_callingfn(dom, level, errnum, msgid, fmt, args...) \
+ printf("LOG: " fmt "\n", ##args)
#define LOG_DEBUG 0
+#ifdef RUN_STANDALONE
+#include <stdbool.h>
+#include <sys/resource.h>
+int
+close_fds_except(int *fdv, size_t count)
+{
+ int i = 0;
+ size_t j = 0;
+ bool should_close = true;
+ struct rlimit rl;
+ int ret = -1;
+
+ ret = getrlimit(RLIMIT_NOFILE, &rl);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < rl.rlim_cur; i++) {
+ should_close = true;
+ for (j = 0; j < count; j++) {
+ if (i == fdv[j]) {
+ should_close = false;
+ break;
+ }
+ }
+ if (should_close)
+ sys_close(i);
+ }
+ return 0;
+}
+#endif
#ifdef __linux__
#define GF_LINUX_HOST_OS
#endif
-#else /* ! RUN_STANDALONE */
-#include "glusterfs.h"
-#include "common-utils.h"
+#else /* ! RUN_STANDALONE || RUN_DO_DEMO */
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/libglusterfs-messages.h"
#endif
-#include "libglusterfs-messages.h"
-#include "run.h"
+#include "glusterfs/run.h"
void
-runinit (runner_t *runner)
+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;
- }
+ 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)
+runner_chio(runner_t *runner, int fd)
{
- GF_ASSERT (fd > 0 && fd < 3);
+ GF_ASSERT(fd > 0 && fd < 3);
- if ((fd > 0) && (fd < 3))
- return runner->chio[fd];
+ if ((fd > 0) && (fd < 3))
+ return runner->chio[fd];
- return NULL;
+ return NULL;
}
static void
-runner_insert_arg (runner_t *runner, char *arg)
+runner_insert_arg(runner_t *runner, char *arg)
{
- int i = 0;
+ int i = 0;
- GF_ASSERT (arg);
+ GF_ASSERT(arg);
- if (runner->runerr)
- return;
+ if (runner->runerr || !runner->argv)
+ 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;
- }
+ for (i = 0; i < runner->argvlen; i++) {
+ if (runner->argv[i] == NULL)
+ break;
+ }
+ GF_ASSERT(i < runner->argvlen);
- runner->argv[i] = arg;
+ 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)
+runner_add_arg(runner_t *runner, const char *arg)
{
- arg = gf_strdup (arg);
- if (!arg) {
- runner->runerr = errno;
- return;
- }
+ arg = gf_strdup(arg);
+ if (!arg) {
+ runner->runerr = errno;
+ return;
+ }
- runner_insert_arg (runner, (char *)arg);
+ runner_insert_arg(runner, (char *)arg);
}
static void
-runner_va_add_args (runner_t *runner, va_list argp)
+runner_va_add_args(runner_t *runner, va_list argp)
{
- const char *arg;
+ const char *arg;
- while ((arg = va_arg (argp, const char *)))
- runner_add_arg (runner, arg);
+ while ((arg = va_arg(argp, const char *)))
+ runner_add_arg(runner, arg);
}
void
-runner_add_args (runner_t *runner, ...)
+runner_add_args(runner_t *runner, ...)
{
- va_list argp;
+ va_list argp;
- va_start (argp, runner);
- runner_va_add_args (runner, argp);
- va_end (argp);
+ va_start(argp, runner);
+ runner_va_add_args(runner, argp);
+ va_end(argp);
}
void
-runner_argprintf (runner_t *runner, const char *format, ...)
+runner_argprintf(runner_t *runner, const char *format, ...)
{
- va_list argva;
- char *arg = NULL;
- int ret = 0;
+ va_list argva;
+ char *arg = NULL;
+ int ret = 0;
- va_start (argva, format);
- ret = gf_vasprintf (&arg, format, argva);
- va_end (argva);
+ va_start(argva, format);
+ ret = gf_vasprintf(&arg, format, argva);
+ va_end(argva);
- if (ret < 0) {
- runner->runerr = errno;
- return;
- }
+ if (ret < 0) {
+ runner->runerr = errno;
+ return;
+ }
- runner_insert_arg (runner, arg);
+ runner_insert_arg(runner, arg);
}
void
-runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
- const char *msg)
+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_msg_callingfn (dom, lvl, 0, LG_MSG_RUNNER_LOG, "%s: %s", msg, buf);
-
- GF_FREE (buf);
+ 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_msg_callingfn(dom, lvl, 0, LG_MSG_RUNNER_LOG, "%s: %s", msg, buf);
+
+ GF_FREE(buf);
}
void
-runner_redir (runner_t *runner, int fd, int tgt_fd)
+runner_redir(runner_t *runner, int fd, int tgt_fd)
{
- GF_ASSERT (fd > 0 && fd < 3);
+ GF_ASSERT(fd > 0 && fd < 3);
- if ((fd > 0) && (fd < 3))
- runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
+ if ((fd > 0) && (fd < 3))
+ runner->chfd[fd] = (tgt_fd >= 0) ? tgt_fd : -2;
}
int
-runner_start (runner_t *runner)
+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;
- }
+ 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 || !runner->argv) {
+ errno = (runner->runerr) ? runner->runerr : EINVAL;
+ 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) {
+ 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;
+ errno_priv = errno;
+ sys_close(xpi[0]);
+ sys_close(xpi[1]);
+ for (i = 0; i < 3; i++) {
+ sys_close(pi[i][0]);
+ sys_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 /* !GF_LINUX_HOST_OS */
- 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 /* !GF_LINUX_HOST_OS */
- }
-
- 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;
- }
+ for (i = 0; i < 3; i++)
+ sys_close(pi[i][i ? 0 : 1]);
+ sys_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);
}
- } 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));
+ }
+
+ if (ret != -1) {
+ int fdv[4] = {0, 1, 2, xpi[1]};
+
+ ret = close_fds_except(fdv, sizeof(fdv) / sizeof(*fdv));
+ }
+
+ if (ret != -1) {
+ /* save child from inheriting our signal handling */
+ sigemptyset(&set);
+ sigprocmask(SIG_SETMASK, &set, NULL);
+
+ execvp(runner->argv[0], runner->argv);
+ }
+ ret = sys_write(xpi[1], &errno, sizeof(errno));
+ _exit(1);
+ }
+
+ errno_priv = errno;
+ for (i = 0; i < 3; i++)
+ sys_close(pi[i][i ? 1 : 0]);
+ sys_close(xpi[1]);
+ if (ret == -1) {
+ for (i = 0; i < 3; i++) {
+ if (runner->chio[i]) {
+ fclose(runner->chio[i]);
+ runner->chio[i] = NULL;
+ }
}
- errno = errno_priv;
- return -1;
+ } else {
+ ret = sys_read(xpi[0], (char *)&errno_priv, sizeof(errno_priv));
+ sys_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)
+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;
+ int i = 0;
+ int ret = 1;
+ int chstat = 0;
+
+ if (runner->chpid > 0) {
+ if (waitpid(runner->chpid, &chstat, 0) == runner->chpid) {
+ if (WIFEXITED(chstat)) {
+ ret = WEXITSTATUS(chstat);
+ } else {
+ ret = chstat;
+ }
}
+ }
- for (i = 0; i < 3; i++) {
- if (runner->chio[i]) {
- fclose (runner->chio[i]);
- runner->chio[i] = NULL;
- }
+ for (i = 0; i < 3; i++) {
+ if (runner->chio[i]) {
+ fclose(runner->chio[i]);
+ runner->chio[i] = NULL;
}
+ }
- return ret;
+ return -ret;
}
int
-runner_end (runner_t *runner)
+runner_end(runner_t *runner)
{
- int i = 0;
- int ret = -1;
- char **p = NULL;
+ int i = 0;
+ int ret = -1;
+ char **p = NULL;
- ret = runner_end_reuse (runner);
+ 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]);
+ if (runner->argv) {
+ for (p = runner->argv; *p; p++)
+ GF_FREE(*p);
+ GF_FREE(runner->argv);
+ }
+ for (i = 0; i < 3; i++)
+ sys_close(runner->chfd[i]);
- return ret;
+ return ret;
}
static int
-runner_run_generic (runner_t *runner, int (*rfin)(runner_t *runner))
+runner_run_generic(runner_t *runner, int (*rfin)(runner_t *runner))
{
- int ret = 0;
+ int ret = 0;
- ret = runner_start (runner);
+ ret = runner_start(runner);
+ if (ret)
+ goto out;
+ ret = rfin(runner);
- return -(rfin (runner) || ret);
+out:
+ return ret;
}
int
-runner_run (runner_t *runner)
+runner_run(runner_t *runner)
{
- return runner_run_generic (runner, runner_end);
+ return runner_run_generic(runner, runner_end);
}
-
int
-runner_run_nowait (runner_t *runner)
+runner_run_nowait(runner_t *runner)
{
- int pid;
+ int pid;
- pid = fork ();
+ pid = fork();
- if (!pid) {
- setsid ();
- _exit (runner_start (runner));
- }
+ if (!pid) {
+ setsid();
+ _exit(runner_start(runner));
+ }
- if (pid > 0)
- runner->chpid = pid;
- return runner_end (runner);
+ if (pid > 0)
+ runner->chpid = pid;
+ return runner_end(runner);
}
-
int
-runner_run_reuse (runner_t *runner)
+runner_run_reuse(runner_t *runner)
{
- return runner_run_generic (runner, runner_end_reuse);
+ return runner_run_generic(runner, runner_end_reuse);
}
int
-runcmd (const char *arg, ...)
+runcmd(const char *arg, ...)
{
- runner_t runner;
- va_list argp;
+ runner_t runner;
+ va_list argp;
- runinit (&runner);
- /* ISO C requires a named argument before '...' */
- runner_add_arg (&runner, arg);
+ 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);
+ va_start(argp, arg);
+ runner_va_add_args(&runner, argp);
+ va_end(argp);
- return runner_run (&runner);
+ return runner_run(&runner);
}
-#ifdef RUN_DO_TESTS
+#ifdef RUN_DO_DEMO
static void
-TBANNER (const char *txt)
+TBANNER(const char *txt)
{
- printf("######\n### testing %s\n", txt);
+ printf("######\n### demoing %s\n", txt);
}
int
-main (int argc, char **argv)
+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;
+ 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;
+ char *tfile;
+
+ wdbuf = malloc(pathmax);
+ assert(wdbuf);
+ getcwd(wdbuf, pathmax);
+
+ TBANNER("basic functionality: running \"echo a b\"");
+ runcmd("echo", "a", "b", NULL);
+
+ TBANNER("argv extension: running \"echo 1 2 ... 100\"");
+ 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:\n"
+ " running a multiline echo command, emit a log about it,\n"
+ " redirect it to a pipe, read output lines\n"
+ " and print them prefixed with \"got: \"");
+ 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: running a non-existent command");
+ ret = runcmd("bafflavvitty", NULL);
+ printf("%d %d [%s]\n", ret, errno, strerror(errno));
+
+ TBANNER(
+ "output redirection: running \"echo foo\" redirected "
+ "to a temp file");
+ tfile = strdup("/tmp/foofXXXXXX");
+ assert(tfile);
+ fd = mkstemp(tfile);
+ assert(fd != -1);
+ printf("redirecting to %s\n", tfile);
+ runinit(&runner);
+ runner_add_args(&runner, "echo", "foo", NULL);
+ runner_redir(&runner, 1, fd);
+ ret = runner_run(&runner);
+ printf("runner_run returned: %d", ret);
+ if (ret != 0)
+ printf(", with errno %d [%s]", errno, strerror(errno));
+ putchar('\n');
+
+ /* sleep for seconds given as argument (0 means forever)
+ * to allow investigation of post-execution state to
+ * cbeck for resource leaks (eg. zombies).
+ */
+ if (argc > 1) {
+ tv.tv_sec = strtoul(argv[1], NULL, 10);
+ printf("### %s", "sleeping for");
+ if (tv.tv_sec > 0) {
+ printf(" %d seconds\n", tv.tv_sec);
+ tvp = &tv;
+ } else
+ printf("%s\n", "ever");
+ select(0, 0, 0, 0, tvp);
+ }
+
+ return 0;
}
#endif
diff --git a/libglusterfs/src/stack.c b/libglusterfs/src/stack.c
index 6977814ec69..1531f0da43f 100644
--- a/libglusterfs/src/stack.c
+++ b/libglusterfs/src/stack.c
@@ -8,419 +8,445 @@
cases as published by the Free Software Foundation.
*/
-#include "statedump.h"
-#include "stack.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/statedump.h"
+#include "glusterfs/stack.h"
+#include "glusterfs/libglusterfs-messages.h"
call_frame_t *
-create_frame (xlator_t *xl, call_pool_t *pool)
+create_frame(xlator_t *xl, call_pool_t *pool)
{
- call_stack_t *stack = NULL;
- call_frame_t *frame = NULL;
-
- if (!xl || !pool) {
- return NULL;
- }
-
- stack = mem_get0 (pool->stack_mem_pool);
- if (!stack)
- return NULL;
-
- INIT_LIST_HEAD (&stack->myframes);
-
- frame = mem_get0 (pool->frame_mem_pool);
- if (!frame) {
- mem_put (stack);
- return NULL;
- }
-
- frame->root = stack;
- frame->this = xl;
- LOCK_INIT (&frame->lock);
- INIT_LIST_HEAD (&frame->frames);
- list_add (&frame->frames, &stack->myframes);
-
- stack->pool = pool;
- stack->ctx = xl->ctx;
-
- if (stack->ctx->measure_latency) {
- if (gettimeofday (&stack->tv, NULL) == -1)
- gf_msg ("stack", GF_LOG_ERROR, errno,
- LG_MSG_GETTIMEOFDAY_FAILED,
- "gettimeofday () failed");
- memcpy (&frame->begin, &stack->tv, sizeof (stack->tv));
- }
-
-
- LOCK (&pool->lock);
- {
- list_add (&stack->all_frames, &pool->all_frames);
- pool->cnt++;
- }
- UNLOCK (&pool->lock);
-
- LOCK_INIT (&stack->stack_lock);
-
- return frame;
+ call_stack_t *stack = NULL;
+ call_frame_t *frame = NULL;
+ static uint64_t unique = 0;
+
+ if (!xl || !pool) {
+ return NULL;
+ }
+
+ stack = mem_get0(pool->stack_mem_pool);
+ if (!stack)
+ return NULL;
+
+ INIT_LIST_HEAD(&stack->myframes);
+
+ frame = mem_get0(pool->frame_mem_pool);
+ if (!frame) {
+ mem_put(stack);
+ return NULL;
+ }
+
+ frame->root = stack;
+ frame->this = xl;
+ LOCK_INIT(&frame->lock);
+ INIT_LIST_HEAD(&frame->frames);
+ list_add(&frame->frames, &stack->myframes);
+
+ stack->pool = pool;
+ stack->ctx = xl->ctx;
+
+ if (frame->root->ctx->measure_latency) {
+ timespec_now(&stack->tv);
+ memcpy(&frame->begin, &stack->tv, sizeof(stack->tv));
+ }
+
+ LOCK(&pool->lock);
+ {
+ list_add(&stack->all_frames, &pool->all_frames);
+ pool->cnt++;
+ stack->unique = unique++;
+ }
+ UNLOCK(&pool->lock);
+ GF_ATOMIC_INC(pool->total_count);
+
+ LOCK_INIT(&stack->stack_lock);
+
+ return frame;
}
void
-gf_proc_dump_call_frame (call_frame_t *call_frame, const char *key_buf,...)
+call_stack_set_groups(call_stack_t *stack, int ngrps, gid_t **groupbuf_p)
{
+ /* We take the ownership of the passed group buffer. */
+
+ if (ngrps <= SMALL_GROUP_COUNT) {
+ memcpy(stack->groups_small, *groupbuf_p, sizeof(gid_t) * ngrps);
+ stack->groups = stack->groups_small;
+ GF_FREE(*groupbuf_p);
+ } else {
+ stack->groups_large = *groupbuf_p;
+ stack->groups = stack->groups_large;
+ }
+
+ stack->ngrps = ngrps;
+ /* Set a canary. */
+ *groupbuf_p = (void *)0xdeadf00d;
+}
- char prefix[GF_DUMP_MAX_BUF_LEN];
- va_list ap;
- call_frame_t my_frame;
- int ret = -1;
- char timestr[256] = {0,};
+void
+gf_proc_dump_call_frame(call_frame_t *call_frame, const char *key_buf, ...)
+{
+ char prefix[GF_DUMP_MAX_BUF_LEN];
+ va_list ap;
+ call_frame_t my_frame = {
+ 0,
+ };
+
+ int ret = -1;
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ int len;
+
+ if (!call_frame)
+ return;
- if (!call_frame)
- return;
+ GF_ASSERT(key_buf);
- GF_ASSERT (key_buf);
+ va_start(ap, key_buf);
+ vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
+ va_end(ap);
- memset(prefix, 0, sizeof(prefix));
- memset(&my_frame, 0, sizeof(my_frame));
- va_start(ap, key_buf);
- vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
- va_end(ap);
+ ret = TRY_LOCK(&call_frame->lock);
+ if (ret)
+ goto out;
- ret = TRY_LOCK(&call_frame->lock);
- if (ret)
- goto out;
+ memcpy(&my_frame, call_frame, sizeof(my_frame));
+ UNLOCK(&call_frame->lock);
- memcpy(&my_frame, call_frame, sizeof(my_frame));
- UNLOCK(&call_frame->lock);
+ if (my_frame.root->ctx->measure_latency) {
+ gf_time_fmt(timestr, sizeof(timestr), my_frame.begin.tv_sec,
+ gf_timefmt_FT);
+ len = strlen(timestr);
+ snprintf(timestr + len, sizeof(timestr) - len, ".%" GF_PRI_SNSECONDS,
+ my_frame.begin.tv_nsec);
+ gf_proc_dump_write("frame-creation-time", "%s", timestr);
+ gf_proc_dump_write(
+ "timings", "%ld.%" GF_PRI_SNSECONDS " -> %ld.%" GF_PRI_SNSECONDS,
+ my_frame.begin.tv_sec, my_frame.begin.tv_nsec, my_frame.end.tv_sec,
+ my_frame.end.tv_nsec);
+ }
- if (my_frame.this->ctx->measure_latency) {
- gf_time_fmt (timestr, sizeof timestr, my_frame.begin.tv_sec,
- gf_timefmt_FT);
- snprintf (timestr + strlen (timestr),
- sizeof timestr - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, my_frame.begin.tv_usec);
- gf_proc_dump_write("frame-creation-time", "%s", timestr);
- }
+ gf_proc_dump_write("frame", "%p", call_frame);
+ 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);
- gf_proc_dump_write("frame", "%p", call_frame);
- 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.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_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.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_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);
+ if (my_frame.unwind_to)
+ gf_proc_dump_write("unwind_to", "%s", my_frame.unwind_to);
- ret = 0;
+ ret = 0;
out:
- if (ret) {
- gf_proc_dump_write("Unable to dump the frame information",
- "(Lock acquisition failed) %p", my_frame);
- return;
- }
+ if (ret) {
+ gf_proc_dump_write("Unable to dump the frame information",
+ "(Lock acquisition failed)");
+ return;
+ }
}
-
void
-gf_proc_dump_call_stack (call_stack_t *call_stack, const char *key_buf,...)
+gf_proc_dump_call_stack(call_stack_t *call_stack, const char *key_buf, ...)
{
- char prefix[GF_DUMP_MAX_BUF_LEN];
- va_list ap;
- call_frame_t *trav;
- int32_t i = 1, cnt = 0;
- char timestr[256] = {0,};
-
- if (!call_stack)
- return;
-
- GF_ASSERT (key_buf);
-
- memset(prefix, 0, sizeof(prefix));
- va_start(ap, key_buf);
- vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
- va_end(ap);
-
- cnt = call_frames_count (call_stack);
- if (call_stack->ctx->measure_latency) {
- gf_time_fmt (timestr, sizeof timestr, call_stack->tv.tv_sec,
- gf_timefmt_FT);
- snprintf (timestr + strlen (timestr),
- sizeof timestr - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, call_stack->tv.tv_usec);
- gf_proc_dump_write("callstack-creation-time", "%s", timestr);
- }
-
- gf_proc_dump_write("stack", "%p", call_stack);
- 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));
-
- if (call_stack->type == GF_OP_TYPE_FOP)
- gf_proc_dump_write("op", "%s",
- (char *)gf_fop_list[call_stack->op]);
- else
- gf_proc_dump_write("op", "stack");
-
- gf_proc_dump_write("type", "%d", call_stack->type);
- gf_proc_dump_write("cnt", "%d", cnt);
-
- list_for_each_entry (trav, &call_stack->myframes, frames) {
- gf_proc_dump_add_section("%s.frame.%d", prefix, i);
- gf_proc_dump_call_frame(trav, "%s.frame.%d", prefix, i);
- i++;
- }
+ char prefix[GF_DUMP_MAX_BUF_LEN];
+ va_list ap;
+ call_frame_t *trav;
+ int32_t i = 1, cnt = 0;
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ int len;
+
+ if (!call_stack)
+ return;
+
+ GF_ASSERT(key_buf);
+
+ va_start(ap, key_buf);
+ vsnprintf(prefix, GF_DUMP_MAX_BUF_LEN, key_buf, ap);
+ va_end(ap);
+
+ cnt = call_frames_count(call_stack);
+ gf_time_fmt(timestr, sizeof(timestr), call_stack->tv.tv_sec, gf_timefmt_FT);
+ len = strlen(timestr);
+ snprintf(timestr + len, sizeof(timestr) - len, ".%" GF_PRI_SNSECONDS,
+ call_stack->tv.tv_nsec);
+ gf_proc_dump_write("callstack-creation-time", "%s", timestr);
+
+ gf_proc_dump_write("stack", "%p", call_stack);
+ 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", "%" PRIu64, call_stack->unique);
+ gf_proc_dump_write("lk-owner", "%s", lkowner_utoa(&call_stack->lk_owner));
+ gf_proc_dump_write("ctime", "%" GF_PRI_SECOND ".%" GF_PRI_SNSECONDS,
+ call_stack->tv.tv_sec, call_stack->tv.tv_nsec);
+
+ if (call_stack->type == GF_OP_TYPE_FOP)
+ gf_proc_dump_write("op", "%s", (char *)gf_fop_list[call_stack->op]);
+ else
+ gf_proc_dump_write("op", "stack");
+
+ gf_proc_dump_write("type", "%d", call_stack->type);
+ gf_proc_dump_write("cnt", "%d", cnt);
+
+ list_for_each_entry(trav, &call_stack->myframes, frames)
+ {
+ gf_proc_dump_add_section("%s.frame.%d", prefix, i);
+ gf_proc_dump_call_frame(trav, "%s.frame.%d", prefix, i);
+ i++;
+ }
}
void
-gf_proc_dump_pending_frames (call_pool_t *call_pool)
+gf_proc_dump_pending_frames(call_pool_t *call_pool)
{
+ call_stack_t *trav = NULL;
+ int i = 1;
+ int ret = -1;
+ gf_boolean_t section_added = _gf_false;
- call_stack_t *trav = NULL;
- int i = 1;
- int ret = -1;
- gf_boolean_t section_added = _gf_true;
-
- if (!call_pool)
- return;
-
- ret = TRY_LOCK (&(call_pool->lock));
- if (ret)
- goto out;
-
+ if (!call_pool)
+ return;
- gf_proc_dump_add_section("global.callpool");
- section_added = _gf_true;
- gf_proc_dump_write("callpool_address","%p", call_pool);
- gf_proc_dump_write("callpool.cnt","%d", call_pool->cnt);
+ ret = TRY_LOCK(&(call_pool->lock));
+ if (ret)
+ goto out;
+ gf_proc_dump_add_section("global.callpool");
+ section_added = _gf_true;
+ gf_proc_dump_write("callpool_address", "%p", call_pool);
+ gf_proc_dump_write("callpool.cnt", "%" PRId64, call_pool->cnt);
- list_for_each_entry (trav, &call_pool->all_frames, all_frames) {
- gf_proc_dump_add_section("global.callpool.stack.%d",i);
- gf_proc_dump_call_stack(trav, "global.callpool.stack.%d", i);
- i++;
- }
- UNLOCK (&(call_pool->lock));
+ list_for_each_entry(trav, &call_pool->all_frames, all_frames)
+ {
+ gf_proc_dump_add_section("global.callpool.stack.%d", i);
+ gf_proc_dump_call_stack(trav, "global.callpool.stack.%d", i);
+ i++;
+ }
+ UNLOCK(&(call_pool->lock));
- ret = 0;
+ ret = 0;
out:
- if (ret) {
- if (_gf_false == section_added)
- gf_proc_dump_add_section("global.callpool");
- gf_proc_dump_write("Unable to dump the callpool",
- "(Lock acquisition failed) %p",
- call_pool);
- }
- return;
+ if (ret) {
+ if (_gf_false == section_added)
+ gf_proc_dump_add_section("global.callpool");
+ gf_proc_dump_write("Unable to dump the callpool",
+ "(Lock acquisition failed) %p", call_pool);
+ }
+ return;
}
void
-gf_proc_dump_call_frame_to_dict (call_frame_t *call_frame,
- char *prefix, dict_t *dict)
+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,};
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+ char msg[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);
+
+ snprintf(key, sizeof(key), "%s.refcount", prefix);
+ ret = dict_set_int32(dict, key, tmp_frame.ref_count);
+ if (ret)
+ return;
- if (!call_frame || !dict)
- return;
+ snprintf(key, sizeof(key), "%s.translator", prefix);
+ ret = dict_set_dynstr(dict, key, gf_strdup(tmp_frame.this->name));
+ if (ret)
+ return;
+
+ snprintf(key, sizeof(key), "%s.complete", prefix);
+ ret = dict_set_int32(dict, key, tmp_frame.complete);
+ if (ret)
+ return;
- ret = TRY_LOCK (&call_frame->lock);
+ if (tmp_frame.root->ctx->measure_latency) {
+ snprintf(key, sizeof(key), "%s.timings", prefix);
+ snprintf(msg, sizeof(msg),
+ "%ld.%" GF_PRI_SNSECONDS " -> %ld.%" GF_PRI_SNSECONDS,
+ tmp_frame.begin.tv_sec, tmp_frame.begin.tv_nsec,
+ tmp_frame.end.tv_sec, tmp_frame.end.tv_nsec);
+ ret = dict_set_str(dict, key, msg);
if (ret)
- return;
- memcpy (&tmp_frame, call_frame, sizeof (tmp_frame));
- UNLOCK (&call_frame->lock);
+ return;
+ }
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.refcount", prefix);
- ret = dict_set_int32 (dict, key, tmp_frame.ref_count);
+ if (tmp_frame.parent) {
+ snprintf(key, sizeof(key), "%s.parent", prefix);
+ ret = dict_set_dynstr(dict, key,
+ gf_strdup(tmp_frame.parent->this->name));
if (ret)
- return;
+ 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 (tmp_frame.wind_from) {
+ snprintf(key, sizeof(key), "%s.windfrom", prefix);
+ ret = dict_set_dynstr(dict, key, gf_strdup(tmp_frame.wind_from));
if (ret)
- return;
+ return;
+ }
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.complete", prefix);
- ret = dict_set_int32 (dict, key, tmp_frame.complete);
+ if (tmp_frame.wind_to) {
+ 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.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;
+ }
- return;
+ if (tmp_frame.unwind_from) {
+ 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) {
+ snprintf(key, sizeof(key), "%s.unwind_to", prefix);
+ ret = dict_set_dynstr(dict, key, gf_strdup(tmp_frame.unwind_to));
+ if (ret)
+ return;
+ }
+
+ return;
}
void
-gf_proc_dump_call_stack_to_dict (call_stack_t *call_stack,
- char *prefix, dict_t *dict)
+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 i = 0;
- int count = 0;
-
- if (!call_stack || !dict)
- return;
-
- count = call_frames_count (call_stack);
- 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;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+ call_frame_t *trav = NULL;
+ int i = 0;
+ int count = 0;
+
+ if (!call_stack || !dict)
+ 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;
+ count = call_frames_count(call_stack);
+ 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.unique", prefix);
- ret = dict_set_uint64 (dict, key, call_stack->unique);
- if (ret)
- return;
+ 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.op", prefix);
- if (call_stack->type == GF_OP_TYPE_FOP)
- ret = dict_set_str (dict, key,
- (char *)gf_fop_list[call_stack->op]);
- else
- ret = dict_set_str (dict, key, "other");
+ snprintf(key, sizeof(key), "%s.pid", prefix);
+ ret = dict_set_int32(dict, key, call_stack->pid);
+ if (ret)
+ return;
- if (ret)
- return;
+ 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.type", prefix);
- ret = dict_set_int32 (dict, key, call_stack->type);
- if (ret)
- return;
+ snprintf(key, sizeof(key), "%s.op", prefix);
+ if (call_stack->type == GF_OP_TYPE_FOP)
+ ret = dict_set_str(dict, key, (char *)gf_fop_list[call_stack->op]);
+ else
+ ret = dict_set_str(dict, key, "other");
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.count", prefix);
- ret = dict_set_int32 (dict, key, count);
- if (ret)
- return;
+ if (ret)
+ return;
- list_for_each_entry (trav, &call_stack->myframes, frames) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.frame%d",
- prefix, i);
- gf_proc_dump_call_frame_to_dict (trav, key, dict);
- i++;
- }
+ snprintf(key, sizeof(key), "%s.type", prefix);
+ ret = dict_set_int32(dict, key, call_stack->type);
+ if (ret)
+ return;
+ snprintf(key, sizeof(key), "%s.count", prefix);
+ ret = dict_set_int32(dict, key, count);
+ if (ret)
return;
+
+ list_for_each_entry(trav, &call_stack->myframes, frames)
+ {
+ snprintf(key, sizeof(key), "%s.frame%d", prefix, i);
+ gf_proc_dump_call_frame_to_dict(trav, key, dict);
+ i++;
+ }
+
+ return;
}
void
-gf_proc_dump_pending_frames_to_dict (call_pool_t *call_pool, dict_t *dict)
+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_msg (THIS->name, GF_LOG_WARNING, errno,
- LG_MSG_LOCK_FAILURE, "Unable to dump call "
- "pool to dict.");
- return;
- }
-
- ret = dict_set_int32 (dict, "callpool.count", call_pool->cnt);
- if (ret)
- goto out;
+ int ret = -1;
+ call_stack_t *trav = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+ int i = 0;
+
+ if (!call_pool || !dict)
+ return;
- 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++;
- }
+ ret = TRY_LOCK(&call_pool->lock);
+ if (ret) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_LOCK_FAILURE,
+ "Unable to dump call "
+ "pool to dict.");
+ 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)
+ {
+ snprintf(key, sizeof(key), "callpool.stack%d", i);
+ gf_proc_dump_call_stack_to_dict(trav, key, dict);
+ i++;
+ }
out:
- UNLOCK (&call_pool->lock);
+ UNLOCK(&call_pool->lock);
- return;
+ return;
}
gf_boolean_t
-__is_fuse_call (call_frame_t *frame)
+__is_fuse_call(call_frame_t *frame)
{
- gf_boolean_t is_fuse_call = _gf_false;
- GF_ASSERT (frame);
- GF_ASSERT (frame->root);
+ gf_boolean_t is_fuse_call = _gf_false;
+ GF_ASSERT(frame);
+ GF_ASSERT(frame->root);
- if (NFS_PID != frame->root->pid)
- is_fuse_call = _gf_true;
- return is_fuse_call;
+ if (NFS_PID != frame->root->pid)
+ is_fuse_call = _gf_true;
+ return is_fuse_call;
}
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
deleted file mode 100644
index 5c0655f2ead..00000000000
--- a/libglusterfs/src/stack.h
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- 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.
-*/
-
-/*
- This file defines MACROS and static inlines used to emulate a function
- call over asynchronous communication with remote server
-*/
-
-#ifndef _STACK_H
-#define _STACK_H
-
-struct _call_stack_t;
-typedef struct _call_stack_t call_stack_t;
-struct _call_frame_t;
-typedef struct _call_frame_t call_frame_t;
-struct call_pool;
-typedef struct call_pool call_pool_t;
-
-#include <sys/time.h>
-
-#include "xlator.h"
-#include "dict.h"
-#include "list.h"
-#include "common-utils.h"
-#include "globals.h"
-#include "lkowner.h"
-#include "client_t.h"
-#include "libglusterfs-messages.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,
- int32_t op_ret,
- int32_t op_errno,
- ...);
-
-struct call_pool {
- union {
- struct list_head all_frames;
- struct {
- call_stack_t *next_call;
- call_stack_t *prev_call;
- } all_stacks;
- };
- int64_t cnt;
- gf_lock_t lock;
- struct mem_pool *frame_mem_pool;
- struct mem_pool *stack_mem_pool;
-};
-
-struct _call_frame_t {
- call_stack_t *root; /* stack root */
- call_frame_t *parent; /* previous BP */
- struct list_head frames;
- void *local; /* local variables */
- xlator_t *this; /* implicit object */
- ret_fn_t ret; /* op_return address */
- int32_t ref_count;
- gf_lock_t lock;
- void *cookie; /* unique cookie */
- gf_boolean_t complete;
-
- 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;
-};
-
-#define SMALL_GROUP_COUNT 128
-
-struct _call_stack_t {
- union {
- struct list_head all_frames;
- struct {
- call_stack_t *next_call;
- call_stack_t *prev_call;
- };
- };
- call_pool_t *pool;
- gf_lock_t stack_lock;
- client_t *client;
- uint64_t unique;
- void *state; /* pointer to request state */
- uid_t uid;
- gid_t gid;
- pid_t pid;
- uint16_t ngrps;
- uint32_t groups_small[SMALL_GROUP_COUNT];
- uint32_t *groups_large;
- uint32_t *groups;
- gf_lkowner_t lk_owner;
- glusterfs_ctx_t *ctx;
-
- struct list_head myframes; /* List of call_frame_t that go
- to make the call stack */
-
- int32_t op;
- int8_t type;
- struct timeval tv;
-};
-
-
-#define frame_set_uid_gid(frm, u, g) \
- do { \
- if (frm) { \
- (frm)->root->uid = u; \
- (frm)->root->gid = g; \
- (frm)->root->ngrps = 0; \
- } \
- } while (0); \
-
-
-struct xlator_fops;
-
-void
-gf_latency_begin (call_frame_t *frame, void *fn);
-
-void
-gf_latency_end (call_frame_t *frame);
-
-static inline void
-FRAME_DESTROY (call_frame_t *frame)
-{
- void *local = NULL;
-
- list_del_init (&frame->frames);
- if (frame->local) {
- local = frame->local;
- frame->local = NULL;
-
- }
-
- LOCK_DESTROY (&frame->lock);
- mem_put (frame);
-
- if (local)
- mem_put (local);
-}
-
-
-static inline void
-STACK_DESTROY (call_stack_t *stack)
-{
- void *local = NULL;
- call_frame_t *frame = NULL;
- call_frame_t *tmp = NULL;
-
- LOCK (&stack->pool->lock);
- {
- list_del_init (&stack->all_frames);
- stack->pool->cnt--;
- }
- UNLOCK (&stack->pool->lock);
-
- LOCK_DESTROY (&stack->stack_lock);
-
- list_for_each_entry_safe (frame, tmp, &stack->myframes, frames) {
- FRAME_DESTROY (frame);
- }
-
- GF_FREE (stack->groups_large);
-
- mem_put (stack);
-
- if (local)
- mem_put (local);
-}
-
-static inline void
-STACK_RESET (call_stack_t *stack)
-{
- void *local = NULL;
- call_frame_t *frame = NULL;
- call_frame_t *tmp = NULL;
- call_frame_t *last = NULL;
- struct list_head toreset = {0};
-
- INIT_LIST_HEAD (&toreset);
-
- /* We acquire call_pool->lock only to remove the frames from this stack
- * to preserve atomicity. This synchronizes across concurrent requests
- * like statedump, STACK_DESTROY etc. */
-
- LOCK (&stack->pool->lock);
- {
- last = list_last_entry (&stack->myframes, call_frame_t, frames);
- list_del_init (&last->frames);
- list_splice_init (&stack->myframes, &toreset);
- list_add (&last->frames, &stack->myframes);
- }
- UNLOCK (&stack->pool->lock);
-
- list_for_each_entry_safe (frame, tmp, &toreset, frames) {
- FRAME_DESTROY (frame);
- }
-
- if (local)
- mem_put (local);
-}
-
-#define cbk(x) cbk_##x
-
-#define FRAME_SU_DO(frm, local_type) \
- do { \
- local_type *__local = (frm)->local; \
- __local->uid = frm->root->uid; \
- __local->gid = frm->root->gid; \
- frm->root->uid = 0; \
- frm->root->gid = 0; \
- } while (0); \
-
-#define FRAME_SU_UNDO(frm, local_type) \
- do { \
- local_type *__local = (frm)->local; \
- frm->root->uid = __local->uid; \
- frm->root->gid = __local->gid; \
- } while (0); \
-
-
-/* make a call */
-#define STACK_WIND(frame, rfn, obj, fn, params ...) \
- do { \
- call_frame_t *_new = NULL; \
- xlator_t *old_THIS = NULL; \
- \
- _new = mem_get0 (frame->root->pool->frame_mem_pool); \
- if (!_new) { \
- break; \
- } \
- typeof(fn##_cbk) tmp_cbk = rfn; \
- _new->root = frame->root; \
- _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); \
- LOCK(&frame->root->stack_lock); \
- { \
- list_add (&_new->frames, &frame->root->myframes);\
- frame->ref_count++; \
- } \
- UNLOCK(&frame->root->stack_lock); \
- old_THIS = THIS; \
- THIS = obj; \
- if (frame->this->ctx->measure_latency) \
- gf_latency_begin (_new, fn); \
- fn (_new, obj, params); \
- THIS = old_THIS; \
- } while (0)
-
-
-/* make a call without switching frames */
-#define STACK_WIND_TAIL(frame, obj, fn, params ...) \
- do { \
- xlator_t *old_THIS = NULL; \
- \
- frame->this = obj; \
- frame->wind_to = #fn; \
- old_THIS = THIS; \
- THIS = obj; \
- fn (frame, obj, params); \
- THIS = old_THIS; \
- } while (0)
-
-
-/* make a call with a cookie */
-#define STACK_WIND_COOKIE(frame, rfn, cky, obj, fn, params ...) \
- do { \
- call_frame_t *_new = NULL; \
- xlator_t *old_THIS = NULL; \
- \
- _new = mem_get0 (frame->root->pool->frame_mem_pool); \
- if (!_new) { \
- break; \
- } \
- typeof(fn##_cbk) tmp_cbk = rfn; \
- _new->root = frame->root; \
- _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); \
- LOCK(&frame->root->stack_lock); \
- { \
- list_add (&_new->frames, &frame->root->myframes);\
- frame->ref_count++; \
- } \
- UNLOCK(&frame->root->stack_lock); \
- fn##_cbk = rfn; \
- old_THIS = THIS; \
- THIS = obj; \
- if (obj->ctx->measure_latency) \
- gf_latency_begin (_new, fn); \
- fn (_new, obj, params); \
- THIS = old_THIS; \
- } while (0)
-
-
-/* return from function */
-#define STACK_UNWIND(frame, params ...) \
- do { \
- ret_fn_t fn = NULL; \
- call_frame_t *_parent = NULL; \
- xlator_t *old_THIS = NULL; \
- if (!frame) { \
- gf_msg ("stack", GF_LOG_CRITICAL, 0, \
- LG_MSG_FRAME_ERROR, "!frame"); \
- break; \
- } \
- fn = frame->ret; \
- _parent = frame->parent; \
- 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__; \
- if (frame->this->ctx->measure_latency) \
- gf_latency_end (frame); \
- fn (_parent, frame->cookie, _parent->this, params); \
- THIS = old_THIS; \
- } while (0)
-
-
-/* return from function in type-safe way */
-#define STACK_UNWIND_STRICT(op, frame, params ...) \
- do { \
- fop_##op##_cbk_t fn = NULL; \
- call_frame_t *_parent = NULL; \
- xlator_t *old_THIS = NULL; \
- \
- if (!frame) { \
- gf_msg ("stack", GF_LOG_CRITICAL, 0, \
- LG_MSG_FRAME_ERROR, "!frame"); \
- break; \
- } \
- fn = (fop_##op##_cbk_t )frame->ret; \
- _parent = frame->parent; \
- 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__; \
- if (frame->this->ctx->measure_latency) \
- gf_latency_end (frame); \
- fn (_parent, frame->cookie, _parent->this, params); \
- THIS = old_THIS; \
- } while (0)
-
-
-static inline int
-call_stack_alloc_groups (call_stack_t *stack, int ngrps)
-{
- if (ngrps <= SMALL_GROUP_COUNT) {
- stack->groups = stack->groups_small;
- } else {
- stack->groups_large = GF_CALLOC (sizeof (gid_t), ngrps,
- gf_common_mt_groups_t);
- if (!stack->groups_large)
- return -1;
- stack->groups = stack->groups_large;
- }
-
- stack->ngrps = ngrps;
-
- return 0;
-}
-
-static inline
-int call_frames_count (call_stack_t *call_stack)
-{
- call_frame_t *pos;
- int32_t count = 0;
-
- if (!call_stack)
- return count;
-
- list_for_each_entry (pos, &call_stack->myframes, frames)
- count++;
-
- return count;
-}
-
-static inline call_frame_t *
-copy_frame (call_frame_t *frame)
-{
- call_stack_t *newstack = NULL;
- call_stack_t *oldstack = NULL;
- call_frame_t *newframe = NULL;
-
- if (!frame) {
- return NULL;
- }
-
- newstack = mem_get0 (frame->root->pool->stack_mem_pool);
- if (newstack == NULL) {
- return NULL;
- }
-
- INIT_LIST_HEAD (&newstack->myframes);
-
- newframe = mem_get0 (frame->root->pool->frame_mem_pool);
- if (!newframe) {
- mem_put (newstack);
- return NULL;
- }
-
- newframe->this = frame->this;
- newframe->root = newstack;
- INIT_LIST_HEAD (&newframe->frames);
- list_add (&newframe->frames, &newstack->myframes);
-
- oldstack = frame->root;
-
- newstack->uid = oldstack->uid;
- newstack->gid = oldstack->gid;
- newstack->pid = oldstack->pid;
- newstack->ngrps = oldstack->ngrps;
- newstack->op = oldstack->op;
- newstack->type = oldstack->type;
- if (call_stack_alloc_groups (newstack, oldstack->ngrps) != 0) {
- mem_put (newstack);
- return NULL;
- }
- memcpy (newstack->groups, oldstack->groups,
- sizeof (gid_t) * oldstack->ngrps);
- newstack->unique = oldstack->unique;
- newstack->pool = oldstack->pool;
- newstack->lk_owner = oldstack->lk_owner;
- newstack->ctx = oldstack->ctx;
-
- if (newstack->ctx->measure_latency) {
- if (gettimeofday (&newstack->tv, NULL) == -1)
- gf_msg ("stack", GF_LOG_ERROR, errno,
- LG_MSG_GETTIMEOFDAY_FAILED,
- "gettimeofday () failed.");
- memcpy (&newframe->begin, &newstack->tv,
- sizeof (newstack->tv));
- }
-
- LOCK_INIT (&newframe->lock);
- LOCK_INIT (&newstack->stack_lock);
-
- LOCK (&oldstack->pool->lock);
- {
- list_add (&newstack->all_frames, &oldstack->all_frames);
- newstack->pool->cnt++;
- }
- UNLOCK (&oldstack->pool->lock);
-
- return newframe;
-}
-
-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);
-call_frame_t *create_frame (xlator_t *xl, call_pool_t *pool);
-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 fc66421be2f..65f0eb5c7f3 100644
--- a/libglusterfs/src/statedump.c
+++ b/libglusterfs/src/statedump.c
@@ -9,13 +9,11 @@
*/
#include <stdarg.h>
-#include "glusterfs.h"
-#include "logging.h"
-#include "iobuf.h"
-#include "statedump.h"
-#include "stack.h"
-#include "common-utils.h"
-
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/logging.h"
+#include "glusterfs/statedump.h"
+#include "glusterfs/stack.h"
+#include "glusterfs/syscall.h"
#ifdef HAVE_MALLOC_H
#include <malloc.h>
@@ -25,961 +23,1031 @@
'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
+#undef gf_log
#endif
-#define GF_PROC_DUMP_IS_OPTION_ENABLED(opt) \
- (dump_options.dump_##opt == _gf_true)
+#define GF_PROC_DUMP_IS_OPTION_ENABLED(opt) \
+ (dump_options.dump_##opt == _gf_true)
-#define GF_PROC_DUMP_IS_XL_OPTION_ENABLED(opt) \
- (dump_options.xl_options.dump_##opt == _gf_true)
+#define GF_PROC_DUMP_IS_XL_OPTION_ENABLED(opt) \
+ (dump_options.xl_options.dump_##opt == _gf_true)
extern xlator_t global_xlator;
-static pthread_mutex_t gf_proc_dump_mutex;
+static pthread_mutex_t gf_proc_dump_mutex;
static int gf_dump_fd = -1;
gf_dump_options_t dump_options;
static strfd_t *gf_dump_strfd = NULL;
static void
-gf_proc_dump_lock (void)
+gf_proc_dump_lock(void)
{
- pthread_mutex_lock (&gf_proc_dump_mutex);
+ pthread_mutex_lock(&gf_proc_dump_mutex);
}
-
static void
-gf_proc_dump_unlock (void)
+gf_proc_dump_unlock(void)
{
- pthread_mutex_unlock (&gf_proc_dump_mutex);
+ pthread_mutex_unlock(&gf_proc_dump_mutex);
}
static int
-gf_proc_dump_open (char *tmpname)
+gf_proc_dump_open(char *tmpname)
{
- int dump_fd = -1;
+ int dump_fd = -1;
- mode_t mask = umask(S_IRWXG | S_IRWXO);
- dump_fd = mkstemp (tmpname);
- umask(mask);
- if (dump_fd < 0)
- return -1;
+ mode_t mask = umask(S_IRWXG | S_IRWXO);
+ dump_fd = mkstemp(tmpname);
+ umask(mask);
+ if (dump_fd < 0)
+ return -1;
- gf_dump_fd = dump_fd;
- return 0;
+ gf_dump_fd = dump_fd;
+ return 0;
}
static void
-gf_proc_dump_close (void)
+gf_proc_dump_close(void)
{
- close (gf_dump_fd);
- gf_dump_fd = -1;
+ sys_close(gf_dump_fd);
+ gf_dump_fd = -1;
}
static int
-gf_proc_dump_set_path (char *dump_options_file)
+gf_proc_dump_set_path(char *dump_options_file)
{
- int ret = -1;
- FILE *fp = NULL;
- char buf[256];
- char *key = NULL, *value = NULL;
- char *saveptr = NULL;
+ int ret = -1;
+ FILE *fp = NULL;
+ char buf[256];
+ char *key = NULL, *value = NULL;
+ char *saveptr = NULL;
+
+ fp = fopen(dump_options_file, "r");
+ if (!fp)
+ goto out;
+
+ ret = fscanf(fp, "%255s", buf);
+
+ while (ret != EOF) {
+ key = strtok_r(buf, "=", &saveptr);
+ if (!key) {
+ ret = fscanf(fp, "%255s", buf);
+ continue;
+ }
- fp = fopen (dump_options_file, "r");
- if (!fp)
- goto out;
+ value = strtok_r(NULL, "=", &saveptr);
- ret = fscanf (fp, "%s", buf);
-
- while (ret != EOF) {
- key = strtok_r (buf, "=", &saveptr);
- if (!key) {
- ret = fscanf (fp, "%s", buf);
- continue;
- }
-
- value = strtok_r (NULL, "=", &saveptr);
-
- if (!value) {
- ret = fscanf (fp, "%s", buf);
- continue;
- }
- if (!strcmp (key, "path")) {
- dump_options.dump_path = gf_strdup (value);
- break;
- }
+ if (!value) {
+ ret = fscanf(fp, "%255s", buf);
+ continue;
}
+ if (!strcmp(key, "path")) {
+ dump_options.dump_path = gf_strdup(value);
+ break;
+ }
+ }
out:
- if (fp)
- fclose (fp);
- return ret;
+ if (fp)
+ fclose(fp);
+ return ret;
}
-int
-gf_proc_dump_add_section_fd (char *key, va_list ap)
+static int
+gf_proc_dump_add_section_fd(char *key, va_list ap)
{
+ char buf[GF_DUMP_MAX_BUF_LEN];
+ int len;
- char buf[GF_DUMP_MAX_BUF_LEN];
+ GF_ASSERT(key);
- GF_ASSERT(key);
-
- memset (buf, 0, sizeof(buf));
- snprintf (buf, GF_DUMP_MAX_BUF_LEN, "\n[");
- vsnprintf (buf + strlen(buf),
- GF_DUMP_MAX_BUF_LEN - strlen (buf), key, ap);
- snprintf (buf + strlen(buf),
- GF_DUMP_MAX_BUF_LEN - strlen (buf), "]\n");
- return write (gf_dump_fd, buf, strlen (buf));
+ len = snprintf(buf, GF_DUMP_MAX_BUF_LEN, "\n[");
+ len += vsnprintf(buf + len, GF_DUMP_MAX_BUF_LEN - len, key, ap);
+ len += snprintf(buf + len, GF_DUMP_MAX_BUF_LEN - len, "]\n");
+ return sys_write(gf_dump_fd, buf, len);
}
-
-int
-gf_proc_dump_add_section_strfd (char *key, va_list ap)
+static int
+gf_proc_dump_add_section_strfd(char *key, va_list ap)
{
- int ret = 0;
+ int ret = 0;
- ret += strprintf (gf_dump_strfd, "[");
- ret += strvprintf (gf_dump_strfd, key, ap);
- ret += strprintf (gf_dump_strfd, "]\n");
+ ret += strprintf(gf_dump_strfd, "[");
+ ret += strvprintf(gf_dump_strfd, key, ap);
+ ret += strprintf(gf_dump_strfd, "]\n");
- return ret;
+ return ret;
}
-
int
-gf_proc_dump_add_section (char *key, ...)
+gf_proc_dump_add_section(char *key, ...)
{
- va_list ap;
- int ret = 0;
+ va_list ap;
+ int ret = 0;
- va_start (ap, key);
- if (gf_dump_strfd)
- ret = gf_proc_dump_add_section_strfd (key, ap);
- else
- ret = gf_proc_dump_add_section_fd (key, ap);
- va_end (ap);
+ va_start(ap, key);
+ if (gf_dump_strfd)
+ ret = gf_proc_dump_add_section_strfd(key, ap);
+ else
+ ret = gf_proc_dump_add_section_fd(key, ap);
+ va_end(ap);
- return ret;
+ return ret;
}
-
-int
-gf_proc_dump_write_fd (char *key, char *value, va_list ap)
+static int
+gf_proc_dump_write_fd(char *key, char *value, va_list ap)
{
+ char buf[GF_DUMP_MAX_BUF_LEN];
+ int len = 0;
- char buf[GF_DUMP_MAX_BUF_LEN];
- int offset = 0;
+ GF_ASSERT(key);
- GF_ASSERT (key);
+ len = snprintf(buf, GF_DUMP_MAX_BUF_LEN, "%s=", key);
+ len += vsnprintf(buf + len, GF_DUMP_MAX_BUF_LEN - len, value, ap);
- offset = strlen (key);
+ len += snprintf(buf + len, GF_DUMP_MAX_BUF_LEN - len, "\n");
+ return sys_write(gf_dump_fd, buf, len);
+}
- memset (buf, 0, GF_DUMP_MAX_BUF_LEN);
- snprintf (buf, GF_DUMP_MAX_BUF_LEN, "%s", key);
- snprintf (buf + offset, GF_DUMP_MAX_BUF_LEN - offset, "=");
- offset += 1;
- vsnprintf (buf + offset, GF_DUMP_MAX_BUF_LEN - offset, value, ap);
+static int
+gf_proc_dump_write_strfd(char *key, char *value, va_list ap)
+{
+ int ret = 0;
- offset = strlen (buf);
- snprintf (buf + offset, GF_DUMP_MAX_BUF_LEN - offset, "\n");
- return write (gf_dump_fd, buf, strlen (buf));
-}
+ ret += strprintf(gf_dump_strfd, "%s = ", key);
+ ret += strvprintf(gf_dump_strfd, value, ap);
+ ret += strprintf(gf_dump_strfd, "\n");
+ return ret;
+}
int
-gf_proc_dump_write_strfd (char *key, char *value, va_list ap)
+gf_proc_dump_write(char *key, char *value, ...)
{
- int ret = 0;
+ int ret = 0;
+ va_list ap;
- ret += strprintf (gf_dump_strfd, "%s = ", key);
- ret += strvprintf (gf_dump_strfd, value, ap);
- ret += strprintf (gf_dump_strfd, "\n");
+ va_start(ap, value);
+ if (gf_dump_strfd)
+ ret = gf_proc_dump_write_strfd(key, value, ap);
+ else
+ ret = gf_proc_dump_write_fd(key, value, ap);
+ va_end(ap);
- return ret;
+ return ret;
}
+void
+gf_latency_statedump_and_reset(char *key, gf_latency_t *lat)
+{
+ /* Doesn't make sense to continue if there are no fops
+ came in the given interval */
+ if (!lat || !lat->count)
+ return;
+ gf_proc_dump_write(key,
+ "AVG:%lf CNT:%" PRIu64 " TOTAL:%" PRIu64 " MIN:%" PRIu64
+ " MAX:%" PRIu64,
+ (((double)lat->total) / lat->count), lat->count,
+ lat->total, lat->min, lat->max);
+ gf_latency_reset(lat);
+}
-int
-gf_proc_dump_write (char *key, char *value, ...)
+void
+gf_proc_dump_xl_latency_info(xlator_t *xl)
{
- int ret = 0;
- va_list ap;
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i;
- va_start (ap, value);
- if (gf_dump_strfd)
- ret = gf_proc_dump_write_strfd (key, value, ap);
- else
- ret = gf_proc_dump_write_fd (key, value, ap);
- va_end (ap);
+ snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.latency", xl->name);
+ gf_proc_dump_add_section("%s", key_prefix);
- return ret;
-}
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ gf_proc_dump_build_key(key, key_prefix, "%s", (char *)gf_fop_list[i]);
+ gf_latency_t *lat = &xl->stats.interval.latencies[i];
+
+ gf_latency_statedump_and_reset(key, lat);
+ }
+}
static void
-gf_proc_dump_xlator_mem_info (xlator_t *xl)
-{
- int i = 0;
- struct mem_acct rec = {0,};
-
- if (!xl)
- return;
-
- if (!xl->mem_acct)
- 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 (!(memcmp (&xl->mem_acct->rec[i], &rec,
- sizeof (struct mem_acct))))
- continue;
-
- gf_proc_dump_add_section ("%s.%s - usage-type %s memusage",
- xl->type, xl->name,
- xl->mem_acct->rec[i].typestr);
- 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);
- }
+gf_proc_dump_xlator_mem_info(xlator_t *xl)
+{
+ int i = 0;
+ if (!xl)
return;
+
+ if (!xl->mem_acct)
+ 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].num_allocs == 0)
+ continue;
+
+ gf_proc_dump_add_section("%s.%s - usage-type %s memusage", xl->type,
+ xl->name, xl->mem_acct->rec[i].typestr);
+ gf_proc_dump_write("size", "%" PRIu64, 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", "%" PRIu64,
+ 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", "%" PRIu64,
+ xl->mem_acct->rec[i].total_allocs);
+ }
+
+ return;
}
static void
-gf_proc_dump_xlator_mem_info_only_in_use (xlator_t *xl)
+gf_proc_dump_xlator_mem_info_only_in_use(xlator_t *xl)
{
- int i = 0;
+ int i = 0;
- if (!xl)
- return;
+ if (!xl)
+ return;
- if (!xl->mem_acct->rec)
- return;
+ if (!xl->mem_acct)
+ 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);
+ 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;
+ 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_add_section("%s.%s - usage-type %d", xl->type, xl->name,
+ i);
- 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);
- }
+ gf_proc_dump_write("size", "%" PRIu64, xl->mem_acct->rec[i].size);
+ gf_proc_dump_write("max_size", "%" PRIu64,
+ 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", "%" PRIu64,
+ xl->mem_acct->rec[i].total_allocs);
+ }
- return;
+ return;
}
-
-
/* Currently this dumps only mallinfo. More can be built on here */
void
-gf_proc_dump_mem_info ()
-{
-#ifdef HAVE_MALLOC_STATS
- struct mallinfo info;
-
- memset (&info, 0, sizeof (struct mallinfo));
- info = mallinfo ();
-
- gf_proc_dump_add_section ("mallinfo");
- gf_proc_dump_write ("mallinfo_arena", "%d", info.arena);
- gf_proc_dump_write ("mallinfo_ordblks", "%d", info.ordblks);
- gf_proc_dump_write ("mallinfo_smblks", "%d", info.smblks);
- gf_proc_dump_write ("mallinfo_hblks", "%d", info.hblks);
- gf_proc_dump_write ("mallinfo_hblkhd", "%d", info.hblkhd);
- gf_proc_dump_write ("mallinfo_usmblks", "%d", info.usmblks);
- gf_proc_dump_write ("mallinfo_fsmblks", "%d", info.fsmblks);
- gf_proc_dump_write ("mallinfo_uordblks", "%d", info.uordblks);
- gf_proc_dump_write ("mallinfo_fordblks", "%d", info.fordblks);
- gf_proc_dump_write ("mallinfo_keepcost", "%d", info.keepcost);
+gf_proc_dump_mem_info()
+{
+#ifdef HAVE_MALLINFO
+ struct mallinfo info;
+
+ memset(&info, 0, sizeof(struct mallinfo));
+ info = mallinfo();
+
+ gf_proc_dump_add_section("mallinfo");
+ gf_proc_dump_write("mallinfo_arena", "%d", info.arena);
+ gf_proc_dump_write("mallinfo_ordblks", "%d", info.ordblks);
+ gf_proc_dump_write("mallinfo_smblks", "%d", info.smblks);
+ gf_proc_dump_write("mallinfo_hblks", "%d", info.hblks);
+ gf_proc_dump_write("mallinfo_hblkhd", "%d", info.hblkhd);
+ gf_proc_dump_write("mallinfo_usmblks", "%d", info.usmblks);
+ gf_proc_dump_write("mallinfo_fsmblks", "%d", info.fsmblks);
+ gf_proc_dump_write("mallinfo_uordblks", "%d", info.uordblks);
+ gf_proc_dump_write("mallinfo_fordblks", "%d", info.fordblks);
+ gf_proc_dump_write("mallinfo_keepcost", "%d", info.keepcost);
#endif
- gf_proc_dump_xlator_mem_info(&global_xlator);
-
+ gf_proc_dump_xlator_mem_info(&global_xlator);
}
void
-gf_proc_dump_mem_info_to_dict (dict_t *dict)
+gf_proc_dump_mem_info_to_dict(dict_t *dict)
{
- if (!dict)
- return;
-#ifdef HAVE_MALLOC_STATS
- struct mallinfo info;
- int ret = -1;
+ if (!dict)
+ return;
+#ifdef HAVE_MALLINFO
+ struct mallinfo info;
+ int ret = -1;
- memset (&info, 0, sizeof(struct mallinfo));
- info = mallinfo ();
+ memset(&info, 0, sizeof(struct mallinfo));
+ info = mallinfo();
- ret = dict_set_int32 (dict, "mallinfo.arena", info.arena);
- if (ret)
- return;
+ ret = dict_set_int32(dict, "mallinfo.arena", info.arena);
+ if (ret)
+ return;
- ret = dict_set_int32 (dict, "mallinfo.ordblks", info.ordblks);
- if (ret)
- return;
+ 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.smblks", info.smblks);
+ if (ret)
+ return;
- ret = dict_set_int32 (dict, "mallinfo.hblks", info.hblks);
- 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.hblkhd", info.hblkhd);
+ if (ret)
+ return;
- ret = dict_set_int32 (dict, "mallinfo.usmblks", info.usmblks);
- 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;
+ ret = dict_set_int32(dict, "mallinfo.fsmblks", info.fsmblks);
+ if (ret)
+ return;
- ret = dict_set_int32 (dict, "mallinfo.uordblks", info.uordblks);
- if (ret)
- return;
+ ret = dict_set_int32(dict, "mallinfo.uordblks", info.uordblks);
+ if (ret)
+ return;
- ret = dict_set_int32 (dict, "mallinfo.fordblks", info.fordblks);
- if (ret)
- return;
+ ret = dict_set_int32(dict, "mallinfo.fordblks", info.fordblks);
+ if (ret)
+ return;
- ret = dict_set_int32 (dict, "mallinfo.keepcost", info.keepcost);
- if (ret)
- return;
-#endif
+ ret = dict_set_int32(dict, "mallinfo.keepcost", info.keepcost);
+ if (ret)
return;
+#endif
+ return;
+}
+
+void
+gf_proc_dump_mempool_info(glusterfs_ctx_t *ctx)
+{
+#ifdef GF_DISABLE_MEMPOOL
+ gf_proc_dump_write("built with --disable-mempool", " so no memory pools");
+#else
+ struct mem_pool *pool = NULL;
+
+ gf_proc_dump_add_section("mempool");
+
+ LOCK(&ctx->lock);
+ {
+ list_for_each_entry(pool, &ctx->mempool_list, owner)
+ {
+ int64_t active = GF_ATOMIC_GET(pool->active);
+
+ gf_proc_dump_write("-----", "-----");
+ gf_proc_dump_write("pool-name", "%s", pool->name);
+ gf_proc_dump_write("xlator-name", "%s", pool->xl_name);
+ gf_proc_dump_write("active-count", "%" GF_PRI_ATOMIC, active);
+ gf_proc_dump_write("sizeof-type", "%lu", pool->sizeof_type);
+ gf_proc_dump_write("padded-sizeof", "%d",
+ 1 << pool->pool->power_of_two);
+ gf_proc_dump_write("size", "%" PRId64,
+ (1 << pool->pool->power_of_two) * active);
+ gf_proc_dump_write("shared-pool", "%p", pool->pool);
+ }
+ }
+ UNLOCK(&ctx->lock);
+#endif /* GF_DISABLE_MEMPOOL */
}
void
-gf_proc_dump_mempool_info (glusterfs_ctx_t *ctx)
+gf_proc_dump_mempool_info_to_dict(glusterfs_ctx_t *ctx, dict_t *dict)
{
- struct mem_pool *pool = NULL;
+#ifndef GF_DISABLE_MEMPOOL
+ struct mem_pool *pool = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {
+ 0,
+ };
+ int count = 0;
+ int ret = -1;
+
+ if (!ctx || !dict)
+ return;
+
+ LOCK(&ctx->lock);
+ {
+ list_for_each_entry(pool, &ctx->mempool_list, owner)
+ {
+ int64_t active = GF_ATOMIC_GET(pool->active);
+
+ snprintf(key, sizeof(key), "pool%d.name", count);
+ ret = dict_set_str(dict, key, pool->name);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "pool%d.active-count", count);
+ ret = dict_set_uint64(dict, key, active);
+ if (ret)
+ goto out;
- gf_proc_dump_add_section ("mempool");
+ snprintf(key, sizeof(key), "pool%d.sizeof-type", count);
+ ret = dict_set_uint64(dict, key, pool->sizeof_type);
+ if (ret)
+ goto out;
- 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);
+ snprintf(key, sizeof(key), "pool%d.padded-sizeof", count);
+ ret = dict_set_uint64(dict, key, 1 << pool->pool->power_of_two);
+ if (ret)
+ goto out;
+
+ snprintf(key, sizeof(key), "pool%d.size", count);
+ ret = dict_set_uint64(dict, key,
+ (1 << pool->pool->power_of_two) * active);
+ if (ret)
+ goto out;
- gf_proc_dump_write ("pool-misses", "%"PRIu64, pool->pool_misses);
- gf_proc_dump_write ("cur-stdalloc", "%d", pool->curr_stdalloc);
- gf_proc_dump_write ("max-stdalloc", "%d", pool->max_stdalloc);
+ snprintf(key, sizeof(key), "pool%d.shared-pool", count);
+ ret = dict_set_static_ptr(dict, key, pool->pool);
+ if (ret)
+ goto out;
}
+ }
+out:
+ UNLOCK(&ctx->lock);
+#endif /* !GF_DISABLE_MEMPOOL */
}
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;
-
- 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;
-
- 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;
-
- 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;
-
- 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;
-
- 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);
+gf_proc_dump_latency_info(xlator_t *xl);
- return;
+void
+gf_proc_dump_dict_info(glusterfs_ctx_t *ctx)
+{
+ int64_t total_dicts = 0;
+ int64_t total_pairs = 0;
+
+ total_dicts = GF_ATOMIC_GET(ctx->stats.total_dicts_used);
+ total_pairs = GF_ATOMIC_GET(ctx->stats.total_pairs_used);
+
+ gf_proc_dump_write("max-pairs-per-dict", "%" GF_PRI_ATOMIC,
+ GF_ATOMIC_GET(ctx->stats.max_dict_pairs));
+ gf_proc_dump_write("total-pairs-used", "%" PRId64, total_pairs);
+ gf_proc_dump_write("total-dicts-used", "%" PRId64, total_dicts);
+ gf_proc_dump_write("average-pairs-per-dict", "%" PRId64,
+ (total_pairs / total_dicts));
}
-void gf_proc_dump_latency_info (xlator_t *xl);
-
-void
-gf_proc_dump_xlator_info (xlator_t *top)
+static void
+gf_proc_dump_single_xlator_info(xlator_t *trav)
{
- xlator_t *trav = NULL;
- glusterfs_ctx_t *ctx = NULL;
- char itable_key[1024] = {0,};
+ glusterfs_ctx_t *ctx = trav->ctx;
+ char itable_key[1024] = {
+ 0,
+ };
- if (!top)
- return;
+ if (trav->cleanup_starting)
+ return;
- ctx = top->ctx;
+ if (ctx->measure_latency)
+ gf_proc_dump_xl_latency_info(trav);
- trav = top;
- while (trav) {
+ gf_proc_dump_xlator_mem_info(trav);
- if (ctx->measure_latency)
- gf_proc_dump_latency_info (trav);
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED(inode) && (trav->itable)) {
+ snprintf(itable_key, sizeof(itable_key), "%d.%s.itable", ctx->graph_id,
+ trav->name);
+ }
- gf_proc_dump_xlator_mem_info(trav);
+ if (!trav->dumpops) {
+ return;
+ }
+
+ if (trav->dumpops->priv && GF_PROC_DUMP_IS_XL_OPTION_ENABLED(priv))
+ trav->dumpops->priv(trav);
- if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
- (trav->itable)) {
- snprintf (itable_key, 1024, "%d.%s.itable",
- ctx->graph_id, trav->name);
- }
+ 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);
- if (!trav->dumpops) {
- trav = trav->next;
- continue;
- }
+ if (trav->dumpops->history && GF_PROC_DUMP_IS_XL_OPTION_ENABLED(history))
+ trav->dumpops->history(trav);
+}
+
+static void
+gf_proc_dump_per_xlator_info(xlator_t *top)
+{
+ xlator_t *trav = top;
- if (trav->dumpops->priv &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (priv))
- trav->dumpops->priv (trav);
+ while (trav && !trav->cleanup_starting) {
+ gf_proc_dump_single_xlator_info(trav);
+ trav = trav->next;
+ }
+}
- if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
- (trav->dumpops->inode))
- trav->dumpops->inode (trav);
+void
+gf_proc_dump_xlator_info(xlator_t *top, gf_boolean_t brick_mux)
+{
+ xlator_t *trav = NULL;
+ xlator_list_t **trav_p = NULL;
- if (trav->dumpops->fd &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (fd))
- trav->dumpops->fd (trav);
+ if (!top)
+ return;
- if (trav->dumpops->history &&
- GF_PROC_DUMP_IS_XL_OPTION_ENABLED (history))
- trav->dumpops->history (trav);
+ trav = top;
+ gf_proc_dump_per_xlator_info(trav);
- trav = trav->next;
+ if (brick_mux) {
+ trav_p = &top->children;
+ while (*trav_p) {
+ trav = (*trav_p)->xlator;
+ gf_proc_dump_per_xlator_info(trav);
+ trav_p = &(*trav_p)->next;
}
+ }
- return;
+ return;
}
static void
-gf_proc_dump_oldgraph_xlator_info (xlator_t *top)
+gf_proc_dump_oldgraph_xlator_info(xlator_t *top)
{
- xlator_t *trav = NULL;
+ xlator_t *trav = NULL;
- if (!top)
- return;
+ if (!top)
+ return;
- trav = top;
- while (trav) {
- gf_proc_dump_xlator_mem_info_only_in_use (trav);
+ trav = top;
+ while (trav) {
+ gf_proc_dump_xlator_mem_info_only_in_use(trav);
- if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
- (trav->itable)) {
- /*TODO: dump inode table info if necessary by
- printing the graph id (taken by glusterfs_cbtx_t)
- in the key
- */
- }
+ if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED(inode) && (trav->itable)) {
+ /*TODO: dump inode table info if necessary by
+ printing the graph id (taken by glusterfs_cbtx_t)
+ in the key
+ */
+ }
- if (!trav->dumpops) {
- trav = trav->next;
- continue;
- }
+ if (!trav->dumpops) {
+ trav = trav->next;
+ continue;
+ }
- if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
- (trav->dumpops->inode))
- trav->dumpops->inode (trav);
+ 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);
+ if (trav->dumpops->fd && GF_PROC_DUMP_IS_XL_OPTION_ENABLED(fd))
+ trav->dumpops->fd(trav);
- trav = trav->next;
- }
+ trav = trav->next;
+ }
- return;
+ return;
}
static int
-gf_proc_dump_enable_all_options ()
+gf_proc_dump_enable_all_options()
{
-
- GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_true);
- GF_PROC_DUMP_SET_OPTION (dump_options.dump_iobuf, _gf_true);
- GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_true);
- GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_priv, _gf_true);
- GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inode, _gf_true);
- GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fd, _gf_true);
- 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;
+ GF_PROC_DUMP_SET_OPTION(dump_options.dump_mem, _gf_true);
+ GF_PROC_DUMP_SET_OPTION(dump_options.dump_iobuf, _gf_true);
+ GF_PROC_DUMP_SET_OPTION(dump_options.dump_callpool, _gf_true);
+ GF_PROC_DUMP_SET_OPTION(dump_options.xl_options.dump_priv, _gf_true);
+ GF_PROC_DUMP_SET_OPTION(dump_options.xl_options.dump_inode, _gf_true);
+ GF_PROC_DUMP_SET_OPTION(dump_options.xl_options.dump_fd, _gf_true);
+ 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;
}
gf_boolean_t
-is_gf_proc_dump_all_disabled ()
-{
- gf_boolean_t all_disabled = _gf_true;
-
- GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_mem, all_disabled, out);
- GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_iobuf, all_disabled, out);
- GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_callpool, all_disabled,
- out);
- GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_priv,
- all_disabled, out);
- GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_inode,
- all_disabled, out);
- GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_fd,
- all_disabled, out);
- GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_inodectx,
- all_disabled, out);
- GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_fdctx,
- all_disabled, out);
- GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_history,
- all_disabled, out);
+is_gf_proc_dump_all_disabled()
+{
+ gf_boolean_t all_disabled = _gf_true;
+
+ GF_CHECK_DUMP_OPTION_ENABLED(dump_options.dump_mem, all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED(dump_options.dump_iobuf, all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED(dump_options.dump_callpool, all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED(dump_options.xl_options.dump_priv,
+ all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED(dump_options.xl_options.dump_inode,
+ all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED(dump_options.xl_options.dump_fd, all_disabled,
+ out);
+ GF_CHECK_DUMP_OPTION_ENABLED(dump_options.xl_options.dump_inodectx,
+ all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED(dump_options.xl_options.dump_fdctx,
+ all_disabled, out);
+ GF_CHECK_DUMP_OPTION_ENABLED(dump_options.xl_options.dump_history,
+ all_disabled, out);
out:
- return all_disabled;
+ return all_disabled;
}
/* These options are dumped by default if glusterdump.options
file exists and it is emtpty
*/
static int
-gf_proc_dump_enable_default_options ()
+gf_proc_dump_enable_default_options()
{
- GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_true);
- GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_true);
+ GF_PROC_DUMP_SET_OPTION(dump_options.dump_mem, _gf_true);
+ GF_PROC_DUMP_SET_OPTION(dump_options.dump_callpool, _gf_true);
- return 0;
+ return 0;
}
static int
-gf_proc_dump_disable_all_options ()
-{
-
- GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_false);
- GF_PROC_DUMP_SET_OPTION (dump_options.dump_iobuf, _gf_false);
- GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_false);
- GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_priv, _gf_false);
- GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_inode,
- _gf_false);
- GF_PROC_DUMP_SET_OPTION (dump_options.xl_options.dump_fd, _gf_false);
- 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;
+gf_proc_dump_disable_all_options()
+{
+ GF_PROC_DUMP_SET_OPTION(dump_options.dump_mem, _gf_false);
+ GF_PROC_DUMP_SET_OPTION(dump_options.dump_iobuf, _gf_false);
+ GF_PROC_DUMP_SET_OPTION(dump_options.dump_callpool, _gf_false);
+ GF_PROC_DUMP_SET_OPTION(dump_options.xl_options.dump_priv, _gf_false);
+ GF_PROC_DUMP_SET_OPTION(dump_options.xl_options.dump_inode, _gf_false);
+ GF_PROC_DUMP_SET_OPTION(dump_options.xl_options.dump_fd, _gf_false);
+ 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;
-
+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;
+ int len;
+
+ 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
+ len = snprintf(buf, sizeof(buf),
+ "[Warning]:None of the options "
+ "matched key : %s\n",
+ key);
+ if (len < 0)
+ ret = -1;
+ else {
+ ret = sys_write(gf_dump_fd, buf, len);
+ if (ret >= 0)
+ ret = -1;
}
+ goto out;
+ }
- opt_value = (strncasecmp (value, "yes", 3) ?
- _gf_false: _gf_true);
+ opt_value = (strncasecmp(value, "yes", 3) ? _gf_false : _gf_true);
- GF_PROC_DUMP_SET_OPTION (*opt_key, opt_value);
+ GF_PROC_DUMP_SET_OPTION(*opt_key, opt_value);
- ret = 0;
+ ret = 0;
out:
- return ret;
+ return ret;
}
static int
-gf_proc_dump_options_init ()
-{
- int ret = -1;
- FILE *fp = NULL;
- char buf[256];
- char *key = NULL, *value = NULL;
- char *saveptr = NULL;
- char dump_option_file[PATH_MAX];
-
- /* glusterd will create a file glusterdump.<pid>.options and
- sets the statedump options for the process and the file is removed
- after the statedump is taken. Direct issue of SIGUSR1 does not have
- mechanism for considering the statedump options. So to have a way
- of configuring the statedump of all the glusterfs processes through
- both cli command and SIGUSR1, glusterdump.options file is searched
- and the options mentioned in it are given the higher priority.
- */
- snprintf (dump_option_file, sizeof (dump_option_file),
- DEFAULT_VAR_RUN_DIRECTORY
- "/glusterdump.options");
- fp = fopen (dump_option_file, "r");
- if (!fp) {
- snprintf (dump_option_file, sizeof (dump_option_file),
- DEFAULT_VAR_RUN_DIRECTORY
- "/glusterdump.%d.options", getpid ());
-
- fp = fopen (dump_option_file, "r");
-
- if (!fp) {
- //ENOENT, return success
- (void) gf_proc_dump_enable_all_options ();
- return 0;
- }
- }
-
- (void) gf_proc_dump_disable_all_options ();
-
- // swallow the errors if setting statedump file path is failed.
- ret = gf_proc_dump_set_path (dump_option_file);
-
- ret = fscanf (fp, "%s", buf);
-
- while (ret != EOF) {
- key = strtok_r (buf, "=", &saveptr);
- if (!key) {
- ret = fscanf (fp, "%s", buf);
- continue;
- }
-
- value = strtok_r (NULL, "=", &saveptr);
-
- if (!value) {
- ret = fscanf (fp, "%s", buf);
- continue;
- }
-
- gf_proc_dump_parse_set_option (key, value);
- }
-
- if (is_gf_proc_dump_all_disabled ())
- (void) gf_proc_dump_enable_default_options ();
-
- if (fp)
- fclose (fp);
-
- return 0;
-}
-
-void
-gf_proc_dump_info (int signum, glusterfs_ctx_t *ctx)
+gf_proc_dump_options_init()
{
- int i = 0;
- int ret = -1;
- glusterfs_graph_t *trav = NULL;
- char brick_name[PATH_MAX] = {0,};
- char timestr[256] = {0,};
- char sign_string[512] = {0,};
- char tmp_dump_name[PATH_MAX] = {0,};
- char path[PATH_MAX] = {0,};
- struct timeval tv = {0,};
-
- gf_proc_dump_lock ();
+ int ret = -1;
+ FILE *fp = NULL;
+ char buf[256];
+ char *key = NULL, *value = NULL;
+ char *saveptr = NULL;
+ char dump_option_file[PATH_MAX];
+
+ /* glusterd will create a file glusterdump.<pid>.options and
+ sets the statedump options for the process and the file is removed
+ after the statedump is taken. Direct issue of SIGUSR1 does not have
+ mechanism for considering the statedump options. So to have a way
+ of configuring the statedump of all the glusterfs processes through
+ both cli command and SIGUSR1, glusterdump.options file is searched
+ and the options mentioned in it are given the higher priority.
+ */
+ snprintf(dump_option_file, sizeof(dump_option_file),
+ DEFAULT_VAR_RUN_DIRECTORY "/glusterdump.options");
+ fp = fopen(dump_option_file, "r");
+ if (!fp) {
+ snprintf(dump_option_file, sizeof(dump_option_file),
+ DEFAULT_VAR_RUN_DIRECTORY "/glusterdump.%d.options", getpid());
+
+ fp = fopen(dump_option_file, "r");
- 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));
-
- ret = gf_proc_dump_options_init ();
- if (ret < 0)
- goto out;
-
- snprintf (path, sizeof (path), "%s/%s.%d.dump.%"PRIu64,
- ((dump_options.dump_path != NULL)?dump_options.dump_path:
- ((ctx->statedump_path != NULL)?ctx->statedump_path:
- DEFAULT_VAR_RUN_DIRECTORY)), brick_name, getpid(),
- (uint64_t) time (NULL));
-
- snprintf (tmp_dump_name, PATH_MAX, "%s/dumpXXXXXX",
- ((dump_options.dump_path != NULL)?dump_options.dump_path:
- ((ctx->statedump_path != NULL)?ctx->statedump_path:
- DEFAULT_VAR_RUN_DIRECTORY)));
-
- ret = gf_proc_dump_open (tmp_dump_name);
- if (ret < 0)
- goto out;
-
- //continue even though gettimeofday() has failed
- ret = gettimeofday (&tv, NULL);
- if (0 == ret) {
- 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);
+ if (!fp) {
+ // ENOENT, return success
+ (void)gf_proc_dump_enable_all_options();
+ return 0;
}
+ }
- snprintf (sign_string, sizeof (sign_string), "DUMP-START-TIME: %s\n",
- timestr);
+ (void)gf_proc_dump_disable_all_options();
- //swallow the errors of write for start and end marker
- ret = write (gf_dump_fd, sign_string, strlen (sign_string));
+ // swallow the errors if setting statedump file path is failed.
+ (void)gf_proc_dump_set_path(dump_option_file);
- memset (sign_string, 0, sizeof (sign_string));
- memset (timestr, 0, sizeof (timestr));
- memset (&tv, 0, sizeof (tv));
+ ret = fscanf(fp, "%255s", buf);
- if (GF_PROC_DUMP_IS_OPTION_ENABLED (mem)) {
- gf_proc_dump_mem_info ();
- gf_proc_dump_mempool_info (ctx);
+ while (ret != EOF) {
+ key = strtok_r(buf, "=", &saveptr);
+ if (!key) {
+ ret = fscanf(fp, "%255s", buf);
+ continue;
}
- 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);
+ value = strtok_r(NULL, "=", &saveptr);
- if (ctx->master) {
- gf_proc_dump_add_section ("fuse");
- gf_proc_dump_xlator_info (ctx->master);
+ if (!value) {
+ ret = fscanf(fp, "%255s", buf);
+ continue;
}
- if (ctx->active) {
- gf_proc_dump_add_section ("active graph - %d", ctx->graph_id);
- gf_proc_dump_xlator_info (ctx->active->top);
- }
+ gf_proc_dump_parse_set_option(key, value);
+ }
- i = 0;
- list_for_each_entry (trav, &ctx->graphs, list) {
- if (trav == ctx->active)
- continue;
+ if (is_gf_proc_dump_all_disabled())
+ (void)gf_proc_dump_enable_default_options();
- gf_proc_dump_add_section ("oldgraph[%d]", i);
+ if (fp)
+ fclose(fp);
- gf_proc_dump_oldgraph_xlator_info (trav->top);
- i++;
- }
+ return 0;
+}
- ret = gettimeofday (&tv, NULL);
- if (0 == ret) {
- 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);
+void
+gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx)
+{
+ int i = 0;
+ int ret = -1;
+ glusterfs_graph_t *trav = NULL;
+ char brick_name[PATH_MAX] = {
+ 0,
+ };
+ char timestr[GF_TIMESTR_SIZE] = {
+ 0,
+ };
+ char sign_string[512] = {
+ 0,
+ };
+ char tmp_dump_name[PATH_MAX] = {
+ 0,
+ };
+ char path[PATH_MAX] = {
+ 0,
+ };
+ struct timeval tv = {
+ 0,
+ };
+ gf_boolean_t is_brick_mux = _gf_false;
+ xlator_t *top = NULL;
+ xlator_list_t **trav_p = NULL;
+ int brick_count = 0;
+ int len = 0;
+
+ gf_msg_trace("dump", 0, "received statedump request (sig:USR1)");
+
+ if (!ctx)
+ goto out;
+
+ /*
+ * Multiplexed daemons can change the active graph when attach/detach
+ * is called. So this has to be protected with the cleanup lock.
+ */
+ if (mgmt_is_multiplexed_daemon(ctx->cmd_args.process_name))
+ pthread_mutex_lock(&ctx->cleanup_lock);
+ gf_proc_dump_lock();
+
+ if (!mgmt_is_multiplexed_daemon(ctx->cmd_args.process_name) &&
+ (ctx && ctx->active)) {
+ top = ctx->active->first;
+ for (trav_p = &top->children; *trav_p; trav_p = &(*trav_p)->next) {
+ brick_count++;
}
- snprintf (sign_string, sizeof (sign_string), "\nDUMP-END-TIME: %s",
- timestr);
- ret = write (gf_dump_fd, sign_string, strlen (sign_string));
-
+ if (brick_count > 1)
+ is_brick_mux = _gf_true;
+ }
+
+ if (ctx->cmd_args.brick_name) {
+ GF_REMOVE_SLASH_FROM_PATH(ctx->cmd_args.brick_name, brick_name);
+ } else
+ snprintf(brick_name, sizeof(brick_name), "glusterdump");
+
+ ret = gf_proc_dump_options_init();
+ if (ret < 0)
+ goto out;
+
+ ret = snprintf(
+ path, sizeof(path), "%s/%s.%d.dump.%" PRIu64,
+ ((dump_options.dump_path != NULL)
+ ? dump_options.dump_path
+ : ((ctx->statedump_path != NULL) ? ctx->statedump_path
+ : DEFAULT_VAR_RUN_DIRECTORY)),
+ brick_name, getpid(), (uint64_t)gf_time());
+ if ((ret < 0) || (ret >= sizeof(path))) {
+ goto out;
+ }
+
+ snprintf(
+ tmp_dump_name, PATH_MAX, "%s/dumpXXXXXX",
+ ((dump_options.dump_path != NULL)
+ ? dump_options.dump_path
+ : ((ctx->statedump_path != NULL) ? ctx->statedump_path
+ : DEFAULT_VAR_RUN_DIRECTORY)));
+
+ ret = gf_proc_dump_open(tmp_dump_name);
+ if (ret < 0)
+ goto out;
+
+ // continue even though gettimeofday() has failed
+ ret = gettimeofday(&tv, NULL);
+ if (0 == ret) {
+ gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT);
+ }
+
+ len = snprintf(sign_string, sizeof(sign_string), "DUMP-START-TIME: %s\n",
+ timestr);
+
+ // swallow the errors of write for start and end marker
+ (void)sys_write(gf_dump_fd, sign_string, len);
+
+ memset(timestr, 0, sizeof(timestr));
+
+ if (GF_PROC_DUMP_IS_OPTION_ENABLED(mem)) {
+ gf_proc_dump_mem_info();
+ gf_proc_dump_mempool_info(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);
+
+ /* dictionary stats */
+ gf_proc_dump_add_section("dict");
+ gf_proc_dump_dict_info(ctx);
+
+ if (ctx->master) {
+ gf_proc_dump_add_section("fuse");
+ gf_proc_dump_single_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, is_brick_mux);
+ }
+
+ i = 0;
+ list_for_each_entry(trav, &ctx->graphs, list)
+ {
+ if (trav == ctx->active)
+ continue;
+
+ gf_proc_dump_add_section("oldgraph[%d]", i);
+
+ gf_proc_dump_oldgraph_xlator_info(trav->top);
+ i++;
+ }
+
+ ret = gettimeofday(&tv, NULL);
+ if (0 == ret) {
+ gf_time_fmt_tv(timestr, sizeof timestr, &tv, gf_timefmt_FT);
+ }
+
+ len = snprintf(sign_string, sizeof(sign_string), "\nDUMP-END-TIME: %s",
+ timestr);
+ (void)sys_write(gf_dump_fd, sign_string, len);
+
+ if (gf_dump_fd != -1)
+ gf_proc_dump_close();
+ sys_rename(tmp_dump_name, path);
out:
- if (gf_dump_fd != -1)
- gf_proc_dump_close ();
- rename (tmp_dump_name, path);
- GF_FREE (dump_options.dump_path);
- dump_options.dump_path = NULL;
- gf_proc_dump_unlock ();
-
- return;
+ GF_FREE(dump_options.dump_path);
+ dump_options.dump_path = NULL;
+ if (ctx) {
+ gf_proc_dump_unlock();
+ if (mgmt_is_multiplexed_daemon(ctx->cmd_args.process_name))
+ pthread_mutex_unlock(&ctx->cleanup_lock);
+ }
+
+ return;
}
-
void
-gf_proc_dump_fini (void)
+gf_proc_dump_fini(void)
{
- pthread_mutex_destroy (&gf_proc_dump_mutex);
+ pthread_mutex_destroy(&gf_proc_dump_mutex);
}
-
void
-gf_proc_dump_init ()
+gf_proc_dump_init()
{
- pthread_mutex_init (&gf_proc_dump_mutex, NULL);
+ pthread_mutex_init(&gf_proc_dump_mutex, NULL);
- return;
+ return;
}
-
void
-gf_proc_dump_cleanup (void)
+gf_proc_dump_cleanup(void)
{
- pthread_mutex_destroy (&gf_proc_dump_mutex);
+ pthread_mutex_destroy(&gf_proc_dump_mutex);
}
-
void
-gf_proc_dump_xlator_private (xlator_t *this, strfd_t *strfd)
+gf_proc_dump_xlator_private(xlator_t *this, strfd_t *strfd)
{
- gf_proc_dump_lock ();
- {
- gf_dump_strfd = strfd;
+ gf_proc_dump_lock();
+ {
+ gf_dump_strfd = strfd;
- if (this->dumpops && this->dumpops->priv)
- this->dumpops->priv (this);
+ if (this->dumpops && this->dumpops->priv)
+ this->dumpops->priv(this);
- gf_dump_strfd = NULL;
- }
- gf_proc_dump_unlock ();
+ gf_dump_strfd = NULL;
+ }
+ gf_proc_dump_unlock();
}
-
void
-gf_proc_dump_mallinfo (strfd_t *strfd)
+gf_proc_dump_mallinfo(strfd_t *strfd)
{
- gf_proc_dump_lock ();
- {
- gf_dump_strfd = strfd;
+ gf_proc_dump_lock();
+ {
+ gf_dump_strfd = strfd;
- gf_proc_dump_mem_info ();
+ gf_proc_dump_mem_info();
- gf_dump_strfd = NULL;
- }
- gf_proc_dump_unlock ();
+ gf_dump_strfd = NULL;
+ }
+ gf_proc_dump_unlock();
}
-
void
-gf_proc_dump_xlator_history (xlator_t *this, strfd_t *strfd)
+gf_proc_dump_xlator_history(xlator_t *this, strfd_t *strfd)
{
- gf_proc_dump_lock ();
- {
- gf_dump_strfd = strfd;
+ gf_proc_dump_lock();
+ {
+ gf_dump_strfd = strfd;
- if (this->dumpops && this->dumpops->history)
- this->dumpops->history (this);
+ if (this->dumpops && this->dumpops->history)
+ this->dumpops->history(this);
- gf_dump_strfd = NULL;
- }
- gf_proc_dump_unlock ();
+ gf_dump_strfd = NULL;
+ }
+ gf_proc_dump_unlock();
}
-
void
-gf_proc_dump_xlator_itable (xlator_t *this, strfd_t *strfd)
+gf_proc_dump_xlator_itable(xlator_t *this, strfd_t *strfd)
{
- gf_proc_dump_lock ();
- {
- gf_dump_strfd = strfd;
-
+ gf_proc_dump_lock();
+ {
+ gf_dump_strfd = strfd;
- gf_dump_strfd = NULL;
- }
- gf_proc_dump_unlock ();
+ gf_dump_strfd = NULL;
+ }
+ gf_proc_dump_unlock();
}
-
void
-gf_proc_dump_xlator_meminfo (xlator_t *this, strfd_t *strfd)
+gf_proc_dump_xlator_meminfo(xlator_t *this, strfd_t *strfd)
{
- gf_proc_dump_lock ();
- {
- gf_dump_strfd = strfd;
+ gf_proc_dump_lock();
+ {
+ gf_dump_strfd = strfd;
- gf_proc_dump_xlator_mem_info (this);
+ gf_proc_dump_xlator_mem_info(this);
- gf_dump_strfd = NULL;
- }
- gf_proc_dump_unlock ();
+ gf_dump_strfd = NULL;
+ }
+ gf_proc_dump_unlock();
}
-
void
-gf_proc_dump_xlator_profile (xlator_t *this, strfd_t *strfd)
+gf_proc_dump_xlator_profile(xlator_t *this, strfd_t *strfd)
{
- gf_proc_dump_lock ();
- {
- gf_dump_strfd = strfd;
+ gf_proc_dump_lock();
+ {
+ gf_dump_strfd = strfd;
- gf_proc_dump_latency_info (this);
+ gf_proc_dump_xl_latency_info(this);
- gf_dump_strfd = NULL;
- }
- gf_proc_dump_unlock ();
+ gf_dump_strfd = NULL;
+ }
+ gf_proc_dump_unlock();
}
diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h
deleted file mode 100644
index 39a68bd69da..00000000000
--- a/libglusterfs/src/statedump.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- 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 STATEDUMP_H
-#define STATEDUMP_H
-
-#include <stdarg.h>
-#include "inode.h"
-#include "strfd.h"
-
-#define GF_DUMP_MAX_BUF_LEN 4096
-
-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_ {
- gf_boolean_t dump_mem;
- gf_boolean_t dump_iobuf;
- gf_boolean_t dump_callpool;
- gf_dump_xl_options_t xl_options; //options for all xlators
- char *dump_path;
-} gf_dump_options_t;
-
-extern gf_dump_options_t dump_options;
-
-static inline
-void _gf_proc_dump_build_key (char *key, const char *prefix, char *fmt,...)
-{
- char buf[GF_DUMP_MAX_BUF_LEN];
- va_list ap;
-
- memset(buf, 0, sizeof(buf));
- va_start(ap, fmt);
- vsnprintf(buf, GF_DUMP_MAX_BUF_LEN, fmt, ap);
- va_end(ap);
- snprintf(key, GF_DUMP_MAX_BUF_LEN, "%s.%s", prefix, buf);
-}
-
-#define gf_proc_dump_build_key(key, key_prefix, fmt...) \
- { \
- _gf_proc_dump_build_key(key, key_prefix, ##fmt); \
- }
-
-#define GF_PROC_DUMP_SET_OPTION(opt,val) opt = val
-
-#define GF_CHECK_DUMP_OPTION_ENABLED(option_dump, var, label) \
- do { \
- if (option_dump == _gf_true) { \
- var = _gf_false; \
- goto label; \
- } \
- } while (0);
-
-void gf_proc_dump_init();
-
-void gf_proc_dump_fini(void);
-
-void gf_proc_dump_cleanup(void);
-
-void gf_proc_dump_info(int signum, glusterfs_ctx_t *ctx);
-
-int gf_proc_dump_add_section(char *key,...);
-
-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);
-
-void gf_proc_dump_xlator_private (xlator_t *this, strfd_t *strfd);
-
-void gf_proc_dump_mallinfo (strfd_t *strfd);
-
-void gf_proc_dump_xlator_history (xlator_t *this, strfd_t *strfd);
-
-void gf_proc_dump_xlator_meminfo (xlator_t *this, strfd_t *strfd);
-
-void gf_proc_dump_xlator_profile (xlator_t *this, strfd_t *strfd);
-
-#endif /* STATEDUMP_H */
diff --git a/libglusterfs/src/store.c b/libglusterfs/src/store.c
index daa57101a46..5c316b9291a 100644
--- a/libglusterfs/src/store.c
+++ b/libglusterfs/src/store.c
@@ -11,717 +11,734 @@
#include <inttypes.h>
#include <libgen.h>
-#include "glusterfs.h"
-#include "store.h"
-#include "dict.h"
-#include "xlator.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/glusterfs.h"
+#include "glusterfs/store.h"
+#include "glusterfs/xlator.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/libglusterfs-messages.h"
+
int32_t
-gf_store_mkdir (char *path)
+gf_store_mkdir(char *path)
{
- int32_t ret = -1;
+ int32_t ret = -1;
- ret = mkdir (path, 0777);
+ ret = mkdir_p(path, 0755, _gf_true);
- if ((-1 == ret) && (EEXIST != errno)) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, "mkdir()"
- " failed on path %s.", path);
- } else {
- ret = 0;
- }
+ if ((-1 == ret) && (EEXIST != errno)) {
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
+ "mkdir()"
+ " failed on path %s.",
+ path);
+ } else {
+ ret = 0;
+ }
- return ret;
+ return ret;
}
int32_t
-gf_store_handle_create_on_absence (gf_store_handle_t **shandle,
- char *path)
+gf_store_handle_create_on_absence(gf_store_handle_t **shandle, char *path)
{
- GF_ASSERT (shandle);
- int32_t ret = 0;
+ GF_ASSERT(shandle);
+ int32_t ret = 0;
- if (*shandle == NULL) {
- ret = gf_store_handle_new (path, shandle);
+ if (*shandle == NULL) {
+ ret = gf_store_handle_new(path, shandle);
- if (ret) {
- gf_msg ("", GF_LOG_ERROR, 0,
- LG_MSG_STORE_HANDLE_CREATE_FAILED, "Unable to"
- " create store handle for path: %s", path);
- }
+ if (ret) {
+ gf_msg("", GF_LOG_ERROR, 0, LG_MSG_STORE_HANDLE_CREATE_FAILED,
+ "Unable to"
+ " create store handle for path: %s",
+ path);
}
- return ret;
+ }
+ return ret;
}
int32_t
-gf_store_mkstemp (gf_store_handle_t *shandle)
+gf_store_mkstemp(gf_store_handle_t *shandle)
{
- char tmppath[PATH_MAX] = {0,};
-
- GF_VALIDATE_OR_GOTO ("store", shandle, out);
- GF_VALIDATE_OR_GOTO ("store", shandle->path, out);
-
- snprintf (tmppath, sizeof (tmppath), "%s.tmp", shandle->path);
- shandle->tmp_fd = open (tmppath, O_RDWR | O_CREAT | O_TRUNC, 0600);
- if (shandle->tmp_fd < 0) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Failed to open %s.", tmppath);
- }
+ char tmppath[PATH_MAX] = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO("store", shandle, out);
+ GF_VALIDATE_OR_GOTO("store", shandle->path, out);
+
+ snprintf(tmppath, sizeof(tmppath), "%s.tmp", shandle->path);
+ shandle->tmp_fd = open(tmppath, O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (shandle->tmp_fd < 0) {
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to open %s.", tmppath);
+ }
out:
- return shandle->tmp_fd;
+ return shandle->tmp_fd;
}
int
-gf_store_sync_direntry (char *path)
+gf_store_sync_direntry(char *path)
{
- int ret = -1;
- int dirfd = -1;
- char *dir = NULL;
- char *pdir = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- dir = gf_strdup (path);
- if (!dir)
- goto out;
-
- pdir = dirname (dir);
- dirfd = open (pdir, O_RDONLY);
- if (dirfd == -1) {
- gf_msg (this->name, GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
- "Failed to open directory %s.", pdir);
- goto out;
- }
-
- ret = fsync (dirfd);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- LG_MSG_DIR_OP_FAILED, "Failed to fsync %s.", pdir);
- goto out;
- }
-
- ret = 0;
+ int ret = -1;
+ int dirfd = -1;
+ char *dir = NULL;
+ char *pdir = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ dir = gf_strdup(path);
+ if (!dir)
+ goto out;
+
+ pdir = dirname(dir);
+ dirfd = open(pdir, O_RDONLY);
+ if (dirfd == -1) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
+ "Failed to open directory %s.", pdir);
+ goto out;
+ }
+
+ ret = sys_fsync(dirfd);
+ if (ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
+ "Failed to fsync %s.", pdir);
+ goto out;
+ }
+
+ ret = 0;
out:
- if (dirfd >= 0) {
- ret = close (dirfd);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- LG_MSG_DIR_OP_FAILED, "Failed to close %s", pdir);
- }
+ if (dirfd >= 0) {
+ ret = sys_close(dirfd);
+ if (ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
+ "Failed to close %s", pdir);
}
+ }
- if (dir)
- GF_FREE (dir);
+ if (dir)
+ GF_FREE(dir);
- return ret;
+ return ret;
}
int32_t
-gf_store_rename_tmppath (gf_store_handle_t *shandle)
+gf_store_rename_tmppath(gf_store_handle_t *shandle)
{
- int32_t ret = -1;
- char tmppath[PATH_MAX] = {0,};
-
- GF_VALIDATE_OR_GOTO ("store", shandle, out);
- GF_VALIDATE_OR_GOTO ("store", shandle->path, out);
-
- ret = fsync (shandle->tmp_fd);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Failed to fsync %s", shandle->path);
- goto out;
- }
- snprintf (tmppath, sizeof (tmppath), "%s.tmp", shandle->path);
- ret = rename (tmppath, shandle->path);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Failed to rename %s to %s", tmppath,
- shandle->path);
- goto out;
- }
-
- ret = gf_store_sync_direntry (tmppath);
+ int32_t ret = -1;
+ char tmppath[PATH_MAX] = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO("store", shandle, out);
+ GF_VALIDATE_OR_GOTO("store", shandle->path, out);
+
+ ret = sys_fsync(shandle->tmp_fd);
+ if (ret) {
+ gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to fsync %s", shandle->path);
+ goto out;
+ }
+ snprintf(tmppath, sizeof(tmppath), "%s.tmp", shandle->path);
+ ret = sys_rename(tmppath, shandle->path);
+ if (ret) {
+ gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to rename %s to %s", tmppath, shandle->path);
+ goto out;
+ }
+
+ ret = gf_store_sync_direntry(tmppath);
out:
- if (shandle && shandle->tmp_fd >= 0) {
- close (shandle->tmp_fd);
- shandle->tmp_fd = -1;
- }
- return ret;
+ if (shandle && shandle->tmp_fd >= 0) {
+ sys_close(shandle->tmp_fd);
+ shandle->tmp_fd = -1;
+ }
+ return ret;
}
int32_t
-gf_store_unlink_tmppath (gf_store_handle_t *shandle)
+gf_store_unlink_tmppath(gf_store_handle_t *shandle)
{
- int32_t ret = -1;
- char tmppath[PATH_MAX] = {0,};
-
- GF_VALIDATE_OR_GOTO ("store", shandle, out);
- GF_VALIDATE_OR_GOTO ("store", shandle->path, out);
-
- snprintf (tmppath, sizeof (tmppath), "%s.tmp", shandle->path);
- ret = unlink (tmppath);
- if (ret && (errno != ENOENT)) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Failed to mv %s to %s", tmppath,
- shandle->path);
- } else {
- ret = 0;
- }
+ int32_t ret = -1;
+ char tmppath[PATH_MAX] = {
+ 0,
+ };
+
+ GF_VALIDATE_OR_GOTO("store", shandle, out);
+ GF_VALIDATE_OR_GOTO("store", shandle->path, out);
+
+ snprintf(tmppath, sizeof(tmppath), "%s.tmp", shandle->path);
+ ret = sys_unlink(tmppath);
+ if (ret && (errno != ENOENT)) {
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to mv %s to %s", tmppath, shandle->path);
+ } else {
+ ret = 0;
+ }
out:
- if (shandle && shandle->tmp_fd >= 0) {
- close (shandle->tmp_fd);
- shandle->tmp_fd = -1;
- }
- return ret;
+ if (shandle && shandle->tmp_fd >= 0) {
+ sys_close(shandle->tmp_fd);
+ shandle->tmp_fd = -1;
+ }
+ return ret;
}
int
-gf_store_read_and_tokenize (FILE *file, char *str, char **iter_key,
- char **iter_val, gf_store_op_errno_t *store_errno)
+gf_store_read_and_tokenize(FILE *file, char **iter_key, char **iter_val,
+ gf_store_op_errno_t *store_errno)
{
- int32_t ret = -1;
- char *savetok = NULL;
- char *key = NULL;
- char *value = NULL;
- char *temp = NULL;
- size_t str_len = 0;
-
- GF_ASSERT (file);
- GF_ASSERT (str);
- GF_ASSERT (iter_key);
- GF_ASSERT (iter_val);
- GF_ASSERT (store_errno);
-
- temp = fgets (str, PATH_MAX, file);
- if (temp == NULL || feof (file)) {
- ret = -1;
- *store_errno = GD_STORE_EOF;
- goto out;
- }
-
- str_len = strlen(str);
- str[str_len - 1] = '\0';
- /* Truncate the "\n", as fgets stores "\n" in str */
-
- key = strtok_r (str, "=", &savetok);
- if (!key) {
- ret = -1;
- *store_errno = GD_STORE_KEY_NULL;
- goto out;
- }
-
- value = strtok_r (NULL, "", &savetok);
- if (!value) {
- ret = -1;
- *store_errno = GD_STORE_VALUE_NULL;
- goto out;
- }
-
- *iter_key = key;
- *iter_val = value;
- *store_errno = GD_STORE_SUCCESS;
- ret = 0;
+ int32_t ret = -1;
+ char *savetok = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ char *temp = NULL;
+ size_t str_len = 0;
+ char str[8192];
+
+ GF_ASSERT(file);
+ GF_ASSERT(iter_key);
+ GF_ASSERT(iter_val);
+ GF_ASSERT(store_errno);
+
+retry:
+ temp = fgets(str, 8192, file);
+ if (temp == NULL || feof(file)) {
+ ret = -1;
+ *store_errno = GD_STORE_EOF;
+ goto out;
+ }
+
+ if (strcmp(str, "\n") == 0)
+ goto retry;
+
+ str_len = strlen(str);
+ str[str_len - 1] = '\0';
+ /* Truncate the "\n", as fgets stores "\n" in str */
+
+ key = strtok_r(str, "=", &savetok);
+ if (!key) {
+ ret = -1;
+ *store_errno = GD_STORE_KEY_NULL;
+ goto out;
+ }
+
+ value = strtok_r(NULL, "", &savetok);
+ if (!value) {
+ ret = -1;
+ *store_errno = GD_STORE_VALUE_NULL;
+ goto out;
+ }
+
+ *iter_key = key;
+ *iter_val = value;
+ *store_errno = GD_STORE_SUCCESS;
+ ret = 0;
out:
- return ret;
+ return ret;
}
int32_t
-gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value)
+gf_store_retrieve_value(gf_store_handle_t *handle, char *key, char **value)
{
- int32_t ret = -1;
- char *scan_str = NULL;
- char *iter_key = NULL;
- char *iter_val = NULL;
- char *free_str = NULL;
- struct stat st = {0,};
- gf_store_op_errno_t store_errno = GD_STORE_SUCCESS;
-
- GF_ASSERT (handle);
-
- if (handle->locked == F_ULOCK)
- /* no locking is used handle->fd gets closed() after usage */
- handle->fd = open (handle->path, O_RDWR);
- else
- /* handle->fd is valid already, kept open for lockf() */
- lseek (handle->fd, 0, SEEK_SET);
-
- if (handle->fd == -1) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Unable to open file %s", handle->path);
- goto out;
- }
- if (!handle->read)
- handle->read = fdopen (dup(handle->fd), "r");
- else
- fseek (handle->read, 0, SEEK_SET);
-
+ int32_t ret = -1;
+ char *iter_key = NULL;
+ char *iter_val = NULL;
+ gf_store_op_errno_t store_errno = GD_STORE_SUCCESS;
+
+ GF_ASSERT(handle);
+
+ if (handle->locked == F_ULOCK)
+ /* no locking is used handle->fd gets closed() after usage */
+ handle->fd = open(handle->path, O_RDWR);
+ else
+ /* handle->fd is valid already, kept open for lockf() */
+ sys_lseek(handle->fd, 0, SEEK_SET);
+
+ if (handle->fd == -1) {
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Unable to open file %s", handle->path);
+ goto out;
+ }
+ if (!handle->read) {
+ int duped_fd = dup(handle->fd);
+
+ if (duped_fd >= 0)
+ handle->read = fdopen(duped_fd, "r");
if (!handle->read) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Unable to open file %s", handle->path);
- goto out;
- }
-
- ret = fstat (handle->fd, &st);
+ if (duped_fd != -1)
+ sys_close(duped_fd);
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Unable to open file %s", handle->path);
+ goto out;
+ }
+ } else {
+ fseek(handle->read, 0, SEEK_SET);
+ }
+ do {
+ ret = gf_store_read_and_tokenize(handle->read, &iter_key, &iter_val,
+ &store_errno);
if (ret < 0) {
- gf_msg ("", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
- "stat on file %s failed", handle->path);
- ret = -1;
- store_errno = GD_STORE_STAT_FAILED;
- goto out;
- }
-
- /* "st.st_size + 1" is used as we are fetching each
- * line of a file using fgets, fgets will append "\0"
- * to the end of the string
- */
- scan_str = GF_CALLOC (1, st.st_size + 1,
- gf_common_mt_char);
-
- if (scan_str == NULL) {
- ret = -1;
- store_errno = GD_STORE_ENOMEM;
- goto out;
+ gf_msg_trace("", 0,
+ "error while reading key '%s': "
+ "%s",
+ key, gf_store_strerror(store_errno));
+ goto out;
}
- free_str = scan_str;
-
- do {
- ret = gf_store_read_and_tokenize (handle->read, scan_str,
- &iter_key, &iter_val,
- &store_errno);
- if (ret < 0) {
- gf_msg_trace ("", 0, "error while reading key '%s': "
- "%s", key,
- gf_store_strerror (store_errno));
- goto out;
- }
-
- gf_msg_trace ("", 0, "key %s read", iter_key);
-
- if (!strcmp (key, iter_key)) {
- gf_msg_debug ("", 0, "key %s found", key);
- ret = 0;
- if (iter_val)
- *value = gf_strdup (iter_val);
- goto out;
- }
- } while (1);
-out:
- if (handle->read) {
- fclose (handle->read);
- handle->read = NULL;
- }
+ gf_msg_trace("", 0, "key %s read", iter_key);
- if (handle->fd > 0 && handle->locked == F_ULOCK) {
- /* only invalidate handle->fd if not locked */
- close (handle->fd);
+ if (!strcmp(key, iter_key)) {
+ gf_msg_debug("", 0, "key %s found", key);
+ ret = 0;
+ if (iter_val)
+ *value = gf_strdup(iter_val);
+ goto out;
}
+ } while (1);
+out:
+ if (handle->read) {
+ fclose(handle->read);
+ handle->read = NULL;
+ }
- GF_FREE (free_str);
+ if (handle->fd > 0 && handle->locked == F_ULOCK) {
+ /* only invalidate handle->fd if not locked */
+ sys_close(handle->fd);
+ }
- return ret;
+ return ret;
}
int32_t
-gf_store_save_value (int fd, char *key, char *value)
+gf_store_save_value(int fd, char *key, char *value)
{
- int32_t ret = -1;
- int dup_fd = -1;
- FILE *fp = NULL;
-
- GF_ASSERT (fd > 0);
- GF_ASSERT (key);
- GF_ASSERT (value);
-
- dup_fd = dup (fd);
- if (dup_fd == -1)
- goto out;
-
- fp = fdopen (dup_fd, "a+");
- if (fp == NULL) {
- gf_msg (THIS->name, GF_LOG_WARNING, errno,
- LG_MSG_FILE_OP_FAILED, "fdopen failed.");
- ret = -1;
- goto out;
- }
-
- ret = fprintf (fp, "%s=%s\n", key, value);
- if (ret < 0) {
- gf_msg (THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
- "Unable to store key: %s, value: %s.",
- key, value);
- ret = -1;
- goto out;
- }
-
- ret = fflush (fp);
- if (ret) {
- gf_msg (THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
- "fflush failed.");
- ret = -1;
- goto out;
- }
-
- ret = 0;
+ int32_t ret = -1;
+ int dup_fd = -1;
+ FILE *fp = NULL;
+
+ GF_ASSERT(fd > 0);
+ GF_ASSERT(key);
+ GF_ASSERT(value);
+
+ dup_fd = dup(fd);
+ if (dup_fd == -1)
+ goto out;
+
+ fp = fdopen(dup_fd, "a+");
+ if (fp == NULL) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "fdopen failed.");
+ ret = -1;
+ goto out;
+ }
+
+ ret = fprintf(fp, "%s=%s\n", key, value);
+ if (ret < 0) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Unable to store key: %s, value: %s.", key, value);
+ ret = -1;
+ goto out;
+ }
+
+ ret = fflush(fp);
+ if (ret) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "fflush failed.");
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
out:
- if (fp)
- fclose (fp);
+ if (fp)
+ fclose(fp);
- gf_msg_debug (THIS->name, 0, "returning: %d", ret);
- return ret;
+ gf_msg_debug(THIS->name, 0, "returning: %d", ret);
+ return ret;
}
int32_t
-gf_store_handle_new (const char *path, gf_store_handle_t **handle)
+gf_store_save_items(int fd, char *items)
{
- int32_t ret = -1;
- gf_store_handle_t *shandle = NULL;
- int fd = -1;
- char *spath = NULL;
-
- shandle = GF_CALLOC (1, sizeof (*shandle), gf_common_mt_store_handle_t);
- if (!shandle)
- goto out;
-
- spath = gf_strdup (path);
- if (!spath)
- goto out;
-
- fd = open (path, O_RDWR | O_CREAT | O_APPEND, 0600);
- if (fd < 0) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Failed to open file: %s.", path);
- goto out;
- }
-
- ret = gf_store_sync_direntry (spath);
- if (ret)
- goto out;
+ int32_t ret = -1;
+ int dup_fd = -1;
+ FILE *fp = NULL;
+
+ GF_ASSERT(fd > 0);
+ GF_ASSERT(items);
+
+ dup_fd = dup(fd);
+ if (dup_fd == -1)
+ goto out;
+
+ fp = fdopen(dup_fd, "a+");
+ if (fp == NULL) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "fdopen failed.");
+ ret = -1;
+ goto out;
+ }
+
+ ret = fputs(items, fp);
+ if (ret < 0) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "Unable to store items: %s", items);
+ ret = -1;
+ goto out;
+ }
+
+ ret = fflush(fp);
+ if (ret) {
+ gf_msg(THIS->name, GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
+ "fflush failed.");
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (fp)
+ fclose(fp);
- shandle->path = spath;
- shandle->locked = F_ULOCK;
- *handle = shandle;
- shandle->tmp_fd = -1;
+ gf_msg_debug(THIS->name, 0, "returning: %d", ret);
+ return ret;
+}
- ret = 0;
+int32_t
+gf_store_handle_new(const char *path, gf_store_handle_t **handle)
+{
+ int32_t ret = -1;
+ gf_store_handle_t *shandle = NULL;
+ int fd = -1;
+ char *spath = NULL;
+
+ shandle = GF_CALLOC(1, sizeof(*shandle), gf_common_mt_store_handle_t);
+ if (!shandle)
+ goto out;
+
+ spath = gf_strdup(path);
+ if (!spath)
+ goto out;
+
+ fd = open(path, O_RDWR | O_CREAT | O_APPEND, 0600);
+ if (fd < 0) {
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to open file: %s.", path);
+ goto out;
+ }
+
+ ret = gf_store_sync_direntry(spath);
+ if (ret)
+ goto out;
+
+ shandle->path = spath;
+ shandle->locked = F_ULOCK;
+ *handle = shandle;
+ shandle->tmp_fd = -1;
+
+ ret = 0;
out:
- if (fd >= 0)
- close (fd);
+ if (fd >= 0)
+ sys_close(fd);
- if (ret == -1) {
- GF_FREE (spath);
- GF_FREE (shandle);
- }
+ if (ret) {
+ GF_FREE(spath);
+ GF_FREE(shandle);
+ }
- gf_msg_debug ("", 0, "Returning %d", ret);
- return ret;
+ gf_msg_debug("", 0, "Returning %d", ret);
+ return ret;
}
int
-gf_store_handle_retrieve (char *path, gf_store_handle_t **handle)
+gf_store_handle_retrieve(char *path, gf_store_handle_t **handle)
{
- int32_t ret = -1;
- struct stat statbuf = {0};
-
- ret = stat (path, &statbuf);
- if (ret) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_PATH_NOT_FOUND, "Path "
- "corresponding to %s.", path);
- goto out;
- }
- ret = gf_store_handle_new (path, handle);
+ int32_t ret = -1;
+ struct stat statbuf = {0};
+
+ ret = sys_stat(path, &statbuf);
+ if (ret) {
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_PATH_NOT_FOUND,
+ "Path "
+ "corresponding to %s.",
+ path);
+ goto out;
+ }
+ ret = gf_store_handle_new(path, handle);
out:
- gf_msg_debug ("", 0, "Returning %d", ret);
- return ret;
+ gf_msg_debug("", 0, "Returning %d", ret);
+ return ret;
}
int32_t
-gf_store_handle_destroy (gf_store_handle_t *handle)
+gf_store_handle_destroy(gf_store_handle_t *handle)
{
- int32_t ret = -1;
+ int32_t ret = -1;
- if (!handle) {
- ret = 0;
- goto out;
- }
+ if (!handle) {
+ ret = 0;
+ goto out;
+ }
- GF_FREE (handle->path);
+ GF_FREE(handle->path);
- GF_FREE (handle);
+ GF_FREE(handle);
- ret = 0;
+ ret = 0;
out:
- gf_msg_debug ("", 0, "Returning %d", ret);
+ gf_msg_debug("", 0, "Returning %d", ret);
- return ret;
+ return ret;
}
int32_t
-gf_store_iter_new (gf_store_handle_t *shandle, gf_store_iter_t **iter)
+gf_store_iter_new(gf_store_handle_t *shandle, gf_store_iter_t **iter)
{
- int32_t ret = -1;
- FILE *fp = NULL;
- gf_store_iter_t *tmp_iter = NULL;
-
- GF_ASSERT (shandle);
- GF_ASSERT (iter);
-
- fp = fopen (shandle->path, "r");
- if (!fp) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Unable to open file %s", shandle->path);
- goto out;
- }
+ int32_t ret = -1;
+ FILE *fp = NULL;
+ gf_store_iter_t *tmp_iter = NULL;
- tmp_iter = GF_CALLOC (1, sizeof (*tmp_iter),
- gf_common_mt_store_iter_t);
- if (!tmp_iter)
- goto out;
+ GF_ASSERT(shandle);
+ GF_ASSERT(iter);
- strncpy (tmp_iter->filepath, shandle->path, sizeof (tmp_iter->filepath));
- tmp_iter->filepath[sizeof (tmp_iter->filepath) - 1] = 0;
- tmp_iter->file = fp;
+ fp = fopen(shandle->path, "r");
+ if (!fp) {
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Unable to open file %s", shandle->path);
+ goto out;
+ }
- *iter = tmp_iter;
- tmp_iter = NULL;
- ret = 0;
+ tmp_iter = GF_CALLOC(1, sizeof(*tmp_iter), gf_common_mt_store_iter_t);
+ if (!tmp_iter)
+ goto out;
+
+ if (snprintf(tmp_iter->filepath, sizeof(tmp_iter->filepath), "%s",
+ shandle->path) >= sizeof(tmp_iter->filepath))
+ goto out;
+
+ tmp_iter->file = fp;
+
+ *iter = tmp_iter;
+ tmp_iter = NULL;
+ ret = 0;
out:
- if (ret && fp)
- fclose (fp);
+ if (ret && fp)
+ fclose(fp);
- GF_FREE (tmp_iter);
+ GF_FREE(tmp_iter);
- gf_msg_debug ("", 0, "Returning with %d", ret);
- return ret;
+ gf_msg_debug("", 0, "Returning with %d", ret);
+ return ret;
}
int32_t
-gf_store_validate_key_value (char *storepath, char *key, char *val,
- gf_store_op_errno_t *op_errno)
+gf_store_validate_key_value(char *storepath, char *key, char *val,
+ gf_store_op_errno_t *op_errno)
{
- int ret = 0;
-
- GF_ASSERT (op_errno);
- GF_ASSERT (storepath);
-
- if ((key == NULL) && (val == NULL)) {
- ret = -1;
- gf_msg ("", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "Glusterd "
- "store may be corrupted, Invalid key and value (null)"
- " in %s", storepath);
- *op_errno = GD_STORE_KEY_VALUE_NULL;
- } else if (key == NULL) {
- ret = -1;
- gf_msg ("", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "Glusterd "
- "store may be corrupted, Invalid key (null) in %s",
- storepath);
- *op_errno = GD_STORE_KEY_NULL;
- } else if (val == NULL) {
- ret = -1;
- gf_msg ("", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "Glusterd "
- "store may be corrupted, Invalid value (null) for key"
- " %s in %s", key, storepath);
- *op_errno = GD_STORE_VALUE_NULL;
- } else {
- ret = 0;
- *op_errno = GD_STORE_SUCCESS;
- }
+ int ret = 0;
+
+ GF_ASSERT(op_errno);
+ GF_ASSERT(storepath);
+
+ if ((key == NULL) && (val == NULL)) {
+ ret = -1;
+ gf_msg("", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
+ "Glusterd "
+ "store may be corrupted, Invalid key and value (null)"
+ " in %s",
+ storepath);
+ *op_errno = GD_STORE_KEY_VALUE_NULL;
+ } else if (key == NULL) {
+ ret = -1;
+ gf_msg("", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
+ "Glusterd "
+ "store may be corrupted, Invalid key (null) in %s",
+ storepath);
+ *op_errno = GD_STORE_KEY_NULL;
+ } else if (val == NULL) {
+ ret = -1;
+ gf_msg("", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
+ "Glusterd "
+ "store may be corrupted, Invalid value (null) for key"
+ " %s in %s",
+ key, storepath);
+ *op_errno = GD_STORE_VALUE_NULL;
+ } else {
+ ret = 0;
+ *op_errno = GD_STORE_SUCCESS;
+ }
- return ret;
+ return ret;
}
int32_t
-gf_store_iter_get_next (gf_store_iter_t *iter, char **key, char **value,
- gf_store_op_errno_t *op_errno)
+gf_store_iter_get_next(gf_store_iter_t *iter, char **key, char **value,
+ gf_store_op_errno_t *op_errno)
{
- int32_t ret = -1;
- char *scan_str = NULL;
- char *iter_key = NULL;
- char *iter_val = NULL;
- struct stat st = {0,};
- gf_store_op_errno_t store_errno = GD_STORE_SUCCESS;
-
- GF_ASSERT (iter);
- GF_ASSERT (key);
- GF_ASSERT (value);
-
- ret = stat (iter->filepath, &st);
- if (ret < 0) {
- gf_msg ("", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED,
- "stat on file failed");
- ret = -1;
- store_errno = GD_STORE_STAT_FAILED;
- goto out;
- }
-
- /* "st.st_size + 1" is used as we are fetching each
- * line of a file using fgets, fgets will append "\0"
- * to the end of the string
- */
- scan_str = GF_CALLOC (1, st.st_size + 1,
- gf_common_mt_char);
- if (!scan_str) {
- ret = -1;
- store_errno = GD_STORE_ENOMEM;
- goto out;
- }
-
- ret = gf_store_read_and_tokenize (iter->file, scan_str,
- &iter_key, &iter_val,
- &store_errno);
- if (ret < 0) {
- goto out;
- }
-
- ret = gf_store_validate_key_value (iter->filepath, iter_key,
- iter_val, &store_errno);
- if (ret)
- goto out;
-
- *key = gf_strdup (iter_key);
- if (!*key) {
- ret = -1;
- store_errno = GD_STORE_ENOMEM;
- goto out;
- }
- *value = gf_strdup (iter_val);
- if (!*value) {
- ret = -1;
- store_errno = GD_STORE_ENOMEM;
- goto out;
- }
- ret = 0;
+ int32_t ret = -1;
+ char *iter_key = NULL;
+ char *iter_val = NULL;
+ gf_store_op_errno_t store_errno = GD_STORE_SUCCESS;
+
+ GF_ASSERT(iter);
+ GF_ASSERT(key);
+ GF_ASSERT(value);
+
+ ret = gf_store_read_and_tokenize(iter->file, &iter_key, &iter_val,
+ &store_errno);
+ if (ret < 0) {
+ goto out;
+ }
+
+ ret = gf_store_validate_key_value(iter->filepath, iter_key, iter_val,
+ &store_errno);
+ if (ret)
+ goto out;
+
+ *key = gf_strdup(iter_key);
+ if (!*key) {
+ ret = -1;
+ store_errno = GD_STORE_ENOMEM;
+ goto out;
+ }
+ *value = gf_strdup(iter_val);
+ if (!*value) {
+ ret = -1;
+ store_errno = GD_STORE_ENOMEM;
+ goto out;
+ }
+ ret = 0;
out:
- GF_FREE (scan_str);
- if (ret) {
- GF_FREE (*key);
- GF_FREE (*value);
- *key = NULL;
- *value = NULL;
- }
- if (op_errno)
- *op_errno = store_errno;
-
- gf_msg_debug ("", 0, "Returning with %d", ret);
- return ret;
+ if (ret) {
+ GF_FREE(*key);
+ GF_FREE(*value);
+ *key = NULL;
+ *value = NULL;
+ }
+ if (op_errno)
+ *op_errno = store_errno;
+
+ gf_msg_debug("", 0, "Returning with %d", ret);
+ return ret;
}
int32_t
-gf_store_iter_get_matching (gf_store_iter_t *iter, char *key, char **value)
+gf_store_iter_get_matching(gf_store_iter_t *iter, char *key, char **value)
{
- int32_t ret = -1;
- char *tmp_key = NULL;
- char *tmp_value = NULL;
-
- ret = gf_store_iter_get_next (iter, &tmp_key, &tmp_value, NULL);
- while (!ret) {
- if (!strncmp (key, tmp_key, strlen (key))){
- *value = tmp_value;
- GF_FREE (tmp_key);
- goto out;
- }
- GF_FREE (tmp_key);
- tmp_key = NULL;
- GF_FREE (tmp_value);
- tmp_value = NULL;
- ret = gf_store_iter_get_next (iter, &tmp_key, &tmp_value,
- NULL);
- }
+ int32_t ret = -1;
+ char *tmp_key = NULL;
+ char *tmp_value = NULL;
+
+ ret = gf_store_iter_get_next(iter, &tmp_key, &tmp_value, NULL);
+ while (!ret) {
+ if (!strncmp(key, tmp_key, strlen(key))) {
+ *value = tmp_value;
+ GF_FREE(tmp_key);
+ goto out;
+ }
+ GF_FREE(tmp_key);
+ tmp_key = NULL;
+ GF_FREE(tmp_value);
+ tmp_value = NULL;
+ ret = gf_store_iter_get_next(iter, &tmp_key, &tmp_value, NULL);
+ }
out:
- return ret;
+ return ret;
}
int32_t
-gf_store_iter_destroy (gf_store_iter_t *iter)
+gf_store_iter_destroy(gf_store_iter_t **iter)
{
- int32_t ret = -1;
+ int32_t ret = -1;
+
+ if (!(*iter))
+ return 0;
- if (!iter)
- return 0;
+ /* gf_store_iter_new will not return a valid iter object with iter->file
+ * being NULL*/
+ ret = fclose((*iter)->file);
+ if (ret)
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Unable"
+ " to close file: %s, ret: %d",
+ (*iter)->filepath, ret);
- /* gf_store_iter_new will not return a valid iter object with iter->file
- * being NULL*/
- ret = fclose (iter->file);
- if (ret)
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, "Unable"
- " to close file: %s, ret: %d" ,
- iter->filepath, ret);
+ GF_FREE(*iter);
+ *iter = NULL;
- GF_FREE (iter);
- return ret;
+ return ret;
}
-char*
-gf_store_strerror (gf_store_op_errno_t op_errno)
+char *
+gf_store_strerror(gf_store_op_errno_t op_errno)
{
- switch (op_errno) {
+ switch (op_errno) {
case GD_STORE_SUCCESS:
- return "Success";
+ return "Success";
case GD_STORE_KEY_NULL:
- return "Invalid Key";
+ return "Invalid Key";
case GD_STORE_VALUE_NULL:
- return "Invalid Value";
+ return "Invalid Value";
case GD_STORE_KEY_VALUE_NULL:
- return "Invalid Key and Value";
+ return "Invalid Key and Value";
case GD_STORE_EOF:
- return "No data";
+ return "No data";
case GD_STORE_ENOMEM:
- return "No memory";
+ return "No memory";
default:
- return "Invalid errno";
- }
+ return "Invalid errno";
+ }
}
int
-gf_store_lock (gf_store_handle_t *sh)
+gf_store_lock(gf_store_handle_t *sh)
{
- int ret;
-
- GF_ASSERT (sh);
- GF_ASSERT (sh->path);
- GF_ASSERT (sh->locked == F_ULOCK);
-
- sh->fd = open (sh->path, O_RDWR);
- if (sh->fd == -1) {
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
- "Failed to open '%s'", sh->path);
- return -1;
- }
-
- ret = lockf (sh->fd, F_LOCK, 0);
- if (ret)
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_LOCK_FAILED,
- "Failed to gain lock on '%s'", sh->path);
- else
- /* sh->locked is protected by the lockf(sh->fd) above */
- sh->locked = F_LOCK;
-
- return ret;
+ int ret;
+
+ GF_ASSERT(sh);
+ GF_ASSERT(sh->path);
+ GF_ASSERT(sh->locked == F_ULOCK);
+
+ sh->fd = open(sh->path, O_RDWR);
+ if (sh->fd == -1) {
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED,
+ "Failed to open '%s'", sh->path);
+ return -1;
+ }
+
+ ret = lockf(sh->fd, F_LOCK, 0);
+ if (ret)
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_LOCK_FAILED,
+ "Failed to gain lock on '%s'", sh->path);
+ else
+ /* sh->locked is protected by the lockf(sh->fd) above */
+ sh->locked = F_LOCK;
+
+ return ret;
}
void
-gf_store_unlock (gf_store_handle_t *sh)
+gf_store_unlock(gf_store_handle_t *sh)
{
- GF_ASSERT (sh);
- GF_ASSERT (sh->locked == F_LOCK);
+ GF_ASSERT(sh);
+ GF_ASSERT(sh->locked == F_LOCK);
- sh->locked = F_ULOCK;
+ sh->locked = F_ULOCK;
- /* does not matter if this fails, locks are released on close anyway */
- if (lockf (sh->fd, F_ULOCK, 0) == -1)
- gf_msg ("", GF_LOG_ERROR, errno, LG_MSG_UNLOCK_FAILED,
- "Failed to release lock on '%s'", sh->path);
+ /* does not matter if this fails, locks are released on close anyway */
+ if (lockf(sh->fd, F_ULOCK, 0) == -1)
+ gf_msg("", GF_LOG_ERROR, errno, LG_MSG_UNLOCK_FAILED,
+ "Failed to release lock on '%s'", sh->path);
- close (sh->fd);
+ sys_close(sh->fd);
}
int
-gf_store_locked_local (gf_store_handle_t *sh)
+gf_store_locked_local(gf_store_handle_t *sh)
{
- GF_ASSERT (sh);
+ GF_ASSERT(sh);
- return (sh->locked == F_LOCK);
+ return (sh->locked == F_LOCK);
}
diff --git a/libglusterfs/src/store.h b/libglusterfs/src/store.h
deleted file mode 100644
index 4a726c6f00b..00000000000
--- a/libglusterfs/src/store.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- Copyright (c) 2013 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 _GLUSTERD_STORE_H_
-#define _GLUSTERD_STORE_H_
-
-#include "compat.h"
-#include "glusterfs.h"
-
-struct gf_store_handle_ {
- char *path;
- int fd;
- int tmp_fd;
- FILE *read;
- int locked; /* state of lockf() */
-};
-
-typedef struct gf_store_handle_ gf_store_handle_t;
-
-struct gf_store_iter_ {
- FILE *file;
- char filepath[PATH_MAX];
-};
-
-typedef struct gf_store_iter_ gf_store_iter_t;
-
-typedef enum {
- GD_STORE_SUCCESS,
- GD_STORE_KEY_NULL,
- GD_STORE_VALUE_NULL,
- GD_STORE_KEY_VALUE_NULL,
- GD_STORE_EOF,
- GD_STORE_ENOMEM,
- GD_STORE_STAT_FAILED
-} gf_store_op_errno_t;
-
-int32_t
-gf_store_mkdir (char *path);
-
-int32_t
-gf_store_handle_create_on_absence (gf_store_handle_t **shandle, char *path);
-
-int32_t
-gf_store_mkstemp (gf_store_handle_t *shandle);
-
-int
-gf_store_sync_direntry (char *path);
-
-int32_t
-gf_store_rename_tmppath (gf_store_handle_t *shandle);
-
-int32_t
-gf_store_unlink_tmppath (gf_store_handle_t *shandle);
-
-int
-gf_store_read_and_tokenize (FILE *file, char *str, char **iter_key,
- char **iter_val, gf_store_op_errno_t *store_errno);
-
-int32_t
-gf_store_retrieve_value (gf_store_handle_t *handle, char *key, char **value);
-
-int32_t
-gf_store_save_value (int fd, char *key, char *value);
-
-int32_t
-gf_store_handle_new (const char *path, gf_store_handle_t **handle);
-
-int
-gf_store_handle_retrieve (char *path, gf_store_handle_t **handle);
-
-int32_t
-gf_store_handle_destroy (gf_store_handle_t *handle);
-
-int32_t
-gf_store_iter_new (gf_store_handle_t *shandle, gf_store_iter_t **iter);
-
-int32_t
-gf_store_validate_key_value (char *storepath, char *key, char *val,
- gf_store_op_errno_t *op_errno);
-
-int32_t
-gf_store_iter_get_next (gf_store_iter_t *iter, char **key, char **value,
- gf_store_op_errno_t *op_errno);
-
-int32_t
-gf_store_iter_get_matching (gf_store_iter_t *iter, char *key, char **value);
-
-int32_t
-gf_store_iter_destroy (gf_store_iter_t *iter);
-
-char*
-gf_store_strerror (gf_store_op_errno_t op_errno);
-
-int
-gf_store_lock (gf_store_handle_t *sh);
-
-void
-gf_store_unlock (gf_store_handle_t *sh);
-
-int
-gf_store_locked_local (gf_store_handle_t *sh);
-
-#endif
diff --git a/libglusterfs/src/strfd.c b/libglusterfs/src/strfd.c
index 002d48629bc..8a2580edc85 100644
--- a/libglusterfs/src/strfd.c
+++ b/libglusterfs/src/strfd.c
@@ -10,83 +10,84 @@
#include <stdarg.h>
-#include "mem-types.h"
-#include "mem-pool.h"
-#include "strfd.h"
-#include "common-utils.h"
+#include "glusterfs/mem-types.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/strfd.h"
+#include "glusterfs/common-utils.h"
strfd_t *
-strfd_open ()
+strfd_open()
{
- strfd_t *strfd = NULL;
+ strfd_t *strfd = NULL;
- strfd = GF_CALLOC(1, sizeof(*strfd), gf_common_mt_strfd_t);
+ strfd = GF_CALLOC(1, sizeof(*strfd), gf_common_mt_strfd_t);
- return strfd;
+ return strfd;
}
int
-strvprintf (strfd_t *strfd, const char *fmt, va_list ap)
+strvprintf(strfd_t *strfd, const char *fmt, va_list ap)
{
- char *str = NULL;
- int size = 0;
-
- size = vasprintf (&str, fmt, ap);
-
- if (size < 0)
- return size;
-
- if (!strfd->alloc_size) {
- strfd->data = GF_CALLOC (max(size + 1, 4096), 1,
- gf_common_mt_strfd_data_t);
- if (!strfd->data) {
- free (str); /* NOT GF_FREE */
- return -1;
- }
- strfd->alloc_size = max(size + 1, 4096);
- }
+ char *str = NULL;
+ int size = 0;
+
+ size = vasprintf(&str, fmt, ap);
+
+ if (size < 0)
+ return size;
- if (strfd->alloc_size <= (strfd->size + size)) {
- char *tmp_ptr = NULL;
- int new_size = max ((strfd->alloc_size * 2),
- gf_roundup_next_power_of_two (strfd->size + size + 1));
- tmp_ptr = GF_REALLOC (strfd->data, new_size);
- if (!tmp_ptr) {
- free (str); /* NOT GF_FREE */
- return -1;
- }
- strfd->alloc_size = new_size;
- strfd->data = tmp_ptr;
+ if (!strfd->alloc_size) {
+ strfd->data = GF_CALLOC(max(size + 1, 4096), 1,
+ gf_common_mt_strfd_data_t);
+ if (!strfd->data) {
+ free(str); /* NOT GF_FREE */
+ return -1;
+ }
+ strfd->alloc_size = max(size + 1, 4096);
+ }
+
+ if (strfd->alloc_size <= (strfd->size + size)) {
+ char *tmp_ptr = NULL;
+ int new_size = max(
+ (strfd->alloc_size * 2),
+ gf_roundup_next_power_of_two(strfd->size + size + 1));
+ tmp_ptr = GF_REALLOC(strfd->data, new_size);
+ if (!tmp_ptr) {
+ free(str); /* NOT GF_FREE */
+ return -1;
}
+ strfd->alloc_size = new_size;
+ strfd->data = tmp_ptr;
+ }
- /* Copy the trailing '\0', but do not account for it in ->size.
- This allows safe use of strfd->data as a string. */
- memcpy (strfd->data + strfd->size, str, size + 1);
- strfd->size += size;
+ /* Copy the trailing '\0', but do not account for it in ->size.
+ This allows safe use of strfd->data as a string. */
+ memcpy(strfd->data + strfd->size, str, size + 1);
+ strfd->size += size;
- free (str); /* NOT GF_FREE */
+ free(str); /* NOT GF_FREE */
- return size;
+ return size;
}
int
-strprintf (strfd_t *strfd, const char *fmt, ...)
+strprintf(strfd_t *strfd, const char *fmt, ...)
{
- int ret = 0;
- va_list ap;
+ int ret = 0;
+ va_list ap;
- va_start (ap, fmt);
- ret = strvprintf (strfd, fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ ret = strvprintf(strfd, fmt, ap);
+ va_end(ap);
- return ret;
+ return ret;
}
int
-strfd_close (strfd_t *strfd)
+strfd_close(strfd_t *strfd)
{
- GF_FREE (strfd->data);
- GF_FREE (strfd);
+ GF_FREE(strfd->data);
+ GF_FREE(strfd);
- return 0;
+ return 0;
}
diff --git a/libglusterfs/src/syncop-utils.c b/libglusterfs/src/syncop-utils.c
index 4e8849f06f8..d9f1723856d 100644
--- a/libglusterfs/src/syncop-utils.c
+++ b/libglusterfs/src/syncop-utils.c
@@ -8,30 +8,44 @@
cases as published by the Free Software Foundation.
*/
-#include "syncop.h"
-#include "common-utils.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/syncop.h"
+#include "glusterfs/syncop-utils.h"
+#include "glusterfs/common-utils.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+struct syncop_dir_scan_data {
+ xlator_t *subvol;
+ loc_t *parent;
+ void *data;
+ gf_dirent_t *q;
+ gf_dirent_t *entry;
+ pthread_cond_t *cond;
+ pthread_mutex_t *mut;
+ syncop_dir_scan_fn_t fn;
+ uint32_t *jobs_running;
+ uint32_t *qlen;
+ int32_t *retval;
+};
int
-syncop_dirfd (xlator_t *subvol, loc_t *loc, fd_t **fd, int pid)
+syncop_dirfd(xlator_t *subvol, loc_t *loc, fd_t **fd, int pid)
{
- int ret = 0;
- fd_t *dirfd = NULL;
-
- if (!fd)
- return -EINVAL;
-
- dirfd = fd_create (loc->inode, pid);
- if (!dirfd) {
- gf_msg (subvol->name, GF_LOG_ERROR, errno,
- LG_MSG_FD_CREATE_FAILED, "fd_create of %s",
- uuid_utoa (loc->gfid));
- ret = -errno;
- goto out;
- }
-
- ret = syncop_opendir (subvol, loc, dirfd, NULL, NULL);
- if (ret) {
+ int ret = 0;
+ fd_t *dirfd = NULL;
+
+ if (!fd)
+ return -EINVAL;
+
+ dirfd = fd_create(loc->inode, pid);
+ if (!dirfd) {
+ gf_msg(subvol->name, GF_LOG_ERROR, errno, LG_MSG_FD_CREATE_FAILED,
+ "fd_create of %s", uuid_utoa(loc->gfid));
+ ret = -errno;
+ goto out;
+ }
+
+ ret = syncop_opendir(subvol, loc, dirfd, NULL, NULL);
+ if (ret) {
/*
* On Linux, if the brick was not updated, opendir will
* fail. We therefore use backward compatible code
@@ -42,93 +56,95 @@ syncop_dirfd (xlator_t *subvol, loc_t *loc, fd_t **fd, int pid)
* to provide backward-compatibility.
*/
#ifdef GF_LINUX_HOST_OS
- fd_unref (dirfd);
- dirfd = fd_anonymous (loc->inode);
- if (!dirfd) {
- gf_msg (subvol->name, GF_LOG_ERROR, errno,
- LG_MSG_FD_ANONYMOUS_FAILED, "fd_anonymous of "
- "%s", uuid_utoa (loc->gfid));
- ret = -errno;
- goto out;
- }
- ret = 0;
-#else /* GF_LINUX_HOST_OS */
- fd_unref (dirfd);
- gf_msg (subvol->name, GF_LOG_ERROR, errno,
- LG_MSG_DIR_OP_FAILED, "opendir of %s",
- uuid_utoa (loc->gfid));
- goto out;
-#endif /* GF_LINUX_HOST_OS */
- } else {
- fd_bind (dirfd);
+ fd_unref(dirfd);
+ dirfd = fd_anonymous(loc->inode);
+ if (!dirfd) {
+ gf_msg(subvol->name, GF_LOG_ERROR, errno,
+ LG_MSG_FD_ANONYMOUS_FAILED,
+ "fd_anonymous of "
+ "%s",
+ uuid_utoa(loc->gfid));
+ ret = -errno;
+ goto out;
}
+ ret = 0;
+#else /* GF_LINUX_HOST_OS */
+ fd_unref(dirfd);
+ gf_msg(subvol->name, GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED,
+ "opendir of %s", uuid_utoa(loc->gfid));
+ goto out;
+#endif /* GF_LINUX_HOST_OS */
+ } else {
+ fd_bind(dirfd);
+ }
out:
- if (ret == 0)
- *fd = dirfd;
- return ret;
+ if (ret == 0)
+ *fd = dirfd;
+ return ret;
}
int
-syncop_ftw (xlator_t *subvol, loc_t *loc, int pid, void *data,
- int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
- void *data))
+syncop_ftw(xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn)(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data))
{
- loc_t child_loc = {0, };
- fd_t *fd = NULL;
- uint64_t offset = 0;
- gf_dirent_t *entry = NULL;
- int ret = 0;
- gf_dirent_t entries;
-
- ret = syncop_dirfd (subvol, loc, &fd, pid);
- if (ret)
- goto out;
+ loc_t child_loc = {
+ 0,
+ };
+ fd_t *fd = NULL;
+ uint64_t offset = 0;
+ gf_dirent_t *entry = NULL;
+ int ret = 0;
+ gf_dirent_t entries;
+
+ ret = syncop_dirfd(subvol, loc, &fd, pid);
+ if (ret)
+ goto out;
+
+ INIT_LIST_HEAD(&entries.list);
+
+ while ((ret = syncop_readdirp(subvol, fd, 131072, offset, &entries, NULL,
+ NULL))) {
+ if (ret < 0)
+ break;
- INIT_LIST_HEAD (&entries.list);
+ if (ret > 0) {
+ /* If the entries are only '.', and '..' then ret
+ * value will be non-zero. so set it to zero here. */
+ ret = 0;
+ }
+ list_for_each_entry(entry, &entries.list, list)
+ {
+ offset = entry->d_off;
- while ((ret = syncop_readdirp (subvol, fd, 131072, offset, &entries,
- NULL, NULL))) {
- if (ret < 0)
- break;
+ if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
+ continue;
- if (ret > 0) {
- /* If the entries are only '.', and '..' then ret
- * value will be non-zero. so set it to zero here. */
- ret = 0;
- }
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
-
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
-
- gf_link_inode_from_dirent (NULL, fd->inode, entry);
-
- ret = fn (subvol, entry, loc, data);
- if (ret)
- break;
-
- if (entry->d_stat.ia_type == IA_IFDIR) {
- child_loc.inode = inode_ref (entry->inode);
- gf_uuid_copy (child_loc.gfid, entry->inode->gfid);
- ret = syncop_ftw (subvol, &child_loc,
- pid, data, fn);
- loc_wipe (&child_loc);
- if (ret)
- break;
- }
- }
+ gf_link_inode_from_dirent(NULL, fd->inode, entry);
+
+ ret = fn(subvol, entry, loc, data);
+ if (ret)
+ break;
- gf_dirent_free (&entries);
+ if (entry->d_stat.ia_type == IA_IFDIR) {
+ child_loc.inode = inode_ref(entry->inode);
+ gf_uuid_copy(child_loc.gfid, entry->inode->gfid);
+ ret = syncop_ftw(subvol, &child_loc, pid, data, fn);
+ loc_wipe(&child_loc);
if (ret)
- break;
+ break;
+ }
}
+ gf_dirent_free(&entries);
+ if (ret)
+ break;
+ }
+
out:
- if (fd)
- fd_unref (fd);
- return ret;
+ if (fd)
+ fd_unref(fd);
+ return ret;
}
/**
@@ -141,214 +157,513 @@ out:
* syncop_ftw.
*/
int
-syncop_ftw_throttle (xlator_t *subvol, loc_t *loc, int pid, void *data,
- int (*fn) (xlator_t *subvol, gf_dirent_t *entry,
- loc_t *parent, void *data),
- int count, int sleep_time)
+syncop_ftw_throttle(xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn)(xlator_t *subvol, gf_dirent_t *entry,
+ loc_t *parent, void *data),
+ int count, int sleep_time)
{
- loc_t child_loc = {0, };
- fd_t *fd = NULL;
- uint64_t offset = 0;
- gf_dirent_t *entry = NULL;
- int ret = 0;
- gf_dirent_t entries;
- int tmp = 0;
-
- if (sleep_time <= 0) {
- ret = syncop_ftw (subvol, loc, pid, data, fn);
- goto out;
- }
+ loc_t child_loc = {
+ 0,
+ };
+ fd_t *fd = NULL;
+ uint64_t offset = 0;
+ gf_dirent_t *entry = NULL;
+ int ret = 0;
+ gf_dirent_t entries;
+ int tmp = 0;
+
+ if (sleep_time <= 0) {
+ ret = syncop_ftw(subvol, loc, pid, data, fn);
+ goto out;
+ }
+
+ ret = syncop_dirfd(subvol, loc, &fd, pid);
+ if (ret)
+ goto out;
+
+ INIT_LIST_HEAD(&entries.list);
+
+ while ((ret = syncop_readdirp(subvol, fd, 131072, offset, &entries, NULL,
+ NULL))) {
+ if (ret < 0)
+ break;
- ret = syncop_dirfd (subvol, loc, &fd, pid);
- if (ret)
- goto out;
+ if (ret > 0) {
+ /* If the entries are only '.', and '..' then ret
+ * value will be non-zero. so set it to zero here. */
+ ret = 0;
+ }
- INIT_LIST_HEAD (&entries.list);
+ tmp = 0;
- while ((ret = syncop_readdirp (subvol, fd, 131072, offset, &entries,
- NULL, NULL))) {
- if (ret < 0)
- break;
+ list_for_each_entry(entry, &entries.list, list)
+ {
+ offset = entry->d_off;
- if (ret > 0) {
- /* If the entries are only '.', and '..' then ret
- * value will be non-zero. so set it to zero here. */
- ret = 0;
- }
+ if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
+ continue;
+ if (++tmp >= count) {
tmp = 0;
+ sleep(sleep_time);
+ }
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
-
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
-
- if (++tmp >= count) {
- tmp = 0;
- sleep (sleep_time);
- }
-
- gf_link_inode_from_dirent (NULL, fd->inode, entry);
-
- ret = fn (subvol, entry, loc, data);
- if (ret)
- continue;
-
- if (entry->d_stat.ia_type == IA_IFDIR) {
- child_loc.inode = inode_ref (entry->inode);
- gf_uuid_copy (child_loc.gfid, entry->inode->gfid);
- ret = syncop_ftw_throttle (subvol, &child_loc,
- pid, data, fn, count,
- sleep_time);
- loc_wipe (&child_loc);
- if (ret)
- continue;
- }
- }
+ gf_link_inode_from_dirent(NULL, fd->inode, entry);
+
+ ret = fn(subvol, entry, loc, data);
+ if (ret)
+ continue;
- gf_dirent_free (&entries);
+ if (entry->d_stat.ia_type == IA_IFDIR) {
+ child_loc.inode = inode_ref(entry->inode);
+ gf_uuid_copy(child_loc.gfid, entry->inode->gfid);
+ ret = syncop_ftw_throttle(subvol, &child_loc, pid, data, fn,
+ count, sleep_time);
+ loc_wipe(&child_loc);
if (ret)
- break;
+ continue;
+ }
}
+ gf_dirent_free(&entries);
+ if (ret)
+ break;
+ }
+
out:
- if (fd)
- fd_unref (fd);
- return ret;
+ if (fd)
+ fd_unref(fd);
+ return ret;
+}
+
+static void
+_scan_data_destroy(struct syncop_dir_scan_data *data)
+{
+ GF_FREE(data);
+}
+
+static int
+_dir_scan_job_fn_cbk(int ret, call_frame_t *frame, void *opaque)
+{
+ struct syncop_dir_scan_data *scan_data = opaque;
+
+ _scan_data_destroy(scan_data);
+ return 0;
+}
+
+static int
+_dir_scan_job_fn(void *data)
+{
+ struct syncop_dir_scan_data *scan_data = data;
+ gf_dirent_t *entry = NULL;
+ int ret = 0;
+
+ entry = scan_data->entry;
+ scan_data->entry = NULL;
+ do {
+ ret = scan_data->fn(scan_data->subvol, entry, scan_data->parent,
+ scan_data->data);
+ gf_dirent_entry_free(entry);
+ entry = NULL;
+ pthread_mutex_lock(scan_data->mut);
+ {
+ if (ret)
+ *scan_data->retval |= ret;
+ if (list_empty(&scan_data->q->list)) {
+ (*scan_data->jobs_running)--;
+ pthread_cond_broadcast(scan_data->cond);
+ } else {
+ entry = list_first_entry(&scan_data->q->list,
+ typeof(*scan_data->q), list);
+ list_del_init(&entry->list);
+ (*scan_data->qlen)--;
+ }
+ }
+ pthread_mutex_unlock(scan_data->mut);
+ } while (entry);
+
+ return ret;
+}
+
+static int
+_run_dir_scan_task(call_frame_t *frame, xlator_t *subvol, loc_t *parent,
+ gf_dirent_t *q, gf_dirent_t *entry, int *retval,
+ pthread_mutex_t *mut, pthread_cond_t *cond,
+ uint32_t *jobs_running, uint32_t *qlen,
+ syncop_dir_scan_fn_t fn, void *data)
+{
+ int ret = 0;
+ struct syncop_dir_scan_data *scan_data = NULL;
+
+ scan_data = GF_CALLOC(1, sizeof(struct syncop_dir_scan_data),
+ gf_common_mt_scan_data);
+ if (!scan_data) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ scan_data->subvol = subvol;
+ scan_data->parent = parent;
+ scan_data->data = data;
+ scan_data->mut = mut;
+ scan_data->cond = cond;
+ scan_data->fn = fn;
+ scan_data->jobs_running = jobs_running;
+ scan_data->entry = entry;
+ scan_data->q = q;
+ scan_data->qlen = qlen;
+ scan_data->retval = retval;
+
+ ret = synctask_new(subvol->ctx->env, _dir_scan_job_fn, _dir_scan_job_fn_cbk,
+ frame, scan_data);
+out:
+ if (ret < 0) {
+ gf_dirent_entry_free(entry);
+ _scan_data_destroy(scan_data);
+ pthread_mutex_lock(mut);
+ {
+ *jobs_running = *jobs_running - 1;
+ }
+ pthread_mutex_unlock(mut);
+ /*No need to cond-broadcast*/
+ }
+ return ret;
}
int
-syncop_dir_scan (xlator_t *subvol, loc_t *loc, int pid, void *data,
- int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
- void *data))
+syncop_mt_dir_scan(call_frame_t *frame, xlator_t *subvol, loc_t *loc, int pid,
+ void *data, syncop_dir_scan_fn_t fn, dict_t *xdata,
+ uint32_t max_jobs, uint32_t max_qlen)
{
- fd_t *fd = NULL;
- uint64_t offset = 0;
- gf_dirent_t *entry = NULL;
- int ret = 0;
- gf_dirent_t entries;
+ fd_t *fd = NULL;
+ uint64_t offset = 0;
+ gf_dirent_t *last = NULL;
+ int ret = 0;
+ int retval = 0;
+ gf_dirent_t q;
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+ uint32_t jobs_running = 0;
+ uint32_t qlen = 0;
+ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+ pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
+ gf_dirent_t entries;
+ xlator_t *this = NULL;
+
+ if (frame) {
+ this = frame->this;
+ } else {
+ this = THIS;
+ }
+
+ /*For this functionality to be implemented in general, we need
+ * synccond_t infra which doesn't block the executing thread. Until then
+ * return failures inside synctask if they use this.*/
+ if (synctask_get())
+ return -ENOTSUP;
+
+ if (max_jobs == 0)
+ return -EINVAL;
+
+ /*Code becomes simpler this way. cond_wait just on qlength.
+ * Little bit of cheating*/
+ if (max_qlen == 0)
+ max_qlen = 1;
+
+ ret = syncop_dirfd(subvol, loc, &fd, pid);
+ if (ret)
+ goto out;
+
+ INIT_LIST_HEAD(&entries.list);
+ INIT_LIST_HEAD(&q.list);
+
+ while ((ret = syncop_readdir(subvol, fd, 131072, offset, &entries, xdata,
+ NULL))) {
+ if (ret < 0)
+ break;
- ret = syncop_dirfd (subvol, loc, &fd, pid);
- if (ret)
- goto out;
+ if (ret > 0) {
+ /* If the entries are only '.', and '..' then ret
+ * value will be non-zero. so set it to zero here. */
+ ret = 0;
+ }
- INIT_LIST_HEAD (&entries.list);
+ last = list_last_entry(&entries.list, typeof(*last), list);
+ offset = last->d_off;
- while ((ret = syncop_readdir (subvol, fd, 131072, offset, &entries,
- NULL, NULL))) {
- if (ret < 0)
- break;
+ list_for_each_entry_safe(entry, tmp, &entries.list, list)
+ {
+ if (this && this->cleanup_starting)
+ goto out;
- if (ret > 0) {
- /* If the entries are only '.', and '..' then ret
- * value will be non-zero. so set it to zero here. */
- ret = 0;
- }
+ list_del_init(&entry->list);
+ if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
+ gf_dirent_entry_free(entry);
+ continue;
+ }
- list_for_each_entry (entry, &entries.list, list) {
- offset = entry->d_off;
+ if (entry->d_stat.ia_type == IA_IFDIR) {
+ ret = fn(subvol, entry, loc, data);
+ gf_dirent_entry_free(entry);
+ if (ret)
+ goto out;
+ continue;
+ }
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
+ if (retval) /*Any jobs failed?*/
+ goto out;
- ret = fn (subvol, entry, loc, data);
- if (ret)
- break;
+ pthread_mutex_lock(&mut);
+ {
+ while (qlen == max_qlen)
+ pthread_cond_wait(&cond, &mut);
+ if (max_jobs == jobs_running) {
+ list_add_tail(&entry->list, &q.list);
+ qlen++;
+ entry = NULL;
+ } else {
+ jobs_running++;
}
- gf_dirent_free (&entries);
- if (ret)
- break;
+ }
+ pthread_mutex_unlock(&mut);
+
+ if (!entry)
+ continue;
+
+ ret = _run_dir_scan_task(frame, subvol, loc, &q, entry, &retval,
+ &mut, &cond, &jobs_running, &qlen, fn,
+ data);
+ if (ret)
+ goto out;
}
+ }
out:
- if (fd)
- fd_unref (fd);
- return ret;
+ if (fd)
+ fd_unref(fd);
+
+ pthread_mutex_lock(&mut);
+ {
+ while (jobs_running)
+ pthread_cond_wait(&cond, &mut);
+ }
+ pthread_mutex_unlock(&mut);
+
+ gf_dirent_free(&q);
+ gf_dirent_free(&entries);
+
+ return ret | retval;
}
int
-syncop_is_subvol_local (xlator_t *this, loc_t *loc, gf_boolean_t *is_local)
+syncop_dir_scan(xlator_t *subvol, loc_t *loc, int pid, void *data,
+ int (*fn)(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
+ void *data))
{
- char *pathinfo = NULL;
- dict_t *xattr = NULL;
- int ret = 0;
+ fd_t *fd = NULL;
+ uint64_t offset = 0;
+ gf_dirent_t *entry = NULL;
+ int ret = 0;
+ gf_dirent_t entries;
- if (!this || !this->type || !is_local)
- return -EINVAL;
+ ret = syncop_dirfd(subvol, loc, &fd, pid);
+ if (ret)
+ goto out;
- if (strcmp (this->type, "protocol/client") != 0)
- return -EINVAL;
+ INIT_LIST_HEAD(&entries.list);
- *is_local = _gf_false;
+ while ((ret = syncop_readdir(subvol, fd, 131072, offset, &entries, NULL,
+ NULL))) {
+ if (ret < 0)
+ break;
- ret = syncop_getxattr (this, loc, &xattr, GF_XATTR_PATHINFO_KEY, NULL,
- NULL);
- if (ret < 0) {
- ret = -1;
- goto out;
+ if (ret > 0) {
+ /* If the entries are only '.', and '..' then ret
+ * value will be non-zero. so set it to zero here. */
+ ret = 0;
}
- if (!xattr) {
- ret = -EINVAL;
- goto out;
- }
-
- ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &pathinfo);
- if (ret)
- goto out;
+ list_for_each_entry(entry, &entries.list, list)
+ {
+ offset = entry->d_off;
- ret = glusterfs_is_local_pathinfo (pathinfo, is_local);
+ if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
+ continue;
- gf_msg_debug (this->name, 0, "subvol %s is %slocal",
- this->name, is_local ? "" : "not ");
+ ret = fn(subvol, entry, loc, data);
+ if (ret)
+ break;
+ }
+ gf_dirent_free(&entries);
+ if (ret)
+ break;
+ }
out:
- if (xattr)
- dict_unref (xattr);
-
- return ret;
+ if (fd)
+ fd_unref(fd);
+ return ret;
}
int
-syncop_gfid_to_path (inode_table_t *itable, xlator_t *subvol, uuid_t gfid,
- char **path_p)
+syncop_is_subvol_local(xlator_t *this, loc_t *loc, gf_boolean_t *is_local)
{
- int ret = 0;
- char *path = NULL;
- loc_t loc = {0,};
- dict_t *xattr = NULL;
+ char *pathinfo = NULL;
+ dict_t *xattr = NULL;
+ int ret = 0;
- gf_uuid_copy (loc.gfid, gfid);
- loc.inode = inode_new (itable);
+ if (!this || !this->type || !is_local)
+ return -EINVAL;
- ret = syncop_getxattr (subvol, &loc, &xattr, GFID_TO_PATH_KEY, NULL,
- NULL);
- if (ret < 0)
- goto out;
+ if (strcmp(this->type, "protocol/client") != 0)
+ return -EINVAL;
- ret = dict_get_str (xattr, GFID_TO_PATH_KEY, &path);
- if (ret || !path) {
- ret = -EINVAL;
- goto out;
- }
+ *is_local = _gf_false;
- if (path_p) {
- *path_p = gf_strdup (path);
- if (!*path_p) {
- ret = -ENOMEM;
- goto out;
- }
+ ret = syncop_getxattr(this, loc, &xattr, GF_XATTR_PATHINFO_KEY, NULL, NULL);
+ if (ret < 0) {
+ ret = -1;
+ goto out;
+ }
+
+ if (!xattr) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = dict_get_str(xattr, GF_XATTR_PATHINFO_KEY, &pathinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterfs_is_local_pathinfo(pathinfo, is_local);
+
+ gf_msg_debug(this->name, 0, "subvol %s is %slocal", this->name,
+ *is_local ? "" : "not ");
+
+out:
+ if (xattr)
+ dict_unref(xattr);
+
+ return ret;
+}
+
+/**
+ * For hard resove, it it telling posix to make use of the
+ * gfid2path extended attribute stored on disk. Otherwise
+ * posix xlator (with GFID_TO_PATH_KEY as the key) will just
+ * do a in memory inode_path to get the path. Depending upon
+ * the consumer of this function, they can choose how they want
+ * to proceed. If doing a xattr operation sounds costly, then
+ * use GFID_TO_PATH_KEY as the key for getxattr.
+ **/
+
+int
+syncop_gfid_to_path_hard(inode_table_t *itable, xlator_t *subvol, uuid_t gfid,
+ inode_t *inode, char **path_p,
+ gf_boolean_t hard_resolve)
+{
+ int ret = 0;
+ char *path = NULL;
+ loc_t loc = {
+ 0,
+ };
+ dict_t *xattr = NULL;
+
+ gf_uuid_copy(loc.gfid, gfid);
+
+ if (!inode)
+ loc.inode = inode_new(itable);
+ else
+ loc.inode = inode_ref(inode);
+
+ if (!hard_resolve)
+ ret = syncop_getxattr(subvol, &loc, &xattr, GFID_TO_PATH_KEY, NULL,
+ NULL);
+ else
+ ret = syncop_getxattr(subvol, &loc, &xattr, GFID2PATH_VIRT_XATTR_KEY,
+ NULL, NULL);
+
+ if (ret < 0)
+ goto out;
+
+ /*
+ * posix will do dict_set_dynstr for GFID_TO_PATH_KEY i.e.
+ * for in memory search for the path. And for on disk xattr
+ * fetching of the path for the key GFID2PATH_VIRT_XATTR_KEY
+ * it uses dict_set_dynptr. So, for GFID2PATH_VIRT_XATTR_KEY
+ * use dict_get_ptr to avoid dict complaining about type
+ * mismatch (i.e. str vs ptr)
+ */
+ if (!hard_resolve)
+ ret = dict_get_str(xattr, GFID_TO_PATH_KEY, &path);
+ else
+ ret = dict_get_ptr(xattr, GFID2PATH_VIRT_XATTR_KEY, (void **)&path);
+
+ if (ret || !path) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (path_p) {
+ *path_p = gf_strdup(path);
+ if (!*path_p) {
+ ret = -ENOMEM;
+ goto out;
}
+ }
- ret = 0;
+ ret = 0;
out:
- if (xattr)
- dict_unref (xattr);
- loc_wipe (&loc);
+ if (xattr)
+ dict_unref(xattr);
+ loc_wipe(&loc);
+
+ return ret;
+}
+
+int
+syncop_gfid_to_path(inode_table_t *itable, xlator_t *subvol, uuid_t gfid,
+ char **path_p)
+{
+ return syncop_gfid_to_path_hard(itable, subvol, gfid, NULL, path_p,
+ _gf_false);
+}
- return ret;
+int
+syncop_inode_find(xlator_t *this, xlator_t *subvol, uuid_t gfid,
+ inode_t **inode, dict_t *xdata, dict_t **rsp_dict)
+{
+ int ret = 0;
+ loc_t loc = {
+ 0,
+ };
+ struct iatt iatt = {
+ 0,
+ };
+ *inode = NULL;
+
+ *inode = inode_find(this->itable, gfid);
+ if (*inode)
+ goto out;
+
+ loc.inode = inode_new(this->itable);
+ if (!loc.inode) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ gf_uuid_copy(loc.gfid, gfid);
+
+ ret = syncop_lookup(subvol, &loc, &iatt, NULL, xdata, rsp_dict);
+ if (ret < 0)
+ goto out;
+
+ *inode = inode_link(loc.inode, NULL, NULL, &iatt);
+ if (!*inode) {
+ ret = -ENOMEM;
+ goto out;
+ }
+out:
+ loc_wipe(&loc);
+ return ret;
}
diff --git a/libglusterfs/src/syncop-utils.h b/libglusterfs/src/syncop-utils.h
deleted file mode 100644
index 7a9ccacb285..00000000000
--- a/libglusterfs/src/syncop-utils.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- Copyright (c) 2015, 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 _SYNCOP_UTILS_H
-#define _SYNCOP_UTILS_H
-
-int
-syncop_ftw (xlator_t *subvol, loc_t *loc, int pid, void *data,
- int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
- void *data));
-
-int
-syncop_dir_scan (xlator_t *subvol, loc_t *loc, int pid, void *data,
- int (*fn) (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
- void *data));
-
-int
-syncop_dirfd (xlator_t *subvol, loc_t *loc, fd_t **fd, int pid);
-
-int
-syncop_is_subvol_local (xlator_t *this, loc_t *loc, gf_boolean_t *is_local);
-
-int
-syncop_gfid_to_path (inode_table_t *itable, xlator_t *subvol, uuid_t gfid,
- char **path_p);
-
-int
-syncop_ftw_throttle (xlator_t *subvol, loc_t *loc, int pid, void *data,
- int (*fn) (xlator_t *subvol, gf_dirent_t *entry,
- loc_t *parent, void *data),
- int count, int sleep_time);
-#endif /* _SYNCOP_H */
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index 7c0ec7799e7..df20cec559f 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -8,2638 +8,2855 @@
cases as published by the Free Software Foundation.
*/
-#include "syncop.h"
-#include "libglusterfs-messages.h"
+#include "glusterfs/syncop.h"
+#include "glusterfs/libglusterfs-messages.h"
+
+#ifdef HAVE_TSAN_API
+#include <sanitizer/tsan_interface.h>
+#endif
int
-syncopctx_setfsuid (void *uid)
+syncopctx_setfsuid(void *uid)
{
- struct syncopctx *opctx = NULL;
- int ret = 0;
-
- /* In args check */
- if (!uid) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
+ struct syncopctx *opctx = NULL;
+ int ret = 0;
- opctx = syncopctx_getctx ();
+ /* In args check */
+ if (!uid) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
- /* alloc for this thread the first time */
- if (!opctx) {
- opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
- if (!opctx) {
- ret = -1;
- goto out;
- }
+ opctx = syncopctx_getctx();
- ret = syncopctx_setctx (opctx);
- if (ret != 0) {
- GF_FREE (opctx);
- opctx = NULL;
- goto out;
- }
- }
+ opctx->uid = *(uid_t *)uid;
+ opctx->valid |= SYNCOPCTX_UID;
out:
- if (opctx && uid) {
- opctx->uid = *(uid_t *)uid;
- opctx->valid |= SYNCOPCTX_UID;
- }
+ return ret;
+}
+
+int
+syncopctx_setfsgid(void *gid)
+{
+ struct syncopctx *opctx = NULL;
+ int ret = 0;
+
+ /* In args check */
+ if (!gid) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ opctx = syncopctx_getctx();
+
+ opctx->gid = *(gid_t *)gid;
+ opctx->valid |= SYNCOPCTX_GID;
- return ret;
+out:
+ return ret;
}
int
-syncopctx_setfsgid (void *gid)
+syncopctx_setfsgroups(int count, const void *groups)
{
- struct syncopctx *opctx = NULL;
- int ret = 0;
+ struct syncopctx *opctx = NULL;
+ gid_t *tmpgroups = NULL;
+ int ret = 0;
- /* In args check */
- if (!gid) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
+ /* In args check */
+ if (count != 0 && !groups) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
- opctx = syncopctx_getctx ();
+ opctx = syncopctx_getctx();
- /* alloc for this thread the first time */
- if (!opctx) {
- opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
- if (!opctx) {
- ret = -1;
- goto out;
- }
+ /* resize internal groups as required */
+ if (count && opctx->grpsize < count) {
+ if (opctx->groups) {
+ /* Group list will be updated later, so no need to keep current
+ * data and waste time copying it. It's better to free the current
+ * allocation and then allocate a fresh new memory block. */
+ GF_FREE(opctx->groups);
+ opctx->groups = NULL;
+ opctx->grpsize = 0;
+ }
+ tmpgroups = GF_MALLOC(count * sizeof(gid_t), gf_common_mt_syncopctx);
+ if (tmpgroups == NULL) {
+ ret = -1;
+ goto out;
+ }
- ret = syncopctx_setctx (opctx);
- if (ret != 0) {
- GF_FREE (opctx);
- opctx = NULL;
- goto out;
- }
- }
+ opctx->groups = tmpgroups;
+ opctx->grpsize = count;
+ }
-out:
- if (opctx && gid) {
- opctx->gid = *(gid_t *)gid;
- opctx->valid |= SYNCOPCTX_GID;
- }
-
- return ret;
-}
-
-int
-syncopctx_setfsgroups (int count, const void *groups)
-{
- struct syncopctx *opctx = NULL;
- gid_t *tmpgroups = NULL;
- int ret = 0;
-
- /* In args check */
- if (count != 0 && !groups) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
-
- opctx = syncopctx_getctx ();
-
- /* alloc for this thread the first time */
- if (!opctx) {
- opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
- if (!opctx) {
- ret = -1;
- goto out;
- }
-
- ret = syncopctx_setctx (opctx);
- if (ret != 0) {
- GF_FREE (opctx);
- opctx = NULL;
- goto out;
- }
- }
-
- /* resize internal groups as required */
- if (count && opctx->grpsize < count) {
- if (opctx->groups) {
- tmpgroups = GF_REALLOC (opctx->groups,
- (sizeof (gid_t) * count));
- /* NOTE: Not really required to zero the reallocation,
- * as ngrps controls the validity of data,
- * making a note irrespective */
- if (tmpgroups == NULL) {
- opctx->grpsize = 0;
- GF_FREE (opctx->groups);
- opctx->groups = NULL;
- ret = -1;
- goto out;
- }
- }
- else {
- tmpgroups = GF_CALLOC (count, sizeof (gid_t),
- gf_common_mt_syncopctx);
- if (tmpgroups == NULL) {
- opctx->grpsize = 0;
- ret = -1;
- goto out;
- }
- }
-
- opctx->groups = tmpgroups;
- opctx->grpsize = count;
- }
-
- /* copy out the groups passed */
- if (count)
- memcpy (opctx->groups, groups, (sizeof (gid_t) * count));
-
- /* set/reset the ngrps, this is where reset of groups is handled */
- opctx->ngrps = count;
- opctx->valid |= SYNCOPCTX_GROUPS;
+ /* copy out the groups passed */
+ if (count)
+ memcpy(opctx->groups, groups, (sizeof(gid_t) * count));
+
+ /* set/reset the ngrps, this is where reset of groups is handled */
+ opctx->ngrps = count;
+
+ if ((opctx->valid & SYNCOPCTX_GROUPS) == 0) {
+ /* This is the first time we are storing groups into the TLS structure
+ * so we mark the current thread so that it will be properly cleaned
+ * up when the thread terminates. */
+ gf_thread_needs_cleanup();
+ }
+ opctx->valid |= SYNCOPCTX_GROUPS;
out:
- return ret;
+ return ret;
}
int
-syncopctx_setfspid (void *pid)
+syncopctx_setfspid(void *pid)
{
- struct syncopctx *opctx = NULL;
- int ret = 0;
-
- /* In args check */
- if (!pid) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
+ struct syncopctx *opctx = NULL;
+ int ret = 0;
- opctx = syncopctx_getctx ();
+ /* In args check */
+ if (!pid) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
- /* alloc for this thread the first time */
- if (!opctx) {
- opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
- if (!opctx) {
- ret = -1;
- goto out;
- }
+ opctx = syncopctx_getctx();
- ret = syncopctx_setctx (opctx);
- if (ret != 0) {
- GF_FREE (opctx);
- opctx = NULL;
- goto out;
- }
- }
+ opctx->pid = *(pid_t *)pid;
+ opctx->valid |= SYNCOPCTX_PID;
out:
- if (opctx && pid) {
- opctx->pid = *(pid_t *)pid;
- opctx->valid |= SYNCOPCTX_PID;
- }
-
- return ret;
+ return ret;
}
int
-syncopctx_setfslkowner (gf_lkowner_t *lk_owner)
+syncopctx_setfslkowner(gf_lkowner_t *lk_owner)
{
- struct syncopctx *opctx = NULL;
- int ret = 0;
-
- /* In args check */
- if (!lk_owner) {
- ret = -1;
- errno = EINVAL;
- goto out;
- }
+ struct syncopctx *opctx = NULL;
+ int ret = 0;
- opctx = syncopctx_getctx ();
+ /* In args check */
+ if (!lk_owner) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
- /* alloc for this thread the first time */
- if (!opctx) {
- opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx);
- if (!opctx) {
- ret = -1;
- goto out;
- }
+ opctx = syncopctx_getctx();
- ret = syncopctx_setctx (opctx);
- if (ret != 0) {
- GF_FREE (opctx);
- opctx = NULL;
- goto out;
- }
- }
+ opctx->lk_owner = *lk_owner;
+ opctx->valid |= SYNCOPCTX_LKOWNER;
out:
- if (opctx && lk_owner) {
- opctx->lk_owner = *lk_owner;
- opctx->valid |= SYNCOPCTX_LKOWNER;
- }
-
- return ret;
+ return ret;
}
+void *
+syncenv_processor(void *thdata);
+
static void
-__run (struct synctask *task)
+__run(struct synctask *task)
{
- struct syncenv *env = NULL;
+ struct syncenv *env = NULL;
+ int32_t total, ret, i;
- env = task->env;
+ env = task->env;
- list_del_init (&task->all_tasks);
- switch (task->state) {
+ list_del_init(&task->all_tasks);
+ switch (task->state) {
case SYNCTASK_INIT:
case SYNCTASK_SUSPEND:
- break;
+ break;
case SYNCTASK_RUN:
- gf_msg_debug (task->xl->name, 0, "re-running already running"
- " task");
- env->runcount--;
- break;
+ gf_msg_debug(task->xl->name, 0,
+ "re-running already running"
+ " task");
+ env->runcount--;
+ break;
case SYNCTASK_WAIT:
- env->waitcount--;
- break;
+ break;
case SYNCTASK_DONE:
- gf_msg (task->xl->name, GF_LOG_WARNING, 0,
- LG_MSG_COMPLETED_TASK, "running completed task");
- return;
- case SYNCTASK_ZOMBIE:
- gf_msg (task->xl->name, GF_LOG_WARNING, 0,
- LG_MSG_WAKE_UP_ZOMBIE, "attempted to wake up "
- "zombie!!");
- return;
+ gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_COMPLETED_TASK,
+ "running completed task");
+ return;
+ case SYNCTASK_ZOMBIE:
+ gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_WAKE_UP_ZOMBIE,
+ "attempted to wake up "
+ "zombie!!");
+ return;
+ }
+
+ list_add_tail(&task->all_tasks, &env->runq);
+ task->state = SYNCTASK_RUN;
+
+ env->runcount++;
+
+ total = env->procs + env->runcount - env->procs_idle;
+ if (total > env->procmax) {
+ total = env->procmax;
+ }
+ if (total > env->procs) {
+ for (i = 0; i < env->procmax; i++) {
+ if (env->proc[i].env == NULL) {
+ env->proc[i].env = env;
+ ret = gf_thread_create(&env->proc[i].processor, NULL,
+ syncenv_processor, &env->proc[i],
+ "sproc%d", i);
+ if ((ret < 0) || (++env->procs >= total)) {
+ break;
+ }
+ }
}
-
- list_add_tail (&task->all_tasks, &env->runq);
- env->runcount++;
- task->state = SYNCTASK_RUN;
+ }
}
-
static void
-__wait (struct synctask *task)
+__wait(struct synctask *task)
{
- struct syncenv *env = NULL;
+ struct syncenv *env = NULL;
- env = task->env;
+ env = task->env;
- list_del_init (&task->all_tasks);
- switch (task->state) {
+ list_del_init(&task->all_tasks);
+ switch (task->state) {
case SYNCTASK_INIT:
case SYNCTASK_SUSPEND:
- break;
+ break;
case SYNCTASK_RUN:
- env->runcount--;
- break;
+ env->runcount--;
+ break;
case SYNCTASK_WAIT:
- gf_msg (task->xl->name, GF_LOG_WARNING, 0,
- LG_MSG_REWAITING_TASK, "re-waiting already waiting "
- "task");
- env->waitcount--;
- break;
+ gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_REWAITING_TASK,
+ "re-waiting already waiting "
+ "task");
+ break;
case SYNCTASK_DONE:
- gf_msg (task->xl->name, GF_LOG_WARNING, 0,
- LG_MSG_COMPLETED_TASK,
- "running completed task");
- return;
- case SYNCTASK_ZOMBIE:
- gf_msg (task->xl->name, GF_LOG_WARNING, 0,
- LG_MSG_SLEEP_ZOMBIE,
- "attempted to sleep a zombie!!");
- return;
- }
+ gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_COMPLETED_TASK,
+ "running completed task");
+ return;
+ case SYNCTASK_ZOMBIE:
+ gf_msg(task->xl->name, GF_LOG_WARNING, 0, LG_MSG_SLEEP_ZOMBIE,
+ "attempted to sleep a zombie!!");
+ return;
+ }
- list_add_tail (&task->all_tasks, &env->waitq);
- env->waitcount++;
- task->state = SYNCTASK_WAIT;
+ list_add_tail(&task->all_tasks, &env->waitq);
+ task->state = SYNCTASK_WAIT;
}
-
void
-synctask_yield (struct synctask *task)
+synctask_yield(struct synctask *task, struct timespec *delta)
{
- xlator_t *oldTHIS = THIS;
+ xlator_t *oldTHIS = THIS;
#if defined(__NetBSD__) && defined(_UC_TLSBASE)
- /* Preserve pthread private pointer through swapcontex() */
- task->proc->sched.uc_flags &= ~_UC_TLSBASE;
+ /* Preserve pthread private pointer through swapcontex() */
+ task->proc->sched.uc_flags &= ~_UC_TLSBASE;
#endif
- if (task->state != SYNCTASK_DONE) {
- task->state = SYNCTASK_SUSPEND;
- (void) gf_backtrace_save (task->btbuf);
- }
- if (swapcontext (&task->ctx, &task->proc->sched) < 0) {
- gf_msg ("syncop", GF_LOG_ERROR, errno,
- LG_MSG_SWAPCONTEXT_FAILED, "swapcontext failed");
- }
+ task->delta = delta;
- THIS = oldTHIS;
-}
+ if (task->state != SYNCTASK_DONE) {
+ task->state = SYNCTASK_SUSPEND;
+ }
+
+#ifdef HAVE_TSAN_API
+ __tsan_switch_to_fiber(task->proc->tsan.fiber, 0);
+#endif
+ if (swapcontext(&task->ctx, &task->proc->sched) < 0) {
+ gf_msg("syncop", GF_LOG_ERROR, errno, LG_MSG_SWAPCONTEXT_FAILED,
+ "swapcontext failed");
+ }
+
+ THIS = oldTHIS;
+}
void
-synctask_wake (struct synctask *task)
+synctask_sleep(int32_t secs)
{
- struct syncenv *env = NULL;
+ struct timespec delta;
+ struct synctask *task;
- env = task->env;
+ task = synctask_get();
- pthread_mutex_lock (&env->mutex);
- {
- task->woken = 1;
+ if (task == NULL) {
+ sleep(secs);
+ } else {
+ delta.tv_sec = secs;
+ delta.tv_nsec = 0;
- if (task->slept)
- __run (task);
+ synctask_yield(task, &delta);
+ }
+}
- pthread_cond_broadcast (&env->cond);
- }
- pthread_mutex_unlock (&env->mutex);
+static void
+__synctask_wake(struct synctask *task)
+{
+ task->woken = 1;
+
+ if (task->slept)
+ __run(task);
+
+ pthread_cond_broadcast(&task->env->cond);
}
void
-synctask_wrap (struct synctask *old_task)
+synctask_wake(struct synctask *task)
{
- struct synctask *task = NULL;
+ struct syncenv *env = NULL;
- /* Do not trust the pointer received. It may be
- wrong and can lead to crashes. */
+ env = task->env;
- task = synctask_get ();
- task->ret = task->syncfn (task->opaque);
- if (task->synccbk)
- task->synccbk (task->ret, task->frame, task->opaque);
+ pthread_mutex_lock(&env->mutex);
+ {
+ if (task->timer != NULL) {
+ if (gf_timer_call_cancel(task->xl->ctx, task->timer) != 0) {
+ goto unlock;
+ }
- task->state = SYNCTASK_DONE;
+ task->timer = NULL;
+ task->synccond = NULL;
+ }
- synctask_yield (task);
+ __synctask_wake(task);
+ }
+unlock:
+ pthread_mutex_unlock(&env->mutex);
}
-
void
-synctask_destroy (struct synctask *task)
+synctask_wrap(void)
{
- if (!task)
- return;
+ struct synctask *task = NULL;
- GF_FREE (task->stack);
+ /* Do not trust the pointer received. It may be
+ wrong and can lead to crashes. */
- if (task->opframe)
- STACK_DESTROY (task->opframe->root);
+ task = synctask_get();
+ task->ret = task->syncfn(task->opaque);
+ if (task->synccbk)
+ task->synccbk(task->ret, task->frame, task->opaque);
- if (task->synccbk == NULL) {
- pthread_mutex_destroy (&task->mutex);
- pthread_cond_destroy (&task->cond);
- }
+ task->state = SYNCTASK_DONE;
- GF_FREE (task);
+ synctask_yield(task, NULL);
}
-
void
-synctask_done (struct synctask *task)
+synctask_destroy(struct synctask *task)
{
- if (task->synccbk) {
- synctask_destroy (task);
- return;
- }
+ if (!task)
+ return;
- pthread_mutex_lock (&task->mutex);
- {
- task->state = SYNCTASK_ZOMBIE;
- task->done = 1;
- pthread_cond_broadcast (&task->cond);
- }
- pthread_mutex_unlock (&task->mutex);
+ GF_FREE(task->stack);
+
+ if (task->opframe)
+ STACK_DESTROY(task->opframe->root);
+
+ if (task->synccbk == NULL) {
+ pthread_mutex_destroy(&task->mutex);
+ pthread_cond_destroy(&task->cond);
+ }
+
+#ifdef HAVE_TSAN_API
+ __tsan_destroy_fiber(task->tsan.fiber);
+#endif
+
+ GF_FREE(task);
}
+void
+synctask_done(struct synctask *task)
+{
+ if (task->synccbk) {
+ synctask_destroy(task);
+ return;
+ }
+
+ pthread_mutex_lock(&task->mutex);
+ {
+ task->state = SYNCTASK_ZOMBIE;
+ task->done = 1;
+ pthread_cond_broadcast(&task->cond);
+ }
+ pthread_mutex_unlock(&task->mutex);
+}
int
-synctask_setid (struct synctask *task, uid_t uid, gid_t gid)
+synctask_setid(struct synctask *task, uid_t uid, gid_t gid)
{
- if (!task)
- return -1;
+ if (!task)
+ return -1;
- if (uid != -1)
- task->uid = uid;
+ if (uid != -1)
+ task->uid = uid;
- if (gid != -1)
- task->gid = gid;
+ if (gid != -1)
+ task->gid = gid;
- return 0;
+ return 0;
}
-
struct synctask *
-synctask_create (struct syncenv *env, size_t stacksize, synctask_fn_t fn,
- synctask_cbk_t cbk, call_frame_t *frame, void *opaque)
+synctask_create(struct syncenv *env, size_t stacksize, synctask_fn_t fn,
+ synctask_cbk_t cbk, call_frame_t *frame, void *opaque)
{
- struct synctask *newtask = NULL;
- xlator_t *this = THIS;
- int destroymode = 0;
+ struct synctask *newtask = NULL;
+ xlator_t *this = THIS;
+ int destroymode = 0;
- VALIDATE_OR_GOTO (env, err);
- VALIDATE_OR_GOTO (fn, err);
+ VALIDATE_OR_GOTO(env, err);
+ VALIDATE_OR_GOTO(fn, err);
- /* Check if the syncenv is in destroymode i.e. destroy is SET.
- * If YES, then don't allow any new synctasks on it. Return NULL.
- */
- pthread_mutex_lock (&env->mutex);
- {
- destroymode = env->destroy;
- }
- pthread_mutex_unlock (&env->mutex);
+ /* Check if the syncenv is in destroymode i.e. destroy is SET.
+ * If YES, then don't allow any new synctasks on it. Return NULL.
+ */
+ pthread_mutex_lock(&env->mutex);
+ {
+ destroymode = env->destroy;
+ }
+ pthread_mutex_unlock(&env->mutex);
- /* syncenv is in DESTROY mode, return from here */
- if (destroymode)
- return NULL;
+ /* syncenv is in DESTROY mode, return from here */
+ if (destroymode)
+ return NULL;
- newtask = GF_CALLOC (1, sizeof (*newtask), gf_common_mt_synctask);
- if (!newtask)
- return NULL;
+ newtask = GF_CALLOC(1, sizeof(*newtask), gf_common_mt_synctask);
+ if (!newtask)
+ return NULL;
- newtask->frame = frame;
- if (!frame) {
- newtask->opframe = create_frame (this, this->ctx->pool);
- set_lk_owner_from_ptr (&newtask->opframe->root->lk_owner,
- newtask->opframe->root);
- } else {
- newtask->opframe = copy_frame (frame);
- }
+ newtask->frame = frame;
+ if (!frame) {
+ newtask->opframe = create_frame(this, this->ctx->pool);
if (!newtask->opframe)
- goto err;
- newtask->env = env;
- newtask->xl = this;
- newtask->syncfn = fn;
- newtask->synccbk = cbk;
- newtask->opaque = opaque;
-
- /* default to the uid/gid of the passed frame */
- newtask->uid = newtask->opframe->root->uid;
- newtask->gid = newtask->opframe->root->gid;
-
- INIT_LIST_HEAD (&newtask->all_tasks);
- INIT_LIST_HEAD (&newtask->waitq);
-
- if (getcontext (&newtask->ctx) < 0) {
- gf_msg ("syncop", GF_LOG_ERROR, errno,
- LG_MSG_GETCONTEXT_FAILED, "getcontext failed");
- goto err;
- }
-
- if (stacksize <= 0) {
- newtask->stack = GF_CALLOC (1, env->stacksize,
- gf_common_mt_syncstack);
- newtask->ctx.uc_stack.ss_size = env->stacksize;
- } else {
- newtask->stack = GF_CALLOC (1, stacksize,
- gf_common_mt_syncstack);
- newtask->ctx.uc_stack.ss_size = stacksize;
- }
-
- if (!newtask->stack) {
- goto err;
- }
-
- newtask->ctx.uc_stack.ss_sp = newtask->stack;
-
- makecontext (&newtask->ctx, (void (*)(void)) synctask_wrap, 2, newtask);
+ goto err;
+ set_lk_owner_from_ptr(&newtask->opframe->root->lk_owner,
+ newtask->opframe->root);
+ } else {
+ newtask->opframe = copy_frame(frame);
+ }
+ if (!newtask->opframe)
+ goto err;
+ newtask->env = env;
+ newtask->xl = this;
+ newtask->syncfn = fn;
+ newtask->synccbk = cbk;
+ newtask->opaque = opaque;
+
+ /* default to the uid/gid of the passed frame */
+ newtask->uid = newtask->opframe->root->uid;
+ newtask->gid = newtask->opframe->root->gid;
+
+ INIT_LIST_HEAD(&newtask->all_tasks);
+ INIT_LIST_HEAD(&newtask->waitq);
+
+ if (getcontext(&newtask->ctx) < 0) {
+ gf_msg("syncop", GF_LOG_ERROR, errno, LG_MSG_GETCONTEXT_FAILED,
+ "getcontext failed");
+ goto err;
+ }
+
+ if (stacksize <= 0) {
+ newtask->stack = GF_CALLOC(1, env->stacksize, gf_common_mt_syncstack);
+ newtask->ctx.uc_stack.ss_size = env->stacksize;
+ } else {
+ newtask->stack = GF_CALLOC(1, stacksize, gf_common_mt_syncstack);
+ newtask->ctx.uc_stack.ss_size = stacksize;
+ }
+
+ if (!newtask->stack) {
+ goto err;
+ }
+
+ newtask->ctx.uc_stack.ss_sp = newtask->stack;
+
+ makecontext(&newtask->ctx, (void (*)(void))synctask_wrap, 0);
+
+#ifdef HAVE_TSAN_API
+ newtask->tsan.fiber = __tsan_create_fiber(0);
+ snprintf(newtask->tsan.name, TSAN_THREAD_NAMELEN, "<synctask of %s>",
+ this->name);
+ __tsan_set_fiber_name(newtask->tsan.fiber, newtask->tsan.name);
+#endif
- newtask->state = SYNCTASK_INIT;
+ newtask->state = SYNCTASK_INIT;
- newtask->slept = 1;
+ newtask->slept = 1;
- if (!cbk) {
- pthread_mutex_init (&newtask->mutex, NULL);
- pthread_cond_init (&newtask->cond, NULL);
- newtask->done = 0;
- }
+ if (!cbk) {
+ pthread_mutex_init(&newtask->mutex, NULL);
+ pthread_cond_init(&newtask->cond, NULL);
+ newtask->done = 0;
+ }
- synctask_wake (newtask);
- /*
- * Make sure someone's there to execute anything we just put on the
- * run queue.
- */
- syncenv_scale(env);
+ synctask_wake(newtask);
- return newtask;
+ return newtask;
err:
- if (newtask) {
- GF_FREE (newtask->stack);
- if (newtask->opframe)
- STACK_DESTROY (newtask->opframe->root);
- GF_FREE (newtask);
- }
+ if (newtask) {
+ GF_FREE(newtask->stack);
+ if (newtask->opframe)
+ STACK_DESTROY(newtask->opframe->root);
+ GF_FREE(newtask);
+ }
- return NULL;
+ return NULL;
}
-
int
-synctask_join (struct synctask *task)
+synctask_join(struct synctask *task)
{
- int ret = 0;
+ int ret = 0;
- pthread_mutex_lock (&task->mutex);
- {
- while (!task->done)
- pthread_cond_wait (&task->cond, &task->mutex);
- }
- pthread_mutex_unlock (&task->mutex);
+ pthread_mutex_lock(&task->mutex);
+ {
+ while (!task->done)
+ pthread_cond_wait(&task->cond, &task->mutex);
+ }
+ pthread_mutex_unlock(&task->mutex);
- ret = task->ret;
+ ret = task->ret;
- synctask_destroy (task);
+ synctask_destroy(task);
- return ret;
+ return ret;
}
-
int
-synctask_new1 (struct syncenv *env, size_t stacksize, synctask_fn_t fn,
- synctask_cbk_t cbk, call_frame_t *frame, void *opaque)
+synctask_new1(struct syncenv *env, size_t stacksize, synctask_fn_t fn,
+ synctask_cbk_t cbk, call_frame_t *frame, void *opaque)
{
- struct synctask *newtask = NULL;
- int ret = 0;
+ struct synctask *newtask = NULL;
+ int ret = 0;
- newtask = synctask_create (env, stacksize, fn, cbk, frame, opaque);
- if (!newtask)
- return -1;
+ newtask = synctask_create(env, stacksize, fn, cbk, frame, opaque);
+ if (!newtask)
+ return -1;
- if (!cbk)
- ret = synctask_join (newtask);
+ if (!cbk)
+ ret = synctask_join(newtask);
- return ret;
+ return ret;
}
-
int
-synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
- call_frame_t *frame, void *opaque)
+synctask_new(struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
+ call_frame_t *frame, void *opaque)
{
- return synctask_new1 (env, 0, fn, cbk, frame, opaque);
+ return synctask_new1(env, 0, fn, cbk, frame, opaque);
}
struct synctask *
-syncenv_task (struct syncproc *proc)
+syncenv_task(struct syncproc *proc)
+{
+ struct syncenv *env = NULL;
+ struct synctask *task = NULL;
+ struct timespec sleep_till = {
+ 0,
+ };
+ int ret = 0;
+
+ env = proc->env;
+
+ pthread_mutex_lock(&env->mutex);
+ {
+ while (list_empty(&env->runq)) {
+ /* If either of the conditions are met then exit
+ * the current thread:
+ * 1. syncenv has to scale down(procs > procmin)
+ * 2. syncenv is in destroy mode and no tasks in
+ * either waitq or runq.
+ *
+ * At any point in time, a task can be either in runq,
+ * or in executing state or in the waitq. Once the
+ * destroy mode is set, no new synctask creates will
+ * be allowed, but whatever in waitq or runq should be
+ * allowed to finish before exiting any of the syncenv
+ * processor threads.
+ */
+ if (((ret == ETIMEDOUT) && (env->procs > env->procmin)) ||
+ (env->destroy && list_empty(&env->waitq))) {
+ task = NULL;
+ env->procs--;
+ memset(proc, 0, sizeof(*proc));
+ pthread_cond_broadcast(&env->cond);
+ goto unlock;
+ }
+
+ env->procs_idle++;
+
+ sleep_till.tv_sec = gf_time() + SYNCPROC_IDLE_TIME;
+ ret = pthread_cond_timedwait(&env->cond, &env->mutex, &sleep_till);
+
+ env->procs_idle--;
+ }
+
+ task = list_entry(env->runq.next, struct synctask, all_tasks);
+
+ list_del_init(&task->all_tasks);
+ env->runcount--;
+
+ task->woken = 0;
+ task->slept = 0;
+
+ task->proc = proc;
+ }
+unlock:
+ pthread_mutex_unlock(&env->mutex);
+
+ return task;
+}
+
+static void
+synctask_timer(void *data)
{
- struct syncenv *env = NULL;
- struct synctask *task = NULL;
- struct timespec sleep_till = {0, };
- int ret = 0;
+ struct synctask *task = data;
+ struct synccond *cond;
- env = proc->env;
+ cond = task->synccond;
+ if (cond != NULL) {
+ pthread_mutex_lock(&cond->pmutex);
- pthread_mutex_lock (&env->mutex);
- {
- while (list_empty (&env->runq)) {
- sleep_till.tv_sec = time (NULL) + SYNCPROC_IDLE_TIME;
- ret = pthread_cond_timedwait (&env->cond, &env->mutex,
- &sleep_till);
- if (!list_empty (&env->runq))
- break;
- /* If either of the conditions are met then exit
- * the current thread:
- * 1. syncenv has to scale down(procs > procmin)
- * 2. syncenv is in destroy mode and no tasks in
- * either waitq or runq.
- *
- * At any point in time, a task can be either in runq,
- * or in executing state or in the waitq. Once the
- * destroy mode is set, no new synctask creates will
- * be allowed, but whatever in waitq or runq should be
- * allowed to finish before exiting any of the syncenv
- * processor threads.
- */
- if (((ret == ETIMEDOUT) && (env->procs > env->procmin))
- || (env->destroy && list_empty (&env->waitq))) {
- task = NULL;
- env->procs--;
- memset (proc, 0, sizeof (*proc));
- pthread_cond_broadcast (&env->cond);
- goto unlock;
- }
- }
+ list_del_init(&task->waitq);
+ task->synccond = NULL;
- task = list_entry (env->runq.next, struct synctask, all_tasks);
+ pthread_mutex_unlock(&cond->pmutex);
- list_del_init (&task->all_tasks);
- env->runcount--;
+ task->ret = -ETIMEDOUT;
+ }
- task->woken = 0;
- task->slept = 0;
+ pthread_mutex_lock(&task->env->mutex);
- task->proc = proc;
- }
-unlock:
- pthread_mutex_unlock (&env->mutex);
+ gf_timer_call_cancel(task->xl->ctx, task->timer);
+ task->timer = NULL;
- return task;
-}
+ __synctask_wake(task);
+ pthread_mutex_unlock(&task->env->mutex);
+}
void
-synctask_switchto (struct synctask *task)
+synctask_switchto(struct synctask *task)
{
- struct syncenv *env = NULL;
+ struct syncenv *env = NULL;
- env = task->env;
+ env = task->env;
- synctask_set (task);
- THIS = task->xl;
+ synctask_set(task);
+ THIS = task->xl;
#if defined(__NetBSD__) && defined(_UC_TLSBASE)
- /* Preserve pthread private pointer through swapcontex() */
- task->ctx.uc_flags &= ~_UC_TLSBASE;
+ /* Preserve pthread private pointer through swapcontex() */
+ task->ctx.uc_flags &= ~_UC_TLSBASE;
#endif
- if (swapcontext (&task->proc->sched, &task->ctx) < 0) {
- gf_msg ("syncop", GF_LOG_ERROR, errno, LG_MSG_SWAPCONTEXT_FAILED,
- "swapcontext failed");
- }
+#ifdef HAVE_TSAN_API
+ __tsan_switch_to_fiber(task->tsan.fiber, 0);
+#endif
- if (task->state == SYNCTASK_DONE) {
- synctask_done (task);
- return;
- }
+ if (swapcontext(&task->proc->sched, &task->ctx) < 0) {
+ gf_msg("syncop", GF_LOG_ERROR, errno, LG_MSG_SWAPCONTEXT_FAILED,
+ "swapcontext failed");
+ }
- pthread_mutex_lock (&env->mutex);
- {
- if (task->woken) {
- __run (task);
- } else {
- task->slept = 1;
- __wait (task);
- }
+ 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);
+
+ if (task->delta != NULL) {
+ task->timer = gf_timer_call_after(task->xl->ctx, *task->delta,
+ synctask_timer, task);
+ }
}
- pthread_mutex_unlock (&env->mutex);
+
+ task->delta = NULL;
+ }
+ pthread_mutex_unlock(&env->mutex);
}
void *
-syncenv_processor (void *thdata)
+syncenv_processor(void *thdata)
{
- struct syncenv *env = NULL;
- struct syncproc *proc = NULL;
- struct synctask *task = NULL;
+ struct syncproc *proc = NULL;
+ struct synctask *task = NULL;
- proc = thdata;
- env = proc->env;
+ proc = thdata;
- for (;;) {
- task = syncenv_task (proc);
- if (!task)
- break;
+#ifdef HAVE_TSAN_API
+ proc->tsan.fiber = __tsan_create_fiber(0);
+ snprintf(proc->tsan.name, TSAN_THREAD_NAMELEN, "<sched of syncenv@%p>",
+ proc);
+ __tsan_set_fiber_name(proc->tsan.fiber, proc->tsan.name);
+#endif
- synctask_switchto (task);
+ while ((task = syncenv_task(proc)) != NULL) {
+ synctask_switchto(task);
+ }
- syncenv_scale (env);
- }
+#ifdef HAVE_TSAN_API
+ __tsan_destroy_fiber(proc->tsan.fiber);
+#endif
- return NULL;
+ return NULL;
}
-
+/* The syncenv threads are cleaned up in this routine.
+ */
void
-syncenv_scale (struct syncenv *env)
+syncenv_destroy(struct syncenv *env)
{
- int diff = 0;
- int scale = 0;
- int i = 0;
- int ret = 0;
+ if (env == NULL)
+ return;
- pthread_mutex_lock (&env->mutex);
- {
- if (env->procs > env->runcount)
- goto unlock;
-
- scale = env->runcount;
- if (scale > env->procmax)
- scale = env->procmax;
- if (scale > env->procs)
- diff = scale - env->procs;
- while (diff) {
- diff--;
- for (; (i < env->procmax); i++) {
- if (env->proc[i].processor == 0)
- break;
- }
-
- env->proc[i].env = env;
- ret = gf_thread_create (&env->proc[i].processor, NULL,
- syncenv_processor, &env->proc[i]);
- if (ret)
- break;
- env->procs++;
- i++;
- }
- }
-unlock:
- pthread_mutex_unlock (&env->mutex);
-}
+ /* SET the 'destroy' in syncenv structure to prohibit any
+ * further synctask(s) on this syncenv which is in destroy mode.
+ *
+ * If syncenv threads are in pthread cond wait with no tasks in
+ * their run or wait queue, then the threads are woken up by
+ * broadcasting the cond variable and if destroy field is set,
+ * the infinite loop in syncenv_processor is broken and the
+ * threads return.
+ *
+ * If syncenv threads have tasks in runq or waitq, the tasks are
+ * completed and only then the thread returns.
+ */
+ pthread_mutex_lock(&env->mutex);
+ {
+ env->destroy = 1;
+ /* This broadcast will wake threads in pthread_cond_wait
+ * in syncenv_task
+ */
+ pthread_cond_broadcast(&env->cond);
-/* The syncenv threads are cleaned up in this routine.
- */
-void
-syncenv_destroy (struct syncenv *env)
-{
-
- if (env == NULL)
- return;
-
- /* SET the 'destroy' in syncenv structure to prohibit any
- * further synctask(s) on this syncenv which is in destroy mode.
- *
- * If syncenv threads are in pthread cond wait with no tasks in
- * their run or wait queue, then the threads are woken up by
- * broadcasting the cond variable and if destroy field is set,
- * the infinite loop in syncenv_processor is broken and the
- * threads return.
- *
- * If syncenv threads have tasks in runq or waitq, the tasks are
- * completed and only then the thread returns.
+ /* when the syncenv_task() thread is exiting, it broadcasts to
+ * wake the below wait.
*/
- pthread_mutex_lock (&env->mutex);
- {
- env->destroy = 1;
- /* This broadcast will wake threads in pthread_cond_wait
- * in syncenv_task
- */
- pthread_cond_broadcast (&env->cond);
-
- /* when the syncenv_task() thread is exiting, it broadcasts to
- * wake the below wait.
- */
- while (env->procs != 0) {
- pthread_cond_wait (&env->cond, &env->mutex);
- }
+ while (env->procs != 0) {
+ pthread_cond_wait(&env->cond, &env->mutex);
}
- pthread_mutex_unlock (&env->mutex);
+ }
+ pthread_mutex_unlock(&env->mutex);
- pthread_mutex_destroy (&env->mutex);
- pthread_cond_destroy (&env->cond);
+ pthread_mutex_destroy(&env->mutex);
+ pthread_cond_destroy(&env->cond);
- GF_FREE (env);
+ GF_FREE(env);
- return;
+ return;
}
-
struct syncenv *
-syncenv_new (size_t stacksize, int procmin, int procmax)
+syncenv_new(size_t stacksize, int procmin, int procmax)
{
- struct syncenv *newenv = NULL;
- int ret = 0;
- int i = 0;
+ struct syncenv *newenv = NULL;
+ int ret = 0;
+ int i = 0;
- if (!procmin || procmin < 0)
- procmin = SYNCENV_PROC_MIN;
- if (!procmax || procmax > SYNCENV_PROC_MAX)
- procmax = SYNCENV_PROC_MAX;
+ if (!procmin || procmin < 0)
+ procmin = SYNCENV_PROC_MIN;
+ if (!procmax || procmax > SYNCENV_PROC_MAX)
+ procmax = SYNCENV_PROC_MAX;
- if (procmin > procmax)
- return NULL;
+ if (procmin > procmax)
+ return NULL;
- newenv = GF_CALLOC (1, sizeof (*newenv), gf_common_mt_syncenv);
+ newenv = GF_CALLOC(1, sizeof(*newenv), gf_common_mt_syncenv);
- if (!newenv)
- return NULL;
+ if (!newenv)
+ return NULL;
- pthread_mutex_init (&newenv->mutex, NULL);
- pthread_cond_init (&newenv->cond, NULL);
+ pthread_mutex_init(&newenv->mutex, NULL);
+ pthread_cond_init(&newenv->cond, NULL);
- INIT_LIST_HEAD (&newenv->runq);
- INIT_LIST_HEAD (&newenv->waitq);
+ INIT_LIST_HEAD(&newenv->runq);
+ INIT_LIST_HEAD(&newenv->waitq);
- newenv->stacksize = SYNCENV_DEFAULT_STACKSIZE;
- if (stacksize)
- newenv->stacksize = stacksize;
- newenv->procmin = procmin;
- newenv->procmax = procmax;
+ newenv->stacksize = SYNCENV_DEFAULT_STACKSIZE;
+ if (stacksize)
+ newenv->stacksize = stacksize;
+ newenv->procmin = procmin;
+ newenv->procmax = procmax;
+ newenv->procs_idle = 0;
- for (i = 0; i < newenv->procmin; i++) {
- newenv->proc[i].env = newenv;
- ret = gf_thread_create (&newenv->proc[i].processor, NULL,
- syncenv_processor, &newenv->proc[i]);
- if (ret)
- break;
- newenv->procs++;
- }
+ for (i = 0; i < newenv->procmin; i++) {
+ newenv->proc[i].env = newenv;
+ ret = gf_thread_create(&newenv->proc[i].processor, NULL,
+ syncenv_processor, &newenv->proc[i], "sproc%d",
+ i);
+ if (ret)
+ break;
+ newenv->procs++;
+ }
- if (ret != 0)
- syncenv_destroy (newenv);
+ if (ret != 0) {
+ syncenv_destroy(newenv);
+ newenv = NULL;
+ }
- return newenv;
+ return newenv;
}
-
int
-synclock_init (synclock_t *lock, lock_attr_t attr)
+synclock_init(synclock_t *lock, lock_attr_t attr)
{
- if (!lock)
- return -1;
+ if (!lock)
+ return -1;
- pthread_cond_init (&lock->cond, 0);
- lock->type = LOCK_NULL;
- lock->owner = NULL;
- lock->owner_tid = 0;
- lock->lock = 0;
- lock->attr = attr;
- INIT_LIST_HEAD (&lock->waitq);
+ pthread_cond_init(&lock->cond, 0);
+ lock->type = LOCK_NULL;
+ lock->owner = NULL;
+ lock->owner_tid = 0;
+ lock->lock = 0;
+ lock->attr = attr;
+ INIT_LIST_HEAD(&lock->waitq);
- return pthread_mutex_init (&lock->guard, 0);
+ return pthread_mutex_init(&lock->guard, 0);
}
-
int
-synclock_destroy (synclock_t *lock)
+synclock_destroy(synclock_t *lock)
{
- if (!lock)
- return -1;
+ if (!lock)
+ return -1;
- pthread_cond_destroy (&lock->cond);
- return pthread_mutex_destroy (&lock->guard);
+ pthread_cond_destroy(&lock->cond);
+ return pthread_mutex_destroy(&lock->guard);
}
-
static int
-__synclock_lock (struct synclock *lock)
-{
- struct synctask *task = NULL;
-
- if (!lock)
- return -1;
-
- task = synctask_get ();
-
- if (lock->lock && (lock->attr == SYNC_LOCK_RECURSIVE)) {
- /*Recursive lock (if same owner requested for lock again then
- *increment lock count and return success).
- *Note:same number of unlocks required.
- */
- switch (lock->type) {
- case LOCK_TASK:
- if (task == lock->owner) {
- lock->lock++;
- gf_msg_trace ("", 0, "Recursive lock called by"
- " sync task.owner= %p,lock=%d",
- lock->owner, lock->lock);
- return 0;
- }
- break;
- case LOCK_THREAD:
- if (pthread_self () == lock->owner_tid) {
- lock->lock++;
- gf_msg_trace ("", 0, "Recursive lock called by"
- " thread ,owner=%u lock=%d",
- (unsigned int) lock->owner_tid,
- lock->lock);
- return 0;
- }
- break;
- default:
- gf_msg ("", GF_LOG_CRITICAL, 0,
- LG_MSG_UNKNOWN_LOCK_TYPE, "unknown lock type");
- break;
- }
- }
+__synclock_lock(struct synclock *lock)
+{
+ struct synctask *task = NULL;
+
+ if (!lock)
+ return -1;
+ task = synctask_get();
- while (lock->lock) {
- if (task) {
- /* called within a synctask */
- list_add_tail (&task->waitq, &lock->waitq);
- pthread_mutex_unlock (&lock->guard);
- synctask_yield (task);
- /* task is removed from waitq in unlock,
- * under lock->guard.*/
- pthread_mutex_lock (&lock->guard);
- } else {
- /* called by a non-synctask */
- pthread_cond_wait (&lock->cond, &lock->guard);
+ if (lock->lock && (lock->attr == SYNC_LOCK_RECURSIVE)) {
+ /*Recursive lock (if same owner requested for lock again then
+ *increment lock count and return success).
+ *Note:same number of unlocks required.
+ */
+ switch (lock->type) {
+ case LOCK_TASK:
+ if (task == lock->owner) {
+ lock->lock++;
+ gf_msg_trace("", 0,
+ "Recursive lock called by"
+ " sync task.owner= %p,lock=%d",
+ lock->owner, lock->lock);
+ return 0;
}
+ break;
+ case LOCK_THREAD:
+ if (pthread_equal(pthread_self(), lock->owner_tid)) {
+ lock->lock++;
+ gf_msg_trace("", 0,
+ "Recursive lock called by"
+ " thread ,owner=%u lock=%d",
+ (unsigned int)lock->owner_tid, lock->lock);
+ return 0;
+ }
+ break;
+ default:
+ gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_UNKNOWN_LOCK_TYPE,
+ "unknown lock type");
+ break;
}
+ }
+ while (lock->lock) {
if (task) {
- lock->type = LOCK_TASK;
- lock->owner = task; /* for synctask*/
-
+ /* called within a synctask */
+ task->woken = 0;
+ list_add_tail(&task->waitq, &lock->waitq);
+ pthread_mutex_unlock(&lock->guard);
+ synctask_yield(task, NULL);
+ /* task is removed from waitq in unlock,
+ * under lock->guard.*/
+ pthread_mutex_lock(&lock->guard);
} else {
- lock->type = LOCK_THREAD;
- lock->owner_tid = pthread_self (); /* for non-synctask */
-
+ /* called by a non-synctask */
+ pthread_cond_wait(&lock->cond, &lock->guard);
}
- lock->lock = 1;
+ }
- return 0;
+ if (task) {
+ lock->type = LOCK_TASK;
+ lock->owner = task; /* for synctask*/
+
+ } else {
+ lock->type = LOCK_THREAD;
+ lock->owner_tid = pthread_self(); /* for non-synctask */
+ }
+ lock->lock = 1;
+
+ return 0;
}
+int
+synclock_lock(synclock_t *lock)
+{
+ int ret = 0;
+
+ pthread_mutex_lock(&lock->guard);
+ {
+ ret = __synclock_lock(lock);
+ }
+ pthread_mutex_unlock(&lock->guard);
+
+ return ret;
+}
int
-synclock_lock (synclock_t *lock)
+synclock_trylock(synclock_t *lock)
{
- int ret = 0;
+ int ret = 0;
+
+ errno = 0;
- pthread_mutex_lock (&lock->guard);
- {
- ret = __synclock_lock (lock);
- }
- pthread_mutex_unlock (&lock->guard);
+ pthread_mutex_lock(&lock->guard);
+ {
+ if (lock->lock) {
+ errno = EBUSY;
+ ret = -1;
+ goto unlock;
+ }
+
+ ret = __synclock_lock(lock);
+ }
+unlock:
+ pthread_mutex_unlock(&lock->guard);
- return ret;
+ return ret;
}
+static int
+__synclock_unlock(synclock_t *lock)
+{
+ struct synctask *task = NULL;
+ struct synctask *curr = NULL;
+
+ if (!lock)
+ return -1;
+
+ if (lock->lock == 0) {
+ gf_msg("", GF_LOG_CRITICAL, 0, LG_MSG_UNLOCK_BEFORE_LOCK,
+ "Unlock called before lock ");
+ return -1;
+ }
+ curr = synctask_get();
+ /*unlock should be called by lock owner
+ *i.e this will not allow the lock in nonsync task and unlock
+ * in sync task and vice-versa
+ */
+ switch (lock->type) {
+ case LOCK_TASK:
+ if (curr == lock->owner) {
+ lock->lock--;
+ gf_msg_trace("", 0,
+ "Unlock success %p, remaining"
+ " locks=%d",
+ lock->owner, lock->lock);
+ } else {
+ gf_msg("", GF_LOG_WARNING, 0, LG_MSG_LOCK_OWNER_ERROR,
+ "Unlock called by %p, but lock held by %p", curr,
+ lock->owner);
+ }
+
+ break;
+ case LOCK_THREAD:
+ if (pthread_equal(pthread_self(), lock->owner_tid)) {
+ lock->lock--;
+ gf_msg_trace("", 0,
+ "Unlock success %u, remaining "
+ "locks=%d",
+ (unsigned int)lock->owner_tid, lock->lock);
+ } else {
+ gf_msg("", GF_LOG_WARNING, 0, LG_MSG_LOCK_OWNER_ERROR,
+ "Unlock called by %u, but lock held by %u",
+ (unsigned int)pthread_self(),
+ (unsigned int)lock->owner_tid);
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ if (lock->lock > 0) {
+ return 0;
+ }
+ lock->type = LOCK_NULL;
+ lock->owner = NULL;
+ lock->owner_tid = 0;
+ lock->lock = 0;
+ /* There could be both synctasks and non synctasks
+ waiting (or none, or either). As a mid-approach
+ between maintaining too many waiting counters
+ at one extreme and a thundering herd on unlock
+ at the other, call a cond_signal (which wakes
+ one waiter) and first synctask waiter. So at
+ most we have two threads waking up to grab the
+ just released lock.
+ */
+ pthread_cond_signal(&lock->cond);
+ if (!list_empty(&lock->waitq)) {
+ task = list_entry(lock->waitq.next, struct synctask, waitq);
+ list_del_init(&task->waitq);
+ synctask_wake(task);
+ }
+
+ return 0;
+}
int
-synclock_trylock (synclock_t *lock)
+synclock_unlock(synclock_t *lock)
{
- int ret = 0;
+ int ret = 0;
- errno = 0;
+ pthread_mutex_lock(&lock->guard);
+ {
+ ret = __synclock_unlock(lock);
+ }
+ pthread_mutex_unlock(&lock->guard);
- pthread_mutex_lock (&lock->guard);
- {
- if (lock->lock) {
- errno = EBUSY;
- ret = -1;
- goto unlock;
- }
+ return ret;
+}
- ret = __synclock_lock (lock);
- }
-unlock:
- pthread_mutex_unlock (&lock->guard);
+/* Condition variables */
- return ret;
+int32_t
+synccond_init(synccond_t *cond)
+{
+ int32_t ret;
+
+ INIT_LIST_HEAD(&cond->waitq);
+
+ ret = pthread_mutex_init(&cond->pmutex, NULL);
+ if (ret != 0) {
+ return -ret;
+ }
+
+ ret = pthread_cond_init(&cond->pcond, NULL);
+ if (ret != 0) {
+ pthread_mutex_destroy(&cond->pmutex);
+ }
+
+ return -ret;
}
+void
+synccond_destroy(synccond_t *cond)
+{
+ pthread_cond_destroy(&cond->pcond);
+ pthread_mutex_destroy(&cond->pmutex);
+}
-static int
-__synclock_unlock (synclock_t *lock)
+int
+synccond_timedwait(synccond_t *cond, synclock_t *lock, struct timespec *delta)
{
- struct synctask *task = NULL;
- struct synctask *curr = NULL;
+ struct timespec now;
+ struct synctask *task = NULL;
+ int ret;
- if (!lock)
- return -1;
+ task = synctask_get();
- if (lock->lock == 0) {
- gf_msg ("", GF_LOG_CRITICAL, 0, LG_MSG_UNLOCK_BEFORE_LOCK,
- "Unlock called before lock ");
- return -1;
+ if (task == NULL) {
+ if (delta != NULL) {
+ timespec_now_realtime(&now);
+ timespec_adjust_delta(&now, *delta);
}
- curr = synctask_get ();
- /*unlock should be called by lock owner
- *i.e this will not allow the lock in nonsync task and unlock
- * in sync task and vice-versa
- */
- switch (lock->type) {
- case LOCK_TASK:
- if (curr == lock->owner) {
- lock->lock--;
- gf_msg_trace ("", 0, "Unlock success %p, remaining"
- " locks=%d", lock->owner, lock->lock);
- } else {
- gf_msg ("", GF_LOG_WARNING, 0, LG_MSG_LOCK_OWNER_ERROR,
- "Unlock called by %p, but lock held by %p",
- curr, lock->owner);
- }
- break;
- case LOCK_THREAD:
- if (pthread_self () == lock->owner_tid) {
- lock->lock--;
- gf_msg_trace ("", 0, "Unlock success %u, remaining "
- "locks=%d",
- (unsigned int)lock->owner_tid,
- lock->lock);
- } else {
- gf_msg ("", GF_LOG_WARNING, 0, LG_MSG_LOCK_OWNER_ERROR,
- "Unlock called by %u, but lock held by %u",
- (unsigned int) pthread_self(),
- (unsigned int) lock->owner_tid);
- }
+ pthread_mutex_lock(&cond->pmutex);
- break;
- default:
- break;
+ if (delta == NULL) {
+ ret = -pthread_cond_wait(&cond->pcond, &cond->pmutex);
+ } else {
+ ret = -pthread_cond_timedwait(&cond->pcond, &cond->pmutex, &now);
}
+ } else {
+ pthread_mutex_lock(&cond->pmutex);
- if (lock->lock > 0) {
- return 0;
- }
- lock->type = LOCK_NULL;
- lock->owner = NULL;
- lock->owner_tid = 0;
- lock->lock = 0;
- /* There could be both synctasks and non synctasks
- waiting (or none, or either). As a mid-approach
- between maintaining too many waiting counters
- at one extreme and a thundering herd on unlock
- at the other, call a cond_signal (which wakes
- one waiter) and first synctask waiter. So at
- most we have two threads waking up to grab the
- just released lock.
- */
- pthread_cond_signal (&lock->cond);
- if (!list_empty (&lock->waitq)) {
- task = list_entry (lock->waitq.next, struct synctask, waitq);
- list_del_init (&task->waitq);
- synctask_wake (task);
+ list_add_tail(&task->waitq, &cond->waitq);
+ task->synccond = cond;
+
+ ret = synclock_unlock(lock);
+ if (ret == 0) {
+ pthread_mutex_unlock(&cond->pmutex);
+
+ synctask_yield(task, delta);
+
+ ret = synclock_lock(lock);
+ if (ret == 0) {
+ ret = task->ret;
+ }
+ task->ret = 0;
+
+ return ret;
}
- return 0;
-}
+ list_del_init(&task->waitq);
+ }
+ pthread_mutex_unlock(&cond->pmutex);
+
+ return ret;
+}
int
-synclock_unlock (synclock_t *lock)
+synccond_wait(synccond_t *cond, synclock_t *lock)
{
- int ret = 0;
+ return synccond_timedwait(cond, lock, NULL);
+}
+
+void
+synccond_signal(synccond_t *cond)
+{
+ struct synctask *task;
+
+ pthread_mutex_lock(&cond->pmutex);
- pthread_mutex_lock (&lock->guard);
- {
- ret = __synclock_unlock (lock);
- }
- pthread_mutex_unlock (&lock->guard);
+ if (!list_empty(&cond->waitq)) {
+ task = list_first_entry(&cond->waitq, struct synctask, waitq);
+ list_del_init(&task->waitq);
- return ret;
+ pthread_mutex_unlock(&cond->pmutex);
+
+ synctask_wake(task);
+ } else {
+ pthread_cond_signal(&cond->pcond);
+
+ pthread_mutex_unlock(&cond->pmutex);
+ }
+}
+
+void
+synccond_broadcast(synccond_t *cond)
+{
+ struct list_head list;
+ struct synctask *task;
+
+ INIT_LIST_HEAD(&list);
+
+ pthread_mutex_lock(&cond->pmutex);
+
+ list_splice_init(&cond->waitq, &list);
+ pthread_cond_broadcast(&cond->pcond);
+
+ pthread_mutex_unlock(&cond->pmutex);
+
+ while (!list_empty(&list)) {
+ task = list_first_entry(&list, struct synctask, waitq);
+ list_del_init(&task->waitq);
+
+ synctask_wake(task);
+ }
}
/* Barriers */
int
-syncbarrier_init (struct syncbarrier *barrier)
+syncbarrier_init(struct syncbarrier *barrier)
{
- if (!barrier) {
- errno = EINVAL;
- return -1;
- }
+ int ret = 0;
+ if (!barrier) {
+ errno = EINVAL;
+ return -1;
+ }
- pthread_cond_init (&barrier->cond, 0);
- barrier->count = 0;
- INIT_LIST_HEAD (&barrier->waitq);
+ ret = pthread_cond_init(&barrier->cond, 0);
+ if (ret) {
+ errno = ret;
+ return -1;
+ }
+ barrier->count = 0;
+ barrier->waitfor = 0;
+ INIT_LIST_HEAD(&barrier->waitq);
- return pthread_mutex_init (&barrier->guard, 0);
+ ret = pthread_mutex_init(&barrier->guard, 0);
+ if (ret) {
+ (void)pthread_cond_destroy(&barrier->cond);
+ errno = ret;
+ return -1;
+ }
+ barrier->initialized = _gf_true;
+ return 0;
}
-
int
-syncbarrier_destroy (struct syncbarrier *barrier)
+syncbarrier_destroy(struct syncbarrier *barrier)
{
- if (!barrier) {
- errno = EINVAL;
- return -1;
- }
+ int ret = 0;
+ int ret1 = 0;
+ if (!barrier) {
+ errno = EINVAL;
+ return -1;
+ }
- pthread_cond_destroy (&barrier->cond);
- return pthread_mutex_destroy (&barrier->guard);
+ if (barrier->initialized) {
+ ret = pthread_cond_destroy(&barrier->cond);
+ ret1 = pthread_mutex_destroy(&barrier->guard);
+ barrier->initialized = _gf_false;
+ }
+ if (ret || ret1) {
+ errno = ret ? ret : ret1;
+ return -1;
+ }
+ return 0;
}
-
static int
-__syncbarrier_wait (struct syncbarrier *barrier, int waitfor)
+__syncbarrier_wait(struct syncbarrier *barrier, int waitfor)
{
- struct synctask *task = NULL;
+ struct synctask *task = NULL;
- if (!barrier) {
- errno = EINVAL;
- return -1;
- }
+ if (!barrier) {
+ errno = EINVAL;
+ return -1;
+ }
- task = synctask_get ();
+ task = synctask_get();
- while (barrier->count < waitfor) {
- if (task) {
- /* called within a synctask */
- list_add_tail (&task->waitq, &barrier->waitq);
- pthread_mutex_unlock (&barrier->guard);
- synctask_yield (task);
- pthread_mutex_lock (&barrier->guard);
- } else {
- /* called by a non-synctask */
- pthread_cond_wait (&barrier->cond, &barrier->guard);
- }
- }
+ while (barrier->count < waitfor) {
+ if (task) {
+ /* called within a synctask */
+ list_add_tail(&task->waitq, &barrier->waitq);
+ pthread_mutex_unlock(&barrier->guard);
+ synctask_yield(task, NULL);
+ pthread_mutex_lock(&barrier->guard);
+ } else {
+ /* called by a non-synctask */
+ pthread_cond_wait(&barrier->cond, &barrier->guard);
+ }
+ }
- barrier->count = 0;
+ barrier->count = 0;
- return 0;
+ return 0;
}
-
int
-syncbarrier_wait (struct syncbarrier *barrier, int waitfor)
+syncbarrier_wait(struct syncbarrier *barrier, int waitfor)
{
- int ret = 0;
+ int ret = 0;
- pthread_mutex_lock (&barrier->guard);
- {
- ret = __syncbarrier_wait (barrier, waitfor);
- }
- pthread_mutex_unlock (&barrier->guard);
+ pthread_mutex_lock(&barrier->guard);
+ {
+ ret = __syncbarrier_wait(barrier, waitfor);
+ }
+ pthread_mutex_unlock(&barrier->guard);
- return ret;
+ return ret;
}
-
static int
-__syncbarrier_wake (struct syncbarrier *barrier)
+__syncbarrier_wake(struct syncbarrier *barrier)
{
- struct synctask *task = NULL;
+ struct synctask *task = NULL;
- if (!barrier) {
- errno = EINVAL;
- return -1;
- }
+ if (!barrier) {
+ errno = EINVAL;
+ return -1;
+ }
- barrier->count++;
+ barrier->count++;
+ if (barrier->waitfor && (barrier->count < barrier->waitfor))
+ return 0;
- pthread_cond_signal (&barrier->cond);
- if (!list_empty (&barrier->waitq)) {
- task = list_entry (barrier->waitq.next, struct synctask, waitq);
- list_del_init (&task->waitq);
- synctask_wake (task);
- }
+ pthread_cond_signal(&barrier->cond);
+ if (!list_empty(&barrier->waitq)) {
+ task = list_entry(barrier->waitq.next, struct synctask, waitq);
+ list_del_init(&task->waitq);
+ synctask_wake(task);
+ }
+ barrier->waitfor = 0;
- return 0;
+ return 0;
}
-
int
-syncbarrier_wake (struct syncbarrier *barrier)
+syncbarrier_wake(struct syncbarrier *barrier)
{
- int ret = 0;
+ int ret = 0;
- pthread_mutex_lock (&barrier->guard);
- {
- ret = __syncbarrier_wake (barrier);
- }
- pthread_mutex_unlock (&barrier->guard);
+ pthread_mutex_lock(&barrier->guard);
+ {
+ ret = __syncbarrier_wake(barrier);
+ }
+ pthread_mutex_unlock(&barrier->guard);
- return ret;
+ return ret;
}
-
/* FOPS */
-
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 *xdata, struct iatt *parent)
+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 *xdata, struct iatt *parent)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (op_ret == 0) {
- args->iatt1 = *iatt;
- args->iatt2 = *parent;
- }
+ if (op_ret == 0) {
+ args->iatt1 = *iatt;
+ args->iatt2 = *parent;
+ }
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
-
int
-syncop_lookup (xlator_t *subvol, loc_t *loc, struct iatt *iatt,
- struct iatt *parent, dict_t *xdata_in, dict_t **xdata_out)
+syncop_lookup(xlator_t *subvol, loc_t *loc, struct iatt *iatt,
+ struct iatt *parent, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_lookup_cbk, subvol->fops->lookup,
- loc, xdata_in);
+ SYNCOP(subvol, (&args), syncop_lookup_cbk, subvol->fops->lookup, loc,
+ xdata_in);
- if (iatt)
- *iatt = args.iatt1;
- if (parent)
- *parent = args.iatt2;
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (iatt)
+ *iatt = args.iatt1;
+ if (parent)
+ *parent = args.iatt2;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int32_t
-syncop_readdirp_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 (xdata)
- args->xdata = dict_ref (xdata);
-
-
- if (op_ret >= 0) {
- list_for_each_entry (entry, &entries->list, list) {
- tmp = entry_copy (entry);
- if (!tmp) {
- args->op_ret = -1;
- args->op_errno = ENOMEM;
- gf_dirent_free (&(args->entries));
- break;
- }
- gf_msg_trace (this->name, 0, "adding entry=%s, "
- "count=%d", tmp->d_name, count);
- list_add_tail (&tmp->list, &(args->entries.list));
- count++;
- }
- }
+syncop_readdirp_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;
- __wake (args);
+ int count = 0;
- return 0;
+ args = cookie;
+
+ INIT_LIST_HEAD(&args->entries.list);
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ if (op_ret >= 0) {
+ list_for_each_entry(entry, &entries->list, list)
+ {
+ tmp = entry_copy(entry);
+ if (!tmp) {
+ args->op_ret = -1;
+ args->op_errno = ENOMEM;
+ gf_dirent_free(&(args->entries));
+ break;
+ }
+ gf_msg_trace(this->name, 0,
+ "adding entry=%s, "
+ "count=%d",
+ tmp->d_name, count);
+ list_add_tail(&tmp->list, &(args->entries.list));
+ count++;
+ }
+ }
+
+ __wake(args);
+
+ return 0;
}
int
-syncop_readdirp (xlator_t *subvol,
- fd_t *fd,
- size_t size,
- off_t off,
- gf_dirent_t *entries,
- dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_readdirp(xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ gf_dirent_t *entries, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
-
- SYNCOP (subvol, (&args), syncop_readdirp_cbk, subvol->fops->readdirp,
- fd, size, off, xdata_in);
+ struct syncargs args = {
+ 0,
+ };
- if (entries)
- list_splice_init (&args.entries.list, &entries->list);
- else
- gf_dirent_free (&args.entries);
+ SYNCOP(subvol, (&args), syncop_readdirp_cbk, subvol->fops->readdirp, fd,
+ size, off, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (entries)
+ list_splice_init(&args.entries.list, &entries->list);
+ else
+ gf_dirent_free(&args.entries);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -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 (xdata)
- args->xdata = dict_ref (xdata);
-
- if (op_ret >= 0) {
- list_for_each_entry (entry, &entries->list, list) {
- tmp = entry_copy (entry);
- if (!tmp) {
- args->op_ret = -1;
- args->op_errno = ENOMEM;
- gf_dirent_free (&(args->entries));
- break;
- }
- gf_msg_trace (this->name, 0, "adding "
- "entry=%s, count=%d", tmp->d_name,
- count);
- list_add_tail (&tmp->list, &(args->entries.list));
- count++;
- }
- }
+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;
- __wake (args);
+ int count = 0;
- return 0;
+ args = cookie;
+
+ INIT_LIST_HEAD(&args->entries.list);
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ if (op_ret >= 0) {
+ list_for_each_entry(entry, &entries->list, list)
+ {
+ tmp = entry_copy(entry);
+ if (!tmp) {
+ args->op_ret = -1;
+ args->op_errno = ENOMEM;
+ gf_dirent_free(&(args->entries));
+ break;
+ }
+ gf_msg_trace(this->name, 0,
+ "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,
- dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_readdir(xlator_t *subvol, fd_t *fd, size_t size, off_t off,
+ gf_dirent_t *entries, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_readdir_cbk, subvol->fops->readdir,
- fd, size, off, xdata_in);
+ SYNCOP(subvol, (&args), syncop_readdir_cbk, subvol->fops->readdir, fd, size,
+ off, xdata_in);
- if (entries)
- list_splice_init (&args.entries.list, &entries->list);
- else
- gf_dirent_free (&args.entries);
+ if (entries)
+ list_splice_init(&args.entries.list, &entries->list);
+ else
+ gf_dirent_free(&args.entries);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
-
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int32_t
-syncop_opendir_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd, dict_t *xdata)
+syncop_opendir_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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_opendir (xlator_t *subvol,
- loc_t *loc,
- fd_t *fd,
- dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_opendir(xlator_t *subvol, loc_t *loc, fd_t *fd, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_opendir_cbk, subvol->fops->opendir,
- loc, fd, xdata_in);
+ SYNCOP(subvol, (&args), syncop_opendir_cbk, subvol->fops->opendir, loc, fd,
+ xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
-
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_fsyncdir_cbk (call_frame_t *frame, void* cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+syncop_fsyncdir_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_fsyncdir (xlator_t *subvol, fd_t *fd, int datasync, dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_fsyncdir(xlator_t *subvol, fd_t *fd, int datasync, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_fsyncdir_cbk, subvol->fops->fsyncdir,
- fd, datasync, xdata_in);
+ SYNCOP(subvol, (&args), syncop_fsyncdir_cbk, subvol->fops->fsyncdir, fd,
+ datasync, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_removexattr(xlator_t *subvol, loc_t *loc, const char *name,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_removexattr_cbk,
- subvol->fops->removexattr, loc, name, xdata_in);
+ SYNCOP(subvol, (&args), syncop_removexattr_cbk, subvol->fops->removexattr,
+ loc, name, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_fremovexattr(xlator_t *subvol, fd_t *fd, const char *name,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_fremovexattr_cbk,
- subvol->fops->fremovexattr, fd, name, xdata_in);
+ SYNCOP(subvol, (&args), syncop_fremovexattr_cbk, subvol->fops->fremovexattr,
+ fd, name, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -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, dict_t *xdata)
+syncop_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
-
int
-syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_setxattr(xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_setxattr_cbk, subvol->fops->setxattr,
- loc, dict, flags, xdata_in);
+ SYNCOP(subvol, (&args), syncop_setxattr_cbk, subvol->fops->setxattr, loc,
+ dict, flags, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
-
int
-syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_fsetxattr(xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_fsetxattr_cbk, subvol->fops->fsetxattr,
- fd, dict, flags, xdata_in);
+ SYNCOP(subvol, (&args), syncop_fsetxattr_cbk, subvol->fops->fsetxattr, fd,
+ dict, flags, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (op_ret >= 0)
- args->xattr = dict_ref (dict);
+ if (op_ret >= 0)
+ args->xattr = dict_ref(dict);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_listxattr (xlator_t *subvol, loc_t *loc, dict_t **dict, dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_listxattr(xlator_t *subvol, loc_t *loc, dict_t **dict, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr,
- loc, NULL, xdata_in);
+ SYNCOP(subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr, loc,
+ NULL, xdata_in);
- if (dict)
- *dict = args.xattr;
- else if (args.xattr)
- dict_unref (args.xattr);
+ if (dict)
+ *dict = args.xattr;
+ else if (args.xattr)
+ dict_unref(args.xattr);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_getxattr (xlator_t *subvol, loc_t *loc, dict_t **dict, const char *key,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_getxattr(xlator_t *subvol, loc_t *loc, dict_t **dict, const char *key,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr,
- loc, key, xdata_in);
+ SYNCOP(subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr, loc,
+ key, xdata_in);
- if (dict)
- *dict = args.xattr;
- else if (args.xattr)
- dict_unref (args.xattr);
+ if (dict)
+ *dict = args.xattr;
+ else if (args.xattr)
+ dict_unref(args.xattr);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_fgetxattr (xlator_t *subvol, fd_t *fd, dict_t **dict, const char *key,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_fgetxattr(xlator_t *subvol, fd_t *fd, dict_t **dict, const char *key,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->fgetxattr,
- fd, key, xdata_in);
+ SYNCOP(subvol, (&args), syncop_getxattr_cbk, subvol->fops->fgetxattr, fd,
+ key, xdata_in);
- if (dict)
- *dict = args.xattr;
- else if (args.xattr)
- dict_unref (args.xattr);
+ if (dict)
+ *dict = args.xattr;
+ else if (args.xattr)
+ dict_unref(args.xattr);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct statvfs *buf, dict_t *xdata)
+syncop_statfs_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf,
+ dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (op_ret == 0) {
- args->statvfs_buf = *buf;
- }
+ if (op_ret == 0) {
+ args->statvfs_buf = *buf;
+ }
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
-
int
-syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_statfs(xlator_t *subvol, loc_t *loc, struct statvfs *buf,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_statfs_cbk, subvol->fops->statfs,
- loc, xdata_in);
+ SYNCOP(subvol, (&args), syncop_statfs_cbk, subvol->fops->statfs, loc,
+ xdata_in);
- if (buf)
- *buf = args.statvfs_buf;
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (buf)
+ *buf = args.statvfs_buf;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
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, dict_t *xdata)
+syncop_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *preop,
+ struct iatt *postop, dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (op_ret == 0) {
- args->iatt1 = *preop;
- args->iatt2 = *postop;
- }
+ if (op_ret == 0) {
+ args->iatt1 = *preop;
+ args->iatt2 = *postop;
+ }
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
-
int
-syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
- struct iatt *preop, struct iatt *postop, dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_setattr(xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
+ struct iatt *preop, struct iatt *postop, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_setattr_cbk, subvol->fops->setattr,
- loc, iatt, valid, xdata_in);
+ SYNCOP(subvol, (&args), syncop_setattr_cbk, subvol->fops->setattr, loc,
+ iatt, valid, xdata_in);
- if (preop)
- *preop = args.iatt1;
- if (postop)
- *postop = args.iatt2;
+ if (preop)
+ *preop = args.iatt1;
+ if (postop)
+ *postop = args.iatt2;
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -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, dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_fsetattr(xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid,
+ struct iatt *preop, struct iatt *postop, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_setattr_cbk, subvol->fops->fsetattr,
- fd, iatt, valid, xdata_in);
+ SYNCOP(subvol, (&args), syncop_setattr_cbk, subvol->fops->fsetattr, fd,
+ iatt, valid, xdata_in);
- if (preop)
- *preop = args.iatt1;
- if (postop)
- *postop = args.iatt2;
+ if (preop)
+ *preop = args.iatt1;
+ if (postop)
+ *postop = args.iatt2;
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_open(xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_open_cbk, subvol->fops->open,
- loc, flags, fd, xdata_in);
+ SYNCOP(subvol, (&args), syncop_open_cbk, subvol->fops->open, loc, flags, fd,
+ xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
-
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- INIT_LIST_HEAD (&args->entries.list);
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ INIT_LIST_HEAD(&args->entries.list);
- if (args->op_ret >= 0) {
- if (iobref)
- args->iobref = iobref_ref (iobref);
- args->vector = iov_dup (vector, count);
- args->count = count;
- }
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ if (args->op_ret >= 0) {
+ if (iobref)
+ args->iobref = iobref_ref(iobref);
+ args->vector = iov_dup(vector, count);
+ args->count = count;
+ args->iatt1 = *stbuf;
+ }
- return 0;
+ __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, dict_t *xdata_in, dict_t **xdata_out)
+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 iatt *iatt, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_readv_cbk, subvol->fops->readv,
- fd, size, off, flags, xdata_in);
+ SYNCOP(subvol, (&args), syncop_readv_cbk, subvol->fops->readv, fd, size,
+ off, flags, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- goto out;
+ if (iatt)
+ *iatt = args.iatt1;
- if (vector)
- *vector = args.vector;
- else
- GF_FREE (args.vector);
+ if (args.op_ret < 0)
+ goto out;
- if (count)
- *count = args.count;
+ if (vector)
+ *vector = args.vector;
+ else
+ GF_FREE(args.vector);
- /* Do we need a 'ref' here? */
- if (iobref)
- *iobref = args.iobref;
- else if (args.iobref)
- iobref_unref (args.iobref);
+ if (count)
+ *count = args.count;
-out:
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ /* Do we need a 'ref' here? */
+ if (iobref)
+ *iobref = args.iobref;
+ else if (args.iobref)
+ iobref_unref(args.iobref);
+out:
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ if (op_ret >= 0) {
+ args->iatt1 = *prebuf;
+ args->iatt2 = *postbuf;
+ }
- return 0;
+ __wake(args);
+
+ return 0;
}
int
-syncop_writev (xlator_t *subvol, fd_t *fd, const struct iovec *vector,
- int32_t count, off_t offset, struct iobref *iobref,
- uint32_t flags, dict_t *xdata_in, dict_t **xdata_out)
+syncop_writev(xlator_t *subvol, fd_t *fd, const struct iovec *vector,
+ int32_t count, off_t offset, struct iobref *iobref,
+ uint32_t flags, struct iatt *preiatt, struct iatt *postiatt,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev,
- fd, (struct iovec *) vector, count, offset, flags, iobref,
- xdata_in);
+ SYNCOP(subvol, (&args), syncop_writev_cbk, subvol->fops->writev, fd,
+ (struct iovec *)vector, count, offset, flags, iobref, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (preiatt)
+ *preiatt = args.iatt1;
+ if (postiatt)
+ *postiatt = args.iatt2;
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+
+ if (args.op_ret < 0)
+ return -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,
- dict_t *xdata_in, dict_t **xdata_out)
+int
+syncop_write(xlator_t *subvol, fd_t *fd, const char *buf, int size,
+ off_t offset, struct iobref *iobref, uint32_t flags,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0,};
- struct iovec vec = {0,};
+ struct syncargs args = {
+ 0,
+ };
+ struct iovec vec = {
+ 0,
+ };
- vec.iov_len = size;
- vec.iov_base = (void *)buf;
+ vec.iov_len = size;
+ vec.iov_base = (void *)buf;
- SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev,
- fd, &vec, 1, offset, flags, iobref, xdata_in);
+ SYNCOP(subvol, (&args), syncop_writev_cbk, subvol->fops->writev, fd, &vec,
+ 1, offset, flags, iobref, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
-
int
-syncop_close (fd_t *fd)
+syncop_close(fd_t *fd)
{
- if (fd)
- fd_unref (fd);
- return 0;
+ 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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (buf)
- args->iatt1 = *buf;
+ if (buf)
+ args->iatt1 = *buf;
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, struct iatt *iatt,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_create(xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
+ fd_t *fd, struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_create_cbk, subvol->fops->create,
- loc, flags, mode, 0, fd, xdata_in);
+ SYNCOP(subvol, (&args), syncop_create_cbk, subvol->fops->create, loc, flags,
+ mode, 0, fd, xdata_in);
- if (iatt)
- *iatt = args.iatt1;
+ if (iatt)
+ *iatt = args.iatt1;
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
-
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -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)
+int32_t
+syncop_put_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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ if (buf)
+ args->iatt1 = *buf;
- return 0;
+ __wake(args);
+
+ return 0;
}
int
-syncop_unlink (xlator_t *subvol, loc_t *loc, dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_put(xlator_t *subvol, loc_t *loc, mode_t mode, mode_t umask,
+ uint32_t flags, struct iovec *vector, int32_t count, off_t offset,
+ struct iobref *iobref, dict_t *xattr, struct iatt *iatt,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_unlink_cbk, subvol->fops->unlink, loc,
- 0, xdata_in);
+ SYNCOP(subvol, (&args), syncop_put_cbk, subvol->fops->put, loc, mode, umask,
+ flags, (struct iovec *)vector, count, offset, iobref, xattr,
+ xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (iatt)
+ *iatt = args.iatt1;
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_rmdir_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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_rmdir (xlator_t *subvol, loc_t *loc, int flags, dict_t *xdata_in,
+syncop_unlink(xlator_t *subvol, loc_t *loc, dict_t *xdata_in,
dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_rmdir_cbk, subvol->fops->rmdir, loc,
- flags, xdata_in);
+ SYNCOP(subvol, (&args), syncop_unlink_cbk, subvol->fops->unlink, loc, 0,
+ xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -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)
+syncop_rmdir_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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (buf)
- args->iatt1 = *buf;
+ __wake(args);
- __wake (args);
-
- return 0;
+ return 0;
}
-
int
-syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc, struct iatt *iatt,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_rmdir(xlator_t *subvol, loc_t *loc, int flags, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_link_cbk, subvol->fops->link,
- oldloc, newloc, xdata_in);
+ SYNCOP(subvol, (&args), syncop_rmdir_cbk, subvol->fops->rmdir, loc, flags,
+ xdata_in);
- if (iatt)
- *iatt = args.iatt1;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
-
- if (args.op_ret < 0)
- return -args.op_errno;
-
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
-
int
-syncop_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,
- dict_t *xdata)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ if (buf)
+ args->iatt1 = *buf;
- return 0;
-}
+ __wake(args);
+ return 0;
+}
int
-syncop_rename (xlator_t *subvol, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_link(xlator_t *subvol, loc_t *oldloc, loc_t *newloc, struct iatt *iatt,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_rename_cbk, subvol->fops->rename,
- oldloc, newloc, xdata_in);
+ SYNCOP(subvol, (&args), syncop_link_cbk, subvol->fops->link, oldloc, newloc,
+ xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (iatt)
+ *iatt = args.iatt1;
- if (args.op_ret < 0)
- return -args.op_errno;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- return args.op_ret;
-}
+ if (args.op_ret < 0)
+ return -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)
+syncop_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,
+ dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_ftruncate (xlator_t *subvol, fd_t *fd, off_t offset, dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_rename(xlator_t *subvol, loc_t *oldloc, loc_t *newloc, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_ftruncate_cbk, subvol->fops->ftruncate,
- fd, offset, xdata_in);
+ SYNCOP(subvol, (&args), syncop_rename_cbk, subvol->fops->rename, oldloc,
+ newloc, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+
+ return args.op_ret;
}
int
-syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset, dict_t *xdata_in,
- dict_t **xdata_out)
+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 = {0, };
+ struct syncargs *args = NULL;
- SYNCOP (subvol, (&args), syncop_ftruncate_cbk, subvol->fops->truncate,
- loc, offset, xdata_in);
+ args = cookie;
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (op_ret >= 0) {
+ args->iatt1 = *prebuf;
+ args->iatt2 = *postbuf;
+ }
+
+ __wake(args);
+
+ return 0;
}
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)
+syncop_ftruncate(xlator_t *subvol, fd_t *fd, off_t offset, struct iatt *preiatt,
+ struct iatt *postiatt, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs *args = NULL;
+ struct syncargs args = {
+ 0,
+ };
- args = cookie;
+ SYNCOP(subvol, (&args), syncop_ftruncate_cbk, subvol->fops->ftruncate, fd,
+ offset, xdata_in);
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ if (preiatt)
+ *preiatt = args.iatt1;
+ if (postiatt)
+ *postiatt = args.iatt2;
- __wake (args);
-
- return 0;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_fsync (xlator_t *subvol, fd_t *fd, int dataonly, dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_truncate(xlator_t *subvol, loc_t *loc, off_t offset, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
-
- SYNCOP (subvol, (&args), syncop_fsync_cbk, subvol->fops->fsync,
- fd, dataonly, xdata_in);
+ struct syncargs args = {
+ 0,
+ };
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ SYNCOP(subvol, (&args), syncop_ftruncate_cbk, subvol->fops->truncate, loc,
+ offset, xdata_in);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
-
int
-syncop_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ if (op_ret >= 0) {
+ args->iatt1 = *prebuf;
+ args->iatt2 = *postbuf;
+ }
- return 0;
+ __wake(args);
+ return 0;
}
int
-syncop_flush (xlator_t *subvol, fd_t *fd, dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_fsync(xlator_t *subvol, fd_t *fd, int dataonly, struct iatt *preiatt,
+ struct iatt *postiatt, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0};
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_flush_cbk, subvol->fops->flush,
- fd, xdata_in);
+ SYNCOP(subvol, (&args), syncop_fsync_cbk, subvol->fops->fsync, fd, dataonly,
+ xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (preiatt)
+ *preiatt = args.iatt1;
+ if (postiatt)
+ *postiatt = args.iatt2;
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -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)
+syncop_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (op_ret == 0)
- args->iatt1 = *stbuf;
+ __wake(args);
- __wake (args);
+ return 0;
+}
- return 0;
+int
+syncop_flush(xlator_t *subvol, fd_t *fd, dict_t *xdata_in, dict_t **xdata_out)
+{
+ struct syncargs args = {0};
+
+ SYNCOP(subvol, (&args), syncop_flush_cbk, subvol->fops->flush, fd,
+ xdata_in);
+
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_fstat (xlator_t *subvol, fd_t *fd, struct iatt *stbuf, dict_t *xdata_in,
- dict_t **xdata_out)
+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 = {0, };
+ struct syncargs *args = NULL;
- SYNCOP (subvol, (&args), syncop_fstat_cbk, subvol->fops->fstat,
- fd, xdata_in);
+ args = cookie;
- if (stbuf)
- *stbuf = args.iatt1;
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (op_ret == 0)
+ args->iatt1 = *stbuf;
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ __wake(args);
+ return 0;
}
int
-syncop_stat (xlator_t *subvol, loc_t *loc, struct iatt *stbuf, dict_t *xdata_in,
+syncop_fstat(xlator_t *subvol, fd_t *fd, struct iatt *stbuf, dict_t *xdata_in,
dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_fstat_cbk, subvol->fops->stat,
- loc, xdata_in);
+ SYNCOP(subvol, (&args), syncop_fstat_cbk, subvol->fops->fstat, fd,
+ xdata_in);
- if (stbuf)
- *stbuf = args.iatt1;
+ if (stbuf)
+ *stbuf = args.iatt1;
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
+}
+int
+syncop_stat(xlator_t *subvol, loc_t *loc, struct iatt *stbuf, dict_t *xdata_in,
+ dict_t **xdata_out)
+{
+ struct syncargs args = {
+ 0,
+ };
+
+ SYNCOP(subvol, (&args), syncop_fstat_cbk, subvol->fops->stat, loc,
+ xdata_in);
+
+ if (stbuf)
+ *stbuf = args.iatt1;
+
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (buf)
- args->iatt1 = *buf;
+ if (buf)
+ args->iatt1 = *buf;
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_symlink (xlator_t *subvol, loc_t *loc, const char *newpath,
- struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out)
+syncop_symlink(xlator_t *subvol, loc_t *loc, const char *newpath,
+ struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
-
- SYNCOP (subvol, (&args), syncop_symlink_cbk, subvol->fops->symlink,
- newpath, loc, 0, xdata_in);
+ struct syncargs args = {
+ 0,
+ };
- if (iatt)
- *iatt = args.iatt1;
+ SYNCOP(subvol, (&args), syncop_symlink_cbk, subvol->fops->symlink, newpath,
+ loc, 0, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (iatt)
+ *iatt = args.iatt1;
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if ((op_ret != -1) && path)
- args->buffer = gf_strdup (path);
+ if ((op_ret != -1) && path)
+ args->buffer = gf_strdup(path);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_readlink (xlator_t *subvol, loc_t *loc, char **buffer, size_t size,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_readlink(xlator_t *subvol, loc_t *loc, char **buffer, size_t size,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_readlink_cbk, subvol->fops->readlink,
- loc, size, xdata_in);
+ SYNCOP(subvol, (&args), syncop_readlink_cbk, subvol->fops->readlink, loc,
+ size, xdata_in);
- if (buffer)
- *buffer = args.buffer;
- else GF_FREE (args.buffer);
+ if (buffer)
+ *buffer = args.buffer;
+ else
+ GF_FREE(args.buffer);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -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)
+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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (buf)
- args->iatt1 = *buf;
+ if (buf)
+ args->iatt1 = *buf;
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev,
- struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out)
+syncop_mknod(xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev,
+ struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_mknod_cbk, subvol->fops->mknod,
- loc, mode, rdev, 0, xdata_in);
+ SYNCOP(subvol, (&args), syncop_mknod_cbk, subvol->fops->mknod, loc, mode,
+ rdev, 0, xdata_in);
- if (iatt)
- *iatt = args.iatt1;
+ if (iatt)
+ *iatt = args.iatt1;
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
-
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
-
int
-syncop_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, dict_t *xdata)
+syncop_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, dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- if (buf)
- args->iatt1 = *buf;
+ if (buf)
+ args->iatt1 = *buf;
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
-
int
-syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, struct iatt *iatt,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_mkdir(xlator_t *subvol, loc_t *loc, mode_t mode, struct iatt *iatt,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
-
- SYNCOP (subvol, (&args), syncop_mkdir_cbk, subvol->fops->mkdir,
- loc, mode, 0, xdata_in);
+ struct syncargs args = {
+ 0,
+ };
- if (iatt)
- *iatt = args.iatt1;
+ SYNCOP(subvol, (&args), syncop_mkdir_cbk, subvol->fops->mkdir, loc, mode, 0,
+ xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (iatt)
+ *iatt = args.iatt1;
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+syncop_access_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
/* posix_acl xlator will respond in different ways for access calls from
@@ -2658,323 +2875,698 @@ syncop_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
got is the mode of the access.
*/
int
-syncop_access (xlator_t *subvol, loc_t *loc, int32_t mask, dict_t *xdata_in,
- dict_t **xdata_out)
+syncop_access(xlator_t *subvol, loc_t *loc, int32_t mask, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_access_cbk, subvol->fops->access,
- loc, mask, xdata_in);
+ SYNCOP(subvol, (&args), syncop_access_cbk, subvol->fops->access, loc, mask,
+ xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_errno;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_errno;
}
-
int
-syncop_fallocate_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)
+syncop_fallocate_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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
syncop_fallocate(xlator_t *subvol, fd_t *fd, int32_t keep_size, off_t offset,
- size_t len, dict_t *xdata_in, dict_t **xdata_out)
+ size_t len, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_fallocate_cbk, subvol->fops->fallocate,
- fd, keep_size, offset, len, xdata_in);
+ SYNCOP(subvol, (&args), syncop_fallocate_cbk, subvol->fops->fallocate, fd,
+ keep_size, offset, len, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
-
int
-syncop_discard_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)
+syncop_discard_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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
syncop_discard(xlator_t *subvol, fd_t *fd, off_t offset, size_t len,
- dict_t *xdata_in, dict_t **xdata_out)
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_discard_cbk, subvol->fops->discard,
- fd, offset, len, xdata_in);
+ SYNCOP(subvol, (&args), syncop_discard_cbk, subvol->fops->discard, fd,
+ offset, len, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_zerofill_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+syncop_zerofill_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;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
syncop_zerofill(xlator_t *subvol, fd_t *fd, off_t offset, off_t len,
- dict_t *xdata_in, dict_t **xdata_out)
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_zerofill_cbk, subvol->fops->zerofill,
- fd, offset, len, xdata_in);
+ SYNCOP(subvol, (&args), syncop_zerofill_cbk, subvol->fops->zerofill, fd,
+ offset, len, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
-
int
-syncop_ipc_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+syncop_ipc_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
+ int op_errno, dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
}
int
-syncop_ipc (xlator_t *subvol, int32_t op, dict_t *xdata_in, dict_t **xdata_out)
+syncop_ipc(xlator_t *subvol, int32_t op, dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_ipc_cbk, subvol->fops->ipc,
- op, xdata_in);
+ SYNCOP(subvol, (&args), syncop_ipc_cbk, subvol->fops->ipc, op, xdata_in);
- if (args.xdata) {
- if (xdata_out) {
- /*
- * We're passing this reference to the caller, along
- * with the pointer itself. That means they're
- * responsible for calling dict_unref at some point.
- */
- *xdata_out = args.xdata;
- } else {
- dict_unref(args.xdata);
- }
+ if (args.xdata) {
+ if (xdata_out) {
+ /*
+ * We're passing this reference to the caller, along
+ * with the pointer itself. That means they're
+ * responsible for calling dict_unref at some point.
+ */
+ *xdata_out = args.xdata;
+ } else {
+ dict_unref(args.xdata);
}
+ }
+
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_seek_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
+ int op_errno, off_t offset, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
- if (args.op_ret < 0)
- return -args.op_errno;
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ args->offset = offset;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ __wake(args);
+
+ return 0;
+}
+
+int
+syncop_seek(xlator_t *subvol, fd_t *fd, off_t offset, gf_seek_what_t what,
+ dict_t *xdata_in, off_t *off)
+{
+ struct syncargs args = {
+ 0,
+ };
+
+ SYNCOP(subvol, (&args), syncop_seek_cbk, subvol->fops->seek, fd, offset,
+ what, xdata_in);
+
+ if (args.op_ret < 0) {
+ return -args.op_errno;
+ } else {
+ if (off)
+ *off = args.offset;
return args.op_ret;
+ }
}
int
-syncop_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct gf_flock *flock,
- dict_t *xdata)
+syncop_lease_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
+ int op_errno, struct gf_lease *lease, dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ if (lease)
+ args->lease = *lease;
- if (flock)
- args->flock = *flock;
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
+}
+
+int
+syncop_lease(xlator_t *subvol, loc_t *loc, struct gf_lease *lease,
+ dict_t *xdata_in, dict_t **xdata_out)
+{
+ struct syncargs args = {
+ 0,
+ };
+
+ SYNCOP(subvol, (&args), syncop_lease_cbk, subvol->fops->lease, loc, lease,
+ xdata_in);
+
+ *lease = args.lease;
+
+ if (args.xdata) {
+ if (xdata_out) {
+ /*
+ * We're passing this reference to the caller, along
+ * with the pointer itself. That means they're
+ * responsible for calling dict_unref at some point.
+ */
+ *xdata_out = args.xdata;
+ } else {
+ dict_unref(args.xdata);
+ }
+ }
+
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
+int
+syncop_lk_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
+ int op_errno, struct gf_flock *flock, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ if (flock)
+ args->flock = *flock;
+ __wake(args);
+
+ return 0;
+}
int
-syncop_lk (xlator_t *subvol, fd_t *fd, int cmd, struct gf_flock *flock,
- dict_t *xdata_in, dict_t **xdata_out)
+syncop_lk(xlator_t *subvol, fd_t *fd, int cmd, struct gf_flock *flock,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_lk_cbk, subvol->fops->lk,
- fd, cmd, flock, xdata_in);
+ SYNCOP(subvol, (&args), syncop_lk_cbk, subvol->fops->lk, fd, cmd, flock,
+ xdata_in);
- *flock = args.flock;
+ *flock = args.flock;
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int32_t
-syncop_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+syncop_inodelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
+}
+
+int
+syncop_inodelk(xlator_t *subvol, const char *volume, loc_t *loc, int32_t cmd,
+ struct gf_flock *lock, dict_t *xdata_in, dict_t **xdata_out)
+{
+ struct syncargs args = {
+ 0,
+ };
+ SYNCOP(subvol, (&args), syncop_inodelk_cbk, subvol->fops->inodelk, volume,
+ loc, cmd, lock, xdata_in);
+
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+
+ if (args.op_ret < 0)
+ return -args.op_errno;
+
+ return args.op_ret;
+}
+
+int32_t
+syncop_entrylk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ __wake(args);
+ return 0;
}
int
-syncop_inodelk (xlator_t *subvol, const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata_in, dict_t **xdata_out)
+syncop_entrylk(xlator_t *subvol, const char *volume, loc_t *loc,
+ const char *basename, entrylk_cmd cmd, entrylk_type type,
+ dict_t *xdata_in, dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_inodelk_cbk, subvol->fops->inodelk,
- volume, loc, cmd, lock, xdata_in);
+ SYNCOP(subvol, (&args), syncop_entrylk_cbk, subvol->fops->entrylk, volume,
+ loc, basename, cmd, type, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
+ if (args.op_ret < 0)
+ return -args.op_errno;
- return args.op_ret;
+ return args.op_ret;
}
int32_t
-syncop_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+syncop_xattrop_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict,
+ dict_t *xdata)
{
- struct syncargs *args = NULL;
+ struct syncargs *args = NULL;
- args = cookie;
+ args = cookie;
- args->op_ret = op_ret;
- args->op_errno = op_errno;
- if (xdata)
- args->xdata = dict_ref (xdata);
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+ if (dict)
+ args->dict_out = dict_ref(dict);
- __wake (args);
+ __wake(args);
- return 0;
+ return 0;
+}
+
+int
+syncop_xattrop(xlator_t *subvol, loc_t *loc, gf_xattrop_flags_t flags,
+ dict_t *dict, dict_t *xdata_in, dict_t **dict_out,
+ dict_t **xdata_out)
+{
+ struct syncargs args = {
+ 0,
+ };
+
+ SYNCOP(subvol, (&args), syncop_xattrop_cbk, subvol->fops->xattrop, loc,
+ flags, dict, xdata_in);
+
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+
+ if (dict_out)
+ *dict_out = args.dict_out;
+ else if (args.dict_out)
+ dict_unref(args.dict_out);
+
+ if (args.op_ret < 0)
+ return -args.op_errno;
+ return args.op_ret;
}
int
-syncop_xattrop (xlator_t *subvol, loc_t *loc, gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata_in, dict_t **xdata_out)
+syncop_fxattrop(xlator_t *subvol, fd_t *fd, gf_xattrop_flags_t flags,
+ dict_t *dict, dict_t *xdata_in, dict_t **dict_out,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_xattrop_cbk, subvol->fops->xattrop,
- loc, flags, dict, xdata_in);
+ SYNCOP(subvol, (&args), syncop_xattrop_cbk, subvol->fops->fxattrop, fd,
+ flags, dict, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- if (args.op_ret < 0)
- return -args.op_errno;
+ if (dict_out)
+ *dict_out = args.dict_out;
+ else if (args.dict_out)
+ dict_unref(args.dict_out);
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+
+ return args.op_ret;
+}
+
+int32_t
+syncop_getactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ lock_migration_info_t *locklist, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+ lock_migration_info_t *tmp = NULL;
+ lock_migration_info_t *entry = NULL;
+
+ args = cookie;
+
+ INIT_LIST_HEAD(&args->locklist.list);
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ if (op_ret > 0) {
+ list_for_each_entry(tmp, &locklist->list, list)
+ {
+ entry = GF_CALLOC(1, sizeof(lock_migration_info_t),
+ gf_common_mt_char);
+
+ if (!entry) {
+ gf_msg(THIS->name, GF_LOG_ERROR, 0, 0,
+ "lock mem allocation failed");
+ gf_free_mig_locks(&args->locklist);
+
+ break;
+ }
+
+ INIT_LIST_HEAD(&entry->list);
+
+ entry->flock = tmp->flock;
+
+ entry->lk_flags = tmp->lk_flags;
+
+ entry->client_uid = gf_strdup(tmp->client_uid);
+
+ list_add_tail(&entry->list, &args->locklist.list);
+ }
+ }
+
+ __wake(args);
+
+ return 0;
}
int
-syncop_fxattrop (xlator_t *subvol, fd_t *fd, gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata_in, dict_t **xdata_out)
+syncop_getactivelk(xlator_t *subvol, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata_in,
+ dict_t **xdata_out)
{
- struct syncargs args = {0, };
+ struct syncargs args = {
+ 0,
+ };
- SYNCOP (subvol, (&args), syncop_xattrop_cbk, subvol->fops->fxattrop,
- fd, flags, dict, xdata_in);
+ SYNCOP(subvol, (&args), syncop_getactivelk_cbk, subvol->fops->getactivelk,
+ loc, xdata_in);
- if (xdata_out)
- *xdata_out = args.xdata;
- else if (args.xdata)
- dict_unref (args.xdata);
+ if (locklist)
+ list_splice_init(&args.locklist.list, &locklist->list);
+ else
+ gf_free_mig_locks(&args.locklist);
- if (args.op_ret < 0)
- return -args.op_errno;
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
- return args.op_ret;
+ if (args.op_ret < 0)
+ return -args.op_errno;
+
+ return args.op_ret;
+}
+
+int
+syncop_setactivelk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ __wake(args);
+
+ return 0;
+}
+
+int
+syncop_setactivelk(xlator_t *subvol, loc_t *loc,
+ lock_migration_info_t *locklist, dict_t *xdata_in,
+ dict_t **xdata_out)
+{
+ struct syncargs args = {
+ 0,
+ };
+
+ SYNCOP(subvol, (&args), syncop_setactivelk_cbk, subvol->fops->setactivelk,
+ loc, locklist, xdata_in);
+
+ if (xdata_out)
+ *xdata_out = args.xdata;
+ else if (args.xdata)
+ dict_unref(args.xdata);
+
+ if (args.op_ret < 0)
+ return -args.op_errno;
+
+ return args.op_ret;
+}
+
+int
+syncop_icreate_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 *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ if (buf)
+ args->iatt1 = *buf;
+
+ __wake(args);
+
+ return 0;
+}
+
+int
+syncop_namelink_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;
+
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ __wake(args);
+
+ return 0;
+}
+
+int
+syncop_copy_file_range(xlator_t *subvol, fd_t *fd_in, off64_t off_in,
+ fd_t *fd_out, off64_t off_out, size_t len,
+ uint32_t flags, struct iatt *stbuf,
+ struct iatt *preiatt_dst, struct iatt *postiatt_dst,
+ dict_t *xdata_in, dict_t **xdata_out)
+{
+ struct syncargs args = {
+ 0,
+ };
+
+ SYNCOP(subvol, (&args), syncop_copy_file_range_cbk,
+ subvol->fops->copy_file_range, fd_in, off_in, fd_out, off_out, len,
+ flags, xdata_in);
+
+ if (stbuf) {
+ *stbuf = args.iatt1;
+ }
+ if (preiatt_dst) {
+ *preiatt_dst = args.iatt2;
+ }
+ if (postiatt_dst) {
+ *postiatt_dst = args.iatt3;
+ }
+
+ if (xdata_out) {
+ *xdata_out = args.xdata;
+ } else if (args.xdata) {
+ dict_unref(args.xdata);
+ }
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_copy_file_range_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *stbuf,
+ struct iatt *prebuf_dst, struct iatt *postbuf_dst,
+ dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref(xdata);
+
+ if (op_ret >= 0) {
+ args->iatt1 = *stbuf;
+ args->iatt2 = *prebuf_dst;
+ args->iatt3 = *postbuf_dst;
+ }
+
+ __wake(args);
+
+ return 0;
}
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h
deleted file mode 100644
index 8afc68e7f21..00000000000
--- a/libglusterfs/src/syncop.h
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- 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 _SYNCOP_H
-#define _SYNCOP_H
-
-#include "xlator.h"
-#include <sys/time.h>
-#include <pthread.h>
-#include <ucontext.h>
-
-#define SYNCENV_PROC_MAX 16
-#define SYNCENV_PROC_MIN 2
-#define SYNCPROC_IDLE_TIME 600
-
-/*
- * Flags for syncopctx valid elements
- */
-#define SYNCOPCTX_UID 0x00000001
-#define SYNCOPCTX_GID 0x00000002
-#define SYNCOPCTX_GROUPS 0x00000004
-#define SYNCOPCTX_PID 0x00000008
-#define SYNCOPCTX_LKOWNER 0x00000010
-
-struct synctask;
-struct syncproc;
-struct syncenv;
-
-
-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_ZOMBIE,
-} 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 woken;
- int slept;
- int ret;
-
- uid_t uid;
- gid_t gid;
-
- ucontext_t ctx;
- struct syncproc *proc;
-
- pthread_mutex_t mutex; /* for synchronous spawning of synctask */
- pthread_cond_t cond;
- int done;
-
- struct list_head waitq; /* can wait only "once" at a time */
- char btbuf[GF_BACKTRACE_LEN];
-};
-
-
-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;
-
- int procmin;
- int procmax;
-
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-
- size_t stacksize;
-
- int destroy; /* FLAG to mark syncenv is in destroy mode
- so that no more synctasks are accepted*/
-};
-
-
-typedef enum {
- LOCK_NULL = 0,
- LOCK_TASK,
- LOCK_THREAD
-} lock_type_t;
-
-typedef enum {
- SYNC_LOCK_DEFAULT = 0,
- SYNC_LOCK_RECURSIVE, /*it allows recursive locking*/
-} lock_attr_t;
-
-struct synclock {
- pthread_mutex_t guard; /* guard the remaining members, pair @cond */
- pthread_cond_t cond; /* waiting non-synctasks */
- struct list_head waitq; /* waiting synctasks */
- volatile int lock; /* true(non zero) or false(zero), lock status */
- lock_attr_t attr;
- struct synctask *owner; /* NULL if current owner is not a synctask */
- pthread_t owner_tid;
- lock_type_t type;
-};
-typedef struct synclock synclock_t;
-
-
-struct syncbarrier {
- pthread_mutex_t guard; /* guard the remaining members, pair @cond */
- pthread_cond_t cond; /* waiting non-synctasks */
- struct list_head waitq; /* waiting synctasks */
- int count; /* count the number of wakes */
-};
-typedef struct syncbarrier syncbarrier_t;
-
-
-struct syncargs {
- int op_ret;
- int op_errno;
- struct iatt iatt1;
- struct iatt iatt2;
- dict_t *xattr;
- struct statvfs statvfs_buf;
- struct iovec *vector;
- int count;
- struct iobref *iobref;
- char *buffer;
- dict_t *xdata;
- struct gf_flock flock;
-
- /* some more _cbk needs */
- uuid_t uuid;
- char *errstr;
- dict_t *dict;
- pthread_mutex_t lock_dict;
-
- syncbarrier_t barrier;
-
- /* do not touch */
- struct synctask *task;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int done;
- gf_dirent_t entries;
-};
-
-struct syncopctx {
- unsigned int valid; /* valid flags for elements that are set */
- uid_t uid;
- gid_t gid;
- int grpsize;
- int ngrps;
- gid_t *groups;
- pid_t pid;
- gf_lkowner_t lk_owner;
-};
-
-#define __yawn(args) do { \
- args->task = synctask_get (); \
- if (args->task) \
- break; \
- pthread_mutex_init (&args->mutex, NULL); \
- pthread_cond_init (&args->cond, NULL); \
- args->done = 0; \
- } while (0)
-
-
-#define __wake(args) do { \
- if (args->task) { \
- synctask_wake (args->task); \
- } else { \
- pthread_mutex_lock (&args->mutex); \
- { \
- args->done = 1; \
- pthread_cond_signal (&args->cond); \
- } \
- pthread_mutex_unlock (&args->mutex); \
- } \
- } while (0)
-
-
-#define __yield(args) do { \
- if (args->task) { \
- synctask_yield (args->task); \
- } else { \
- pthread_mutex_lock (&args->mutex); \
- { \
- while (!args->done) \
- 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 SYNCOP(subvol, stb, cbk, op, params ...) do { \
- struct synctask *task = NULL; \
- call_frame_t *frame = NULL; \
- \
- task = synctask_get (); \
- stb->task = task; \
- if (task) \
- frame = task->opframe; \
- else \
- frame = syncop_create_frame (THIS); \
- \
- if (task) { \
- frame->root->uid = task->uid; \
- frame->root->gid = task->gid; \
- } \
- \
- __yawn (stb); \
- \
- STACK_WIND_COOKIE (frame, cbk, (void *)stb, subvol, \
- op, params); \
- \
- __yield (stb); \
- if (task) \
- STACK_RESET (frame->root); \
- else \
- STACK_DESTROY (frame->root); \
- } while (0)
-
-
-#define SYNCENV_DEFAULT_STACKSIZE (2 * 1024 * 1024)
-
-struct syncenv * syncenv_new (size_t stacksize, int procmin, int procmax);
-void syncenv_destroy (struct syncenv *);
-void syncenv_scale (struct syncenv *env);
-
-int synctask_new1 (struct syncenv *, size_t stacksize, synctask_fn_t,
- synctask_cbk_t, call_frame_t *frame, void *);
-int synctask_new (struct syncenv *, synctask_fn_t, synctask_cbk_t,
- call_frame_t *frame, void *);
-struct synctask *synctask_create (struct syncenv *, size_t stacksize,
- synctask_fn_t, synctask_cbk_t, call_frame_t *,
- void *);
-int synctask_join (struct synctask *task);
-void synctask_wake (struct synctask *task);
-void synctask_yield (struct synctask *task);
-void synctask_waitfor (struct synctask *task, int count);
-
-#define synctask_barrier_init(args) syncbarrier_init (&args->barrier)
-#define synctask_barrier_wait(args, n) syncbarrier_wait (&args->barrier, n)
-#define synctask_barrier_wake(args) syncbarrier_wake (&args->barrier)
-
-int synctask_setid (struct synctask *task, uid_t uid, gid_t gid);
-#define SYNCTASK_SETID(uid, gid) synctask_setid (synctask_get(), uid, gid);
-
-int syncopctx_setfsuid (void *uid);
-int syncopctx_setfsgid (void *gid);
-int syncopctx_setfsgroups (int count, const void *groups);
-int syncopctx_setfspid (void *pid);
-int syncopctx_setfslkowner (gf_lkowner_t *lk_owner);
-
-static inline call_frame_t *
-syncop_create_frame (xlator_t *this)
-{
- call_frame_t *frame = NULL;
- int ngrps = -1;
- struct syncopctx *opctx = NULL;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- return NULL;
-
- opctx = syncopctx_getctx ();
-
- if (opctx && (opctx->valid & SYNCOPCTX_PID))
- frame->root->pid = opctx->pid;
- else
- frame->root->pid = getpid ();
-
- if (opctx && (opctx->valid & SYNCOPCTX_UID))
- frame->root->uid = opctx->uid;
- else
- frame->root->uid = geteuid ();
-
- if (opctx && (opctx->valid & SYNCOPCTX_GID))
- frame->root->gid = opctx->gid;
- else
- frame->root->gid = getegid ();
-
- if (opctx && (opctx->valid & SYNCOPCTX_GROUPS)) {
- ngrps = opctx->ngrps;
-
- if (ngrps != 0 && opctx->groups != NULL) {
- if (call_stack_alloc_groups (frame->root, ngrps) != 0) {
- STACK_DESTROY (frame->root);
- return NULL;
- }
-
- memcpy (frame->root->groups, opctx->groups,
- (sizeof (gid_t) * ngrps));
- }
- }
- else {
- ngrps = getgroups (0, 0);
- if (ngrps < 0) {
- STACK_DESTROY (frame->root);
- return NULL;
- }
-
- if (call_stack_alloc_groups (frame->root, ngrps) != 0) {
- STACK_DESTROY (frame->root);
- return NULL;
- }
-
- if (getgroups (ngrps, frame->root->groups) < 0) {
- STACK_DESTROY (frame->root);
- return NULL;
- }
- }
-
- if (opctx && (opctx->valid & SYNCOPCTX_LKOWNER))
- frame->root->lk_owner = opctx->lk_owner;
-
- return frame;
-}
-
-int synclock_init (synclock_t *lock, lock_attr_t attr);
-int synclock_destroy (synclock_t *lock);
-int synclock_lock (synclock_t *lock);
-int synclock_trylock (synclock_t *lock);
-int synclock_unlock (synclock_t *lock);
-
-
-int syncbarrier_init (syncbarrier_t *barrier);
-int syncbarrier_wait (syncbarrier_t *barrier, int waitfor);
-int syncbarrier_wake (syncbarrier_t *barrier);
-int syncbarrier_destroy (syncbarrier_t *barrier);
-
-int syncop_lookup (xlator_t *subvol, loc_t *loc,
- /* out */
- struct iatt *iatt, struct iatt *parent,
- /* xdata */
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_readdirp (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
- /* out */
- gf_dirent_t *entries,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_readdir (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
- gf_dirent_t *entries, dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_opendir (xlator_t *subvol, loc_t *loc, fd_t *fd, dict_t *xdata_in,
- dict_t **xdata_out);
-
-int syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid,
- /* out */
- struct iatt *preop, struct iatt *postop, dict_t *xdata_in,
- dict_t **xdata_out);
-
-int syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid,
- /* out */
- struct iatt *preop, struct iatt *postop, dict_t *xdata_in,
- dict_t **xdata_out);
-
-int syncop_statfs (xlator_t *subvol, loc_t *loc,
- /* out */
- struct statvfs *buf,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_listxattr (xlator_t *subvol, loc_t *loc, dict_t **dict,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_getxattr (xlator_t *xl, loc_t *loc, dict_t **dict, const char *key,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_fgetxattr (xlator_t *xl, fd_t *fd, dict_t **dict, const char *key,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode,
- fd_t *fd, struct iatt *iatt,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd,
- dict_t *xdata_in, dict_t **xdata_out);
-
-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,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_writev (xlator_t *subvol, fd_t *fd, const struct iovec *vector,
- int32_t count, off_t offset, struct iobref *iobref,
- uint32_t flags, dict_t *xdata_in, dict_t **xdata_out);
-
-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,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_ftruncate (xlator_t *subvol, fd_t *fd, off_t offset,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_unlink (xlator_t *subvol, loc_t *loc, dict_t *xdata_in,
- dict_t **xdata_out);
-
-int syncop_rmdir (xlator_t *subvol, loc_t *loc, int flags, dict_t *xdata_in,
- dict_t **xdata_out);
-
-int syncop_fsync (xlator_t *subvol, fd_t *fd, int dataonly, dict_t *xdata_in,
- dict_t **xdata_out);
-
-int syncop_flush (xlator_t *subvol, fd_t *fd, dict_t *xdata_in,
- dict_t **xdata_out);
-
-int syncop_fstat (xlator_t *subvol, fd_t *fd, struct iatt *stbuf,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_stat (xlator_t *subvol, loc_t *loc, struct iatt *stbuf,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_symlink (xlator_t *subvol, loc_t *loc, const char *newpath,
- struct iatt *iatt,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_readlink (xlator_t *subvol, loc_t *loc, char **buffer, size_t size,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev,
- struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, struct iatt *iatt,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc,
- struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_fsyncdir (xlator_t *subvol, fd_t *fd, int datasync,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_access (xlator_t *subvol, loc_t *loc, int32_t mask,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_fallocate(xlator_t *subvol, fd_t *fd, int32_t keep_size,
- off_t offset, size_t len, dict_t *xdata_in,
- dict_t **xdata_out);
-
-int syncop_discard(xlator_t *subvol, fd_t *fd, off_t offset, size_t len,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_zerofill(xlator_t *subvol, fd_t *fd, off_t offset, off_t len,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_rename (xlator_t *subvol, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_lk (xlator_t *subvol, fd_t *fd, int cmd, struct gf_flock *flock,
- dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_inodelk (xlator_t *subvol, const char *volume, loc_t *loc,
- int32_t cmd, struct gf_flock *lock, dict_t *xdata_in,
- dict_t **xdata_out);
-
-int syncop_ipc (xlator_t *subvol, int op, dict_t *xdata_in, dict_t **xdata_out);
-
-int syncop_xattrop (xlator_t *subvol, loc_t *loc, gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata_in, dict_t **xdata_out);
-
-int
-syncop_fxattrop (xlator_t *subvol, fd_t *fd, gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata_in, dict_t **xdata_out);
-#endif /* _SYNCOP_H */
diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c
index dc257f6cfcc..04400f98b6c 100644
--- a/libglusterfs/src/syscall.c
+++ b/libglusterfs/src/syscall.c
@@ -8,597 +8,869 @@
cases as published by the Free Software Foundation.
*/
-#include "compat.h"
-#include "syscall.h"
+#include "glusterfs/compat.h"
+#include "glusterfs/syscall.h"
+#include "glusterfs/mem-pool.h"
+#include "glusterfs/libglusterfs-messages.h"
+#ifdef __FreeBSD__
+#include <sys/sysctl.h>
+#include <signal.h>
+#endif
#include <sys/types.h>
#include <utime.h>
#include <sys/time.h>
#include <fcntl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#ifdef HAVE_COPY_FILE_RANGE_SYS
+#include <sys/syscall.h>
+#endif
+
+#define FS_ERROR_LOG(result) \
+ do { \
+ gf_msg_callingfn("FS", GF_LOG_CRITICAL, EIO, \
+ LG_MSG_SYSCALL_RETURNS_WRONG, \
+ "returned %zd for the syscall", (ssize_t)result); \
+ } while (0)
+
+/*
+ * Input to these macros is generally a function call, so capture the result
+ * i.e. (_ret) in another variable and use that instead of using _ret again
+ */
+#define FS_RET_CHECK(_ret, err) \
+ ({ \
+ typeof(_ret) _result = (_ret); \
+ if (_result < -1) { \
+ FS_ERROR_LOG(_result); \
+ _result = -1; \
+ err = EIO; \
+ } \
+ _result; \
+ })
+
+#define FS_RET_CHECK0(_ret, err) \
+ ({ \
+ typeof(_ret) _result0 = (_ret); \
+ if (_result0 < -1 || _result0 > 0) { \
+ FS_ERROR_LOG(_result0); \
+ _result0 = -1; \
+ err = EIO; \
+ } \
+ _result0; \
+ })
+
+#define FS_RET_CHECK_ERRNO(_ret, err) \
+ ({ \
+ typeof(_ret) _result1 = (_ret); \
+ if (_result1 < 0) { \
+ FS_ERROR_LOG(_result1); \
+ _result1 = -1; \
+ err = EIO; \
+ } else if (_result1 > 0) { \
+ err = _result1; \
+ _result1 = -1; \
+ } \
+ _result1; \
+ })
int
-sys_lstat (const char *path, struct stat *buf)
+sys_lstat(const char *path, struct stat *buf)
{
- return lstat (path, buf);
+ return FS_RET_CHECK0(lstat(path, buf), errno);
}
-
int
-sys_stat (const char *path, struct stat *buf)
+sys_stat(const char *path, struct stat *buf)
{
- return stat (path, buf);
+ return FS_RET_CHECK0(stat(path, buf), errno);
}
-
int
-sys_fstat (int fd, struct stat *buf)
+sys_fstat(int fd, struct stat *buf)
{
- return fstat (fd, buf);
+ return FS_RET_CHECK0(fstat(fd, buf), errno);
}
-
int
sys_fstatat(int dirfd, const char *pathname, struct stat *buf, int flags)
{
#ifdef GF_DARWIN_HOST_OS
- if (fchdir(dirfd) < 0)
- return -1;
- if(flags & AT_SYMLINK_NOFOLLOW)
- return lstat(pathname, buf);
- else
- return stat(pathname, buf);
+ if (fchdir(dirfd) < 0)
+ return -1;
+ if (flags & AT_SYMLINK_NOFOLLOW)
+ return FS_RET_CHECK0(lstat(pathname, buf), errno);
+ else
+ return FS_RET_CHECK0(stat(pathname, buf), errno);
#else
- return fstatat (dirfd, pathname, buf, flags);
+ return FS_RET_CHECK0(fstatat(dirfd, pathname, buf, flags), errno);
#endif
}
-
int
-sys_openat(int dirfd, const char *pathname, int flags, ...)
+sys_openat(int dirfd, const char *pathname, int flags, int mode)